Skip to content
4 changes: 2 additions & 2 deletions app/code/Magento/Catalog/Model/ProductRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ public function get($sku, $editMode = false, $storeId = null, $forceReload = fal
$productId = $this->resourceModel->getIdBySku($sku);
if (!$productId) {
throw new NoSuchEntityException(
__("The product that was requested doesn't exist. Verify the product and try again.")
__("The product with SKU \"%1\" does not exist.", $sku)
);
}
if ($editMode) {
Expand Down Expand Up @@ -319,7 +319,7 @@ public function getById($productId, $editMode = false, $storeId = null, $forceRe
$product->load($productId);
if (!$product->getId()) {
throw new NoSuchEntityException(
__("The product that was requested doesn't exist. Verify the product and try again.")
__("The product with ID \"%1\" does not exist.", $productId)
);
}
$this->cacheProduct($cacheKey, $product);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@
*/
class ManagementTest extends TestCase
{
const STUB_PRODUCT_SKU_1 = 'Simple Product 1';
const STUB_PRODUCT_SKU_2 = 'Simple Product 2';
const STUB_PRODUCT_TYPE = 'simple';
const STUB_LINK_TYPE = 'related';
const STUB_BAD_TYPE = 'bad type';
private const STUB_PRODUCT_SKU_1 = 'Simple Product 1';
private const STUB_PRODUCT_SKU_2 = 'Simple Product 2';
private const STUB_PRODUCT_TYPE = 'simple';
private const STUB_LINK_TYPE = 'related';
private const STUB_BAD_TYPE = 'bad type';

/**
* @var Management
Expand Down Expand Up @@ -289,13 +289,13 @@ public function testSetProductLinksNoProductException()
->method('get')
->willThrowException(
new NoSuchEntityException(
__("The product that was requested doesn't exist. Verify the product and try again.")
__('The product with SKU "' . $productSku . '" does not exist.')
)
);

$this->expectException(NoSuchEntityException::class);
$this->expectExceptionMessage(
"The product that was requested doesn't exist. Verify the product and try again."
'The product with SKU "' . $productSku . '" does not exist.'
);

$this->model->setProductLinks($productSku, $links);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -440,7 +440,7 @@ public function testGetAbsentProduct(): void
{
$this->expectException('Magento\Framework\Exception\NoSuchEntityException');
$this->expectExceptionMessage(
'The product that was requested doesn\'t exist. Verify the product and try again.'
'The product with SKU "test_sku" does not exist.'
);
$this->productFactory->expects($this->once())->method('create')
->willReturn($this->product);
Expand Down Expand Up @@ -521,7 +521,7 @@ public function testGetByIdAbsentProduct(): void
{
$this->expectException('Magento\Framework\Exception\NoSuchEntityException');
$this->expectExceptionMessage(
'The product that was requested doesn\'t exist. Verify the product and try again.'
'The product with ID "product_id" does not exist.'
);
$this->productFactory->expects($this->once())->method('create')
->willReturn($this->product);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -492,18 +492,22 @@ public function testCreateThrowsExceptionIfProvidedImageHasWrongMimeType()
$this->_webApiCall($this->createServiceInfo, ['sku' => 'simple', 'entry' => $requestData]);
}

protected function assertProductNotFoundException(\Exception $e, string $sku): void
{
$decoded = json_decode($e->getMessage(), true);
$this->assertEquals('The product with SKU "%1" does not exist.', $decoded['message']);
$this->assertContains($sku, $decoded['parameters']);
$this->assertEquals(404, $e->getCode());
}

/**
* Test create method if target product does not exist
*
*/
public function testCreateThrowsExceptionIfTargetProductDoesNotExist()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage(
'The product that was requested doesn\'t exist. Verify the product and try again.'
);
$sku = 'wrong_product_sku';

$this->createServiceInfo['rest']['resourcePath'] = '/V1/products/wrong_product_sku/media';
$this->createServiceInfo['rest']['resourcePath'] = '/V1/products/' . $sku . '/media';

$requestData = [
'id' => null,
Expand All @@ -519,7 +523,12 @@ public function testCreateThrowsExceptionIfTargetProductDoesNotExist()
]
];

$this->_webApiCall($this->createServiceInfo, ['sku' => 'simple', 'entry' => $requestData]);
try {
$this->_webApiCall($this->createServiceInfo, ['sku' => $sku, 'entry' => $requestData]);
$this->fail('Expected exception was not thrown.');
} catch (\Exception $e) {
$this->assertProductNotFoundException($e, $sku);
}
}

/**
Expand Down Expand Up @@ -551,19 +560,14 @@ public function testCreateThrowsExceptionIfProvidedImageNameContainsForbiddenCha

/**
* Test update() method if target product does not exist
*
*/
public function testUpdateThrowsExceptionIfTargetProductDoesNotExist()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage(
'The product that was requested doesn\'t exist. Verify the product and try again.'
);
$sku = 'wrong_product_sku';

$this->updateServiceInfo['rest']['resourcePath'] = '/V1/products/wrong_product_sku/media'
. '/' . 'wrong-sku';
$this->updateServiceInfo['rest']['resourcePath'] = '/V1/products/' . $sku . '/media/' . 'wrong-sku';
$requestData = [
'sku' => 'wrong_product_sku',
'sku' => $sku,
'entry' => [
'id' => 9999,
'media_type' => 'image',
Expand All @@ -574,9 +578,15 @@ public function testUpdateThrowsExceptionIfTargetProductDoesNotExist()
],
];

$this->_webApiCall($this->updateServiceInfo, $requestData, null, 'all');
try {
$this->_webApiCall($this->updateServiceInfo, $requestData, null, 'all');
$this->fail('Expected exception was not thrown.');
} catch (\Exception $e) {
$this->assertProductNotFoundException($e, $sku);
}
}


/**
* Test update() method if there is no image with given id
*
Expand Down Expand Up @@ -607,22 +617,23 @@ public function testUpdateThrowsExceptionIfThereIsNoImageWithGivenId()

/**
* Test delete() method if target product does not exist
*
*/
public function testDeleteThrowsExceptionIfTargetProductDoesNotExist()
{
$this->expectException(\Exception::class);
$this->expectExceptionMessage(
'The product that was requested doesn\'t exist. Verify the product and try again.'
);
$sku = 'wrong_product_sku';

$this->deleteServiceInfo['rest']['resourcePath'] = '/V1/products/wrong_product_sku/media/9999';
$this->deleteServiceInfo['rest']['resourcePath'] = '/V1/products/' . $sku . '/media/9999';
$requestData = [
'sku' => 'wrong_product_sku',
'sku' => $sku,
'entryId' => 9999,
];

$this->_webApiCall($this->deleteServiceInfo, $requestData);
try {
$this->_webApiCall($this->deleteServiceInfo, $requestData);
$this->fail('Expected exception was not thrown.');
} catch (\Exception $e) {
$this->assertProductNotFoundException($e, $sku);
}
}

/**
Expand Down Expand Up @@ -778,7 +789,7 @@ public function testGetListForAbsentSku()
if (TESTS_WEB_API_ADAPTER == self::ADAPTER_SOAP) {
$this->expectException('SoapFault');
$this->expectExceptionMessage(
"The product that was requested doesn't exist. Verify the product and try again."
"The product with SKU \"%1\" does not exist."
);
} else {
$this->expectException('Exception');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,7 @@ public function testUpdateNegative($optionData, $message, $exceptionCode)
{
$this->_markTestAsRestOnly();
$productSku = 'simple';

/** @var ProductRepository $productRepository */
$productRepository = $this->objectManager->create(ProductRepository::class);
$options = $productRepository->get($productSku, true)->getOptions();
Expand All @@ -434,10 +435,14 @@ public function testUpdateNegative($optionData, $message, $exceptionCode)
],
];

$this->expectException('Exception');
$this->expectExceptionMessage($message);
$this->expectExceptionCode($exceptionCode);
$this->_webApiCall($serviceInfo, ['option' => $optionData]);
try {
$this->_webApiCall($serviceInfo, ['option' => $optionData]);
$this->fail('Expected exception was not thrown.');
} catch (\Exception $e) {
$this->assertEquals($exceptionCode, $e->getCode());
$this->assertStringContainsString($message, $e->getMessage());
$this->assertStringContainsString($productSku, $e->getMessage());
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
<?php
/**
* Copyright 2025 Adobe
* All Rights Reserved.
*/
declare(strict_types=1);

namespace Magento\Catalog\Api;

use Magento\Catalog\Api\Data\ProductInterface;

/**
* Test for \Magento\Catalog\Api\ProductRepositoryInterface category links
*
* @magentoAppIsolation enabled
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/
class ProductRepositoryCategoryLinksTest extends ProductRepositoryInterfaceTest
{
private const KEY_CATEGORY_LINKS = 'category_links';

/**
* Test product category links
*
* @magentoApiDataFixture Magento/Catalog/_files/category_product.php
*/
public function testProductCategoryLinks()
{
// Create simple product
$productData = $this->getSimpleProductData();
$productData[ProductInterface::EXTENSION_ATTRIBUTES_KEY] = [
self::KEY_CATEGORY_LINKS => [['category_id' => 333, 'position' => 0]],
];
$response = $this->saveProduct($productData);
$this->assertEquals(
[['category_id' => 333, 'position' => 0]],
$response[ProductInterface::EXTENSION_ATTRIBUTES_KEY][self::KEY_CATEGORY_LINKS]
);
$response = $this->getProduct($productData[ProductInterface::SKU]);
$this->assertArrayHasKey(ProductInterface::EXTENSION_ATTRIBUTES_KEY, $response);
$extensionAttributes = $response[ProductInterface::EXTENSION_ATTRIBUTES_KEY];
$this->assertArrayHasKey(self::KEY_CATEGORY_LINKS, $extensionAttributes);
$this->assertEquals([['category_id' => 333, 'position' => 0]], $extensionAttributes[self::KEY_CATEGORY_LINKS]);
}

/**
* Test update product category without categories
*
* @magentoApiDataFixture Magento/Catalog/_files/category_product.php
*/
public function testUpdateProductCategoryLinksNullOrNotExists()
{
$response = $this->getProduct('simple333');
// update product without category_link or category_link is null
$response[ProductInterface::EXTENSION_ATTRIBUTES_KEY][self::KEY_CATEGORY_LINKS] = null;
$response = $this->updateProduct($response);
$this->assertEquals(
[['category_id' => 333, 'position' => 0]],
$response[ProductInterface::EXTENSION_ATTRIBUTES_KEY][self::KEY_CATEGORY_LINKS]
);
unset($response[ProductInterface::EXTENSION_ATTRIBUTES_KEY][self::KEY_CATEGORY_LINKS]);
$response = $this->updateProduct($response);
$this->assertEquals(
[['category_id' => 333, 'position' => 0]],
$response[ProductInterface::EXTENSION_ATTRIBUTES_KEY][self::KEY_CATEGORY_LINKS]
);
}

/**
* Test update product category links position
*
* @magentoApiDataFixture Magento/Catalog/_files/category_product.php
*/
public function testUpdateProductCategoryLinksPosition()
{
$response = $this->getProduct('simple333');
// update category_link position
$response[ProductInterface::EXTENSION_ATTRIBUTES_KEY][self::KEY_CATEGORY_LINKS] = [
['category_id' => 333, 'position' => 10],
];
$response = $this->updateProduct($response);
$this->assertEquals(
[['category_id' => 333, 'position' => 10]],
$response[ProductInterface::EXTENSION_ATTRIBUTES_KEY][self::KEY_CATEGORY_LINKS]
);
}

/**
* Test update product category links unassing
*
* @magentoApiDataFixture Magento/Catalog/_files/category_product.php
*/
public function testUpdateProductCategoryLinksUnassign()
{
$response = $this->getProduct('simple333');
// unassign category_links from product
$response[ProductInterface::EXTENSION_ATTRIBUTES_KEY][self::KEY_CATEGORY_LINKS] = [];
$response = $this->updateProduct($response);
$this->assertArrayNotHasKey(
self::KEY_CATEGORY_LINKS,
$response[ProductInterface::EXTENSION_ATTRIBUTES_KEY]
);
}
}
Loading