diff --git a/src/vs/platform/userDataSync/common/extensionsMerge.ts b/src/vs/platform/userDataSync/common/extensionsMerge.ts index 5d02314b264a6e97277505681b200badf4992940..bb02ff61d843d2985ff00556a8bfbf01149f6233 100644 --- a/src/vs/platform/userDataSync/common/extensionsMerge.ts +++ b/src/vs/platform/userDataSync/common/extensionsMerge.ts @@ -29,6 +29,12 @@ export function merge(localExtensions: ISyncExtension[], remoteExtensions: ISync }; } + // massage incoming extension - add disabled property + const massageIncomingExtension = (extension: ISyncExtension): ISyncExtension => ({ ...extension, ...{ disabled: !!extension.disabled } }); + localExtensions = localExtensions.map(massageIncomingExtension); + remoteExtensions = remoteExtensions.map(massageIncomingExtension); + lastSyncExtensions = lastSyncExtensions ? lastSyncExtensions.map(massageIncomingExtension) : null; + const uuids: Map = new Map(); const addUUID = (identifier: IExtensionIdentifier) => { if (identifier.uuid) { uuids.set(identifier.id.toLowerCase(), identifier.uuid); } }; localExtensions.forEach(({ identifier }) => addUUID(identifier)); @@ -37,10 +43,12 @@ export function merge(localExtensions: ISyncExtension[], remoteExtensions: ISync lastSyncExtensions.forEach(({ identifier }) => addUUID(identifier)); } - const addExtensionToMap = (map: Map, extension: ISyncExtension) => { + const getKey = (extension: ISyncExtension): string => { const uuid = extension.identifier.uuid || uuids.get(extension.identifier.id.toLowerCase()); - const key = uuid ? `uuid:${uuid}` : `id:${extension.identifier.id.toLowerCase()}`; - map.set(key, extension); + return uuid ? `uuid:${uuid}` : `id:${extension.identifier.id.toLowerCase()}`; + }; + const addExtensionToMap = (map: Map, extension: ISyncExtension) => { + map.set(getKey(extension), extension); return map; }; const localExtensionsMap = localExtensions.reduce(addExtensionToMap, new Map()); @@ -62,14 +70,17 @@ export function merge(localExtensions: ISyncExtension[], remoteExtensions: ISync const baseToLocal = compare(lastSyncExtensionsMap, localExtensionsMap, ignoredExtensionsSet); const baseToRemote = compare(lastSyncExtensionsMap, remoteExtensionsMap, ignoredExtensionsSet); - const massageSyncExtension = (extension: ISyncExtension, key: string): ISyncExtension => { + // massage outgoing extension - remove disabled property + const massageOutgoingExtension = (extension: ISyncExtension, key: string): ISyncExtension => { const massagedExtension: ISyncExtension = { identifier: { id: extension.identifier.id, uuid: startsWith(key, 'uuid:') ? key.substring('uuid:'.length) : undefined }, - enabled: extension.enabled, }; + if (extension.disabled) { + massagedExtension.disabled = true; + } if (extension.version) { massagedExtension.version = extension.version; } @@ -90,25 +101,25 @@ export function merge(localExtensions: ISyncExtension[], remoteExtensions: ISync if (baseToLocal.added.has(key)) { // Is different from local to remote if (localToRemote.updated.has(key)) { - updated.push(massageSyncExtension(remoteExtensionsMap.get(key)!, key)); + updated.push(massageOutgoingExtension(remoteExtensionsMap.get(key)!, key)); } } else { // Add to local - added.push(massageSyncExtension(remoteExtensionsMap.get(key)!, key)); + added.push(massageOutgoingExtension(remoteExtensionsMap.get(key)!, key)); } } // Remotely updated extensions for (const key of values(baseToRemote.updated)) { // Update in local always - updated.push(massageSyncExtension(remoteExtensionsMap.get(key)!, key)); + updated.push(massageOutgoingExtension(remoteExtensionsMap.get(key)!, key)); } // Locally added extensions for (const key of values(baseToLocal.added)) { // Not there in remote if (!baseToRemote.added.has(key)) { - newRemoteExtensionsMap.set(key, massageSyncExtension(localExtensionsMap.get(key)!, key)); + newRemoteExtensionsMap.set(key, localExtensionsMap.get(key)!); } } @@ -121,7 +132,7 @@ export function merge(localExtensions: ISyncExtension[], remoteExtensions: ISync // If not updated in remote if (!baseToRemote.updated.has(key)) { - newRemoteExtensionsMap.set(key, massageSyncExtension(localExtensionsMap.get(key)!, key)); + newRemoteExtensionsMap.set(key, localExtensionsMap.get(key)!); } } @@ -133,9 +144,13 @@ export function merge(localExtensions: ISyncExtension[], remoteExtensions: ISync } } + const remote: ISyncExtension[] = []; const remoteChanges = compare(remoteExtensionsMap, newRemoteExtensionsMap, new Set()); - const remote = remoteChanges.added.size > 0 || remoteChanges.updated.size > 0 || remoteChanges.removed.size > 0 ? values(newRemoteExtensionsMap) : null; - return { added, removed, updated, remote }; + if (remoteChanges.added.size > 0 || remoteChanges.updated.size > 0 || remoteChanges.removed.size > 0) { + newRemoteExtensionsMap.forEach((value, key) => remote.push(massageOutgoingExtension(value, key))); + } + + return { added, removed, updated, remote: remote.length ? remote : null }; } function compare(from: Map | null, to: Map, ignoredExtensions: Set): { added: Set, removed: Set, updated: Set } { @@ -152,7 +167,7 @@ function compare(from: Map | null, to: Map { - const remoteExtensions: ISyncExtension[] = remoteUserData.syncData ? JSON.parse(remoteUserData.syncData.content) : null; - const lastSyncExtensions: ISyncExtension[] | null = lastSyncUserData ? JSON.parse(lastSyncUserData.syncData!.content) : null; + const remoteExtensions: ISyncExtension[] | null = remoteUserData.syncData ? this.parseExtensions(remoteUserData.syncData) : null; + const lastSyncExtensions: ISyncExtension[] | null = lastSyncUserData ? this.parseExtensions(lastSyncUserData.syncData!) : null; const skippedExtensions: ISyncExtension[] = lastSyncUserData ? lastSyncUserData.skippedExtensions || [] : []; const localExtensions = await this.getLocalExtensions(); @@ -236,14 +236,14 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse // Builtin Extension: Sync only enablement state if (installedExtension && installedExtension.type === ExtensionType.System) { - if (e.enabled) { - this.logService.trace('Extensions: Enabling extension...', e.identifier.id); - await this.extensionEnablementService.enableExtension(e.identifier); - this.logService.info('Extensions: Enabled extension', e.identifier.id); - } else { + if (e.disabled) { this.logService.trace('Extensions: Disabling extension...', e.identifier.id); await this.extensionEnablementService.disableExtension(e.identifier); this.logService.info('Extensions: Disabled extension', e.identifier.id); + } else { + this.logService.trace('Extensions: Enabling extension...', e.identifier.id); + await this.extensionEnablementService.enableExtension(e.identifier); + this.logService.info('Extensions: Enabled extension', e.identifier.id); } removeFromSkipped.push(e.identifier); return; @@ -252,14 +252,14 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse const extension = await this.extensionGalleryService.getCompatibleExtension(e.identifier, e.version); if (extension) { try { - if (e.enabled) { - this.logService.trace('Extensions: Enabling extension...', e.identifier.id, extension.version); - await this.extensionEnablementService.enableExtension(extension.identifier); - this.logService.info('Extensions: Enabled extension', e.identifier.id, extension.version); - } else { + if (e.disabled) { this.logService.trace('Extensions: Disabling extension...', e.identifier.id, extension.version); await this.extensionEnablementService.disableExtension(extension.identifier); this.logService.info('Extensions: Disabled extension', e.identifier.id, extension.version); + } else { + this.logService.trace('Extensions: Enabling extension...', e.identifier.id, extension.version); + await this.extensionEnablementService.enableExtension(extension.identifier); + this.logService.info('Extensions: Enabled extension', e.identifier.id, extension.version); } // Install only if the extension does not exist if (!installedExtension || installedExtension.manifest.version !== extension.version) { @@ -293,11 +293,33 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse return newSkippedExtensions; } + private parseExtensions(syncData: ISyncData): ISyncExtension[] { + let extensions: ISyncExtension[] = JSON.parse(syncData.content); + if (syncData.version !== this.version) { + extensions = extensions.map(e => { + // #region Migration from v1 (enabled -> disabled) + if (!(e).enabled) { + e.disabled = true; + } + delete (e).enabled; + // #endregion + return e; + }); + } + return extensions; + } + private async getLocalExtensions(): Promise { const installedExtensions = await this.extensionManagementService.getInstalled(); - const disabledExtensions = await this.extensionEnablementService.getDisabledExtensions(); + const disabledExtensions = this.extensionEnablementService.getDisabledExtensions(); return installedExtensions - .map(({ identifier }) => ({ identifier, enabled: !disabledExtensions.some(disabledExtension => areSameExtensions(disabledExtension, identifier)) })); + .map(({ identifier }) => { + const syncExntesion: ISyncExtension = { identifier }; + if (disabledExtensions.some(disabledExtension => areSameExtensions(disabledExtension, identifier))) { + syncExntesion.disabled = true; + } + return syncExntesion; + }); } } diff --git a/src/vs/platform/userDataSync/test/common/extensionsMerge.test.ts b/src/vs/platform/userDataSync/test/common/extensionsMerge.test.ts index b98154aeb5e30972ca1cf9d0fb1853f220ff903e..3bd7057806f13f5efbccee26c91d4a6e364e2cc6 100644 --- a/src/vs/platform/userDataSync/test/common/extensionsMerge.test.ts +++ b/src/vs/platform/userDataSync/test/common/extensionsMerge.test.ts @@ -11,9 +11,9 @@ suite('ExtensionsMerge - No Conflicts', () => { test('merge returns local extension if remote does not exist', async () => { const localExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'c', uuid: 'c' } }, ]; const actual = merge(localExtensions, null, null, [], []); @@ -26,13 +26,13 @@ suite('ExtensionsMerge - No Conflicts', () => { test('merge returns local extension if remote does not exist with ignored extensions', async () => { const localExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'c', uuid: 'c' } }, ]; const expected: ISyncExtension[] = [ - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'c', uuid: 'c' } }, ]; const actual = merge(localExtensions, null, null, [], ['a']); @@ -45,13 +45,13 @@ suite('ExtensionsMerge - No Conflicts', () => { test('merge returns local extension if remote does not exist with ignored extensions (ignore case)', async () => { const localExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'c', uuid: 'c' } }, ]; const expected: ISyncExtension[] = [ - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'c', uuid: 'c' } }, ]; const actual = merge(localExtensions, null, null, [], ['A']); @@ -64,17 +64,17 @@ suite('ExtensionsMerge - No Conflicts', () => { test('merge returns local extension if remote does not exist with skipped extensions', async () => { const localExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'c', uuid: 'c' } }, ]; const skippedExtension: ISyncExtension[] = [ - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, + { identifier: { id: 'b', uuid: 'b' } }, ]; const expected: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'c', uuid: 'c' } }, ]; const actual = merge(localExtensions, null, null, skippedExtension, []); @@ -87,16 +87,16 @@ suite('ExtensionsMerge - No Conflicts', () => { test('merge returns local extension if remote does not exist with skipped and ignored extensions', async () => { const localExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'c', uuid: 'c' } }, ]; const skippedExtension: ISyncExtension[] = [ - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, + { identifier: { id: 'b', uuid: 'b' } }, ]; const expected: ISyncExtension[] = [ - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'c', uuid: 'c' } }, ]; const actual = merge(localExtensions, null, null, skippedExtension, ['a']); @@ -109,23 +109,23 @@ suite('ExtensionsMerge - No Conflicts', () => { test('merge local and remote extensions when there is no base', async () => { const localExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'd', uuid: 'd' } }, ]; const remoteExtensions: ISyncExtension[] = [ - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'c', uuid: 'c' } }, ]; const expected: ISyncExtension[] = [ - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'c', uuid: 'c' } }, + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'd', uuid: 'd' } }, ]; const actual = merge(localExtensions, remoteExtensions, null, [], []); - assert.deepEqual(actual.added, [{ identifier: { id: 'b', uuid: 'b' }, enabled: true }, { identifier: { id: 'c', uuid: 'c' }, enabled: true }]); + assert.deepEqual(actual.added, [{ identifier: { id: 'b', uuid: 'b' } }, { identifier: { id: 'c', uuid: 'c' } }]); assert.deepEqual(actual.removed, []); assert.deepEqual(actual.updated, []); assert.deepEqual(actual.remote, expected); @@ -133,22 +133,22 @@ suite('ExtensionsMerge - No Conflicts', () => { test('merge local and remote extensions when there is no base and with ignored extensions', async () => { const localExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'd', uuid: 'd' } }, ]; const remoteExtensions: ISyncExtension[] = [ - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'c', uuid: 'c' } }, ]; const expected: ISyncExtension[] = [ - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'c', uuid: 'c' } }, + { identifier: { id: 'd', uuid: 'd' } }, ]; const actual = merge(localExtensions, remoteExtensions, null, [], ['a']); - assert.deepEqual(actual.added, [{ identifier: { id: 'b', uuid: 'b' }, enabled: true }, { identifier: { id: 'c', uuid: 'c' }, enabled: true }]); + assert.deepEqual(actual.added, [{ identifier: { id: 'b', uuid: 'b' } }, { identifier: { id: 'c', uuid: 'c' } }]); assert.deepEqual(actual.removed, []); assert.deepEqual(actual.updated, []); assert.deepEqual(actual.remote, expected); @@ -156,43 +156,66 @@ suite('ExtensionsMerge - No Conflicts', () => { test('merge local and remote extensions when remote is moved forwarded', async () => { const baseExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'd', uuid: 'd' } }, ]; const localExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'd', uuid: 'd' } }, ]; const remoteExtensions: ISyncExtension[] = [ - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'c', uuid: 'c' } }, ]; const actual = merge(localExtensions, remoteExtensions, baseExtensions, [], []); - assert.deepEqual(actual.added, [{ identifier: { id: 'b', uuid: 'b' }, enabled: true }, { identifier: { id: 'c', uuid: 'c' }, enabled: true }]); + assert.deepEqual(actual.added, [{ identifier: { id: 'b', uuid: 'b' } }, { identifier: { id: 'c', uuid: 'c' } }]); assert.deepEqual(actual.removed, [{ id: 'a', uuid: 'a' }, { id: 'd', uuid: 'd' }]); assert.deepEqual(actual.updated, []); assert.equal(actual.remote, null); }); + test('merge local and remote extensions when remote is moved forwarded with disabled extension', async () => { + const baseExtensions: ISyncExtension[] = [ + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'd', uuid: 'd' } }, + ]; + const localExtensions: ISyncExtension[] = [ + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'd', uuid: 'd' } }, + ]; + const remoteExtensions: ISyncExtension[] = [ + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'c', uuid: 'c' } }, + { identifier: { id: 'd', uuid: 'd' }, disabled: true }, + ]; + + const actual = merge(localExtensions, remoteExtensions, baseExtensions, [], []); + + assert.deepEqual(actual.added, [{ identifier: { id: 'b', uuid: 'b' } }, { identifier: { id: 'c', uuid: 'c' } }]); + assert.deepEqual(actual.removed, [{ id: 'a', uuid: 'a' }]); + assert.deepEqual(actual.updated, [{ identifier: { id: 'd', uuid: 'd' }, disabled: true }]); + assert.equal(actual.remote, null); + }); + test('merge local and remote extensions when remote moved forwarded with ignored extensions', async () => { const baseExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'd', uuid: 'd' } }, ]; const localExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'd', uuid: 'd' } }, ]; const remoteExtensions: ISyncExtension[] = [ - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'c', uuid: 'c' } }, ]; const actual = merge(localExtensions, remoteExtensions, baseExtensions, [], ['a']); - assert.deepEqual(actual.added, [{ identifier: { id: 'b', uuid: 'b' }, enabled: true }, { identifier: { id: 'c', uuid: 'c' }, enabled: true }]); + assert.deepEqual(actual.added, [{ identifier: { id: 'b', uuid: 'b' } }, { identifier: { id: 'c', uuid: 'c' } }]); assert.deepEqual(actual.removed, [{ id: 'd', uuid: 'd' }]); assert.deepEqual(actual.updated, []); assert.equal(actual.remote, null); @@ -200,23 +223,23 @@ suite('ExtensionsMerge - No Conflicts', () => { test('merge local and remote extensions when remote is moved forwarded with skipped extensions', async () => { const baseExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'd', uuid: 'd' } }, ]; const localExtensions: ISyncExtension[] = [ - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, + { identifier: { id: 'd', uuid: 'd' } }, ]; const skippedExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, ]; const remoteExtensions: ISyncExtension[] = [ - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'c', uuid: 'c' } }, ]; const actual = merge(localExtensions, remoteExtensions, baseExtensions, skippedExtensions, []); - assert.deepEqual(actual.added, [{ identifier: { id: 'b', uuid: 'b' }, enabled: true }, { identifier: { id: 'c', uuid: 'c' }, enabled: true }]); + assert.deepEqual(actual.added, [{ identifier: { id: 'b', uuid: 'b' } }, { identifier: { id: 'c', uuid: 'c' } }]); assert.deepEqual(actual.removed, [{ id: 'd', uuid: 'd' }]); assert.deepEqual(actual.updated, []); assert.equal(actual.remote, null); @@ -224,23 +247,23 @@ suite('ExtensionsMerge - No Conflicts', () => { test('merge local and remote extensions when remote is moved forwarded with skipped and ignored extensions', async () => { const baseExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'd', uuid: 'd' } }, ]; const localExtensions: ISyncExtension[] = [ - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, + { identifier: { id: 'd', uuid: 'd' } }, ]; const skippedExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, ]; const remoteExtensions: ISyncExtension[] = [ - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'c', uuid: 'c' } }, ]; const actual = merge(localExtensions, remoteExtensions, baseExtensions, skippedExtensions, ['b']); - assert.deepEqual(actual.added, [{ identifier: { id: 'c', uuid: 'c' }, enabled: true }]); + assert.deepEqual(actual.added, [{ identifier: { id: 'c', uuid: 'c' } }]); assert.deepEqual(actual.removed, [{ id: 'd', uuid: 'd' }]); assert.deepEqual(actual.updated, []); assert.equal(actual.remote, null); @@ -248,16 +271,39 @@ suite('ExtensionsMerge - No Conflicts', () => { test('merge local and remote extensions when local is moved forwarded', async () => { const baseExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'd', uuid: 'd' } }, + ]; + const localExtensions: ISyncExtension[] = [ + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'c', uuid: 'c' } }, + ]; + const remoteExtensions: ISyncExtension[] = [ + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'd', uuid: 'd' } }, + ]; + + const actual = merge(localExtensions, remoteExtensions, baseExtensions, [], []); + + assert.deepEqual(actual.added, []); + assert.deepEqual(actual.removed, []); + assert.deepEqual(actual.updated, []); + assert.deepEqual(actual.remote, localExtensions); + }); + + test('merge local and remote extensions when local is moved forwarded with disabled extensions', async () => { + const baseExtensions: ISyncExtension[] = [ + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'd', uuid: 'd' } }, ]; const localExtensions: ISyncExtension[] = [ - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' }, disabled: true }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'c', uuid: 'c' } }, ]; const remoteExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'd', uuid: 'd' } }, ]; const actual = merge(localExtensions, remoteExtensions, baseExtensions, [], []); @@ -270,16 +316,16 @@ suite('ExtensionsMerge - No Conflicts', () => { test('merge local and remote extensions when local is moved forwarded with ignored settings', async () => { const baseExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'd', uuid: 'd' } }, ]; const localExtensions: ISyncExtension[] = [ - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'c', uuid: 'c' } }, ]; const remoteExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'd', uuid: 'd' } }, ]; const actual = merge(localExtensions, remoteExtensions, baseExtensions, [], ['b']); @@ -288,30 +334,30 @@ suite('ExtensionsMerge - No Conflicts', () => { assert.deepEqual(actual.removed, []); assert.deepEqual(actual.updated, []); assert.deepEqual(actual.remote, [ - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'c', uuid: 'c' } }, ]); }); test('merge local and remote extensions when local is moved forwarded with skipped extensions', async () => { const baseExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'd', uuid: 'd' } }, ]; const skippedExtensions: ISyncExtension[] = [ - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, + { identifier: { id: 'd', uuid: 'd' } }, ]; const localExtensions: ISyncExtension[] = [ - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'c', uuid: 'c' } }, ]; const remoteExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'd', uuid: 'd' } }, ]; const expected: ISyncExtension[] = [ - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'd', uuid: 'd' } }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'c', uuid: 'c' } }, ]; const actual = merge(localExtensions, remoteExtensions, baseExtensions, skippedExtensions, []); @@ -324,23 +370,23 @@ suite('ExtensionsMerge - No Conflicts', () => { test('merge local and remote extensions when local is moved forwarded with skipped and ignored extensions', async () => { const baseExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'd', uuid: 'd' } }, ]; const skippedExtensions: ISyncExtension[] = [ - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, + { identifier: { id: 'd', uuid: 'd' } }, ]; const localExtensions: ISyncExtension[] = [ - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'c', uuid: 'c' } }, ]; const remoteExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'd', uuid: 'd' } }, ]; const expected: ISyncExtension[] = [ - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, + { identifier: { id: 'd', uuid: 'd' } }, + { identifier: { id: 'b', uuid: 'b' } }, ]; const actual = merge(localExtensions, remoteExtensions, baseExtensions, skippedExtensions, ['c']); @@ -353,28 +399,28 @@ suite('ExtensionsMerge - No Conflicts', () => { test('merge local and remote extensions when both moved forwarded', async () => { const baseExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'd', uuid: 'd' } }, ]; const localExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'c', uuid: 'c' } }, ]; const remoteExtensions: ISyncExtension[] = [ - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'e', uuid: 'e' }, enabled: true }, + { identifier: { id: 'd', uuid: 'd' } }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'e', uuid: 'e' } }, ]; const expected: ISyncExtension[] = [ - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'e', uuid: 'e' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'e', uuid: 'e' } }, + { identifier: { id: 'c', uuid: 'c' } }, ]; const actual = merge(localExtensions, remoteExtensions, baseExtensions, [], []); - assert.deepEqual(actual.added, [{ identifier: { id: 'e', uuid: 'e' }, enabled: true }]); + assert.deepEqual(actual.added, [{ identifier: { id: 'e', uuid: 'e' } }]); assert.deepEqual(actual.removed, [{ id: 'a', uuid: 'a' }]); assert.deepEqual(actual.updated, []); assert.deepEqual(actual.remote, expected); @@ -382,23 +428,23 @@ suite('ExtensionsMerge - No Conflicts', () => { test('merge local and remote extensions when both moved forwarded with ignored extensions', async () => { const baseExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'd', uuid: 'd' } }, ]; const localExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'c', uuid: 'c' } }, ]; const remoteExtensions: ISyncExtension[] = [ - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'e', uuid: 'e' }, enabled: true }, + { identifier: { id: 'd', uuid: 'd' } }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'e', uuid: 'e' } }, ]; const expected: ISyncExtension[] = [ - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'e', uuid: 'e' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'e', uuid: 'e' } }, + { identifier: { id: 'c', uuid: 'c' } }, ]; const actual = merge(localExtensions, remoteExtensions, baseExtensions, [], ['a', 'e']); @@ -411,30 +457,30 @@ suite('ExtensionsMerge - No Conflicts', () => { test('merge local and remote extensions when both moved forwarded with skipped extensions', async () => { const baseExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'd', uuid: 'd' } }, ]; const skippedExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, ]; const localExtensions: ISyncExtension[] = [ - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'c', uuid: 'c' } }, ]; const remoteExtensions: ISyncExtension[] = [ - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'e', uuid: 'e' }, enabled: true }, + { identifier: { id: 'd', uuid: 'd' } }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'e', uuid: 'e' } }, ]; const expected: ISyncExtension[] = [ - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'e', uuid: 'e' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'e', uuid: 'e' } }, + { identifier: { id: 'c', uuid: 'c' } }, ]; const actual = merge(localExtensions, remoteExtensions, baseExtensions, skippedExtensions, []); - assert.deepEqual(actual.added, [{ identifier: { id: 'e', uuid: 'e' }, enabled: true }]); + assert.deepEqual(actual.added, [{ identifier: { id: 'e', uuid: 'e' } }]); assert.deepEqual(actual.removed, []); assert.deepEqual(actual.updated, []); assert.deepEqual(actual.remote, expected); @@ -442,25 +488,25 @@ suite('ExtensionsMerge - No Conflicts', () => { test('merge local and remote extensions when both moved forwarded with skipped and ignoredextensions', async () => { const baseExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'd', uuid: 'd' } }, ]; const skippedExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, ]; const localExtensions: ISyncExtension[] = [ - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'c', uuid: 'c' } }, ]; const remoteExtensions: ISyncExtension[] = [ - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'e', uuid: 'e' }, enabled: true }, + { identifier: { id: 'd', uuid: 'd' } }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'e', uuid: 'e' } }, ]; const expected: ISyncExtension[] = [ - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'e', uuid: 'e' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'e', uuid: 'e' } }, + { identifier: { id: 'c', uuid: 'c' } }, ]; const actual = merge(localExtensions, remoteExtensions, baseExtensions, skippedExtensions, ['e']); @@ -473,24 +519,24 @@ suite('ExtensionsMerge - No Conflicts', () => { test('merge when remote extension has no uuid and different extension id case', async () => { const localExtensions: ISyncExtension[] = [ - { identifier: { id: 'a', uuid: 'a' }, enabled: true }, - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'a', uuid: 'a' } }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'c', uuid: 'c' } }, ]; const remoteExtensions: ISyncExtension[] = [ - { identifier: { id: 'A' }, enabled: true }, - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, + { identifier: { id: 'A' } }, + { identifier: { id: 'd', uuid: 'd' } }, ]; const expected: ISyncExtension[] = [ - { identifier: { id: 'A' }, enabled: true }, - { identifier: { id: 'd', uuid: 'd' }, enabled: true }, - { identifier: { id: 'b', uuid: 'b' }, enabled: true }, - { identifier: { id: 'c', uuid: 'c' }, enabled: true }, + { identifier: { id: 'A', uuid: 'a' } }, + { identifier: { id: 'd', uuid: 'd' } }, + { identifier: { id: 'b', uuid: 'b' } }, + { identifier: { id: 'c', uuid: 'c' } }, ]; const actual = merge(localExtensions, remoteExtensions, null, [], []); - assert.deepEqual(actual.added, [{ identifier: { id: 'd', uuid: 'd' }, enabled: true }]); + assert.deepEqual(actual.added, [{ identifier: { id: 'd', uuid: 'd' } }]); assert.deepEqual(actual.removed, []); assert.deepEqual(actual.updated, []); assert.deepEqual(actual.remote, expected);