diff --git a/app/code/Magento/Customer/Model/Customer/DataProvider.php b/app/code/Magento/Customer/Model/Customer/DataProvider.php index 128ccedaf2b5277371680570b8e82fc88f95a2e2..777a78cb6fa05508712a9c07f4b8f7775ec45029 100644 --- a/app/code/Magento/Customer/Model/Customer/DataProvider.php +++ b/app/code/Magento/Customer/Model/Customer/DataProvider.php @@ -9,7 +9,7 @@ use Magento\Eav\Model\Config; use Magento\Eav\Model\Entity\Type; use Magento\Customer\Model\Address; use Magento\Customer\Model\Customer; -use Magento\Ui\DataProvider\EavValidationRul; +use Magento\Ui\DataProvider\EavValidationRules; use Magento\Customer\Model\Resource\Customer\Collection; use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface; use Magento\Customer\Model\Resource\Customer\CollectionFactory as CustomerCollectionFactory; @@ -75,7 +75,7 @@ class DataProvider implements DataProviderInterface 'sortOrder' => 'sort_order', 'notice' => 'note', 'default' => 'default_value', - 'size' => 'scope_multiline_count' + 'size' => 'multiline_count' ]; /** @@ -90,9 +90,9 @@ class DataProvider implements DataProviderInterface ]; /** - * @var EavValidationRul + * @var EavValidationRules */ - protected $eavValidationRul; + protected $eavValidationRules; /** * Constructor @@ -100,7 +100,7 @@ class DataProvider implements DataProviderInterface * @param string $name * @param string $primaryFieldName * @param string $requestFieldName - * @param EavValidationRul $eavValidationRul + * @param EavValidationRules $eavValidationRules * @param CustomerCollectionFactory $customerCollectionFactory * @param Config $eavConfig * @param array $meta @@ -110,7 +110,7 @@ class DataProvider implements DataProviderInterface $name, $primaryFieldName, $requestFieldName, - EavValidationRul $eavValidationRul, + EavValidationRules $eavValidationRules, CustomerCollectionFactory $customerCollectionFactory, Config $eavConfig, array $meta = [], @@ -119,7 +119,7 @@ class DataProvider implements DataProviderInterface $this->name = $name; $this->primaryFieldName = $primaryFieldName; $this->requestFieldName = $requestFieldName; - $this->eavValidationRul = $eavValidationRul; + $this->eavValidationRules = $eavValidationRules; $this->collection = $customerCollectionFactory->create(); $this->collection->addAttributeToSelect('*'); $this->eavConfig = $eavConfig; @@ -223,6 +223,7 @@ class DataProvider implements DataProviderInterface * @param string|array $field * @param string|null $alias * @return void + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function addField($field, $alias = null) { @@ -260,6 +261,7 @@ class DataProvider implements DataProviderInterface * @param string|null $field * @param bool $isAlias Alias identifier * @return void + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function removeField($field, $isAlias = false) { @@ -369,7 +371,7 @@ class DataProvider implements DataProviderInterface } } - $rules = $this->eavValidationRul->build($attribute, $meta[$code]); + $rules = $this->eavValidationRules->build($attribute, $meta[$code]); if (!empty($rules)) { $meta[$code]['validation'] = $rules; } diff --git a/app/code/Magento/Customer/Test/Unit/Model/Customer/DataProviderTest.php b/app/code/Magento/Customer/Test/Unit/Model/Customer/DataProviderTest.php new file mode 100644 index 0000000000000000000000000000000000000000..eab40c46f84bbc63098fe6222250db2ecd9ed2d7 --- /dev/null +++ b/app/code/Magento/Customer/Test/Unit/Model/Customer/DataProviderTest.php @@ -0,0 +1,249 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Customer\Test\Unit\Model\Customer; + +use Magento\Eav\Model\Config; +use Magento\Eav\Model\Entity\Type; +use Magento\Framework\TestFramework\Unit\Helper\ObjectManager; +use Magento\Ui\DataProvider\EavValidationRules; +use Magento\Customer\Model\Customer\DataProvider; +use Magento\Eav\Model\Entity\Attribute\AbstractAttribute; +use Magento\Customer\Model\Resource\Customer\CollectionFactory; + +/** + * Class DataProviderTest + * + * Test for class \Magento\Customer\Model\Customer\DataProvider + */ +class DataProviderTest extends \PHPUnit_Framework_TestCase +{ + const ATTRIBUTE_CODE = 'test-code'; + const OPTIONS_RESULT = 'test-options'; + + /** + * @var Config|\PHPUnit_Framework_MockObject_MockObject + */ + protected $eavConfigMock; + + /** + * @var CollectionFactory|\PHPUnit_Framework_MockObject_MockObject + */ + protected $customerCollectionFactoryMock; + + /** + * @var EavValidationRules|\PHPUnit_Framework_MockObject_MockObject + */ + protected $eavValidationRulesMock; + + /** + * Set up + * + * @return void + */ + protected function setUp() + { + $this->eavConfigMock = $this->getMockBuilder('Magento\Eav\Model\Config') + ->disableOriginalConstructor() + ->getMock(); + $this->customerCollectionFactoryMock = $this->getMock( + 'Magento\Customer\Model\Resource\Customer\CollectionFactory', + ['create'], + [], + '', + false + ); + $this->eavValidationRulesMock = $this + ->getMockBuilder('Magento\Ui\DataProvider\EavValidationRules') + ->disableOriginalConstructor() + ->getMock(); + } + + /** + * Run test getAttributesMeta method + * + * @param array $expected + * @return void + * + * @dataProvider getAttributesMetaDataProvider + */ + public function testGetAttributesMetaWithOptions(array $expected) + { + $helper = new ObjectManager($this); + $dataProvider = $helper->getObject( + '\Magento\Customer\Model\Customer\DataProvider', + [ + 'name' => 'test-name', + 'primaryFieldName' => 'primary-field-name', + 'requestFieldName' => 'request-field-name', + 'eavValidationRules' => $this->eavValidationRulesMock, + 'customerCollectionFactory' => $this->getCustomerCollectionFactoryMock(), + 'eavConfig' => $this->getEavConfigMock() + ] + ); + + $meta = $dataProvider->getMeta(); + $this->assertNotEmpty($meta); + $this->assertEquals($expected, $meta); + } + + /** + * Data provider for testGetAttributesMeta + * + * @return array + */ + public function getAttributesMetaDataProvider() + { + return [ + [ + 'expected' => [ + 'customer' => [ + 'fields' => [ + self::ATTRIBUTE_CODE => [ + 'dataType' => 'frontend_input', + 'formElement' => 'frontend_input', + 'options' => 'test-options', + 'visible' => 'is_visible', + 'required' => 'is_required', + 'label' => 'frontend_label', + 'sortOrder' => 'sort_order', + 'notice' => 'note', + 'default' => 'default_value', + 'size' => 'multiline_count', + ] + ] + ], + 'address' => [ + 'fields' => [ + self::ATTRIBUTE_CODE => [ + 'dataType' => 'frontend_input', + 'formElement' => 'frontend_input', + 'options' => 'test-options', + 'visible' => 'is_visible', + 'required' => 'is_required', + 'label' => 'frontend_label', + 'sortOrder' => 'sort_order', + 'notice' => 'note', + 'default' => 'default_value', + 'size' => 'multiline_count', + ] + ] + ] + ] + ] + ]; + } + + /** + * @return CollectionFactory|\PHPUnit_Framework_MockObject_MockObject + */ + protected function getCustomerCollectionFactoryMock() + { + $collectionMock = $this->getMockBuilder('Magento\Customer\Model\Resource\Customer\Collection') + ->disableOriginalConstructor() + ->getMock(); + + $collectionMock->expects($this->once()) + ->method('addAttributeToSelect') + ->with('*'); + + $this->customerCollectionFactoryMock->expects($this->once()) + ->method('create') + ->willReturn($collectionMock); + + return $this->customerCollectionFactoryMock; + } + + /** + * @return Config|\PHPUnit_Framework_MockObject_MockObject + */ + protected function getEavConfigMock() + { + $this->eavConfigMock->expects($this->at(0)) + ->method('getEntityType') + ->with('customer') + ->willReturn($this->getTypeCustomerMock()); + $this->eavConfigMock->expects($this->at(1)) + ->method('getEntityType') + ->with('customer_address') + ->willReturn($this->getTypeAddressMock()); + + return $this->eavConfigMock; + } + + /** + * @return Type|\PHPUnit_Framework_MockObject_MockObject + */ + protected function getTypeCustomerMock() + { + $typeCustomerMock = $this->getMockBuilder('Magento\Eav\Model\Entity\Type') + ->disableOriginalConstructor() + ->getMock(); + + $typeCustomerMock->expects($this->once()) + ->method('getAttributeCollection') + ->willReturn($this->getAttributeMock()); + + return $typeCustomerMock; + } + + /** + * @return Type|\PHPUnit_Framework_MockObject_MockObject + */ + protected function getTypeAddressMock() + { + $typeAddressMock = $this->getMockBuilder('Magento\Eav\Model\Entity\Type') + ->disableOriginalConstructor() + ->getMock(); + + $typeAddressMock->expects($this->once()) + ->method('getAttributeCollection') + ->willReturn($this->getAttributeMock()); + + return $typeAddressMock; + } + + /** + * @return AbstractAttribute[]|\PHPUnit_Framework_MockObject_MockObject[] + */ + protected function getAttributeMock() + { + $attributeMock = $this->getMockBuilder('Magento\Eav\Model\Entity\Attribute\AbstractAttribute') + ->setMethods(['getAttributeCode', 'getDataUsingMethod', 'usesSource', 'getSource']) + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + $sourceMock = $this->getMockBuilder('Magento\Eav\Model\Entity\Attribute\Source\AbstractSource') + ->disableOriginalConstructor() + ->getMockForAbstractClass(); + + $sourceMock->expects($this->any()) + ->method('getAllOptions') + ->willReturn(self::OPTIONS_RESULT); + + $attributeMock->expects($this->once()) + ->method('getAttributeCode') + ->willReturn(self::ATTRIBUTE_CODE); + + $attributeMock->expects($this->any()) + ->method('getDataUsingMethod') + ->willReturnCallback( + function ($origName) { + return $origName; + } + ); + $attributeMock->expects($this->any()) + ->method('usesSource') + ->willReturn(true); + $attributeMock->expects($this->any()) + ->method('getSource') + ->willReturn($sourceMock); + + $this->eavValidationRulesMock->expects($this->any()) + ->method('build') + ->with($attributeMock, $this->logicalNot($this->isEmpty())); + + return [$attributeMock]; + } +} diff --git a/app/code/Magento/Payment/Gateway/Command/CommandException.php b/app/code/Magento/Payment/Gateway/Command/CommandException.php new file mode 100644 index 0000000000000000000000000000000000000000..7c4409fb42e62ff9a8afc3a5356891e3ffd3172b --- /dev/null +++ b/app/code/Magento/Payment/Gateway/Command/CommandException.php @@ -0,0 +1,13 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Payment\Gateway\Command; + +use Magento\Framework\Exception\LocalizedException; + +class CommandException extends LocalizedException +{ + +} diff --git a/app/code/Magento/Payment/Gateway/Command/GatewayCommand.php b/app/code/Magento/Payment/Gateway/Command/GatewayCommand.php index a6044462cded037192b2ca675ba06ce32e89549c..b04491622d4ba58b1a54b257388e38f82ba1515b 100644 --- a/app/code/Magento/Payment/Gateway/Command/GatewayCommand.php +++ b/app/code/Magento/Payment/Gateway/Command/GatewayCommand.php @@ -52,8 +52,8 @@ class GatewayCommand implements CommandInterface BuilderInterface $requestBuilder, TransferFactoryInterface $transferFactory, ClientInterface $client, - HandlerInterface $handler, - ValidatorInterface $validator + HandlerInterface $handler = null, + ValidatorInterface $validator = null ) { $this->requestBuilder = $requestBuilder; $this->transferFactory = $transferFactory; @@ -67,6 +67,7 @@ class GatewayCommand implements CommandInterface * * @param array $commandSubject * @return null + * @throws \Exception */ public function execute(array $commandSubject) { @@ -76,16 +77,22 @@ class GatewayCommand implements CommandInterface ); $response = $this->client->placeRequest($transferO); - - $result = $this->validator->validate(array_merge($commandSubject, ['response' => $response])); - if ($result !== null && !$result->isValid()) { - $commandSubject['payment']->getPayment()->setIsTransactionPending(true); - return; + if ($this->validator) { + $result = $this->validator->validate( + array_merge($commandSubject, ['response' => $response]) + ); + if (!$result->isValid()) { + throw new CommandException( + __(implode("\n", $result->getFailsDescription())) + ); + } } - $this->handler->handle( - $commandSubject, - $response - ); + if ($this->handler) { + $this->handler->handle( + $commandSubject, + $response + ); + } } } diff --git a/app/code/Magento/Payment/Gateway/Config/ConfigValueHandler.php b/app/code/Magento/Payment/Gateway/Config/ConfigValueHandler.php index 17566610aa29e171681ff4ade6829053e0a49c51..4811a6426816a538f702db7e0b1d9cfea0dd9a7c 100644 --- a/app/code/Magento/Payment/Gateway/Config/ConfigValueHandler.php +++ b/app/code/Magento/Payment/Gateway/Config/ConfigValueHandler.php @@ -6,6 +6,7 @@ namespace Magento\Payment\Gateway\Config; use Magento\Payment\Gateway\ConfigInterface; +use Magento\Payment\Gateway\Helper\SubjectReader; class ConfigValueHandler implements ValueHandlerInterface { @@ -26,13 +27,13 @@ class ConfigValueHandler implements ValueHandlerInterface /** * Retrieve method configured value * - * @param string $field + * @param array $subject * @param int|null $storeId * * @return mixed */ - public function handle($field, $storeId = null) + public function handle(array $subject, $storeId = null) { - return $this->configInterface->getValue($field, $storeId); + return $this->configInterface->getValue(SubjectReader::readField($subject), $storeId); } } diff --git a/app/code/Magento/Payment/Gateway/Config/ValueHandlerInterface.php b/app/code/Magento/Payment/Gateway/Config/ValueHandlerInterface.php index 5f857ea3cf539bceec121eb2af09120147774bb3..70e13466bfe30df92d45d4a8c8239819f497b0ea 100644 --- a/app/code/Magento/Payment/Gateway/Config/ValueHandlerInterface.php +++ b/app/code/Magento/Payment/Gateway/Config/ValueHandlerInterface.php @@ -10,10 +10,10 @@ interface ValueHandlerInterface /** * Retrieve method configured value * - * @param string $field + * @param array $subject * @param int|null $storeId * * @return mixed */ - public function handle($field, $storeId = null); + public function handle(array $subject, $storeId = null); } diff --git a/app/code/Magento/Payment/Gateway/Data/Order/OrderAdapter.php b/app/code/Magento/Payment/Gateway/Data/Order/OrderAdapter.php index f01bee1d7c77ab2b4c695ea4f00229f165e29132..f9be150d4761af45d4214edc702771444b0e5a08 100644 --- a/app/code/Magento/Payment/Gateway/Data/Order/OrderAdapter.php +++ b/app/code/Magento/Payment/Gateway/Data/Order/OrderAdapter.php @@ -106,4 +106,14 @@ class OrderAdapter implements OrderAdapterInterface { return $this->order->getEntityId(); } + + /** + * Returns order grand total amount + * + * @return float|null + */ + public function getGrandTotalAmount() + { + return $this->order->getBaseGrandTotal(); + } } diff --git a/app/code/Magento/Payment/Gateway/Data/OrderAdapterInterface.php b/app/code/Magento/Payment/Gateway/Data/OrderAdapterInterface.php index 0d925d823a9906c6d1bedbe4f488338f33493d64..c15bf289b2bfeeb0657912aec5beea99d7e36b33 100644 --- a/app/code/Magento/Payment/Gateway/Data/OrderAdapterInterface.php +++ b/app/code/Magento/Payment/Gateway/Data/OrderAdapterInterface.php @@ -55,4 +55,11 @@ interface OrderAdapterInterface * @return int */ public function getId(); + + /** + * Returns order grand total amount + * + * @return float + */ + public function getGrandTotalAmount(); } diff --git a/app/code/Magento/Payment/Gateway/Data/Quote/QuoteAdapter.php b/app/code/Magento/Payment/Gateway/Data/Quote/QuoteAdapter.php index 43a6a9ded86e61c539b5f64dfbbd89de57bc1c94..5e9ab098109729c78375d05cfbff6489e4cb1fb7 100644 --- a/app/code/Magento/Payment/Gateway/Data/Quote/QuoteAdapter.php +++ b/app/code/Magento/Payment/Gateway/Data/Quote/QuoteAdapter.php @@ -106,4 +106,14 @@ class QuoteAdapter implements OrderAdapterInterface { return $this->quote->getId(); } + + /** + * Returns order grand total amount + * + * @return null + */ + public function getGrandTotalAmount() + { + return null; + } } diff --git a/app/code/Magento/Payment/Gateway/Helper/SubjectReader.php b/app/code/Magento/Payment/Gateway/Helper/SubjectReader.php new file mode 100644 index 0000000000000000000000000000000000000000..bef0a4e463301a4ddda60ce704ea817a85f5488a --- /dev/null +++ b/app/code/Magento/Payment/Gateway/Helper/SubjectReader.php @@ -0,0 +1,58 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Payment\Gateway\Helper; + +use Magento\Payment\Gateway\Data\PaymentDataObjectInterface; + +class SubjectReader +{ + /** + * Reads payment from subject + * + * @param array $subject + * @return PaymentDataObjectInterface + */ + public static function readPayment(array $subject) + { + if (!isset($subject['payment']) + || !$subject['payment'] instanceof PaymentDataObjectInterface + ) { + throw new \InvalidArgumentException('Payment data object should be provided'); + } + + return $subject['payment']; + } + + /** + * Reads amount from subject + * + * @param array $subject + * @return mixed + */ + public static function readAmount(array $subject) + { + if (!isset($subject['amount']) || !is_numeric($subject['amount'])) { + throw new \InvalidArgumentException('Amount should be provided'); + } + + return $subject['amount']; + } + + /** + * Reads field from subject + * + * @param array $subject + * @return string + */ + public static function readField(array $subject) + { + if (!isset($subject['field']) || !is_string($subject['field'])) { + throw new \InvalidArgumentException(); + } + + return $subject['field']; + } +} diff --git a/app/code/Magento/Payment/Gateway/Http/Client/Soap.php b/app/code/Magento/Payment/Gateway/Http/Client/Soap.php new file mode 100644 index 0000000000000000000000000000000000000000..80479f0b768b2eb618f71458678a027bb8a663e3 --- /dev/null +++ b/app/code/Magento/Payment/Gateway/Http/Client/Soap.php @@ -0,0 +1,86 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Payment\Gateway\Http\Client; + +use Magento\Framework\Webapi\Soap\ClientFactory; +use Magento\Payment\Gateway\Http\ClientInterface; +use Magento\Payment\Gateway\Http\ConverterInterface; +use Magento\Payment\Gateway\Http\TransferInterface; +use Magento\Payment\Model\Method\Logger; + +class Soap implements ClientInterface +{ + /** + * @var Logger + */ + private $logger; + + /** + * @var ConverterInterface | null + */ + private $converter; + + /** + * @var ClientFactory + */ + private $clientFactory; + + /** + * @param Logger $logger + * @param ClientFactory $clientFactory + * @param ConverterInterface | null $converter + */ + public function __construct( + Logger $logger, + ClientFactory $clientFactory, + ConverterInterface $converter = null + ) { + $this->logger = $logger; + $this->converter = $converter; + $this->clientFactory = $clientFactory; + } + + /** + * Places request to gateway. Returns result as ENV array + * + * @param TransferInterface $transferObject + * @return array + * @throws \Magento\Payment\Gateway\Http\ClientException + * @throws \Magento\Payment\Gateway\Http\ConverterException + * @throws \Exception + */ + public function placeRequest(TransferInterface $transferObject) + { + $this->logger->debug(['request' => $transferObject->getBody()]); + + $client = $this->clientFactory->create( + $transferObject->getClientConfig()['wsdl'], + ['trace' => true] + ); + + try { + $client->__setSoapHeaders($transferObject->getHeaders()); + + $response = $client->__soapCall( + $transferObject->getMethod(), + [$transferObject->getBody()] + ); + + $result = $this->converter + ? $this->converter->convert( + $response + ) + : [$response]; + + $this->logger->debug(['response' => $result]); + } catch (\Exception $e) { + $this->logger->debug(['trace' => $client->__getLastRequest()]); + throw $e; + } + + return $result; + } +} diff --git a/app/code/Magento/Payment/Gateway/Http/Client/Zend.php b/app/code/Magento/Payment/Gateway/Http/Client/Zend.php index 0ea8ffbc871b8e49261c641a5bb71e3669e830d2..0415aab562b97e92f742315a48eca0ace2d56a9e 100644 --- a/app/code/Magento/Payment/Gateway/Http/Client/Zend.php +++ b/app/code/Magento/Payment/Gateway/Http/Client/Zend.php @@ -9,6 +9,7 @@ use Magento\Framework\HTTP\ZendClientFactory; use Magento\Framework\HTTP\ZendClient; use Magento\Payment\Gateway\Http\ClientInterface; use Magento\Payment\Gateway\Http\ConverterInterface; +use Magento\Payment\Gateway\Http\TransferInterface; use Magento\Payment\Model\Method\Logger; class Zend implements ClientInterface @@ -19,7 +20,7 @@ class Zend implements ClientInterface private $clientFactory; /** - * @var ConverterInterface + * @var ConverterInterface | null */ private $converter; @@ -30,13 +31,13 @@ class Zend implements ClientInterface /** * @param ZendClientFactory $clientFactory - * @param ConverterInterface $converter * @param Logger $logger + * @param ConverterInterface | null $converter */ public function __construct( ZendClientFactory $clientFactory, - ConverterInterface $converter, - Logger $logger + Logger $logger, + ConverterInterface $converter = null ) { $this->clientFactory = $clientFactory; $this->converter = $converter; @@ -46,10 +47,11 @@ class Zend implements ClientInterface /** * {inheritdoc} */ - public function placeRequest(\Magento\Payment\Gateway\Http\TransferInterface $transferObject) + public function placeRequest(TransferInterface $transferObject) { $log = [ - 'request' => $transferObject->getBody() + 'request' => $transferObject->getBody(), + 'request_uri' => $transferObject->getUri() ]; $result = []; /** @var ZendClient $client */ @@ -66,7 +68,12 @@ class Zend implements ClientInterface $client->setParameterPost($transferObject->getBody()); break; default: - throw new \LogicException(sprintf('Unsupported HTTP method %s', $transferObject->getMethod())); + throw new \LogicException( + sprintf( + 'Unsupported HTTP method %s', + $transferObject->getMethod() + ) + ); } $client->setHeaders($transferObject->getHeaders()); @@ -76,10 +83,14 @@ class Zend implements ClientInterface try { $response = $client->request(); - $result = $this->converter->convert($response->getBody()); + $result = $this->converter + ? $this->converter->convert($response->getBody()) + : [$response->getBody()]; $log['response'] = $result; } catch (\Zend_Http_Client_Exception $e) { - throw new \Magento\Payment\Gateway\Http\ClientException(__($e->getMessage())); + throw new \Magento\Payment\Gateway\Http\ClientException( + __($e->getMessage()) + ); } catch (\Magento\Payment\Gateway\Http\ConverterException $e) { throw $e; } finally { diff --git a/app/code/Magento/Payment/Gateway/Http/Converter/Soap/ObjectToArrayConverter.php b/app/code/Magento/Payment/Gateway/Http/Converter/Soap/ObjectToArrayConverter.php new file mode 100644 index 0000000000000000000000000000000000000000..e0045085417715e81b6251b719b6a326c63dcdbb --- /dev/null +++ b/app/code/Magento/Payment/Gateway/Http/Converter/Soap/ObjectToArrayConverter.php @@ -0,0 +1,30 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Payment\Gateway\Http\Converter\Soap; + +use Magento\Payment\Gateway\Http\ConverterInterface; + +class ObjectToArrayConverter implements ConverterInterface +{ + /** + * Converts gateway response to ENV structure + * + * @param mixed $response + * @return array + * @throws \Magento\Payment\Gateway\Http\ConverterException + */ + public function convert($response) + { + $response = (array) $response; + foreach ($response as $key => $value) { + if (is_object($value)) { + $response[$key] = $this->convert($value); + } + } + + return $response; + } +} diff --git a/app/code/Magento/Payment/Gateway/Http/ConverterInterface.php b/app/code/Magento/Payment/Gateway/Http/ConverterInterface.php index 776ea4b11673d8589dfca68b53c203da27986bda..673a0bbc847008af50b59bf41da2f0ed2f0f8af7 100644 --- a/app/code/Magento/Payment/Gateway/Http/ConverterInterface.php +++ b/app/code/Magento/Payment/Gateway/Http/ConverterInterface.php @@ -10,7 +10,7 @@ interface ConverterInterface /** * Converts gateway response to ENV structure * - * @param string $response + * @param mixed $response * @return array * @throws \Magento\Payment\Gateway\Http\ConverterException */ diff --git a/app/code/Magento/Payment/Gateway/Http/TransferInterface.php b/app/code/Magento/Payment/Gateway/Http/TransferInterface.php index abd3d530b2ac59ff37b88ee738d29d79a864e8a8..f2150c8e083f23f8a9fa3f0440a52c884f9cfac3 100644 --- a/app/code/Magento/Payment/Gateway/Http/TransferInterface.php +++ b/app/code/Magento/Payment/Gateway/Http/TransferInterface.php @@ -38,7 +38,7 @@ interface TransferInterface /** * Returns request body * - * @return string + * @return array */ public function getBody(); diff --git a/app/code/Magento/Payment/Gateway/Validator/AbstractValidator.php b/app/code/Magento/Payment/Gateway/Validator/AbstractValidator.php index e82e0605445a367d1bbf528989c2081393f35c2c..b9e55ef57eca1d31ef32912e1457f8772c5520af 100644 --- a/app/code/Magento/Payment/Gateway/Validator/AbstractValidator.php +++ b/app/code/Magento/Payment/Gateway/Validator/AbstractValidator.php @@ -30,6 +30,11 @@ abstract class AbstractValidator implements ValidatorInterface */ protected function createResult($isValid, array $fails = []) { - return $this->resultInterfaceFactory->create(['isValid' => (bool)$isValid, 'failsDescription' => $fails]); + return $this->resultInterfaceFactory->create( + [ + 'isValid' => (bool)$isValid, + 'failsDescription' => $fails + ] + ); } } diff --git a/app/code/Magento/Payment/Gateway/Validator/CountryValidator.php b/app/code/Magento/Payment/Gateway/Validator/CountryValidator.php index 3a0ff81186df3aff134f5e14c79d5a7f409a2e7b..0c65b09785040a45d402bed4653c4ab3b691db23 100644 --- a/app/code/Magento/Payment/Gateway/Validator/CountryValidator.php +++ b/app/code/Magento/Payment/Gateway/Validator/CountryValidator.php @@ -9,7 +9,7 @@ use Magento\Framework\Exception\NotFoundException; use Magento\Payment\Gateway\ConfigInterface; use Magento\Payment\Gateway\Validator\ResultInterfaceFactory; -class CountryValidator implements ValidatorInterface +class CountryValidator extends AbstractValidator { /** * @var \Magento\Payment\Gateway\ConfigInterface @@ -17,20 +17,15 @@ class CountryValidator implements ValidatorInterface private $config; /** - * @var ResultInterfaceFactory - */ - private $resultFactory; - - /** - * @param \Magento\Payment\Gateway\ConfigInterface $config * @param ResultInterfaceFactory $resultFactory + * @param \Magento\Payment\Gateway\ConfigInterface $config */ public function __construct( - ConfigInterface $config, - ResultInterfaceFactory $resultFactory + ResultInterfaceFactory $resultFactory, + ConfigInterface $config ) { $this->config = $config; - $this->resultFactory = $resultFactory; + parent::__construct($resultFactory); } /** @@ -55,10 +50,6 @@ class CountryValidator implements ValidatorInterface } } - return $this->resultFactory->create( - [ - 'isValid' => $isValid - ] - ); + return $this->createResult($isValid); } } diff --git a/app/code/Magento/Payment/Gateway/Validator/ValidatorComposite.php b/app/code/Magento/Payment/Gateway/Validator/ValidatorComposite.php index 05a476f9743c12a930052fe27c4dfcb057e54ae5..6e7c5c8c0ab5cecf0031ebc87519306289ea40e2 100644 --- a/app/code/Magento/Payment/Gateway/Validator/ValidatorComposite.php +++ b/app/code/Magento/Payment/Gateway/Validator/ValidatorComposite.php @@ -9,18 +9,13 @@ use Magento\Framework\ObjectManager\TMap; use Magento\Framework\ObjectManager\TMapFactory; use Magento\Payment\Gateway\Validator\ResultInterfaceFactory; -class ValidatorComposite implements ValidatorInterface +class ValidatorComposite extends AbstractValidator { /** * @var ValidatorInterface[] | TMap */ private $validators; - /** - * @var ResultInterfaceFactory - */ - private $resultFactory; - /** * @param ResultInterfaceFactory $resultFactory * @param array $validators @@ -37,7 +32,7 @@ class ValidatorComposite implements ValidatorInterface 'type' => 'Magento\Payment\Gateway\Validator\ValidatorInterface' ] ); - $this->resultFactory = $resultFactory; + parent::__construct($resultFactory); } /** @@ -61,11 +56,6 @@ class ValidatorComposite implements ValidatorInterface } } - return $this->resultFactory->create( - [ - 'isValid' => $isValid, - 'failsDescription' => $failsDescriptionAggregate - ] - ); + return $this->createResult($isValid, $failsDescriptionAggregate); } } diff --git a/app/code/Magento/Payment/Model/Method/Adapter.php b/app/code/Magento/Payment/Model/Method/Adapter.php index acb0e56809e30c3c677aebc4bffc5611ac7112f1..314a03d51550fedde3cd9b9e8c795eb25b4f5061 100644 --- a/app/code/Magento/Payment/Model/Method/Adapter.php +++ b/app/code/Magento/Payment/Model/Method/Adapter.php @@ -7,6 +7,9 @@ namespace Magento\Payment\Model\Method; use Magento\Framework\Exception\LocalizedException; use Magento\Framework\Exception\NotFoundException; +use Magento\Payment\Gateway\Command\CommandPoolInterface; +use Magento\Payment\Gateway\Config\ValueHandlerPoolInterface; +use Magento\Payment\Gateway\Validator\ValidatorPoolInterface; use Magento\Payment\Model\InfoInterface; use Magento\Payment\Model\MethodInterface; @@ -18,17 +21,17 @@ use Magento\Payment\Model\MethodInterface; class Adapter implements MethodInterface { /** - * @var \Magento\Payment\Gateway\Config\ValueHandlerPoolInterface + * @var ValueHandlerPoolInterface */ private $valueHandlerPool; /** - * @var \Magento\Payment\Gateway\Validator\ValidatorPoolInterface + * @var ValidatorPoolInterface */ private $validatorPool; /** - * @var \Magento\Payment\Gateway\Command\CommandPoolInterface + * @var CommandPoolInterface */ private $commandPool; @@ -69,9 +72,9 @@ class Adapter implements MethodInterface /** * @param \Magento\Framework\Event\ManagerInterface $eventManager - * @param \Magento\Payment\Gateway\Config\ValueHandlerPoolInterface $valueHandlerPool - * @param \Magento\Payment\Gateway\Validator\ValidatorPoolInterface $validatorPool - * @param \Magento\Payment\Gateway\Command\CommandPoolInterface $commandPool + * @param ValueHandlerPoolInterface $valueHandlerPool + * @param ValidatorPoolInterface $validatorPool + * @param CommandPoolInterface $commandPool * @param \Magento\Payment\Gateway\Data\PaymentDataObjectFactory $paymentDataObjectFactory * @param string $code * @param string $formBlockType @@ -79,9 +82,9 @@ class Adapter implements MethodInterface */ public function __construct( \Magento\Framework\Event\ManagerInterface $eventManager, - \Magento\Payment\Gateway\Config\ValueHandlerPoolInterface $valueHandlerPool, - \Magento\Payment\Gateway\Validator\ValidatorPoolInterface $validatorPool, - \Magento\Payment\Gateway\Command\CommandPoolInterface $commandPool, + ValueHandlerPoolInterface $valueHandlerPool, + ValidatorPoolInterface $validatorPool, + CommandPoolInterface $commandPool, \Magento\Payment\Gateway\Data\PaymentDataObjectFactory $paymentDataObjectFactory, $code, $formBlockType, @@ -306,7 +309,15 @@ class Adapter implements MethodInterface private function getConfiguredValue($field) { $handler = $this->valueHandlerPool->get($field); - return $handler->handle($field, $this->getStore()); + $subject = [ + 'field' => $field + ]; + + if ($this->getInfoInstance()) { + $subject['payment'] = $this->paymentDataObjectFactory->create($this->getInfoInstance()); + } + + return $handler->handle($subject, $this->getStore()); } /** @@ -522,12 +533,6 @@ class Adapter implements MethodInterface */ public function getInfoInstance() { - if (!$this->infoInstance instanceof InfoInterface) { - throw new LocalizedException( - __('We cannot retrieve the payment information object instance.') - ); - } - return $this->infoInstance; } @@ -548,8 +553,16 @@ class Adapter implements MethodInterface return $this->getConfiguredValue($field); } + $subject = [ + 'field' => $field + ]; + + if ($this->getInfoInstance()) { + $subject['payment'] = $this->paymentDataObjectFactory->create($this->getInfoInstance()); + } + $handler = $this->valueHandlerPool->get($field); - return $handler->handle($field, (int)$storeId); + return $handler->handle($subject, (int)$storeId); } /** @@ -567,6 +580,7 @@ class Adapter implements MethodInterface /** * {inheritdoc} + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function initialize($paymentAction, $stateObject) { diff --git a/app/code/Magento/Payment/Test/Unit/Gateway/Command/GatewayCommandTest.php b/app/code/Magento/Payment/Test/Unit/Gateway/Command/GatewayCommandTest.php index 9872e20250bbe2d34c5375f22cbac5916e69cf3a..7a9d60d8acc18d9ce7fc373bdd14d56f0f0e26e6 100644 --- a/app/code/Magento/Payment/Test/Unit/Gateway/Command/GatewayCommandTest.php +++ b/app/code/Magento/Payment/Test/Unit/Gateway/Command/GatewayCommandTest.php @@ -5,50 +5,67 @@ */ namespace Magento\Payment\Test\Unit\Gateway\Command; +use Magento\Payment\Gateway\Command\GatewayCommand; +use Magento\Payment\Gateway\Http\ClientInterface; +use Magento\Payment\Gateway\Http\TransferFactoryInterface; +use Magento\Payment\Gateway\Request\BuilderInterface; +use Magento\Payment\Gateway\Response\HandlerInterface; +use Magento\Payment\Gateway\Validator\ValidatorInterface; + class GatewayCommandTest extends \PHPUnit_Framework_TestCase { - /** @var \Magento\Payment\Gateway\Command\GatewayCommand */ - protected $model; + /** @var GatewayCommand */ + protected $command; /** - * @var \Magento\Payment\Gateway\Request\BuilderInterface|\PHPUnit_Framework_MockObject_MockObject + * @var BuilderInterface|\PHPUnit_Framework_MockObject_MockObject */ protected $requestBuilderMock; /** - * @var \Magento\Payment\Gateway\Http\TransferFactoryInterface|\PHPUnit_Framework_MockObject_MockObject + * @var TransferFactoryInterface|\PHPUnit_Framework_MockObject_MockObject */ protected $transferFactoryMock; /** - * @var \Magento\Payment\Gateway\Http\ClientInterface|\PHPUnit_Framework_MockObject_MockObject + * @var ClientInterface|\PHPUnit_Framework_MockObject_MockObject */ protected $clientMock; /** - * @var \Magento\Payment\Gateway\Response\HandlerInterface|\PHPUnit_Framework_MockObject_MockObject + * @var HandlerInterface|\PHPUnit_Framework_MockObject_MockObject */ protected $responseHandlerMock; /** - * @var \Magento\Payment\Gateway\Validator\ValidatorInterface|\PHPUnit_Framework_MockObject_MockObject + * @var ValidatorInterface|\PHPUnit_Framework_MockObject_MockObject */ protected $validatorMock; protected function setUp() { - $this->requestBuilderMock = $this->getMockBuilder('Magento\Payment\Gateway\Request\BuilderInterface') + $this->requestBuilderMock = $this->getMockBuilder( + 'Magento\Payment\Gateway\Request\BuilderInterface' + ) ->getMockForAbstractClass(); - $this->transferFactoryMock = $this->getMockBuilder('Magento\Payment\Gateway\Http\TransferFactoryInterface') + $this->transferFactoryMock = $this->getMockBuilder( + 'Magento\Payment\Gateway\Http\TransferFactoryInterface' + ) ->getMockForAbstractClass(); - $this->clientMock = $this->getMockBuilder('Magento\Payment\Gateway\Http\ClientInterface') + $this->clientMock = $this->getMockBuilder( + 'Magento\Payment\Gateway\Http\ClientInterface' + ) ->getMockForAbstractClass(); - $this->responseHandlerMock = $this->getMockBuilder('Magento\Payment\Gateway\Response\HandlerInterface') + $this->responseHandlerMock = $this->getMockBuilder( + 'Magento\Payment\Gateway\Response\HandlerInterface' + ) ->getMockForAbstractClass(); - $this->validatorMock = $this->getMockBuilder('Magento\Payment\Gateway\Validator\ValidatorInterface') + $this->validatorMock = $this->getMockBuilder( + 'Magento\Payment\Gateway\Validator\ValidatorInterface' + ) ->getMockForAbstractClass(); - $this->model = new \Magento\Payment\Gateway\Command\GatewayCommand( + $this->command = new GatewayCommand( $this->requestBuilderMock, $this->transferFactoryMock, $this->clientMock, @@ -60,12 +77,19 @@ class GatewayCommandTest extends \PHPUnit_Framework_TestCase public function testExecute() { $commandSubject = ['authorize']; - $request = ['request_field1' => 'request_value1', 'request_field2' => 'request_value2']; + $request = [ + 'request_field1' => 'request_value1', + 'request_field2' => 'request_value2' + ]; $response = ['response_field1' => 'response_value1']; - $validationResult = $this->getMockBuilder('Magento\Payment\Gateway\Validator\ResultInterface') + $validationResult = $this->getMockBuilder( + 'Magento\Payment\Gateway\Validator\ResultInterface' + ) ->getMockForAbstractClass(); - $transferO = $this->getMockBuilder('Magento\Payment\Gateway\Http\TransferInterface') + $transferO = $this->getMockBuilder( + 'Magento\Payment\Gateway\Http\TransferInterface' + ) ->getMockForAbstractClass(); $this->requestBuilderMock->expects(static::once()) @@ -94,6 +118,56 @@ class GatewayCommandTest extends \PHPUnit_Framework_TestCase ->method('handle') ->with($commandSubject, $response); - $this->model->execute($commandSubject); + $this->command->execute($commandSubject); + } + + public function testExecuteValidationFail() + { + $this->setExpectedException( + 'Magento\Payment\Gateway\Command\CommandException' + ); + + $commandSubject = ['authorize']; + $request = [ + 'request_field1' => 'request_value1', + 'request_field2' => 'request_value2' + ]; + $response = ['response_field1' => 'response_value1']; + $validationResult = $this->getMockBuilder( + 'Magento\Payment\Gateway\Validator\ResultInterface' + ) + ->getMockForAbstractClass(); + + $transferO = $this->getMockBuilder( + 'Magento\Payment\Gateway\Http\TransferInterface' + ) + ->getMockForAbstractClass(); + + $this->requestBuilderMock->expects(static::once()) + ->method('build') + ->with($commandSubject) + ->willReturn($request); + + $this->transferFactoryMock->expects(static::once()) + ->method('create') + ->with($request) + ->willReturn($transferO); + + $this->clientMock->expects(static::once()) + ->method('placeRequest') + ->with($transferO) + ->willReturn($response); + $this->validatorMock->expects(static::once()) + ->method('validate') + ->with(array_merge($commandSubject, ['response' =>$response])) + ->willReturn($validationResult); + $validationResult->expects(static::once()) + ->method('isValid') + ->willReturn(false); + $validationResult->expects(static::once()) + ->method('getFailsDescription') + ->willReturn([]); + + $this->command->execute($commandSubject); } } diff --git a/app/code/Magento/Payment/Test/Unit/Gateway/Config/ConfigValueHandlerTest.php b/app/code/Magento/Payment/Test/Unit/Gateway/Config/ConfigValueHandlerTest.php index eebebfdadf275d0ae66013340594630543dce94e..3f1d4a280ef288d27e52458ecd3950bae936fc05 100644 --- a/app/code/Magento/Payment/Test/Unit/Gateway/Config/ConfigValueHandlerTest.php +++ b/app/code/Magento/Payment/Test/Unit/Gateway/Config/ConfigValueHandlerTest.php @@ -23,7 +23,8 @@ class ConfigValueHandlerTest extends \PHPUnit_Framework_TestCase protected function setUp() { - $this->configMock = $this->getMockBuilder('Magento\Payment\Gateway\ConfigInterface')->getMockForAbstractClass(); + $this->configMock = $this->getMockBuilder('Magento\Payment\Gateway\ConfigInterface') + ->getMockForAbstractClass(); $this->model = new ConfigValueHandler($this->configMock); } @@ -38,7 +39,7 @@ class ConfigValueHandlerTest extends \PHPUnit_Framework_TestCase ->with($field, $storeId) ->willReturn($expected); - $this->assertEquals($expected, $this->model->handle($field, $storeId)); + $this->assertEquals($expected, $this->model->handle(['field' => $field], $storeId)); } public function testHandleWithoutStoreId() @@ -51,6 +52,6 @@ class ConfigValueHandlerTest extends \PHPUnit_Framework_TestCase ->with($field, null) ->willReturn($expected); - $this->assertEquals($expected, $this->model->handle($field)); + $this->assertEquals($expected, $this->model->handle(['field' => $field])); } } diff --git a/app/code/Magento/Payment/Test/Unit/Gateway/Http/Client/SoapTest.php b/app/code/Magento/Payment/Test/Unit/Gateway/Http/Client/SoapTest.php new file mode 100644 index 0000000000000000000000000000000000000000..ef4dd5be64546681d9e328223dad5e9f57386d38 --- /dev/null +++ b/app/code/Magento/Payment/Test/Unit/Gateway/Http/Client/SoapTest.php @@ -0,0 +1,155 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Payment\Test\Unit\Gateway\Http\Client; + +use Magento\Payment\Gateway\Http\Client\Soap; + +class SoapTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $logger; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $clientFactory; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $converter; + + /** + * @var \PHPUnit_Framework_MockObject_MockObject + */ + private $client; + + /** + * @var Soap + */ + private $gatewayClient; + + protected function setUp() + { + $this->logger = $this->getMockBuilder( + 'Magento\Payment\Model\Method\Logger' + ) + ->disableOriginalConstructor() + ->getMock(); + $this->clientFactory = $this->getMockBuilder( + 'Magento\Framework\Webapi\Soap\ClientFactory' + )->getMock(); + $this->converter = $this->getMockBuilder( + 'Magento\Payment\Gateway\Http\ConverterInterface' + )->getMockForAbstractClass(); + $this->client = $this->getMockBuilder('\SoapClient') + ->disableOriginalConstructor() + ->getMock(); + + $this->gatewayClient = new Soap( + $this->logger, + $this->clientFactory, + $this->converter + ); + } + + public function testPlaceRequest() + { + $expectedResult = [ + 'result' => [] + ]; + $soapResult = new \StdClass; + + $this->logger->expects(static::at(0)) + ->method('debug') + ->with( + ['request' => ['body']] + ); + $this->clientFactory->expects(static::once()) + ->method('create') + ->with('path_to_wsdl', ['trace' => true]) + ->willReturn($this->client); + $transferObject = $this->getTransferObject(); + $transferObject->expects(static::any()) + ->method('__setSoapHeaders') + ->with(['headers']); + $this->client->expects(static::once()) + ->method('__soapCall') + ->with('soapMethod', [['body']]) + ->willReturn($soapResult); + $this->converter->expects(static::once()) + ->method('convert') + ->with($soapResult) + ->willReturn($expectedResult); + $this->logger->expects(static::at(1)) + ->method('debug') + ->with(['response' => $expectedResult]); + + static::assertEquals( + $expectedResult, + $this->gatewayClient->placeRequest($transferObject) + ); + } + + public function testPlaceRequestSoapException() + { + $this->setExpectedException('Exception'); + + $this->logger->expects(static::at(0)) + ->method('debug') + ->with( + ['request' => ['body']] + ); + $this->clientFactory->expects(static::once()) + ->method('create') + ->with('path_to_wsdl', ['trace' => true]) + ->willReturn($this->client); + $transferObject = $this->getTransferObject(); + $transferObject->expects(static::any()) + ->method('__setSoapHeaders') + ->with(['headers']); + $this->client->expects(static::once()) + ->method('__soapCall') + ->with('soapMethod', [['body']]) + ->willThrowException(new \Exception); + $this->client->expects(static::once()) + ->method('__getLastRequest') + ->willReturn('RequestTrace'); + $this->logger->expects(static::at(1)) + ->method('debug') + ->with( + ['trace' => 'RequestTrace'] + ); + + $this->gatewayClient->placeRequest($transferObject); + } + + /** + * Returns prepared transfer object + * + * @return \PHPUnit_Framework_MockObject_MockObject + */ + private function getTransferObject() + { + $transferObject = $this->getMockBuilder( + 'Magento\Payment\Gateway\Http\TransferInterface' + )->getMock(); + + $transferObject->expects(static::any()) + ->method('getBody') + ->willReturn(['body']); + $transferObject->expects(static::any()) + ->method('getClientConfig') + ->willReturn(['wsdl' => 'path_to_wsdl']); + $transferObject->expects(static::any()) + ->method('getMethod') + ->willReturn('soapMethod'); + + return $transferObject; + } +} diff --git a/app/code/Magento/Payment/Test/Unit/Gateway/Http/Client/ZendTest.php b/app/code/Magento/Payment/Test/Unit/Gateway/Http/Client/ZendTest.php index 43f2a400ccd77100161afbd5596ddf4fdbc7b8b1..e34cb00d5a24b4822ac6de12e6a406304fc5afcc 100644 --- a/app/code/Magento/Payment/Test/Unit/Gateway/Http/Client/ZendTest.php +++ b/app/code/Magento/Payment/Test/Unit/Gateway/Http/Client/ZendTest.php @@ -65,7 +65,11 @@ class ZendTest extends \PHPUnit_Framework_TestCase $this->transferObjectMock = $this->getMockBuilder('Magento\Payment\Gateway\Http\TransferInterface') ->getMockForAbstractClass(); - $this->model = new Zend($this->zendClientFactoryMock, $this->converterMock, $this->loggerMock); + $this->model = new Zend( + $this->zendClientFactoryMock, + $this->loggerMock, + $this->converterMock + ); } public function testPlaceRequest() @@ -147,7 +151,7 @@ class ZendTest extends \PHPUnit_Framework_TestCase $this->transferObjectMock->expects($this->once())->method('getHeaders')->willReturn($headers); $this->transferObjectMock->expects($this->atLeastOnce())->method('getBody')->willReturn($body); $this->transferObjectMock->expects($this->once())->method('shouldEncode')->willReturn($shouldEncode); - $this->transferObjectMock->expects($this->once())->method('getUri')->willReturn($uri); + $this->transferObjectMock->expects(static::atLeastOnce())->method('getUri')->willReturn($uri); $this->clientMock->expects($this->once())->method('setConfig')->with($config)->willReturnSelf(); $this->clientMock->expects($this->once())->method('setMethod')->with($method)->willReturnSelf(); diff --git a/app/code/Magento/Payment/Test/Unit/Gateway/Http/Converter/Soap/ObjectToArrayConverterTest.php b/app/code/Magento/Payment/Test/Unit/Gateway/Http/Converter/Soap/ObjectToArrayConverterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..c39c6dcb1d8b2f8374ba9897b062dd16320479bf --- /dev/null +++ b/app/code/Magento/Payment/Test/Unit/Gateway/Http/Converter/Soap/ObjectToArrayConverterTest.php @@ -0,0 +1,35 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Payment\Test\Unit\Gateway\Http\Converter\Soap; + +use Magento\Payment\Gateway\Http\Converter\Soap\ObjectToArrayConverter; + +class ObjectToArrayConverterTest extends \PHPUnit_Framework_TestCase +{ + public function testConvert() + { + $input = new \stdClass(); + $input->property = new \stdClass(); + $input->property2 = 'bla'; + $input->property->property3 = new \stdClass(); + $input->property->property4 = 'bla'; + $input->property->property3->property5 = 'bla'; + + $output = [ + 'property' => [ + 'property3' => [ + 'property5' => 'bla' + ], + 'property4' => 'bla' + ], + 'property2' => 'bla' + ]; + + $converter = new ObjectToArrayConverter(); + static::assertEquals($output, $converter->convert($input)); + + } +} diff --git a/app/code/Magento/Payment/Test/Unit/Gateway/Validator/CountryValidatorTest.php b/app/code/Magento/Payment/Test/Unit/Gateway/Validator/CountryValidatorTest.php index 38ac5d69dd3d01176e8f53c8f45a1057dc5ed17c..554b13ef74646f8e1cd6a62f8ede96b1491352ae 100644 --- a/app/code/Magento/Payment/Test/Unit/Gateway/Validator/CountryValidatorTest.php +++ b/app/code/Magento/Payment/Test/Unit/Gateway/Validator/CountryValidatorTest.php @@ -38,8 +38,8 @@ class CountryValidatorTest extends \PHPUnit_Framework_TestCase ->getMock(); $this->model = new \Magento\Payment\Gateway\Validator\CountryValidator( - $this->configMock, - $this->resultFactoryMock + $this->resultFactoryMock, + $this->configMock ); } @@ -62,7 +62,7 @@ class CountryValidatorTest extends \PHPUnit_Framework_TestCase $this->resultFactoryMock->expects($this->once()) ->method('create') - ->with(['isValid' => $isValid]) + ->with(['isValid' => $isValid, 'failsDescription' => []]) ->willReturn($this->resultMock); $this->assertSame($this->resultMock, $this->model->validate($validationSubject)); @@ -90,7 +90,7 @@ class CountryValidatorTest extends \PHPUnit_Framework_TestCase $this->resultFactoryMock->expects($this->once()) ->method('create') - ->with(['isValid' => $isValid]) + ->with(['isValid' => $isValid, 'failsDescription' => []]) ->willReturn($this->resultMock); $this->assertSame($this->resultMock, $this->model->validate($validationSubject)); diff --git a/app/code/Magento/Payment/etc/payment.xml b/app/code/Magento/Payment/etc/payment.xml index 5560a70f11b325ea8d12a85ec5fd2582b29593f1..1d52b718925cddf25f531b1b6d8ea9c941a9b901 100644 --- a/app/code/Magento/Payment/etc/payment.xml +++ b/app/code/Magento/Payment/etc/payment.xml @@ -35,9 +35,6 @@ <type id="DN" order="60"> <label>Diners</label> </type> - <type id="JC" order="70"> - <label>JCB</label> - </type> <type id="MI" order="80"> <label>Maestro International</label> </type> diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo.php b/app/code/Magento/Sales/Model/Order/Creditmemo.php index d0c564c01bf619a5babab63eefe194733eb8242c..56d1c892985da5d8423381fa5d9080be6de2564c 100644 --- a/app/code/Magento/Sales/Model/Order/Creditmemo.php +++ b/app/code/Magento/Sales/Model/Order/Creditmemo.php @@ -373,6 +373,28 @@ class Creditmemo extends AbstractModel implements EntityInterface, CreditmemoInt return false; } + /** + * Returns assigned invoice + * + * @return Invoice|null + */ + public function getInvoice() + { + return $this->getData('invoice'); + } + + /** + * Sets invoice + * + * @param Invoice $invoice + * @return $this + */ + public function setInvoice(Invoice $invoice) + { + $this->setData('invoice', $invoice); + return $this; + } + /** * Check creditmemo cancel action availability * diff --git a/app/code/Magento/Sales/Model/Order/Payment.php b/app/code/Magento/Sales/Model/Order/Payment.php index 6ecf8a298cd1a663af73808e5c79eb6b664d458a..269f9e0187798ed74eb919d31c88b6aada5a6bd5 100644 --- a/app/code/Magento/Sales/Model/Order/Payment.php +++ b/app/code/Magento/Sales/Model/Order/Payment.php @@ -186,6 +186,40 @@ class Payment extends Info implements OrderPaymentInterface return $this->_order; } + /** + * Sets transaction id for current payment + * + * @param string $transactionId + * @return $this + */ + public function setTransactionId($transactionId) + { + $this->setData('transaction_id', $transactionId); + return $this; + } + + /** + * Sets transaction close flag + * + * @param bool $isClosed + * @return $this + */ + public function setIsTransactionClosed($isClosed) + { + $this->setData('is_transaction_closed', (bool)$isClosed); + return $this; + } + + /** + * Returns transaction parent + * + * @return string + */ + public function getParentTransactionId() + { + return $this->getData('parent_transaction_id'); + } + /** * Check order payment capture action availability * @@ -655,6 +689,30 @@ class Payment extends Info implements OrderPaymentInterface return $this->_void(false, $amount); } + /** + * Sets creditmemo for current payment + * + * @param Creditmemo $creditmemo + * @return $this + */ + public function setCreditmemo(Creditmemo $creditmemo) + { + $this->setData('creditmemo', $creditmemo); + return $this; + } + + /** + * Returns Creditmemo assigned for this payment + * + * @return Creditmemo|null + */ + public function getCreditmemo() + { + return $this->getData('creditmemo') instanceof Creditmemo + ? $this->getData('creditmemo') + : null; + } + /** * Refund payment online or offline, depending on whether there is invoice set in the creditmemo instance * Updates transactions hierarchy, if required diff --git a/app/code/Magento/Sales/Model/Order/Payment/Transaction.php b/app/code/Magento/Sales/Model/Order/Payment/Transaction.php index 5d7a2efedd93f35bca87d852441edc3c1ac5e07a..40d528fbeb8d5fec707f059b6cb5e7a77c0c6bcc 100644 --- a/app/code/Magento/Sales/Model/Order/Payment/Transaction.php +++ b/app/code/Magento/Sales/Model/Order/Payment/Transaction.php @@ -614,8 +614,12 @@ class Transaction extends AbstractModel implements TransactionInterface { $this->_verifyThisTransactionExists(); if (null === $this->_paymentObject && $shouldLoad) { + /** @var \Magento\Sales\Model\Order\Payment $payment */ $payment = $this->_paymentFactory->create()->load($this->getPaymentId()); if ($payment->getId()) { + if (!$payment->getOrder()) { + $payment->setOrder($this->getOrder()); + } $this->setOrderPaymentObject($payment); } } diff --git a/app/code/Magento/Ui/Component/AbstractComponent.php b/app/code/Magento/Ui/Component/AbstractComponent.php index c7af5b3f471c7c084826bc98c45a0ab6c2610cb2..0a15bafe9915faa5aefea6f006e169ea626523db 100644 --- a/app/code/Magento/Ui/Component/AbstractComponent.php +++ b/app/code/Magento/Ui/Component/AbstractComponent.php @@ -8,14 +8,13 @@ namespace Magento\Ui\Component; use Magento\Framework\Object; use Magento\Framework\View\Element\UiComponentInterface; use Magento\Framework\View\Element\UiComponent\ContextInterface; -use Magento\Framework\View\Element\UiComponent\JsConfigInterface; use Magento\Framework\View\Element\UiComponent\DataSourceInterface; /** * Abstract class AbstractComponent * @SuppressWarnings(PHPMD.NumberOfChildren) */ -abstract class AbstractComponent extends Object implements UiComponentInterface, JsConfigInterface +abstract class AbstractComponent extends Object implements UiComponentInterface { /** * Render context @@ -227,6 +226,7 @@ abstract class AbstractComponent extends Object implements UiComponentInterface, * * @param array $dataSource * @return void + * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function prepareDataSource(array & $dataSource) { diff --git a/app/code/Magento/Ui/Component/Container.php b/app/code/Magento/Ui/Component/Container.php index 6b642b9a3e04525c63ac0df53a8c6113eb44cf66..352dfdf2942bcd5d1557d1f9df5041c588f1074e 100644 --- a/app/code/Magento/Ui/Component/Container.php +++ b/app/code/Magento/Ui/Component/Container.php @@ -5,8 +5,6 @@ */ namespace Magento\Ui\Component; -use Magento\Framework\View\Element\UiComponent\DataSourceInterface; - /** * Class Container */ diff --git a/app/code/Magento/Ui/Component/Form.php b/app/code/Magento/Ui/Component/Form.php index ed0b344658a30c610169de97e9de8aaeb20d41f8..ee1e32e30e07e954786963644079ba439842ae0a 100644 --- a/app/code/Magento/Ui/Component/Form.php +++ b/app/code/Magento/Ui/Component/Form.php @@ -5,8 +5,6 @@ */ namespace Magento\Ui\Component; -use Magento\Framework\View\Element\UiComponent\DataSourceInterface; - /** * Class Form */ diff --git a/app/code/Magento/Ui/Component/Form/Element/Multiline.php b/app/code/Magento/Ui/Component/Form/Element/Multiline.php index 5f508343d4316fbf6b3f788fddab37057d669474..3669cd079a44f56e85d0c816da41f7cdb78b675e 100644 --- a/app/code/Magento/Ui/Component/Form/Element/Multiline.php +++ b/app/code/Magento/Ui/Component/Form/Element/Multiline.php @@ -5,6 +5,11 @@ */ namespace Magento\Ui\Component\Form\Element; +use Magento\Ui\Component\Form\Field; +use Magento\Framework\View\Element\UiComponentFactory; +use Magento\Framework\View\Element\UiComponentInterface; +use Magento\Framework\View\Element\UiComponent\ContextInterface; + /** * Class Multiline */ @@ -12,6 +17,35 @@ class Multiline extends AbstractElement { const NAME = 'multiline'; + const FORM_ELEMENT = 'input'; + + const DATA_TYPE = 'text'; + + /** + * UI component factory + * + * @var UiComponentFactory + */ + protected $uiComponentFactory; + + /** + * Constructor + * + * @param ContextInterface $context + * @param UiComponentFactory $uiComponentFactory + * @param UiComponentInterface[] $components + * @param array $data + */ + public function __construct( + ContextInterface $context, + UiComponentFactory $uiComponentFactory, + array $components = [], + array $data = [] + ) { + $this->uiComponentFactory = $uiComponentFactory; + parent::__construct($context, $components, $data); + } + /** * Get component name * @@ -23,10 +57,37 @@ class Multiline extends AbstractElement } /** - * @return mixed|string + * Prepare component configuration + * + * @return void */ - public function getType() + public function prepare() { - return $this->getData('input_type') ? $this->getData('input_type') : 'text'; + $size = abs((int) $this->getData('config/size')); + $validation = [$this->getData('config/validation')]; + while ($size--) { + $identifier = $this->getName() . '_' . $size; + $arguments = [ + 'data' => [ + 'name' => $identifier, + 'config' => [ + 'dataScope' => $size, + 'dataType' => static::DATA_TYPE, + 'formElement' => static::FORM_ELEMENT, + 'sortOrder' => $size, + ] + ] + ]; + + if (!empty($validation[$size])) { + $arguments['data']['config']['validation'] = $validation[$size]; + } + + $component = $this->uiComponentFactory->create($identifier, Field::NAME, $arguments); + $component->prepare(); + + $this->components[$identifier] = $component; + } + parent::prepare(); } } diff --git a/app/code/Magento/Ui/Component/Form/Field.php b/app/code/Magento/Ui/Component/Form/Field.php index 670fa9004b6752f1afad78854824a9a0b66547c3..d2ff377ae5bd4868179d4bef1db12cf640df4fb5 100644 --- a/app/code/Magento/Ui/Component/Form/Field.php +++ b/app/code/Magento/Ui/Component/Form/Field.php @@ -80,23 +80,23 @@ class Field extends AbstractComponent $formElement, array_merge(['context' => $this->getContext()], (array)$this->getData()) ); + $this->wrappedComponent->setData( + 'config', + array_replace_recursive( + (array) $this->wrappedComponent->getData('config'), + (array) $this->getData('config') + ) + ); $this->wrappedComponent->prepare(); + $this->components = $this->wrappedComponent->getChildComponents(); // Merge JS configuration with wrapped component configuration $wrappedComponentConfig = $this->getJsConfig($this->wrappedComponent); - $jsConfig = array_replace_recursive( - $wrappedComponentConfig, - $this->getJsConfig($this) - ); + + $jsConfig = array_replace_recursive($wrappedComponentConfig, $this->getJsConfig($this)); $jsConfig['extends'] = $this->wrappedComponent->getComponentName(); $this->setData('js_config', $jsConfig); - $this->setData( - 'config', - array_replace_recursive( - (array)$this->wrappedComponent->getData('config'), - (array)$this->getData('config') - ) - ); + $this->setData('config', $this->wrappedComponent->getData('config')); parent::prepare(); } diff --git a/app/code/Magento/Ui/Component/Form/Fieldset.php b/app/code/Magento/Ui/Component/Form/Fieldset.php index 00a1b0579e9e8e6767a2fcd17e41ed46be0f2cd1..45d03c005f602734617487639dda3f1f91748d7a 100644 --- a/app/code/Magento/Ui/Component/Form/Fieldset.php +++ b/app/code/Magento/Ui/Component/Form/Fieldset.php @@ -5,7 +5,6 @@ */ namespace Magento\Ui\Component\Form; -use Magento\Framework\Exception\LocalizedException; use Magento\Ui\Component\Container; use Magento\Ui\Component\AbstractComponent; use Magento\Framework\View\Element\UiComponentFactory; @@ -104,7 +103,7 @@ class Fieldset extends AbstractComponent 'config' => $fieldData ] ]; - $fieldComponent = $this->uiComponentFactory->create($name, 'field', $argument); + $fieldComponent = $this->uiComponentFactory->create($name, Field::NAME, $argument); $fieldComponent->prepare(); $this->addComponent($name, $fieldComponent); } else { diff --git a/app/code/Magento/Ui/Component/Layout/Generic.php b/app/code/Magento/Ui/Component/Layout/Generic.php index 0d8ee7d0cea07c5dcda4197b2dcf68833aa572ae..92d0a406f38e067fd5fc189ae3e1821fd788eeac 100644 --- a/app/code/Magento/Ui/Component/Layout/Generic.php +++ b/app/code/Magento/Ui/Component/Layout/Generic.php @@ -6,7 +6,6 @@ namespace Magento\Ui\Component\Layout; use Magento\Framework\View\Element\UiComponent\DataSourceInterface; -use Magento\Framework\View\Element\UiComponent\JsConfigInterface; use Magento\Framework\View\Element\UiComponent\LayoutInterface; use Magento\Framework\View\Element\UiComponentInterface; diff --git a/app/code/Magento/Ui/Component/Listing.php b/app/code/Magento/Ui/Component/Listing.php index 7d7d7b692b26042a08d41295f7a24d6536fd1802..363144c10d29a3991d070e65299de367be2425d1 100644 --- a/app/code/Magento/Ui/Component/Listing.php +++ b/app/code/Magento/Ui/Component/Listing.php @@ -6,8 +6,6 @@ namespace Magento\Ui\Component; use Magento\Ui\Component\Listing\Columns; -use Magento\Ui\Component\Listing\Columns\Column; -use Magento\Framework\View\Element\UiComponent\DataSourceInterface; /** * Class Listing diff --git a/app/code/Magento/Ui/DataProvider/EavValidationRul.php b/app/code/Magento/Ui/DataProvider/EavValidationRules.php similarity index 96% rename from app/code/Magento/Ui/DataProvider/EavValidationRul.php rename to app/code/Magento/Ui/DataProvider/EavValidationRules.php index 1d338ec30755af34f8653ca99b65f8202b141d7a..28551180b16fb4e33da680fe0f24211639f35bd7 100644 --- a/app/code/Magento/Ui/DataProvider/EavValidationRul.php +++ b/app/code/Magento/Ui/DataProvider/EavValidationRules.php @@ -8,9 +8,9 @@ namespace Magento\Ui\DataProvider; use Magento\Eav\Model\Entity\Attribute\AbstractAttribute; /** - * Class EavValidationRul + * Class EavValidationRules */ -class EavValidationRul +class EavValidationRules { /** * @var array diff --git a/app/code/Magento/Ui/Test/Unit/Component/Form/Field/MultilineTest.php b/app/code/Magento/Ui/Test/Unit/Component/Form/Field/MultilineTest.php new file mode 100644 index 0000000000000000000000000000000000000000..c1e717c1525fed4c226a20a697b0e9ce5f488172 --- /dev/null +++ b/app/code/Magento/Ui/Test/Unit/Component/Form/Field/MultilineTest.php @@ -0,0 +1,137 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\Test\Unit\Component\Form\Field; + +use Magento\Ui\Component\Form\Field; +use Magento\Ui\Component\Form\Element\Multiline; +use Magento\Framework\View\Element\UiComponentFactory; +use Magento\Framework\View\Element\UiComponentInterface; +use Magento\Framework\View\Element\UiComponent\ContextInterface; + +/** + * Class MultilineTest + * + * Test for class \Magento\Ui\Component\Form\Element\Multiline + */ +class MultilineTest extends \PHPUnit_Framework_TestCase +{ + const NAME = 'test-name'; + + /** + * @var Multiline + */ + protected $multiline; + + /** + * @var UiComponentFactory|\PHPUnit_Framework_MockObject_MockObject + */ + protected $uiComponentFactoryMock; + + /** + * @var ContextInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $contextMock; + + /** + * Set up + * + * @return void + */ + protected function setUp() + { + $this->uiComponentFactoryMock = $this->getMockBuilder('Magento\Framework\View\Element\UiComponentFactory') + ->disableOriginalConstructor() + ->getMock(); + $this->contextMock = $this->getMockBuilder('Magento\Framework\View\Element\UiComponent\ContextInterface') + ->getMockForAbstractClass(); + + $this->multiline = new Multiline( + $this->contextMock, + $this->uiComponentFactoryMock + ); + } + + /** + * Run test for prepare method + * + * @param array $data + * @return void + * + * @dataProvider prepareDataProvider + */ + public function testPrepare(array $data) + { + $this->uiComponentFactoryMock->expects($this->exactly($data['config']['size'])) + ->method('create') + ->with($this->stringContains(self::NAME . '_'), Field::NAME, $this->logicalNot($this->isEmpty())) + ->willReturn($this->getComponentMock($data['config']['size'])); + + $this->multiline->setData($data); + $this->multiline->prepare(); + + $result = $this->multiline->getData(); + + $this->assertEquals($data, $result); + } + + /** + * @param int $exactly + * @return UiComponentInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected function getComponentMock($exactly) + { + $componentMock = $this->getMockBuilder('Magento\Framework\View\Element\UiComponentInterface') + ->getMockForAbstractClass(); + + $componentMock->expects($this->exactly($exactly)) + ->method('prepare'); + + return $componentMock; + } + + /** + * Data provider for testPrepare + * + * @return array + */ + public function prepareDataProvider() + { + return [ + [ + 'data' => [ + 'name' => self::NAME, + 'config' => [ + 'size' => 2, + ] + ], + ], + [ + 'data' => [ + 'name' => self::NAME, + 'config' => [ + 'size' => 3, + ] + ], + ], + [ + 'data' => [ + 'name' => self::NAME, + 'config' => [ + 'size' => 1, + ] + ], + ], + [ + 'data' => [ + 'name' => self::NAME, + 'config' => [ + 'size' => 5, + ] + ], + ], + ]; + } +} diff --git a/app/code/Magento/Ui/Test/Unit/Component/Form/FieldTest.php b/app/code/Magento/Ui/Test/Unit/Component/Form/FieldTest.php new file mode 100644 index 0000000000000000000000000000000000000000..86a47115d31129abfedb6fe3ceafafc394879912 --- /dev/null +++ b/app/code/Magento/Ui/Test/Unit/Component/Form/FieldTest.php @@ -0,0 +1,177 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Ui\Test\Unit\Component\Form; + +use Magento\Ui\Component\Form\Field; +use Magento\Framework\View\Element\UiComponentFactory; +use Magento\Framework\View\Element\UiComponentInterface; +use Magento\Framework\View\Element\UiComponent\ContextInterface; + +/** + * Class FieldTest + * + * Test for class \Magento\Ui\Component\Form\Field + */ +class FieldTest extends \PHPUnit_Framework_TestCase +{ + const NAME = 'test-name'; + const COMPONENT_NAME = 'test-name'; + const COMPONENT_NAMESPACE = 'test-name'; + + /** + * @var Field + */ + protected $field; + + /** + * @var UiComponentFactory|\PHPUnit_Framework_MockObject_MockObject + */ + protected $uiComponentFactoryMock; + + /** + * @var ContextInterface|\PHPUnit_Framework_MockObject_MockObject + */ + protected $contextMock; + + /** + * @var array + */ + protected $testConfigData = [ + ['config', null, ['test-key' => 'test-value']], + ['js_config', null, ['test-key' => 'test-value']] + ]; + + /** + * Set up + * + * @return void + */ + protected function setUp() + { + $this->uiComponentFactoryMock = $this->getMockBuilder('Magento\Framework\View\Element\UiComponentFactory') + ->disableOriginalConstructor() + ->getMock(); + $this->contextMock = $this->getMockBuilder('Magento\Framework\View\Element\UiComponent\ContextInterface') + ->getMockForAbstractClass(); + + $this->field = new Field( + $this->contextMock, + $this->uiComponentFactoryMock + ); + } + + /** + * Run test for prepare method + * + * @param array $data + * @param array $expectedData + * @return void + * + * @dataProvider prepareSuccessDataProvider + */ + public function testPrepareSuccess(array $data, array $expectedData) + { + $this->uiComponentFactoryMock->expects($this->once()) + ->method('create') + ->with(self::NAME, $data['config']['formElement'], $this->arrayHasKey('context')) + ->willReturn($this->getWrappedComponentMock()); + + $this->contextMock->expects($this->any()) + ->method('getNamespace') + ->willReturn(self::COMPONENT_NAMESPACE); + + $this->field->setData($data); + $this->field->prepare(); + $result = $this->field->getData(); + + $this->assertEquals($expectedData, $result); + } + + /** + * Data provider for testPrepare + * + * @return array + */ + public function prepareSuccessDataProvider() + { + return [ + [ + 'data' => [ + 'name' => self::NAME, + 'config' => [ + 'formElement' => 'test', + ] + ], + 'expectedData' => [ + 'name' => self::NAME, + 'config' => [ + 'test-key' => 'test-value', + ], + 'js_config' => [ + 'extends' => self::NAME, + 'test-key' => 'test-value', + ] + ] + ], + ]; + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject|UiComponentInterface + */ + protected function getWrappedComponentMock() + { + $wrappedComponentMock = $this->getMockBuilder('Magento\Framework\View\Element\UiComponentInterface') + ->getMockForAbstractClass(); + + $wrappedComponentMock->expects($this->any()) + ->method('getData') + ->willReturnMap($this->testConfigData); + $wrappedComponentMock->expects($this->once()) + ->method('setData') + ->with('config', $this->logicalNot($this->isEmpty())); + $wrappedComponentMock->expects($this->once()) + ->method('prepare'); + $wrappedComponentMock->expects($this->once()) + ->method('getChildComponents') + ->willReturn($this->getComponentsMock()); + $wrappedComponentMock->expects($this->exactly(2)) + ->method('getComponentName') + ->willReturn(self::COMPONENT_NAME); + $wrappedComponentMock->expects($this->once()) + ->method('getContext') + ->willReturn($this->contextMock); + + return $wrappedComponentMock; + } + + /** + * @return \PHPUnit_Framework_MockObject_MockObject[]|UiComponentInterface[] + */ + protected function getComponentsMock() + { + $componentMock = $this->getMockBuilder('Magento\Framework\View\Element\UiComponentInterface') + ->getMockForAbstractClass(); + + return [$componentMock]; + } + + /** + * Run test prepare method (Exception) + * + * @return void + * + * @expectedException \Magento\Framework\Exception\LocalizedException + * @expectedExceptionMessage The configuration parameter "formElement" is a required for "test-name" field. + */ + public function testPrepareException() + { + $this->uiComponentFactoryMock->expects($this->never()) + ->method('create'); + $this->field->setData(['name' => self::NAME]); + $this->field->prepare(); + } +} diff --git a/app/code/Magento/Ui/etc/ui_components.xsd b/app/code/Magento/Ui/etc/ui_components.xsd index 86a6f5aaeca39cee9fccbc8f6714446f57d87872..17a80e2f4ac37e725e061d347aeb431e23162244 100644 --- a/app/code/Magento/Ui/etc/ui_components.xsd +++ b/app/code/Magento/Ui/etc/ui_components.xsd @@ -177,6 +177,15 @@ </xs:extension> </xs:complexContent> </xs:complexType> + <xs:complexType name="multiline"> + <xs:complexContent> + <xs:extension base="ui_element"> + <xs:choice minOccurs="0" maxOccurs="unbounded"> + <xs:group ref="configurable"/> + </xs:choice> + </xs:extension> + </xs:complexContent> + </xs:complexType> <xs:complexType name="fieldset"> <xs:complexContent> <xs:extension base="ui_element"> diff --git a/app/code/Magento/Ui/etc/ui_definition.xsd b/app/code/Magento/Ui/etc/ui_definition.xsd index 171b3e1b7dbef8660f7cee0d70f38d39cfb3336f..f0154eecb99647f17d7bb96c9c9c7c554806f0d1 100644 --- a/app/code/Magento/Ui/etc/ui_definition.xsd +++ b/app/code/Magento/Ui/etc/ui_definition.xsd @@ -39,6 +39,7 @@ <xs:element type="select" name="select"/> <xs:element type="multiselect" name="multiselect"/> <xs:element type="textarea" name="textarea"/> + <xs:element type="multiline" name="multiline"/> <xs:element type="dataTypeText" name="text"/> <xs:element type="dataTypeBoolean" name="boolean"/> <xs:element type="dataTypeNumber" name="number"/> diff --git a/app/code/Magento/Ui/view/base/ui_component/etc/definition.xml b/app/code/Magento/Ui/view/base/ui_component/etc/definition.xml index 54e661645fec41aba65109bd3025aa626c27cb0b..df5cfa21eca0a080805e940d75726c60f188141f 100644 --- a/app/code/Magento/Ui/view/base/ui_component/etc/definition.xml +++ b/app/code/Magento/Ui/view/base/ui_component/etc/definition.xml @@ -178,6 +178,13 @@ </item> </argument> </textarea> + <multiline class="Magento\Ui\Component\Form\Element\Multiline"> + <argument name="data" xsi:type="array"> + <item name="js_config" xsi:type="array"> + <item name="component" xsi:type="string">Magento_Ui/js/form/components/group</item> + </item> + </argument> + </multiline> <!-- Form elements --> <!-- Form element data types --> diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/group.js b/app/code/Magento/Ui/view/base/web/js/form/components/group.js index aeb0ce9db858cc9f7a36dd1c7b41684476830e6b..1e0ff9ac97a3259adc764509c57b49bd379c3a0f 100644 --- a/app/code/Magento/Ui/view/base/web/js/form/components/group.js +++ b/app/code/Magento/Ui/view/base/web/js/form/components/group.js @@ -35,7 +35,10 @@ define([ */ initObservable: function () { this._super() - .observe('visible required'); + .observe('visible') + .observe({ + required: !!+this.required + }); return this; }, diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php index c563b677620382c5b08c868fec60488247f6d359..e342206fe0b6e802e9ccf4e216e16d0cbcddbd22 100755 --- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php +++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php @@ -3657,6 +3657,8 @@ return [ ['Magento\Centinel\Test\TestCase\CentinelPaymentsValidCcTest'], ['Magento\Centinel\CreateOrderTest'], ['Magento\Payment\Model\Checks\PaymentMethodChecksInterface', 'Magento\Payment\Model\MethodInterface'], + ['Magento\Ui\DataProvider\EavValidationRul', 'Magento\Ui\DataProvider\EavValidationRules'], + ['Magento\Framework\View\Element\UiComponent\JsConfigInterface'], ['Magento\GiftMessage\Model\Plugin\TotalsDataProcessorPlugin'], ['Magento\Catalog\Model\Product\Attribute\Backend\Startdate', 'Magento\Catalog\Model\Attribute\Backend\Startdate'], ]; diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Provider/Component/Definition.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Provider/Component/Definition.php index 7e7e27bed013d0205c3f2f00c2112b9ba635b39e..5ea6d07f40505b7aff8d8d9bfeec2bba237410c4 100644 --- a/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Provider/Component/Definition.php +++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Provider/Component/Definition.php @@ -5,7 +5,9 @@ */ namespace Magento\Framework\View\Element\UiComponent\Config\Provider\Component; +use Magento\Framework\Phrase; use Magento\Framework\Config\CacheInterface; +use Magento\Framework\Exception\LocalizedException; use Magento\Framework\View\Element\UiComponent\Config\Converter; use Magento\Framework\View\Element\UiComponent\ArrayObjectFactory; use Magento\Framework\View\Element\UiComponent\Config\UiReaderInterface; @@ -66,9 +68,18 @@ class Definition * * @param string $name * @return array + * @throws LocalizedException */ public function getComponentData($name) { + if (!$this->componentData->offsetExists($name)) { + throw new LocalizedException( + new Phrase( + 'The requested component ("' . $name . '") is not found. ' + . 'Before using, you must add the implementation.' + ) + ); + } return (array) $this->componentData->offsetGet($name); } diff --git a/lib/internal/Magento/Framework/Webapi/Soap/ClientFactory.php b/lib/internal/Magento/Framework/Webapi/Soap/ClientFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..42d62ab67c334df5d03979441cafad633f0b769d --- /dev/null +++ b/lib/internal/Magento/Framework/Webapi/Soap/ClientFactory.php @@ -0,0 +1,25 @@ +<?php +/** + * Copyright © 2015 Magento. All rights reserved. + * See COPYING.txt for license details. + */ +namespace Magento\Framework\Webapi\Soap; + +/** + * Class ClientFactory + * @package Magento\Framework\Webapi\Soap + */ +class ClientFactory +{ + /** + * Factory method for \SoapClient + * + * @param string $wsdl + * @param array $options + * @return \SoapClient + */ + public function create($wsdl, array $options = []) + { + return new \SoapClient($wsdl, $options); + } +}