Skip to content

Commit e71bf77

Browse files
committed
MCP-288: [Load Cart Section] Replace Zend_Currency component with Intl NumberFormatter
- Fix integration test & update unit test;
1 parent 227db97 commit e71bf77

File tree

3 files changed

+137
-37
lines changed

3 files changed

+137
-37
lines changed

app/code/Magento/Directory/Model/Currency.php

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ public function __construct(
118118
array $data = [],
119119
CurrencyConfig $currencyConfig = null,
120120
LocalResolverInterface $localeResolver = null,
121-
\Magento\Framework\NumberFormatter $numberFormatterFactory = null
121+
\Magento\Framework\NumberFormatterFactory $numberFormatterFactory = null
122122
) {
123123
parent::__construct(
124124
$context,
@@ -366,11 +366,24 @@ public function formatTxt($price, $options = [])
366366
*/
367367
private function useNumberFormatter(array $options): bool
368368
{
369-
return (empty($options) || array_key_exists(LocaleCurrency::CURRENCY_OPTION_SYMBOL, $options)
370-
|| (array_key_exists(LocaleCurrency::CURRENCY_OPTION_DISPLAY, $options)
371-
&& ($options[LocaleCurrency::CURRENCY_OPTION_DISPLAY] === \Magento\Framework\Currency::NO_SYMBOL
372-
|| $options[LocaleCurrency::CURRENCY_OPTION_DISPLAY] === \Magento\Framework\Currency::USE_SYMBOL))
373-
|| array_key_exists('precision', $options));
369+
$allowedOptions = [
370+
'precision',
371+
LocaleCurrency::CURRENCY_OPTION_DISPLAY,
372+
LocaleCurrency::CURRENCY_OPTION_SYMBOL
373+
];
374+
375+
if (!empty(array_diff(array_keys($options), $allowedOptions))) {
376+
return false;
377+
}
378+
379+
if (array_key_exists('display', $options)
380+
&& $options['display'] !== \Magento\Framework\Currency::NO_SYMBOL
381+
&& $options['display'] !== \Magento\Framework\Currency::USE_SYMBOL
382+
) {
383+
return false;
384+
}
385+
386+
return true;
374387
}
375388

376389
/**
@@ -396,7 +409,9 @@ private function formatCurrency(string $price, array $options): string
396409

397410
$this->setOptions($options);
398411

399-
$formattedCurrency = $this->numberFormatter->formatCurrency($price, $this->getCode());
412+
$formattedCurrency = $this->numberFormatter->formatCurrency(
413+
$price, $this->getCode() ?? LocaleCurrency::DEFAULT_CURRENCY
414+
);
400415

401416
if (array_key_exists(LocaleCurrency::CURRENCY_OPTION_DISPLAY, $options)
402417
&& $options[LocaleCurrency::CURRENCY_OPTION_DISPLAY] === \Magento\Framework\Currency::NO_SYMBOL) {

app/code/Magento/Directory/Test/Unit/Model/CurrencyTest.php

Lines changed: 112 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
use Magento\Directory\Model\Currency;
1111
use Magento\Framework\Locale\CurrencyInterface;
12+
use Magento\Framework\Locale\ResolverInterface as LocalResolverInterface;
13+
use Magento\Framework\NumberFormatterFactory;
1214
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
1315
use PHPUnit\Framework\MockObject\MockObject;
1416
use PHPUnit\Framework\TestCase;
@@ -27,82 +29,165 @@ class CurrencyTest extends TestCase
2729
*/
2830
protected $localeCurrencyMock;
2931

32+
/**
33+
* @var LocalResolverInterface
34+
*/
35+
private $localeResolver;
36+
37+
/**
38+
* @var NumberFormatterFactory
39+
*/
40+
private $numberFormatterFactory;
41+
3042
protected function setUp(): void
3143
{
3244
$this->localeCurrencyMock = $this->getMockForAbstractClass(CurrencyInterface::class);
45+
$currencyFilterFactory = $this->getMockBuilder(\Magento\Directory\Model\Currency\FilterFactory::class)
46+
->disableOriginalConstructor()
47+
->getMock();
48+
$this->localeResolver = $this->getMockBuilder(LocalResolverInterface::class)
49+
->getMockForAbstractClass();
50+
$this->numberFormatterFactory = $this->getMockBuilder(NumberFormatterFactory::class)
51+
->disableOriginalConstructor()
52+
->setMethods(['create'])
53+
->getMock();
3354

3455
$objectManager = new ObjectManager($this);
3556
$this->currency = $objectManager->getObject(
3657
Currency::class,
3758
[
3859
'localeCurrency' => $this->localeCurrencyMock,
60+
'currencyFilterFactory' => $currencyFilterFactory,
61+
'localeResolver' => $this->localeResolver,
62+
'numberFormatterFactory' => $this->numberFormatterFactory,
3963
'data' => [
4064
'currency_code' => $this->currencyCode,
4165
]
4266
]
4367
);
4468
}
4569

46-
public function testGetCurrencySymbol()
70+
public function testGetCurrencySymbol(): void
4771
{
4872
$currencySymbol = '$';
4973

5074
$currencyMock = $this->getMockBuilder(\Magento\Framework\Currency::class)
5175
->disableOriginalConstructor()
5276
->getMock();
53-
$currencyMock->expects($this->once())
77+
$currencyMock->expects(self::once())
5478
->method('getSymbol')
5579
->willReturn($currencySymbol);
5680

57-
$this->localeCurrencyMock->expects($this->once())
81+
$this->localeCurrencyMock->expects(self::once())
5882
->method('getCurrency')
5983
->with($this->currencyCode)
6084
->willReturn($currencyMock);
61-
$this->assertEquals($currencySymbol, $this->currency->getCurrencySymbol());
85+
self::assertEquals($currencySymbol, $this->currency->getCurrencySymbol());
6286
}
6387

6488
/**
6589
* @dataProvider getOutputFormatDataProvider
66-
* @param $withCurrency
67-
* @param $noCurrency
6890
* @param $expected
91+
* @param $locale
6992
*/
70-
public function testGetOutputFormat($withCurrency, $noCurrency, $expected)
93+
public function testGetOutputFormat($expected, $locale): void
7194
{
72-
$currencyMock = $this->getMockBuilder(\Magento\Framework\Currency::class)
73-
->disableOriginalConstructor()
74-
->getMock();
75-
$currencyMock->expects($this->at(0))
76-
->method('toCurrency')
77-
->willReturn($withCurrency);
78-
$currencyMock->expects($this->at(1))
79-
->method('toCurrency')
80-
->willReturn($noCurrency);
81-
$this->localeCurrencyMock->expects($this->atLeastOnce())
82-
->method('getCurrency')
83-
->with($this->currencyCode)
84-
->willReturn($currencyMock);
85-
$this->assertEquals($expected, $this->currency->getOutputFormat());
95+
$this->localeResolver->method('getLocale')->willReturn($locale);
96+
$this->numberFormatterFactory
97+
->method('create')
98+
->with(['locale' => $locale, 'style' => 2])
99+
->willReturn(new \NumberFormatter($locale, 2));
100+
self::assertEquals($expected, $this->currency->getOutputFormat());
86101
}
87102

88103
/**
89-
* Return data sets for testGetCurrencySymbol()
104+
* Return data sets for testGetOutputFormat()
90105
*
91106
* @return array
92107
*/
93-
public function getOutputFormatDataProvider()
108+
public function getOutputFormatDataProvider(): array
94109
{
95110
return [
96111
'no_unicode' => [
97-
'withCurrency' => '$0.00',
98-
'noCurrency' => '0.00',
99112
'expected' => '$%s',
113+
'locale' => 'en_US'
100114
],
101115
'arabic_unicode' => [
102-
'withCurrency' => json_decode('"\u200E"') . '$0.00',
103-
'noCurrency' => json_decode('"\u200E"') . '0.00',
104116
'expected' => json_decode('"\u200E"') . '$%s',
117+
'locale' => 'fa_IR'
105118
]
106119
];
107120
}
121+
122+
/**
123+
* @dataProvider getFormatTxtNumberFormatterDataProvider
124+
* @param string $price
125+
* @param array $options
126+
* @param string $locale
127+
* @param string $expected
128+
*/
129+
public function testFormatTxtWithNumberFormatter(
130+
string $price,
131+
array $options,
132+
string $locale,
133+
string $expected
134+
): void {
135+
$this->localeResolver->expects(self::once())->method('getLocale')->willReturn($locale);
136+
$this->numberFormatterFactory
137+
->expects(self::once())
138+
->method('create')
139+
->with(['locale' => $locale, 'style' => 2])
140+
->willReturn(new \NumberFormatter($locale, 2));
141+
142+
self::assertEquals($expected, $this->currency->formatTxt($price, $options));
143+
}
144+
145+
/**
146+
* Return data sets for testFormatTxtWithNumberFormatter()
147+
*
148+
* @return array
149+
*/
150+
public function getFormatTxtNumberFormatterDataProvider(): array
151+
{
152+
return [
153+
['9999', [], 'en_US', '$9,999.00'],
154+
['9999', ['display' => \Magento\Framework\Currency::NO_SYMBOL, 'precision' => 2], 'en_US', '9,999.00'],
155+
['9999', ['display' => \Magento\Framework\Currency::NO_SYMBOL], 'en_US', '9,999.00'],
156+
['9999', ['precision' => 1], 'en_US', '$9,999.0']
157+
];
158+
}
159+
160+
/**
161+
* @dataProvider getFormatTxtZendCurrencyDataProvider
162+
* @param string $price
163+
* @param array $options
164+
* @param string $expected
165+
* @throws \Zend_Currency_Exception
166+
*/
167+
public function testFormatTxtWithZendCurrency(string $price, array $options, string $expected): void
168+
{
169+
$this->localeCurrencyMock
170+
->expects(self::once())
171+
->method('getCurrency')
172+
->with($this->currencyCode)
173+
->willReturn(new \Zend_Currency($options, 'en_US'));
174+
175+
self::assertEquals($expected, $this->currency->formatTxt($price, $options));
176+
}
177+
178+
/**
179+
* Return data sets for testFormatTxtWithZendCurrency()
180+
*
181+
* @return array
182+
*/
183+
public function getFormatTxtZendCurrencyDataProvider(): array
184+
{
185+
return [
186+
['9999', ['display' => \Magento\Framework\Currency::USE_SYMBOL, 'foo' => 'bar'], '$9,999.00'],
187+
['9999', ['display' => \Magento\Framework\Currency::USE_SHORTNAME, 'foo' => 'bar'], 'USD9,999.00'],
188+
['9999', ['currency' => 'USD'], '$9,999.00'],
189+
['9999', ['currency' => 'CNY'], 'CN¥9,999.00'],
190+
['9999', ['locale' => 'fr_FR'], '9 999,00 $']
191+
];
192+
}
108193
}

dev/tests/integration/testsuite/Magento/Catalog/Block/Product/View/MultiStoreCurrencyTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ protected function setUp(): void
5252
public function testMultiStoreRenderPrice(): void
5353
{
5454
$this->localeResolver->setLocale('zh_CN');
55-
$this->assertProductStorePrice('simple2', '70.00');
55+
$this->assertProductStorePrice('simple2', '¥70.00');
5656

5757
$this->reloadProductPriceInfo();
5858
$this->localeResolver->setLocale('uk_UA');
@@ -76,7 +76,7 @@ public function testMultiStoreRenderPrice(): void
7676
public function testMultiStoreRenderSpecialPrice(): void
7777
{
7878
$this->localeResolver->setLocale('zh_CN');
79-
$this->assertProductStorePrice('simple', 'Special Price 41.93 Regular Price 70.00');
79+
$this->assertProductStorePrice('simple', 'Special Price ¥41.93 Regular Price ¥70.00');
8080

8181
$this->reloadProductPriceInfo();
8282
$this->localeResolver->setLocale('uk_UA');
@@ -102,7 +102,7 @@ public function testMultiStoreRenderTierPrice(): void
102102
$this->localeResolver->setLocale('zh_CN');
103103
$this->assertProductStorePrice(
104104
'simple-product-tax-none',
105-
'Buy 2 for 280.00 each and save 80%',
105+
'Buy 2 for ¥280.00 each and save 80%',
106106
'default',
107107
self::TIER_PRICE_BLOCK_NAME
108108
);

0 commit comments

Comments
 (0)