From 90395fe7c4ed7bb27302895b9dcb641d6e714d09 Mon Sep 17 00:00:00 2001 From: Valeriy Nayda Date: Wed, 6 Sep 2017 17:19:56 +0300 Subject: [PATCH] MSI: Web api of stock source links management --- .../Api/AssignSourcesToStockInterface.php | 6 +- .../GetAssignedSourcesForStockInterface.php | 2 + .../Api/UnassignSourceFromStockInterface.php | 5 +- .../AssignSourcesToStockTest.php | 166 ++++++++++++++++++ .../GetAssignedSourcesForStockTest.php | 76 ++++++++ .../UnassignSourceFromStockTest.php | 140 +++++++++++++++ app/code/Magento/InventoryApi/etc/acl.xml | 3 +- app/code/Magento/InventoryApi/etc/webapi.xml | 19 ++ 8 files changed, 413 insertions(+), 4 deletions(-) create mode 100644 app/code/Magento/InventoryApi/Test/Api/StockSourceLink/AssignSourcesToStockTest.php create mode 100644 app/code/Magento/InventoryApi/Test/Api/StockSourceLink/GetAssignedSourcesForStockTest.php create mode 100644 app/code/Magento/InventoryApi/Test/Api/StockSourceLink/UnassignSourceFromStockTest.php diff --git a/app/code/Magento/InventoryApi/Api/AssignSourcesToStockInterface.php b/app/code/Magento/InventoryApi/Api/AssignSourcesToStockInterface.php index 808574cc9314..3fc5b85f6ecd 100644 --- a/app/code/Magento/InventoryApi/Api/AssignSourcesToStockInterface.php +++ b/app/code/Magento/InventoryApi/Api/AssignSourcesToStockInterface.php @@ -6,7 +6,7 @@ namespace Magento\InventoryApi\Api; /** - * Interface to assign source id list by stock id + * Assign Sources to Stock * * Used fully qualified namespaces in annotations for proper work of WebApi request parser * @@ -15,7 +15,9 @@ interface AssignSourcesToStockInterface { /** - * Assign source id list by stock id + * Assign Sources to Stock + * + * If one of the Sources or Stock with given id don't exist then exception will be throw * * @param int[] $sourceIds * @param int $stockId diff --git a/app/code/Magento/InventoryApi/Api/GetAssignedSourcesForStockInterface.php b/app/code/Magento/InventoryApi/Api/GetAssignedSourcesForStockInterface.php index 4fb481715190..a23dbccfa497 100644 --- a/app/code/Magento/InventoryApi/Api/GetAssignedSourcesForStockInterface.php +++ b/app/code/Magento/InventoryApi/Api/GetAssignedSourcesForStockInterface.php @@ -17,6 +17,8 @@ interface GetAssignedSourcesForStockInterface /** * Get Sources assigned to Stock * + * If Stock with given id doesn't exist then return an empty array + * * @param int $stockId * @return \Magento\InventoryApi\Api\Data\SourceInterface[] * @throws \Magento\Framework\Exception\InputException diff --git a/app/code/Magento/InventoryApi/Api/UnassignSourceFromStockInterface.php b/app/code/Magento/InventoryApi/Api/UnassignSourceFromStockInterface.php index c60e96414336..d1c09f1b0443 100644 --- a/app/code/Magento/InventoryApi/Api/UnassignSourceFromStockInterface.php +++ b/app/code/Magento/InventoryApi/Api/UnassignSourceFromStockInterface.php @@ -6,7 +6,7 @@ namespace Magento\InventoryApi\Api; /** - * Unassign source from stock + * Unassign Source from Stock * * Used fully qualified namespaces in annotations for proper work of WebApi request parser * @@ -17,10 +17,13 @@ interface UnassignSourceFromStockInterface /** * Unassign source from stock * + * If Source or Stock with given id doesn't exist then do nothing + * * @param int $sourceId * @param int $stockId * @return void * @throws \Magento\Framework\Exception\InputException + * @throws \Magento\Framework\Exception\CouldNotDeleteException */ public function execute($sourceId, $stockId); } diff --git a/app/code/Magento/InventoryApi/Test/Api/StockSourceLink/AssignSourcesToStockTest.php b/app/code/Magento/InventoryApi/Test/Api/StockSourceLink/AssignSourcesToStockTest.php new file mode 100644 index 000000000000..b8ae2d734bfb --- /dev/null +++ b/app/code/Magento/InventoryApi/Test/Api/StockSourceLink/AssignSourcesToStockTest.php @@ -0,0 +1,166 @@ + [ + 'resourcePath' => self::RESOURCE_PATH_ASSIGN_SOURCES_TO_STOCK . '/' . $stockId, + 'httpMethod' => Request::HTTP_METHOD_POST, + ], + 'soap' => [ + 'service' => self::SERVICE_NAME_ASSIGN_SOURCES_TO_STOCK, + 'operation' => self::SERVICE_NAME_ASSIGN_SOURCES_TO_STOCK . 'Execute', + ], + ]; + (TESTS_WEB_API_ADAPTER == self::ADAPTER_REST) + ? $this->_webApiCall($serviceInfo, ['sourceIds' => $sourceIds]) + : $this->_webApiCall($serviceInfo, ['sourceIds' => $sourceIds, 'stockId' => $stockId]); + + $assignedSourcesForStock = $this->getAssignedSourcesForStock($stockId); + self::assertEquals($sourceIds, array_column($assignedSourcesForStock, SourceInterface::SOURCE_ID)); + } + + /** + * @magentoApiDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/sources.php + * @magentoApiDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/stock.php + * @param string|array $sourceIds + * @param string|int $stockId + * @param array $expectedErrorData + * @throws \Exception + * @dataProvider dataProviderWrongParameters + */ + public function testAssignSourcesToStockWithWrongParameters($sourceIds, $stockId, array $expectedErrorData) + { + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => self::RESOURCE_PATH_ASSIGN_SOURCES_TO_STOCK . '/' . $stockId, + 'httpMethod' => Request::HTTP_METHOD_POST, + ], + 'soap' => [ + 'service' => self::SERVICE_NAME_ASSIGN_SOURCES_TO_STOCK, + 'operation' => self::SERVICE_NAME_ASSIGN_SOURCES_TO_STOCK . 'Execute', + ], + ]; + try { + (TESTS_WEB_API_ADAPTER == self::ADAPTER_REST) + ? $this->_webApiCall($serviceInfo, ['sourceIds' => $sourceIds]) + : $this->_webApiCall($serviceInfo, ['sourceIds' => $sourceIds, 'stockId' => $stockId]); + $this->fail('Expected throwing exception'); + } catch (\Exception $e) { + if (TESTS_WEB_API_ADAPTER == self::ADAPTER_REST) { + $errorData = $this->processRestExceptionResult($e); + self::assertEquals($expectedErrorData['rest_message'], $errorData['message']); + self::assertEquals(Exception::HTTP_BAD_REQUEST, $e->getCode()); + } elseif (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) { + $this->assertInstanceOf('SoapFault', $e); + $this->checkSoapFault( + $e, + $expectedErrorData['soap_message'], + 'env:Sender' + ); + } else { + throw $e; + } + } + } + + /** + * @return array + */ + public function dataProviderWrongParameters() + { + return [ + 'not_numeric_stock_id' => [ + [1, 2], + 'not_numeric', + [ + 'rest_message' => 'Invalid type for value: "not_numeric". Expected Type: "int".', + // During SOAP stock_id parameter will be converted to zero so error is different + 'soap_message' => 'Could not assign Sources to Stock', + ], + ], + 'nonexistent_stock_id' => [ + [1, 2], + -1, + [ + 'rest_message' => 'Could not assign Sources to Stock', + 'soap_message' => 'Could not assign Sources to Stock', + ], + ], + 'not_array_source_ids' => [ + 'not_array', + 1, + [ + 'rest_message' => 'Invalid type for value: "string". Expected Type: "int[]".', + // During SOAP source_ids parameter will be converted to empty array so error is different + 'soap_message' => 'Input data is invalid', + ], + ], + 'empty_source_ids' => [ + [], + 1, + [ + 'rest_message' => 'Input data is invalid', + 'soap_message' => 'Input data is invalid', + ], + ], + 'nonexistent_source_id' => [ + [-1, 2], + 1, + [ + 'rest_message' => 'Could not assign Sources to Stock', + 'soap_message' => 'Could not assign Sources to Stock', + ], + ], + ]; + } + + /** + * @param int $stockId + * @return array + */ + private function getAssignedSourcesForStock(int $stockId) + { + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => self::RESOURCE_PATH_GET_ASSIGNED_SOURCES_FOR_STOCK . '/' . $stockId, + 'httpMethod' => Request::HTTP_METHOD_GET, + ], + 'soap' => [ + 'service' => self::SERVICE_NAME_GET_ASSIGNED_SOURCES_FOR_STOCK, + 'operation' => self::SERVICE_NAME_GET_ASSIGNED_SOURCES_FOR_STOCK . 'Execute', + ], + ]; + $response = (TESTS_WEB_API_ADAPTER == self::ADAPTER_REST) + ? $this->_webApiCall($serviceInfo) + : $this->_webApiCall($serviceInfo, ['stockId' => $stockId]); + return $response; + } +} diff --git a/app/code/Magento/InventoryApi/Test/Api/StockSourceLink/GetAssignedSourcesForStockTest.php b/app/code/Magento/InventoryApi/Test/Api/StockSourceLink/GetAssignedSourcesForStockTest.php new file mode 100644 index 000000000000..dc3d8a7b7631 --- /dev/null +++ b/app/code/Magento/InventoryApi/Test/Api/StockSourceLink/GetAssignedSourcesForStockTest.php @@ -0,0 +1,76 @@ + [ + 'resourcePath' => self::RESOURCE_PATH_GET_ASSIGNED_SOURCES_FOR_STOCK . '/' . $stockId, + 'httpMethod' => Request::HTTP_METHOD_GET, + ], + 'soap' => [ + 'service' => self::SERVICE_NAME_GET_ASSIGNED_SOURCES_FOR_STOCK, + 'operation' => self::SERVICE_NAME_GET_ASSIGNED_SOURCES_FOR_STOCK . 'Execute', + ], + ]; + $response = (TESTS_WEB_API_ADAPTER == self::ADAPTER_REST) + ? $this->_webApiCall($serviceInfo) + : $this->_webApiCall($serviceInfo, ['stockId' => $stockId]); + self::assertEquals([1, 2], array_column($response, SourceInterface::SOURCE_ID)); + } + + /** + * @magentoApiDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/sources.php + * @magentoApiDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/stocks.php + * @magentoApiDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/stock_source_link.php + */ + public function testGetAssignedSourcesWithNotNumericStockId() + { + if (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) { + $this->markTestSkipped( + 'Test works only for REST adapter because in SOAP one stock_id would be converted' + . ' into zero (zero is allowed input for service ner mind it\'s illigible value as' + . ' there are no Stocks in the system with stock_id given)' + ); + } + $stockId = 'not_numeric'; + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => self::RESOURCE_PATH_GET_ASSIGNED_SOURCES_FOR_STOCK . '/' . $stockId, + 'httpMethod' => Request::HTTP_METHOD_GET, + ], + ]; + try { + $this->_webApiCall($serviceInfo); + $this->fail('Expected throwing exception'); + } catch (\Exception $e) { + $errorData = $this->processRestExceptionResult($e); + self::assertEquals('Invalid type for value: "not_numeric". Expected Type: "int".', $errorData['message']); + self::assertEquals(Exception::HTTP_BAD_REQUEST, $e->getCode()); + } + } +} diff --git a/app/code/Magento/InventoryApi/Test/Api/StockSourceLink/UnassignSourceFromStockTest.php b/app/code/Magento/InventoryApi/Test/Api/StockSourceLink/UnassignSourceFromStockTest.php new file mode 100644 index 000000000000..a2ab52b560a7 --- /dev/null +++ b/app/code/Magento/InventoryApi/Test/Api/StockSourceLink/UnassignSourceFromStockTest.php @@ -0,0 +1,140 @@ + [ + 'resourcePath' => self::RESOURCE_PATH_UNASSIGN_SOURCES_FROM_STOCK . '/' . $stockId . '/' . $sourceId, + 'httpMethod' => Request::HTTP_METHOD_DELETE, + ], + 'soap' => [ + 'service' => self::SERVICE_NAME_UNASSIGN_SOURCES_FROM_STOCK, + 'operation' => self::SERVICE_NAME_UNASSIGN_SOURCES_FROM_STOCK . 'Execute', + ], + ]; + (TESTS_WEB_API_ADAPTER == self::ADAPTER_REST) + ? $this->_webApiCall($serviceInfo) + : $this->_webApiCall($serviceInfo, ['sourceId' => $sourceId, 'stockId' => $stockId]); + + $assignedSourcesForStock = $this->getAssignedSourcesForStock($stockId); + self::assertEquals([2], array_column($assignedSourcesForStock, SourceInterface::SOURCE_ID)); + } + + /** + * @magentoApiDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/sources.php + * @magentoApiDataFixture ../../../../app/code/Magento/InventoryApi/Test/_files/stock.php + * @param string|int $sourceId + * @param string|int $stockId + * @param array $expectedErrorData + * @throws \Exception + * @dataProvider dataProviderWrongParameters + */ + public function testUnassignSourceFromStockWithWrongParameters($sourceId, $stockId, array $expectedErrorData) + { + if (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) { + $this->markTestSkipped( + 'Test works only for REST adapter because in SOAP one source_id/stock_id would be converted' + . ' into zero (zero is allowed input for service ner mind it\'s illigible value as' + . ' there are no Sources(Stocks) in the system with source_id/stock_id given)' + ); + } + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => self::RESOURCE_PATH_UNASSIGN_SOURCES_FROM_STOCK . '/' . $stockId . '/' . $sourceId, + 'httpMethod' => Request::HTTP_METHOD_DELETE, + ], + ]; + try { + $this->_webApiCall($serviceInfo); + $this->fail('Expected throwing exception'); + } catch (\Exception $e) { + $errorData = $this->processRestExceptionResult($e); + self::assertEquals($expectedErrorData['rest_message'], $errorData['message']); + self::assertEquals(Exception::HTTP_BAD_REQUEST, $e->getCode()); + } + } + + /** + * @return array + */ + public function dataProviderWrongParameters() + { + return [ + 'not_numeric_stock_id' => [ + 1, + 'not_numeric', + [ + 'message' => 'Invalid type for value: "not_numeric". Expected Type: "int".', + ], + ], + 'not_numeric_source_id' => [ + 'not_numeric', + 1, + [ + 'message' => 'Invalid type for value: "not_numeric". Expected Type: "int".', + ], + ], + ]; + } + + /** + * @param int $stockId + * @return array + */ + private function getAssignedSourcesForStock(int $stockId) + { + $serviceInfo = [ + 'rest' => [ + 'resourcePath' => self::RESOURCE_PATH_GET_ASSIGNED_SOURCES_FOR_STOCK . '/' . $stockId, + 'httpMethod' => Request::HTTP_METHOD_GET, + ], + 'soap' => [ + 'service' => self::SERVICE_NAME_GET_ASSIGNED_SOURCES_FOR_STOCK, + 'operation' => self::SERVICE_NAME_GET_ASSIGNED_SOURCES_FOR_STOCK . 'Execute', + ], + ]; + $response = (TESTS_WEB_API_ADAPTER == self::ADAPTER_REST) + ? $this->_webApiCall($serviceInfo) + : $this->_webApiCall($serviceInfo, ['stockId' => $stockId]); + return $response; + } +} diff --git a/app/code/Magento/InventoryApi/etc/acl.xml b/app/code/Magento/InventoryApi/etc/acl.xml index 222f09d261a3..388346fd6a6a 100644 --- a/app/code/Magento/InventoryApi/etc/acl.xml +++ b/app/code/Magento/InventoryApi/etc/acl.xml @@ -14,7 +14,8 @@ - + + diff --git a/app/code/Magento/InventoryApi/etc/webapi.xml b/app/code/Magento/InventoryApi/etc/webapi.xml index 8acadfa08def..92548c284992 100644 --- a/app/code/Magento/InventoryApi/etc/webapi.xml +++ b/app/code/Magento/InventoryApi/etc/webapi.xml @@ -63,4 +63,23 @@ + + + + + + + + + + + + + + + + + + +