Skip to content

fix(MoveMailboxModal): make self-move a real no-op and always reset state - #13661

Open
chiliec wants to merge 1 commit into
nextcloud:mainfrom
chiliec:fix/move-mailbox-self-move-guard
Open

fix(MoveMailboxModal): make self-move a real no-op and always reset state#13661
chiliec wants to merge 1 commit into
nextcloud:mainfrom
chiliec:fix/move-mailbox-self-move-guard

Conversation

@chiliec

@chiliec chiliec commented Sep 9, 2026

Copy link
Copy Markdown

What

Closes #13534

Fixes the dead self-move guard in the move-folder modal.

The bug

onMove() set this.moving = true and then guarded the whole operation with this.mailbox.id !== this.destMailboxId:

  • Mailbox::jsonSerialize exposes id as base64_encode($name), while destMailboxId is always the numeric databaseId (or undefined). The two can never be equal, so the "moving a folder into itself is a no-op" check never fired — selecting the current parent for a folder that already sits there issued a rename to its own name, and the resulting IMAP error was only logged (silent no-op for the user).
  • The moving = false / $emit('close') cleanup lived inside the finally of that dead branch, so a corrected early exit would have left the dialog's primary button disabled forever (since fix: minor adjustment in moving messages, threads and folders #13431 made the handler's promise the one NcDialogButton awaits).

Fix

  • Compare this.mailbox.databaseId against this.destMailboxId.
  • Return early (after emitting close) when they match, before setting moving = true.
  • The try/finally now covers the actual move, so moving is always reset and the dialog always closes.

Tests

Added src/tests/unit/components/MoveMailboxModal.vue.spec.js covering: same-mailbox no-op (no renameMailbox, moving reset, close emitted), a real move with correct new name, and state reset after a failed move.

Validation

$ npx vitest --run src/tests/unit/components/MoveMailboxModal.vue.spec.js
 Test Files  1 passed (1)
      Tests  3 passed (3)

Genuine RED→GREEN: reverting src/components/MoveMailboxModal.vue to the buggy version makes the "same mailbox is a no-op" test fail (the old code calls renameMailbox when moving into itself); restoring the fix turns it green.

npx eslint on both changed files is clean. I ran the full vitest --run suite too — a handful of unrelated files (TranslationModal, MessageService, store/actions, filePicker, languageDetection) fail non-deterministically with jsdom timeouts on the same count on a clean main checkout without my change, so they are pre-existing and outside this diff.

Happy to adjust.

…tate

The self-move guard compared the base64-encoded mailbox id against the
numeric destMailboxId, so it never matched and a folder moved onto itself
issued a rename to its own name. The state cleanup also lived inside that
dead branch, so an early return would have left the dialog stuck.

Compare databaseId, return early on a match, and hoist the finally cleanup
so moving is always reset and the dialog closes.

Assisted-by: Claude Code:claude-opus-4-8
Signed-off-by: Vladimir Babin <vovababin@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Move-folder modal: self-move guard is dead code and leaves moving stuck

1 participant