| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- <?php
- namespace Tests\Integration;
- use App\Services\MenuService;
- use Illuminate\Config\Repository;
- use Illuminate\Database\Capsule\Manager;
- use Illuminate\Database\Eloquent\Model;
- use Illuminate\Database\Schema\Blueprint;
- use Illuminate\Foundation\Application;
- use Illuminate\Support\Facades\DB;
- use Illuminate\Support\Facades\Facade;
- use PHPUnit\Framework\TestCase;
- class MenuOrderTest extends TestCase
- {
- protected function setUp(): void
- {
- Facade::clearResolvedInstances();
- Model::clearBootedModels();
- $app = new Application(dirname(__DIR__, 2));
- $app->instance('config', new Repository(['app' => ['url' => 'https://admin.example.test']]));
- Facade::setFacadeApplication($app);
- $db = new Manager($app);
- $db->addConnection(['driver' => 'sqlite', 'database' => ':memory:', 'prefix' => 'bot_']);
- $db->setAsGlobal();
- $db->bootEloquent();
- $app->instance('db', $db->getDatabaseManager());
- $db->schema()->create('menus', function (Blueprint $t) {
- $t->id();
- $t->integer('parent_id')->default(0);
- $t->string('title');
- $t->integer('sort')->default(0);
- $t->integer('status')->default(1);
- $t->integer('type')->default(1);
- $t->string('uri')->default('');
- });
- $db->schema()->create('roles', function (Blueprint $t) {
- $t->id();
- $t->string('name');
- });
- foreach (['role_user' => 'user_id', 'role_menu' => 'menu_id'] as $table => $field) {
- $db->schema()->create($table, function (Blueprint $t) use ($field) {
- $t->id();
- $t->integer('role_id');
- $t->integer($field);
- });
- }
- }
- protected function tearDown(): void
- {
- DB::disconnect();
- Facade::clearResolvedInstances();
- Model::clearBootedModels();
- parent::tearDown();
- }
- private function menu(int $id, int $sort, int $parent = 0, int $status = 1, int $type = 1): void
- {
- DB::table('menus')->insert([
- 'id' => $id, 'title' => 'Menu ' . $id, 'sort' => $sort,
- 'parent_id' => $parent, 'status' => $status, 'type' => $type,
- ]);
- }
- private function role(int $id, array $menus, array $users): void
- {
- DB::table('roles')->insert(['id' => $id, 'name' => 'Role ' . $id]);
- foreach ($menus as $menuId) {
- DB::table('role_menu')->insert(['role_id' => $id, 'menu_id' => $menuId]);
- }
- foreach ($users as $userId) {
- DB::table('role_user')->insert(['role_id' => $id, 'user_id' => $userId]);
- }
- }
- private function treeIds($tree): array
- {
- $result = [];
- foreach ($tree as $node) {
- $result[] = ['id' => (int) $node['id'], 'children' => $this->treeIds($node['children'])];
- }
- return $result;
- }
- public function test_single_and_multiple_roles_follow_admin_order_for_roots_children_and_equal_sort(): void
- {
- foreach ([[10, 30], [20, 10], [30, 10]] as [$id, $sort]) {
- $this->menu($id, $sort);
- }
- foreach ([[50, 30], [60, 5], [70, 5], [80, 20]] as [$id, $sort]) {
- $this->menu($id, $sort, 20);
- }
- $this->role(1, [10, 30, 50, 70], [20]);
- $this->role(2, [20, 30, 60, 70, 80], [20]);
- $this->role(3, [70, 50, 30, 10, 80, 60, 20], [21]);
- $expected = $this->treeIds(MenuService::getUserMenu(1));
- $this->assertSame([20, 30, 10], array_column($expected, 'id'));
- $this->assertSame([60, 70, 80, 50], array_column($expected[0]['children'], 'id'));
- $this->assertSame($expected, $this->treeIds(MenuService::getUserMenu(20)));
- $this->assertSame($expected, $this->treeIds(MenuService::getUserMenu(21)));
- }
- public function test_sorting_preserves_role_permissions_existing_hidden_menus_and_menu_types(): void
- {
- $this->menu(10, 30);
- $this->menu(20, 10);
- $this->menu(30, 20, status: 2);
- $this->menu(40, 20, type: 2);
- $this->menu(50, 10, type: 2);
- $this->menu(60, 0, type: 2);
- $this->role(1, [10, 30, 40, 50], [20]);
- $this->role(2, [20], [21]);
- $this->assertSame([30, 10], array_column($this->treeIds(MenuService::getUserMenu(20)), 'id'));
- $this->assertSame([20], array_column($this->treeIds(MenuService::getUserMenu(21)), 'id'));
- $buttons = MenuService::getUserMenu(20, 2);
- $this->assertSame([50, 40], array_column($buttons, 'id'));
- $this->assertSame([], MenuService::getUserMenu(99));
- $this->assertSame([], MenuService::getUserMenu(99, 2));
- // Admin still uses its existing sort-only query and visible-menu filter.
- $this->assertSame([20, 10], array_column($this->treeIds(MenuService::getUserMenu(1)), 'id'));
- $this->assertSame([60, 50, 40], MenuService::getUserMenu(1, 2)->pluck('id')->all());
- }
- }
|