[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:
Adam Świderski
2026-04-22 11:26:39 +02:00
committed by GitHub
parent 7f05fc510c
commit a2631db0e2
15 changed files with 365 additions and 352 deletions
+5
View File
@@ -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}`);
}
}
}