Added default sorting by date in descending order for order queries. Updated related views and tests to reflect this change.
193 lines
6.2 KiB
PHP
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.
|
|
});
|
|
});
|