introduced url structure for categories and products (SEO improvements)
This commit is contained in:
parent
e3d9377dc4
commit
25c2a15b65
|
|
@ -151,6 +151,24 @@ class CategoryRepository extends Repository
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $urlPath
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function findByPathOrFail(string $urlPath)
|
||||
{
|
||||
$category = $this->model->whereTranslation('url_path', $urlPath)->first();
|
||||
|
||||
if ($category) {
|
||||
return $category;
|
||||
}
|
||||
|
||||
throw (new ModelNotFoundException)->setModel(
|
||||
get_class($this->model), $urlPath
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @param $id
|
||||
|
|
|
|||
|
|
@ -166,14 +166,14 @@ class WishlistController extends Controller
|
|||
} else {
|
||||
session()->flash('info', trans('shop::app.wishlist.option-missing'));
|
||||
|
||||
return redirect()->route('shop.products.index', $wishlistItem->product->url_key);
|
||||
return redirect()->route('shop.productOrCategory.index', $wishlistItem->product->url_key);
|
||||
}
|
||||
|
||||
return redirect()->back();
|
||||
} catch (\Exception $e) {
|
||||
session()->flash('warning', $e->getMessage());
|
||||
|
||||
return redirect()->route('shop.products.index', ['slug' => $wishlistItem->product->url_key]);
|
||||
return redirect()->route('shop.productOrCategory.index', ['slug' => $wishlistItem->product->url_key]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,32 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddColumnUrlPathToCategoryTranslations extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::table('category_translations', function (Blueprint $table) {
|
||||
$table->string('url_path');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::table('category_translations', function (Blueprint $table) {
|
||||
$table->dropColumn('url_path');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddStoredFunctionToGetUrlPathOfCategory extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
$functionSQL = <<< SQL
|
||||
DROP FUNCTION IF EXISTS `get_url_path_of_category`;
|
||||
CREATE FUNCTION get_url_path_of_category(
|
||||
categoryId INT
|
||||
)
|
||||
RETURNS VARCHAR(255)
|
||||
DETERMINISTIC
|
||||
BEGIN
|
||||
|
||||
DECLARE urlPath VARCHAR(255);
|
||||
IF categoryId != 1
|
||||
THEN
|
||||
SELECT
|
||||
GROUP_CONCAT(parent_translations.slug SEPARATOR '/') INTO urlPath
|
||||
FROM
|
||||
categories AS node,
|
||||
categories AS parent
|
||||
JOIN category_translations AS parent_translations ON parent.id = parent_translations.category_id
|
||||
WHERE
|
||||
node._lft >= parent._lft
|
||||
AND node._rgt <= parent._rgt
|
||||
AND node.id = categoryId
|
||||
AND parent.id <> 1
|
||||
GROUP BY
|
||||
node.id;
|
||||
|
||||
IF urlPath IS NULL
|
||||
THEN
|
||||
SET urlPath = (SELECT slug FROM category_translations WHERE category_translations.category_id = categoryId);
|
||||
END IF;
|
||||
ELSE
|
||||
SET urlPath = '';
|
||||
END IF;
|
||||
|
||||
RETURN urlPath;
|
||||
END;
|
||||
SQL;
|
||||
|
||||
DB::unprepared($functionSQL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
DB::unprepared('DROP FUNCTION IF EXISTS `get_url_path_of_category`;');
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddTriggerToCategoryTranslations extends Migration
|
||||
{
|
||||
private const TRIGGER_NAME_INSERT = 'trig_category_translations_insert';
|
||||
private const TRIGGER_NAME_UPDATE = 'trig_category_translations_update';
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
$insertTriggerBody = $this->getTriggerBody('insert');
|
||||
$insertTrigger = <<< SQL
|
||||
CREATE TRIGGER %s
|
||||
BEFORE INSERT ON category_translations
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
$insertTriggerBody
|
||||
END;
|
||||
SQL;
|
||||
|
||||
$updateTriggerBody = $this->getTriggerBody();
|
||||
$updateTrigger = <<< SQL
|
||||
CREATE TRIGGER %s
|
||||
BEFORE UPDATE ON category_translations
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
$updateTriggerBody
|
||||
END;
|
||||
SQL;
|
||||
|
||||
DB::unprepared(sprintf('DROP TRIGGER IF EXISTS %s;', self::TRIGGER_NAME_INSERT));
|
||||
DB::unprepared(sprintf($insertTrigger, self::TRIGGER_NAME_INSERT));
|
||||
|
||||
DB::unprepared(sprintf('DROP TRIGGER IF EXISTS %s;', self::TRIGGER_NAME_UPDATE));
|
||||
DB::unprepared(sprintf($updateTrigger, self::TRIGGER_NAME_UPDATE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
DB::unprepared(sprintf('DROP TRIGGER IF EXISTS %s;', self::TRIGGER_NAME_INSERT));
|
||||
DB::unprepared(sprintf('DROP TRIGGER IF EXISTS %s;', self::TRIGGER_NAME_UPDATE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns trigger body as string based on type ('update' or 'insert').
|
||||
*
|
||||
* @param string $type
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getTriggerBody(string $type = 'update'): string
|
||||
{
|
||||
$addOnInsert = ($type === 'update') ? '' : <<< SQL
|
||||
ELSE
|
||||
SELECT CONCAT(urlPath, '/', NEW.slug) INTO urlPath;
|
||||
SQL;
|
||||
|
||||
return <<< SQL
|
||||
DECLARE urlPath varchar(255);
|
||||
|
||||
IF NEW.category_id != 1
|
||||
THEN
|
||||
SELECT
|
||||
GROUP_CONCAT(parent_translations.slug SEPARATOR '/') INTO urlPath
|
||||
FROM
|
||||
categories AS node,
|
||||
categories AS parent
|
||||
JOIN category_translations AS parent_translations ON parent.id = parent_translations.category_id
|
||||
WHERE
|
||||
node._lft >= parent._lft
|
||||
AND node._rgt <= parent._rgt
|
||||
AND node.id = NEW.category_id
|
||||
AND parent.id <> 1
|
||||
GROUP BY
|
||||
node.id;
|
||||
|
||||
IF urlPath IS NULL
|
||||
THEN
|
||||
SET urlPath = NEW.slug;
|
||||
$addOnInsert
|
||||
END IF;
|
||||
|
||||
SET NEW.url_path = urlPath;
|
||||
END IF;
|
||||
SQL;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Webkul\Category\Models\CategoryTranslation;
|
||||
|
||||
class AddUrlPathToExistingCategoryTranslations extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
$sql = <<< SQL
|
||||
SELECT
|
||||
GROUP_CONCAT(parent_translations.slug SEPARATOR '/') AS url_path
|
||||
FROM
|
||||
categories AS node,
|
||||
categories AS parent
|
||||
JOIN category_translations AS parent_translations ON parent.id = parent_translations.category_id
|
||||
WHERE
|
||||
node._lft >= parent._lft
|
||||
AND node._rgt <= parent._rgt
|
||||
AND node.id = :category_id
|
||||
AND node.id <> 1
|
||||
AND parent.id <> 1
|
||||
GROUP BY
|
||||
node.id
|
||||
SQL;
|
||||
|
||||
$categoryTranslationsTableName = app(CategoryTranslation::class)->getTable();
|
||||
|
||||
foreach (DB::table($categoryTranslationsTableName)->get() as $categoryTranslation) {
|
||||
$urlPathQueryResult = DB::selectOne($sql, ['category_id' => $categoryTranslation->category_id]);
|
||||
$url_path = $urlPathQueryResult ? $urlPathQueryResult->url_path : '';
|
||||
|
||||
DB::table($categoryTranslationsTableName)
|
||||
->where('id', $categoryTranslation->id)
|
||||
->update(['url_path' => $url_path]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class AddTriggerToCategories extends Migration
|
||||
{
|
||||
private const TRIGGER_NAME_INSERT = 'trig_categories_insert';
|
||||
private const TRIGGER_NAME_UPDATE = 'trig_categories_update';
|
||||
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
$triggerBody = <<< SQL
|
||||
DECLARE urlPath VARCHAR(255);
|
||||
|
||||
SELECT get_url_path_of_category(NEW.id) INTO urlPath;
|
||||
|
||||
IF EXISTS (SELECT * FROM category_translations WHERE category_id = NEW.id)
|
||||
THEN
|
||||
UPDATE category_translations
|
||||
SET url_path = urlPath
|
||||
WHERE category_translations.category_id = NEW.id;
|
||||
END IF;
|
||||
SQL;
|
||||
|
||||
$insertTrigger = <<< SQL
|
||||
CREATE TRIGGER %s
|
||||
AFTER INSERT ON categories
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
$triggerBody
|
||||
END;
|
||||
SQL;
|
||||
|
||||
$updateTrigger = <<< SQL
|
||||
CREATE TRIGGER %s
|
||||
AFTER UPDATE ON categories
|
||||
FOR EACH ROW
|
||||
BEGIN
|
||||
$triggerBody
|
||||
END;
|
||||
SQL;
|
||||
|
||||
DB::unprepared(sprintf('DROP TRIGGER IF EXISTS %s;', self::TRIGGER_NAME_INSERT));
|
||||
DB::unprepared(sprintf($insertTrigger, self::TRIGGER_NAME_INSERT));
|
||||
|
||||
DB::unprepared(sprintf('DROP TRIGGER IF EXISTS %s;', self::TRIGGER_NAME_UPDATE));
|
||||
DB::unprepared(sprintf($updateTrigger, self::TRIGGER_NAME_UPDATE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
DB::unprepared(sprintf('DROP TRIGGER IF EXISTS %s;', self::TRIGGER_NAME_INSERT));
|
||||
DB::unprepared(sprintf('DROP TRIGGER IF EXISTS %s;', self::TRIGGER_NAME_UPDATE));
|
||||
}
|
||||
}
|
||||
|
|
@ -96,7 +96,7 @@ class CartController extends Controller
|
|||
|
||||
$product = $this->productRepository->find($id);
|
||||
|
||||
return redirect()->route('shop.products.index', ['slug' => $product->url_key]);
|
||||
return redirect()->route('shop.productOrCategory.index', ['slug' => $product->url_key]);
|
||||
}
|
||||
|
||||
return redirect()->back();
|
||||
|
|
|
|||
|
|
@ -38,17 +38,4 @@ class CategoryController extends Controller
|
|||
|
||||
$this->_config = request('_config');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param string $slug
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function index($slug)
|
||||
{
|
||||
$category = $this->categoryRepository->findBySlugOrFail($slug);
|
||||
|
||||
return view($this->_config['view'], compact('category'));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,21 +79,6 @@ class ProductController extends Controller
|
|||
$this->_config = request('_config');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*
|
||||
* @param string $slug
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function index($slug)
|
||||
{
|
||||
$product = $this->productRepository->findBySlugOrFail($slug);
|
||||
|
||||
$customer = auth()->guard('customer')->user();
|
||||
|
||||
return view($this->_config['view'], compact('product', 'customer'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Download image or file
|
||||
*
|
||||
|
|
|
|||
|
|
@ -0,0 +1,92 @@
|
|||
<?php
|
||||
|
||||
|
||||
namespace Webkul\Shop\Http\Controllers;
|
||||
|
||||
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
||||
use Webkul\Category\Models\CategoryTranslation;
|
||||
use Webkul\Product\Models\ProductFlat;
|
||||
use Webkul\Category\Repositories\CategoryRepository;
|
||||
use Webkul\Product\Repositories\ProductRepository;
|
||||
|
||||
class ProductsCategoriesProxyController extends Controller
|
||||
{
|
||||
/**
|
||||
* Contains route related configuration
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $_config;
|
||||
|
||||
/**
|
||||
* CategoryRepository object
|
||||
*
|
||||
* @var CategoryRepository
|
||||
*/
|
||||
protected $categoryRepository;
|
||||
|
||||
/**
|
||||
* ProductRepository object
|
||||
*
|
||||
* @var ProductRepository
|
||||
*/
|
||||
protected $productRepository;
|
||||
|
||||
/**
|
||||
* Create a new controller instance.
|
||||
*
|
||||
* @param CategoryRepository $categoryRepository
|
||||
* @param ProductRepository $productRepository
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(CategoryRepository $categoryRepository, ProductRepository $productRepository)
|
||||
{
|
||||
$this->categoryRepository = $categoryRepository;
|
||||
$this->productRepository = $productRepository;
|
||||
|
||||
$this->_config = request('_config');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display a listing of the resource which can be a category or a product.
|
||||
*
|
||||
*
|
||||
* @param string $slug
|
||||
*
|
||||
* @return \Illuminate\View\View
|
||||
*/
|
||||
public function index(string $slug)
|
||||
{
|
||||
$slug = rtrim($slug, '/ ');
|
||||
|
||||
if (preg_match('/^([a-z-]+\/?)+$/', $slug)) {
|
||||
|
||||
if (DB::table(app(CategoryTranslation::class)->getTable())
|
||||
->where('url_path', '=', $slug)
|
||||
->exists()
|
||||
) {
|
||||
|
||||
$category = $this->categoryRepository->findByPathOrFail($slug);
|
||||
|
||||
return view($this->_config['category_view'], compact('category'));
|
||||
}
|
||||
|
||||
if (DB::table(app(ProductFlat::class)->getTable())
|
||||
->where('url_key', '=', $slug)
|
||||
->exists()
|
||||
) {
|
||||
$product = $this->productRepository->findBySlugOrFail($slug);
|
||||
|
||||
$customer = auth()->guard('customer')->user();
|
||||
|
||||
return view($this->_config['product_view'], compact('product', 'customer'));
|
||||
}
|
||||
|
||||
} else {
|
||||
throw new NotFoundHttpException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -13,11 +13,6 @@ Route::group(['middleware' => ['web', 'locale', 'theme', 'currency']], function
|
|||
//unsubscribe
|
||||
Route::get('/unsubscribe/{token}', 'Webkul\Shop\Http\Controllers\SubscriptionController@unsubscribe')->name('shop.unsubscribe');
|
||||
|
||||
//Store front header nav-menu fetch
|
||||
Route::get('/categories/{slug}', 'Webkul\Shop\Http\Controllers\CategoryController@index')->defaults('_config', [
|
||||
'view' => 'shop::products.index'
|
||||
])->name('shop.categories.index');
|
||||
|
||||
//Store front search
|
||||
Route::get('/search', 'Webkul\Shop\Http\Controllers\SearchController@index')->defaults('_config', [
|
||||
'view' => 'shop::search.search'
|
||||
|
|
@ -89,11 +84,6 @@ Route::group(['middleware' => ['web', 'locale', 'theme', 'currency']], function
|
|||
//Shop buynow button action
|
||||
Route::get('move/wishlist/{id}', 'Webkul\Shop\Http\Controllers\CartController@moveToWishlist')->name('shop.movetowishlist');
|
||||
|
||||
//Show Product Details Page(For individually Viewable Product)
|
||||
Route::get('/products/{slug}', 'Webkul\Shop\Http\Controllers\ProductController@index')->defaults('_config', [
|
||||
'view' => 'shop::products.view'
|
||||
])->name('shop.products.index');
|
||||
|
||||
Route::get('/downloadable/download-sample/{type}/{id}', 'Webkul\Shop\Http\Controllers\ProductController@downloadSample')->name('shop.downloadable.download_sample');
|
||||
|
||||
// Show Product Review Form
|
||||
|
|
@ -307,5 +297,13 @@ Route::group(['middleware' => ['web', 'locale', 'theme', 'currency']], function
|
|||
|
||||
Route::get('page/{slug}', 'Webkul\CMS\Http\Controllers\Shop\PagePresenterController@presenter')->name('shop.cms.page');
|
||||
|
||||
Route::get('{slug}', \Webkul\Shop\Http\Controllers\ProductsCategoriesProxyController::class . '@index')
|
||||
->defaults('_config', [
|
||||
'product_view' => 'shop::products.view',
|
||||
'category_view' => 'shop::products.index'
|
||||
])
|
||||
->where('slug', '^([a-z-]+\/?)+$')
|
||||
->name('shop.productOrCategory.index');
|
||||
|
||||
Route::fallback('Webkul\Shop\Http\Controllers\HomeController@notFound');
|
||||
});
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@ class ShopServiceProvider extends ServiceProvider
|
|||
*/
|
||||
public function boot(Router $router)
|
||||
{
|
||||
$this->loadMigrationsFrom(__DIR__ . '/../Database/Migrations');
|
||||
|
||||
$this->loadRoutesFrom(__DIR__ . '/../Http/routes.php');
|
||||
|
||||
$this->loadTranslationsFrom(__DIR__ . '/../Resources/lang', 'shop');
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
<ul class="list-group">
|
||||
@foreach ($categories as $key => $category)
|
||||
<li>
|
||||
<a href="{{ route('shop.categories.index', $category->slug) }}">{{ $category->name }}</a>
|
||||
<a href="{{ route('shop.productOrCategory.index', $category->slug) }}">{{ $category->name }}</a>
|
||||
</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
@endif
|
||||
|
||||
<div class="product-image">
|
||||
<a href="{{ route('shop.products.index', $product->url_key) }}" title="{{ $product->name }}">
|
||||
<a href="{{ route('shop.productOrCategory.index', $product->url_key) }}" title="{{ $product->name }}">
|
||||
<img src="{{ $productBaseImage['medium_image_url'] }}" onerror="this.src='{{ asset('vendor/webkul/ui/assets/images/product/meduim-product-placeholder.png') }}'"/>
|
||||
</a>
|
||||
</div>
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
<div class="product-information">
|
||||
|
||||
<div class="product-name">
|
||||
<a href="{{ url()->to('/').'/products/' . $product->url_key }}" title="{{ $product->name }}">
|
||||
<a href="{{ route('shop.productOrCategory.index', $product->url_key) }}" title="{{ $product->name }}">
|
||||
<span>
|
||||
{{ $product->name }}
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -15,13 +15,13 @@
|
|||
<?php $productBaseImage = $productImageHelper->getProductBaseImage($product); ?>
|
||||
|
||||
<div class="product-image">
|
||||
<a href="{{ route('shop.products.index', $product->url_key) }}" title="{{ $product->name }}">
|
||||
<a href="{{ route('shop.productOrCategory.index', $product->url_key) }}" title="{{ $product->name }}">
|
||||
<img src="{{ $productBaseImage['medium_image_url'] }}" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="product-name mt-20">
|
||||
<a href="{{ url()->to('/').'/products/'.$product->url_key }}" title="{{ $product->name }}">
|
||||
<a href="{{ route('shop.productOrCategory.index', $product->url_key) }}" title="{{ $product->name }}">
|
||||
<span>{{ $product->name }}</span>
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -17,13 +17,13 @@
|
|||
|
||||
<div class="product-info">
|
||||
<div class="product-image">
|
||||
<a href="{{ route('shop.products.index', $product->url_key) }}" title="{{ $product->name }}">
|
||||
<a href="{{ route('shop.productOrCategory.index', $product->url_key) }}" title="{{ $product->name }}">
|
||||
<img src="{{ $productBaseImage['medium_image_url'] }}" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="product-name mt-20">
|
||||
<a href="{{ url()->to('/').'/products/'.$product->url_key }}" title="{{ $product->name }}">
|
||||
<a href="{{ ('shop.productOrCategory.index', $product->url_key) }}" title="{{ $product->name }}">
|
||||
<span>{{ $product->name }}</span>
|
||||
</a>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ class ProductCategoryTest extends DuskTestCase
|
|||
}
|
||||
|
||||
$this->browse(function (Browser $browser) use($testSlug, $testProduct) {
|
||||
$browser->visit(route('shop.categories.index', $testSlug));
|
||||
$browser->visit(route('shop.productOrCategory.index', $testSlug));
|
||||
$browser->assertSeeLink($testProduct[0]['name']);
|
||||
$browser->pause(5000);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue