API pagination: Fixed #19155 - API not paginating correctly with page=x, added tests
This commit is contained in:
@@ -107,7 +107,7 @@ class AccessoriesController extends Controller
|
||||
}
|
||||
|
||||
// Make sure the offset and limit are actually integers and do not exceed system limits
|
||||
$offset = ($request->input('offset') > $accessories->count()) ? $accessories->count() : abs($request->input('offset'));
|
||||
$offset = ($request->input('offset') > $accessories->count()) ? $accessories->count() : app('api_offset_value');
|
||||
$limit = app('api_limit_value');
|
||||
|
||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||
|
||||
@@ -133,7 +133,8 @@ class AssetModelsController extends Controller
|
||||
}
|
||||
|
||||
// Make sure the offset and limit are actually integers and do not exceed system limits
|
||||
$offset = ($request->input('offset') > $assetmodels->count()) ? $assetmodels->count() : abs($request->input('offset'));
|
||||
$total = $assetmodels->count();
|
||||
$offset = ($request->input('offset') > $total) ? $total : app('api_offset_value');
|
||||
$limit = app('api_limit_value');
|
||||
|
||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||
@@ -157,7 +158,6 @@ class AssetModelsController extends Controller
|
||||
break;
|
||||
}
|
||||
|
||||
$total = $assetmodels->count();
|
||||
$assetmodels = $assetmodels->skip($offset)->take($limit)->get();
|
||||
|
||||
return (new AssetModelsTransformer)->transformAssetModels($assetmodels, $total);
|
||||
|
||||
@@ -30,7 +30,7 @@ class MaintenanceTypesController extends Controller
|
||||
$types->where('name', '=', $request->input('name'));
|
||||
}
|
||||
|
||||
$offset = ($request->input('offset') > $types->count()) ? $types->count() : abs($request->input('offset'));
|
||||
$offset = ($request->input('offset') > $types->count()) ? $types->count() : app('api_offset_value');
|
||||
$limit = app('api_limit_value');
|
||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||
$sort = in_array($request->input('sort'), ['id', 'name', 'created_at', 'updated_at']) ? $request->input('sort') : 'name';
|
||||
|
||||
@@ -102,7 +102,7 @@ class MaintenancesController extends Controller
|
||||
}
|
||||
|
||||
// Make sure the offset and limit are actually integers and do not exceed system limits
|
||||
$offset = ($request->input('offset') > $maintenances->count()) ? $maintenances->count() : abs($request->input('offset'));
|
||||
$offset = ($request->input('offset') > $maintenances->count()) ? $maintenances->count() : app('api_offset_value');
|
||||
$limit = app('api_limit_value');
|
||||
|
||||
$allowed_columns = [
|
||||
|
||||
@@ -52,7 +52,7 @@ class UploadedFilesController extends Controller
|
||||
$uploads = self::$map_object_type[$object_type]::withTrashed()->find($id)->uploads()
|
||||
->with('adminuser');
|
||||
|
||||
$offset = ($request->input('offset') > $uploads->count()) ? $uploads->count() : abs($request->input('offset'));
|
||||
$offset = ($request->input('offset') > $uploads->count()) ? $uploads->count() : app('api_offset_value');
|
||||
$limit = app('api_limit_value');
|
||||
$order = $request->input('order') === 'asc' ? 'asc' : 'desc';
|
||||
$sort = in_array($request->input('sort'), $allowed_columns) ? $request->input('sort') : 'created_at';
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature\Accessories\Api;
|
||||
|
||||
use App\Models\Accessory;
|
||||
use App\Models\User;
|
||||
use Tests\TestCase;
|
||||
|
||||
class AccessoryPaginationTest extends TestCase
|
||||
{
|
||||
private User $user;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->user = User::factory()->superuser()->create();
|
||||
}
|
||||
|
||||
public function test_page_one_returns_first_items()
|
||||
{
|
||||
foreach (range(1, 10) as $i) {
|
||||
Accessory::factory()->create(['name' => sprintf('PAG-TEST-%03d', $i)]);
|
||||
}
|
||||
|
||||
$names = $this->actingAsForApi($this->user)
|
||||
->getJson(route('api.accessories.index', ['page' => 1, 'limit' => 5, 'sort' => 'name', 'order' => 'asc']))
|
||||
->assertOk()
|
||||
->json('rows.*.name');
|
||||
|
||||
$this->assertEquals(
|
||||
['PAG-TEST-001', 'PAG-TEST-002', 'PAG-TEST-003', 'PAG-TEST-004', 'PAG-TEST-005'],
|
||||
$names
|
||||
);
|
||||
}
|
||||
|
||||
public function test_page_two_returns_second_set_of_items()
|
||||
{
|
||||
foreach (range(1, 10) as $i) {
|
||||
Accessory::factory()->create(['name' => sprintf('PAG-TEST-%03d', $i)]);
|
||||
}
|
||||
|
||||
$names = $this->actingAsForApi($this->user)
|
||||
->getJson(route('api.accessories.index', ['page' => 2, 'limit' => 5, 'sort' => 'name', 'order' => 'asc']))
|
||||
->assertOk()
|
||||
->json('rows.*.name');
|
||||
|
||||
$this->assertEquals(
|
||||
['PAG-TEST-006', 'PAG-TEST-007', 'PAG-TEST-008', 'PAG-TEST-009', 'PAG-TEST-010'],
|
||||
$names
|
||||
);
|
||||
}
|
||||
|
||||
public function test_offset_returns_correct_items()
|
||||
{
|
||||
foreach (range(1, 10) as $i) {
|
||||
Accessory::factory()->create(['name' => sprintf('PAG-TEST-%03d', $i)]);
|
||||
}
|
||||
|
||||
$names = $this->actingAsForApi($this->user)
|
||||
->getJson(route('api.accessories.index', ['offset' => 5, 'limit' => 5, 'sort' => 'name', 'order' => 'asc']))
|
||||
->assertOk()
|
||||
->json('rows.*.name');
|
||||
|
||||
$this->assertEquals(
|
||||
['PAG-TEST-006', 'PAG-TEST-007', 'PAG-TEST-008', 'PAG-TEST-009', 'PAG-TEST-010'],
|
||||
$names
|
||||
);
|
||||
}
|
||||
|
||||
public function test_page_param_respects_limit()
|
||||
{
|
||||
Accessory::factory()->count(10)->create();
|
||||
|
||||
$response = $this->actingAsForApi($this->user)
|
||||
->getJson(route('api.accessories.index', ['page' => 1, 'limit' => 4]))
|
||||
->assertOk();
|
||||
|
||||
$this->assertCount(4, $response->json('rows'));
|
||||
}
|
||||
|
||||
public function test_page_beyond_results_returns_empty_rows()
|
||||
{
|
||||
Accessory::factory()->count(5)->create();
|
||||
|
||||
$response = $this->actingAsForApi($this->user)
|
||||
->getJson(route('api.accessories.index', ['page' => 99, 'limit' => 5]))
|
||||
->assertOk();
|
||||
|
||||
$this->assertCount(0, $response->json('rows'));
|
||||
$this->assertEquals(5, $response->json('total'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature\AssetModels\Api;
|
||||
|
||||
use App\Models\AssetModel;
|
||||
use App\Models\User;
|
||||
use Tests\TestCase;
|
||||
|
||||
class AssetModelPaginationTest extends TestCase
|
||||
{
|
||||
private User $user;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->user = User::factory()->superuser()->create();
|
||||
}
|
||||
|
||||
public function test_page_one_returns_first_items()
|
||||
{
|
||||
foreach (range(1, 10) as $i) {
|
||||
AssetModel::factory()->create(['name' => sprintf('PAG-TEST-%03d', $i)]);
|
||||
}
|
||||
|
||||
$names = $this->actingAsForApi($this->user)
|
||||
->getJson(route('api.models.index', ['page' => 1, 'limit' => 5, 'sort' => 'name', 'order' => 'asc']))
|
||||
->assertOk()
|
||||
->json('rows.*.name');
|
||||
|
||||
$this->assertEquals(
|
||||
['PAG-TEST-001', 'PAG-TEST-002', 'PAG-TEST-003', 'PAG-TEST-004', 'PAG-TEST-005'],
|
||||
$names
|
||||
);
|
||||
}
|
||||
|
||||
public function test_page_two_returns_second_set_of_items()
|
||||
{
|
||||
foreach (range(1, 10) as $i) {
|
||||
AssetModel::factory()->create(['name' => sprintf('PAG-TEST-%03d', $i)]);
|
||||
}
|
||||
|
||||
$names = $this->actingAsForApi($this->user)
|
||||
->getJson(route('api.models.index', ['page' => 2, 'limit' => 5, 'sort' => 'name', 'order' => 'asc']))
|
||||
->assertOk()
|
||||
->json('rows.*.name');
|
||||
|
||||
$this->assertEquals(
|
||||
['PAG-TEST-006', 'PAG-TEST-007', 'PAG-TEST-008', 'PAG-TEST-009', 'PAG-TEST-010'],
|
||||
$names
|
||||
);
|
||||
}
|
||||
|
||||
public function test_offset_returns_correct_items()
|
||||
{
|
||||
foreach (range(1, 10) as $i) {
|
||||
AssetModel::factory()->create(['name' => sprintf('PAG-TEST-%03d', $i)]);
|
||||
}
|
||||
|
||||
$names = $this->actingAsForApi($this->user)
|
||||
->getJson(route('api.models.index', ['offset' => 5, 'limit' => 5, 'sort' => 'name', 'order' => 'asc']))
|
||||
->assertOk()
|
||||
->json('rows.*.name');
|
||||
|
||||
$this->assertEquals(
|
||||
['PAG-TEST-006', 'PAG-TEST-007', 'PAG-TEST-008', 'PAG-TEST-009', 'PAG-TEST-010'],
|
||||
$names
|
||||
);
|
||||
}
|
||||
|
||||
public function test_page_param_respects_limit()
|
||||
{
|
||||
AssetModel::factory()->count(10)->create();
|
||||
|
||||
$response = $this->actingAsForApi($this->user)
|
||||
->getJson(route('api.models.index', ['page' => 1, 'limit' => 4]))
|
||||
->assertOk();
|
||||
|
||||
$this->assertCount(4, $response->json('rows'));
|
||||
}
|
||||
|
||||
public function test_page_beyond_results_returns_empty_rows()
|
||||
{
|
||||
AssetModel::factory()->count(5)->create();
|
||||
|
||||
$response = $this->actingAsForApi($this->user)
|
||||
->getJson(route('api.models.index', ['page' => 99, 'limit' => 5]))
|
||||
->assertOk();
|
||||
|
||||
$this->assertCount(0, $response->json('rows'));
|
||||
$this->assertEquals(5, $response->json('total'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature\Assets\Api;
|
||||
|
||||
use App\Models\Actionlog;
|
||||
use App\Models\Asset;
|
||||
use App\Models\User;
|
||||
use Tests\TestCase;
|
||||
|
||||
class UploadedFilesPaginationTest extends TestCase
|
||||
{
|
||||
private User $user;
|
||||
private Asset $asset;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->user = User::factory()->superuser()->create();
|
||||
$this->asset = Asset::factory()->create();
|
||||
}
|
||||
|
||||
private function createUploadLog(string $filename): void
|
||||
{
|
||||
$log = new Actionlog();
|
||||
$log->item_id = $this->asset->id;
|
||||
$log->item_type = Asset::class;
|
||||
$log->action_type = 'uploaded';
|
||||
$log->filename = $filename;
|
||||
$log->created_by = $this->user->id;
|
||||
$log->save();
|
||||
}
|
||||
|
||||
public function test_page_one_returns_first_items()
|
||||
{
|
||||
foreach (range(1, 10) as $i) {
|
||||
$this->createUploadLog(sprintf('PAG-TEST-%03d.jpg', $i));
|
||||
}
|
||||
|
||||
$filenames = $this->actingAsForApi($this->user)
|
||||
->getJson(route('api.files.index', [
|
||||
'object_type' => 'assets',
|
||||
'id' => $this->asset->id,
|
||||
'page' => 1,
|
||||
'limit' => 5,
|
||||
'sort' => 'filename',
|
||||
'order' => 'asc',
|
||||
]))
|
||||
->assertOk()
|
||||
->json('rows.*.filename');
|
||||
|
||||
$this->assertEquals(
|
||||
['PAG-TEST-001.jpg', 'PAG-TEST-002.jpg', 'PAG-TEST-003.jpg', 'PAG-TEST-004.jpg', 'PAG-TEST-005.jpg'],
|
||||
$filenames
|
||||
);
|
||||
}
|
||||
|
||||
public function test_page_two_returns_second_set_of_items()
|
||||
{
|
||||
foreach (range(1, 10) as $i) {
|
||||
$this->createUploadLog(sprintf('PAG-TEST-%03d.jpg', $i));
|
||||
}
|
||||
|
||||
$filenames = $this->actingAsForApi($this->user)
|
||||
->getJson(route('api.files.index', [
|
||||
'object_type' => 'assets',
|
||||
'id' => $this->asset->id,
|
||||
'page' => 2,
|
||||
'limit' => 5,
|
||||
'sort' => 'filename',
|
||||
'order' => 'asc',
|
||||
]))
|
||||
->assertOk()
|
||||
->json('rows.*.filename');
|
||||
|
||||
$this->assertEquals(
|
||||
['PAG-TEST-006.jpg', 'PAG-TEST-007.jpg', 'PAG-TEST-008.jpg', 'PAG-TEST-009.jpg', 'PAG-TEST-010.jpg'],
|
||||
$filenames
|
||||
);
|
||||
}
|
||||
|
||||
public function test_offset_returns_correct_items()
|
||||
{
|
||||
foreach (range(1, 10) as $i) {
|
||||
$this->createUploadLog(sprintf('PAG-TEST-%03d.jpg', $i));
|
||||
}
|
||||
|
||||
$filenames = $this->actingAsForApi($this->user)
|
||||
->getJson(route('api.files.index', [
|
||||
'object_type' => 'assets',
|
||||
'id' => $this->asset->id,
|
||||
'offset' => 5,
|
||||
'limit' => 5,
|
||||
'sort' => 'filename',
|
||||
'order' => 'asc',
|
||||
]))
|
||||
->assertOk()
|
||||
->json('rows.*.filename');
|
||||
|
||||
$this->assertEquals(
|
||||
['PAG-TEST-006.jpg', 'PAG-TEST-007.jpg', 'PAG-TEST-008.jpg', 'PAG-TEST-009.jpg', 'PAG-TEST-010.jpg'],
|
||||
$filenames
|
||||
);
|
||||
}
|
||||
|
||||
public function test_page_param_respects_limit()
|
||||
{
|
||||
foreach (range(1, 10) as $i) {
|
||||
$this->createUploadLog(sprintf('PAG-TEST-%03d.jpg', $i));
|
||||
}
|
||||
|
||||
$response = $this->actingAsForApi($this->user)
|
||||
->getJson(route('api.files.index', [
|
||||
'object_type' => 'assets',
|
||||
'id' => $this->asset->id,
|
||||
'page' => 1,
|
||||
'limit' => 4,
|
||||
]))
|
||||
->assertOk();
|
||||
|
||||
$this->assertCount(4, $response->json('rows'));
|
||||
}
|
||||
|
||||
public function test_page_beyond_results_returns_empty_rows()
|
||||
{
|
||||
foreach (range(1, 5) as $i) {
|
||||
$this->createUploadLog(sprintf('PAG-TEST-%03d.jpg', $i));
|
||||
}
|
||||
|
||||
$response = $this->actingAsForApi($this->user)
|
||||
->getJson(route('api.files.index', [
|
||||
'object_type' => 'assets',
|
||||
'id' => $this->asset->id,
|
||||
'page' => 99,
|
||||
'limit' => 5,
|
||||
]))
|
||||
->assertOk();
|
||||
|
||||
$this->assertCount(0, $response->json('rows'));
|
||||
$this->assertEquals(5, $response->json('total'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature\Maintenances\Api;
|
||||
|
||||
use App\Models\Maintenance;
|
||||
use App\Models\User;
|
||||
use Tests\TestCase;
|
||||
|
||||
class MaintenancePaginationTest extends TestCase
|
||||
{
|
||||
private User $user;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->user = User::factory()->superuser()->create();
|
||||
}
|
||||
|
||||
public function test_page_one_returns_first_items()
|
||||
{
|
||||
foreach (range(1, 10) as $i) {
|
||||
Maintenance::factory()->create(['name' => sprintf('PAG-TEST-%03d', $i)]);
|
||||
}
|
||||
|
||||
$names = $this->actingAsForApi($this->user)
|
||||
->getJson(route('api.maintenances.index', ['page' => 1, 'limit' => 5, 'sort' => 'name', 'order' => 'asc']))
|
||||
->assertOk()
|
||||
->json('rows.*.name');
|
||||
|
||||
$this->assertEquals(
|
||||
['PAG-TEST-001', 'PAG-TEST-002', 'PAG-TEST-003', 'PAG-TEST-004', 'PAG-TEST-005'],
|
||||
$names
|
||||
);
|
||||
}
|
||||
|
||||
public function test_page_two_returns_second_set_of_items()
|
||||
{
|
||||
foreach (range(1, 10) as $i) {
|
||||
Maintenance::factory()->create(['name' => sprintf('PAG-TEST-%03d', $i)]);
|
||||
}
|
||||
|
||||
$names = $this->actingAsForApi($this->user)
|
||||
->getJson(route('api.maintenances.index', ['page' => 2, 'limit' => 5, 'sort' => 'name', 'order' => 'asc']))
|
||||
->assertOk()
|
||||
->json('rows.*.name');
|
||||
|
||||
$this->assertEquals(
|
||||
['PAG-TEST-006', 'PAG-TEST-007', 'PAG-TEST-008', 'PAG-TEST-009', 'PAG-TEST-010'],
|
||||
$names
|
||||
);
|
||||
}
|
||||
|
||||
public function test_offset_returns_correct_items()
|
||||
{
|
||||
foreach (range(1, 10) as $i) {
|
||||
Maintenance::factory()->create(['name' => sprintf('PAG-TEST-%03d', $i)]);
|
||||
}
|
||||
|
||||
$names = $this->actingAsForApi($this->user)
|
||||
->getJson(route('api.maintenances.index', ['offset' => 5, 'limit' => 5, 'sort' => 'name', 'order' => 'asc']))
|
||||
->assertOk()
|
||||
->json('rows.*.name');
|
||||
|
||||
$this->assertEquals(
|
||||
['PAG-TEST-006', 'PAG-TEST-007', 'PAG-TEST-008', 'PAG-TEST-009', 'PAG-TEST-010'],
|
||||
$names
|
||||
);
|
||||
}
|
||||
|
||||
public function test_page_param_respects_limit()
|
||||
{
|
||||
Maintenance::factory()->count(10)->create();
|
||||
|
||||
$response = $this->actingAsForApi($this->user)
|
||||
->getJson(route('api.maintenances.index', ['page' => 1, 'limit' => 4]))
|
||||
->assertOk();
|
||||
|
||||
$this->assertCount(4, $response->json('rows'));
|
||||
}
|
||||
|
||||
public function test_page_beyond_results_returns_empty_rows()
|
||||
{
|
||||
Maintenance::factory()->count(5)->create();
|
||||
|
||||
$response = $this->actingAsForApi($this->user)
|
||||
->getJson(route('api.maintenances.index', ['page' => 99, 'limit' => 5]))
|
||||
->assertOk();
|
||||
|
||||
$this->assertCount(0, $response->json('rows'));
|
||||
$this->assertEquals(5, $response->json('total'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature\Maintenances\Api;
|
||||
|
||||
use App\Models\MaintenanceType;
|
||||
use App\Models\User;
|
||||
use Tests\TestCase;
|
||||
|
||||
class MaintenanceTypesPaginationTest extends TestCase
|
||||
{
|
||||
private User $user;
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
$this->user = User::factory()->superuser()->create();
|
||||
// Remove migration-seeded types so alphabetical sorting is predictable
|
||||
MaintenanceType::query()->delete();
|
||||
}
|
||||
|
||||
public function test_page_one_returns_first_items()
|
||||
{
|
||||
foreach (range(1, 10) as $i) {
|
||||
MaintenanceType::factory()->create(['name' => sprintf('PAG-TEST-%03d', $i)]);
|
||||
}
|
||||
|
||||
$names = $this->actingAsForApi($this->user)
|
||||
->getJson(route('api.maintenance-types.index', ['page' => 1, 'limit' => 5, 'sort' => 'name', 'order' => 'asc']))
|
||||
->assertOk()
|
||||
->json('rows.*.name');
|
||||
|
||||
$this->assertEquals(
|
||||
['PAG-TEST-001', 'PAG-TEST-002', 'PAG-TEST-003', 'PAG-TEST-004', 'PAG-TEST-005'],
|
||||
$names
|
||||
);
|
||||
}
|
||||
|
||||
public function test_page_two_returns_second_set_of_items()
|
||||
{
|
||||
foreach (range(1, 10) as $i) {
|
||||
MaintenanceType::factory()->create(['name' => sprintf('PAG-TEST-%03d', $i)]);
|
||||
}
|
||||
|
||||
$names = $this->actingAsForApi($this->user)
|
||||
->getJson(route('api.maintenance-types.index', ['page' => 2, 'limit' => 5, 'sort' => 'name', 'order' => 'asc']))
|
||||
->assertOk()
|
||||
->json('rows.*.name');
|
||||
|
||||
$this->assertEquals(
|
||||
['PAG-TEST-006', 'PAG-TEST-007', 'PAG-TEST-008', 'PAG-TEST-009', 'PAG-TEST-010'],
|
||||
$names
|
||||
);
|
||||
}
|
||||
|
||||
public function test_offset_returns_correct_items()
|
||||
{
|
||||
foreach (range(1, 10) as $i) {
|
||||
MaintenanceType::factory()->create(['name' => sprintf('PAG-TEST-%03d', $i)]);
|
||||
}
|
||||
|
||||
$names = $this->actingAsForApi($this->user)
|
||||
->getJson(route('api.maintenance-types.index', ['offset' => 5, 'limit' => 5, 'sort' => 'name', 'order' => 'asc']))
|
||||
->assertOk()
|
||||
->json('rows.*.name');
|
||||
|
||||
$this->assertEquals(
|
||||
['PAG-TEST-006', 'PAG-TEST-007', 'PAG-TEST-008', 'PAG-TEST-009', 'PAG-TEST-010'],
|
||||
$names
|
||||
);
|
||||
}
|
||||
|
||||
public function test_page_param_respects_limit()
|
||||
{
|
||||
MaintenanceType::factory()->count(10)->create();
|
||||
|
||||
$response = $this->actingAsForApi($this->user)
|
||||
->getJson(route('api.maintenance-types.index', ['page' => 1, 'limit' => 4]))
|
||||
->assertOk();
|
||||
|
||||
$this->assertCount(4, $response->json('rows'));
|
||||
}
|
||||
|
||||
public function test_page_beyond_results_returns_empty_rows()
|
||||
{
|
||||
MaintenanceType::factory()->count(5)->create();
|
||||
|
||||
$response = $this->actingAsForApi($this->user)
|
||||
->getJson(route('api.maintenance-types.index', ['page' => 99, 'limit' => 5]))
|
||||
->assertOk();
|
||||
|
||||
$this->assertCount(0, $response->json('rows'));
|
||||
$this->assertEquals(5, $response->json('total'));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user