diff --git a/src/app/actions/movemessage.action.spec.ts b/src/app/actions/movemessage.action.spec.ts
new file mode 100644
index 000000000..48974941f
--- /dev/null
+++ b/src/app/actions/movemessage.action.spec.ts
@@ -0,0 +1,78 @@
+// --------- BEGIN RUNBOX LICENSE ---------
+// Copyright (C) 2016-2026 Runbox Solutions AS (runbox.com).
+//
+// This file is part of Runbox 7.
+//
+// Runbox 7 is free software: You can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the
+// Free Software Foundation, either version 3 of the License, or (at your
+// option) any later version.
+//
+// Runbox 7 is distributed in the hope that it will be useful, but
+// WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Runbox 7. If not, see .
+// ---------- END RUNBOX LICENSE ----------
+
+import { of } from 'rxjs';
+import { MatLegacyDialogRef as MatDialogRef } from '@angular/material/legacy-dialog';
+
+import { FolderListEntry } from '../common/folderlistentry';
+import { RunboxWebmailAPI } from '../rmmapi/rbwebmail';
+import { MoveMessageDialogComponent } from './movemessage.action';
+
+describe('MoveMessageDialogComponent', () => {
+ const folders = [
+ new FolderListEntry(1, 0, 10, 'inbox', 'Inbox', 'Inbox', 0),
+ new FolderListEntry(2, 0, 5, 'user', 'Projects', 'Archive/Projects', 1),
+ new FolderListEntry(3, 0, 2, 'user', 'Invoices', 'Archive/Invoices', 1),
+ new FolderListEntry(4, 0, 4, 'sent', 'Sent', 'Sent', 0),
+ new FolderListEntry(5, 0, 1, 'drafts', 'Drafts', 'Drafts', 0),
+ new FolderListEntry(6, 0, 1, 'templates', 'Templates', 'Templates', 0),
+ ];
+
+ let dialogRef: MatDialogRef;
+ let component: MoveMessageDialogComponent;
+
+ beforeEach(() => {
+ dialogRef = {
+ close: jasmine.createSpy('close'),
+ } as unknown as MatDialogRef;
+ const rmmapi = {
+ getFolderList: () => of(folders),
+ } as unknown as RunboxWebmailAPI;
+ component = new MoveMessageDialogComponent(dialogRef, rmmapi);
+ });
+
+ it('should exclude folders that cannot be used as move targets', () => {
+ component.ngOnInit();
+
+ expect(component.folderListEntries.map(folder => folder.folderName))
+ .toEqual(['Inbox', 'Projects', 'Invoices']);
+ expect(component.filteredFolderListEntries.map(folder => folder.folderName))
+ .toEqual(['Inbox', 'Projects', 'Invoices']);
+ });
+
+ it('should filter folders by name or path', () => {
+ component.ngOnInit();
+
+ component.folderFilter = 'archive';
+ component.updateFolderFilter();
+ expect(component.filteredFolderListEntries.map(folder => folder.folderName))
+ .toEqual(['Projects', 'Invoices']);
+
+ component.folderFilter = 'invoice';
+ component.updateFolderFilter();
+ expect(component.filteredFolderListEntries.map(folder => folder.folderName))
+ .toEqual(['Invoices']);
+ });
+
+ it('should close with the selected folder id', () => {
+ component.moveMessages(3);
+
+ expect(dialogRef.close).toHaveBeenCalledWith(3);
+ });
+});
diff --git a/src/app/actions/movemessage.action.ts b/src/app/actions/movemessage.action.ts
index d6ba19289..6e8a3e0ab 100644
--- a/src/app/actions/movemessage.action.ts
+++ b/src/app/actions/movemessage.action.ts
@@ -25,9 +25,19 @@ import { RunboxWebmailAPI } from '../rmmapi/rbwebmail';
@Component({
template: `
-
-
-
+
+ Search folders
+
+
+
+
+
@@ -39,12 +49,31 @@ import { RunboxWebmailAPI } from '../rmmapi/rbwebmail';