From 85bfe77e80e69d8f80f26af0bcc418b45b5b44ac Mon Sep 17 00:00:00 2001 From: MichalKinas Date: Fri, 27 Oct 2023 08:16:48 +0200 Subject: [PATCH 1/9] Sonarcloud issues fixes --- docs/index.html | 2 +- docs/ja/index.html | 2 +- .../suites/actions/copy-move/copy.test.ts | 24 +++++++++---------- .../suites/list-views/file-libraries.test.ts | 6 +++-- .../lib/services/node-actions.service.spec.ts | 2 +- .../src/api/nodes-api.ts | 11 ++++----- .../src/utilities/admin-actions.ts | 18 +++++--------- .../apis/shared-links/shared-links-api.ts | 24 +++++++++---------- .../src/utilities/user-actions.ts | 20 +++++++--------- 9 files changed, 50 insertions(+), 59 deletions(-) diff --git a/docs/index.html b/docs/index.html index 6a444ef8d6..fcef58f611 100644 --- a/docs/index.html +++ b/docs/index.html @@ -1,5 +1,5 @@ - + diff --git a/docs/ja/index.html b/docs/ja/index.html index 1f6d1a6f18..dcddf66f0f 100644 --- a/docs/ja/index.html +++ b/docs/ja/index.html @@ -1,5 +1,5 @@ - + diff --git a/e2e/protractor/suites/actions/copy-move/copy.test.ts b/e2e/protractor/suites/actions/copy-move/copy.test.ts index 7ea7f7a2c2..d162114442 100755 --- a/e2e/protractor/suites/actions/copy-move/copy.test.ts +++ b/e2e/protractor/suites/actions/copy-move/copy.test.ts @@ -248,7 +248,7 @@ describe('Copy content', () => { async function copyFile(fileName: string, location: string = '', destination: string, doBefore?: () => void) { if (doBefore) { - await doBefore(); + doBefore(); } await dataTable.selectItem(fileName, location); await toolbar.clickMoreActionsCopy(); @@ -269,7 +269,7 @@ describe('Copy content', () => { async function copyFolderWithContent(folderName: string, location: string = '', destination: string, doBefore?: () => void) { if (doBefore) { - await doBefore(); + doBefore(); } await dataTable.selectItem(folderName, location); await toolbar.clickMoreActionsCopy(); @@ -294,7 +294,7 @@ describe('Copy content', () => { async function copyMultipleItems(items: string[], location: string = '', destination: string, doBefore?: () => void) { if (doBefore) { - await doBefore(); + doBefore(); } await dataTable.selectMultipleItems(items, location); await toolbar.clickMoreActionsCopy(); @@ -317,7 +317,7 @@ describe('Copy content', () => { async function copyFileWithNameThatAlreadyExists(fileName: string, location: string = '', destination: string, doBefore?: () => void) { if (doBefore) { - await doBefore(); + doBefore(); } await dataTable.selectItem(fileName, location); await toolbar.clickMoreActionsCopy(); @@ -338,7 +338,7 @@ describe('Copy content', () => { async function copyFolderWithNameThatAlreadyExists(folderName: string, location: string = '', destination: string, doBefore?: () => void) { if (doBefore) { - await doBefore(); + doBefore(); } await dataTable.selectItem(folderName, location); await toolbar.clickMoreActionsCopy(); @@ -362,7 +362,7 @@ describe('Copy content', () => { async function copyItemsIntoLibrary(items: string[], location: string = '', destination: string, doBefore?: () => void) { if (doBefore) { - await doBefore(); + doBefore(); } const noOfItems = items.length; await dataTable.selectMultipleItems(items, location); @@ -393,7 +393,7 @@ describe('Copy content', () => { async function copyLockedFile(fileName: string, location: string = '', destination: string, doBefore?: () => void) { if (doBefore) { - await doBefore(); + doBefore(); } await dataTable.selectItem(fileName, location); @@ -417,7 +417,7 @@ describe('Copy content', () => { async function copyFolderThatContainsLockedFile(folderName: string, location: string = '', destination: string, doBefore?: () => void) { if (doBefore) { - await doBefore(); + doBefore(); } await dataTable.selectItem(folderName, location); @@ -451,7 +451,7 @@ describe('Copy content', () => { async function undoCopyFile(fileName: string, location: string = '', destination: string, doBefore?: () => void) { if (doBefore) { - await doBefore(); + doBefore(); } await dataTable.selectItem(fileName, location); await toolbar.clickMoreActionsCopy(); @@ -475,7 +475,7 @@ describe('Copy content', () => { async function undoCopyFolder(folderName: string, location: string = '', destination: string, doBefore?: () => void) { if (doBefore) { - await doBefore(); + doBefore(); } await dataTable.selectItem(folderName, location); await toolbar.clickMoreActionsCopy(); @@ -497,7 +497,7 @@ describe('Copy content', () => { expect(await dataTable.isEmpty()).toBe(true, 'Trash is not empty'); } - async function undoCopyFileWithExistingName(fileName: string, location: string = '', destination: string, doBefore?: () => void) { + async function undoCopyFileWithExistingName(fileName: string, location: string = '', destination: string, doBefore?: () => Promise) { if (doBefore) { await doBefore(); } @@ -527,7 +527,7 @@ describe('Copy content', () => { async function undoCopyFolderWithExistingName(folderName: string, location: string = '', destination: string, doBefore?: () => void) { if (doBefore) { - await doBefore(); + doBefore(); } await dataTable.selectItem(folderName, location); diff --git a/e2e/protractor/suites/list-views/file-libraries.test.ts b/e2e/protractor/suites/list-views/file-libraries.test.ts index efbeed8183..896bd6f916 100755 --- a/e2e/protractor/suites/list-views/file-libraries.test.ts +++ b/e2e/protractor/suites/list-views/file-libraries.test.ts @@ -56,6 +56,8 @@ describe('File Libraries', () => { const { dataTable } = page; const adminApiActions = new AdminActions(); + const sortAlphabetically = (a: string, b: string) => a.localeCompare(b); + beforeAll(async () => { try { await adminApiActions.createUser({ username }); @@ -146,7 +148,7 @@ describe('File Libraries', () => { it('[C217098] Site ID is displayed when two sites have the same name', async () => { const expectedSites = [`${siteName} (${siteId1})`, `${siteName} (${siteId2})`]; const actualSites = await dataTable.getCellsContainingName(siteName); - expect(actualSites.sort()).toEqual(expectedSites.sort()); + expect(actualSites.sort(sortAlphabetically)).toEqual(expectedSites.sort(sortAlphabetically)); }); it('[C217096] Tooltip for sites without description', async () => { @@ -211,7 +213,7 @@ describe('File Libraries', () => { it('[C289896] Site ID is displayed when two sites have the same name', async () => { const expectedSites = [`${siteName} (${siteId1})`, `${siteName} (${siteId2})`]; const actualSites = await dataTable.getCellsContainingName(siteName); - expect(actualSites.sort()).toEqual(expectedSites.sort()); + expect(actualSites.sort(sortAlphabetically)).toEqual(expectedSites.sort(sortAlphabetically)); }); it('[C289894] Tooltip for sites without description', async () => { diff --git a/projects/aca-content/src/lib/services/node-actions.service.spec.ts b/projects/aca-content/src/lib/services/node-actions.service.spec.ts index f825c894c2..255801bc8e 100644 --- a/projects/aca-content/src/lib/services/node-actions.service.spec.ts +++ b/projects/aca-content/src/lib/services/node-actions.service.spec.ts @@ -89,7 +89,7 @@ describe('NodeActionsService', () => { reject(permissionError); } else { const node = familyNodes.filter((familyNode) => familyNode.parentNodeId === parentId); - resolve({ list: { entries: node[0].nodeChildren } } || emptyChildrenList); + resolve(node.length > 0 ? { list: { entries: node[0].nodeChildren } } : emptyChildrenList); } }) }; diff --git a/projects/aca-playwright-shared/src/api/nodes-api.ts b/projects/aca-playwright-shared/src/api/nodes-api.ts index f242c61ad9..8cb7d3837f 100755 --- a/projects/aca-playwright-shared/src/api/nodes-api.ts +++ b/projects/aca-playwright-shared/src/api/nodes-api.ts @@ -215,12 +215,11 @@ export class NodesApi { } private async getDataDictionaryId(): Promise { - try { - return this.getNodeIdFromParent('Data Dictionary', '-root-'); - } catch (error) { - logger.error('Admin Actions - getDataDictionaryId failed : ', error); - return ''; - } + return this.getNodeIdFromParent('Data Dictionary', '-root-') + .catch((error) => { + logger.error('Admin Actions - getDataDictionaryId failed : ', error); + return ''; + }); } async setGranularPermission(nodeId: string, inheritPermissions: boolean = false, username: string, role: string): Promise { diff --git a/projects/aca-testing-shared/src/utilities/admin-actions.ts b/projects/aca-testing-shared/src/utilities/admin-actions.ts index 09c38d0c9d..8ce6a74801 100755 --- a/projects/aca-testing-shared/src/utilities/admin-actions.ts +++ b/projects/aca-testing-shared/src/utilities/admin-actions.ts @@ -42,12 +42,10 @@ export class AdminActions extends UserActions { } private async getDataDictionaryId(): Promise { - try { - return this.nodes.getNodeIdFromParent('Data Dictionary', '-root-'); - } catch (error) { + return this.nodes.getNodeIdFromParent('Data Dictionary', '-root-').catch((error) => { super.handleError('Admin Actions - getDataDictionaryId failed : ', error); return ''; - } + }); } async getNodeTemplatesFolderId(): Promise { @@ -106,19 +104,15 @@ export class AdminActions extends UserActions { } async createNodeTemplatesHierarchy(hierarchy: NodeContentTree): Promise { - try { - return this.nodes.createContent(hierarchy, `Data Dictionary/Node Templates`); - } catch (error) { + return this.nodes.createContent(hierarchy, `Data Dictionary/Node Templates`).catch((error) => { super.handleError('Admin Actions - createNodeTemplatesHierarchy failed : ', error); - } + }); } async createSpaceTemplatesHierarchy(hierarchy: NodeContentTree): Promise { - try { - return this.nodes.createContent(hierarchy, `Data Dictionary/Space Templates`); - } catch (error) { + return this.nodes.createContent(hierarchy, `Data Dictionary/Space Templates`).catch((error) => { super.handleError('Admin Actions - createSpaceTemplatesHierarchy failed : ', error); - } + }); } async removeUserAccessOnNodeTemplate(nodeName: string): Promise { diff --git a/projects/aca-testing-shared/src/utilities/repo-client/apis/shared-links/shared-links-api.ts b/projects/aca-testing-shared/src/utilities/repo-client/apis/shared-links/shared-links-api.ts index ac6f01a924..17190a9c6a 100755 --- a/projects/aca-testing-shared/src/utilities/repo-client/apis/shared-links/shared-links-api.ts +++ b/projects/aca-testing-shared/src/utilities/repo-client/apis/shared-links/shared-links-api.ts @@ -97,22 +97,20 @@ export class SharedLinksApi extends RepoApi { } async waitForFilesToBeShared(filesIds: string[]): Promise { - try { - const sharedFile = async () => { - const sharedFiles = (await this.getSharedLinks()).list.entries.map((link) => link.entry.nodeId); - const foundItems = filesIds.every((id) => sharedFiles.includes(id)); - if (foundItems) { - return Promise.resolve(foundItems); - } else { - return Promise.reject(foundItems); - } - }; + const sharedFile = async () => { + const sharedFiles = (await this.getSharedLinks()).list.entries.map((link) => link.entry.nodeId); + const foundItems = filesIds.every((id) => sharedFiles.includes(id)); + if (foundItems) { + return Promise.resolve(foundItems); + } else { + return Promise.reject(foundItems); + } + }; - return Utils.retryCall(sharedFile); - } catch (error) { + return Utils.retryCall(sharedFile).catch((error) => { Logger.error(`SharedLinksApi waitForFilesToBeShared : catch : ${error}`); Logger.error(`\tWait timeout reached waiting for files to be shared`); - } + }); } async waitForFilesToNotBeShared(filesIds: string[]): Promise { diff --git a/projects/aca-testing-shared/src/utilities/user-actions.ts b/projects/aca-testing-shared/src/utilities/user-actions.ts index acc68f8b6b..2fded960bb 100644 --- a/projects/aca-testing-shared/src/utilities/user-actions.ts +++ b/projects/aca-testing-shared/src/utilities/user-actions.ts @@ -142,20 +142,18 @@ export class UserActions { * @param expectedSize Size of the trashcan to wait for. */ async waitForTrashcanSize(expectedSize: number): Promise { - try { - return Utils.retryCall(async () => { - const totalItems = await this.getTrashcanSize(); + return Utils.retryCall(async () => { + const totalItems = await this.getTrashcanSize(); - if (totalItems !== expectedSize) { - return Promise.reject(totalItems); - } else { - return Promise.resolve(totalItems); - } - }); - } catch (error) { + if (totalItems !== expectedSize) { + return Promise.reject(totalItems); + } else { + return Promise.resolve(totalItems); + } + }).catch((error) => { this.handleError('User Actions - waitForTrashcanSize failed : ', error); return -1; - } + }); } async lockNodes(nodeIds: string[], lockType: string = 'ALLOW_OWNER_CHANGES') { From a228ab68eb77f08ad23218df736434aa1f5dd677 Mon Sep 17 00:00:00 2001 From: MichalKinas Date: Fri, 27 Oct 2023 08:27:09 +0200 Subject: [PATCH 2/9] Code smell fixes --- e2e/protractor/suites/list-views/file-libraries.test.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/e2e/protractor/suites/list-views/file-libraries.test.ts b/e2e/protractor/suites/list-views/file-libraries.test.ts index 896bd6f916..ea7e964c14 100755 --- a/e2e/protractor/suites/list-views/file-libraries.test.ts +++ b/e2e/protractor/suites/list-views/file-libraries.test.ts @@ -148,7 +148,9 @@ describe('File Libraries', () => { it('[C217098] Site ID is displayed when two sites have the same name', async () => { const expectedSites = [`${siteName} (${siteId1})`, `${siteName} (${siteId2})`]; const actualSites = await dataTable.getCellsContainingName(siteName); - expect(actualSites.sort(sortAlphabetically)).toEqual(expectedSites.sort(sortAlphabetically)); + actualSites.sort(sortAlphabetically); + expectedSites.sort(sortAlphabetically); + expect(actualSites).toEqual(expectedSites); }); it('[C217096] Tooltip for sites without description', async () => { @@ -213,7 +215,9 @@ describe('File Libraries', () => { it('[C289896] Site ID is displayed when two sites have the same name', async () => { const expectedSites = [`${siteName} (${siteId1})`, `${siteName} (${siteId2})`]; const actualSites = await dataTable.getCellsContainingName(siteName); - expect(actualSites.sort(sortAlphabetically)).toEqual(expectedSites.sort(sortAlphabetically)); + actualSites.sort(sortAlphabetically); + expectedSites.sort(sortAlphabetically); + expect(actualSites).toEqual(expectedSites); }); it('[C289894] Tooltip for sites without description', async () => { From 0e98703b24d01f49515f183445228e67ec9c6349 Mon Sep 17 00:00:00 2001 From: MichalKinas Date: Fri, 27 Oct 2023 10:10:01 +0200 Subject: [PATCH 3/9] Refactoring to remove new code duplications --- .../suites/actions/copy-move/copy.test.ts | 218 +++++------------- .../suites/list-views/file-libraries.test.ts | 13 +- 2 files changed, 66 insertions(+), 165 deletions(-) diff --git a/e2e/protractor/suites/actions/copy-move/copy.test.ts b/e2e/protractor/suites/actions/copy-move/copy.test.ts index d162114442..73b820d37e 100755 --- a/e2e/protractor/suites/actions/copy-move/copy.test.ts +++ b/e2e/protractor/suites/actions/copy-move/copy.test.ts @@ -246,21 +246,64 @@ describe('Copy content', () => { undoCopyFolderWithExistingName(folderExisting, '', destinationPF)); }); - async function copyFile(fileName: string, location: string = '', destination: string, doBefore?: () => void) { - if (doBefore) { - doBefore(); + async function baseCopy( + itemName: string | string[], + location: string, + destination: string, + undo: boolean = false, + expectedMsg: string = 'Copied 1 item' + ) { + if (itemName instanceof Array) { + await dataTable.selectMultipleItems(itemName, location); + } else { + await dataTable.selectItem(itemName, location); } - await dataTable.selectItem(fileName, location); await toolbar.clickMoreActionsCopy(); await copyDialog.selectLocation('Personal Files'); await copyDialog.selectDestination(destination); await BrowserActions.click(copyDialog.copyButton); const msg = await page.getSnackBarMessage(); - expect(msg).toContain('Copied 1 item'); + expect(msg).toContain(expectedMsg); const action = await page.getSnackBarAction(); expect(action).toContain('Undo'); + if (undo) { + await page.clickSnackBarAction(); + await page.clickPersonalFilesAndWait(); + } else { + await copyDialog.waitForDialogToClose(); + } + } - await copyDialog.waitForDialogToClose(); + async function baseCopyDoBefore( + itemName: string | string[], + location: string, + destination: string, + doBefore?: () => void, + undo?: boolean, + expectedMsg?: string + ) { + if (doBefore) { + doBefore(); + } + await baseCopy(itemName, location, destination, undo, expectedMsg); + } + + async function baseCopyDoBeforeAsync( + itemName: string | string[], + location: string, + destination: string, + doBefore?: () => Promise, + undo?: boolean, + expectedMsg?: string + ) { + if (doBefore) { + await doBefore(); + } + await baseCopy(itemName, location, destination, undo, expectedMsg); + } + + async function copyFile(fileName: string, location: string = '', destination: string, doBefore?: () => void) { + await baseCopyDoBefore(fileName, location, destination, doBefore); expect(await dataTable.isItemPresent(fileName)).toBe(true, `${fileName} not present in source folder`); await page.clickPersonalFilesAndWait(); await dataTable.doubleClickOnRowByName(destination); @@ -268,20 +311,7 @@ describe('Copy content', () => { } async function copyFolderWithContent(folderName: string, location: string = '', destination: string, doBefore?: () => void) { - if (doBefore) { - doBefore(); - } - await dataTable.selectItem(folderName, location); - await toolbar.clickMoreActionsCopy(); - await copyDialog.selectLocation('Personal Files'); - await copyDialog.selectDestination(destination); - await BrowserActions.click(copyDialog.copyButton); - const msg = await page.getSnackBarMessage(); - expect(msg).toContain('Copied 1 item'); - const action = await page.getSnackBarAction(); - expect(action).toContain('Undo'); - - await copyDialog.waitForDialogToClose(); + await baseCopyDoBefore(folderName, location, destination, doBefore); expect(await dataTable.isItemPresent(folderName)).toBe(true, `${folderName} not present in source folder`); await page.clickPersonalFilesAndWait(); await dataTable.doubleClickOnRowByName(destination); @@ -293,20 +323,7 @@ describe('Copy content', () => { } async function copyMultipleItems(items: string[], location: string = '', destination: string, doBefore?: () => void) { - if (doBefore) { - doBefore(); - } - await dataTable.selectMultipleItems(items, location); - await toolbar.clickMoreActionsCopy(); - await copyDialog.selectLocation('Personal Files'); - await copyDialog.selectDestination(destination); - await BrowserActions.click(copyDialog.copyButton); - const msg = await page.getSnackBarMessage(); - expect(msg).toContain('Copied 2 items'); - const action = await page.getSnackBarAction(); - expect(action).toContain('Undo'); - - await copyDialog.waitForDialogToClose(); + await baseCopyDoBefore(items, location, destination, doBefore, false, 'Copied 2 items'); expect(await dataTable.isItemPresent(items[0])).toBe(true, `${items[0]} not present in source folder`); expect(await dataTable.isItemPresent(items[1])).toBe(true, `${items[1]} not present in source folder`); await page.clickPersonalFilesAndWait(); @@ -316,20 +333,7 @@ describe('Copy content', () => { } async function copyFileWithNameThatAlreadyExists(fileName: string, location: string = '', destination: string, doBefore?: () => void) { - if (doBefore) { - doBefore(); - } - await dataTable.selectItem(fileName, location); - await toolbar.clickMoreActionsCopy(); - await copyDialog.selectLocation('Personal Files'); - await copyDialog.selectDestination(destination); - await BrowserActions.click(copyDialog.copyButton); - const msg = await page.getSnackBarMessage(); - expect(msg).toContain('Copied 1 item'); - const action = await page.getSnackBarAction(); - expect(action).toContain('Undo'); - - await copyDialog.waitForDialogToClose(); + await baseCopyDoBefore(fileName, location, destination, doBefore); expect(await dataTable.isItemPresent(fileName)).toBe(true, `${fileName}.txt not present in source folder`); await page.clickPersonalFilesAndWait(); await dataTable.doubleClickOnRowByName(destination); @@ -337,20 +341,7 @@ describe('Copy content', () => { } async function copyFolderWithNameThatAlreadyExists(folderName: string, location: string = '', destination: string, doBefore?: () => void) { - if (doBefore) { - doBefore(); - } - await dataTable.selectItem(folderName, location); - await toolbar.clickMoreActionsCopy(); - await copyDialog.selectLocation('Personal Files'); - await copyDialog.selectDestination(destination); - await BrowserActions.click(copyDialog.copyButton); - const msg = await page.getSnackBarMessage(); - expect(msg).toContain('Copied 1 item'); - const action = await page.getSnackBarAction(); - expect(action).toContain('Undo'); - - await copyDialog.waitForDialogToClose(); + await baseCopyDoBefore(folderName, location, destination, doBefore); expect(await dataTable.isItemPresent(folderName)).toBe(true, `${folderName} not present in source folder`); await page.clickPersonalFilesAndWait(); await dataTable.doubleClickOnRowByName(destination); @@ -392,21 +383,7 @@ describe('Copy content', () => { } async function copyLockedFile(fileName: string, location: string = '', destination: string, doBefore?: () => void) { - if (doBefore) { - doBefore(); - } - - await dataTable.selectItem(fileName, location); - await toolbar.clickMoreActionsCopy(); - await copyDialog.selectLocation('Personal Files'); - await copyDialog.selectDestination(destination); - await BrowserActions.click(copyDialog.copyButton); - const msg = await page.getSnackBarMessage(); - expect(msg).toContain('Copied 1 item'); - const action = await page.getSnackBarAction(); - expect(action).toContain('Undo'); - - await copyDialog.waitForDialogToClose(); + await baseCopyDoBefore(fileName, location, destination, doBefore); expect(await dataTable.isItemPresent(fileName)).toBe(true, `${fileName} not present in source folder`); expect(await apis.nodes.isFileLockedByName(fileName, locationId)).toBe(true, `${fileName} not locked in ${location}`); await page.clickPersonalFilesAndWait(); @@ -416,21 +393,7 @@ describe('Copy content', () => { } async function copyFolderThatContainsLockedFile(folderName: string, location: string = '', destination: string, doBefore?: () => void) { - if (doBefore) { - doBefore(); - } - - await dataTable.selectItem(folderName, location); - await toolbar.clickMoreActionsCopy(); - await copyDialog.selectLocation('Personal Files'); - await copyDialog.selectDestination(destination); - await BrowserActions.click(copyDialog.copyButton); - const msg = await page.getSnackBarMessage(); - expect(msg).toContain('Copied 1 item'); - const action = await page.getSnackBarAction(); - expect(action).toContain('Undo'); - - await copyDialog.waitForDialogToClose(); + await baseCopyDoBefore(folderName, location, destination, doBefore); expect(await dataTable.isItemPresent(folderName)).toBe(true, `${folderName} not present in source folder`); await page.clickPersonalFilesAndWait(); await dataTable.doubleClickOnRowByName(destination); @@ -450,22 +413,7 @@ describe('Copy content', () => { } async function undoCopyFile(fileName: string, location: string = '', destination: string, doBefore?: () => void) { - if (doBefore) { - doBefore(); - } - await dataTable.selectItem(fileName, location); - await toolbar.clickMoreActionsCopy(); - await copyDialog.selectLocation('Personal Files'); - await copyDialog.selectDestination(destination); - await BrowserActions.click(copyDialog.copyButton); - const msg = await page.getSnackBarMessage(); - expect(msg).toContain('Copied 1 item'); - const action = await page.getSnackBarAction(); - expect(action).toContain('Undo'); - - await page.clickSnackBarAction(); - - await page.clickPersonalFilesAndWait(); + await baseCopyDoBefore(fileName, location, destination, doBefore, true); await dataTable.doubleClickOnRowByName(destination); expect(await dataTable.isItemPresent(fileName)).toBe(false, `${fileName} present in ${destination} folder`); @@ -474,22 +422,7 @@ describe('Copy content', () => { } async function undoCopyFolder(folderName: string, location: string = '', destination: string, doBefore?: () => void) { - if (doBefore) { - doBefore(); - } - await dataTable.selectItem(folderName, location); - await toolbar.clickMoreActionsCopy(); - await copyDialog.selectLocation('Personal Files'); - await copyDialog.selectDestination(destination); - await BrowserActions.click(copyDialog.copyButton); - const msg = await page.getSnackBarMessage(); - expect(msg).toContain('Copied 1 item'); - const action = await page.getSnackBarAction(); - expect(action).toContain('Undo'); - - await page.clickSnackBarAction(); - - await page.clickPersonalFilesAndWait(); + await baseCopyDoBefore(folderName, location, destination, doBefore, true); await dataTable.doubleClickOnRowByName(destination); expect(await dataTable.isItemPresent(folderName)).toBe(false, `${folderName} present in ${destination} folder`); @@ -498,24 +431,7 @@ describe('Copy content', () => { } async function undoCopyFileWithExistingName(fileName: string, location: string = '', destination: string, doBefore?: () => Promise) { - if (doBefore) { - await doBefore(); - } - - await dataTable.selectItem(fileName, location); - await toolbar.clickMoreActionsCopy(); - await copyDialog.selectLocation('Personal Files'); - await copyDialog.dataTable.doubleClickOnRowByName(source); - await copyDialog.selectDestination(destination); - await BrowserActions.click(copyDialog.copyButton); - const msg = await page.getSnackBarMessage(); - expect(msg).toContain('Copied 1 item'); - const action = await page.getSnackBarAction(); - expect(action).toContain('Undo'); - - await page.clickSnackBarAction(); - - await page.clickPersonalFilesAndWait(); + await baseCopyDoBeforeAsync(fileName, location, destination, doBefore, true); await dataTable.doubleClickOnRowByName(source); await dataTable.doubleClickOnRowByName(folder2); expect(await dataTable.isItemPresent(fileInFolder2)).toBe(true, `${fileInFolder2} not present in ${destination} folder`); @@ -526,23 +442,7 @@ describe('Copy content', () => { } async function undoCopyFolderWithExistingName(folderName: string, location: string = '', destination: string, doBefore?: () => void) { - if (doBefore) { - doBefore(); - } - - await dataTable.selectItem(folderName, location); - await toolbar.clickMoreActionsCopy(); - await copyDialog.selectLocation('Personal Files'); - await copyDialog.dataTable.doubleClickOnRowByName(destination); - await BrowserActions.click(copyDialog.copyButton); - const msg = await page.getSnackBarMessage(); - expect(msg).toContain('Copied 1 item'); - const action = await page.getSnackBarAction(); - expect(action).toContain('Undo'); - - await page.clickSnackBarAction(); - - await page.clickPersonalFilesAndWait(); + await baseCopyDoBefore(folderName, location, destination, doBefore, true); await dataTable.doubleClickOnRowByName(destination); expect(await dataTable.isItemPresent(folderName)).toBe(true, `${folderName} not present in ${destination} folder`); await dataTable.doubleClickOnRowByName(folderName); diff --git a/e2e/protractor/suites/list-views/file-libraries.test.ts b/e2e/protractor/suites/list-views/file-libraries.test.ts index ea7e964c14..7a9bc6dffb 100755 --- a/e2e/protractor/suites/list-views/file-libraries.test.ts +++ b/e2e/protractor/suites/list-views/file-libraries.test.ts @@ -57,6 +57,11 @@ describe('File Libraries', () => { const adminApiActions = new AdminActions(); const sortAlphabetically = (a: string, b: string) => a.localeCompare(b); + const sortAndCompare = (actual: string[], expected: string[]) => { + actual.sort(sortAlphabetically); + expected.sort(sortAlphabetically); + expect(actual).toEqual(expected); + }; beforeAll(async () => { try { @@ -148,9 +153,7 @@ describe('File Libraries', () => { it('[C217098] Site ID is displayed when two sites have the same name', async () => { const expectedSites = [`${siteName} (${siteId1})`, `${siteName} (${siteId2})`]; const actualSites = await dataTable.getCellsContainingName(siteName); - actualSites.sort(sortAlphabetically); - expectedSites.sort(sortAlphabetically); - expect(actualSites).toEqual(expectedSites); + sortAndCompare(actualSites, expectedSites); }); it('[C217096] Tooltip for sites without description', async () => { @@ -215,9 +218,7 @@ describe('File Libraries', () => { it('[C289896] Site ID is displayed when two sites have the same name', async () => { const expectedSites = [`${siteName} (${siteId1})`, `${siteName} (${siteId2})`]; const actualSites = await dataTable.getCellsContainingName(siteName); - actualSites.sort(sortAlphabetically); - expectedSites.sort(sortAlphabetically); - expect(actualSites).toEqual(expectedSites); + sortAndCompare(actualSites, expectedSites); }); it('[C289894] Tooltip for sites without description', async () => { From 5b9ecafd1ad4572b120d783e070faccb5d5e0ee0 Mon Sep 17 00:00:00 2001 From: MichalKinas Date: Fri, 27 Oct 2023 13:45:30 +0200 Subject: [PATCH 4/9] Sonarcloud code smell fixes part I --- app/proxy.conf.js | 2 +- app/src/main.ts | 2 +- .../viewer/src/tests/viewer-protected.spec.ts | 2 +- .../suites/actions/copy-move/copy.test.ts | 56 +++++++++---------- .../suites/list-views/sort-list.test.ts | 8 +-- .../actions/rule-action.ui-component.ts | 8 +-- .../lib/components/preview.component.spec.ts | 2 +- .../src/lib/components/preview.component.ts | 24 +++----- .../location-link/location-link.component.ts | 8 ++- .../toggle-shared/toggle-shared.component.ts | 2 +- .../context-menu-item.component.ts | 2 +- .../context-menu-outside-event.directive.ts | 8 +-- .../context-menu/context-menu.service.ts | 5 -- .../favorite-libraries.component.ts | 2 +- .../favorites/favorites.component.ts | 4 +- .../lib/components/files/files.component.ts | 30 +++++----- .../library-metadata-form.component.ts | 4 +- .../libraries/libraries.component.ts | 2 +- .../recent-files/recent-files.component.ts | 6 +- .../search-input-control.component.spec.ts | 16 +++--- 20 files changed, 81 insertions(+), 112 deletions(-) diff --git a/app/proxy.conf.js b/app/proxy.conf.js index cd22e0f55a..0d90716bc5 100644 --- a/app/proxy.conf.js +++ b/app/proxy.conf.js @@ -18,7 +18,7 @@ module.exports = { // workaround for REPO-2260 onProxyRes: function (proxyRes) { const header = proxyRes.headers['www-authenticate']; - if (header && header.startsWith('Basic')) { + if (header?.startsWith('Basic')) { proxyRes.headers['www-authenticate'] = 'x' + header; } } diff --git a/app/src/main.ts b/app/src/main.ts index 0e42d77f5c..dcd2f5e328 100644 --- a/app/src/main.ts +++ b/app/src/main.ts @@ -32,4 +32,4 @@ if (environment.production) { enableProdMode(); } -void platformBrowserDynamic().bootstrapModule(AppModule); +platformBrowserDynamic().bootstrapModule(AppModule); diff --git a/e2e/playwright/viewer/src/tests/viewer-protected.spec.ts b/e2e/playwright/viewer/src/tests/viewer-protected.spec.ts index 3f613864a2..91fb4274b2 100644 --- a/e2e/playwright/viewer/src/tests/viewer-protected.spec.ts +++ b/e2e/playwright/viewer/src/tests/viewer-protected.spec.ts @@ -33,7 +33,7 @@ test.describe('viewer file', () => { let folderId: string; let fileDocxId: string; - test.beforeAll(async ({ fileAction, shareAction, favoritesPageAction: favoritesPageAction }) => { + test.beforeAll(async ({ fileAction, shareAction, favoritesPageAction }) => { await apiClientFactory.setUpAcaBackend('hruser'); const node = await apiClientFactory.nodes.createNode('-my-', { name: randomFolderName, nodeType: 'cm:folder', relativePath: '/' }); folderId = node.entry.id; diff --git a/e2e/protractor/suites/actions/copy-move/copy.test.ts b/e2e/protractor/suites/actions/copy-move/copy.test.ts index 73b820d37e..37ac716066 100755 --- a/e2e/protractor/suites/actions/copy-move/copy.test.ts +++ b/e2e/protractor/suites/actions/copy-move/copy.test.ts @@ -206,53 +206,47 @@ describe('Copy content', () => { await dataTable.doubleClickOnRowByName(source); }); - it('[C217135] Copy a file', async () => copyFile(file1, '', destinationPF)); + it('[C217135] Copy a file', async () => copyFile(file1, destinationPF)); - it('[C291888] Copy a folder with content', async () => copyFolderWithContent(folder1, '', destinationPF)); + it('[C291888] Copy a folder with content', async () => copyFolderWithContent(folder1, destinationPF)); - it('[C291889] Copy multiple items', async () => copyMultipleItems([file2, file3], '', destinationPF)); + it('[C291889] Copy multiple items', async () => copyMultipleItems([file2, file3], destinationPF)); it('[C217137] Copy a file with a name that already exists on the destination', async () => - copyFileWithNameThatAlreadyExists(existingFile, '', destinationPF)); + copyFileWithNameThatAlreadyExists(existingFile, destinationPF)); it('[C217138] Copy a folder with a name that already exists on the destination', async () => - copyFolderWithNameThatAlreadyExists(existingFolder, '', destinationPF)); + copyFolderWithNameThatAlreadyExists(existingFolder, destinationPF)); - it('[C280282] Copy items into a library', async () => copyItemsIntoLibrary([file1, folder1], '', folderSitePF)); + it('[C280282] Copy items into a library', async () => copyItemsIntoLibrary([file1, folder1], folderSitePF)); it('[C217139] Copy locked file', async () => - copyLockedFile(fileLocked1, '', destinationPF, () => { + copyLockedFile(fileLocked1, destinationPF, '', () => { locationId = sourceId; destinationId = destinationIdPF; })); it('[C217140] Copy folder that contains locked file', async () => - copyFolderThatContainsLockedFile(folderWithLockedFiles, '', destinationPF, () => { + copyFolderThatContainsLockedFile(folderWithLockedFiles, destinationPF, '', () => { locationId = folderWithLockedFilesId; destinationId = destinationIdPF; })); - it('[C217171] Undo copy of files', async () => undoCopyFile(file4, '', destinationPF)); + it('[C217171] Undo copy of files', async () => undoCopyFile(file4, destinationPF)); - it('[C217172] Undo copy of folders', async () => undoCopyFolder(folder2, '', destinationPF)); + it('[C217172] Undo copy of folders', async () => undoCopyFolder(folder2, destinationPF)); it('[C217173] Undo copy of a file when a file with same name already exists on the destination', async () => - undoCopyFileWithExistingName(fileInFolder, '', folder2, async () => { + undoCopyFileWithExistingName(fileInFolder, folder2, '', async () => { await dataTable.doubleClickOnRowByName(folder1); await dataTable.waitForHeader(); })); it('[C217174] Undo copy of a folder when a folder with same name already exists on the destination', async () => - undoCopyFolderWithExistingName(folderExisting, '', destinationPF)); + undoCopyFolderWithExistingName(folderExisting, destinationPF)); }); - async function baseCopy( - itemName: string | string[], - location: string, - destination: string, - undo: boolean = false, - expectedMsg: string = 'Copied 1 item' - ) { + async function baseCopy(itemName: string | string[], location: string, destination: string, undo = false, expectedMsg = 'Copied 1 item') { if (itemName instanceof Array) { await dataTable.selectMultipleItems(itemName, location); } else { @@ -302,7 +296,7 @@ describe('Copy content', () => { await baseCopy(itemName, location, destination, undo, expectedMsg); } - async function copyFile(fileName: string, location: string = '', destination: string, doBefore?: () => void) { + async function copyFile(fileName: string, destination: string, location = '', doBefore?: () => void) { await baseCopyDoBefore(fileName, location, destination, doBefore); expect(await dataTable.isItemPresent(fileName)).toBe(true, `${fileName} not present in source folder`); await page.clickPersonalFilesAndWait(); @@ -310,7 +304,7 @@ describe('Copy content', () => { expect(await dataTable.isItemPresent(fileName)).toBe(true, `${fileName} not present in ${destination} folder`); } - async function copyFolderWithContent(folderName: string, location: string = '', destination: string, doBefore?: () => void) { + async function copyFolderWithContent(folderName: string, destination: string, location = '', doBefore?: () => void) { await baseCopyDoBefore(folderName, location, destination, doBefore); expect(await dataTable.isItemPresent(folderName)).toBe(true, `${folderName} not present in source folder`); await page.clickPersonalFilesAndWait(); @@ -322,7 +316,7 @@ describe('Copy content', () => { expect(await dataTable.isItemPresent(fileInFolder)).toBe(true, `${fileInFolder} is not present in ${folderName} folder in ${destination}`); } - async function copyMultipleItems(items: string[], location: string = '', destination: string, doBefore?: () => void) { + async function copyMultipleItems(items: string[], destination: string, location = '', doBefore?: () => void) { await baseCopyDoBefore(items, location, destination, doBefore, false, 'Copied 2 items'); expect(await dataTable.isItemPresent(items[0])).toBe(true, `${items[0]} not present in source folder`); expect(await dataTable.isItemPresent(items[1])).toBe(true, `${items[1]} not present in source folder`); @@ -332,7 +326,7 @@ describe('Copy content', () => { expect(await dataTable.isItemPresent(items[1])).toBe(true, `${items[1]} not present in ${destination} folder`); } - async function copyFileWithNameThatAlreadyExists(fileName: string, location: string = '', destination: string, doBefore?: () => void) { + async function copyFileWithNameThatAlreadyExists(fileName: string, destination: string, location = '', doBefore?: () => void) { await baseCopyDoBefore(fileName, location, destination, doBefore); expect(await dataTable.isItemPresent(fileName)).toBe(true, `${fileName}.txt not present in source folder`); await page.clickPersonalFilesAndWait(); @@ -340,7 +334,7 @@ describe('Copy content', () => { expect(await dataTable.isItemPresent(fileName)).toBe(true, `${fileName}.txt not present in ${destination} folder`); } - async function copyFolderWithNameThatAlreadyExists(folderName: string, location: string = '', destination: string, doBefore?: () => void) { + async function copyFolderWithNameThatAlreadyExists(folderName: string, destination: string, location = '', doBefore?: () => void) { await baseCopyDoBefore(folderName, location, destination, doBefore); expect(await dataTable.isItemPresent(folderName)).toBe(true, `${folderName} not present in source folder`); await page.clickPersonalFilesAndWait(); @@ -351,7 +345,7 @@ describe('Copy content', () => { expect(await dataTable.isItemPresent(file3InFolder)).toBe(true, `${file3InFolder} not present in ${destination} folder in ${folderName}`); } - async function copyItemsIntoLibrary(items: string[], location: string = '', destination: string, doBefore?: () => void) { + async function copyItemsIntoLibrary(items: string[], destination: string, location = '', doBefore?: () => void) { if (doBefore) { doBefore(); } @@ -382,7 +376,7 @@ describe('Copy content', () => { } } - async function copyLockedFile(fileName: string, location: string = '', destination: string, doBefore?: () => void) { + async function copyLockedFile(fileName: string, destination: string, location = '', doBefore?: () => void) { await baseCopyDoBefore(fileName, location, destination, doBefore); expect(await dataTable.isItemPresent(fileName)).toBe(true, `${fileName} not present in source folder`); expect(await apis.nodes.isFileLockedByName(fileName, locationId)).toBe(true, `${fileName} not locked in ${location}`); @@ -392,7 +386,7 @@ describe('Copy content', () => { expect(await apis.nodes.isFileLockedByName(fileName, destinationId)).toBe(false, `${fileName} is locked in ${destination}`); } - async function copyFolderThatContainsLockedFile(folderName: string, location: string = '', destination: string, doBefore?: () => void) { + async function copyFolderThatContainsLockedFile(folderName: string, destination: string, location = '', doBefore?: () => void) { await baseCopyDoBefore(folderName, location, destination, doBefore); expect(await dataTable.isItemPresent(folderName)).toBe(true, `${folderName} not present in source folder`); await page.clickPersonalFilesAndWait(); @@ -412,7 +406,7 @@ describe('Copy content', () => { ); } - async function undoCopyFile(fileName: string, location: string = '', destination: string, doBefore?: () => void) { + async function undoCopyFile(fileName: string, destination: string, location = '', doBefore?: () => void) { await baseCopyDoBefore(fileName, location, destination, doBefore, true); await dataTable.doubleClickOnRowByName(destination); expect(await dataTable.isItemPresent(fileName)).toBe(false, `${fileName} present in ${destination} folder`); @@ -421,7 +415,7 @@ describe('Copy content', () => { expect(await dataTable.isEmpty()).toBe(true, 'Trash is not empty'); } - async function undoCopyFolder(folderName: string, location: string = '', destination: string, doBefore?: () => void) { + async function undoCopyFolder(folderName: string, destination: string, location = '', doBefore?: () => void) { await baseCopyDoBefore(folderName, location, destination, doBefore, true); await dataTable.doubleClickOnRowByName(destination); expect(await dataTable.isItemPresent(folderName)).toBe(false, `${folderName} present in ${destination} folder`); @@ -430,7 +424,7 @@ describe('Copy content', () => { expect(await dataTable.isEmpty()).toBe(true, 'Trash is not empty'); } - async function undoCopyFileWithExistingName(fileName: string, location: string = '', destination: string, doBefore?: () => Promise) { + async function undoCopyFileWithExistingName(fileName: string, destination: string, location = '', doBefore?: () => Promise) { await baseCopyDoBeforeAsync(fileName, location, destination, doBefore, true); await dataTable.doubleClickOnRowByName(source); await dataTable.doubleClickOnRowByName(folder2); @@ -441,7 +435,7 @@ describe('Copy content', () => { expect(await dataTable.isEmpty()).toBe(true, 'Trash is not empty'); } - async function undoCopyFolderWithExistingName(folderName: string, location: string = '', destination: string, doBefore?: () => void) { + async function undoCopyFolderWithExistingName(folderName: string, destination: string, location = '', doBefore?: () => void) { await baseCopyDoBefore(folderName, location, destination, doBefore, true); await dataTable.doubleClickOnRowByName(destination); expect(await dataTable.isItemPresent(folderName)).toBe(true, `${folderName} not present in ${destination} folder`); diff --git a/e2e/protractor/suites/list-views/sort-list.test.ts b/e2e/protractor/suites/list-views/sort-list.test.ts index 5afb145178..d826938b17 100644 --- a/e2e/protractor/suites/list-views/sort-list.test.ts +++ b/e2e/protractor/suites/list-views/sort-list.test.ts @@ -26,7 +26,7 @@ import { AdminActions, LoginPage, RepoClient, FILES, BrowsingPage, DataTable, Cr import { BrowserActions, ContentNodeSelectorDialogPage, DocumentListPage, PaginationPage, ViewerPage } from '@alfresco/adf-testing'; describe('Remember sorting', () => { - interface nodesIds { + interface NodesIds { [index: string]: string; } @@ -38,9 +38,9 @@ describe('Remember sorting', () => { const folderToMove = `folder1`; const folderToContain = `folder2`; const uiCreatedFolder = `folder3`; - const filesIdsUser1: nodesIds = {}; - const filesIdsUser2: nodesIds = {}; - const folderIds: nodesIds = {}; + const filesIdsUser1: NodesIds = {}; + const filesIdsUser2: NodesIds = {}; + const folderIds: NodesIds = {}; const testData = { user1: { diff --git a/projects/aca-content/folder-rules/src/rule-details/actions/rule-action.ui-component.ts b/projects/aca-content/folder-rules/src/rule-details/actions/rule-action.ui-component.ts index d61041e070..9e14e9b2bf 100644 --- a/projects/aca-content/folder-rules/src/rule-details/actions/rule-action.ui-component.ts +++ b/projects/aca-content/folder-rules/src/rule-details/actions/rule-action.ui-component.ts @@ -266,13 +266,7 @@ export class RuleActionUiComponent implements ControlValueAccessor, OnInit, OnCh setDefaultParameters() { this.parameters = {}; (this.selectedActionDefinition?.parameterDefinitions ?? []).forEach((paramDef: ActionParameterDefinition) => { - switch (paramDef.type) { - case 'd:boolean': - this.parameters[paramDef.name] = false; - break; - default: - this.parameters[paramDef.name] = ''; - } + this.parameters[paramDef.name] = paramDef.type === 'd:boolean' ? false : ''; }); } diff --git a/projects/aca-content/preview/src/lib/components/preview.component.spec.ts b/projects/aca-content/preview/src/lib/components/preview.component.spec.ts index 7ac2af91ec..efe3522ee7 100644 --- a/projects/aca-content/preview/src/lib/components/preview.component.spec.ts +++ b/projects/aca-content/preview/src/lib/components/preview.component.spec.ts @@ -393,7 +393,7 @@ describe('PreviewComponent', () => { }); it('should return empty nearest nodes for crashed fields id request', async () => { - spyOn(component, 'getFileIds').and.returnValue(Promise.reject('err')); + spyOn(component, 'getFileIds').and.returnValue(Promise.reject(new Error('err'))); const nearest = await component.getNearestNodes('node1', 'folder1'); diff --git a/projects/aca-content/preview/src/lib/components/preview.component.ts b/projects/aca-content/preview/src/lib/components/preview.component.ts index 853e02eed4..a6b0716819 100644 --- a/projects/aca-content/preview/src/lib/components/preview.component.ts +++ b/projects/aca-content/preview/src/lib/components/preview.component.ts @@ -177,7 +177,7 @@ export class PreviewComponent extends PageComponent implements OnInit, OnDestroy this.node = await this.contentApi.getNodeInfo(id).toPromise(); this.store.dispatch(new SetSelectedNodesAction([{ entry: this.node }])); - if (this.node && this.node.isFile) { + if (this.node?.isFile) { const nearest = await this.getNearestNodes(this.node.id, this.node.parentId); this.previousNodeId = nearest.left; @@ -196,11 +196,9 @@ export class PreviewComponent extends PageComponent implements OnInit, OnDestroy @HostListener('document:keydown', ['$event']) handleKeyboardEvent(event: KeyboardEvent) { - const key = event.keyCode; - const rightArrow = 39; - const leftArrow = 37; + const key = event.key; - if (key === rightArrow || key === leftArrow) { + if (key === 'ArrowRight' || key === 'ArrowLeft') { event.preventDefault(); event.stopImmediatePropagation(); } @@ -410,19 +408,11 @@ export class PreviewComponent extends PageComponent implements OnInit, OnDestroy } items.sort((a: any, b: any) => { - let left = ObjectUtils.getValue(a, key); - if (left) { - left = left instanceof Date ? left.valueOf().toString() : left.toString(); - } else { - left = ''; - } + let left = ObjectUtils.getValue(a, key) ?? ''; + left = left instanceof Date ? left.valueOf().toString() : left.toString(); - let right = ObjectUtils.getValue(b, key); - if (right) { - right = right instanceof Date ? right.valueOf().toString() : right.toString(); - } else { - right = ''; - } + let right = ObjectUtils.getValue(b, key) ?? ''; + right = right instanceof Date ? right.valueOf().toString() : right.toString(); return direction === 'asc' ? left.localeCompare(right, undefined, options) : right.localeCompare(left, undefined, options); }); diff --git a/projects/aca-content/src/lib/components/common/location-link/location-link.component.ts b/projects/aca-content/src/lib/components/common/location-link/location-link.component.ts index 74edff4f2c..85d05a87e7 100644 --- a/projects/aca-content/src/lib/components/common/location-link/location-link.component.ts +++ b/projects/aca-content/src/lib/components/common/location-link/location-link.component.ts @@ -83,10 +83,10 @@ export class LocationLinkComponent implements OnInit { ngOnInit() { if (this.context) { const node: NodeEntry = this.context.row.node; - if (node && node.entry && node.entry.path) { + if (node?.entry && node?.entry?.path) { const path = node.entry.path; - if (path && path.name && path.elements) { + if (path?.name && path?.elements) { if (this.showLocation) { this.displayText = of(path.name.substring(1).replace(/\//g, ' › ')); } else { @@ -144,7 +144,9 @@ export class LocationLinkComponent implements OnInit { let result: string = null; - const elements = path.elements.map((e) => Object.assign({}, e)); + const elements = path.elements.map((e) => { + return { ...e }; + }); const personalFiles = this.translationService.instant('APP.BROWSE.PERSONAL.TITLE'); const fileLibraries = this.translationService.instant('APP.BROWSE.LIBRARIES.TITLE'); diff --git a/projects/aca-content/src/lib/components/common/toggle-shared/toggle-shared.component.ts b/projects/aca-content/src/lib/components/common/toggle-shared/toggle-shared.component.ts index 46ac9e9616..40ee19dec5 100644 --- a/projects/aca-content/src/lib/components/common/toggle-shared/toggle-shared.component.ts +++ b/projects/aca-content/src/lib/components/common/toggle-shared/toggle-shared.component.ts @@ -62,7 +62,7 @@ export class ToggleSharedComponent implements OnInit, OnDestroy { this.selectionState = selectionState; this.isShared = - (this.selectionState.first && this.selectionState.first.entry && (this.selectionState.first.entry as any).sharedByUser) || + (this.selectionState?.first?.entry && (this.selectionState.first.entry as any).sharedByUser) || !!this.selectionState?.first?.entry?.properties?.['qshare:sharedId']; this.selectionLabel = this.isShared ? 'APP.ACTIONS.SHARE_EDIT' : 'APP.ACTIONS.SHARE'; diff --git a/projects/aca-content/src/lib/components/context-menu/context-menu-item.component.ts b/projects/aca-content/src/lib/components/context-menu/context-menu-item.component.ts index 54f9b1704d..afe3172789 100644 --- a/projects/aca-content/src/lib/components/context-menu/context-menu-item.component.ts +++ b/projects/aca-content/src/lib/components/context-menu/context-menu-item.component.ts @@ -52,7 +52,7 @@ export class ContextMenuItemComponent { } private hasClickAction(actionRef: ContentActionRef): boolean { - return !!(actionRef && actionRef.actions && actionRef.actions.click); + return !!actionRef?.actions?.click; } trackByActionId(_: number, obj: ContentActionRef): string { diff --git a/projects/aca-content/src/lib/components/context-menu/context-menu-outside-event.directive.ts b/projects/aca-content/src/lib/components/context-menu/context-menu-outside-event.directive.ts index 0a53eaa292..74e2b31bd3 100644 --- a/projects/aca-content/src/lib/components/context-menu/context-menu-outside-event.directive.ts +++ b/projects/aca-content/src/lib/components/context-menu/context-menu-outside-event.directive.ts @@ -36,8 +36,6 @@ export class OutsideEventDirective implements OnInit, OnDestroy { @Output() clickOutside: EventEmitter = new EventEmitter(); - constructor() {} - ngOnInit() { this.subscriptions = this.subscriptions.concat([ fromEvent(document.body, 'click') @@ -54,11 +52,9 @@ export class OutsideEventDirective implements OnInit, OnDestroy { private findAncestor(el: Element): boolean { const className = 'aca-context-menu'; - if (el.classList.contains(className)) { - return true; + while (el && !el.classList.contains(className)) { + el = el.parentElement; } - // eslint-disable-next-line curly - while ((el = el.parentElement) && !el.classList.contains(className)); return !!el; } } diff --git a/projects/aca-content/src/lib/components/context-menu/context-menu.service.ts b/projects/aca-content/src/lib/components/context-menu/context-menu.service.ts index 0719be9e32..c5b7566def 100644 --- a/projects/aca-content/src/lib/components/context-menu/context-menu.service.ts +++ b/projects/aca-content/src/lib/components/context-menu/context-menu.service.ts @@ -68,11 +68,6 @@ export class ContextMenuService { } private createInjector(contextmenuOverlayRef: ContextMenuOverlayRef): Injector { - const injectionTokens = new WeakMap(); - - injectionTokens.set(ContextMenuOverlayRef, contextmenuOverlayRef); - injectionTokens.set(CONTEXT_MENU_DIRECTION, this.direction); - return Injector.create({ parent: this.injector, providers: [ diff --git a/projects/aca-content/src/lib/components/favorite-libraries/favorite-libraries.component.ts b/projects/aca-content/src/lib/components/favorite-libraries/favorite-libraries.component.ts index a2b2461720..ac67baf8c9 100644 --- a/projects/aca-content/src/lib/components/favorite-libraries/favorite-libraries.component.ts +++ b/projects/aca-content/src/lib/components/favorite-libraries/favorite-libraries.component.ts @@ -95,7 +95,7 @@ export class FavoriteLibrariesComponent extends PageComponent implements OnInit } navigateTo(node: SiteEntry) { - if (node && node.entry && node.entry.guid) { + if (node?.entry?.guid) { this.store.dispatch(new NavigateLibraryAction(node.entry.guid, 'favorite/libraries')); } } diff --git a/projects/aca-content/src/lib/components/favorites/favorites.component.ts b/projects/aca-content/src/lib/components/favorites/favorites.component.ts index 5389d3053e..a33692b05e 100644 --- a/projects/aca-content/src/lib/components/favorites/favorites.component.ts +++ b/projects/aca-content/src/lib/components/favorites/favorites.component.ts @@ -83,7 +83,7 @@ export class FavoritesComponent extends PageComponent implements OnInit { const { isFolder, id } = favorite; // TODO: rework as it will fail on non-English setups - const isSitePath = (path: PathInfo): boolean => path && path.elements && path.elements.some(({ name }: PathElement) => name === 'Sites'); + const isSitePath = (path: PathInfo): boolean => path?.elements?.some(({ name }: PathElement) => name === 'Sites'); if (isFolder) { this.contentApi @@ -97,7 +97,7 @@ export class FavoritesComponent extends PageComponent implements OnInit { } onNodeDoubleClick(node: NodeEntry) { - if (node && node.entry) { + if (node?.entry) { if (node.entry.isFolder) { this.navigate(node.entry); } diff --git a/projects/aca-content/src/lib/components/files/files.component.ts b/projects/aca-content/src/lib/components/files/files.component.ts index a5043f6e97..759e780c8e 100644 --- a/projects/aca-content/src/lib/components/files/files.component.ts +++ b/projects/aca-content/src/lib/components/files/files.component.ts @@ -102,7 +102,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy { (node) => { this.isValidPath = true; - if (node.entry && node.entry.isFolder) { + if (node?.entry?.isFolder) { this.updateCurrentNode(node.entry); } else { this.router.navigate(['/personal-files', node.entry.parentId], { @@ -190,7 +190,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy { } navigateTo(node: NodeEntry) { - if (node && node.entry) { + if (node?.entry) { this.selectedNode = node; const { isFolder } = node.entry; @@ -220,7 +220,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy { this.documentList.resetNewFolderPagination(); // todo: review this approach once 5.2.3 is out - if (this.nodePath && this.nodePath.length > 2) { + if (this.nodePath && this.nodePath?.length > 2) { if (this.nodePath[1].name === 'Sites' && this.nodePath[2].id === route.id) { return this.navigate(this.nodePath[3].id); } @@ -232,31 +232,31 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy { const node: NodeEntry = event.file.data; // check root and child nodes - if (node && node.entry && node.entry.parentId === this.getParentNodeId()) { + if (node?.entry?.parentId === this.getParentNodeId()) { this.reload(this.selectedNode); return; } // check the child nodes to show dropped folder if (event && event.file.options.parentId === this.getParentNodeId()) { - this.displayFolderParent(event.file.options.path, 0); + this.displayFolderParent(0, event.file.options.path); return; } - if (event && event.file.options.parentId) { + if (event?.file.options.parentId) { if (this.nodePath) { const correspondingNodePath = this.nodePath.find((pathItem) => pathItem.id === event.file.options.parentId); // check if the current folder has the 'trigger-upload-folder' as one of its parents if (correspondingNodePath) { const correspondingIndex = this.nodePath.length - this.nodePath.indexOf(correspondingNodePath); - this.displayFolderParent(event.file.options.path, correspondingIndex); + this.displayFolderParent(correspondingIndex, event.file.options.path); } } } } - displayFolderParent(filePath = '', index: number) { + displayFolderParent(index: number, filePath = '') { const parentName = filePath.split('/')[index]; const currentFoldersDisplayed = (this.documentList.data.getRows() as ShareDataRow[]) || []; @@ -269,7 +269,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy { } onContentCopied(nodes: NodeEntry[]) { - const newNode = nodes.find((node) => node && node.entry && node.entry.parentId === this.getParentNodeId()); + const newNode = nodes.find((node) => node?.entry?.parentId === this.getParentNodeId()); if (newNode) { this.reload(this.selectedNode); } @@ -279,10 +279,12 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy { private async updateCurrentNode(node: Node) { this.nodePath = null; - if (node && node.path && node.path.elements) { + if (node?.path?.elements) { const elements = node.path.elements; - this.nodePath = elements.map((pathElement) => Object.assign({}, pathElement)); + this.nodePath = elements.map((pathElement) => { + return { ...pathElement }; + }); if (elements.length > 1) { if (elements[1].name === 'User Homes') { @@ -329,14 +331,14 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy { } isSiteContainer(node: Node): boolean { - if (node && node.aspectNames && node.aspectNames.length > 0) { + if (node?.aspectNames?.length > 0) { return node.aspectNames.indexOf('st:siteContainer') >= 0; } return false; } isRootNode(nodeId: string): boolean { - if (this.node && this.node.path && this.node.path.elements && this.node.path.elements.length > 0) { + if (this.node?.path?.elements?.length > 0) { return this.node.path.elements[0].id === nodeId; } return false; @@ -359,7 +361,7 @@ export class FilesComponent extends PageComponent implements OnInit, OnDestroy { const objectFromMap = {}; activeFilters.forEach((filter: FilterSearch) => { let paramValue; - if (filter.value && filter.value.from && filter.value.to) { + if (filter?.value?.from && filter?.value?.to) { paramValue = `${filter.value.from}||${filter.value.to}`; } else { paramValue = filter.value; diff --git a/projects/aca-content/src/lib/components/info-drawer/library-metadata-tab/library-metadata-form.component.ts b/projects/aca-content/src/lib/components/info-drawer/library-metadata-tab/library-metadata-form.component.ts index 9817ff90a5..aac068eae4 100644 --- a/projects/aca-content/src/lib/components/info-drawer/library-metadata-tab/library-metadata-form.component.ts +++ b/projects/aca-content/src/lib/components/info-drawer/library-metadata-tab/library-metadata-form.component.ts @@ -60,8 +60,8 @@ import { Actions, ofType } from '@ngrx/effects'; export class InstantErrorStateMatcher implements ErrorStateMatcher { isErrorState(control: UntypedFormControl | null, form: FormGroupDirective | NgForm | null): boolean { - const isSubmitted = form && form.submitted; - return !!(control && control.invalid && (control.dirty || control.touched || isSubmitted)); + const isSubmitted = form?.submitted; + return !!(control?.invalid && (control?.dirty || control?.touched || isSubmitted)); } } diff --git a/projects/aca-content/src/lib/components/libraries/libraries.component.ts b/projects/aca-content/src/lib/components/libraries/libraries.component.ts index c6c1369fd7..8475cebd35 100644 --- a/projects/aca-content/src/lib/components/libraries/libraries.component.ts +++ b/projects/aca-content/src/lib/components/libraries/libraries.component.ts @@ -81,7 +81,7 @@ export class LibrariesComponent extends PageComponent implements OnInit { } navigateTo(node: SiteEntry) { - if (node && node.entry && node.entry.guid) { + if (node?.entry?.guid) { this.store.dispatch(new NavigateLibraryAction(node.entry.guid)); } } diff --git a/projects/aca-content/src/lib/components/recent-files/recent-files.component.ts b/projects/aca-content/src/lib/components/recent-files/recent-files.component.ts index d4a4d8fdcf..889114d59d 100644 --- a/projects/aca-content/src/lib/components/recent-files/recent-files.component.ts +++ b/projects/aca-content/src/lib/components/recent-files/recent-files.component.ts @@ -63,10 +63,6 @@ import { TranslateModule } from '@ngx-translate/core'; export class RecentFilesComponent extends PageComponent implements OnInit { columns: DocumentListPresetRef[] = []; - constructor() { - super(); - } - ngOnInit() { super.ngOnInit(); @@ -79,7 +75,7 @@ export class RecentFilesComponent extends PageComponent implements OnInit { } onNodeDoubleClick(node: NodeEntry) { - if (node && node.entry) { + if (node?.entry) { this.showPreview(node, { location: this.router.url }); } } diff --git a/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.spec.ts b/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.spec.ts index eb152b5310..45b5c10ec7 100644 --- a/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.spec.ts +++ b/projects/aca-content/src/lib/components/search/search-input-control/search-input-control.component.spec.ts @@ -42,39 +42,39 @@ describe('SearchInputControlComponent', () => { fixture.detectChanges(); }); - it('should emit submit event on searchSubmit', async () => { + it('should emit submit event on searchSubmit', () => { const keyboardEvent = { target: { value: 'a' } }; let eventArgs = null; component.submit.subscribe((args) => (eventArgs = args)); - await component.searchSubmit(keyboardEvent); + component.searchSubmit(keyboardEvent); expect(eventArgs).toBe(keyboardEvent); }); - it('should emit searchChange event on inputChange', async () => { + it('should emit searchChange event on inputChange', () => { const searchTerm = 'b'; let eventArgs = null; component.searchChange.subscribe((args) => (eventArgs = args)); - await component.inputChange(searchTerm); + component.inputChange(searchTerm); expect(eventArgs).toBe(searchTerm); }); - it('should emit searchChange event on clear', async () => { + it('should emit searchChange event on clear', () => { let eventArgs = null; component.searchChange.subscribe((args) => (eventArgs = args)); - await component.clear(); + component.clear(); expect(eventArgs).toBe(''); }); - it('should clear searchTerm', async () => { + it('should clear searchTerm', () => { component.searchTerm = 'c'; fixture.detectChanges(); - await component.clear(); + component.clear(); expect(component.searchTerm).toBe(''); }); From b0e288a98989323487d11490e4a0fa3d9812d0c1 Mon Sep 17 00:00:00 2001 From: MichalKinas Date: Fri, 27 Oct 2023 15:32:53 +0200 Subject: [PATCH 5/9] Sonarcloud code smell fixes part II --- .../tests/special-permissions-actions.test.ts | 8 ++-- ...ch-libraries-query-builder.service.spec.ts | 4 +- .../search-libraries-query-builder.service.ts | 6 +-- .../search-libraries-results.component.ts | 4 +- .../search-results-row.component.ts | 2 +- .../search-results.component.spec.ts | 20 ++-------- .../search-results.component.ts | 2 +- .../shared-link-view.component.spec.ts | 2 +- .../directives/active-link.directive.spec.ts | 1 - .../directives/active-link.directive.ts | 4 +- .../directives/expansion-panel.directive.ts | 2 +- .../directives/menu-panel.directive.ts | 2 +- .../sidenav/user-menu/user-menu.component.ts | 2 +- .../toggle-edit-offline.component.spec.ts | 2 +- .../src/lib/services/node-actions.service.ts | 14 +++---- .../services/node-template.service.spec.ts | 6 +-- .../src/lib/services/node-template.service.ts | 2 +- .../src/lib/store/effects/library.effects.ts | 6 +-- .../src/lib/store/effects/node.effects.ts | 26 ++++++------- .../store/effects/template.effects.spec.ts | 18 ++------- .../src/lib/store/effects/upload.effects.ts | 10 +---- .../src/lib/store/effects/viewer.effects.ts | 4 +- .../src/lib/store/reducers/app.reducer.ts | 4 +- .../lib/components/viewer/viewer.component.ts | 26 ++++--------- .../src/api/file-actions.ts | 4 +- .../dataTable/mat-menu.component.ts | 3 +- .../components/viewer.component.ts | 3 +- .../src/page-objects/pages/base.page.ts | 21 +++++----- projects/aca-shared/rules/src/app.rules.ts | 38 +++++++------------ .../aca-shared/rules/src/navigation.rules.ts | 24 ++++++------ .../document-base-page.component.ts | 4 +- .../document-base-page.spec.ts | 4 -- .../toolbar-button.component.ts | 2 +- .../toolbar-menu-item.component.ts | 2 +- .../contextmenu/contextmenu.directive.ts | 6 +-- .../src/lib/services/app.extension.service.ts | 8 ++-- .../store/src/actions/router.actions.ts | 2 - .../store/src/actions/search.actions.ts | 1 - .../store/src/actions/template.actions.ts | 4 -- .../store/src/effects/router.effects.ts | 8 ++-- .../src/components/login/login.ts | 5 --- .../src/utilities/admin-actions.ts | 4 -- 42 files changed, 118 insertions(+), 202 deletions(-) diff --git a/e2e/playwright/special-permissions-actions-available/src/tests/special-permissions-actions.test.ts b/e2e/playwright/special-permissions-actions-available/src/tests/special-permissions-actions.test.ts index b04b18e865..70701c387e 100644 --- a/e2e/playwright/special-permissions-actions-available/src/tests/special-permissions-actions.test.ts +++ b/e2e/playwright/special-permissions-actions-available/src/tests/special-permissions-actions.test.ts @@ -108,12 +108,12 @@ test.describe('Special permissions : ', () => { await managerSiteActions.addSiteMember(sitePrivate, userCollaborator, Site.RoleEnum.SiteCollaborator); await managerSiteActions.addSiteMember(sitePrivate, userDemoted, Site.RoleEnum.SiteManager); - await managerFileActions.uploadFileWithRename(TEST_FILES.DOCX.path, docLibId, testData.fileDocx.name); - fileDocxFavId = (await managerFileActions.uploadFileWithRename(TEST_FILES.DOCX.path, docLibId, testData.fileDocxFav.name)).entry.id; + await managerFileActions.uploadFileWithRename(TEST_FILES.DOCX.path, testData.fileDocx.name, docLibId); + fileDocxFavId = (await managerFileActions.uploadFileWithRename(TEST_FILES.DOCX.path, testData.fileDocxFav.name, docLibId)).entry.id; await managerNodeActions.createFile(testData.file.name, docLibId); fileFavId = (await managerNodeActions.createFile(testData.fileFav.name, docLibId)).entry.id; - fileDocxSharedId = (await managerFileActions.uploadFileWithRename(TEST_FILES.DOCX.path, docLibId, testData.fileDocxShared.name)).entry.id; - fileDocxSharedFavId = (await managerFileActions.uploadFileWithRename(TEST_FILES.DOCX.path, docLibId, testData.fileDocxSharedFav.name)).entry.id; + fileDocxSharedId = (await managerFileActions.uploadFileWithRename(TEST_FILES.DOCX.path, testData.fileDocxShared.name, docLibId)).entry.id; + fileDocxSharedFavId = (await managerFileActions.uploadFileWithRename(TEST_FILES.DOCX.path, testData.fileDocxSharedFav.name, docLibId)).entry.id; fileSharedId = (await managerNodeActions.createFile(testData.fileShared.name, docLibId)).entry.id; fileSharedFavId = (await managerNodeActions.createFile(testData.fileSharedFav.name, docLibId)).entry.id; fileLockedId = (await managerNodeActions.createFile(testData.fileLocked.name, docLibId)).entry.id; diff --git a/projects/aca-content/src/lib/components/search/search-libraries-results/search-libraries-query-builder.service.spec.ts b/projects/aca-content/src/lib/components/search/search-libraries-results/search-libraries-query-builder.service.spec.ts index 97303d0c0b..06d8e234e4 100644 --- a/projects/aca-content/src/lib/components/search/search-libraries-results/search-libraries-query-builder.service.spec.ts +++ b/projects/aca-content/src/lib/components/search/search-libraries-results/search-libraries-query-builder.service.spec.ts @@ -53,13 +53,13 @@ describe('SearchLibrariesQueryBuilderService', () => { expect(builder.userQuery).toEqual('something'); }); - it('should build query and raise an event on update', async () => { + it('should build query and raise an event on update', () => { spyOn(builder, 'buildQuery').and.returnValue(query); let eventArgs = null; builder.updated.subscribe((args) => (eventArgs = args)); - await builder.update(); + builder.update(); expect(eventArgs).toBe(query); }); diff --git a/projects/aca-content/src/lib/components/search/search-libraries-results/search-libraries-query-builder.service.ts b/projects/aca-content/src/lib/components/search/search-libraries-results/search-libraries-query-builder.service.ts index 2e9122efa3..a6dbb2741b 100644 --- a/projects/aca-content/src/lib/components/search/search-libraries-results/search-libraries-query-builder.service.ts +++ b/projects/aca-content/src/lib/components/search/search-libraries-results/search-libraries-query-builder.service.ts @@ -80,12 +80,12 @@ export class SearchLibrariesQueryBuilderService { buildQuery(): LibrarySearchQuery { const query = this.userQuery; - if (query && query.length > 1) { + if (query?.length > 1) { return { term: query, opts: { - skipCount: this.paging && this.paging.skipCount, - maxItems: this.paging && this.paging.maxItems + skipCount: this.paging?.skipCount, + maxItems: this.paging?.maxItems } }; } diff --git a/projects/aca-content/src/lib/components/search/search-libraries-results/search-libraries-results.component.ts b/projects/aca-content/src/lib/components/search/search-libraries-results/search-libraries-results.component.ts index 145f5501f0..908e19eff2 100644 --- a/projects/aca-content/src/lib/components/search/search-libraries-results/search-libraries-results.component.ts +++ b/projects/aca-content/src/lib/components/search/search-libraries-results/search-libraries-results.component.ts @@ -158,7 +158,7 @@ export class SearchLibrariesResultsComponent extends PageComponent implements On } getNumberOfResults() { - if (this.data && this.data.list && this.data.list.pagination) { + if (this.data?.list?.pagination) { return this.data.list.pagination.totalItems; } return 0; @@ -173,7 +173,7 @@ export class SearchLibrariesResultsComponent extends PageComponent implements On } navigateTo(node: SiteEntry) { - if (node && node.entry && node.entry.guid) { + if (node?.entry?.guid) { this.store.dispatch(new NavigateLibraryAction(node.entry.guid)); } } diff --git a/projects/aca-content/src/lib/components/search/search-results-row/search-results-row.component.ts b/projects/aca-content/src/lib/components/search/search-results-row/search-results-row.component.ts index 3c99761faf..2bb23bd140 100644 --- a/projects/aca-content/src/lib/components/search/search-results-row/search-results-row.component.ts +++ b/projects/aca-content/src/lib/components/search/search-results-row/search-results-row.component.ts @@ -74,7 +74,7 @@ export class SearchResultsRowComponent implements OnInit, OnDestroy { if (entry.id === node.id) { entry.name = node.name; - entry.properties = Object.assign({}, node.properties); + entry.properties = { ...node.properties }; this.updateValues(); } diff --git a/projects/aca-content/src/lib/components/search/search-results/search-results.component.spec.ts b/projects/aca-content/src/lib/components/search/search-results/search-results.component.spec.ts index 2229e648e5..e8614b0a6f 100644 --- a/projects/aca-content/src/lib/components/search/search-results/search-results.component.spec.ts +++ b/projects/aca-content/src/lib/components/search/search-results/search-results.component.spec.ts @@ -95,11 +95,7 @@ describe('SearchComponent', () => { }); it('should raise an error if search fails', fakeAsync(() => { - spyOn(queryBuilder['searchApi'], 'search').and.returnValue( - Promise.reject({ - message: `{ "error": { "statusCode": 500 } } ` - }) - ); + spyOn(queryBuilder['searchApi'], 'search').and.returnValue(Promise.reject(new Error('{ "error": { "statusCode": 500 } }'))); spyOn(queryBuilder, 'buildQuery').and.returnValue(searchRequest); spyOn(store, 'dispatch').and.stub(); @@ -118,11 +114,7 @@ describe('SearchComponent', () => { return key; }); - spyOn(queryBuilder['searchApi'], 'search').and.returnValue( - Promise.reject({ - message: `{ "error": { "statusCode": 401 } } ` - }) - ); + spyOn(queryBuilder['searchApi'], 'search').and.returnValue(Promise.reject(new Error('{ "error": { "statusCode": 401 } }'))); spyOn(queryBuilder, 'buildQuery').and.returnValue(searchRequest); spyOn(store, 'dispatch').and.stub(); @@ -141,11 +133,7 @@ describe('SearchComponent', () => { return key; }); - spyOn(queryBuilder['searchApi'], 'search').and.returnValue( - Promise.reject({ - message: `{ "error": { "statusCode": 401 } } ` - }) - ); + spyOn(queryBuilder['searchApi'], 'search').and.returnValue(Promise.reject(new Error('{ "error": { "statusCode": 401 } }'))); spyOn(queryBuilder, 'buildQuery').and.returnValue(searchRequest); spyOn(store, 'dispatch').and.stub(); @@ -191,7 +179,7 @@ describe('SearchComponent', () => { }); it('should format user input as cm:name if configuration not provided', () => { - const query = component.formatSearchQuery('hello', undefined); + const query = component.formatSearchQuery('hello'); expect(query).toBe(`(cm:name:"hello*")`); }); diff --git a/projects/aca-content/src/lib/components/search/search-results/search-results.component.ts b/projects/aca-content/src/lib/components/search/search-results/search-results.component.ts index 14585c19a7..84bdd04727 100644 --- a/projects/aca-content/src/lib/components/search/search-results/search-results.component.ts +++ b/projects/aca-content/src/lib/components/search/search-results/search-results.component.ts @@ -266,7 +266,7 @@ export class SearchResultsComponent extends PageComponent implements OnInit { } onNodeDoubleClick(node: NodeEntry) { - if (node && node.entry) { + if (node?.entry) { if (node.entry.isFolder) { this.store.dispatch(new NavigateToFolder(node)); return; diff --git a/projects/aca-content/src/lib/components/shared-link-view/shared-link-view.component.spec.ts b/projects/aca-content/src/lib/components/shared-link-view/shared-link-view.component.spec.ts index 6a6c3f8ab1..1157dd42cb 100644 --- a/projects/aca-content/src/lib/components/shared-link-view/shared-link-view.component.spec.ts +++ b/projects/aca-content/src/lib/components/shared-link-view/shared-link-view.component.spec.ts @@ -95,7 +95,7 @@ describe('SharedLinkViewComponent', () => { })); it('should not update store on error', fakeAsync(() => { - spyGetSharedLink.and.returnValue(Promise.reject('error')); + spyGetSharedLink.and.returnValue(Promise.reject(new Error('error'))); fixture.detectChanges(); tick(); diff --git a/projects/aca-content/src/lib/components/sidenav/directives/active-link.directive.spec.ts b/projects/aca-content/src/lib/components/sidenav/directives/active-link.directive.spec.ts index 7c156c7d9b..9c96c78f6d 100644 --- a/projects/aca-content/src/lib/components/sidenav/directives/active-link.directive.spec.ts +++ b/projects/aca-content/src/lib/components/sidenav/directives/active-link.directive.spec.ts @@ -75,7 +75,6 @@ describe('ActionDirective', () => { it('should add active route class name', () => { fixture.detectChanges(); router.navigateByUrl('/dummy'); - // fixture.detectChanges(); expect(document.body.querySelector('#test-element').className.includes('active-link-class')).toBe(true); }); diff --git a/projects/aca-content/src/lib/components/sidenav/directives/active-link.directive.ts b/projects/aca-content/src/lib/components/sidenav/directives/active-link.directive.ts index d2f3e7a579..5ccc7150e6 100644 --- a/projects/aca-content/src/lib/components/sidenav/directives/active-link.directive.ts +++ b/projects/aca-content/src/lib/components/sidenav/directives/active-link.directive.ts @@ -67,7 +67,7 @@ export class ActiveLinkDirective implements OnInit, AfterContentInit { } private render(routerUrl: string, actionUrl: string) { - if (routerUrl && routerUrl.substring(1).startsWith(actionUrl)) { + if (routerUrl?.substring(1).startsWith(actionUrl)) { this.isLinkActive = true; this.renderer.addClass(this.element.nativeElement, this.acaActiveLink); } else { @@ -82,6 +82,6 @@ export class ActiveLinkDirective implements OnInit, AfterContentInit { } private resolveUrl(item): string { - return (item.action && item.action.click && item.action.click.payload) || item.action.route; + return item.action?.click?.payload || item.action?.route; } } diff --git a/projects/aca-content/src/lib/components/sidenav/directives/expansion-panel.directive.ts b/projects/aca-content/src/lib/components/sidenav/directives/expansion-panel.directive.ts index 9af098c6e6..76243e03b5 100644 --- a/projects/aca-content/src/lib/components/sidenav/directives/expansion-panel.directive.ts +++ b/projects/aca-content/src/lib/components/sidenav/directives/expansion-panel.directive.ts @@ -58,7 +58,7 @@ export class ExpansionPanelDirective implements OnInit, OnDestroy { constructor(private store: Store, private router: Router, private expansionPanel: MatExpansionPanel) {} hasActiveLinks() { - if (this.acaExpansionPanel && this.acaExpansionPanel.children) { + if (this.acaExpansionPanel?.children) { return this.acaExpansionPanel.children.some((child) => this.router.url.startsWith(child.url || child.action.payload)); } return false; diff --git a/projects/aca-content/src/lib/components/sidenav/directives/menu-panel.directive.ts b/projects/aca-content/src/lib/components/sidenav/directives/menu-panel.directive.ts index 3401d78940..0a7767a2f4 100644 --- a/projects/aca-content/src/lib/components/sidenav/directives/menu-panel.directive.ts +++ b/projects/aca-content/src/lib/components/sidenav/directives/menu-panel.directive.ts @@ -57,7 +57,7 @@ export class MenuPanelDirective implements OnInit, OnDestroy { constructor(private store: Store, private router: Router) {} hasActiveLinks() { - if (this.acaMenuPanel && this.acaMenuPanel.children) { + if (this.acaMenuPanel?.children) { return this.acaMenuPanel.children.some((child) => this.router.url.startsWith(child.url || child.action.payload)); } return false; diff --git a/projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.ts b/projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.ts index d1b13a8d43..a4c7e2fae5 100644 --- a/projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.ts +++ b/projects/aca-content/src/lib/components/sidenav/user-menu/user-menu.component.ts @@ -57,7 +57,7 @@ export class UserMenuComponent implements OnInit { ngOnInit() { this.getUserInfo(); - if (this.data && this.data.items) { + if (this.data?.items) { this.data.items.sort((a, b) => a.order - b.order); } } diff --git a/projects/aca-content/src/lib/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.spec.ts b/projects/aca-content/src/lib/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.spec.ts index e061c2a599..ab1d849afd 100644 --- a/projects/aca-content/src/lib/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.spec.ts +++ b/projects/aca-content/src/lib/components/toolbar/toggle-edit-offline/toggle-edit-offline.component.spec.ts @@ -69,7 +69,7 @@ describe('ToggleEditOfflineComponent', () => { fixture.detectChanges(); - expect(component.selection).toEqual(selection.file as any); + expect(component.selection).toEqual(selection.file); }); it('should download content when node is locked', async () => { diff --git a/projects/aca-content/src/lib/services/node-actions.service.ts b/projects/aca-content/src/lib/services/node-actions.service.ts index 7b2c1493d2..ee3443e718 100644 --- a/projects/aca-content/src/lib/services/node-actions.service.ts +++ b/projects/aca-content/src/lib/services/node-actions.service.ts @@ -143,8 +143,8 @@ export class NodeActionsService { } isEntryEntitiesArray(contentEntities: any[]): boolean { - if (contentEntities && contentEntities.length) { - const nonEntryNode = contentEntities.find((node) => !node || !node.entry || !(node.entry.nodeId || node.entry.id)); + if (contentEntities?.length) { + const nonEntryNode = contentEntities.find((node) => !(node?.entry?.nodeId || node?.entry?.id)); return !nonEntryNode; } return false; @@ -160,7 +160,7 @@ export class NodeActionsService { if (nodeEntry.parentId) { entryParentId = nodeEntry.parentId; - } else if (nodeEntry.path && nodeEntry.path.elements && nodeEntry.path.elements.length) { + } else if (nodeEntry.path?.elements?.length) { entryParentId = nodeEntry.path.elements[nodeEntry.path.elements.length - 1].id; } @@ -255,7 +255,7 @@ export class NodeActionsService { // todo: review this approach once 5.2.3 is out private customizeBreadcrumb(node: Node) { - if (node && node.path && node.path.elements) { + if (node?.path?.elements) { const elements = node.path.elements; if (elements.length > 1) { @@ -316,7 +316,7 @@ export class NodeActionsService { } isSiteContainer(node: Node): boolean { - if (node && node.aspectNames && node.aspectNames.length > 0) { + if (node?.aspectNames?.length > 0) { return node.aspectNames.indexOf('st:siteContainer') >= 0; } return false; @@ -658,7 +658,7 @@ export class NodeActionsService { const folderMoveResponseData = this.flatten(next); const foundError = folderMoveResponseData.find((node) => node instanceof Error); // data might contain also items of form: { itemMoved, initialParentId } - const foundEntry = folderMoveResponseData.find((node) => (node.itemMoved && node.itemMoved.entry) || (node && node.entry)); + const foundEntry = folderMoveResponseData.find((node) => node.itemMoved?.entry || node?.entry); if (!foundError) { // consider success if NONE of the items from the folder move response is an error @@ -677,7 +677,7 @@ export class NodeActionsService { return acc; }, moveStatus); } else { - if ((data.itemMoved && data.itemMoved.entry) || (data && data.entry)) { + if (data.itemMoved?.entry || data?.entry) { moveStatus.succeeded.push(data); } else { moveStatus.failed.push(data); diff --git a/projects/aca-content/src/lib/services/node-template.service.spec.ts b/projects/aca-content/src/lib/services/node-template.service.spec.ts index 19fb9bd050..fff43b1926 100644 --- a/projects/aca-content/src/lib/services/node-template.service.spec.ts +++ b/projects/aca-content/src/lib/services/node-template.service.spec.ts @@ -153,11 +153,7 @@ describe('NodeTemplateService', () => { })); it('should raise an error when getNodeInfo fails', fakeAsync(() => { - spyOn(nodeTemplateService['searchApi'], 'search').and.returnValue( - Promise.reject({ - message: `{ "error": { "statusCode": 404 } } ` - }) - ); + spyOn(nodeTemplateService['searchApi'], 'search').and.returnValue(Promise.reject(new Error('{ "error": { "statusCode": 404 } }'))); spyOn(store, 'dispatch'); nodeTemplateService.selectTemplateDialog(fileTemplateConfig); diff --git a/projects/aca-content/src/lib/services/node-template.service.ts b/projects/aca-content/src/lib/services/node-template.service.ts index d6e264b0af..744367d5e9 100644 --- a/projects/aca-content/src/lib/services/node-template.service.ts +++ b/projects/aca-content/src/lib/services/node-template.service.ts @@ -125,7 +125,7 @@ export class NodeTemplateService { } private transformNode(node: Node): Node { - if (node && node.path && node.path && node.path.elements instanceof Array) { + if (node?.path?.elements instanceof Array) { node.path.elements = this.getPathElements(node); } return node; diff --git a/projects/aca-content/src/lib/store/effects/library.effects.ts b/projects/aca-content/src/lib/store/effects/library.effects.ts index 61585ffec8..59b4c49406 100644 --- a/projects/aca-content/src/lib/store/effects/library.effects.ts +++ b/projects/aca-content/src/lib/store/effects/library.effects.ts @@ -62,7 +62,7 @@ export class LibraryEffects { .select(getAppSelection) .pipe(take(1)) .subscribe((selection) => { - if (selection && selection.library) { + if (selection?.library) { this.content.deleteLibrary(selection.library.entry.id); } }); @@ -84,7 +84,7 @@ export class LibraryEffects { .select(getAppSelection) .pipe(take(1)) .subscribe((selection) => { - if (selection && selection.library) { + if (selection?.library) { this.content.leaveLibrary(selection.library.entry.id, action.configuration?.focusedElementOnCloseSelector); } }); @@ -138,7 +138,7 @@ export class LibraryEffects { .select(getAppSelection) .pipe(take(1)) .subscribe((selection) => { - if (selection && selection.library) { + if (selection?.library) { const { id } = selection.library.entry; const { title, description, visibility } = action.payload; diff --git a/projects/aca-content/src/lib/store/effects/node.effects.ts b/projects/aca-content/src/lib/store/effects/node.effects.ts index 15e2efd928..06594660d1 100644 --- a/projects/aca-content/src/lib/store/effects/node.effects.ts +++ b/projects/aca-content/src/lib/store/effects/node.effects.ts @@ -78,7 +78,7 @@ export class NodeEffects { .select(getAppSelection) .pipe(take(1)) .subscribe((selection) => { - if (selection && selection.file) { + if (selection?.file) { this.contentService.shareNode(selection.file, action.configuration?.focusedElementOnCloseSelector); } }); @@ -93,7 +93,7 @@ export class NodeEffects { this.actions$.pipe( ofType(NodeActionTypes.Unshare), map((action) => { - if (action && action.payload && action.payload.length > 0) { + if (action?.payload?.length > 0) { this.contentService.unshareNodes(action.payload); } else { this.store @@ -115,7 +115,7 @@ export class NodeEffects { this.actions$.pipe( ofType(NodeActionTypes.PurgeDeleted), map((action) => { - if (action && action.payload && action.payload.length > 0) { + if (action?.payload?.length > 0) { this.contentService.purgeDeletedNodes(action.payload); } else { this.store @@ -137,7 +137,7 @@ export class NodeEffects { this.actions$.pipe( ofType(NodeActionTypes.RestoreDeleted), map((action) => { - if (action && action.payload && action.payload.length > 0) { + if (action?.payload?.length > 0) { this.contentService.restoreDeletedNodes(action.payload); } else { this.store @@ -160,7 +160,7 @@ export class NodeEffects { ofType(NodeActionTypes.Delete), map((action) => { this.store.dispatch(new ShowLoaderAction(true)); - if (action && action.payload && action.payload.length > 0) { + if (action?.payload?.length > 0) { this.contentService.deleteNodes(action.payload); } else { this.store @@ -202,7 +202,7 @@ export class NodeEffects { .select(getCurrentFolder) .pipe(take(1)) .subscribe((node) => { - if (node && node.id) { + if (node?.id) { this.contentService.createFolder(node.id); } }); @@ -224,7 +224,7 @@ export class NodeEffects { .select(getAppSelection) .pipe(take(1)) .subscribe((selection) => { - if (selection && selection.folder) { + if (selection?.folder) { this.contentService.editFolder(selection.folder, action.configuration?.focusedElementOnCloseSelector); } }); @@ -347,7 +347,7 @@ export class NodeEffects { .select(getAppSelection) .pipe(take(1)) .subscribe((selection) => { - if (selection && selection.file) { + if (selection?.file) { this.contentService.manageVersions(selection.file, action.configuration?.focusedElementOnCloseSelector); } }); @@ -362,14 +362,14 @@ export class NodeEffects { this.actions$.pipe( ofType(NodeActionTypes.PrintFile), map((action) => { - if (action && action.payload) { + if (action?.payload) { this.printFile(action.payload); } else { this.store .select(getAppSelection) .pipe(take(1)) .subscribe((selection) => { - if (selection && selection.file) { + if (selection?.file) { this.printFile(selection.file); } }); @@ -384,14 +384,14 @@ export class NodeEffects { this.actions$.pipe( ofType(NodeActionTypes.UnlockForWriting), map((action) => { - if (action && action.payload) { + if (action?.payload) { this.contentService.unlockNode(action.payload); } else { this.store .select(getAppSelection) .pipe(take(1)) .subscribe((selection) => { - if (selection && selection.file) { + if (selection?.file) { this.contentService.unlockNode(selection.file); } }); @@ -424,7 +424,7 @@ export class NodeEffects { ); printFile(node: any) { - if (node && node.entry) { + if (node?.entry) { // shared and favorite const id = node.entry.nodeId || node.entry.guid || node.entry.id; const mimeType = node.entry.content.mimeType; diff --git a/projects/aca-content/src/lib/store/effects/template.effects.spec.ts b/projects/aca-content/src/lib/store/effects/template.effects.spec.ts index 89de4c16d8..94b00a07b2 100644 --- a/projects/aca-content/src/lib/store/effects/template.effects.spec.ts +++ b/projects/aca-content/src/lib/store/effects/template.effects.spec.ts @@ -156,11 +156,7 @@ describe('TemplateEffects', () => { })); it('should raise generic error when copyNode api fails', fakeAsync(() => { - copyNodeSpy.and.returnValue( - Promise.reject({ - message: `{ "error": { "statusCode": 404 } } ` - }) - ); + copyNodeSpy.and.returnValue(Promise.reject(new Error('{ "error": { "statusCode": 404 } }'))); store.dispatch(new CreateFromTemplate(node)); tick(); @@ -170,11 +166,7 @@ describe('TemplateEffects', () => { })); it('should raise name conflict error when copyNode api returns 409', fakeAsync(() => { - copyNodeSpy.and.returnValue( - Promise.reject({ - message: `{ "error": { "statusCode": 409 } } ` - }) - ); + copyNodeSpy.and.returnValue(Promise.reject(new Error('{ "error": { "statusCode": 409 } }'))); store.dispatch(new CreateFromTemplate(node)); tick(); @@ -195,11 +187,7 @@ describe('TemplateEffects', () => { } as NodeEntry; copyNodeSpy.and.returnValue(of(TEST_NODE)); - updateNodeSpy.and.returnValue( - Promise.reject({ - message: `{ "error": { "statusCode": 404 } } ` - }) - ); + updateNodeSpy.and.returnValue(Promise.reject(new Error('{ "error": { "statusCode": 404 } }'))); store.dispatch(new CreateFromTemplate(TEST_NODE.entry)); tick(); diff --git a/projects/aca-content/src/lib/store/effects/upload.effects.ts b/projects/aca-content/src/lib/store/effects/upload.effects.ts index 4c4f8f302d..1ae59fc288 100644 --- a/projects/aca-content/src/lib/store/effects/upload.effects.ts +++ b/projects/aca-content/src/lib/store/effects/upload.effects.ts @@ -150,7 +150,7 @@ export class UploadEffects { .select(getCurrentFolder) .pipe(take(1)) .subscribe((node) => { - if (node && node.id) { + if (node?.id) { const input = event.currentTarget as HTMLInputElement; const files = FileUtils.toFileArray(input.files).map( (file: any) => @@ -186,13 +186,7 @@ export class UploadEffects { this.uploadService.uploadFilesInTheQueue(); const subscription = this.uploadService.fileUploadComplete.subscribe((completed) => { - if ( - file.data && - file.data.entry && - file.data.entry.properties && - file.data.entry.properties['cm:lockType'] === 'WRITE_LOCK' && - file.data.entry.id === completed.data.entry.id - ) { + if (file.data?.entry?.properties?.['cm:lockType'] === 'WRITE_LOCK' && file.data?.entry?.id === completed.data.entry.id) { this.store.dispatch(new UnlockWriteAction(completed.data)); } diff --git a/projects/aca-content/src/lib/store/effects/viewer.effects.ts b/projects/aca-content/src/lib/store/effects/viewer.effects.ts index 819d61d2cc..c78b754412 100644 --- a/projects/aca-content/src/lib/store/effects/viewer.effects.ts +++ b/projects/aca-content/src/lib/store/effects/viewer.effects.ts @@ -101,7 +101,7 @@ export class ViewerEffects { this.actions$.pipe( ofType(ViewerActionTypes.ViewFile), map((action) => { - if (action.payload && action.payload.entry) { + if (action.payload?.entry) { const { id, nodeId, isFile } = action.payload.entry as any; if (this.extensions.canPreviewNode(action.payload) && (isFile || nodeId)) { @@ -112,7 +112,7 @@ export class ViewerEffects { .select(fileToPreview) .pipe(take(1)) .subscribe((result) => { - if (result.selection && result.selection.file) { + if (result.selection?.file) { const { id, nodeId, isFile } = result.selection.file.entry as any; if (this.extensions.canPreviewNode(action.payload) && (isFile || nodeId)) { diff --git a/projects/aca-content/src/lib/store/reducers/app.reducer.ts b/projects/aca-content/src/lib/store/reducers/app.reducer.ts index 7cb29e0b80..7c4695cfb7 100644 --- a/projects/aca-content/src/lib/store/reducers/app.reducer.ts +++ b/projects/aca-content/src/lib/store/reducers/app.reducer.ts @@ -47,7 +47,7 @@ export function appReducer(state: AppState = INITIAL_APP_STATE, action: Action): switch (action.type) { case AppActionTypes.SetInitialState: - newState = Object.assign({}, (action as SetInitialStateAction).payload); + newState = { ...(action as SetInitialStateAction).payload }; break; case NodeActionTypes.SetSelection: newState = updateSelectedNodes(state, action as SetSelectedNodesAction); @@ -198,7 +198,7 @@ function updateSelectedNodes(state: AppState, action: SetSelectedNodesAction): A const libraries: any[] = [...action.payload].filter((node: any) => node.isLibrary); if (libraries.length === 1) { - library = libraries[0] as any; + library = libraries[0]; } if (isEmpty) { diff --git a/projects/aca-content/viewer/src/lib/components/viewer/viewer.component.ts b/projects/aca-content/viewer/src/lib/components/viewer/viewer.component.ts index f336a91998..ada20bc3af 100644 --- a/projects/aca-content/viewer/src/lib/components/viewer/viewer.component.ts +++ b/projects/aca-content/viewer/src/lib/components/viewer/viewer.component.ts @@ -182,7 +182,7 @@ export class AcaViewerComponent implements OnInit, OnDestroy { this.navigationPath = params.path || params.location; }); - if (this.route.snapshot.data && this.route.snapshot.data.navigateSource) { + if (this.route.snapshot.data?.navigateSource) { const source = this.route.snapshot.data.navigateSource.toLowerCase(); if (this.navigationSources.includes(source)) { this.navigateSource = this.route.snapshot.data.navigateSource; @@ -239,7 +239,7 @@ export class AcaViewerComponent implements OnInit, OnDestroy { return; } - if (this.node && this.node.isFile) { + if (this.node?.isFile) { const nearest = await this.getNearestNodes(this.node.id, this.node.parentId); this.nodeId = this.node.id; this.previousNodeId = nearest.left; @@ -420,11 +420,9 @@ export class AcaViewerComponent implements OnInit, OnDestroy { @HostListener('document:keydown', ['$event']) handleKeyboardEvent(event: KeyboardEvent) { - const key = event.keyCode; - const rightArrow = 39; - const leftArrow = 37; + const key = event.key; - if (key === rightArrow || key === leftArrow) { + if (key === 'ArrowRight' || key === 'ArrowLeft') { event.preventDefault(); event.stopImmediatePropagation(); } @@ -438,19 +436,11 @@ export class AcaViewerComponent implements OnInit, OnDestroy { } items.sort((a: any, b: any) => { - let left = ObjectUtils.getValue(a, key); - if (left) { - left = left instanceof Date ? left.valueOf().toString() : left.toString(); - } else { - left = ''; - } + let left = ObjectUtils.getValue(a, key) ?? ''; + left = left instanceof Date ? left.valueOf().toString() : left.toString(); - let right = ObjectUtils.getValue(b, key); - if (right) { - right = right instanceof Date ? right.valueOf().toString() : right.toString(); - } else { - right = ''; - } + let right = ObjectUtils.getValue(b, key) ?? ''; + right = right instanceof Date ? right.valueOf().toString() : right.toString(); return direction === 'asc' ? left.localeCompare(right, undefined, options) : right.localeCompare(left, undefined, options); }); diff --git a/projects/aca-playwright-shared/src/api/file-actions.ts b/projects/aca-playwright-shared/src/api/file-actions.ts index 6f6c254ffe..f2883c5383 100644 --- a/projects/aca-playwright-shared/src/api/file-actions.ts +++ b/projects/aca-playwright-shared/src/api/file-actions.ts @@ -50,7 +50,7 @@ export class FileActionsApi { }); } - async uploadFileWithRename(fileLocation: string, parentId: string = '-my-', newName: string, title: string = '', description: string = '') { + async uploadFileWithRename(fileLocation: string, newName: string, parentId: string = '-my-', title: string = '', description: string = '') { const file = fs.createReadStream(fileLocation); const nodeProps = { properties: { @@ -93,7 +93,7 @@ export class FileActionsApi { async getNodeProperty(nodeId: string, property: string): Promise { try { const node = await this.getNodeById(nodeId); - return (node.entry.properties && node.entry.properties[property]) || ''; + return (node.entry.properties?.[property]) || ''; } catch (error) { Logger.error(`${this.constructor.name} ${this.getNodeProperty.name}`, error); return ''; diff --git a/projects/aca-playwright-shared/src/page-objects/components/dataTable/mat-menu.component.ts b/projects/aca-playwright-shared/src/page-objects/components/dataTable/mat-menu.component.ts index cc9881b83a..d9e5085f96 100644 --- a/projects/aca-playwright-shared/src/page-objects/components/dataTable/mat-menu.component.ts +++ b/projects/aca-playwright-shared/src/page-objects/components/dataTable/mat-menu.component.ts @@ -22,9 +22,8 @@ * from Hyland Software. If not, see . */ -import { Page } from '@playwright/test'; +import { Page, expect } from '@playwright/test'; import { BaseComponent } from '../base.component'; -import { expect } from '@playwright/test'; export class MatMenuComponent extends BaseComponent { private static rootElement = '.mat-menu-content'; diff --git a/projects/aca-playwright-shared/src/page-objects/components/viewer.component.ts b/projects/aca-playwright-shared/src/page-objects/components/viewer.component.ts index dc3dd5613c..8c06ae37a4 100644 --- a/projects/aca-playwright-shared/src/page-objects/components/viewer.component.ts +++ b/projects/aca-playwright-shared/src/page-objects/components/viewer.component.ts @@ -22,11 +22,10 @@ * from Hyland Software. If not, see . */ -import { Page } from '@playwright/test'; +import { Page, expect } from '@playwright/test'; import { BaseComponent } from './base.component'; import { AcaHeader } from './aca-header.component'; import { timeouts } from '../../utils'; -import { expect } from '@playwright/test'; export class ViewerComponent extends BaseComponent { private static rootElement = 'adf-viewer'; diff --git a/projects/aca-playwright-shared/src/page-objects/pages/base.page.ts b/projects/aca-playwright-shared/src/page-objects/pages/base.page.ts index e4812d171f..a4f0f6666e 100644 --- a/projects/aca-playwright-shared/src/page-objects/pages/base.page.ts +++ b/projects/aca-playwright-shared/src/page-objects/pages/base.page.ts @@ -69,20 +69,17 @@ export abstract class BasePage extends PlaywrightBase { await this.page.goto(actualOptions.remoteUrl, { waitUntil: actualOptions.waitUntil }); + } else if (this.urlRequest && actualOptions.waitForRequest) { + await Promise.all([ + this.page.goto(`./#/${this.pageUrl}${actualOptions.query}`, { waitUntil: 'load' }), + this.page.waitForResponse(this.urlRequest) + ]); } else { - if (this.urlRequest && actualOptions.waitForRequest) { - await Promise.all([ - this.page.goto(`./#/${this.pageUrl}${actualOptions.query}`, { waitUntil: 'load' }), - this.page.waitForResponse(this.urlRequest) - ]); - } else { - await this.page.goto(`./#/${this.pageUrl}${actualOptions.query}`, { - waitUntil: actualOptions.waitUntil, - timeout: 60000 - }); - } + await this.page.goto(`./#/${this.pageUrl}${actualOptions.query}`, { + waitUntil: actualOptions.waitUntil, + timeout: 60000 + }); } - await this.spinner.waitForReload(); } diff --git a/projects/aca-shared/rules/src/app.rules.ts b/projects/aca-shared/rules/src/app.rules.ts index 71333f4bc6..a77daaad66 100644 --- a/projects/aca-shared/rules/src/app.rules.ts +++ b/projects/aca-shared/rules/src/app.rules.ts @@ -178,7 +178,7 @@ export function isShared(context: RuleContext): boolean { } if (navigation.isNotTrashcan(context) && !context.selection.isEmpty && context.selection.file) { - return !!(context.selection.file.entry && context.selection.file.entry.properties && context.selection.file.entry.properties['qshare:sharedId']); + return !!context.selection.file.entry?.properties?.['qshare:sharedId']; } return false; @@ -268,14 +268,7 @@ export const canCreateLibrary = (context: AcaRuleContext): boolean => * JSON ref: `app.navigation.folder.canUpload` */ export function canUpload(context: AcaRuleContext): boolean { - if (isContentServiceEnabled(context) && (navigation.isPersonalFiles(context) || navigation.isLibraryContent(context))) { - const { currentFolder } = context.navigation; - - if (currentFolder) { - return context.permissions.check(currentFolder, ['create']); - } - } - return false; + return canCreateFolder(context); } /** @@ -307,7 +300,7 @@ export const hasLibrarySelected = (context: RuleContext): boolean => !!context.s */ export function isPrivateLibrary(context: RuleContext): boolean { const library = context.selection.library; - return library ? !!(library.entry && library.entry.visibility && library.entry.visibility === 'PRIVATE') : false; + return library ? !!(library.entry?.visibility === 'PRIVATE') : false; } /** @@ -316,7 +309,7 @@ export function isPrivateLibrary(context: RuleContext): boolean { */ export function hasLibraryRole(context: RuleContext): boolean { const library = context.selection.library; - return library ? !!(library.entry && library.entry.role) : false; + return library ? !!library.entry?.role : false; } /** @@ -329,7 +322,7 @@ export const hasNoLibraryRole = (context: RuleContext): boolean => !hasLibraryRo * Checks if user has selected a file. * JSON ref: `app.selection.file` */ -export const hasFileSelected = (context: RuleContext): boolean => !!(context && context.selection && context.selection.file); +export const hasFileSelected = (context: RuleContext): boolean => !!context?.selection?.file; /** * Checks if user can update the first selected node. @@ -376,13 +369,13 @@ export function canUpdateSelectedFolder(context: RuleContext): boolean { * JSON ref: `app.selection.file.isLocked` */ export function hasLockedFiles(context: RuleContext): boolean { - if (context && context.selection && context.selection.nodes) { + if (context?.selection?.nodes) { return context.selection.nodes.some((node) => { if (!node.entry.isFile) { return false; } - return node.entry.isLocked || (node.entry.properties && node.entry.properties['cm:lockType'] === 'READ_ONLY_LOCK'); + return node.entry.isLocked || node.entry.properties?.['cm:lockType'] === 'READ_ONLY_LOCK'; }); } @@ -395,13 +388,8 @@ export function hasLockedFiles(context: RuleContext): boolean { */ export const isWriteLocked = (context: RuleContext): boolean => !!( - context && - context.selection && - context.selection.file && - context.selection.file.entry && - context.selection.file.entry.properties && - (context.selection.file.entry.properties['cm:lockType'] === 'WRITE_LOCK' || - context.selection.file.entry.properties['cm:lockType'] === 'READ_ONLY_LOCK') + context?.selection?.file?.entry?.properties?.['cm:lockType'] === 'WRITE_LOCK' || + context?.selection?.file?.entry?.properties?.['cm:lockType'] === 'READ_ONLY_LOCK' ); /** @@ -589,17 +577,17 @@ export function canOpenWithOffice(context: AcaRuleContext): boolean { return false; } - if (context.navigation && context.navigation.url && context.navigation.url.startsWith('/trashcan')) { + if (context.navigation?.url?.startsWith('/trashcan')) { return false; } - if (!context || !context.selection) { + if (!context?.selection) { return false; } const { file } = context.selection; - if (!file || !file.entry) { + if (!file?.entry) { return false; } @@ -626,7 +614,7 @@ export function canOpenWithOffice(context: AcaRuleContext): boolean { } // workaround for Shared files - if (context.navigation && context.navigation.url && context.navigation.url.startsWith('/shared')) { + if (context.navigation?.url?.startsWith('/shared')) { // eslint-disable-next-line no-prototype-builtins if (file.entry.hasOwnProperty('allowableOperationsOnTarget')) { return context.permissions.check(file, ['update'], { diff --git a/projects/aca-shared/rules/src/navigation.rules.ts b/projects/aca-shared/rules/src/navigation.rules.ts index 02d6a6df93..8a3abc762c 100644 --- a/projects/aca-shared/rules/src/navigation.rules.ts +++ b/projects/aca-shared/rules/src/navigation.rules.ts @@ -39,7 +39,7 @@ export function isPreview(context: RuleContext): boolean { */ export function isFavorites(context: RuleContext): boolean { const { url } = context.navigation; - return url && url.startsWith('/favorites') && !isPreview(context); + return url?.startsWith('/favorites') && !isPreview(context); } /** @@ -54,7 +54,7 @@ export const isNotFavorites = (context: RuleContext): boolean => !isFavorites(co */ export function isSharedFiles(context: RuleContext): boolean { const { url } = context.navigation; - return url && url.startsWith('/shared') && !isPreview(context); + return url?.startsWith('/shared') && !isPreview(context); } /** @@ -69,7 +69,7 @@ export const isNotSharedFiles = (context: RuleContext): boolean => !isSharedFile */ export function isTrashcan(context: RuleContext): boolean { const { url } = context.navigation; - return url && url.startsWith('/trashcan'); + return url?.startsWith('/trashcan'); } /** @@ -84,7 +84,7 @@ export const isNotTrashcan = (context: RuleContext): boolean => !isTrashcan(cont */ export function isPersonalFiles(context: RuleContext): boolean { const { url } = context.navigation; - return url && url.startsWith('/personal-files'); + return url?.startsWith('/personal-files'); } /** @@ -93,7 +93,7 @@ export function isPersonalFiles(context: RuleContext): boolean { */ export function isLibraryFiles(context: RuleContext): boolean { const { url } = context.navigation; - return url && url.startsWith('/libraries'); + return url?.startsWith('/libraries'); } /** @@ -102,12 +102,12 @@ export function isLibraryFiles(context: RuleContext): boolean { */ export function isLibraries(context: RuleContext): boolean { const { url } = context.navigation; - return url && (url.endsWith('/libraries') || url.startsWith('/search-libraries')); + return url?.endsWith('/libraries') || url?.startsWith('/search-libraries'); } export function isLibraryContent(context: RuleContext): boolean { const { url } = context.navigation; - return url && (url.endsWith('/libraries') || url.includes('/libraries/') || url.startsWith('/search-libraries')); + return url?.endsWith('/libraries') || url?.includes('/libraries/') || url?.startsWith('/search-libraries'); } /** @@ -122,7 +122,7 @@ export const isNotLibraries = (context: RuleContext): boolean => !isLibraries(co */ export function isRecentFiles(context: RuleContext): boolean { const { url } = context.navigation; - return url && url.startsWith('/recent-files'); + return url?.startsWith('/recent-files'); } /** @@ -140,7 +140,7 @@ export function isSearchResults( // ...args: RuleParameter[] ): boolean { const { url } = context.navigation; - return url && url.startsWith('/search'); + return url?.startsWith('/search'); } /** @@ -155,7 +155,7 @@ export const isNotSearchResults = (context: RuleContext): boolean => !isSearchRe */ export function isSharedPreview(context: RuleContext): boolean { const { url } = context.navigation; - return url && (url.startsWith('/shared/preview/') || (url.startsWith('/shared') && url.includes('viewer:view'))); + return url?.startsWith('/shared/preview/') || (url?.startsWith('/shared') && url?.includes('viewer:view')); } /** @@ -164,7 +164,7 @@ export function isSharedPreview(context: RuleContext): boolean { */ export function isFavoritesPreview(context: RuleContext): boolean { const { url } = context.navigation; - return url && (url.startsWith('/favorites/preview/') || (url.startsWith('/favorites') && url.includes('viewer:view'))); + return url?.startsWith('/favorites/preview/') || (url?.startsWith('/favorites') && url?.includes('viewer:view')); } /** @@ -173,5 +173,5 @@ export function isFavoritesPreview(context: RuleContext): boolean { */ export function isSharedFileViewer(context: RuleContext): boolean { const { url } = context.navigation; - return url && url.startsWith('/preview/s/'); + return url?.startsWith('/preview/s/'); } diff --git a/projects/aca-shared/src/lib/components/document-base-page/document-base-page.component.ts b/projects/aca-shared/src/lib/components/document-base-page/document-base-page.component.ts index 7c72919a75..baf04f2522 100644 --- a/projects/aca-shared/src/lib/components/document-base-page/document-base-page.component.ts +++ b/projects/aca-shared/src/lib/components/document-base-page/document-base-page.component.ts @@ -130,7 +130,7 @@ export abstract class PageComponent implements OnInit, OnDestroy, OnChanges { } ngOnChanges(changes: SimpleChanges) { - if (changes.nodeResult && changes.nodeResult.currentValue) { + if (changes.nodeResult?.currentValue) { this.nodeResult = changes.nodeResult.currentValue; } } @@ -145,7 +145,7 @@ export abstract class PageComponent implements OnInit, OnDestroy, OnChanges { } showPreview(node: NodeEntry, extras?: ViewNodeExtras) { - if (node && node.entry) { + if (node?.entry) { if (this.fileAutoDownloadService?.shouldFileAutoDownload(node.entry?.content?.sizeInBytes)) { this.fileAutoDownloadService.autoDownloadFile(node); } else { diff --git a/projects/aca-shared/src/lib/components/document-base-page/document-base-page.spec.ts b/projects/aca-shared/src/lib/components/document-base-page/document-base-page.spec.ts index bee443e72c..d6517af7d1 100644 --- a/projects/aca-shared/src/lib/components/document-base-page/document-base-page.spec.ts +++ b/projects/aca-shared/src/lib/components/document-base-page/document-base-page.spec.ts @@ -91,10 +91,6 @@ class DocumentBasePageServiceMock extends DocumentBasePageService { class TestComponent extends PageComponent { node: any; - constructor() { - super(); - } - addSubscription(entry: Subscription) { this.subscriptions.push(entry); } diff --git a/projects/aca-shared/src/lib/components/toolbar/toolbar-button/toolbar-button.component.ts b/projects/aca-shared/src/lib/components/toolbar/toolbar-button/toolbar-button.component.ts index e2d27cb6fb..c1cca81490 100644 --- a/projects/aca-shared/src/lib/components/toolbar/toolbar-button/toolbar-button.component.ts +++ b/projects/aca-shared/src/lib/components/toolbar/toolbar-button/toolbar-button.component.ts @@ -74,6 +74,6 @@ export class ToolbarButtonComponent { } private hasClickAction(actionRef: ContentActionRef): boolean { - return !!(actionRef && actionRef.actions && actionRef.actions.click); + return !!actionRef?.actions?.click; } } diff --git a/projects/aca-shared/src/lib/components/toolbar/toolbar-menu-item/toolbar-menu-item.component.ts b/projects/aca-shared/src/lib/components/toolbar/toolbar-menu-item/toolbar-menu-item.component.ts index 56b3845ec1..be244db81b 100644 --- a/projects/aca-shared/src/lib/components/toolbar/toolbar-menu-item/toolbar-menu-item.component.ts +++ b/projects/aca-shared/src/lib/components/toolbar/toolbar-menu-item/toolbar-menu-item.component.ts @@ -71,7 +71,7 @@ export class ToolbarMenuItemComponent { } private hasClickAction(actionRef: ContentActionRef): boolean { - return !!(actionRef && actionRef.actions && actionRef.actions.click); + return !!actionRef?.actions?.click; } trackByActionId(_: number, obj: ContentActionRef): string { diff --git a/projects/aca-shared/src/lib/directives/contextmenu/contextmenu.directive.ts b/projects/aca-shared/src/lib/directives/contextmenu/contextmenu.directive.ts index f61f5a7c16..5429de3d75 100644 --- a/projects/aca-shared/src/lib/directives/contextmenu/contextmenu.directive.ts +++ b/projects/aca-shared/src/lib/directives/contextmenu/contextmenu.directive.ts @@ -98,11 +98,9 @@ export class ContextActionsDirective implements OnInit, OnDestroy { } private findAncestor(el: Element, className: string): Element { - if (el.classList.contains(className)) { - return el; + while (el && !el.classList.contains(className)) { + el = el.parentElement; } - // eslint-disable-next-line curly - while ((el = el.parentElement) && !el.classList.contains(className)); return el; } } diff --git a/projects/aca-shared/src/lib/services/app.extension.service.ts b/projects/aca-shared/src/lib/services/app.extension.service.ts index 00e9e8ab8f..81c01e6a0c 100644 --- a/projects/aca-shared/src/lib/services/app.extension.service.ts +++ b/projects/aca-shared/src/lib/services/app.extension.service.ts @@ -180,7 +180,7 @@ export class AppExtensionService implements RuleContext { this.withCredentials = this.appConfig.get('auth.withCredentials', false); - if (config.features && config.features.viewer) { + if (config.features?.viewer) { this.viewerRules = (config.features.viewer['rules'] as ViewerRules) || {}; } @@ -340,7 +340,7 @@ export class AppExtensionService implements RuleContext { private setActionDisabledFromRule(action: ContentActionRef) { let disabled = false; - if (action && action.rules && action.rules.enabled) { + if (action?.rules?.enabled) { disabled = !this.extensions.evaluateRule(action.rules.enabled, this); } @@ -483,7 +483,7 @@ export class AppExtensionService implements RuleContext { } filterVisible(action: ContentActionRef | SettingsGroupRef | SidebarTabRef | DocumentListPresetRef): boolean { - if (action && action.rules && action.rules.visible) { + if (action?.rules?.visible) { return this.extensions.evaluateRule(action.rules.visible, this); } return true; @@ -495,7 +495,7 @@ export class AppExtensionService implements RuleContext { return true; } - if (extension.rules && extension.rules.disabled) { + if (extension.rules?.disabled) { return this.extensions.evaluateRule(extension.rules.disabled, this); } } diff --git a/projects/aca-shared/store/src/actions/router.actions.ts b/projects/aca-shared/store/src/actions/router.actions.ts index b56bf6b2a0..d79e0a8ad5 100644 --- a/projects/aca-shared/store/src/actions/router.actions.ts +++ b/projects/aca-shared/store/src/actions/router.actions.ts @@ -52,6 +52,4 @@ export class NavigateToParentFolder implements Action { export class NavigateToPreviousPage implements Action { readonly type = RouterActionTypes.NavigateToPreviousPage; - - constructor() {} } diff --git a/projects/aca-shared/store/src/actions/search.actions.ts b/projects/aca-shared/store/src/actions/search.actions.ts index bac13da10f..c7ad773bf0 100644 --- a/projects/aca-shared/store/src/actions/search.actions.ts +++ b/projects/aca-shared/store/src/actions/search.actions.ts @@ -32,7 +32,6 @@ export enum SearchActionTypes { export class SearchAction implements Action { readonly type = SearchActionTypes.Search; - constructor() {} } export class SearchByTermAction implements Action { diff --git a/projects/aca-shared/store/src/actions/template.actions.ts b/projects/aca-shared/store/src/actions/template.actions.ts index 79a1797edb..01e077d90e 100644 --- a/projects/aca-shared/store/src/actions/template.actions.ts +++ b/projects/aca-shared/store/src/actions/template.actions.ts @@ -28,14 +28,10 @@ import { TemplateActionTypes } from './template-action-types'; export class FileFromTemplate implements Action { readonly type = TemplateActionTypes.FileFromTemplate; - - constructor() {} } export class FolderFromTemplate implements Action { readonly type = TemplateActionTypes.FolderFromTemplate; - - constructor() {} } export class CreateFromTemplate implements Action { diff --git a/projects/aca-shared/store/src/effects/router.effects.ts b/projects/aca-shared/store/src/effects/router.effects.ts index c000c87dca..08f101a7ab 100644 --- a/projects/aca-shared/store/src/effects/router.effects.ts +++ b/projects/aca-shared/store/src/effects/router.effects.ts @@ -67,7 +67,7 @@ export class RouterEffects { this.actions$.pipe( ofType(RouterActionTypes.NavigateFolder), map((action) => { - if (action.payload && action.payload.entry) { + if (action.payload?.entry) { this.navigateToFolder(action.payload.entry); } }) @@ -80,7 +80,7 @@ export class RouterEffects { this.actions$.pipe( ofType(RouterActionTypes.NavigateParentFolder), map((action) => { - if (action.payload && action.payload.entry) { + if (action.payload?.entry) { this.navigateToParentFolder(action.payload.entry); } }) @@ -101,7 +101,7 @@ export class RouterEffects { let link: any[] = null; const { path, id } = node; - if (path && path.name && path.elements) { + if (path?.name && path?.elements) { const isLibraryPath = this.isLibraryContent(path); const parent = path.elements[path.elements.length - 1]; @@ -126,7 +126,7 @@ export class RouterEffects { let link: any[] = null; const { path } = node; - if (path && path.name && path.elements) { + if (path?.name && path?.elements) { const isLibraryPath = this.isLibraryContent(path); const parent = path.elements[path.elements.length - 1]; diff --git a/projects/aca-testing-shared/src/components/login/login.ts b/projects/aca-testing-shared/src/components/login/login.ts index dddb2df33a..0878f5debe 100755 --- a/projects/aca-testing-shared/src/components/login/login.ts +++ b/projects/aca-testing-shared/src/components/login/login.ts @@ -58,12 +58,7 @@ export class LoginComponent extends Component { const type = await this.passwordInput.getAttribute('type'); if (type === 'text') { return true; - } else { - if (type === 'password') { - return false; - } } - return false; } diff --git a/projects/aca-testing-shared/src/utilities/admin-actions.ts b/projects/aca-testing-shared/src/utilities/admin-actions.ts index 8ce6a74801..3c413b427a 100755 --- a/projects/aca-testing-shared/src/utilities/admin-actions.ts +++ b/projects/aca-testing-shared/src/utilities/admin-actions.ts @@ -28,10 +28,6 @@ import { UserActions } from './user-actions'; import { browser } from 'protractor'; export class AdminActions extends UserActions { - constructor() { - super(); - } - sites: SitesApi = new SitesApi(); upload: UploadApi = new UploadApi(); nodes: NodesApi = new NodesApi(); From 5505a17a734179480026361287274c4282af0a43 Mon Sep 17 00:00:00 2001 From: MichalKinas Date: Fri, 27 Oct 2023 15:53:15 +0200 Subject: [PATCH 6/9] Missing code smell fix --- projects/aca-shared/rules/src/app.rules.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/projects/aca-shared/rules/src/app.rules.ts b/projects/aca-shared/rules/src/app.rules.ts index a77daaad66..9659103723 100644 --- a/projects/aca-shared/rules/src/app.rules.ts +++ b/projects/aca-shared/rules/src/app.rules.ts @@ -299,8 +299,7 @@ export const hasLibrarySelected = (context: RuleContext): boolean => !!context.s * JSON ref: `app.selection.isPrivateLibrary` */ export function isPrivateLibrary(context: RuleContext): boolean { - const library = context.selection.library; - return library ? !!(library.entry?.visibility === 'PRIVATE') : false; + return context.selection.library?.entry?.visibility === 'PRIVATE'; } /** From 308f806e6cf46bdc7f6807b2013d07597efcefaf Mon Sep 17 00:00:00 2001 From: MichalKinas Date: Mon, 30 Oct 2023 11:48:15 +0100 Subject: [PATCH 7/9] Add new ESLint rules to cover fixed SonarCloud issues --- .eslintrc.json | 12 +++++++--- .../content-management.service.spec.ts | 2 +- .../services/content-management.service.ts | 24 +++++++++---------- 3 files changed, 22 insertions(+), 16 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 2049cce6dc..9c44ada551 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -113,7 +113,9 @@ "@angular-eslint/component-class-suffix": "error", "@angular-eslint/directive-class-suffix": "error", "@angular-eslint/no-conflicting-lifecycle": "error", - "@typescript-eslint/no-floating-promises": "off", + "@typescript-eslint/no-floating-promises": "warn", + "@typescript-eslint/no-misused-promises": "warn", + "@typescript-eslint/default-param-last": "warn", "@angular-eslint/no-input-rename": "error", "@angular-eslint/no-output-native": "error", "@angular-eslint/no-output-on-prefix": "error", @@ -122,7 +124,7 @@ "@angular-eslint/no-outputs-metadata-property": "error", "@angular-eslint/use-lifecycle-interface": "error", "@angular-eslint/use-pipe-transform-interface": "error", - "@typescript-eslint/prefer-optional-chain": "warn", + "@typescript-eslint/prefer-optional-chain": "error", "@typescript-eslint/no-misused-new": "error", "@typescript-eslint/no-non-null-assertion": "error", "@typescript-eslint/prefer-function-type": "error", @@ -204,6 +206,7 @@ "newline-per-chained-call": "off", "prefer-rest-params": "error", "prefer-spread": "error", + "prefer-promise-reject-errors": "error", "import/order": "off", "max-len": [ "error", @@ -226,6 +229,8 @@ "no-caller": "error", "no-global-assign": "error", "no-cond-assign": "error", + "no-constant-binary-expression": "error", + "no-useless-rename": "error", "no-console": [ "error", { @@ -324,7 +329,8 @@ { "files": ["*.spec.ts", "*.test.ts"], "rules": { - "@typescript-eslint/no-floating-promises": "off", + "@typescript-eslint/no-floating-promises": "warn", + "@typescript-eslint/no-misused-promises": "warn", "max-lines": "off" } } diff --git a/projects/aca-content/src/lib/services/content-management.service.spec.ts b/projects/aca-content/src/lib/services/content-management.service.spec.ts index 7ba86db38b..2f4484615a 100644 --- a/projects/aca-content/src/lib/services/content-management.service.spec.ts +++ b/projects/aca-content/src/lib/services/content-management.service.spec.ts @@ -1503,7 +1503,7 @@ describe('ContentManagementService', () => { })); it('should raise error when unlock node fails', fakeAsync(() => { - spyOn(contentApi, 'unlockNode').and.callFake(() => new Promise((_resolve, reject) => reject('error'))); + spyOn(contentApi, 'unlockNode').and.callFake(() => new Promise((_resolve, reject) => reject(new Error('error')))); spyOn(store, 'dispatch').and.callThrough(); store.dispatch(new UnlockWriteAction({ entry: { id: 'node-id', name: 'some-file' } })); tick(); diff --git a/projects/aca-content/src/lib/services/content-management.service.ts b/projects/aca-content/src/lib/services/content-management.service.ts index 48367d5bc9..6adb643ccb 100644 --- a/projects/aca-content/src/lib/services/content-management.service.ts +++ b/projects/aca-content/src/lib/services/content-management.service.ts @@ -122,7 +122,7 @@ export class ContentManagementService { } manageVersions(node: any, focusedElementOnCloseSelector?: string) { - if (node && node.entry) { + if (node?.entry) { // shared and favorite const id = node.entry.nodeId || (node as any).entry.guid; @@ -137,7 +137,7 @@ export class ContentManagementService { } manageAspects(node: any, focusedElementOnCloseSelector?: string) { - if (node && node.entry) { + if (node?.entry) { // shared and favorite const id = node.entry.nodeId || (node as any).entry.guid; @@ -174,7 +174,7 @@ export class ContentManagementService { } shareNode(node: any, focusedElementOnCloseSelector?: string): void { - if (node && node.entry) { + if (node?.entry) { // shared and favorite const id = node.entry.nodeId || (node as any).entry.guid; @@ -276,7 +276,7 @@ export class ContentManagementService { this.focusAfterClose(this.createMenuButtonSelector); }), map((node: SiteEntry) => { - if (node && node.entry && node.entry.guid) { + if (node?.entry?.guid) { return node.entry.guid; } return null; @@ -557,7 +557,7 @@ export class ContentManagementService { errorJson = JSON.parse(error.message); } catch {} - if (errorJson && errorJson.error && errorJson.error.statusCode === 403) { + if (errorJson?.error?.statusCode === 403) { i18nMessageString = 'APP.MESSAGES.ERRORS.PERMISSION'; } @@ -609,8 +609,8 @@ export class ContentManagementService { } private undoMoveNodes(moveResponse, selectionParentId: string) { - const movedNodes = moveResponse && moveResponse['succeeded'] ? moveResponse['succeeded'] : []; - const partiallyMovedNodes = moveResponse && moveResponse['partiallySucceeded'] ? moveResponse['partiallySucceeded'] : []; + const movedNodes = moveResponse?.['succeeded'] ?? []; + const partiallyMovedNodes = moveResponse?.['partiallySucceeded'] ?? []; const restoreDeletedNodesBatch = this.nodeActionsService.moveDeletedEntries.map((folderEntry) => this.contentApi.restoreNode(folderEntry.nodeId || folderEntry.id).pipe(map((node) => node.entry)) @@ -623,7 +623,7 @@ export class ContentManagementService { const revertMoveBatch = this.nodeActionsService .flatten(nodesToBeMovedBack) - .filter((node) => node.entry || (node.itemMoved && node.itemMoved.entry)) + .filter((node) => node.entry || node.itemMoved?.entry) .map((node) => { if (node.itemMoved) { return this.nodeActionsService.moveNodeAction(node.itemMoved.entry, node.initialParentId); @@ -647,7 +647,7 @@ export class ContentManagementService { errorJson = JSON.parse(error.message); } catch {} - if (errorJson && errorJson.error && errorJson.error.statusCode === 403) { + if (errorJson?.error?.statusCode === 403) { message = 'APP.MESSAGES.ERRORS.PERMISSION'; } @@ -1009,9 +1009,9 @@ export class ContentManagementService { } private showMoveMessage(nodes: Array, info: any, moveResponse?: any) { - const succeeded = moveResponse && moveResponse['succeeded'] ? moveResponse['succeeded'].length : 0; - const partiallySucceeded = moveResponse && moveResponse['partiallySucceeded'] ? moveResponse['partiallySucceeded'].length : 0; - const failures = moveResponse && moveResponse['failed'] ? moveResponse['failed'].length : 0; + const succeeded = moveResponse?.['succeeded'].length ?? 0; + const partiallySucceeded = moveResponse?.['partiallySucceeded'].length ?? 0; + const failures = moveResponse?.['failed'].length ?? 0; let successMessage = ''; let partialSuccessMessage = ''; From 4c9ab0df8e5555fa5ec718077b4d6a6e0adb4142 Mon Sep 17 00:00:00 2001 From: MichalKinas Date: Fri, 3 Nov 2023 09:34:33 +0100 Subject: [PATCH 8/9] Add missing command --- e2e/protractor/suites/actions/copy-move/copy.test.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/e2e/protractor/suites/actions/copy-move/copy.test.ts b/e2e/protractor/suites/actions/copy-move/copy.test.ts index 37ac716066..5959d8654a 100755 --- a/e2e/protractor/suites/actions/copy-move/copy.test.ts +++ b/e2e/protractor/suites/actions/copy-move/copy.test.ts @@ -254,6 +254,7 @@ describe('Copy content', () => { } await toolbar.clickMoreActionsCopy(); await copyDialog.selectLocation('Personal Files'); + await copyDialog.dataTable.doubleClickOnRowByName(source); await copyDialog.selectDestination(destination); await BrowserActions.click(copyDialog.copyButton); const msg = await page.getSnackBarMessage(); From 87bd5fd90d282ec6ad3b9521b36d2fd1a4616bd9 Mon Sep 17 00:00:00 2001 From: MichalKinas Date: Fri, 3 Nov 2023 10:22:14 +0100 Subject: [PATCH 9/9] Add missing is existing check --- .../suites/actions/copy-move/copy.test.ts | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/e2e/protractor/suites/actions/copy-move/copy.test.ts b/e2e/protractor/suites/actions/copy-move/copy.test.ts index 5959d8654a..7df99ba4cc 100755 --- a/e2e/protractor/suites/actions/copy-move/copy.test.ts +++ b/e2e/protractor/suites/actions/copy-move/copy.test.ts @@ -246,7 +246,14 @@ describe('Copy content', () => { undoCopyFolderWithExistingName(folderExisting, destinationPF)); }); - async function baseCopy(itemName: string | string[], location: string, destination: string, undo = false, expectedMsg = 'Copied 1 item') { + async function baseCopy( + itemName: string | string[], + location: string, + destination: string, + undo = false, + isExisting = false, + expectedMsg = 'Copied 1 item' + ) { if (itemName instanceof Array) { await dataTable.selectMultipleItems(itemName, location); } else { @@ -254,7 +261,9 @@ describe('Copy content', () => { } await toolbar.clickMoreActionsCopy(); await copyDialog.selectLocation('Personal Files'); - await copyDialog.dataTable.doubleClickOnRowByName(source); + if (isExisting) { + await copyDialog.dataTable.doubleClickOnRowByName(source); + } await copyDialog.selectDestination(destination); await BrowserActions.click(copyDialog.copyButton); const msg = await page.getSnackBarMessage(); @@ -280,7 +289,7 @@ describe('Copy content', () => { if (doBefore) { doBefore(); } - await baseCopy(itemName, location, destination, undo, expectedMsg); + await baseCopy(itemName, location, destination, undo, false, expectedMsg); } async function baseCopyDoBeforeAsync( @@ -289,12 +298,13 @@ describe('Copy content', () => { destination: string, doBefore?: () => Promise, undo?: boolean, + isExisting?: boolean, expectedMsg?: string ) { if (doBefore) { await doBefore(); } - await baseCopy(itemName, location, destination, undo, expectedMsg); + await baseCopy(itemName, location, destination, undo, isExisting, expectedMsg); } async function copyFile(fileName: string, destination: string, location = '', doBefore?: () => void) { @@ -426,7 +436,7 @@ describe('Copy content', () => { } async function undoCopyFileWithExistingName(fileName: string, destination: string, location = '', doBefore?: () => Promise) { - await baseCopyDoBeforeAsync(fileName, location, destination, doBefore, true); + await baseCopyDoBeforeAsync(fileName, location, destination, doBefore, true, true); await dataTable.doubleClickOnRowByName(source); await dataTable.doubleClickOnRowByName(folder2); expect(await dataTable.isItemPresent(fileInFolder2)).toBe(true, `${fileInFolder2} not present in ${destination} folder`);