mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2026-09-09 18:02:54 +00:00
[ACS-11612] helium ACA e2es updates (#5159)
* [ACS-11612] helium ACA e2es updates * [ACS-11612] helium testing week small tests fixes * [ACS-11612] copilot review 1 * [ACS-11612] sonar fix 2 * [ACS-11612] copilot review fix 2 * [ACS-11612] shared links api small fixes * [ACS-11612] sonar cloud fix 3 * [ACS-11612] fixed returns for promise<void> methods * [ACS-11612] eslint fix and added override-ci skip in yml
This commit is contained in:
@@ -109,6 +109,7 @@ jobs:
|
||||
run: npm run ci:test -- $TEST_OPTS
|
||||
|
||||
e2es-playwright:
|
||||
if: ${{ !contains(github.event.pull_request.labels.*.name, 'override-ci') }}
|
||||
needs: [lint, build, unit-tests]
|
||||
name: E2E | ${{ matrix.browser || 'chromium' }} | ${{ matrix.e2e-suites.name }} | Playwright
|
||||
runs-on: ubuntu-24.04
|
||||
@@ -256,6 +257,10 @@ jobs:
|
||||
}}
|
||||
run: exit 1
|
||||
|
||||
- name: Check e2e skipped
|
||||
if: ${{ contains(github.event.pull_request.labels.*.name, 'override-ci') }}
|
||||
run: echo "E2E tests were skipped due to override-ci label"
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
/*!
|
||||
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||
*
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* This file is part of the Alfresco Example Content Application.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { test } from '@alfresco/aca-playwright-shared';
|
||||
import { expect } from '@playwright/test';
|
||||
|
||||
export function favoritesTests(username: string) {
|
||||
test.describe('Pagination controls : ', () => {
|
||||
test.beforeEach(async ({ loginPage, favoritePage }) => {
|
||||
await loginPage.navigate();
|
||||
await loginPage.loginUser({ username: username, password: username });
|
||||
|
||||
await favoritePage.navigate();
|
||||
await favoritePage.waitForPageLoad();
|
||||
});
|
||||
|
||||
test('[XAT-4575] Pagination control default items', async ({ favoritePage }) => {
|
||||
expect(await favoritePage.pagination.getRange()).toContain('1-25 of 51');
|
||||
expect(await favoritePage.pagination.getMaxItems()).toContain('25');
|
||||
expect(await favoritePage.pagination.getCurrentPage()).toContain('Page 1');
|
||||
expect(await favoritePage.pagination.getTotalPages()).toContain('of 3');
|
||||
expect(await favoritePage.pagination.isPreviousEnabled()).toBe(false);
|
||||
expect(await favoritePage.pagination.isNextEnabled()).toBe(true);
|
||||
});
|
||||
|
||||
test('[XAT-4576] Items per page values', async ({ favoritePage }) => {
|
||||
await favoritePage.pagination.openMaxItemsMenu();
|
||||
expect(await favoritePage.pagination.getItemsCount()).toBe(3);
|
||||
await favoritePage.pagination.clickMenuItem('25');
|
||||
await favoritePage.dataTable.spinnerWaitForReload();
|
||||
expect(await favoritePage.pagination.getMaxItems()).toContain('25');
|
||||
expect(await favoritePage.pagination.getTotalPages()).toContain('of 3');
|
||||
|
||||
await favoritePage.pagination.openMaxItemsMenu();
|
||||
await favoritePage.pagination.clickMenuItem('50');
|
||||
await favoritePage.dataTable.spinnerWaitForReload();
|
||||
expect(await favoritePage.pagination.getMaxItems()).toContain('50');
|
||||
expect(await favoritePage.pagination.getTotalPages()).toContain('of 2');
|
||||
|
||||
await favoritePage.pagination.closeMenu();
|
||||
|
||||
await favoritePage.pagination.openMaxItemsMenu();
|
||||
await favoritePage.pagination.clickMenuItem('100');
|
||||
await favoritePage.dataTable.spinnerWaitForReload();
|
||||
expect(await favoritePage.pagination.getMaxItems()).toContain('100');
|
||||
expect(await favoritePage.pagination.getTotalPages()).toContain('of 1');
|
||||
|
||||
await favoritePage.pagination.resetToDefaultPageSize();
|
||||
});
|
||||
|
||||
test('[XAT-4578] Change the current page from the page selector', async ({ favoritePage }) => {
|
||||
await favoritePage.pagination.clickOnNextPage();
|
||||
expect(await favoritePage.pagination.getRange()).toContain('Showing 26-50 of 51');
|
||||
expect(await favoritePage.pagination.getCurrentPage()).toContain('Page 2');
|
||||
expect(await favoritePage.pagination.isPreviousEnabled()).toBe(true);
|
||||
expect(await favoritePage.pagination.isNextEnabled()).toBe(true);
|
||||
await favoritePage.pagination.resetToDefaultPageSize();
|
||||
});
|
||||
|
||||
test('[XAT-4580] Next and Previous buttons navigation', async ({ favoritePage }) => {
|
||||
await favoritePage.pagination.openMaxItemsMenu();
|
||||
await favoritePage.pagination.clickMenuItem('25');
|
||||
expect(await favoritePage.pagination.getMaxItems()).toContain('25');
|
||||
await favoritePage.pagination.clickOnNextPage();
|
||||
await favoritePage.dataTable.spinnerWaitForReload();
|
||||
expect(await favoritePage.pagination.getRange()).toContain('Showing 26-50 of 51');
|
||||
await favoritePage.pagination.clickOnPreviousPage();
|
||||
await favoritePage.dataTable.spinnerWaitForReload();
|
||||
expect(await favoritePage.pagination.getRange()).toContain('Showing 1-25 of 51');
|
||||
});
|
||||
|
||||
test('[XAT-4579] Next button is disabled on last page', async ({ favoritePage }) => {
|
||||
await favoritePage.pagination.openMaxItemsMenu();
|
||||
await favoritePage.pagination.clickNthItem(3);
|
||||
expect(await favoritePage.pagination.getCurrentPage()).toContain('Page 1');
|
||||
expect(await favoritePage.pagination.isNextEnabled()).toBe(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -22,9 +22,79 @@
|
||||
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { ApiClientFactory, FavoritesPageApi, NodesApi, test, timeouts, Utils, TrashcanApi } from '@alfresco/aca-playwright-shared';
|
||||
import { personalFilesTests } from './personal-files';
|
||||
import { favoritesTests } from './favorites';
|
||||
import {
|
||||
ApiClientFactory,
|
||||
DataTableComponent,
|
||||
FavoritesPageApi,
|
||||
NodesApi,
|
||||
PaginationComponent,
|
||||
SearchApi,
|
||||
test,
|
||||
timeouts,
|
||||
Utils,
|
||||
TrashcanApi
|
||||
} from '@alfresco/aca-playwright-shared';
|
||||
import { expect } from '@playwright/test';
|
||||
|
||||
async function assertDefaultPaginationState(pagination: PaginationComponent, range: string): Promise<void> {
|
||||
expect(await pagination.getRange()).toContain(range);
|
||||
expect(await pagination.getMaxItems()).toContain('25');
|
||||
expect(await pagination.getCurrentPage()).toContain('Page 1');
|
||||
expect(await pagination.getTotalPages()).toContain('of 3');
|
||||
expect(await pagination.isPreviousEnabled()).toBe(false);
|
||||
expect(await pagination.isNextEnabled()).toBe(true);
|
||||
}
|
||||
|
||||
async function assertItemsPerPage(pagination: PaginationComponent, dataTable: DataTableComponent): Promise<void> {
|
||||
await pagination.openMaxItemsMenu();
|
||||
expect(await pagination.getItemsCount()).toBe(3);
|
||||
await pagination.clickMenuItem('25');
|
||||
await dataTable.spinnerWaitForReload();
|
||||
expect(await pagination.getMaxItems()).toContain('25');
|
||||
expect(await pagination.getTotalPages()).toContain('of 3');
|
||||
|
||||
await pagination.openMaxItemsMenu();
|
||||
await pagination.clickMenuItem('50');
|
||||
await dataTable.spinnerWaitForReload();
|
||||
expect(await pagination.getMaxItems()).toContain('50');
|
||||
expect(await pagination.getTotalPages()).toContain('of 2');
|
||||
|
||||
await pagination.openMaxItemsMenu();
|
||||
await pagination.clickMenuItem('100');
|
||||
await dataTable.spinnerWaitForReload();
|
||||
expect(await pagination.getMaxItems()).toContain('100');
|
||||
expect(await pagination.getTotalPages()).toContain('of 1');
|
||||
|
||||
await pagination.resetToDefaultPageSize();
|
||||
}
|
||||
|
||||
async function assertNextPageNavigation(pagination: PaginationComponent): Promise<void> {
|
||||
await pagination.clickOnNextPage();
|
||||
expect(await pagination.getRange()).toContain('Showing 26-50 of 51');
|
||||
expect(await pagination.getCurrentPage()).toContain('Page 2');
|
||||
expect(await pagination.isPreviousEnabled()).toBe(true);
|
||||
expect(await pagination.isNextEnabled()).toBe(true);
|
||||
await pagination.resetToDefaultPageSize();
|
||||
}
|
||||
|
||||
async function assertNextPreviousNavigation(pagination: PaginationComponent, dataTable: DataTableComponent): Promise<void> {
|
||||
await pagination.openMaxItemsMenu();
|
||||
await pagination.clickMenuItem('25');
|
||||
expect(await pagination.getMaxItems()).toContain('25');
|
||||
await pagination.clickOnNextPage();
|
||||
await dataTable.spinnerWaitForReload();
|
||||
expect(await pagination.getRange()).toContain('Showing 26-50 of 51');
|
||||
await pagination.clickOnPreviousPage();
|
||||
await dataTable.spinnerWaitForReload();
|
||||
expect(await pagination.getRange()).toContain('Showing 1-25 of 51');
|
||||
}
|
||||
|
||||
async function assertNextButtonDisabledOnLastPage(pagination: PaginationComponent): Promise<void> {
|
||||
await pagination.openMaxItemsMenu();
|
||||
await pagination.clickNthItem(3);
|
||||
expect(await pagination.getCurrentPage()).toContain('Page 1');
|
||||
expect(await pagination.isNextEnabled()).toBe(false);
|
||||
}
|
||||
|
||||
test.describe('Pagination on multiple pages : ', () => {
|
||||
const random = Utils.random();
|
||||
@@ -32,9 +102,11 @@ test.describe('Pagination on multiple pages : ', () => {
|
||||
let nodesApi: NodesApi;
|
||||
let trashcanApi: TrashcanApi;
|
||||
let favoritesApi: FavoritesPageApi;
|
||||
let searchApi: SearchApi;
|
||||
|
||||
const parent = `parent-multi-${random}`;
|
||||
let initialFavoritesTotalItems: number;
|
||||
let parentId: string;
|
||||
let fileIds: string[];
|
||||
|
||||
const apiClientFactory = new ApiClientFactory();
|
||||
|
||||
@@ -43,17 +115,18 @@ test.describe('Pagination on multiple pages : ', () => {
|
||||
await apiClientFactory.setUpAcaBackend('admin');
|
||||
await apiClientFactory.createUser({ username });
|
||||
nodesApi = await NodesApi.initialize(username, username);
|
||||
trashcanApi = await TrashcanApi.initialize(username, username);
|
||||
favoritesApi = await FavoritesPageApi.initialize(username, username);
|
||||
searchApi = await SearchApi.initialize(username, username);
|
||||
|
||||
const files = Array(51)
|
||||
.fill('my-file')
|
||||
.map((name, index): string => `${name}-${index + 1}-${random}.txt`);
|
||||
|
||||
await nodesApi.createFolder(parent);
|
||||
const filesIds = (await nodesApi.createFiles(files, parent)).list.entries.map((entries) => entries.entry.id);
|
||||
initialFavoritesTotalItems = await favoritesApi.getFavoritesTotalItems(username);
|
||||
parentId = (await nodesApi.createFolder(parent)).entry.id;
|
||||
fileIds = (await nodesApi.createFiles(files, parent)).list?.entries?.map((entries) => entries.entry.id) ?? [];
|
||||
|
||||
await favoritesApi.addFavoritesByIds('file', filesIds);
|
||||
expect(fileIds).toHaveLength(51);
|
||||
});
|
||||
|
||||
test.afterAll(async () => {
|
||||
@@ -61,14 +134,80 @@ test.describe('Pagination on multiple pages : ', () => {
|
||||
});
|
||||
|
||||
test.describe('on Personal Files', () => {
|
||||
personalFilesTests(username, parent);
|
||||
test.beforeAll(async () => {
|
||||
await searchApi.waitForFolderPathIndexing(parentId, { nodesExpected: 51 });
|
||||
});
|
||||
|
||||
test.describe('Pagination controls : ', () => {
|
||||
test.beforeEach(async ({ loginPage, personalFiles, page }) => {
|
||||
await loginPage.navigate();
|
||||
await loginPage.loginUser({ username: username, password: username });
|
||||
await personalFiles.waitForPageLoad();
|
||||
await personalFiles.dataTable.getRowByName(parent).dblclick();
|
||||
await page.waitForTimeout(timeouts.tiny);
|
||||
});
|
||||
|
||||
test('[XAT-4530] Pagination control default items', async ({ personalFiles }) => {
|
||||
await assertDefaultPaginationState(personalFiles.pagination, 'Showing 1-25 of 51');
|
||||
});
|
||||
|
||||
test('[XAT-4531] Items per page values', async ({ personalFiles }) => {
|
||||
await assertItemsPerPage(personalFiles.pagination, personalFiles.dataTable);
|
||||
});
|
||||
|
||||
test('[XAT-4533] Change the current page from the page selector', async ({ personalFiles }) => {
|
||||
await assertNextPageNavigation(personalFiles.pagination);
|
||||
});
|
||||
|
||||
test('[XAT-4536] Next and Previous buttons navigation', async ({ personalFiles }) => {
|
||||
await assertNextPreviousNavigation(personalFiles.pagination, personalFiles.dataTable);
|
||||
});
|
||||
|
||||
test('[XAT-4534] Previous button is disabled on first page', async ({ personalFiles }) => {
|
||||
expect(await personalFiles.pagination.getCurrentPage()).toContain('Page 1');
|
||||
expect(await personalFiles.pagination.isPreviousEnabled()).toBe(false);
|
||||
});
|
||||
|
||||
test('[XAT-4535] Next button is disabled on last page', async ({ personalFiles }) => {
|
||||
await assertNextButtonDisabledOnLastPage(personalFiles.pagination);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('on Favorites', () => {
|
||||
test.beforeAll(async () => {
|
||||
const initialFavoritesTotalItems = await favoritesApi.getFavoritesTotalItems(username);
|
||||
await favoritesApi.addFavoritesByIds('file', fileIds);
|
||||
await favoritesApi.waitForApi(username, { expect: initialFavoritesTotalItems + 51 });
|
||||
});
|
||||
|
||||
favoritesTests(username);
|
||||
test.describe('Pagination controls : ', () => {
|
||||
test.beforeEach(async ({ loginPage, favoritePage }) => {
|
||||
await loginPage.navigate();
|
||||
await loginPage.loginUser({ username: username, password: username });
|
||||
await favoritePage.navigate();
|
||||
await favoritePage.waitForPageLoad();
|
||||
});
|
||||
|
||||
test('[XAT-4575] Pagination control default items', async ({ favoritePage }) => {
|
||||
await assertDefaultPaginationState(favoritePage.pagination, '1-25 of 51');
|
||||
});
|
||||
|
||||
test('[XAT-4576] Items per page values', async ({ favoritePage }) => {
|
||||
await assertItemsPerPage(favoritePage.pagination, favoritePage.dataTable);
|
||||
});
|
||||
|
||||
test('[XAT-4578] Change the current page from the page selector', async ({ favoritePage }) => {
|
||||
await assertNextPageNavigation(favoritePage.pagination);
|
||||
});
|
||||
|
||||
test('[XAT-4580] Next and Previous buttons navigation', async ({ favoritePage }) => {
|
||||
await assertNextPreviousNavigation(favoritePage.pagination, favoritePage.dataTable);
|
||||
});
|
||||
|
||||
test('[XAT-4579] Next button is disabled on last page', async ({ favoritePage }) => {
|
||||
await assertNextButtonDisabledOnLastPage(favoritePage.pagination);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
/*!
|
||||
* Copyright © 2005-2025 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||
*
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* This file is part of the Alfresco Example Content Application.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { test, timeouts } from '@alfresco/aca-playwright-shared';
|
||||
import { expect } from '@playwright/test';
|
||||
|
||||
export function personalFilesTests(userName: string, parentName: string) {
|
||||
test.describe('Pagination controls : ', () => {
|
||||
test.beforeEach(async ({ loginPage, personalFiles, page }) => {
|
||||
await loginPage.navigate();
|
||||
await loginPage.loginUser({ username: userName, password: userName });
|
||||
await personalFiles.waitForPageLoad();
|
||||
await personalFiles.dataTable.getRowByName(parentName).dblclick();
|
||||
await page.waitForTimeout(timeouts.tiny);
|
||||
});
|
||||
|
||||
test('[XAT-4530] Pagination control default items', async ({ personalFiles }) => {
|
||||
expect(await personalFiles.pagination.getRange()).toContain('Showing 1-25 of 51');
|
||||
expect(await personalFiles.pagination.getMaxItems()).toContain('25');
|
||||
expect(await personalFiles.pagination.getCurrentPage()).toContain('Page 1');
|
||||
expect(await personalFiles.pagination.getTotalPages()).toContain('of 3');
|
||||
expect(await personalFiles.pagination.isPreviousEnabled()).toBe(false);
|
||||
expect(await personalFiles.pagination.isNextEnabled()).toBe(true);
|
||||
});
|
||||
|
||||
test('[XAT-4531] Items per page values', async ({ personalFiles }) => {
|
||||
await personalFiles.pagination.openMaxItemsMenu();
|
||||
expect(await personalFiles.pagination.getItemsCount()).toBe(3);
|
||||
await personalFiles.pagination.clickMenuItem('25');
|
||||
await personalFiles.dataTable.spinnerWaitForReload();
|
||||
expect(await personalFiles.pagination.getMaxItems()).toContain('25');
|
||||
expect(await personalFiles.pagination.getTotalPages()).toContain('of 3');
|
||||
|
||||
await personalFiles.pagination.openMaxItemsMenu();
|
||||
await personalFiles.pagination.clickMenuItem('50');
|
||||
expect(await personalFiles.pagination.getMaxItems()).toContain('50');
|
||||
expect(await personalFiles.pagination.getTotalPages()).toContain('of 2');
|
||||
|
||||
await personalFiles.pagination.openMaxItemsMenu();
|
||||
await personalFiles.pagination.clickMenuItem('100');
|
||||
expect(await personalFiles.pagination.getMaxItems()).toContain('100');
|
||||
expect(await personalFiles.pagination.getTotalPages()).toContain('of 1');
|
||||
|
||||
await personalFiles.pagination.resetToDefaultPageSize();
|
||||
});
|
||||
|
||||
test('[XAT-4533] Change the current page from the page selector', async ({ personalFiles }) => {
|
||||
await personalFiles.pagination.clickOnNextPage();
|
||||
expect(await personalFiles.pagination.getRange()).toContain('Showing 26-50 of 51');
|
||||
expect(await personalFiles.pagination.getCurrentPage()).toContain('Page 2');
|
||||
expect(await personalFiles.pagination.isPreviousEnabled()).toBe(true);
|
||||
expect(await personalFiles.pagination.isNextEnabled()).toBe(true);
|
||||
await personalFiles.pagination.resetToDefaultPageSize();
|
||||
});
|
||||
|
||||
test('[XAT-4536] Next and Previous buttons navigation', async ({ personalFiles }) => {
|
||||
await personalFiles.pagination.openMaxItemsMenu();
|
||||
await personalFiles.pagination.clickMenuItem('25');
|
||||
expect(await personalFiles.pagination.getMaxItems()).toContain('25');
|
||||
await personalFiles.pagination.clickOnNextPage();
|
||||
await personalFiles.dataTable.spinnerWaitForReload();
|
||||
expect(await personalFiles.pagination.getRange()).toContain('Showing 26-50 of 51');
|
||||
await personalFiles.pagination.clickOnPreviousPage();
|
||||
await personalFiles.dataTable.spinnerWaitForReload();
|
||||
expect(await personalFiles.pagination.getRange()).toContain('Showing 1-25 of 51');
|
||||
});
|
||||
|
||||
test('[XAT-4534] Previous button is disabled on first page', async ({ personalFiles }) => {
|
||||
expect(await personalFiles.pagination.getCurrentPage()).toContain('Page 1');
|
||||
expect(await personalFiles.pagination.isPreviousEnabled()).toBe(false);
|
||||
});
|
||||
|
||||
test('[XAT-4535] Next button is disabled on last page', async ({ personalFiles }) => {
|
||||
await personalFiles.pagination.openMaxItemsMenu();
|
||||
await personalFiles.pagination.clickNthItem(3);
|
||||
expect(await personalFiles.pagination.getCurrentPage()).toContain('Page 1');
|
||||
expect(await personalFiles.pagination.isNextEnabled()).toBe(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -45,6 +45,7 @@ import {
|
||||
TagsApi
|
||||
} from '@alfresco/js-api';
|
||||
import { users } from '../base-config';
|
||||
import { logger } from '../utils';
|
||||
import { Person, PersonModel } from './people-api-models';
|
||||
|
||||
export interface AcaBackend {
|
||||
@@ -89,13 +90,9 @@ export class ApiClientFactory {
|
||||
public queriesApi: QueriesApi;
|
||||
public categoriesApi: CategoriesApi;
|
||||
public tagsApi: TagsApi;
|
||||
|
||||
constructor() {
|
||||
this.alfrescoApi = new AlfrescoApi(config);
|
||||
}
|
||||
|
||||
public async setUpAcaBackend(userName: string, password?: string): Promise<AcaBackend> {
|
||||
await this.login(userName, password);
|
||||
|
||||
this.sites = new SitesApi(this.alfrescoApi);
|
||||
this.upload = new UploadApi(this.alfrescoApi);
|
||||
this.nodes = new NodesApi(this.alfrescoApi);
|
||||
@@ -107,6 +104,7 @@ export class ApiClientFactory {
|
||||
this.search = new SearchApi(this.alfrescoApi);
|
||||
this.securityGroupsApi = new SecurityGroupsApi(this.alfrescoApi);
|
||||
this.securityMarksApi = new SecurityMarksApi(this.alfrescoApi);
|
||||
this.contentClient = new ContentClient(config, '/alfresco');
|
||||
this.share = new SharedlinksApi(this.alfrescoApi);
|
||||
this.favorites = new FavoritesApi(this.alfrescoApi);
|
||||
this.trashCan = new TrashcanApi(this.alfrescoApi);
|
||||
@@ -114,7 +112,10 @@ export class ApiClientFactory {
|
||||
this.queriesApi = new QueriesApi(this.alfrescoApi);
|
||||
this.categoriesApi = new CategoriesApi(this.alfrescoApi);
|
||||
this.tagsApi = new TagsApi(this.alfrescoApi);
|
||||
}
|
||||
|
||||
public async setUpAcaBackend(userName: string, password?: string): Promise<AcaBackend> {
|
||||
await this.login(userName, password);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -124,49 +125,55 @@ export class ApiClientFactory {
|
||||
}
|
||||
|
||||
async login(userName: string, password?: string) {
|
||||
const predefinedUserKey = Object.keys(users).find((user) => user === userName || users[user].username === userName);
|
||||
const predefinedUserKey = Object.keys(users).find(
|
||||
(userAlias) => userAlias === userName || users[userAlias as keyof typeof users].username === userName
|
||||
) as keyof typeof users | undefined;
|
||||
const userToLog = predefinedUserKey ? users[predefinedUserKey] : undefined;
|
||||
let e: any;
|
||||
|
||||
const user = userToLog?.username ?? userName;
|
||||
const userPassword = userToLog?.password ?? password;
|
||||
if (!userPassword) {
|
||||
throw new Error(`[API Client Factory] No password provided for user ${user}`);
|
||||
}
|
||||
try {
|
||||
e = await this.alfrescoApi.login(user, userPassword);
|
||||
await this.alfrescoApi.login(user, userPassword);
|
||||
} catch (error) {
|
||||
console.error(`[API Client Factory] Log in user ${user} failed ${e}`);
|
||||
logger.error(`[API Client Factory] Log in user ${user} failed ${error}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async loginUser(user: PersonModel) {
|
||||
let e: any;
|
||||
if (!user.username || !user.password) {
|
||||
throw new Error(`[API Client Factory] No username or password provided`);
|
||||
}
|
||||
try {
|
||||
e = await this.alfrescoApi.login(user.username, user.password);
|
||||
await this.alfrescoApi.login(user.username, user.password);
|
||||
} catch (error) {
|
||||
console.error(`[API Client Factory] Log in user ${user.username} failed ${e}`);
|
||||
logger.error(`[API Client Factory] Log in user ${user.username} failed ${error}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async createUser(user: PersonModel): Promise<PersonEntry> {
|
||||
async createUser(user: PersonModel): Promise<PersonEntry | null> {
|
||||
const person = new Person(user);
|
||||
const peopleApi = new PeopleApi(this.alfrescoApi);
|
||||
|
||||
try {
|
||||
return peopleApi.createPerson(person);
|
||||
return await peopleApi.createPerson(person);
|
||||
} catch (error) {
|
||||
console.error('[API Client Factory] createUser failed : ', error);
|
||||
logger.error(`[API Client Factory] createUser failed: ${error}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async changePassword(username: string, newPassword: string): Promise<PersonEntry> {
|
||||
async changePassword(username: string, newPassword: string): Promise<PersonEntry | null> {
|
||||
const peopleApi = new PeopleApi(this.alfrescoApi);
|
||||
|
||||
try {
|
||||
return peopleApi.updatePerson(username, { password: newPassword });
|
||||
return await peopleApi.updatePerson(username, { password: newPassword });
|
||||
} catch (error) {
|
||||
console.error('[API Client Factory] changePassword failed : ', error);
|
||||
logger.error(`[API Client Factory] changePassword failed: ${error}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
import { ApiClientFactory } from './api-client-factory';
|
||||
import { logger } from '../utils';
|
||||
import { CategoryEntry, CategoryBody, CategoryQuery, CategoryPaging, CategoryLinkBody } from '@alfresco/js-api';
|
||||
|
||||
export class CategoriesApi {
|
||||
@@ -42,21 +43,21 @@ export class CategoriesApi {
|
||||
try {
|
||||
return this.apiService.categoriesApi.createSubcategories(categoryId, categoryBodyCreate, opts);
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
logger.error(`${error}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async deleteCategory(categoryId: string): Promise<void> {
|
||||
if (categoryId === null) {
|
||||
console.error('categoryId is null, skipping deletion');
|
||||
async deleteCategory(categoryId?: string): Promise<void> {
|
||||
if (!categoryId) {
|
||||
logger.error('categoryId is null, skipping deletion');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
await this.apiService.categoriesApi.deleteCategory(categoryId);
|
||||
} catch (error) {
|
||||
console.error(`${this.constructor.name} ${this.deleteCategory.name}: ${error}`);
|
||||
logger.error(`${this.constructor.name} ${this.deleteCategory.name}: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,7 +69,7 @@ export class CategoriesApi {
|
||||
try {
|
||||
return this.apiService.categoriesApi.linkNodeToCategory(nodeId, categoryLinkBodyCreate, opts);
|
||||
} catch (error) {
|
||||
console.error(`${this.constructor.name} ${this.linkNodeToCategory.name}: ${error}`);
|
||||
logger.error(`${this.constructor.name} ${this.linkNodeToCategory.name}: ${error}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
import { ApiClientFactory } from './api-client-factory';
|
||||
import { FavoriteEntry, FavoritePaging } from '@alfresco/js-api';
|
||||
import { Utils } from '../utils';
|
||||
import { logger, Utils } from '../utils';
|
||||
|
||||
export class FavoritesPageApi {
|
||||
private readonly apiService: ApiClientFactory;
|
||||
@@ -124,7 +124,7 @@ export class FavoritesPageApi {
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('FavoritesApi: removeFavoritesByIds failed ', error);
|
||||
logger.error(`FavoritesApi: removeFavoritesByIds failed: ${error}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
import * as fs from 'fs';
|
||||
import { ApiClientFactory } from './api-client-factory';
|
||||
import { Utils, waitForApi } from '../utils';
|
||||
import { logger, Utils, waitForApi } from '../utils';
|
||||
import { NodeBodyCreate, NodeEntry, ResultSetPaging, SearchRequest } from '@alfresco/js-api';
|
||||
|
||||
export class FileActionsApi {
|
||||
@@ -161,7 +161,9 @@ export class FileActionsApi {
|
||||
await waitForApi(apiCall, predicate, 30, 2500);
|
||||
} catch {
|
||||
const actual = await apiCall();
|
||||
throw new Error(`waitForNodes: Timed out waiting for "${searchTerm}" — expected ${data.expect} nodes, found ${actual}`);
|
||||
const message = `waitForNodes: Timed out waiting for "${searchTerm}" — expected ${data.expect} nodes, found ${actual}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -208,16 +210,16 @@ export class FileActionsApi {
|
||||
try {
|
||||
return (await this.queryNodesSearchHighlight(searchTerm)).list.pagination.totalItems;
|
||||
} catch (error) {
|
||||
console.warn(`queryNodesSearchHighlight failed for "${searchTerm}":`, error);
|
||||
logger.warn(`queryNodesSearchHighlight failed for "${searchTerm}": ${error}`);
|
||||
return 0;
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
await waitForApi(apiCall, predicate, 30, 2500);
|
||||
console.log(`waitForNodesSearchHighlight: Found ${data.expect} nodes with search term "${searchTerm}"`);
|
||||
logger.log(`waitForNodesSearchHighlight: Found ${data.expect} nodes with search term "${searchTerm}"`);
|
||||
} catch (error) {
|
||||
console.error(`Error: ${error}`);
|
||||
logger.error(`Error: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,9 +230,9 @@ export class FileActionsApi {
|
||||
comment: comment,
|
||||
name: newName
|
||||
};
|
||||
return this.apiService.nodes.updateNodeContent(nodeId, content, opts);
|
||||
return await this.apiService.nodes.updateNodeContent(nodeId, content, opts);
|
||||
} catch (error) {
|
||||
console.error(`${this.constructor.name} ${this.updateNodeContent.name}`, error);
|
||||
logger.error(`${this.constructor.name} ${this.updateNodeContent.name}: ${error}`);
|
||||
return Promise.reject(error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
import { ApiClientFactory } from './api-client-factory';
|
||||
import { NodeChildAssociationPaging, NodeEntry, NodePaging, NodesIncludeQuery, NodeBodyUpdate } from '@alfresco/js-api';
|
||||
import { NodeContentTree, flattenNodeContentTree } from './node-content-tree';
|
||||
import { Utils } from '../utils';
|
||||
import { logger, Utils } from '../utils';
|
||||
|
||||
export class NodesApi {
|
||||
private readonly apiService: ApiClientFactory;
|
||||
@@ -51,7 +51,9 @@ export class NodesApi {
|
||||
try {
|
||||
return await this.createNode('cm:folder', name, parentId, title, description, null, author, true, aspectNames);
|
||||
} catch (error) {
|
||||
throw new Error(`${this.constructor.name} ${this.createFolder.name}: ${error}`);
|
||||
const message = `${this.constructor.name} ${this.createFolder.name}: ${error}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +69,9 @@ export class NodesApi {
|
||||
try {
|
||||
return await this.createNode('cm:content', name, parentId, title, description, null, author, majorVersion, aspectNames);
|
||||
} catch (error) {
|
||||
throw new Error(`${this.constructor.name} ${this.createFile.name}: ${error}`);
|
||||
const message = `${this.constructor.name} ${this.createFile.name}: ${error}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,7 +79,9 @@ export class NodesApi {
|
||||
try {
|
||||
return await this.createContent({ files: names }, relativePath);
|
||||
} catch (error) {
|
||||
throw new Error(`${this.constructor.name} ${this.createFiles.name}: ${error}`);
|
||||
const message = `${this.constructor.name} ${this.createFiles.name}: ${error}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,6 +93,9 @@ export class NodesApi {
|
||||
createdFiles.push(file);
|
||||
}
|
||||
}
|
||||
logger.info(
|
||||
`${this.constructor.name} ${this.createMultipleFiles.name}: created ${createdFiles.length} of ${count} files in parent "${parentId}"`
|
||||
);
|
||||
return createdFiles;
|
||||
}
|
||||
|
||||
@@ -94,7 +103,9 @@ export class NodesApi {
|
||||
try {
|
||||
return await this.createContent({ folders: names }, relativePath);
|
||||
} catch (error) {
|
||||
throw new Error(`${this.constructor.name} ${this.createFolders.name}: ${error}`);
|
||||
const message = `${this.constructor.name} ${this.createFolders.name}: ${error}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,7 +113,7 @@ export class NodesApi {
|
||||
try {
|
||||
await this.apiService.trashCan.deleteDeletedNode(name);
|
||||
} catch (error) {
|
||||
console.error(`${this.constructor.name} ${this.deleteDeletedNode.name}: ${error}`);
|
||||
logger.error(`${this.constructor.name} ${this.deleteDeletedNode.name}: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,11 +144,13 @@ export class NodesApi {
|
||||
}
|
||||
|
||||
try {
|
||||
return this.apiService.nodes.createNode(parentId, nodeBody, {
|
||||
return await this.apiService.nodes.createNode(parentId, nodeBody, {
|
||||
majorVersion
|
||||
});
|
||||
} catch (error) {
|
||||
throw new Error(`${this.constructor.name} ${this.createNode.name}: ${error}`);
|
||||
const message = `${this.constructor.name} ${this.createNode.name}: ${error}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,7 +158,7 @@ export class NodesApi {
|
||||
try {
|
||||
return this.apiService.nodes.updateNode(nodeId, { name: newName });
|
||||
} catch (error) {
|
||||
console.error(`${this.constructor.name} ${this.renameNode.name}`, error);
|
||||
logger.error(`${this.constructor.name} ${this.renameNode.name}: ${error}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -159,7 +172,7 @@ export class NodesApi {
|
||||
try {
|
||||
await this.apiService.nodes.deleteNodes(nodeIds, { permanent });
|
||||
} catch (error) {
|
||||
console.error(`${this.constructor.name} ${this.deleteNodes.name}`, error);
|
||||
logger.error(`${this.constructor.name} ${this.deleteNodes.name}: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,7 +180,7 @@ export class NodesApi {
|
||||
try {
|
||||
return await this.apiService.nodes.updateNode(nodeId, nodeBodyUpdate, opts);
|
||||
} catch (error) {
|
||||
console.error(`${this.constructor.name} ${this.updateNode.name}`, error);
|
||||
logger.error(`${this.constructor.name} ${this.updateNode.name}: ${error}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -182,7 +195,7 @@ export class NodesApi {
|
||||
const userNodesIds = userNodes.map((nodeChild) => nodeChild.entry.id);
|
||||
await this.deleteNodes(userNodesIds);
|
||||
} catch (error) {
|
||||
console.error(`${this.constructor.name} ${this.deleteCurrentUserNodes.name}`, error);
|
||||
logger.error(`${this.constructor.name} ${this.deleteCurrentUserNodes.name}: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,7 +205,7 @@ export class NodesApi {
|
||||
await this.apiService.nodes.lockNode(nodeId, { type: lockType });
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`${this.constructor.name} ${this.lockNodes.name}`, error);
|
||||
logger.error(`${this.constructor.name} ${this.lockNodes.name}: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -202,7 +215,7 @@ export class NodesApi {
|
||||
await this.apiService.nodes.unlockNode(nodeId);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`${this.constructor.name} ${this.unlockNodes.name}`, error);
|
||||
logger.error(`${this.constructor.name} ${this.unlockNodes.name}: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,7 +223,9 @@ export class NodesApi {
|
||||
try {
|
||||
return this.apiService.nodes.createNode('-my-', flattenNodeContentTree(content, relativePath) as any);
|
||||
} catch (error) {
|
||||
throw new Error(`${this.constructor.name} ${this.createContent.name}: ${error}`);
|
||||
const message = `${this.constructor.name} ${this.createContent.name}: ${error}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,7 +233,9 @@ export class NodesApi {
|
||||
try {
|
||||
return this.apiService.nodes.getNode(id);
|
||||
} catch (error) {
|
||||
throw new Error(`${this.constructor.name} ${this.getNodeById.name}: ${error}`);
|
||||
const message = `${this.constructor.name} ${this.getNodeById.name}: ${error}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,7 +244,7 @@ export class NodesApi {
|
||||
const children = (await this.getNodeChildren(parentId))?.list?.entries ?? [];
|
||||
return children.find((elem) => elem.entry.name === name)?.entry.id ?? '';
|
||||
} catch (error) {
|
||||
console.error(`${this.constructor.name} ${this.getNodeIdFromParent.name}`, error);
|
||||
logger.error(`${this.constructor.name} ${this.getNodeIdFromParent.name}: ${error}`);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
@@ -239,7 +256,7 @@ export class NodesApi {
|
||||
};
|
||||
return this.apiService.nodes.listNodeChildren(nodeId, opts);
|
||||
} catch (error) {
|
||||
console.error(`${this.constructor.name} ${this.getNodeChildren.name}`, error);
|
||||
logger.error(`${this.constructor.name} ${this.getNodeChildren.name}: ${error}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -248,7 +265,7 @@ export class NodesApi {
|
||||
try {
|
||||
await this.apiService.nodes.deleteNode(id, { permanent });
|
||||
} catch (error) {
|
||||
console.error(`${this.constructor.name} ${this.deleteNodeById.name}`, error);
|
||||
logger.error(`${this.constructor.name} ${this.deleteNodeById.name}: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -260,7 +277,7 @@ export class NodesApi {
|
||||
await this.deleteNodeById(nodeId);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Admin Actions - cleanupNodeTemplatesItems failed : ', error);
|
||||
logger.error(`Admin Actions - cleanupNodeTemplatesItems failed: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,7 +289,7 @@ export class NodesApi {
|
||||
await this.deleteNodeById(nodeId);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Admin Actions - cleanupSpaceTemplatesFolder failed : ', error);
|
||||
logger.error(`Admin Actions - cleanupSpaceTemplatesFolder failed: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -280,7 +297,7 @@ export class NodesApi {
|
||||
try {
|
||||
return this.getNodeIdFromParent('Node Templates', await this.getDataDictionaryId());
|
||||
} catch (error) {
|
||||
console.error('Admin Actions - getNodeTemplatesFolderId failed : ', error);
|
||||
logger.error(`Admin Actions - getNodeTemplatesFolderId failed: ${error}`);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
@@ -289,14 +306,14 @@ export class NodesApi {
|
||||
try {
|
||||
return this.getNodeIdFromParent('Space Templates', await this.getDataDictionaryId());
|
||||
} catch (error) {
|
||||
console.error('Admin Actions - getSpaceTemplatesFolderId failed : ', error);
|
||||
logger.error(`Admin Actions - getSpaceTemplatesFolderId failed: ${error}`);
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
private async getDataDictionaryId(): Promise<string> {
|
||||
return this.getNodeIdFromParent('Data Dictionary', '-root-').catch((error) => {
|
||||
console.error('Admin Actions - getDataDictionaryId failed : ', error);
|
||||
logger.error(`Admin Actions - getDataDictionaryId failed: ${error}`);
|
||||
return '';
|
||||
});
|
||||
}
|
||||
@@ -317,7 +334,7 @@ export class NodesApi {
|
||||
try {
|
||||
return this.apiService.nodes.updateNode(nodeId, data);
|
||||
} catch (error) {
|
||||
console.error(`${this.constructor.name} ${this.setGranularPermission.name}`, error);
|
||||
logger.error(`${this.constructor.name} ${this.setGranularPermission.name}: ${error}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -329,7 +346,7 @@ export class NodesApi {
|
||||
|
||||
return this.setInheritPermissions(nodeId, false);
|
||||
} catch (error) {
|
||||
console.error('Admin Actions - removeUserAccessOnNodeTemplate failed : ', error);
|
||||
logger.error(`Admin Actions - removeUserAccessOnNodeTemplate failed: ${error}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -341,7 +358,7 @@ export class NodesApi {
|
||||
|
||||
return this.setInheritPermissions(nodeId, false);
|
||||
} catch (error) {
|
||||
console.error('Admin Actions - removeUserAccessOnSpaceTemplate failed : ', error);
|
||||
logger.error(`Admin Actions - removeUserAccessOnSpaceTemplate failed: ${error}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -356,7 +373,7 @@ export class NodesApi {
|
||||
try {
|
||||
return this.apiService.nodes.updateNode(nodeId, data);
|
||||
} catch (error) {
|
||||
console.error(`${this.constructor.name} ${this.setInheritPermissions.name}`, error);
|
||||
logger.error(`${this.constructor.name} ${this.setInheritPermissions.name}: ${error}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -365,7 +382,7 @@ export class NodesApi {
|
||||
try {
|
||||
return this.apiService.nodes.updateNode(nodeId, { aspectNames });
|
||||
} catch (error) {
|
||||
console.error(`${this.constructor.name} ${this.addAspects.name}`, error);
|
||||
logger.error(`${this.constructor.name} ${this.addAspects.name}: ${error}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -385,7 +402,7 @@ export class NodesApi {
|
||||
await this.addAspects(originalNodeId, ['app:linked']);
|
||||
return link;
|
||||
} catch (error) {
|
||||
console.error(`${this.constructor.name} ${this.createFileLink.name}`, error);
|
||||
logger.error(`${this.constructor.name} ${this.createFileLink.name}: ${error}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -408,7 +425,7 @@ export class NodesApi {
|
||||
await this.addAspects(originalNodeId, ['app:linked']);
|
||||
return link;
|
||||
} catch (error) {
|
||||
console.error(`${this.constructor.name} ${this.createFolderLink.name}`, error);
|
||||
logger.error(`${this.constructor.name} ${this.createFolderLink.name}: ${error}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -421,7 +438,9 @@ export class NodesApi {
|
||||
|
||||
return this.createFileLink(nodeId, destinationParentId);
|
||||
} catch (error) {
|
||||
throw new Error(`Admin Actions - createLinkToFileName failed : ${error}`);
|
||||
const message = `Admin Actions - createLinkToFileName failed : ${error}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -432,7 +451,9 @@ export class NodesApi {
|
||||
const nodeId = await this.getNodeIdFromParent(originalFolderName, originalFolderParentId);
|
||||
return this.createFolderLink(nodeId, destinationParentId);
|
||||
} catch (error) {
|
||||
throw new Error(`Admin Actions - createLinkToFolderName failed : ${error}`);
|
||||
const message = `Admin Actions - createLinkToFolderName failed : ${error}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -441,7 +462,9 @@ export class NodesApi {
|
||||
const node = await this.getNodeById(nodeId);
|
||||
return node.entry.properties?.[property] ?? '';
|
||||
} catch (error) {
|
||||
throw new Error(`${this.constructor.name} ${this.getNodeProperty.name}: ${error}`);
|
||||
const message = `${this.constructor.name} ${this.getNodeProperty.name}: ${error}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -450,7 +473,9 @@ export class NodesApi {
|
||||
const sharedId = await this.getNodeProperty(nodeId, 'qshare:sharedId');
|
||||
return sharedId !== '';
|
||||
} catch (error) {
|
||||
throw new Error(`${this.constructor.name} ${this.isFileShared.name}: ${error}`);
|
||||
const message = `${this.constructor.name} ${this.isFileShared.name}: ${error}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -459,7 +484,9 @@ export class NodesApi {
|
||||
const lockType = await this.getNodeProperty(nodeId, 'cm:lockType');
|
||||
return lockType || '';
|
||||
} catch (error) {
|
||||
throw new Error(`${this.constructor.name} ${this.getLockType.name}: ${error}`);
|
||||
const message = `${this.constructor.name} ${this.getLockType.name}: ${error}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -467,7 +494,9 @@ export class NodesApi {
|
||||
try {
|
||||
return (await this.getLockType(nodeId)) === 'WRITE_LOCK';
|
||||
} catch (error) {
|
||||
throw new Error(`${this.constructor.name} ${this.isFileLockedWrite.name}: ${error}`);
|
||||
const message = `${this.constructor.name} ${this.isFileLockedWrite.name}: ${error}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
import { FindQuery } from '@alfresco/js-api';
|
||||
import { Utils } from '../utils';
|
||||
import { logger, Utils } from '../utils';
|
||||
import { ApiClientFactory } from './api-client-factory';
|
||||
|
||||
export class QueriesApi {
|
||||
@@ -52,8 +52,7 @@ export class QueriesApi {
|
||||
|
||||
return await Utils.retryCall(sites);
|
||||
} catch (error) {
|
||||
console.error(`QueriesApi waitForSites : catch : `);
|
||||
console.error(`\tExpected: ${data.expect} items, but found ${error}`);
|
||||
logger.error(`QueriesApi waitForSites : catch : Expected: ${data.expect} items, but found ${error}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -68,7 +67,7 @@ export class QueriesApi {
|
||||
const sites = await this.apiService.queries.findSites(searchTerm, opts);
|
||||
return sites.list.pagination.totalItems;
|
||||
} catch (error) {
|
||||
console.error(`QueriesApi findSitesTotalItems : catch :`, error);
|
||||
logger.error(`QueriesApi findSitesTotalItems : catch : ${error}`);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
import { ApiClientFactory } from './api-client-factory';
|
||||
import { Utils } from '../utils';
|
||||
import { logger, Utils } from '../utils';
|
||||
import { ResultSetPaging, SearchRequest } from '@alfresco/js-api';
|
||||
|
||||
export class SearchApi {
|
||||
@@ -59,7 +59,7 @@ export class SearchApi {
|
||||
}
|
||||
|
||||
async getTotalItems(username: string): Promise<number> {
|
||||
return (await this.querySearchFiles(username)).list.pagination.totalItems;
|
||||
return (await this.querySearchFiles(username)).list?.pagination?.totalItems ?? 0;
|
||||
}
|
||||
|
||||
async waitForApi(username: string, data: { expect: number }) {
|
||||
@@ -92,29 +92,31 @@ export class SearchApi {
|
||||
|
||||
do {
|
||||
result = await this.apiService.search.search(query);
|
||||
const currentCount = result.list.pagination.count;
|
||||
const currentCount = result.list?.pagination?.count ?? 0;
|
||||
|
||||
if (currentCount !== options.nodesExpected) {
|
||||
retryCount++;
|
||||
|
||||
if (retryCount % 30 === 0) {
|
||||
console.info(
|
||||
logger.info(
|
||||
`waitForFolderPathIndexing: After ${retryCount} seconds, expected ${options.nodesExpected} nodes but found ${currentCount} in folder ${folderId}`
|
||||
);
|
||||
}
|
||||
|
||||
if (retryCount >= retryLimit) {
|
||||
throw new Error(`Expected ${options.nodesExpected} nodes but found ${currentCount} after ${retryLimit} retries`);
|
||||
const message = `Expected ${options.nodesExpected} nodes but found ${currentCount} after ${retryLimit} retries`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
await Utils.delayInSeconds(1);
|
||||
}
|
||||
} while (result.list.pagination.count !== options.nodesExpected);
|
||||
} while (result.list?.pagination?.count !== options.nodesExpected);
|
||||
|
||||
console.info(`waitForFolderPathIndexing: Found expected ${options.nodesExpected} nodes in folder ${folderId}`);
|
||||
return result.list.pagination.count;
|
||||
logger.info(`waitForFolderPathIndexing: Found expected ${options.nodesExpected} nodes in folder ${folderId}`);
|
||||
return result.list?.pagination?.count ?? 0;
|
||||
} catch (error) {
|
||||
console.error(`waitForFolderPathIndexing failed for folderId "${folderId}": ${error}`);
|
||||
logger.error(`waitForFolderPathIndexing failed for folderId "${folderId}": ${error}`);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
import { ApiClientFactory } from './api-client-factory';
|
||||
import { SharedLinkEntry, SharedLinkPaging } from '@alfresco/js-api';
|
||||
import { Utils } from '../utils';
|
||||
import { logger, Utils } from '../utils';
|
||||
|
||||
export class SharedLinksApi {
|
||||
private readonly apiService: ApiClientFactory;
|
||||
@@ -44,7 +44,7 @@ export class SharedLinksApi {
|
||||
nodeId: id,
|
||||
expiresAt: expireDate
|
||||
};
|
||||
return this.apiService.share.createSharedLink(data);
|
||||
return await this.apiService.share.createSharedLink(data);
|
||||
} catch (error) {
|
||||
return null;
|
||||
}
|
||||
@@ -56,11 +56,13 @@ export class SharedLinksApi {
|
||||
if (ids && ids.length > 0) {
|
||||
for (const id of ids) {
|
||||
const sharedLink = await this.shareFileById(id, expireDate);
|
||||
sharedLinks.push(sharedLink);
|
||||
if (sharedLink) {
|
||||
sharedLinks.push(sharedLink);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`SharedLinksApi shareFilesByIds : catch : `, error);
|
||||
logger.error(`SharedLinksApi shareFilesByIds : catch : ${error}`);
|
||||
}
|
||||
return sharedLinks;
|
||||
}
|
||||
@@ -70,72 +72,68 @@ export class SharedLinksApi {
|
||||
const opts = {
|
||||
maxItems
|
||||
};
|
||||
return this.apiService.share.listSharedLinks(opts);
|
||||
return await this.apiService.share.listSharedLinks(opts);
|
||||
} catch (error) {
|
||||
console.error(`SharedLinksApi getSharedLinks : catch : `, error);
|
||||
logger.error(`SharedLinksApi getSharedLinks : catch : ${error}`);
|
||||
return new SharedLinkPaging();
|
||||
}
|
||||
}
|
||||
|
||||
async waitForFilesToBeShared(filesIds: string[]): Promise<void> {
|
||||
async waitForFilesToBeShared(fileIds: string[]): Promise<void> {
|
||||
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 sharedFiles = (await this.getSharedLinks()).list?.entries?.map((link) => link.entry.nodeId) ?? [];
|
||||
const foundItems = fileIds.every((id) => sharedFiles.includes(id));
|
||||
if (!foundItems) {
|
||||
const message = 'Not all files are shared yet';
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
};
|
||||
|
||||
return await Utils.retryCall(sharedFile);
|
||||
await Utils.retryCall(sharedFile);
|
||||
} catch (error) {
|
||||
console.error(`SharedLinksApi waitForFilesToBeShared : catch : ${error}`);
|
||||
console.error(`\tWait timeout reached waiting for files to be shared`);
|
||||
logger.error(`SharedLinksApi waitForFilesToBeShared : catch : ${error} - Wait timeout reached waiting for files to be shared`);
|
||||
}
|
||||
}
|
||||
|
||||
private async getSharedIdOfNode(fileId: string): Promise<string> {
|
||||
try {
|
||||
const sharedLinksEntries = (await this.getSharedLinks())?.list.entries;
|
||||
const found = sharedLinksEntries.find((sharedLink) => sharedLink.entry.nodeId === fileId);
|
||||
return found?.entry.id;
|
||||
} catch (error) {
|
||||
console.error(`SharedLinksApi getSharedIdOfNode : catch : `, error);
|
||||
return null;
|
||||
const sharedLinksEntries = (await this.getSharedLinks())?.list?.entries ?? [];
|
||||
const found = sharedLinksEntries.find((sharedLink) => sharedLink.entry.nodeId === fileId);
|
||||
if (!found?.entry.id) {
|
||||
const message = `SharedLinksApi getSharedIdOfNode: no shared link found for node ${fileId}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
return found.entry.id;
|
||||
}
|
||||
|
||||
async unshareFileById(fileId: string): Promise<void> {
|
||||
try {
|
||||
const sharedId = await this.getSharedIdOfNode(fileId);
|
||||
return this.apiService.share.deleteSharedLink(sharedId);
|
||||
await this.apiService.share.deleteSharedLink(sharedId);
|
||||
} catch (error) {
|
||||
console.error(`SharedLinksApi unshareFileById : catch : `, error);
|
||||
logger.error(`SharedLinksApi unshareFileById : catch : ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
async waitForFilesToNotBeShared(filesIds: string[]): Promise<any> {
|
||||
async waitForFilesToNotBeShared(fileIds: string[]): Promise<void> {
|
||||
try {
|
||||
const sharedFile = async () => {
|
||||
const sharedFiles = (await this.getSharedLinks()).list.entries.map((link) => link.entry.nodeId);
|
||||
const sharedFiles = (await this.getSharedLinks()).list?.entries?.map((link) => link.entry.nodeId) ?? [];
|
||||
|
||||
const foundItems = filesIds.some((id) => {
|
||||
return sharedFiles.includes(id);
|
||||
});
|
||||
const foundItems = fileIds.some((id) => sharedFiles.includes(id));
|
||||
|
||||
if (foundItems) {
|
||||
return Promise.reject(foundItems);
|
||||
} else {
|
||||
return Promise.resolve(foundItems);
|
||||
const message = 'Some files are still shared';
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
};
|
||||
|
||||
return await Utils.retryCall(sharedFile);
|
||||
await Utils.retryCall(sharedFile);
|
||||
} catch (error) {
|
||||
console.error(`SharedLinksApi waitForFilesToNotBeShared : catch : ${error}`);
|
||||
console.error(`\tWait timeout reached waiting for files to no longer be shared`);
|
||||
logger.error(`SharedLinksApi waitForFilesToNotBeShared : catch : ${error} - Wait timeout reached waiting for files to no longer be shared`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
import { ApiClientFactory } from './api-client-factory';
|
||||
import { logger } from '../utils';
|
||||
import {
|
||||
Site,
|
||||
SiteBodyCreate,
|
||||
@@ -55,9 +56,11 @@ export class SitesApi {
|
||||
} as SiteBodyCreate;
|
||||
|
||||
try {
|
||||
return this.apiService.sites.createSite(site);
|
||||
return await this.apiService.sites.createSite(site);
|
||||
} catch (error) {
|
||||
throw new Error(`SitesApi ${this.createSite.name}: ${error}`);
|
||||
const message = `SitesApi ${this.createSite.name}: ${error}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,11 +68,15 @@ export class SitesApi {
|
||||
try {
|
||||
const id = (await this.apiService.sites.listSiteContainers(siteId)).list?.entries?.[0]?.entry?.id;
|
||||
if (!id) {
|
||||
throw new Error(`Document library not found for site ${siteId}`);
|
||||
const message = `Document library not found for site ${siteId}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
return id;
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to get document library ID for site ${siteId}: ${error}`);
|
||||
const message = `Failed to get document library ID for site ${siteId}: ${error}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +93,7 @@ export class SitesApi {
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(`${this.constructor.name} ${this.deleteSites.name}`, error);
|
||||
logger.error(`${this.constructor.name} ${this.deleteSites.name}: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,9 +103,9 @@ export class SitesApi {
|
||||
} as SiteMembershipBodyUpdate;
|
||||
|
||||
try {
|
||||
return this.apiService.sites.updateSiteMembership(siteId, userId, siteRole);
|
||||
return await this.apiService.sites.updateSiteMembership(siteId, userId, siteRole);
|
||||
} catch (error) {
|
||||
console.error(`SitesApi updateSiteMember : catch : `, error);
|
||||
logger.error(`SitesApi updateSiteMember : catch : ${error}`);
|
||||
return new SiteMemberEntry();
|
||||
}
|
||||
}
|
||||
@@ -127,7 +134,9 @@ export class SitesApi {
|
||||
try {
|
||||
return this.apiService.sites.createSiteMembershipRequestForPerson(personId, body);
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to create site membership request for person ${personId} and site ${siteId}: ${error}`);
|
||||
const message = `Failed to create site membership request for person ${personId} and site ${siteId}: ${error}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,7 +144,9 @@ export class SitesApi {
|
||||
try {
|
||||
return this.apiService.sites.approveSiteMembershipRequest(siteId, inviteeId);
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to approve site membership request for invitee ${inviteeId} and site ${siteId}: ${error}`);
|
||||
const message = `Failed to approve site membership request for invitee ${inviteeId} and site ${siteId}: ${error}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,7 +156,9 @@ export class SitesApi {
|
||||
const requests = entries.map((e) => e.entry?.id).filter((id): id is string => !!id);
|
||||
return requests.includes(siteId);
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to check site membership request for person ${personId} and site ${siteId}: ${error}`);
|
||||
const message = `Failed to check site membership request for person ${personId} and site ${siteId}: ${error}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,7 +166,7 @@ export class SitesApi {
|
||||
try {
|
||||
return this.apiService.sites.deleteSiteMembership(siteId, userId);
|
||||
} catch (error) {
|
||||
console.error(`SitesApi deleteSiteMember : catch : `, error);
|
||||
logger.error(`SitesApi deleteSiteMember : catch : ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,7 +174,9 @@ export class SitesApi {
|
||||
try {
|
||||
return this.apiService.sites.getSite(siteId);
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to get site ${siteId}: ${error}`);
|
||||
const message = `Failed to get site ${siteId}: ${error}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,26 +50,34 @@ export class TagsApi {
|
||||
} else if ('list' in result) {
|
||||
const firstEntry = result.list?.entries?.[0];
|
||||
if (!firstEntry) {
|
||||
throw new Error(`createTags returned a paging result with no entries for tag "${tag}"`);
|
||||
const message = `createTags returned a paging result with no entries for tag "${tag}"`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
created = firstEntry;
|
||||
} else {
|
||||
throw new Error(`createTags returned an unexpected response format for tag "${tag}"`);
|
||||
const message = `createTags returned an unexpected response format for tag "${tag}"`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
logger.info(`Tag created: "${created.entry.tag}" (id: ${created.entry.id})`);
|
||||
results.push(created);
|
||||
}
|
||||
return results;
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to create tags: ${error}`);
|
||||
const message = `Failed to create tags: ${error}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
async assignTagToNode(nodeId: string, tag: TagBody): Promise<TagEntry> {
|
||||
try {
|
||||
return this.apiService.tagsApi.assignTagToNode(nodeId, tag);
|
||||
return await this.apiService.tagsApi.assignTagToNode(nodeId, tag);
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to assign tag to node: ${error}`);
|
||||
const message = `Failed to assign tag to node: ${error}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +89,9 @@ export class TagsApi {
|
||||
logger.info(`Tag deleted: ${tagLabel}(id: ${id})`);
|
||||
}
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to delete tags: ${error}`);
|
||||
const message = `Failed to delete tags: ${error}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,7 +99,9 @@ export class TagsApi {
|
||||
try {
|
||||
return this.apiService.tagsApi.listTagsForNode(nodeId);
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to list tags for node: ${error}`);
|
||||
const message = `Failed to list tags for node: ${error}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,7 +109,9 @@ export class TagsApi {
|
||||
try {
|
||||
return this.apiService.tagsApi.listTags(params);
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to list tags: ${error}`);
|
||||
const message = `Failed to list tags: ${error}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +121,9 @@ export class TagsApi {
|
||||
const tags = response.list?.entries.map((entry) => entry.entry) || [];
|
||||
await this.deleteTags(...tags);
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to delete tags by tag name: ${error}`);
|
||||
const message = `Failed to delete tags by tag name: ${error}`;
|
||||
logger.error(message);
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
import { ApiClientFactory } from './api-client-factory';
|
||||
import { logger } from '../utils';
|
||||
|
||||
export class TrashcanApi {
|
||||
private readonly apiService = new ApiClientFactory();
|
||||
@@ -50,7 +51,7 @@ export class TrashcanApi {
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('User Actions - emptyTrashcan failed : ', error);
|
||||
logger.error(`User Actions - emptyTrashcan failed: ${error}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user