Skip to content

Commit af02add

Browse files
committed
AC-15345: Undefined array key in ProductRepository getById
Added complete unit test coverage for Magento\Review\Block\Form
1 parent dcccb50 commit af02add

File tree

1 file changed

+158
-0
lines changed

1 file changed

+158
-0
lines changed

app/code/Magento/Review/Test/Unit/Block/FormTest.php

Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
use Magento\Store\Model\StoreManagerInterface;
2121
use PHPUnit\Framework\MockObject\MockObject;
2222
use PHPUnit\Framework\TestCase;
23+
use Magento\Review\Model\RatingFactory;
24+
use Magento\Review\Model\Rating;
25+
use Magento\Review\Model\ResourceModel\Rating\Collection as RatingCollection;
2326

2427
class FormTest extends TestCase
2528
{
@@ -201,4 +204,159 @@ public function testGetJsLayout()
201204
->willReturn(json_encode($jsLayout));
202205
$this->assertEquals('{"some-layout":"layout information"}', $this->object->getJsLayout());
203206
}
207+
208+
public function testGetRatingsReturnsPreparedCollection(): void
209+
{
210+
$storeId = 10;
211+
212+
$store = new DataObject(['id' => $storeId]);
213+
214+
$storeManager = $this->createMock(StoreManagerInterface::class);
215+
$storeManager->method('getStore')->willReturn($store);
216+
217+
$ratingCollection = $this->createMock(RatingCollection::class);
218+
$ratingCollection->expects($this->once())
219+
->method('addEntityFilter')
220+
->with('product')
221+
->willReturnSelf();
222+
$ratingCollection->expects($this->once())
223+
->method('setPositionOrder')
224+
->willReturnSelf();
225+
$ratingCollection->expects($this->once())
226+
->method('addRatingPerStoreName')
227+
->with($storeId)
228+
->willReturnSelf();
229+
$ratingCollection->expects($this->once())
230+
->method('setStoreFilter')
231+
->with($storeId)
232+
->willReturnSelf();
233+
$ratingCollection->expects($this->once())
234+
->method('setActiveFilter')
235+
->with(true)
236+
->willReturnSelf();
237+
$ratingCollection->expects($this->once())
238+
->method('load')
239+
->willReturnSelf();
240+
$ratingCollection->expects($this->once())
241+
->method('addOptionToItems')
242+
->willReturnSelf();
243+
244+
$rating = $this->createMock(Rating::class);
245+
$rating->method('getResourceCollection')->willReturn($ratingCollection);
246+
247+
$ratingFactory = $this->createMock(RatingFactory::class);
248+
$ratingFactory->method('create')->willReturn($rating);
249+
250+
$formBlock = $this->getFormBlockWithInjectedDependencies($storeManager, $ratingFactory);
251+
252+
$result = $formBlock->getRatings();
253+
254+
$this->assertSame($ratingCollection, $result);
255+
}
256+
257+
public function testGetRegisterUrl(): void
258+
{
259+
$expectedUrl = 'https://example.com/customer/account/create/';
260+
261+
$customerUrl = $this->getMockBuilder(\Magento\Customer\Model\Url::class)
262+
->disableOriginalConstructor()
263+
->onlyMethods(['getRegisterUrl'])
264+
->getMock();
265+
266+
$customerUrl->expects($this->once())
267+
->method('getRegisterUrl')
268+
->willReturn($expectedUrl);
269+
270+
$formBlock = $this->getFormBlockWithInjectedDependencies(
271+
$this->storeManager,
272+
$this->createMock(RatingFactory::class)
273+
);
274+
$this->setProtectedProperty($formBlock, 'customerUrl', $customerUrl);
275+
276+
$this->assertSame($expectedUrl, $formBlock->getRegisterUrl());
277+
}
278+
279+
public function testConstructSetsLoginLinkWhenGuestCannotWrite(): void
280+
{
281+
$currentUrl = 'https://example.com/current';
282+
$encoded = 'ENCODED_REFERER';
283+
$loginUrlBase = 'https://example.com/customer/account/login/';
284+
285+
$urlBuilder = $this->createMock(\Magento\Framework\UrlInterface::class);
286+
$urlBuilder->method('getUrl')
287+
->willReturnCallback(function ($route, $params = []) use ($currentUrl, $encoded, $loginUrlBase) {
288+
if ($route === '*/*/*') {
289+
$this->assertSame(['_current' => true], $params);
290+
return $currentUrl;
291+
}
292+
if ($route === 'customer/account/login/') {
293+
$this->assertArrayHasKey(\Magento\Customer\Model\Url::REFERER_QUERY_PARAM_NAME, $params);
294+
$this->assertSame($encoded, $params[\Magento\Customer\Model\Url::REFERER_QUERY_PARAM_NAME]);
295+
return $loginUrlBase . '?' . \Magento\Customer\Model\Url::REFERER_QUERY_PARAM_NAME . '=' . $encoded;
296+
}
297+
return '';
298+
});
299+
300+
$urlEncoder = $this->createMock(\Magento\Framework\Url\EncoderInterface::class);
301+
$urlEncoder->expects($this->once())
302+
->method('encode')
303+
->with($currentUrl . '#review-form')
304+
->willReturn($encoded);
305+
306+
$httpContext = $this->createMock(\Magento\Framework\App\Http\Context::class);
307+
$httpContext->method('getValue')
308+
->with(\Magento\Customer\Model\Context::CONTEXT_AUTH)
309+
->willReturn(false);
310+
311+
$reviewData = $this->createMock(\Magento\Review\Helper\Data::class);
312+
$reviewData->method('getIsGuestAllowToWrite')->willReturn(false);
313+
314+
$formBlock = $this->getMockBuilder(Form::class)
315+
->disableOriginalConstructor()
316+
->onlyMethods([])
317+
->getMock();
318+
319+
$this->setProtectedProperty($formBlock, '_urlBuilder', $urlBuilder);
320+
$this->setProtectedProperty($formBlock, 'urlEncoder', $urlEncoder);
321+
$this->setProtectedProperty($formBlock, 'httpContext', $httpContext);
322+
$this->setProtectedProperty($formBlock, '_reviewData', $reviewData);
323+
324+
$ref = new \ReflectionObject($formBlock);
325+
$method = $ref->getMethod('_construct');
326+
$method->setAccessible(true);
327+
$method->invoke($formBlock);
328+
329+
$expectedLoginUrl = $loginUrlBase . '?' . \Magento\Customer\Model\Url::REFERER_QUERY_PARAM_NAME . '=' . $encoded;
330+
$this->assertSame($expectedLoginUrl, $formBlock->getLoginLink());
331+
}
332+
333+
private function getFormBlockWithInjectedDependencies(
334+
StoreManagerInterface $storeManager,
335+
RatingFactory $ratingFactory
336+
): Form {
337+
$formBlock = $this->getMockBuilder(Form::class)
338+
->disableOriginalConstructor()
339+
->onlyMethods([])
340+
->getMock();
341+
342+
// Inject protected properties via reflection to avoid full framework context construction
343+
$this->setProtectedProperty($formBlock, '_storeManager', $storeManager);
344+
$this->setProtectedProperty($formBlock, '_ratingFactory', $ratingFactory);
345+
346+
return $formBlock;
347+
}
348+
349+
private function setProtectedProperty(object $object, string $property, mixed $value): void
350+
{
351+
$reflection = new \ReflectionObject($object);
352+
while ($reflection && !$reflection->hasProperty($property)) {
353+
$reflection = $reflection->getParentClass();
354+
if ($reflection === false) {
355+
$this->fail('Property ' . $property . ' not found in class hierarchy');
356+
}
357+
}
358+
$prop = $reflection->getProperty($property);
359+
$prop->setAccessible(true);
360+
$prop->setValue($object, $value);
361+
}
204362
}

0 commit comments

Comments
 (0)