justReturn(['primary-menu' => 'Hauptmenü']); Functions\when('get_nav_menu_locations')->justReturn(['primary-menu' => 3]); Functions\when('wp_get_nav_menu_object')->alias( static fn (int $id) => match ($id) { 8 => (object) ['term_id' => 8, 'name' => 'Neu'], 3 => (object) ['term_id' => 3, 'name' => 'Hauptmenü'], default => false, } ); } public function testAssignsAndReportsThePreviousMenu(): void { Functions\expect('set_theme_mod')->once()->with('nav_menu_locations', ['primary-menu' => 8]); $log = new FakeChangeLog(6); $result = (new MenuAssignLocationAbility($log))->execute(['location' => 'primary-menu', 'menu_id' => 8]); self::assertSame(3, $result['previous_menu_id']); self::assertSame('assigned', $result['changed'][0]['action']); self::assertSame(6, $result['log_id']); $log->assertRecorded([ 'ability' => 'lit/menu-assign-location', 'object_type' => 'menu_location', 'object_id' => 'primary-menu', 'summary' => 'Menü 8 der Position primary-menu zugewiesen', ]); } public function testRemovingAnAssignmentNeedsConfirmation(): void { Functions\expect('set_theme_mod')->never(); $result = (new MenuAssignLocationAbility(FakeChangeLog::forbidden())) ->execute(['location' => 'primary-menu', 'menu_id' => 0]); self::assertToolError($result, 'confirm_required'); self::assertStringContainsString( '"Hauptmenü" (ID 3)', self::clientError($result)['message'] ); } public function testZeroRemovesTheAssignmentAndNamesTheRemovedMenu(): void { Functions\expect('set_theme_mod')->once()->with('nav_menu_locations', []); $log = new FakeChangeLog(7); $result = (new MenuAssignLocationAbility($log)) ->execute(['location' => 'primary-menu', 'menu_id' => 0, 'confirm' => true]); self::assertSame('unassigned', $result['changed'][0]['action']); self::assertSame(3, $result['previous_menu_id']); self::assertStringContainsString('"Hauptmenü" (ID 3)', $result['summary']); self::assertSame(7, $result['log_id']); $log->assertRecorded([ 'ability' => 'lit/menu-assign-location', 'object_type' => 'menu_location', 'object_id' => 'primary-menu', 'summary' => 'Menü "Hauptmenü" (ID 3) von der Position primary-menu entfernt', ]); } public function testRemovingFromAnEmptyLocationNeedsNoConfirmation(): void { Functions\when('get_nav_menu_locations')->justReturn([]); Functions\expect('set_theme_mod')->once()->with('nav_menu_locations', []); $log = new FakeChangeLog(8); $result = (new MenuAssignLocationAbility($log))->execute(['location' => 'primary-menu', 'menu_id' => 0]); self::assertTrue($result['ok']); self::assertNull($result['previous_menu_id']); } public function testDescribesTheConfirmationForRemoval(): void { $ability = new MenuAssignLocationAbility(FakeChangeLog::forbidden()); self::assertArrayHasKey('confirm', $ability->inputSchema()['properties']); self::assertStringContainsString('confirm: true', $ability->description()); } public function testUnknownMenuIsNotFound(): void { Functions\expect('set_theme_mod')->never(); $result = (new MenuAssignLocationAbility(FakeChangeLog::forbidden())) ->execute(['location' => 'primary-menu', 'menu_id' => 99]); self::assertToolError($result, 'not_found'); } public function testPermissionNeedsThemeOptionRights(): void { Functions\when('current_user_can')->justReturn(false); $ability = new MenuAssignLocationAbility(FakeChangeLog::forbidden()); $input = ['location' => 'primary-menu', 'menu_id' => 8]; self::assertToolError($ability->permission($input), 'forbidden'); } public function testIsDestructiveBecauseItReplacesTheMenuOfTheLocation(): void { $ability = new MenuAssignLocationAbility(FakeChangeLog::forbidden()); self::assertSame(['readonly' => false, 'destructive' => true, 'idempotent' => true], $ability->annotations()); } }