ldc-boutique-cnc-sable/tests/Unit/Services/DataTableServiceTest.php
Jérémy Munsch cd7d5f5fe9
feat(orders): implement default sorting for order queries
Added default sorting by date in descending order for order queries.
Updated related views and tests to reflect this change.
2026-10-29 21:16:06 +01:00

193 lines
6.2 KiB
PHP

<?php
declare(strict_types=1);
namespace Tests\Unit\Services;
use App\Models\Order;
use App\Models\Product;
use App\Services\DataTableService;
use Illuminate\Contracts\Database\Query\Builder;
use Illuminate\Contracts\Session\Session;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Schema;
use SortDirection;
describe('DataTableService', function () {
beforeEach(function () {
DataTableService::clearColumnsCache();
});
it('retrieves sort request from request inputs', function () {
// GIVEN
$request = Request::create('/bo/products', 'GET', [
'sort_col' => 'name',
'sort_way' => 'desc',
]);
$session = mock(Session::class);
$session->shouldReceive('get')->andReturn(null);
$service = new DataTableService($request, $session);
// WHEN
$sort = $service->getSortRequest();
// THEN
expect($sort['sort_col'])->toBe('name');
expect($sort['sort_way'])->toBe(SortDirection::Descending);
});
it('falls back to session when sort request input is not provided', function () {
// GIVEN
$request = Request::create('/bo/products', 'GET');
$session = mock(Session::class);
$session->shouldReceive('get')->with('noroute.sort_col', 'undefined')->andReturn('name');
$session->shouldReceive('get')->with('noroute.sort_way')->andReturn('asc');
$service = new DataTableService($request, $session);
// WHEN
$sort = $service->getSortRequest();
// THEN
expect($sort['sort_col'])->toBe('name');
expect($sort['sort_way'])->toBe(SortDirection::Ascending);
});
it('resets sort session when rst parameter is present', function () {
// GIVEN
$request = Request::create('/bo/products', 'GET', ['rst' => '1']);
$session = mock(Session::class);
$session->shouldReceive('forget')->with([
'noroute.sort_col',
'noroute.sort_way',
'noroute.sorted',
])->once();
$session->shouldReceive('get')->andReturn(null);
$service = new DataTableService($request, $session);
// WHEN
$service->resetSortSession('noroute');
// THEN
// Mockery verifies on teardown that forget() was called exactly once with the sort keys.
});
it('sorts query using cached table column listing', function () {
// GIVEN
$request = Request::create('/bo/products', 'GET', [
'sort_col' => 'name',
'sort_way' => 'asc',
]);
$session = mock(Session::class);
$session->shouldReceive('get')->andReturn(null);
$session->shouldReceive('put')->times(4);
Schema::shouldReceive('getColumnListing')
->once()
->with('products')
->andReturn(['id', 'name', 'order', 'created_at']);
$query = mock(Builder::class);
$query->shouldReceive('orderBy')->once()->with('products.name', 'asc');
$query2 = mock(Builder::class);
$query2->shouldReceive('orderBy')->once()->with('products.name', 'asc');
$service = new DataTableService($request, $session);
// WHEN
// First call triggers getColumnListing
$service->sortQuery(Product::class, $query);
// Second call uses columnsCache without re-calling getColumnListing
$service->sortQuery(Product::class, $query2);
// THEN
// Mockery verifies on teardown: getColumnListing() once, orderBy() once per query.
});
it('sorts by default order column if model has order attribute and no sort column is specified', function () {
// GIVEN
$request = Request::create('/bo/products', 'GET');
$session = mock(Session::class);
$session->shouldReceive('get')->andReturn(null);
Schema::shouldReceive('getColumnListing')
->once()
->with('products')
->andReturn(['id', 'name', 'order', 'created_at']);
$query = mock(Builder::class);
$query->shouldReceive('orderBy')->once()->with('order', 'asc');
$service = new DataTableService($request, $session);
// WHEN
$service->sortQuery(Product::class, $query);
// THEN
// Mockery verifies on teardown that orderBy('order', 'asc') was called once.
});
it('sorts by custom default column and way when no sort column is specified', function () {
// GIVEN
$request = Request::create('/bo/orders', 'GET');
$session = mock(Session::class);
$session->shouldReceive('get')->andReturn(null);
Schema::shouldReceive('getColumnListing')
->once()
->with('orders')
->andReturn(['id', 'reference', 'status', 'total']);
$query = mock(Builder::class);
$query->shouldReceive('orderBy')->once()->with('orders.id', 'desc');
$service = new DataTableService($request, $session);
// WHEN
$service->sortQuery(
Order::class,
$query,
defaultSortCol: 'date',
defaultSortWay: SortDirection::Descending,
columnMap: ['date' => 'id'],
);
// THEN
// Mockery verifies on teardown that orderBy('orders.id', 'desc') was called once.
});
it('uses columnMap when sorting by an explicit virtual column', function () {
// GIVEN
$request = Request::create('/bo/orders', 'GET', [
'sort_col' => 'date',
'sort_way' => 'asc',
]);
$session = mock(Session::class);
$session->shouldReceive('get')->andReturn(null);
$session->shouldReceive('put')->twice();
Schema::shouldReceive('getColumnListing')
->once()
->with('orders')
->andReturn(['id', 'reference', 'status', 'total']);
$query = mock(Builder::class);
$query->shouldReceive('orderBy')->once()->with('orders.id', 'asc');
$service = new DataTableService($request, $session);
// WHEN
$service->sortQuery(
Order::class,
$query,
columnMap: ['date' => 'id'],
);
// THEN
// Mockery verifies on teardown that orderBy('orders.id', 'asc') was called once.
});
});