<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */
namespace Magento\CatalogUrlRewrite\Observer;

use Magento\UrlRewrite\Service\V1\Data\UrlRewrite;
use Magento\CatalogUrlRewrite\Model\CategoryUrlRewriteGenerator;

/**
 * Test Cases:
 *
 * - has changes for url_key, is_anchor, changed product list
 * - in global scope
 * - in store
 * - generate canonical
 * - generate children
 * - has children
 * - generate current
 * - has rewrites history
 * @magentoAppArea adminhtml
 */
class CategoryProcessUrlRewriteSavingObserverTest extends \PHPUnit\Framework\TestCase
{
    /** @var \Magento\Framework\ObjectManagerInterface */
    protected $objectManager;

    protected function setUp(): void
    {
        $this->objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
    }

    /**
     * @param array $filter
     * @return array
     */
    private function getActualResults(array $filter)
    {
        /** @var \Magento\UrlRewrite\Model\UrlFinderInterface $urlFinder */
        $urlFinder = $this->objectManager->get(\Magento\UrlRewrite\Model\UrlFinderInterface::class);
        $actualResults = [];
        foreach ($urlFinder->findAllByData($filter) as $url) {
            $actualResults[] = [
                'request_path' => $url->getRequestPath(),
                'target_path' => $url->getTargetPath(),
                'is_auto_generated' => (int)$url->getIsAutogenerated(),
                'redirect_type' => $url->getRedirectType()
            ];
        }
        return $actualResults;
    }

    protected function tearDown(): void
    {
        $category = $this->objectManager->create(\Magento\Catalog\Model\Category::class);
        $category->load(3);
        $category->delete();
    }

    /**
     * @magentoDataFixture Magento/CatalogUrlRewrite/_files/categories.php
     * @magentoDbIsolation enabled
     * @magentoAppIsolation enabled
     */
    public function testUrlKeyHasChanged()
    {
        $categoryFilter = [
            UrlRewrite::ENTITY_TYPE => 'category',
        ];
        $expected = [
            [
                'request_path' => "category-1.html",
                'target_path' => "catalog/category/view/id/3",
                'is_auto_generated' => 1,
                'redirect_type' => 0
            ],
            [
                'request_path' => "category-1/category-1-1.html",
                'target_path' => "catalog/category/view/id/4",
                'is_auto_generated' => 1,
                'redirect_type' => 0
            ],
            [
                'request_path' => "category-1/category-1-1/category-1-1-1.html",
                'target_path' => "catalog/category/view/id/5",
                'is_auto_generated' => 1,
                'redirect_type' => 0
            ],
            [
                'request_path' => "category-2.html",
                'target_path' =>  "catalog/category/view/id/6",
                'is_auto_generated' => 1,
                'redirect_type' => 0
            ]

        ];
        $actual = $this->getActualResults($categoryFilter);
        foreach ($expected as $row) {
            $this->assertContains($row, $actual);
        }
        /** @var \Magento\Catalog\Model\Category $category */
        $category = $this->objectManager->create(\Magento\Catalog\Model\Category::class);
        $category->load(3);
        $category->setData('save_rewrites_history', false);
        $category->setUrlKey('new-url');
        $category->save();
        $expected = [
            [
                'request_path' => "new-url.html",
                'target_path' => "catalog/category/view/id/3",
                'is_auto_generated' => 1,
                'redirect_type' => 0
            ],
            [
                'request_path' => "new-url/category-1-1.html",
                'target_path' => "catalog/category/view/id/4",
                'is_auto_generated' => 1,
                'redirect_type' => 0
            ],
            [
                'request_path' => "new-url/category-1-1/category-1-1-1.html",
                'target_path' => "catalog/category/view/id/5",
                'is_auto_generated' => 1,
                'redirect_type' => 0
            ],
            [
                'request_path' => "category-2.html",
                'target_path' =>  "catalog/category/view/id/6",
                'is_auto_generated' => 1,
                'redirect_type' => 0
            ]

        ];
        $actual = $this->getActualResults($categoryFilter);
        foreach ($expected as $row) {
            $this->assertContains($row, $actual);
        }
    }

    /**
     * @magentoDataFixture Magento/CatalogUrlRewrite/_files/categories_with_products.php
     * @magentoDbIsolation enabled
     * @magentoAppIsolation enabled
     */
    public function testIsAnchorHasChanged()
    {
        $categoryFilter = [
            UrlRewrite::ENTITY_TYPE => CategoryUrlRewriteGenerator::ENTITY_TYPE,
        ];
        /** @var \Magento\Catalog\Model\Category $category */
        $category = $this->objectManager->create(\Magento\Catalog\Model\Category::class);
        $category->load(3);
        $category->setData('is_anchor', false);
        $category->save();
        $expected = [
            [
                'request_path' => "category-1.html",
                'target_path' => "catalog/category/view/id/3",
                'is_auto_generated' => 1,
                'redirect_type' => 0
            ],
            [
                'request_path' => "category-1/category-1-1.html",
                'target_path' => "catalog/category/view/id/4",
                'is_auto_generated' => 1,
                'redirect_type' => 0
            ],
            [
                'request_path' => "category-1/category-1-1/category-1-1-1.html",
                'target_path' => "catalog/category/view/id/5",
                'is_auto_generated' => 1,
                'redirect_type' => 0
            ],
            [
                'request_path' => "category-2.html",
                'target_path' =>  "catalog/category/view/id/6",
                'is_auto_generated' => 1,
                'redirect_type' => 0
            ]

        ];
        $actual = $this->getActualResults($categoryFilter);
        foreach ($expected as $row) {
            $this->assertContains($row, $actual);
        }
    }
}
