diff --git a/app/code/Magento/Backend/Test/Mftf/Section/AdminMainActionsSection.xml b/app/code/Magento/Backend/Test/Mftf/Section/AdminMainActionsSection.xml index 344a209b93f60..3a0737bcae4a1 100644 --- a/app/code/Magento/Backend/Test/Mftf/Section/AdminMainActionsSection.xml +++ b/app/code/Magento/Backend/Test/Mftf/Section/AdminMainActionsSection.xml @@ -10,9 +10,9 @@ xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd">
- - + +
diff --git a/app/code/Magento/Catalog/Model/CategoryList.php b/app/code/Magento/Catalog/Model/CategoryList.php index 790ea6b921fbe..86692c7d6bc61 100644 --- a/app/code/Magento/Catalog/Model/CategoryList.php +++ b/app/code/Magento/Catalog/Model/CategoryList.php @@ -15,6 +15,9 @@ use Magento\Framework\Api\SearchCriteriaInterface; use Magento\Framework\Api\SearchCriteria\CollectionProcessorInterface; +/** + * Class for getting category list. + */ class CategoryList implements CategoryListInterface { /** @@ -64,7 +67,7 @@ public function __construct( } /** - * {@inheritdoc} + * @inheritdoc */ public function getList(SearchCriteriaInterface $searchCriteria) { @@ -75,8 +78,8 @@ public function getList(SearchCriteriaInterface $searchCriteria) $this->collectionProcessor->process($searchCriteria, $collection); $items = []; - foreach ($collection->getAllIds() as $id) { - $items[] = $this->categoryRepository->get($id); + foreach ($collection->getItems() as $category) { + $items[] = $this->categoryRepository->get($category->getId()); } /** @var CategorySearchResultsInterface $searchResult */ diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml index d158243d42540..c8c24d1f41e19 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductData.xml @@ -295,4 +295,8 @@ 1 EavStock1 + + 100 + EavStock100 + diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/ProductExtensionAttributeData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/ProductExtensionAttributeData.xml index 5424e48261085..5b2dc5e691a2b 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/ProductExtensionAttributeData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/ProductExtensionAttributeData.xml @@ -14,4 +14,7 @@ Qty_1 + + Qty_100 + diff --git a/app/code/Magento/Catalog/Test/Mftf/Data/StockItemData.xml b/app/code/Magento/Catalog/Test/Mftf/Data/StockItemData.xml index 99e072b91c3a9..a071c068b575d 100644 --- a/app/code/Magento/Catalog/Test/Mftf/Data/StockItemData.xml +++ b/app/code/Magento/Catalog/Test/Mftf/Data/StockItemData.xml @@ -16,4 +16,8 @@ 1 true + + 100 + true + diff --git a/app/code/Magento/Catalog/Test/Unit/Model/CategoryListTest.php b/app/code/Magento/Catalog/Test/Unit/Model/CategoryListTest.php index b8b76524099f4..ab0c0ea38d79c 100644 --- a/app/code/Magento/Catalog/Test/Unit/Model/CategoryListTest.php +++ b/app/code/Magento/Catalog/Test/Unit/Model/CategoryListTest.php @@ -86,14 +86,16 @@ public function testGetList() $categoryIdSecond = 2; $categoryFirst = $this->getMockBuilder(Category::class)->disableOriginalConstructor()->getMock(); + $categoryFirst->expects($this->atLeastOnce())->method('getId')->willReturn($categoryIdFirst); $categorySecond = $this->getMockBuilder(Category::class)->disableOriginalConstructor()->getMock(); + $categorySecond->expects($this->atLeastOnce())->method('getId')->willReturn($categoryIdSecond); /** @var SearchCriteriaInterface|\PHPUnit_Framework_MockObject_MockObject $searchCriteria */ $searchCriteria = $this->createMock(SearchCriteriaInterface::class); $collection = $this->getMockBuilder(Collection::class)->disableOriginalConstructor()->getMock(); $collection->expects($this->once())->method('getSize')->willReturn($totalCount); - $collection->expects($this->once())->method('getAllIds')->willReturn([$categoryIdFirst, $categoryIdSecond]); + $collection->expects($this->once())->method('getItems')->willReturn([$categoryFirst, $categorySecond]); $this->collectionProcessorMock->expects($this->once()) ->method('process') diff --git a/app/code/Magento/Cms/Test/Mftf/Test/AdminRestrictedUserOnlyAccessCmsBlockTest.xml b/app/code/Magento/Cms/Test/Mftf/Test/AdminRestrictedUserOnlyAccessCmsBlockTest.xml new file mode 100644 index 0000000000000..d0ed330779676 --- /dev/null +++ b/app/code/Magento/Cms/Test/Mftf/Test/AdminRestrictedUserOnlyAccessCmsBlockTest.xml @@ -0,0 +1,59 @@ + + + + + + + + + <description value="Check that the system shows information only in Blocks"/> + <severity value="MAJOR"/> + <testCaseId value="MC-13814"/> + <useCaseId value="MAGETWO-88612"/> + <group value="Cms"/> + </annotations> + <before> + <createData entity="restrictedWebUser" stepKey="createRestrictedAdmin"/> + <actionGroup ref="LoginToAdminActionGroup" stepKey="loginToBackend"/> + <actionGroup ref="AdminCreateUserRoleActionGroup" stepKey="createRestrictedAdminRole"> + <argument name="roleName" value="{{RoleTest.roleName}}"/> + <argument name="resourceAccess" value="Custom"/> + <argument name="resource" value="Magento_Cms::block"/> + </actionGroup> + <actionGroup ref="AdminAssignUserRoleActionGroup" stepKey="assignAdminRole"> + <argument name="user_restricted" value="$$createRestrictedAdmin$$"/> + <argument name="roleName" value="{{RoleTest.roleName}}"/> + </actionGroup> + <actionGroup ref="logout" stepKey="logOut"/> + </before> + <after> + <actionGroup ref="LoginActionGroup" stepKey="loginAsAdminWithAllAccess"/> + <actionGroup ref="AdminDeleteUserRoleActionGroup" stepKey="deleteRestrictedRole"> + <argument name="roleName" value="{{RoleTest.roleName}}"/> + </actionGroup> + <actionGroup ref="AdminDeleteUserActionGroup" stepKey="deleteRestrictedUser"> + <argument name="user_restricted" value="$$createRestrictedAdmin$$"/> + </actionGroup> + <!--Log Out--> + <actionGroup ref="logout" stepKey="logOut"/> + </after> + + <!--login as restricted user--> + <actionGroup ref="AdminLoginAsAnyUser" stepKey="logAsNewUser"> + <argument name="login" value="$$createRestrictedAdmin.username$$"/> + <argument name="password" value="$$createRestrictedAdmin.password$$"/> + </actionGroup> + + <!--Verify that The system shows information included in "Blocks"--> + <see userInput="Blocks" stepKey="seeBlocksPage"/> + <seeInCurrentUrl url="{{AdminCmsBlockGridPage.url}}" stepKey="assertUrl"/> + <!--Log Out--> + <actionGroup ref="logout" stepKey="logOut"/> + </test> +</tests> diff --git a/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/DataProviderTest.php b/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/DataProviderTest.php index 54e0e17ab7ad6..ec9cb86c6c9dc 100644 --- a/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/DataProviderTest.php +++ b/app/code/Magento/Cms/Test/Unit/Ui/Component/Listing/DataProviderTest.php @@ -118,11 +118,12 @@ public function testPrepareMetadata() 'config' => [ 'editorConfig' => [ 'enabled' => false - ] - ] - ] - ] - ] + ], + 'componentType' => \Magento\Ui\Component\Container::NAME, + ], + ], + ], + ], ]; $this->assertEquals( diff --git a/app/code/Magento/Cms/Ui/Component/DataProvider.php b/app/code/Magento/Cms/Ui/Component/DataProvider.php index 5fc9c5a896037..a0f68f8dde05a 100644 --- a/app/code/Magento/Cms/Ui/Component/DataProvider.php +++ b/app/code/Magento/Cms/Ui/Component/DataProvider.php @@ -13,6 +13,9 @@ use Magento\Framework\AuthorizationInterface; use Magento\Framework\View\Element\UiComponent\DataProvider\Reporting; +/** + * DataProvider for cms ui. + */ class DataProvider extends \Magento\Framework\View\Element\UiComponent\DataProvider\DataProvider { /** @@ -67,6 +70,8 @@ public function __construct( } /** + * Get authorization info. + * * @deprecated 101.0.7 * @return AuthorizationInterface|mixed */ @@ -95,11 +100,12 @@ public function prepareMetadata() 'config' => [ 'editorConfig' => [ 'enabled' => false - ] - ] - ] - ] - ] + ], + 'componentType' => \Magento\Ui\Component\Container::NAME, + ], + ], + ], + ], ]; } diff --git a/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCheckingProductQtyAfterOrderCancelTest.xml b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCheckingProductQtyAfterOrderCancelTest.xml new file mode 100644 index 0000000000000..af463c9042357 --- /dev/null +++ b/app/code/Magento/ConfigurableProduct/Test/Mftf/Test/AdminCheckingProductQtyAfterOrderCancelTest.xml @@ -0,0 +1,135 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd"> + <test name="AdminCheckingProductQtyAfterOrderCancelTest"> + <annotations> + <features value="ConfigurableProduct"/> + <stories value="Product quantity after order cancel"/> + <title value="Products quantity return after order cancel"/> + <description value="Checking product quantity after the order cancel"/> + <severity value="CRITICAL"/> + <testCaseId value="MC-13790"/> + <group value="configurableProduct"/> + </annotations> + <before> + <!--Create category--> + <createData entity="ApiCategory" stepKey="createCategory"/> + <!--Create configurable product and add it to the category--> + <createData entity="ApiConfigurableProduct" stepKey="createConfigProduct"> + <requiredEntity createDataKey="createCategory"/> + </createData> + <!--Create attribute--> + <createData entity="productAttributeWithDropdownTwoOptions" stepKey="createConfigProductAttribute"/> + <createData entity="productAttributeOption1" stepKey="createConfigProductAttributeOption1"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <!--Add the attribute to default attribute set--> + <createData entity="AddToDefaultSet" stepKey="createConfigAddToAttributeSet"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </createData> + <!--Get the option of the attribute--> + <getData entity="ProductAttributeOptionGetter" index="1" stepKey="getConfigAttributeOption"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + </getData> + <!--Create simple product and give it the attribute with option--> + <createData entity="ApiSimpleWithQty100" stepKey="createConfigChildProduct"> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption"/> + </createData> + <!--Create configurable product--> + <createData entity="ConfigurableProductTwoOptions" stepKey="createConfigProductOption"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigProductAttribute"/> + <requiredEntity createDataKey="getConfigAttributeOption"/> + </createData> + <!--Add simple product to the configurable product--> + <createData entity="ConfigurableProductAddChild" stepKey="createConfigProductAddChild"> + <requiredEntity createDataKey="createConfigProduct"/> + <requiredEntity createDataKey="createConfigChildProduct"/> + </createData> + <!--Create customer--> + <createData entity="Simple_US_Customer" stepKey="createCustomer"/> + <!--Login--> + <actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/> + </before> + <after> + <!--Clear grid filters--> + <amOnPage url="{{AdminOrdersPage.url}}" stepKey="goToOrderGridPage"/> + <actionGroup ref="clearFiltersAdminDataGrid" stepKey="clearGridFilter"/> + <!--Delete entities--> + <deleteData createDataKey="createCustomer" stepKey="deleteCustomer"/> + <deleteData createDataKey="createConfigProduct" stepKey="deleteConfigProduct"/> + <deleteData createDataKey="createConfigChildProduct" stepKey="deleteConfigChildProduct"/> + <deleteData createDataKey="createConfigProductAttribute" stepKey="deleteConfigProductAttribute"/> + <deleteData createDataKey="createCategory" stepKey="deleteCategory"/> + <!--Logout--> + <actionGroup ref="logout" stepKey="logoutFromAdmin"/> + <actionGroup ref="CustomerLogoutStorefrontActionGroup" stepKey="logoutFromStorefront"/> + </after> + + <!--Go to Storefront as Customer--> + <actionGroup ref="CustomerLoginOnStorefront" stepKey="customerLogin"> + <argument name="customer" value="$$createCustomer$$" /> + </actionGroup> + + <!--Go to the configurable product page on Storefront--> + <amOnPage url="{{StorefrontProductPage.url($$createConfigProduct.sku$$)}}" stepKey="goToProductPage"/> + <!--Select option--> + <selectOption selector="{{StorefrontProductInfoMainSection.productAttributeOptionsSelectButton}}" userInput="$$getConfigAttributeOption.label$$" stepKey="selectOption"/> + <!--Add product to the Shopping cart--> + <actionGroup ref="StorefrontAddProductToCartQuantityActionGroup" stepKey="addProductToCart"> + <argument name="productName" value="$createConfigProduct.name$"/> + <argument name="quantity" value="4"/> + </actionGroup> + + <!--Open Shopping cart--> + <actionGroup ref="StorefrontOpenCartFromMinicartActionGroup" stepKey="openShoppingCartFromMinicart"/> + <!--Place order--> + <actionGroup ref="PlaceOrderWithLoggedUserActionGroup" stepKey="placeOrder"> + <argument name="shippingMethod" value="Flat Rate"/> + <argument name="paymentMethod" value="Check / Money order"/> + </actionGroup> + <grabTextFrom selector="{{CheckoutSuccessMainSection.orderNumber22}}" stepKey="grabOrderNumber"/> + + <!--Open order--> + <actionGroup ref="OpenOrderById" stepKey="openOrderById"> + <argument name="orderId" value="{$grabOrderNumber}"/> + </actionGroup> + + <!--Start create invoice--> + <actionGroup ref="StartCreateInvoiceFromOrderPage" stepKey="startCreateInvoice"/> + <!--Create partial invoice--> + <actionGroup ref="CreatePartialInvoice" stepKey="createPartialInvoice"> + <argument name="productSku" value="$createConfigChildProduct.sku$"/> + <argument name="qtyToInvoice" value="1"/> + </actionGroup> + <!--Submit Invoice--> + <actionGroup ref="SubmitInvoice" stepKey="submitInvoice"/> + <!--Create Shipment--> + <actionGroup ref="StartCreateShipmentFromOrderPage" stepKey="startCreateShipment"/> + <fillField selector="{{AdminShipmentItemsSection.itemQtyToShip('1')}}" userInput="1" stepKey="changeItemQtyToShip"/> + <actionGroup ref="SubmitShipment" stepKey="submitShipment"/> + + <!--Cancel order--> + <actionGroup ref="CancelProcessingOrder" stepKey="cancelOrder"/> + <!--Check quantities in "Items Ordered" table--> + <see selector="{{AdminOrderItemsOrderedSection.itemQty('1')}}" userInput="Invoiced 1" stepKey="seeInvoicedQuantity"/> + <see selector="{{AdminOrderItemsOrderedSection.itemQty('1')}}" userInput="Shipped 1" stepKey="seeShippedQuantity"/> + <see selector="{{AdminOrderItemsOrderedSection.itemQty('1')}}" userInput="Canceled 3" stepKey="seeCanceledQuantity"/> + + <!--Go to catalog products page on Admin--> + <amOnPage url="{{AdminCatalogProductPage.url}}" stepKey="goToCatalogProductPage"/> + <actionGroup ref="filterProductGridBySku" stepKey="filterProductGrid"> + <argument name="product" value="$$createConfigChildProduct$$"/> + </actionGroup> + + <!--Check quantity of configurable child product--> + <see selector="{{AdminProductGridSection.productGridCell('1', 'Quantity')}}" userInput="99" stepKey="seeProductSkuInGrid"/> + </test> +</tests> diff --git a/app/code/Magento/Email/Test/Mftf/ActionGroup/AdminEmailTemplateActionGroup.xml b/app/code/Magento/Email/Test/Mftf/ActionGroup/AdminEmailTemplateActionGroup.xml index 4019e0538dd06..b0899c6d5ce4d 100644 --- a/app/code/Magento/Email/Test/Mftf/ActionGroup/AdminEmailTemplateActionGroup.xml +++ b/app/code/Magento/Email/Test/Mftf/ActionGroup/AdminEmailTemplateActionGroup.xml @@ -35,7 +35,8 @@ <argument name="emailTemplate" defaultValue="EmailTemplate"/> </arguments> <seeInCurrentUrl url="email_template/edit/id" stepKey="seeCreatedTemplateUrl"/> - <click selector="{{AdminMainActionsSection.delete}}" stepKey="clickDeleteTemplateButton"/> + <!--Do not change it to use element from AdminMainActionsSection. Refer to AdminEmailTemplateEditSection comment --> + <click selector="{{AdminEmailTemplateEditSection.delete}}" stepKey="clickDeleteTemplateButton"/> <acceptPopup stepKey="acceptDeletingTemplatePopUp"/> <see userInput="You deleted the email template." stepKey="seeSuccessfulMessage"/> <click selector="{{AdminDataGridHeaderSection.clearFilters}}" stepKey="clickResetFilterButton"/> diff --git a/app/code/Magento/Email/Test/Mftf/Section/AdminEmailTemplateEditSection.xml b/app/code/Magento/Email/Test/Mftf/Section/AdminEmailTemplateEditSection.xml index 9da02b64cb2e7..81c29b28a3fd6 100644 --- a/app/code/Magento/Email/Test/Mftf/Section/AdminEmailTemplateEditSection.xml +++ b/app/code/Magento/Email/Test/Mftf/Section/AdminEmailTemplateEditSection.xml @@ -14,5 +14,7 @@ <element name="templateNameField" type="input" selector="#template_code"/> <element name="templateSubjectField" type="input" selector="#template_subject"/> <element name="previewTemplateButton" type="button" selector="#preview"/> + <!--Do not add time to this element. It call alert when clicking, so adding time will brake test--> + <element name="delete" type="button" selector="#delete"/> </section> </sections> diff --git a/app/code/Magento/Indexer/Test/Mftf/ActionGroup/AdminIndexerActionGroup.xml b/app/code/Magento/Indexer/Test/Mftf/ActionGroup/AdminIndexerActionGroup.xml new file mode 100644 index 0000000000000..5cf6656f9fb50 --- /dev/null +++ b/app/code/Magento/Indexer/Test/Mftf/ActionGroup/AdminIndexerActionGroup.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd"> + <actionGroup name="UpdateIndexerMode"> + <arguments> + <argument name="indexerId" type="string"/> + <argument name="indexerMode" type="string" defaultValue="Update on Save"/> + </arguments> + <amOnPage url="{{AdminIndexManagementPage.url}}" stepKey="amOnIndexManagementPage"/> + <checkOption selector="{{AdminIndexManagementSection.indexerCheckbox(indexerId)}}" stepKey="selectIndexer"/> + <selectOption selector="{{AdminIndexManagementSection.massActionSelect}}" userInput="{{indexerMode}}" stepKey="selectIndexerMode"/> + <click selector="{{AdminIndexManagementSection.massActionSubmit}}" stepKey="submitIndexerForm"/> + <see selector="{{AdminMessagesSection.success}}" userInput='1 indexer(s) are in "{{indexerMode}}" mode.' stepKey="seeSuccessMessage"/> + </actionGroup> +</actionGroups> diff --git a/app/code/Magento/Indexer/Test/Mftf/Page/AdminIndexManagementPage.xml b/app/code/Magento/Indexer/Test/Mftf/Page/AdminIndexManagementPage.xml new file mode 100644 index 0000000000000..504608d0721fe --- /dev/null +++ b/app/code/Magento/Indexer/Test/Mftf/Page/AdminIndexManagementPage.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> +<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd"> + <page name="AdminIndexManagementPage" url="indexer/indexer/list" module="Magento_Indexer" area="admin"> + <section name="AdminIndexManagementSection"/> + </page> +</pages> diff --git a/app/code/Magento/Indexer/Test/Mftf/Section/AdminIndexManagementSection.xml b/app/code/Magento/Indexer/Test/Mftf/Section/AdminIndexManagementSection.xml new file mode 100644 index 0000000000000..07d93ff850221 --- /dev/null +++ b/app/code/Magento/Indexer/Test/Mftf/Section/AdminIndexManagementSection.xml @@ -0,0 +1,16 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + /** + * Copyright © Magento, Inc. All rights reserved. + * See COPYING.txt for license details. + */ +--> + +<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd"> + <section name="AdminIndexManagementSection"> + <element name="indexerCheckbox" type="checkbox" selector="#gridIndexer_table input[value='{{indexerId}}']" parameterized="true"/> + <element name="massActionSelect" type="select" selector="#gridIndexer_massaction-select"/> + <element name="massActionSubmit" type="button" selector="#gridIndexer_massaction-form button" timeout="30"/> + </section> +</sections> diff --git a/app/code/Magento/Sales/Model/Service/InvoiceService.php b/app/code/Magento/Sales/Model/Service/InvoiceService.php index 718f55c3e551c..b66f59d2a2962 100644 --- a/app/code/Magento/Sales/Model/Service/InvoiceService.php +++ b/app/code/Magento/Sales/Model/Service/InvoiceService.php @@ -5,6 +5,7 @@ */ namespace Magento\Sales\Model\Service; +use Magento\Sales\Api\Data\OrderItemInterface; use Magento\Sales\Api\InvoiceManagementInterface; use Magento\Sales\Model\Order; @@ -136,14 +137,14 @@ public function prepareInvoice(Order $order, array $qtys = []) $totalQty = 0; $qtys = $this->prepareItemsQty($order, $qtys); foreach ($order->getAllItems() as $orderItem) { - if (!$this->_canInvoiceItem($orderItem)) { + if (!$this->_canInvoiceItem($orderItem, $qtys)) { continue; } $item = $this->orderConverter->itemToInvoiceItem($orderItem); - if ($orderItem->isDummy()) { - $qty = $orderItem->getQtyOrdered() ? $orderItem->getQtyOrdered() : 1; - } elseif (isset($qtys[$orderItem->getId()])) { + if (isset($qtys[$orderItem->getId()])) { $qty = (double) $qtys[$orderItem->getId()]; + } elseif ($orderItem->isDummy()) { + $qty = $orderItem->getQtyOrdered() ? $orderItem->getQtyOrdered() : 1; } elseif (empty($qtys)) { $qty = $orderItem->getQtyToInvoice(); } else { @@ -170,38 +171,55 @@ private function prepareItemsQty(Order $order, array $qtys = []) { foreach ($order->getAllItems() as $orderItem) { if (empty($qtys[$orderItem->getId()])) { - continue; - } - if ($orderItem->isDummy()) { - if ($orderItem->getHasChildren()) { - foreach ($orderItem->getChildrenItems() as $child) { - if (!isset($qtys[$child->getId()])) { - $qtys[$child->getId()] = $child->getQtyToInvoice(); - } - } - } elseif ($orderItem->getParentItem()) { - $parent = $orderItem->getParentItem(); - if (!isset($qtys[$parent->getId()])) { - $qtys[$parent->getId()] = $parent->getQtyToInvoice(); - } + $parentId = $orderItem->getParentItemId(); + if ($parentId && array_key_exists($parentId, $qtys)) { + $qtys[$orderItem->getId()] = $qtys[$parentId]; + } else { + continue; } } + $this->prepareItemQty($orderItem, $qtys); } return $qtys; } + /** + * Prepare qty to invoice item. + * + * @param OrderItemInterface $orderItem + * @param array $qtys + * @return void + */ + private function prepareItemQty(OrderItemInterface $orderItem, array &$qtys) + { + if ($orderItem->isDummy()) { + if ($orderItem->getHasChildren()) { + foreach ($orderItem->getChildrenItems() as $child) { + if (!isset($qtys[$child->getId()])) { + $qtys[$child->getId()] = $child->getQtyToInvoice(); + } + } + } elseif ($orderItem->getParentItem()) { + $parent = $orderItem->getParentItem(); + if (!isset($qtys[$parent->getId()])) { + $qtys[$parent->getId()] = $parent->getQtyToInvoice(); + } + } + } + } + /** * Check if order item can be invoiced. Dummy item can be invoiced or with his children or * with parent item which is included to invoice * - * @param \Magento\Sales\Api\Data\OrderItemInterface $item + * @param OrderItemInterface $item + * @param array $qtys * @return bool * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ - protected function _canInvoiceItem(\Magento\Sales\Api\Data\OrderItemInterface $item) + protected function _canInvoiceItem(OrderItemInterface $item, array $qtys = []) { - $qtys = []; if ($item->getLockedDoInvoice()) { return false; } diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminInvoiceActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminInvoiceActionGroup.xml index 1ce5c38256295..ed63da75df9e1 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminInvoiceActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminInvoiceActionGroup.xml @@ -45,6 +45,18 @@ <see selector="{{AdminHeaderSection.pageTitle}}" userInput="New Invoice" stepKey="seeNewInvoicePageTitle"/> </actionGroup> + <actionGroup name="CreatePartialInvoice"> + <arguments> + <argument name="productSku" type="string"/> + <argument name="qtyToInvoice" type="string" defaultValue="1"/> + </arguments> + <fillField selector="{{AdminInvoiceItemsSection.itemQtyToInvoiceBySku(productSku)}}" userInput="{{qtyToInvoice}}" stepKey="changeQtyToInvoice"/> + <waitForElementVisible selector="{{AdminInvoiceItemsSection.updateQtyEnabled}}" stepKey="waitForUpdateQtyEnabled"/> + <click selector="{{AdminInvoiceItemsSection.updateQty}}" stepKey="updateQty"/> + <waitForLoadingMaskToDisappear stepKey="waitForQtyToUpdate"/> + <waitForElementVisible selector="{{AdminInvoiceMainActionsSection.submitInvoice}}" stepKey="waitForSubmitInvoiceButton"/> + </actionGroup> + <actionGroup name="SubmitInvoice"> <click selector="{{AdminInvoiceMainActionsSection.submitInvoice}}" stepKey="clickSubmitInvoice"/> <waitForElementVisible selector="{{AdminMessagesSection.successMessage}}" stepKey="waitForMessageAppears"/> diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml index bb3bfdc03d340..730d3d6a5a185 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderActionGroup.xml @@ -18,6 +18,12 @@ <see selector="{{AdminOrderDetailsInformationSection.orderStatus}}" userInput="Canceled" stepKey="seeOrderStatusCanceled"/> </actionGroup> + <!--Cancel order that is in processing status--> + <actionGroup name="CancelProcessingOrder" extends="cancelPendingOrder"> + <remove keyForRemoval="seeOrderStatusCanceled"/> + <see selector="{{AdminOrderDetailsInformationSection.orderStatus}}" after="seeCancelSuccessMessage" userInput="{{CONST.orderStatusComplete}}" stepKey="seeOrderStatusComplete"/> + </actionGroup> + <!--Navigate to create order page (New Order -> Create New Customer)--> <actionGroup name="navigateToNewOrderPageNewCustomerSingleStore"> <arguments> diff --git a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderGridActionGroup.xml b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderGridActionGroup.xml index d99551de24db0..e5646e0a64621 100644 --- a/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderGridActionGroup.xml +++ b/app/code/Magento/Sales/Test/Mftf/ActionGroup/AdminOrderGridActionGroup.xml @@ -23,7 +23,7 @@ <amOnPage url="{{AdminOrdersPage.url}}" stepKey="goToGridOrdersPage"/> <conditionalClick selector="{{AdminOrdersGridSection.clearFilters}}" dependentSelector="{{AdminOrdersGridSection.enabledFilters}}" visible="true" stepKey="clickOnButtonToRemoveFiltersIfPresent"/> </actionGroup> - <actionGroup name="openOrderById" extends="filterOrderGridById"> + <actionGroup name="OpenOrderById" extends="filterOrderGridById"> <click selector="{{AdminDataGridTableSection.firstRow}}" after="clickOrderApplyFilters" stepKey="openOrderViewPage"/> <waitForPageLoad after="openOrderViewPage" stepKey="waitForOrderViewPageOpened"/> </actionGroup> diff --git a/app/code/Magento/Sales/Test/Mftf/Section/AdminInvoiceItemsSection.xml b/app/code/Magento/Sales/Test/Mftf/Section/AdminInvoiceItemsSection.xml index 0ab46bfff5d25..93d1b32f58dc0 100644 --- a/app/code/Magento/Sales/Test/Mftf/Section/AdminInvoiceItemsSection.xml +++ b/app/code/Magento/Sales/Test/Mftf/Section/AdminInvoiceItemsSection.xml @@ -14,5 +14,6 @@ <element name="updateQty" type="button" selector=".order-invoice-tables tfoot button[data-ui-id='order-items-update-button']"/> <element name="updateQtyEnabled" type="button" selector=".order-invoice-tables tfoot button[data-ui-id='order-items-update-button'][class='action-default scalable update-button']"/> <element name="productColumn" type="text" selector="//*[contains(@class,'order-invoice-tables')]//td[@class = 'col-product']//div[contains(text(),'{{productName}}')]" parameterized="true"/> + <element name="itemQtyToInvoiceBySku" type="input" selector="//div[contains(@class,'product-sku-block') and contains(., '{{productSku}}')]/ancestor::tr//td[contains(@class,'col-qty-invoice')]//input" parameterized="true"/> </section> </sections> diff --git a/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/AddressRepositoryTest.php b/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/AddressRepositoryTest.php index 2b74a58288600..37a36b1b3c42a 100644 --- a/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/AddressRepositoryTest.php +++ b/dev/tests/integration/testsuite/Magento/Customer/Model/ResourceModel/AddressRepositoryTest.php @@ -17,6 +17,8 @@ use Magento\Store\Api\WebsiteRepositoryInterface; /** + * Class with integration tests for AddressRepository. + * * @SuppressWarnings(PHPMD.TooManyMethods) * @SuppressWarnings(PHPMD.ExcessivePublicCount) * @SuppressWarnings(PHPMD.CouplingBetweenObjects) @@ -39,6 +41,9 @@ class AddressRepositoryTest extends \PHPUnit\Framework\TestCase /** @var \Magento\Framework\Api\DataObjectHelper */ private $dataObjectHelper; + /** + * @inheritdoc + */ protected function setUp() { $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); @@ -87,6 +92,9 @@ protected function setUp() $this->expectedAddresses = [$address, $address2]; } + /** + * @inheritdoc + */ protected function tearDown() { $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager(); @@ -96,6 +104,8 @@ protected function tearDown() } /** + * Test for save address changes. + * * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDataFixture Magento/Customer/_files/customer_address.php * @magentoDataFixture Magento/Customer/_files/customer_two_addresses.php @@ -117,6 +127,8 @@ public function testSaveAddressChanges() } /** + * Test for method save address with new id. + * * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDataFixture Magento/Customer/_files/customer_address.php * @magentoDataFixture Magento/Customer/_files/customer_two_addresses.php @@ -131,6 +143,8 @@ public function testSaveAddressesIdSetButNotAlreadyExisting() } /** + * Test for method get address by id. + * * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDataFixture Magento/Customer/_files/customer_address.php * @magentoDataFixture Magento/Customer/_files/customer_two_addresses.php @@ -144,6 +158,8 @@ public function testGetAddressById() } /** + * Test for method get address by id with incorrect id. + * * @magentoDataFixture Magento/Customer/_files/customer.php * @expectedException \Magento\Framework\Exception\NoSuchEntityException * @expectedExceptionMessage No such entity with addressId = 12345 @@ -154,6 +170,8 @@ public function testGetAddressByIdBadAddressId() } /** + * Test for method save new address. + * * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDataFixture Magento/Customer/_files/customer_address.php * @magentoAppIsolation enabled @@ -174,6 +192,8 @@ public function testSaveNewAddress() } /** + * Test for saving address with invalid address. + * * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDataFixture Magento/Customer/_files/customer_address.php * @magentoAppIsolation enabled @@ -199,6 +219,8 @@ public function testSaveNewAddressWithAttributes() } /** + * Test for method saaveNewAddress with new attributes. + * * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDataFixture Magento/Customer/_files/customer_address.php * @magentoAppIsolation enabled @@ -222,6 +244,11 @@ public function testSaveNewInvalidAddress() } } + /** + * Test for saving address without existing customer. + * + * @return void + */ public function testSaveAddressesCustomerIdNotExist() { $proposedAddress = $this->_createSecondAddress()->setCustomerId(4200); @@ -233,6 +260,11 @@ public function testSaveAddressesCustomerIdNotExist() } } + /** + * Test for saving addresses with invalid customer id. + * + * @return void + */ public function testSaveAddressesCustomerIdInvalid() { $proposedAddress = $this->_createSecondAddress()->setCustomerId('this_is_not_a_valid_id'); @@ -245,6 +277,8 @@ public function testSaveAddressesCustomerIdInvalid() } /** + * Test for deleteAddressById. + * * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDataFixture Magento/Customer/_files/customer_address.php */ @@ -268,6 +302,8 @@ public function testDeleteAddress() } /** + * Test for delete method. + * * @magentoDataFixture Magento/Customer/_files/customer.php * @magentoDataFixture Magento/Customer/_files/customer_address.php */ @@ -291,6 +327,8 @@ public function testDeleteAddressById() } /** + * Test delete address from customer with incorrect address id. + * * @magentoDataFixture Magento/Customer/_files/customer.php */ public function testDeleteAddressFromCustomerBadAddressId() @@ -304,10 +342,14 @@ public function testDeleteAddressFromCustomerBadAddressId() } /** + * Test for searching addressed. + * * @param \Magento\Framework\Api\Filter[] $filters - * @param \Magento\Framework\Api\Filter[] $filterGroup - * @param \Magento\Framework\Api\SortOrder[] $filterOrders + * @param \Magento\Framework\Api\Filter[]|null $filterGroup + * @param \Magento\Framework\Api\SortOrder[]|null $filterOrders * @param array $expectedResult array of expected results indexed by ID + * @param int $currentPage current page for search criteria + * @return void * * @dataProvider searchAddressDataProvider * @@ -315,8 +357,13 @@ public function testDeleteAddressFromCustomerBadAddressId() * @magentoDataFixture Magento/Customer/_files/customer_two_addresses.php * @magentoAppIsolation enabled */ - public function testSearchAddresses($filters, $filterGroup, $filterOrders, $expectedResult) - { + public function testSearchAddresses( + array $filters, + $filterGroup, + $filterOrders, + array $expectedResult, + int $currentPage + ) { /** @var \Magento\Framework\Api\SearchCriteriaBuilder $searchBuilder */ $searchBuilder = $this->objectManager->create(\Magento\Framework\Api\SearchCriteriaBuilder::class); foreach ($filters as $filter) { @@ -332,7 +379,7 @@ public function testSearchAddresses($filters, $filterGroup, $filterOrders, $expe } $searchBuilder->setPageSize(1); - $searchBuilder->setCurrentPage(2); + $searchBuilder->setCurrentPage($currentPage); $searchCriteria = $searchBuilder->create(); $searchResults = $this->repository->getList($searchCriteria); @@ -350,7 +397,12 @@ public function testSearchAddresses($filters, $filterGroup, $filterOrders, $expe $this->assertEquals($expectedResult[$expectedResultIndex]['firstname'], $items[0]->getFirstname()); } - public function searchAddressDataProvider() + /** + * Data provider for searchAddresses. + * + * @return array + */ + public function searchAddressDataProvider(): array { /** * @var \Magento\Framework\Api\FilterBuilder $filterBuilder @@ -365,23 +417,25 @@ public function searchAddressDataProvider() return [ 'Address with postcode 75477' => [ [$filterBuilder->setField('postcode')->setValue('75477')->create()], - null, + [], null, [ ['id' => 1, 'city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John'], ], + 1, ], 'Address with city CityM' => [ [$filterBuilder->setField('city')->setValue('CityM')->create()], - null, + [], null, [ ['id' => 1, 'city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John'], ], + 1, ], 'Addresses with firstname John sorted by firstname desc, city asc' => [ [$filterBuilder->setField('firstname')->setValue('John')->create()], - null, + [], [ $orderBuilder->setField('firstname')->setDirection(SortOrder::SORT_DESC)->create(), $orderBuilder->setField('city')->setDirection(SortOrder::SORT_ASC)->create(), @@ -390,6 +444,7 @@ public function searchAddressDataProvider() ['id' => 1, 'city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John'], ['id' => 2, 'city' => 'CityX', 'postcode' => 47676, 'firstname' => 'John'], ], + 2, ], 'Addresses with postcode of either 75477 or 47676 sorted by city desc' => [ [], @@ -404,10 +459,11 @@ public function searchAddressDataProvider() ['id' => 2, 'city' => 'CityX', 'postcode' => 47676, 'firstname' => 'John'], ['id' => 1, 'city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John'], ], + 2, ], 'Addresses with postcode greater than 0 sorted by firstname asc, postcode desc' => [ [$filterBuilder->setField('postcode')->setValue('0')->setConditionType('gt')->create()], - null, + [], [ $orderBuilder->setField('firstname')->setDirection(SortOrder::SORT_ASC)->create(), $orderBuilder->setField('postcode')->setDirection(SortOrder::SORT_ASC)->create(), @@ -416,11 +472,14 @@ public function searchAddressDataProvider() ['id' => 2, 'city' => 'CityX', 'postcode' => 47676, 'firstname' => 'John'], ['id' => 1, 'city' => 'CityM', 'postcode' => 75477, 'firstname' => 'John'], ], + 2, ], ]; } /** + * Test for save addresses with restricted countries. + * * @magentoDataFixture Magento/Customer/Fixtures/customer_sec_website.php */ public function testSaveAddressWithRestrictedCountries() diff --git a/lib/internal/Magento/Framework/App/DeploymentConfig.php b/lib/internal/Magento/Framework/App/DeploymentConfig.php index 615c295675adc..beb4f98ae76bd 100644 --- a/lib/internal/Magento/Framework/App/DeploymentConfig.php +++ b/lib/internal/Magento/Framework/App/DeploymentConfig.php @@ -70,6 +70,11 @@ public function get($key = null, $defaultValue = null) if ($key === null) { return $this->flatData; } + + if (array_key_exists($key, $this->flatData) && $this->flatData[$key] === null) { + return ''; + } + return $this->flatData[$key] ?? $defaultValue; } diff --git a/lib/internal/Magento/Framework/App/Test/Unit/DeploymentConfigTest.php b/lib/internal/Magento/Framework/App/Test/Unit/DeploymentConfigTest.php index 80ab2302dc91c..3508cfed0777b 100644 --- a/lib/internal/Magento/Framework/App/Test/Unit/DeploymentConfigTest.php +++ b/lib/internal/Magento/Framework/App/Test/Unit/DeploymentConfigTest.php @@ -140,4 +140,43 @@ public function keyCollisionDataProvider() ] ]; } + + /** + * @param string $key + * @param string|null $expectedFlattenData + * @return void + * @dataProvider getDataProvider + */ + public function testGet(string $key, $expectedFlattenData) + { + $flatData = [ + 'key1' => 'value', + 'key2' => null, + ]; + + $this->reader->expects($this->once())->method('load')->willReturn($flatData); + + $this->assertEquals($expectedFlattenData, $this->_deploymentConfig->get($key)); + } + + /** + * @return array + */ + public function getDataProvider(): array + { + return [ + [ + 'key' => 'key1', + 'expectedFlattenData' => 'value', + ], + [ + 'key' => 'key2', + 'expectedFlattenData' => '', + ], + [ + 'key' => 'key3', + 'expectedFlattenData' => null, + ], + ]; + } } diff --git a/lib/internal/Magento/Framework/Data/Collection.php b/lib/internal/Magento/Framework/Data/Collection.php index 099753ac1b56f..4e9132d49a2e2 100644 --- a/lib/internal/Magento/Framework/Data/Collection.php +++ b/lib/internal/Magento/Framework/Data/Collection.php @@ -7,6 +7,7 @@ use Magento\Framework\Data\Collection\EntityFactoryInterface; use Magento\Framework\Option\ArrayInterface; +use Magento\Framework\Exception\InputException; /** * Data collection @@ -234,12 +235,20 @@ protected function _setIsLoaded($flag = true) * Get current collection page * * @param int $displacement + * @throws \Magento\Framework\Exception\InputException * @return int */ public function getCurPage($displacement = 0) { if ($this->_curPage + $displacement < 1) { return 1; + } elseif ($this->_curPage > $this->getLastPageNumber() && $displacement === 0) { + throw new InputException( + __( + 'currentPage value %1 specified is greater than the %2 page(s) available.', + [$this->_curPage, $this->getLastPageNumber()] + ) + ); } elseif ($this->_curPage + $displacement > $this->getLastPageNumber()) { return $this->getLastPageNumber(); } else { diff --git a/lib/internal/Magento/Framework/Data/Test/Unit/CollectionTest.php b/lib/internal/Magento/Framework/Data/Test/Unit/CollectionTest.php index 2ecc67e1eb70e..0b6ddd6999d3e 100644 --- a/lib/internal/Magento/Framework/Data/Test/Unit/CollectionTest.php +++ b/lib/internal/Magento/Framework/Data/Test/Unit/CollectionTest.php @@ -7,6 +7,9 @@ // @codingStandardsIgnoreFile +/** + * Class for Collection test. + */ class CollectionTest extends \PHPUnit\Framework\TestCase { /** @@ -14,6 +17,9 @@ class CollectionTest extends \PHPUnit\Framework\TestCase */ protected $_model; + /** + * @inheritdoc + */ protected function setUp() { $this->_model = new \Magento\Framework\Data\Collection( @@ -21,6 +27,11 @@ protected function setUp() ); } + /** + * Test for method removeAllItems. + * + * @return void + */ public function testRemoveAllItems() { $this->_model->addItem(new \Magento\Framework\DataObject()); @@ -32,6 +43,7 @@ public function testRemoveAllItems() /** * Test loadWithFilter() + * * @return void */ public function testLoadWithFilter() @@ -44,6 +56,8 @@ public function testLoadWithFilter() } /** + * Test for method etItemObjectClass. + * * @dataProvider setItemObjectClassDataProvider */ public function testSetItemObjectClass($class) @@ -53,6 +67,8 @@ public function testSetItemObjectClass($class) } /** + * Data provider. + * * @return array */ public function setItemObjectClassDataProvider() @@ -61,6 +77,8 @@ public function setItemObjectClassDataProvider() } /** + * Test for method setItemObjectClass with exception. + * * @expectedException \InvalidArgumentException * @expectedExceptionMessage Incorrect_ClassName does not extend \Magento\Framework\DataObject */ @@ -69,12 +87,22 @@ public function testSetItemObjectClassException() $this->_model->setItemObjectClass('Incorrect_ClassName'); } + /** + * Test for method addFilter. + * + * @return void + */ public function testAddFilter() { $this->_model->addFilter('field1', 'value'); $this->assertEquals('field1', $this->_model->getFilter('field1')->getData('field')); } + /** + * Test for method getFilters. + * + * @return void + */ public function testGetFilters() { $this->_model->addFilter('field1', 'value'); @@ -83,12 +111,22 @@ public function testGetFilters() $this->assertEquals('field2', $this->_model->getFilter(['field1', 'field2'])[1]->getData('field')); } + /** + * Test for method get non existion filters. + * + * @return void + */ public function testGetNonExistingFilters() { $this->assertEmpty($this->_model->getFilter([])); $this->assertEmpty($this->_model->getFilter('non_existing_filter')); } + /** + * Test for lag. + * + * @return void + */ public function testFlag() { $this->_model->setFlag('flag_name', 'flag_value'); @@ -97,12 +135,35 @@ public function testFlag() $this->assertNull($this->_model->getFlag('non_existing_flag')); } + /** + * Test for method getCurPage. + * + * @return void + */ public function testGetCurPage() { - $this->_model->setCurPage(10); + $this->_model->setCurPage(1); $this->assertEquals(1, $this->_model->getCurPage()); } + /** + * Test for getCurPage with exception. + * + * @expectedException \Magento\Framework\Exception\InputException + * @expectedExceptionMessage currentPage value 10 specified is greater than the 1 page(s) available. + * @return void + */ + public function testGetCurPageWithException() + { + $this->_model->setCurPage(10); + $this->_model->getCurPage(); + } + + /** + * Test for method possibleFlowWithItem. + * + * @return void + */ public function testPossibleFlowWithItem() { $firstItemMock = $this->createPartialMock(\Magento\Framework\DataObject::class, ['getId', 'getData', 'toArray']); @@ -164,6 +225,11 @@ public function testPossibleFlowWithItem() $this->assertEquals([], $this->_model->getItems()); } + /** + * Test for method eachCallsMethodOnEachItemWithNoArgs. + * + * @return void + */ public function testEachCallsMethodOnEachItemWithNoArgs() { for ($i = 0; $i < 3; $i++) { @@ -173,7 +239,12 @@ public function testEachCallsMethodOnEachItemWithNoArgs() } $this->_model->each('testCallback'); } - + + /** + * Test for method eachCallsMethodOnEachItemWithArgs. + * + * @return void + */ public function testEachCallsMethodOnEachItemWithArgs() { for ($i = 0; $i < 3; $i++) { @@ -184,6 +255,11 @@ public function testEachCallsMethodOnEachItemWithArgs() $this->_model->each('testCallback', ['a', 'b', 'c']); } + /** + * Test for method callsClosureWithEachItemAndNoArgs. + * + * @return void + */ public function testCallsClosureWithEachItemAndNoArgs() { for ($i = 0; $i < 3; $i++) { @@ -196,6 +272,11 @@ public function testCallsClosureWithEachItemAndNoArgs() }); } + /** + * Test for method callsClosureWithEachItemAndArgs. + * + * @return void + */ public function testCallsClosureWithEachItemAndArgs() { for ($i = 0; $i < 3; $i++) { @@ -208,6 +289,11 @@ public function testCallsClosureWithEachItemAndArgs() }, ['a', 'b', 'c']); } + /** + * Test for method callsCallableArrayWithEachItemNoArgs. + * + * @return void + */ public function testCallsCallableArrayWithEachItemNoArgs() { $mockCallbackObject = $this->getMockBuilder('DummyEachCallbackInstance') @@ -226,6 +312,11 @@ public function testCallsCallableArrayWithEachItemNoArgs() $this->_model->each([$mockCallbackObject, 'testObjCallback']); } + /** + * Test for method callsCallableArrayWithEachItemAndArgs. + * + * @return void + */ public function testCallsCallableArrayWithEachItemAndArgs() { $mockCallbackObject = $this->getMockBuilder('DummyEachCallbackInstance')