Compare commits

...
Author SHA1 Message Date
sonarly-bot 7140da7d6a fix(front): don’t auto-sync parent on folder-only selection
https://sonarly.com/issue/38200?type=bug

Selecting a Microsoft subfolder under Sent also marks the Sent parent as synced, so import processes the full Sent folder instead of just the chosen subfolder.

Fix: I removed ancestor auto-selection when turning sync on in `computeFolderIdsForSyncToggle`.
Previously, sync-on returned `childIds + parentIds`, which caused selecting a nested Microsoft folder (e.g. under Sent) to also mark its parent as synced. That expanded backend import scope to the whole parent folder.

Now, sync-on returns only the selected folder and its descendants (`childIds`), while keeping existing unsync cascade behavior unchanged.

I also updated the colocated unit test file to reflect the intended behavior:
- nested folder sync should not include ancestors
- child sync should not include parent
- deep nested sync should not bubble up to ancestors
- syncing middle node should include descendants, not ancestors

This directly prevents Sent parent from being auto-synced when a user selects only a Sent subfolder.

Authored by Sonarly by autonomous analysis (run 43537).
2026-05-17 20:24:53 +00:00
2 changed files with 10 additions and 17 deletions
@@ -39,7 +39,7 @@ describe('computeFolderIdsForSyncToggle', () => {
expect(result).toEqual(['inbox']);
});
it('should include ancestors when syncing a nested folder', () => {
it('should not include ancestors when syncing a nested folder', () => {
const work = createFolder({
id: 'work',
name: 'Work',
@@ -57,9 +57,7 @@ describe('computeFolderIdsForSyncToggle', () => {
isSynced: true,
});
expect(result).toContain('nested');
expect(result).toContain('work');
expect(result).toHaveLength(2);
expect(result).toEqual(['nested']);
});
it('should NOT include siblings when syncing a child folder', () => {
@@ -97,13 +95,13 @@ describe('computeFolderIdsForSyncToggle', () => {
});
expect(result).toContain('child-a');
expect(result).toContain('parent');
expect(result).not.toContain('parent');
expect(result).not.toContain('child-b');
expect(result).not.toContain('child-c');
expect(result).toHaveLength(2);
expect(result).toHaveLength(1);
});
it('should include all ancestors up to root', () => {
it('should not include ancestors up to root', () => {
const work = createFolder({
id: 'work',
name: 'Work',
@@ -127,10 +125,7 @@ describe('computeFolderIdsForSyncToggle', () => {
isSynced: true,
});
expect(result).toContain('deep');
expect(result).toContain('nested');
expect(result).toContain('work');
expect(result).toHaveLength(3);
expect(result).toEqual(['deep']);
});
it('should include descendants when syncing a parent folder', () => {
@@ -163,7 +158,7 @@ describe('computeFolderIdsForSyncToggle', () => {
expect(result).toHaveLength(3);
});
it('should include both ancestors and descendants', () => {
it('should include descendants but not ancestors', () => {
const root = createFolder({
id: 'root',
name: 'Root',
@@ -187,10 +182,10 @@ describe('computeFolderIdsForSyncToggle', () => {
isSynced: true,
});
expect(result).toContain('root');
expect(result).not.toContain('root');
expect(result).toContain('middle');
expect(result).toContain('leaf');
expect(result).toHaveLength(3);
expect(result).toHaveLength(2);
});
});
@@ -54,9 +54,7 @@ export const computeFolderIdsForSyncToggle = ({
const childIds = collectChildren(folderId);
if (isSynced) {
const parentIds = collectParents(folderId).map((folder) => folder.id);
return [...new Set([...childIds, ...parentIds])];
return [...new Set(childIds)];
}
const idsToUnsync = new Set(childIds);