Skip to content

Commit 99267b2

Browse files
[Magento Community Engineering] Community Contributions - 2.3-develop
- merged latest code from mainline branch
2 parents 95d55e6 + 8439b5a commit 99267b2

File tree

42 files changed

+869
-272
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+869
-272
lines changed

app/code/Magento/CatalogImportExport/Model/Import/Uploader.php

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,6 @@ class Uploader extends \Magento\MediaStorage\Model\File\Uploader
3636
*/
3737
protected $_tmpDir = '';
3838

39-
/**
40-
* Download directory for url-based resources.
41-
*
42-
* @var string
43-
*/
44-
private $downloadDir;
45-
4639
/**
4740
* Destination directory.
4841
*
@@ -151,7 +144,6 @@ public function __construct(
151144
$this->_setUploadFile($filePath);
152145
}
153146
$this->random = $random ?: ObjectManager::getInstance()->get(\Magento\Framework\Math\Random::class);
154-
$this->downloadDir = DirectoryList::getDefaultConfig()[DirectoryList::TMP][DirectoryList::PATH];
155147
}
156148

157149
/**
@@ -187,8 +179,7 @@ public function move($fileName, $renameFileOff = false)
187179
$driver = ($matches[0] === $this->httpScheme) ? DriverPool::HTTP : DriverPool::HTTPS;
188180
$tmpFilePath = $this->downloadFileFromUrl($url, $driver);
189181
} else {
190-
$tmpDir = $this->getTmpDir() ? ($this->getTmpDir() . '/') : '';
191-
$tmpFilePath = $this->_directory->getRelativePath($tmpDir . $fileName);
182+
$tmpFilePath = $this->_directory->getRelativePath($this->getTempFilePath($fileName));
192183
}
193184

194185
$this->_setUploadFile($tmpFilePath);
@@ -225,8 +216,13 @@ private function downloadFileFromUrl($url, $driver)
225216
$tmpFileName = str_replace(".$fileExtension", '', $fileName);
226217
$tmpFileName .= '_' . $this->random->getRandomString(16);
227218
$tmpFileName .= $fileExtension ? ".$fileExtension" : '';
228-
$tmpFilePath = $this->_directory->getRelativePath($this->downloadDir . '/' . $tmpFileName);
219+
$tmpFilePath = $this->_directory->getRelativePath($this->getTempFilePath($tmpFileName));
229220

221+
if (!$this->_directory->isWritable($this->getTmpDir())) {
222+
throw new \Magento\Framework\Exception\LocalizedException(
223+
__('Import images directory must be writable in order to process remote images.')
224+
);
225+
}
230226
$this->_directory->writeFile(
231227
$tmpFilePath,
232228
$this->_readFactory->create($url, $driver)->readAll()
@@ -402,6 +398,19 @@ protected function _moveFile($tmpPath, $destPath)
402398
}
403399
}
404400

401+
/**
402+
* Append temp path to filename
403+
*
404+
* @param string $filename
405+
* @return string
406+
*/
407+
private function getTempFilePath(string $filename): string
408+
{
409+
return $this->getTmpDir()
410+
? rtrim($this->getTmpDir(), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR . $filename
411+
: $filename;
412+
}
413+
405414
/**
406415
* @inheritdoc
407416
*/

app/code/Magento/CatalogImportExport/Test/Mftf/ActionGroup/AdminExportActionGroup.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
<wait stepKey="waitForScroll" time="5"/>
4242
<click selector="{{AdminExportAttributeSection.continueBtn}}" stepKey="clickContinueButton"/>
4343
<wait stepKey="waitForClick" time="5"/>
44-
<see selector="{{AdminMessagesSection.success}}" userInput="Message is added to queue, wait to get your file soon" stepKey="seeSuccessMessage"/>
44+
<see selector="{{AdminMessagesSection.success}}" userInput="Message is added to queue, wait to get your file soon. Make sure your cron job is running to export the file" stepKey="seeSuccessMessage"/>
4545
</actionGroup>
4646

4747
<!-- Download first file in the grid -->

app/code/Magento/CatalogImportExport/Test/Unit/Model/Import/UploaderTest.php

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ public function testMoveFileUrl($fileUrl, $expectedHost, $expectedFileName, $che
128128
{
129129
$tmpDir = 'var/tmp';
130130
$destDir = 'var/dest/dir';
131+
$this->uploader->method('getTmpDir')->willReturn($tmpDir);
131132

132133
// Expected invocation to validate file extension
133134
$this->uploader->expects($this->exactly($checkAllowedExtension))->method('checkAllowedExtension')
@@ -159,9 +160,11 @@ public function testMoveFileUrl($fileUrl, $expectedHost, $expectedFileName, $che
159160
$this->directoryMock->expects($this->any())->method('writeFile')
160161
->will($this->returnValue($expectedFileName));
161162

162-
// Expected invocations to move the temp file to the destination directory
163-
$this->directoryMock->expects($this->once())->method('isWritable')
164-
->with($destDir)
163+
// Expected invocations save the downloaded file to temp file
164+
// and move the temp file to the destination directory
165+
$this->directoryMock->expects($this->exactly(2))
166+
->method('isWritable')
167+
->withConsecutive([$destDir], [$tmpDir])
165168
->willReturn(true);
166169
$this->directoryMock->expects($this->once())->method('getAbsolutePath')
167170
->with($destDir)
@@ -172,9 +175,6 @@ public function testMoveFileUrl($fileUrl, $expectedHost, $expectedFileName, $che
172175
->with($destDir . '/' . $expectedFileName)
173176
->willReturn(['name' => $expectedFileName, 'path' => 'absPath']);
174177

175-
// Do not use configured temp directory
176-
$this->uploader->expects($this->never())->method('getTmpDir');
177-
178178
$this->uploader->setDestDir($destDir);
179179
$result = $this->uploader->move($fileUrl);
180180

app/code/Magento/Checkout/view/frontend/web/js/view/form/element/email.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,12 +145,19 @@ define([
145145
var loginFormSelector = 'form[data-role=email-with-possible-login]',
146146
usernameSelector = loginFormSelector + ' input[name=username]',
147147
loginForm = $(loginFormSelector),
148-
validator;
148+
validator,
149+
valid;
149150

150151
loginForm.validation();
151152

152153
if (focused === false && !!this.email()) {
153-
return !!$(usernameSelector).valid();
154+
valid = !!$(usernameSelector).valid();
155+
156+
if (valid) {
157+
$(usernameSelector).removeAttr('aria-invalid aria-describedby');
158+
}
159+
160+
return valid;
154161
}
155162

156163
validator = loginForm.validate();

app/code/Magento/CurrencySymbol/Controller/Adminhtml/System/Currency/FetchRates.php

Lines changed: 57 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,40 +3,83 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
declare(strict_types=1);
67

78
namespace Magento\CurrencySymbol\Controller\Adminhtml\System\Currency;
89

10+
use Magento\Backend\App\Action\Context;
11+
use Magento\Backend\Model\View\Result\Redirect;
12+
use Magento\Backend\Model\Session as BackendSession;
13+
use Magento\CurrencySymbol\Controller\Adminhtml\System\Currency as CurrencyAction;
14+
use Magento\Directory\Model\Currency\Import\Factory as CurrencyImportFactory;
15+
use Magento\Directory\Model\Currency\Import\ImportInterface as CurrencyImport;
916
use Magento\Framework\App\Action\HttpGetActionInterface;
1017
use Magento\Framework\App\Action\HttpPostActionInterface as HttpPostActionInterface;
18+
use Magento\Framework\App\ObjectManager;
19+
use Magento\Framework\Escaper;
1120
use Magento\Framework\Exception\LocalizedException;
1221
use Magento\Framework\Controller\ResultFactory;
13-
use Magento\CurrencySymbol\Controller\Adminhtml\System\Currency as CurrencyAction;
22+
use Magento\Framework\Registry;
23+
use Exception;
1424

1525
/**
16-
* Class FetchRates
26+
* Fetch rates controller.
1727
*/
1828
class FetchRates extends CurrencyAction implements HttpGetActionInterface, HttpPostActionInterface
1929
{
30+
/**
31+
* @var BackendSession
32+
*/
33+
private $backendSession;
34+
35+
/**
36+
* @var CurrencyImportFactory
37+
*/
38+
private $currencyImportFactory;
39+
40+
/**
41+
* @var Escaper
42+
*/
43+
private $escaper;
44+
45+
/**
46+
* @param Context $context
47+
* @param Registry $coreRegistry
48+
* @param BackendSession|null $backendSession
49+
* @param CurrencyImportFactory|null $currencyImportFactory
50+
* @param Escaper|null $escaper
51+
*/
52+
public function __construct(
53+
Context $context,
54+
Registry $coreRegistry,
55+
?BackendSession $backendSession = null,
56+
?CurrencyImportFactory $currencyImportFactory = null,
57+
?Escaper $escaper = null
58+
) {
59+
parent::__construct($context, $coreRegistry);
60+
$this->backendSession = $backendSession ?: ObjectManager::getInstance()->get(BackendSession::class);
61+
$this->currencyImportFactory = $currencyImportFactory ?: ObjectManager::getInstance()
62+
->get(CurrencyImportFactory::class);
63+
$this->escaper = $escaper ?: ObjectManager::getInstance()->get(Escaper::class);
64+
}
65+
2066
/**
2167
* Fetch rates action
2268
*
23-
* @return \Magento\Backend\Model\View\Result\Redirect
69+
* @return Redirect
2470
*/
2571
public function execute()
2672
{
27-
/** @var \Magento\Backend\Model\Session $backendSession */
28-
$backendSession = $this->_objectManager->get(\Magento\Backend\Model\Session::class);
2973
try {
3074
$service = $this->getRequest()->getParam('rate_services');
3175
$this->_getSession()->setCurrencyRateService($service);
3276
if (!$service) {
3377
throw new LocalizedException(__('The Import Service is incorrect. Verify the service and try again.'));
3478
}
3579
try {
36-
/** @var \Magento\Directory\Model\Currency\Import\ImportInterface $importModel */
37-
$importModel = $this->_objectManager->get(\Magento\Directory\Model\Currency\Import\Factory::class)
38-
->create($service);
39-
} catch (\Exception $e) {
80+
/** @var CurrencyImport $importModel */
81+
$importModel = $this->currencyImportFactory->create($service);
82+
} catch (Exception $e) {
4083
throw new LocalizedException(
4184
__("The import model can't be initialized. Verify the model and try again.")
4285
);
@@ -45,7 +88,8 @@ public function execute()
4588
$errors = $importModel->getMessages();
4689
if (count($errors) > 0) {
4790
foreach ($errors as $error) {
48-
$this->messageManager->addWarningMessage($error);
91+
$escapedError = $this->escaper->escapeHtml($error);
92+
$this->messageManager->addWarningMessage($escapedError);
4993
}
5094
$this->messageManager->addWarningMessage(
5195
__('Click "Save" to apply the rates we found.')
@@ -54,12 +98,12 @@ public function execute()
5498
$this->messageManager->addSuccessMessage(__('Click "Save" to apply the rates we found.'));
5599
}
56100

57-
$backendSession->setRates($rates);
58-
} catch (\Exception $e) {
101+
$this->backendSession->setRates($rates);
102+
} catch (Exception $e) {
59103
$this->messageManager->addErrorMessage($e->getMessage());
60104
}
61105

62-
/** @var \Magento\Backend\Model\View\Result\Redirect $resultRedirect */
106+
/** @var Redirect $resultRedirect */
63107
$resultRedirect = $this->resultFactory->create(ResultFactory::TYPE_REDIRECT);
64108
return $resultRedirect->setPath('adminhtml/*/');
65109
}

app/code/Magento/CurrencySymbol/Test/Mftf/ActionGroup/AdminCurrencyRatesActionGroup.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,19 @@
88

99
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1010
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="AdminImportCurrencyRatesActionGroup">
12+
<arguments>
13+
<argument name="rateService" type="string" defaultValue="Fixer.io"/>
14+
</arguments>
15+
<selectOption selector="{{AdminCurrencyRatesSection.rateService}}" userInput="{{rateService}}" stepKey="selectRateService"/>
16+
<click selector="{{AdminCurrencyRatesSection.import}}" stepKey="clickImport"/>
17+
<waitForElementVisible selector="{{AdminCurrencyRatesSection.oldRate}}" stepKey="waitForOldRateVisible"/>
18+
</actionGroup>
19+
<actionGroup name="AdminSaveCurrencyRatesActionGroup">
20+
<click selector="{{AdminCurrencyRatesSection.saveCurrencyRates}}" stepKey="clickSaveCurrencyRates"/>
21+
<waitForPageLoad stepKey="waitForSave"/>
22+
<see selector="{{AdminMessagesSection.success}}" userInput="All valid rates have been saved." stepKey="seeSuccessMessage"/>
23+
</actionGroup>
1124
<actionGroup name="AdminSetCurrencyRatesActionGroup">
1225
<arguments>
1326
<argument name="firstCurrency" type="string" defaultValue="USD"/>

app/code/Magento/CurrencySymbol/Test/Mftf/ActionGroup/StorefrontCurrencyRatesActionGroup.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@
88

99
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1010
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="StorefrontSwitchCurrencyActionGroup">
12+
<arguments>
13+
<argument name="currency" type="string" defaultValue="EUR"/>
14+
</arguments>
15+
<click selector="{{StorefrontSwitchCurrencyRatesSection.currencyToggle}}" stepKey="openToggle"/>
16+
<waitForElementVisible selector="{{StorefrontSwitchCurrencyRatesSection.currency(currency)}}" stepKey="waitForCurrency"/>
17+
<click selector="{{StorefrontSwitchCurrencyRatesSection.currency(currency)}}" stepKey="chooseCurrency"/>
18+
<see selector="{{StorefrontSwitchCurrencyRatesSection.selectedCurrency}}" userInput="{{currency}}" stepKey="seeSelectedCurrency"/>
19+
</actionGroup>
1120
<actionGroup name="StorefrontSwitchCurrency">
1221
<arguments>
1322
<argument name="currency" type="string" defaultValue="EUR"/>

app/code/Magento/CurrencySymbol/Test/Mftf/Section/AdminCurrencyRatesSection.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
<element name="import" type="button" selector="//button[@title='Import']"/>
1313
<element name="saveCurrencyRates" type="button" selector="//button[@title='Save Currency Rates']"/>
1414
<element name="oldRate" type="text" selector="//div[contains(@class, 'admin__field-note') and contains(text(), 'Old rate:')]/strong"/>
15+
<element name="rateService" type="select" selector="#rate_services"/>
1516
<element name="currencyRate" type="input" selector="input[name='rate[{{fistCurrency}}][{{secondCurrency}}]']" parameterized="true"/>
1617
</section>
1718
</sections>

app/code/Magento/CurrencySymbol/Test/Mftf/Section/StorefrontSwitchCurrencyRatesSection.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1010
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd">
1111
<section name="StorefrontSwitchCurrencyRatesSection">
12+
<element name="currencyToggle" type="select" selector="#switcher-currency-trigger" timeout="30"/>
1213
<element name="currencyTrigger" type="select" selector="#switcher-currency-trigger" timeout="30"/>
1314
<element name="currency" type="button" selector="//div[@id='switcher-currency-trigger']/following-sibling::ul//a[contains(text(), '{{currency}}')]" parameterized="true" timeout="10"/>
1415
<element name="selectedCurrency" type="text" selector="#switcher-currency-trigger span"/>
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<tests xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/testSchema.xsd">
11+
<test name="AdminCurrencyConverterAPIConfigurationTest">
12+
<annotations>
13+
<features value="CurrencySymbol"/>
14+
<stories value="Currency Rates"/>
15+
<title value="Currency Converter API configuration"/>
16+
<description value="Currency Converter API configuration"/>
17+
<severity value="CRITICAL"/>
18+
<testCaseId value="MC-19272"/>
19+
<useCaseId value="MAGETWO-94919"/>
20+
<group value="currency"/>
21+
<skip>
22+
<issueId value="MQE-1578"/>
23+
</skip>
24+
</annotations>
25+
<before>
26+
<!--Set currency allow config-->
27+
<magentoCLI command="config:set currency/options/allow RHD,CHW,CHE,AMD,EUR,USD" stepKey="setCurrencyAllow"/>
28+
<!--TODO: Add Api key-->
29+
<magentoCLI command="cache:flush" stepKey="clearCache"/>
30+
<!--Create product-->
31+
<createData entity="SimpleSubCategory" stepKey="createCategory"/>
32+
<createData entity="SimpleProduct" stepKey="createProduct">
33+
<requiredEntity createDataKey="createCategory"/>
34+
</createData>
35+
<actionGroup ref="LoginAsAdmin" stepKey="loginAsAdmin"/>
36+
</before>
37+
<after>
38+
<!--Set currency allow previous config-->
39+
<magentoCLI command="config:set currency/options/allow EUR,USD" stepKey="setCurrencyAllow"/>
40+
<!--Delete created data-->
41+
<deleteData createDataKey="createProduct" stepKey="deleteProduct"/>
42+
<deleteData createDataKey="createCategory" stepKey="deleteCategory"/>
43+
<actionGroup ref="logout" stepKey="logout"/>
44+
</after>
45+
<!--Import rates from Currency Converter API-->
46+
<amOnPage url="{{AdminCurrencyRatesPage.url}}" stepKey="onCurrencyRatePage"/>
47+
<actionGroup ref="AdminImportCurrencyRatesActionGroup" stepKey="importCurrencyRates">
48+
<argument name="rateService" value="Currency Converter API"/>
49+
</actionGroup>
50+
<see selector="{{AdminMessagesSection.warningMessage}}" userInput='Click "Save" to apply the rates we found.' stepKey="seeImportMessage"/>
51+
<see selector="{{AdminMessagesSection.warningMessage}}" userInput="We can't retrieve a rate from https://free.currconv.com for CHE." stepKey="seeWarningMessageForCHE"/>
52+
<see selector="{{AdminMessagesSection.warningMessage}}" userInput="We can't retrieve a rate from https://free.currconv.com for RHD." stepKey="seeWarningMessageForRHD"/>
53+
<see selector="{{AdminMessagesSection.warningMessage}}" userInput="We can't retrieve a rate from https://free.currconv.com for CHW." stepKey="seeWarningMessageForCHW"/>
54+
<actionGroup ref="AdminSaveCurrencyRatesActionGroup" stepKey="saveCurrencyRates"/>
55+
<see selector="{{AdminMessagesSection.warningMessage}}" userInput='Please correct the input data for "USD => CHE" rate' stepKey="seeCHEMessageAfterSave"/>
56+
<see selector="{{AdminMessagesSection.warningMessage}}" userInput='Please correct the input data for "USD => RHD" rate' stepKey="seeRHDMessageAfterSave"/>
57+
<see selector="{{AdminMessagesSection.warningMessage}}" userInput='Please correct the input data for "USD => CHW" rate' stepKey="seeCHWMessageAfterSave"/>
58+
<!--Go to the Storefront and check currency rates-->
59+
<amOnPage url="{{StorefrontCategoryPage.url($$createCategory.name$$)}}" stepKey="onCategoryPage"/>
60+
<waitForPageLoad stepKey="waitForCategoryPageLoad"/>
61+
<actionGroup ref="StorefrontSwitchCurrencyActionGroup" stepKey="switchAMDCurrency">
62+
<argument name="currency" value="AMD"/>
63+
</actionGroup>
64+
<see selector="{{StorefrontCategoryMainSection.productPrice}}" userInput="AMD" stepKey="seeAMDInPrice"/>
65+
<actionGroup ref="StorefrontSwitchCurrencyActionGroup" stepKey="switchEURCurrency">
66+
<argument name="currency" value="EUR"/>
67+
</actionGroup>
68+
<see selector="{{StorefrontCategoryMainSection.productPrice}}" userInput="" stepKey="seeEURInPrice"/>
69+
<!--Set allowed currencies greater then 10-->
70+
<magentoCLI command="config:set currency/options/allow RHD,CHW,YER,ZMK,CHE,EUR,USD,AMD,RUB,DZD,ARS,AWG" stepKey="setCurrencyAllow"/>
71+
<magentoCLI command="cache:flush" stepKey="clearCache"/>
72+
<!--Import rates from Currency Converter API with currencies greater then 10-->
73+
<amOnPage url="{{AdminCurrencyRatesPage.url}}" stepKey="onCurrencyRatePageSecondTime"/>
74+
<actionGroup ref="AdminImportCurrencyRatesActionGroup" stepKey="importCurrencyRatesGreaterThen10">
75+
<argument name="rateService" value="Currency Converter API"/>
76+
</actionGroup>
77+
<see selector="{{AdminMessagesSection.warningMessage}}" userInput="Too many pairs. Maximum of 10 is supported for the free version." stepKey="seeTooManyPairsMessage"/>
78+
</test>
79+
</tests>

0 commit comments

Comments
 (0)