Skip to content

Commit a408079

Browse files
committed
Remove dependency of date renderer on global state locale
Summary == This patch introduces a test to reproduce the bug described in issue #1468. `\Magento\Reports\Test\Unit\Block\Adminhtml\Sales\Grid\Column\Renderer\DateTest::testDateIsRenderedIndependentOfSystemDefaultLocale` The existing test `testRender` was refactored a little to avoid code duplication with the new test. The patch also includes a fix for the issue, which simply is to pass the locale that was used to create the date format as a third argument to `\IntlDateFormatter::formatObject()`. The following contents of the commit message are a slightly abbreviated copy of the issue #1468. ----- The method `\Magento\Reports\Block\Adminhtml\Sales\Grid\Column\Renderer\Date::render()` creates it's return value by calling `\IntlDateFormatter::formatObject($date, $format);`. Please note that `formatObject()` is called without the optional third parameter specifying the locale, which means that the default ICU locale will be used. Here is the method signature from the [PHP manual](http://php.net/manual/en/intldateformatter.formatobject.php): ``` public static string IntlDateFormatter::formatObject ( object $object [, mixed $format = NULL [, string $locale = NULL ]] ) ``` If the third locale is not specified as an argument, the default ICU locale is used. If no default locale is set, this value will default to the system default. This causes the test `\Magento\Reports\Test\Unit\Block\Adminhtml\Sales\Grid\Column\Renderer\DateTest::testRender()` to fail sometimes, because it depends on the system locale. If the system locale is set to a **en_US** locale the test is green. If it is a non-english locale, the test fails, because the expected output does not match the expected format. `` 1) Magento\Reports\Test\Unit\Block\Adminhtml\Sales\Grid\Column\Renderer\DateTest::testRender with data set #4 ('2014-06-25', 'en_US', 'period', 'day', 'Jun 25, 2014') Failed asserting that two strings are equal. --- Expected +++ Actual @@ @@ -'Jun 25, 2014' +'Juni 25, 2014' ``` The above output is from a dev machine where the system locale is set to **de_DE.UTF-8**. To summarize: The date format is correctly constructed for a given locale. However, the date constants rendered do not necessarily match that locale.
1 parent c028812 commit a408079

File tree

2 files changed

+79
-29
lines changed
  • app/code/Magento/Reports
    • Block/Adminhtml/Sales/Grid/Column/Renderer
    • Test/Unit/Block/Adminhtml/Sales/Grid/Column/Renderer

2 files changed

+79
-29
lines changed

app/code/Magento/Reports/Block/Adminhtml/Sales/Grid/Column/Renderer/Date.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public function render(\Magento\Framework\Object $row)
7878
} else {
7979
$date = $this->_localeDate->date(new \DateTime($data), null, false);
8080
}
81-
return \IntlDateFormatter::formatObject($date, $format);
81+
return \IntlDateFormatter::formatObject($date, $format, $this->_localeResolver->getLocale());
8282
}
8383
return $this->getColumn()->getDefault();
8484
}

app/code/Magento/Reports/Test/Unit/Block/Adminhtml/Sales/Grid/Column/Renderer/DateTest.php

+78-28
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,44 @@ class DateTest extends \PHPUnit_Framework_TestCase
3030
*/
3131
protected $localeDate;
3232

33+
/**
34+
* @var string
35+
*/
36+
private $globalStateLocaleBackup;
37+
38+
/**
39+
* @param string $locale
40+
*/
41+
private function mockGridDateRendererBehaviorWithLocale($locale)
42+
{
43+
$this->resolverMock->expects($this->any())->method('getLocale')->willReturn($locale);
44+
$this->localeDate->expects($this->any())->method('getDateFormat')->willReturnCallback(
45+
function ($value) use ($locale) {
46+
return (new \IntlDateFormatter(
47+
$locale,
48+
$value,
49+
\IntlDateFormatter::NONE
50+
))->getPattern();
51+
}
52+
);
53+
}
54+
55+
/**
56+
* @param string $objectDataIndex
57+
* @param string $periodType
58+
*/
59+
private function mockGridDateColumnConfig($objectDataIndex, $periodType)
60+
{
61+
$columnMock = $this->getMockBuilder('Magento\Backend\Block\Widget\Grid\Column')
62+
->disableOriginalConstructor()
63+
->setMethods(['getIndex', 'getPeriodType'])
64+
->getMock();
65+
$columnMock->expects($this->once())->method('getIndex')->willReturn($objectDataIndex);
66+
$columnMock->expects($this->atLeastOnce())->method('getPeriodType')->willReturn($periodType);
67+
68+
$this->date->setColumn($columnMock);
69+
}
70+
3371
/**
3472
* {@inheritDoc}
3573
*/
@@ -41,15 +79,15 @@ protected function setUp()
4179
$this->localeDate
4280
->expects($this->once())
4381
->method('date')
44-
->will($this->returnArgument(0));
82+
->willReturnArgument(0);
4583

4684
$this->contextMock = $this->getMockBuilder('Magento\Backend\Block\Context')
4785
->disableOriginalConstructor()
4886
->getMock();
4987
$this->contextMock
5088
->expects($this->once())
5189
->method('getLocaleDate')
52-
->will($this->returnValue($this->localeDate));
90+
->willReturn($this->localeDate);
5391

5492
$this->resolverMock = $this->getMockBuilder('Magento\Framework\Locale\ResolverInterface')
5593
->getMock();
@@ -58,43 +96,41 @@ protected function setUp()
5896
$this->contextMock,
5997
$this->resolverMock
6098
);
99+
100+
$this->globalStateLocaleBackup = \Locale::getDefault();
101+
}
102+
103+
protected function tearDown()
104+
{
105+
$this->restoreTheDefaultLocaleGlobalState();
106+
}
107+
108+
private function restoreTheDefaultLocaleGlobalState()
109+
{
110+
if (\Locale::getDefault() !== $this->globalStateLocaleBackup) {
111+
\Locale::setDefault($this->globalStateLocaleBackup);
112+
}
61113
}
62114

63115
/**
64116
* @param string $data
65-
* @param string $index
66117
* @param string $locale
118+
* @param string $index
67119
* @param string $period
68120
* @param string $result
69121
* @dataProvider datesDataProvider
70122
* @return void
71123
*/
72-
public function testRender($data, $index, $locale, $period, $result)
124+
public function testRender($data, $locale, $index, $period, $result)
73125
{
74-
$this->resolverMock->expects($this->any())->method('getLocale')->will($this->returnValue($locale));
75-
$this->localeDate->expects($this->any())->method('getDateFormat')->willReturnCallback(
76-
function ($value) use ($locale) {
77-
return (new \IntlDateFormatter(
78-
$locale,
79-
$value,
80-
\IntlDateFormatter::NONE
81-
))->getPattern();
82-
}
83-
);
126+
$this->mockGridDateRendererBehaviorWithLocale($locale);
127+
$this->mockGridDateColumnConfig($index, $period);
84128

85129
$objectMock = $this->getMockBuilder('Magento\Framework\Object')
86130
->setMethods(['getData'])
87131
->getMock();
88-
$objectMock->expects($this->once())->method('getData')->will($this->returnValue($data));
89-
90-
$columnMock = $this->getMockBuilder('Magento\Backend\Block\Widget\Grid\Column')
91-
->disableOriginalConstructor()
92-
->setMethods(['getIndex', 'getPeriodType'])
93-
->getMock();
94-
$columnMock->expects($this->once())->method('getIndex')->will($this->returnValue($index));
95-
$columnMock->expects($this->atLeastOnce())->method('getPeriodType')->will($this->returnValue($period));
132+
$objectMock->expects($this->once())->method('getData')->willReturn($data);
96133

97-
$this->date->setColumn($columnMock);
98134

99135
$this->assertEquals($result, $this->date->render($objectMock));
100136
}
@@ -107,39 +143,53 @@ public function datesDataProvider()
107143
return [
108144
[
109145
'data' => '2000',
110-
'index' => 'period',
111146
'locale' => 'en_US',
147+
'index' => 'period',
112148
'period' => 'year',
113149
'result' => '2000'
114150
],
115151
[
116152
'data' => '2030',
117-
'index' => 'period',
118153
'locale' => 'en_US',
154+
'index' => 'period',
119155
'period' => 'year',
120156
'result' => '2030'
121157
],
122158
[
123159
'data' => '2000-01',
124-
'index' => 'period',
125160
'locale' => 'en_US',
161+
'index' => 'period',
126162
'period' => 'month',
127163
'result' => '1/2000'
128164
],
129165
[
130166
'data' => '2030-12',
131-
'index' => 'period',
132167
'locale' => 'en_US',
168+
'index' => 'period',
133169
'period' => 'month',
134170
'result' => '12/2030'
135171
],
136172
[
137173
'data' => '2014-06-25',
138-
'index' => 'period',
139174
'locale' => 'en_US',
175+
'index' => 'period',
140176
'period' => 'day',
141177
'result' => 'Jun 25, 2014'
142178
]
143179
];
144180
}
181+
182+
public function testDateIsRenderedIndependentOfSystemDefaultLocale()
183+
{
184+
\Locale::setDefault('de_DE');
185+
$this->mockGridDateRendererBehaviorWithLocale('en_US');
186+
$this->mockGridDateColumnConfig('period', 'day');
187+
188+
$objectMock = $this->getMockBuilder('Magento\Framework\Object')
189+
->setMethods(['getData'])
190+
->getMock();
191+
$objectMock->expects($this->any())->method('getData')->willReturn('2014-06-25');
192+
193+
$this->assertEquals('Jun 25, 2014', $this->date->render($objectMock));
194+
}
145195
}

0 commit comments

Comments
 (0)