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 = Mockery::mock(ChangeLog::class); $log->expects('record') ->with( 'lit/menu-assign-location', 'menu_location', 'primary-menu', 'Menü 8 der Position primary-menu zugewiesen' ) ->andReturn(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']); } public function testRemovingAnAssignmentNeedsConfirmation(): void { Functions\expect('set_theme_mod')->never(); $result = (new MenuAssignLocationAbility(Mockery::mock(ChangeLog::class))) ->execute(['location' => 'primary-menu', 'menu_id' => 0]); self::assertSame('lit_confirm_required', $result->get_error_code()); self::assertStringContainsString( '"Hauptmenü" (ID 3)', json_decode($result->get_error_message(), true)['message'] ); } public function testZeroRemovesTheAssignmentAndNamesTheRemovedMenu(): void { Functions\expect('set_theme_mod')->once()->with('nav_menu_locations', []); $log = Mockery::mock(ChangeLog::class); $log->expects('record') ->with( 'lit/menu-assign-location', 'menu_location', 'primary-menu', 'Menü "Hauptmenü" (ID 3) von der Position primary-menu entfernt' ) ->andReturn(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']); } public function testRemovingFromAnEmptyLocationNeedsNoConfirmation(): void { Functions\when('get_nav_menu_locations')->justReturn([]); Functions\expect('set_theme_mod')->once()->with('nav_menu_locations', []); $log = Mockery::mock(ChangeLog::class); $log->allows('record')->andReturn(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(Mockery::mock(ChangeLog::class)); 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(Mockery::mock(ChangeLog::class))) ->execute(['location' => 'primary-menu', 'menu_id' => 99]); self::assertSame('lit_not_found', $result->get_error_code()); } public function testPermissionNeedsThemeOptionRights(): void { Functions\when('current_user_can')->justReturn(false); $ability = new MenuAssignLocationAbility(Mockery::mock(ChangeLog::class)); $input = ['location' => 'primary-menu', 'menu_id' => 8]; self::assertSame('lit_forbidden', $ability->permission($input)->get_error_code()); } }