Skip to content

Commit 9461139

Browse files
committed
ACP2E-4354: Customer create form error messages are not translated
1 parent 648dd92 commit 9461139

File tree

1 file changed

+225
-0
lines changed

1 file changed

+225
-0
lines changed
Lines changed: 225 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,225 @@
1+
<?php
2+
/**
3+
* Copyright 2025 Adobe
4+
* All Rights Reserved.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Customer\Test\Unit\Controller\Account;
9+
10+
use Magento\Customer\Controller\Account\CreatePost;
11+
use Magento\Framework\Exception\InputException;
12+
use Magento\Framework\Exception\LocalizedException;
13+
use Magento\Framework\Message\AbstractMessage;
14+
use Magento\Framework\Message\ManagerInterface;
15+
use Magento\Framework\Phrase;
16+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
17+
use Magento\Framework\Validator\Exception as ValidatorException;
18+
use PHPUnit\Framework\MockObject\MockObject;
19+
use PHPUnit\Framework\TestCase;
20+
use ReflectionClass;
21+
use ReflectionMethod;
22+
23+
/**
24+
* Test class for CreatePost exception handling methods
25+
*/
26+
class CreatePostExceptionHandlingTest extends TestCase
27+
{
28+
/**
29+
* @var CreatePost|MockObject
30+
*/
31+
private $controller;
32+
33+
/**
34+
* @var ManagerInterface|MockObject
35+
*/
36+
private $messageManagerMock;
37+
38+
/**
39+
* @inheritDoc
40+
*/
41+
protected function setUp(): void
42+
{
43+
$this->messageManagerMock = $this->createMock(ManagerInterface::class);
44+
45+
$this->controller = $this->getMockBuilder(CreatePost::class)
46+
->disableOriginalConstructor()
47+
->getMock();
48+
49+
$reflection = new ReflectionClass($this->controller);
50+
$messageManagerProperty = $reflection->getProperty('messageManager');
51+
$messageManagerProperty->setValue($this->controller, $this->messageManagerMock);
52+
}
53+
54+
/**
55+
* Test processValidatorException with multiple messages
56+
*/
57+
public function testProcessValidatorExceptionWithMessages(): void
58+
{
59+
$errorMessage1 = $this->createMock(AbstractMessage::class);
60+
$errorMessage1->expects($this->once())
61+
->method('getText')
62+
->willReturn('First Name is not valid!');
63+
64+
$errorMessage2 = $this->createMock(AbstractMessage::class);
65+
$errorMessage2->expects($this->once())
66+
->method('getText')
67+
->willReturn('Last Name is not valid!');
68+
69+
$validatorException = $this->createMock(ValidatorException::class);
70+
$validatorException->expects($this->once())
71+
->method('getMessages')
72+
->willReturn([$errorMessage1, $errorMessage2]);
73+
74+
$this->messageManagerMock->expects($this->once())
75+
->method('addErrorMessage')
76+
->with($this->callback(function ($message) {
77+
return is_string($message) &&
78+
(str_contains($message, 'First Name is not valid!') ||
79+
str_contains($message, 'Der Vorname ist ungültig!')) &&
80+
(str_contains($message, 'Last Name is not valid!') ||
81+
str_contains($message, 'Der Nachname ist ungültig!'));
82+
}));
83+
84+
$this->invokePrivateMethod('processValidatorException', [$validatorException]);
85+
}
86+
87+
/**
88+
* Test processValidatorException with empty messages (fallback)
89+
*/
90+
public function testProcessValidatorExceptionWithEmptyMessages(): void
91+
{
92+
$validatorException = $this->getMockBuilder(ValidatorException::class)
93+
->setConstructorArgs([new Phrase('Combined error message')])
94+
->onlyMethods(['getMessages'])
95+
->getMock();
96+
$validatorException->expects($this->once())
97+
->method('getMessages')
98+
->willReturn([]);
99+
100+
$this->messageManagerMock->expects($this->once())
101+
->method('addErrorMessage')
102+
->with($this->isType('string'));
103+
104+
$this->invokePrivateMethod('processValidatorException', [$validatorException]);
105+
}
106+
107+
/**
108+
* Test processValidatorException with string messages (not AbstractMessage)
109+
*/
110+
public function testProcessValidatorExceptionWithStringMessages(): void
111+
{
112+
$validatorException = $this->createMock(ValidatorException::class);
113+
$validatorException->expects($this->once())
114+
->method('getMessages')
115+
->willReturn(['First Name is not valid!', 'Last Name is not valid!']);
116+
117+
$this->messageManagerMock->expects($this->once())
118+
->method('addErrorMessage')
119+
->with($this->isType('string'));
120+
121+
$this->invokePrivateMethod('processValidatorException', [$validatorException]);
122+
}
123+
124+
/**
125+
* Test processStandardInputException with errors
126+
*/
127+
public function testProcessStandardInputExceptionWithErrors(): void
128+
{
129+
$error1 = $this->getMockBuilder(LocalizedException::class)
130+
->setConstructorArgs([new Phrase('Error 1')])
131+
->getMock();
132+
133+
$error2 = $this->getMockBuilder(LocalizedException::class)
134+
->setConstructorArgs([new Phrase('Error 2')])
135+
->getMock();
136+
137+
$inputException = $this->getMockBuilder(InputException::class)
138+
->setConstructorArgs([new Phrase('Main message')])
139+
->onlyMethods(['getErrors'])
140+
->getMock();
141+
$inputException->expects($this->once())
142+
->method('getErrors')
143+
->willReturn([$error1, $error2]);
144+
145+
$this->messageManagerMock->expects($this->exactly(2))
146+
->method('addErrorMessage')
147+
->with($this->isType('string'));
148+
149+
$this->invokePrivateMethod('processStandardInputException', [$inputException]);
150+
}
151+
152+
/**
153+
* Test processStandardInputException without errors
154+
*/
155+
public function testProcessStandardInputExceptionWithoutErrors(): void
156+
{
157+
$inputException = $this->getMockBuilder(InputException::class)
158+
->setConstructorArgs([new Phrase('Main error message')])
159+
->onlyMethods(['getErrors'])
160+
->getMock();
161+
$inputException->expects($this->once())
162+
->method('getErrors')
163+
->willReturn([]);
164+
165+
$this->messageManagerMock->expects($this->once())
166+
->method('addErrorMessage')
167+
->with($this->isType('string'));
168+
169+
$this->invokePrivateMethod('processStandardInputException', [$inputException]);
170+
}
171+
172+
/**
173+
* Test processInputException routes to ValidatorException handler
174+
*/
175+
public function testProcessInputExceptionRoutesToValidatorException(): void
176+
{
177+
$validatorException = $this->getMockBuilder(ValidatorException::class)
178+
->setConstructorArgs([new Phrase('Fallback message')])
179+
->onlyMethods(['getMessages'])
180+
->getMock();
181+
$validatorException->expects($this->once())
182+
->method('getMessages')
183+
->willReturn([]);
184+
185+
$this->messageManagerMock->expects($this->once())
186+
->method('addErrorMessage')
187+
->with($this->isType('string'));
188+
189+
$this->invokePrivateMethod('processInputException', [$validatorException]);
190+
}
191+
192+
/**
193+
* Test processInputException routes to standard InputException handler
194+
*/
195+
public function testProcessInputExceptionRoutesToStandardInputException(): void
196+
{
197+
$inputException = $this->getMockBuilder(InputException::class)
198+
->setConstructorArgs([new Phrase('Standard error')])
199+
->onlyMethods(['getErrors'])
200+
->getMock();
201+
$inputException->expects($this->once())
202+
->method('getErrors')
203+
->willReturn([]);
204+
205+
$this->messageManagerMock->expects($this->once())
206+
->method('addErrorMessage')
207+
->with($this->isType('string'));
208+
209+
$this->invokePrivateMethod('processInputException', [$inputException]);
210+
}
211+
212+
/**
213+
* Invoke a private method using reflection
214+
*
215+
* @param string $methodName
216+
* @param array $args
217+
* @return mixed
218+
*/
219+
private function invokePrivateMethod(string $methodName, array $args)
220+
{
221+
$reflection = new ReflectionClass($this->controller);
222+
$method = $reflection->getMethod($methodName);
223+
return $method->invokeArgs($this->controller, $args);
224+
}
225+
}

0 commit comments

Comments
 (0)