admin = User::factory()->create(); $this->admin->roles()->create([ 'name' => 'Admin', 'slug' => 'admin', ]); } public function test_can_access_navigation_management() { $response = $this->actingAs($this->admin) ->get(env('ADMIN_PATH', 'loom') . '/navigation'); $response->assertStatus(200); $response->assertViewIs('admin.navigation.index'); } public function test_can_add_navigation_item() { $page = Page::factory()->create(['slug' => 'test-page']); $response = $this->actingAs($this->admin) ->post(env('ADMIN_PATH', 'loom') . '/navigation', [ 'label' => 'Test Link', 'page_id' => $page->id, 'target' => '_self', ]); $response->assertRedirect(); $this->assertDatabaseHas('navigation_items', [ 'label' => 'Test Link', 'page_id' => $page->id, ]); } public function test_navigation_is_shared_with_views() { $item = NavigationItem::create([ 'label' => 'Home', 'url' => '/', 'order' => 0, 'target' => '_self', ]); $response = $this->get('/'); $response->assertStatus(200); $this->assertTrue(isset($response->original->getData()['navigation'])); // NavigationManager uses IDs as keys for DB items $this->assertArrayHasKey($item->id, $response->original->getData()['navigation']); $this->assertEquals('Home', $response->original->getData()['navigation'][$item->id]['label']); } public function test_navigation_manager_merges_items() { $navManager = new NavigationManager(); $navManager->register('test', 'Old Label', '/old'); $navManager->register('test', 'New Label', '/new'); $items = $navManager->getItems(); $this->assertCount(1, $items); $this->assertEquals('New Label', $items['test']['label']); $this->assertEquals('/new', $items['test']['url']); } public function test_can_register_navigation_via_manager_singleton() { $navManager = app(NavigationManager::class); $navManager->register('plugin_item', 'Plugin Page', '/plugin'); $response = $this->get('/'); $response->assertStatus(200); $navigation = $response->original->getData()['navigation']; $this->assertArrayHasKey('plugin_item', $navigation); $this->assertEquals('Plugin Page', $navigation['plugin_item']['label']); } public function test_can_create_page_with_navigation_item() { $response = $this->actingAs($this->admin) ->post(env('ADMIN_PATH', 'loom') . '/pages', [ 'title' => 'Nav Page', 'slug' => 'nav-page', 'content' => [['type' => 'paragraph', 'data' => ['text' => 'Hello']]], 'include_in_navigation' => true, ]); $response->assertRedirect(); $this->assertDatabaseHas('pages', ['title' => 'Nav Page']); $this->assertDatabaseHas('navigation_items', ['label' => 'Nav Page']); } public function test_can_update_page_navigation_item() { $page = Page::factory()->create(['title' => 'Old Title', 'slug' => 'old-slug']); // First, enable navigation $response = $this->actingAs($this->admin) ->put(env('ADMIN_PATH', 'loom') . '/pages/' . $page->id, [ 'title' => 'New Title', 'slug' => 'old-slug', 'content' => [['type' => 'paragraph', 'data' => ['text' => 'Hello']]], 'include_in_navigation' => true, ]); $response->assertRedirect(); $this->assertDatabaseHas('navigation_items', ['page_id' => $page->id, 'label' => 'New Title']); // Now, disable navigation $this->actingAs($this->admin) ->put(env('ADMIN_PATH', 'loom') . '/pages/' . $page->id, [ 'title' => 'New Title', 'slug' => 'old-slug', 'content' => [['type' => 'paragraph', 'data' => ['text' => 'Hello']]], 'include_in_navigation' => false, ]); $this->assertDatabaseMissing('navigation_items', ['page_id' => $page->id]); } public function test_can_create_dropdown_menu() { $parent = NavigationItem::create([ 'label' => 'Parent Menu', 'url' => '#', 'order' => 0, 'target' => '_self', ]); $response = $this->actingAs($this->admin) ->post(env('ADMIN_PATH', 'loom') . '/navigation', [ 'label' => 'Sub Link', 'url' => '/sub-link', 'parent_id' => $parent->id, 'target' => '_self', ]); $response->assertRedirect(); $this->assertDatabaseHas('navigation_items', [ 'label' => 'Sub Link', 'parent_id' => $parent->id, ]); $indexResponse = $this->actingAs($this->admin) ->get(env('ADMIN_PATH', 'loom') . '/navigation'); $indexResponse->assertStatus(200); $items = $indexResponse->viewData('items'); $this->assertCount(1, $items); // Only top-level $this->assertCount(1, $items[0]->children); $this->assertEquals('Sub Link', $items[0]->children[0]->label); $parentItems = $indexResponse->viewData('parentItems'); $this->assertCount(1, $parentItems); $this->assertEquals('Parent Menu', $parentItems[0]->label); } }