e2e cleanup (#2951)

* reduce the code

* reduce code

* reduce code

* reduce code

* cleanup tests

* more readable code

* cleanup code

* fix code

* even more cleanup

* remove some deprecated apis

* code fixes

* cleanup files

* more files switching to user actions
This commit is contained in:
Denys Vuika
2023-02-01 23:22:37 +00:00
committed by GitHub
parent a325deaf1a
commit 567882e864
42 changed files with 628 additions and 926 deletions

View File

@@ -24,7 +24,7 @@
*/
import { PersonEntry, NodeEntry, PeopleApi } from '@alfresco/js-api';
import { PersonModel, SitesApi, UploadApi, NodesApi, FavoritesApi, SearchApi, NodeContentTree, Person, SharedLinksApi } from './repo-client/apis';
import { PersonModel, SitesApi, UploadApi, NodesApi, NodeContentTree, Person, SharedLinksApi } from './repo-client/apis';
import { UserActions } from './user-actions';
import { browser } from 'protractor';
@@ -36,15 +36,13 @@ export class AdminActions extends UserActions {
sites: SitesApi = new SitesApi();
upload: UploadApi = new UploadApi();
nodes: NodesApi = new NodesApi();
favorites: FavoritesApi = new FavoritesApi();
search: SearchApi = new SearchApi();
shared: SharedLinksApi = new SharedLinksApi();
async login(username?: string, password?: string) {
return super.login(username || browser.params.ADMIN_USERNAME, password || browser.params.ADMIN_PASSWORD);
}
async getDataDictionaryId(): Promise<string> {
private async getDataDictionaryId(): Promise<string> {
try {
return this.nodes.getNodeIdFromParent('Data Dictionary', '-root-');
} catch (error) {
@@ -108,17 +106,6 @@ export class AdminActions extends UserActions {
}
}
async createNodeTemplate(name: string, title: string = '', description: string = '', author: string = ''): Promise<NodeEntry> {
try {
const templatesRootFolderId: string = await this.getNodeTemplatesFolderId();
return this.nodes.createFile(name, templatesRootFolderId, title, description, author);
} catch (error) {
super.handleError('Admin Actions - createNodeTemplate failed : ', error);
return null;
}
}
async createNodeTemplatesHierarchy(hierarchy: NodeContentTree): Promise<any> {
try {
return this.nodes.createContent(hierarchy, `Data Dictionary/Node Templates`);
@@ -127,17 +114,6 @@ export class AdminActions extends UserActions {
}
}
async createSpaceTemplate(name: string, title: string = '', description: string = ''): Promise<NodeEntry> {
try {
const templatesRootFolderId: string = await this.getSpaceTemplatesFolderId();
return this.nodes.createFolder(name, templatesRootFolderId, title, description);
} catch (error) {
super.handleError('Admin Actions - createSpaceTemplate failed : ', error);
return null;
}
}
async createSpaceTemplatesHierarchy(hierarchy: NodeContentTree): Promise<any> {
try {
return this.nodes.createContent(hierarchy, `Data Dictionary/Space Templates`);
@@ -170,14 +146,6 @@ export class AdminActions extends UserActions {
}
}
async cleanupNodeTemplatesFolder(): Promise<void> {
try {
return this.nodes.deleteNodeChildren(await this.getNodeTemplatesFolderId());
} catch (error) {
super.handleError('Admin Actions - cleanupNodeTemplatesFolder failed : ', error);
}
}
async cleanupNodeTemplatesItems(nodeNames: string[]): Promise<void> {
try {
const templatesFolderId = await this.getNodeTemplatesFolderId();
@@ -190,21 +158,6 @@ export class AdminActions extends UserActions {
}
}
async cleanupSpaceTemplatesFolder(): Promise<void> {
try {
const spaceTemplatesNodeId = await this.getSpaceTemplatesFolderId();
// folder links are deleted automatically when original folder is deleted
// Software Engineering Project is the default folder template coming from ACS, should not be deleted
const nodesToDelete = (await this.nodes.getNodeChildren(spaceTemplatesNodeId)).list.entries
.filter((node) => node.entry.nodeType !== 'app:folderlink' && node.entry.name !== 'Software Engineering Project')
.map((node) => node.entry.id);
return this.nodes.deleteNodesById(nodesToDelete);
} catch (error) {
super.handleError('Admin Actions - cleanupSpaceTemplatesFolder failed : ', error);
}
}
async cleanupSpaceTemplatesItems(nodeNames: string[]): Promise<void> {
try {
const spaceTemplatesNodeId = await this.getSpaceTemplatesFolderId();
@@ -217,15 +170,6 @@ export class AdminActions extends UserActions {
}
}
async createLinkToFileId(originalFileId: string, destinationParentId: string): Promise<NodeEntry> {
try {
return this.nodes.createFileLink(originalFileId, destinationParentId);
} catch (error) {
super.handleError('Admin Actions - createLinkToFileId failed : ', error);
return null;
}
}
async createLinkToFileName(originalFileName: string, originalFileParentId: string, destinationParentId?: string): Promise<NodeEntry> {
if (!destinationParentId) {
destinationParentId = originalFileParentId;
@@ -234,22 +178,13 @@ export class AdminActions extends UserActions {
try {
const nodeId = await this.nodes.getNodeIdFromParent(originalFileName, originalFileParentId);
return this.createLinkToFileId(nodeId, destinationParentId);
return this.nodes.createFileLink(nodeId, destinationParentId);
} catch (error) {
super.handleError('Admin Actions - createLinkToFileName failed : ', error);
return null;
}
}
async createLinkToFolderId(originalFolderId: string, destinationParentId: string): Promise<NodeEntry> {
try {
return this.nodes.createFolderLink(originalFolderId, destinationParentId);
} catch (error) {
super.handleError('Admin Actions - createLinkToFolderId failed : ', error);
return null;
}
}
async createLinkToFolderName(originalFolderName: string, originalFolderParentId: string, destinationParentId?: string): Promise<NodeEntry> {
if (!destinationParentId) {
destinationParentId = originalFolderParentId;
@@ -258,7 +193,7 @@ export class AdminActions extends UserActions {
try {
const nodeId = await this.nodes.getNodeIdFromParent(originalFolderName, originalFolderParentId);
return this.createLinkToFolderId(nodeId, destinationParentId);
return this.nodes.createFolderLink(nodeId, destinationParentId);
} catch (error) {
super.handleError('Admin Actions - createLinkToFolderName failed : ', error);
return null;

View File

@@ -25,7 +25,6 @@
import { RepoApi } from '../repo-api';
import { Logger } from '@alfresco/adf-testing';
import { RepoClient } from './../../repo-client';
import { Utils } from '../../../../utilities/utils';
import { FavoritesApi as AdfFavoritesApi, SitesApi as AdfSiteApi, FavoriteEntry } from '@alfresco/js-api';
@@ -37,23 +36,6 @@ export class FavoritesApi extends RepoApi {
super(username, password);
}
async addFavorite(api: RepoClient, nodeType: string, name: string, parentFolderId?: string) {
try {
const nodeId = (await api.nodes.getNodeByPath(name, parentFolderId)).entry.id;
const data = {
target: {
[nodeType]: {
guid: nodeId
}
}
};
return await this.favoritesApi.createFavorite('-me-', data);
} catch (error) {
this.handleError(`FavoritesApi addFavorite : catch : `, error);
return null;
}
}
async addFavoriteById(nodeType: 'file' | 'folder' | 'site', id: string): Promise<FavoriteEntry | null> {
let guid;
try {
@@ -92,7 +74,7 @@ export class FavoritesApi extends RepoApi {
return favorites;
}
async getFavorites() {
private async getFavorites() {
try {
await this.apiAuth();
return await this.favoritesApi.listFavorites(this.username);
@@ -147,7 +129,7 @@ export class FavoritesApi extends RepoApi {
return isFavorite;
}
async removeFavoriteById(nodeId: string) {
private async removeFavoriteById(nodeId: string) {
try {
await this.apiAuth();
return await this.favoritesApi.deleteFavorite('-me-', nodeId);

View File

@@ -24,13 +24,12 @@
*/
import { RepoApi } from '../repo-api';
import { NodeBodyCreate } from './node-body-create';
import { NodeContentTree, flattenNodeContentTree } from './node-content-tree';
import { NodesApi as AdfNodeApi, NodeBodyLock, NodeEntry, NodeChildAssociationPaging } from '@alfresco/js-api';
import { NodesApi as AdfNodeApi, NodeEntry, NodeChildAssociationPaging } from '@alfresco/js-api';
import { Utils } from '../../../../utilities/utils';
export class NodesApi extends RepoApi {
nodesApi = new AdfNodeApi(this.alfrescoJsApi);
private nodesApi = new AdfNodeApi(this.alfrescoJsApi);
constructor(username?: string, password?: string) {
super(username, password);
@@ -178,15 +177,16 @@ export class NodesApi extends RepoApi {
async deleteNodesById(ids: string[], permanent: boolean = true): Promise<void> {
try {
await this.apiAuth();
for (const id of ids) {
await this.deleteNodeById(id, permanent);
await this.nodesApi.deleteNode(id, { permanent });
}
} catch (error) {
this.handleError(`${this.constructor.name} ${this.deleteNodesById.name}`, error);
}
}
async getNodeChildren(nodeId: string): Promise<NodeChildAssociationPaging | null> {
private async getNodeChildren(nodeId: string): Promise<NodeChildAssociationPaging | null> {
try {
const opts = {
include: ['properties']
@@ -214,7 +214,7 @@ export class NodesApi extends RepoApi {
}
}
async createImageNode(name: string, parentId: string = '-my-', title: string = '', description: string = ''): Promise<NodeEntry | null> {
private async createImageNode(name: string, parentId: string = '-my-', title: string = '', description: string = ''): Promise<NodeEntry | null> {
const imageProps = {
'exif:pixelXDimension': 1000,
'exif:pixelYDimension': 1200
@@ -227,7 +227,7 @@ export class NodesApi extends RepoApi {
}
}
async createNode(
private async createNode(
nodeType: string,
name: string,
parentId: string = '-my-',
@@ -308,18 +308,10 @@ export class NodesApi extends RepoApi {
}
}
async createChildren(data: NodeBodyCreate[]): Promise<NodeEntry | any> {
try {
await this.apiAuth();
return await this.nodesApi.createNode('-my-', data as any);
} catch (error) {
this.handleError(`${this.constructor.name} ${this.createChildren.name}`, error);
}
}
async createContent(content: NodeContentTree, relativePath: string = '/'): Promise<NodeEntry | any> {
try {
return await this.createChildren(flattenNodeContentTree(content, relativePath));
await this.apiAuth();
return await this.nodesApi.createNode('-my-', flattenNodeContentTree(content, relativePath) as any);
} catch (error) {
this.handleError(`${this.constructor.name} ${this.createContent.name}`, error);
}
@@ -341,7 +333,7 @@ export class NodesApi extends RepoApi {
}
}
async addAspects(nodeId: string, aspectNames: string[]): Promise<NodeEntry> {
private async addAspects(nodeId: string, aspectNames: string[]): Promise<NodeEntry> {
try {
await this.apiAuth();
return this.nodesApi.updateNode(nodeId, { aspectNames });
@@ -396,16 +388,6 @@ export class NodesApi extends RepoApi {
}
}
// node content
async getNodeContent(nodeId: string): Promise<any> {
try {
await this.apiAuth();
return await this.nodesApi.getNodeContent(nodeId);
} catch (error) {
this.handleError(`${this.constructor.name} ${this.getNodeContent.name}`, error);
}
}
async updateNodeContent(
nodeId: string,
content: string,
@@ -476,33 +458,7 @@ export class NodesApi extends RepoApi {
}
}
// lock node
async lockFile(nodeId: string, lockType: string = 'ALLOW_OWNER_CHANGES'): Promise<NodeEntry | null> {
const data = {
type: lockType
} as NodeBodyLock;
try {
await this.apiAuth();
return await this.nodesApi.lockNode(nodeId, data);
} catch (error) {
this.handleError(`${this.constructor.name} ${this.lockFile.name}`, error);
return null;
}
}
/* @deprecated check {UserActions.unlockNodes} instead. */
async unlockFile(nodeId: string): Promise<NodeEntry | null> {
try {
await this.apiAuth();
return await this.nodesApi.unlockNode(nodeId);
} catch (error) {
this.handleError(`${this.constructor.name} ${this.unlockFile.name}`, error);
return null;
}
}
async getLockType(nodeId: string): Promise<string> {
private async getLockType(nodeId: string): Promise<string> {
try {
const lockType = await this.getNodeProperty(nodeId, 'cm:lockType');
return lockType || '';
@@ -512,16 +468,6 @@ export class NodesApi extends RepoApi {
}
}
async getLockOwner(nodeId: string): Promise<string> {
try {
const lockOwner = await this.getNodeProperty(nodeId, 'cm:lockOwner');
return lockOwner || '';
} catch (error) {
this.handleError(`${this.constructor.name} ${this.getLockOwner.name}`, error);
return '';
}
}
async isFileLockedWrite(nodeId: string): Promise<boolean> {
try {
return (await this.getLockType(nodeId)) === 'WRITE_LOCK';

View File

@@ -35,45 +35,23 @@ export class QueriesApi extends RepoApi {
super(username, password);
}
async findSites(searchTerm: string) {
const data = {
term: searchTerm,
fields: ['title']
};
private async findSitesTotalItems(searchTerm: string): Promise<number> {
try {
await this.apiAuth();
return this.queriesApi.findSites(searchTerm, data);
} catch (error) {
this.handleError(`QueriesApi findSites : catch : `, error);
return null;
}
}
async findSitesTotalItems(searchTerm: string): Promise<number> {
try {
return (await this.findSites(searchTerm)).list.pagination.totalItems;
const opts = {
term: searchTerm,
fields: ['title']
};
const sites = await this.queriesApi.findSites(searchTerm, opts);
return sites.list.pagination.totalItems;
} catch (error) {
this.handleError(`QueriesApi findSitesTotalItems : catch :`, error);
return -1;
}
}
async findNodes(searchTerm: string) {
const data = {
term: searchTerm,
fields: ['name']
};
try {
await this.apiAuth();
return this.queriesApi.findNodes(searchTerm, data);
} catch (error) {
this.handleError(`QueriesApi findNodes : catch : `, error);
return null;
}
}
async waitForSites(searchTerm: string, data: { expect: number }) {
try {
const sites = async () => {
@@ -91,22 +69,4 @@ export class QueriesApi extends RepoApi {
Logger.error(`\tExpected: ${data.expect} items, but found ${error}`);
}
}
async waitForFilesAndFolders(searchTerm: string, data: { expect: number }) {
try {
const nodes = async () => {
const totalItems = (await this.findNodes(searchTerm)).list.pagination.totalItems;
if (totalItems !== data.expect) {
return Promise.reject(totalItems);
} else {
return Promise.resolve(totalItems);
}
};
return await Utils.retryCall(nodes);
} catch (error) {
Logger.error(`QueriesApi waitForFilesAndFolders : catch : `);
Logger.error(`\tExpected: ${data.expect} items, but found ${error}`);
}
}
}

View File

@@ -35,7 +35,7 @@ export class SearchApi extends RepoApi {
super(username, password);
}
async queryRecentFiles(username: string) {
private async queryRecentFiles(username: string) {
const data = {
query: {
query: '*',
@@ -66,7 +66,7 @@ export class SearchApi extends RepoApi {
}
}
async queryNodesNames(searchTerm: string) {
private async queryNodesNames(searchTerm: string) {
const data = {
query: {
query: `cm:name:\"${searchTerm}*\"`,
@@ -84,33 +84,6 @@ export class SearchApi extends RepoApi {
}
}
async getSearchByTermTotalItems(searchTerm: string): Promise<number> {
try {
return (await this.queryNodesNames(searchTerm)).list.pagination.totalItems;
} catch (error) {
this.handleError(`SearchApi getSearchByTermTotalItems : catch : `, error);
return -1;
}
}
async queryNodesExactNames(searchTerm: string) {
const data = {
query: {
query: `cm:name:\"${searchTerm}\"`,
language: 'afts'
},
filterQueries: [{ query: `+TYPE:'cm:folder' OR +TYPE:'cm:content'` }]
};
try {
await this.apiAuth();
return this.searchApi.search(data);
} catch (error) {
this.handleError(`SearchApi queryNodesExactNames : catch : `, error);
return null;
}
}
async waitForApi(username: string, data: { expect: number }) {
try {
const recentFiles = async () => {
@@ -134,7 +107,7 @@ export class SearchApi extends RepoApi {
const apiCall = async () => {
try {
return await this.getSearchByTermTotalItems(searchTerm);
return (await this.queryNodesNames(searchTerm)).list.pagination.totalItems;
} catch (error) {
return 0;
}

View File

@@ -64,7 +64,7 @@ export class SharedLinksApi extends RepoApi {
return sharedLinks;
}
async getSharedIdOfNode(fileId: string): Promise<string> {
private async getSharedIdOfNode(fileId: string): Promise<string> {
try {
const sharedLinksEntries = (await this.getSharedLinks())?.list.entries;
const found = sharedLinksEntries.find((sharedLink) => sharedLink.entry.nodeId === fileId);
@@ -84,7 +84,7 @@ export class SharedLinksApi extends RepoApi {
}
}
async getSharedLinks(maxItems: number = 250): Promise<SharedLinkPaging | null> {
private async getSharedLinks(maxItems: number = 250): Promise<SharedLinkPaging | null> {
try {
await this.apiAuth();
const opts = {
@@ -97,38 +97,6 @@ export class SharedLinksApi extends RepoApi {
}
}
async getSharedLinksTotalItems(): Promise<number> {
try {
await this.apiAuth();
const opts = {
maxItems: 250
};
const sharedList = await this.sharedlinksApi.listSharedLinks(opts);
return sharedList.list.entries.length;
} catch (error) {
this.handleError(`SharedLinksApi getSharedLinksTotalItems : catch : `, error);
return -1;
}
}
async waitForApi(data: { expect: number }): Promise<any> {
try {
const sharedFiles = async () => {
const totalItems = await this.getSharedLinksTotalItems();
if (totalItems !== data.expect) {
return Promise.reject(totalItems);
} else {
return Promise.resolve(totalItems);
}
};
return await Utils.retryCall(sharedFiles);
} catch (error) {
Logger.error(`SharedLinksApi waitForApi : catch : `);
Logger.error(`\tExpected: ${data.expect} items, but found ${error}`);
}
}
async waitForFilesToBeShared(filesIds: string[]): Promise<any> {
try {
const sharedFile = async () => {

View File

@@ -54,26 +54,6 @@ export class SitesApi extends RepoApi {
}
}
async getSites() {
try {
await this.apiAuth();
return await this.sitesApi.listSiteMembershipsForPerson(this.username);
} catch (error) {
this.handleError(`SitesApi getSites : catch : `, error);
return null;
}
}
async getSitesTotalItems(): Promise<number> {
try {
await this.apiAuth();
return (await this.sitesApi.listSiteMembershipsForPerson(this.username)).list.pagination.totalItems;
} catch (error) {
this.handleError(`SitesApi getSitesTotalItems : catch : `, error);
return -1;
}
}
async getDocLibId(siteId: string): Promise<string> {
try {
await this.apiAuth();
@@ -84,36 +64,6 @@ export class SitesApi extends RepoApi {
}
}
async getVisibility(siteId: string) {
try {
const site = await this.getSite(siteId);
return site.entry.visibility;
} catch (error) {
this.handleError(`SitesApi getVisibility : catch : `, error);
return null;
}
}
async getDescription(siteId: string) {
try {
const site = await this.getSite(siteId);
return site.entry.description;
} catch (error) {
this.handleError(`SitesApi getDescription : catch : `, error);
return null;
}
}
async getTitle(siteId: string) {
try {
const site = await this.getSite(siteId);
return site.entry.title;
} catch (error) {
this.handleError(`SitesApi getTitle : catch : `, error);
return null;
}
}
async createSite(title: string, visibility?: string, description?: string, siteId?: string): Promise<SiteEntry | null> {
const site = {
title,
@@ -131,14 +81,6 @@ export class SitesApi extends RepoApi {
}
}
async createSitePrivate(title: string, description?: string, siteId?: string): Promise<SiteEntry> {
return this.createSite(title, SITE_VISIBILITY.PRIVATE, description, siteId);
}
async createSiteModerated(title: string, description?: string, siteId?: string): Promise<SiteEntry> {
return this.createSite(title, SITE_VISIBILITY.MODERATED, description, siteId);
}
async createSites(siteNames: string[], visibility?: string): Promise<SiteEntry[]> {
const sites: SiteEntry[] = [];
try {
@@ -154,10 +96,6 @@ export class SitesApi extends RepoApi {
return sites;
}
async createSitesPrivate(siteNames: string[]): Promise<any> {
return this.createSites(siteNames, SITE_VISIBILITY.PRIVATE);
}
async deleteSite(siteId: string, permanent: boolean = true) {
try {
await this.apiAuth();
@@ -183,7 +121,9 @@ export class SitesApi extends RepoApi {
async deleteAllUserSites(permanent: boolean = true) {
try {
const siteIds = (await this.getSites()).list.entries.map((entries) => entries.entry.id);
await this.apiAuth();
const sites = await this.sitesApi.listSiteMembershipsForPerson(this.username);
const siteIds = sites.list.entries.map((entries) => entries.entry.id);
return await siteIds.reduce(async (previous, current) => {
await previous;
@@ -280,7 +220,9 @@ export class SitesApi extends RepoApi {
async waitForSitesToBeCreated(sitesIds: string[]) {
try {
const site = async () => {
const sitesList = (await this.getSites()).list.entries.map((link) => link.entry.id);
await this.apiAuth();
const sites = await this.sitesApi.listSiteMembershipsForPerson(this.username);
const sitesList = sites.list.entries.map((link) => link.entry.id);
const foundItems = sitesIds.every((id) => sitesList.includes(id));
if (foundItems) {
return Promise.resolve(foundItems);
@@ -295,22 +237,4 @@ export class SitesApi extends RepoApi {
Logger.error(`\tWait timeout reached waiting for sites to be created`);
}
}
async waitForApi(data: { expect: number }) {
try {
const sites = async () => {
const totalItems = await this.getSitesTotalItems();
if (totalItems !== data.expect) {
return Promise.reject(totalItems);
} else {
return Promise.resolve(totalItems);
}
};
return await Utils.retryCall(sites);
} catch (error) {
Logger.error(`SitesApi waitForApi : catch : `);
Logger.error(`\tExpected: ${data.expect} items, but found ${error}`);
}
}
}

View File

@@ -29,8 +29,8 @@ import { browser } from 'protractor';
import * as fs from 'fs';
export class UploadApi extends RepoApi {
upload = new AdfUploadApi(this.alfrescoJsApi);
e2eRootPath = browser.params.e2eRootPath;
private upload = new AdfUploadApi(this.alfrescoJsApi);
private e2eRootPath = browser.params.e2eRootPath;
constructor(username?: string, password?: string) {
super(username, password);

View File

@@ -74,4 +74,14 @@ export class RepoClient {
await this.apiAuth();
return this.alfrescoApi.logout();
}
async createFolder(name: string, parentId?: string): Promise<string> {
const response = await this.nodes.createFolder(name, parentId);
return response.entry.id;
}
async createFile(name: string, parentId?: string): Promise<string> {
const response = await this.nodes.createFile(name, parentId);
return response.entry.id;
}
}

View File

@@ -24,8 +24,9 @@
*/
import { Logger } from '@alfresco/adf-testing';
import { AlfrescoApi, Comment, CommentsApi, NodesApi, TrashcanApi, SitesApi, SharedlinksApi } from '@alfresco/js-api';
import { AlfrescoApi, Comment, CommentsApi, NodesApi, TrashcanApi, SitesApi, SharedlinksApi, SiteEntry } from '@alfresco/js-api';
import { browser } from 'protractor';
import { SITE_VISIBILITY } from '../configs';
import { Utils } from './utils';
export class UserActions {
@@ -158,6 +159,16 @@ export class UserActions {
}
}
async lockNodes(nodeIds: string[], lockType: string = 'ALLOW_OWNER_CHANGES') {
try {
for (const nodeId of nodeIds) {
await this.nodesApi.lockNode(nodeId, { type: lockType });
}
} catch (error) {
this.handleError('User Actions - lockNodes failed : ', error);
}
}
/**
* Unlock multiple nodes.
* @param nodeIds The list of node IDs to unlock.
@@ -172,6 +183,32 @@ export class UserActions {
}
}
/**
* Create multiple sites
* @param siteNames The list of the site names
* @param visibility Default site visibility
* @returns List of site entries
*/
async createSites(siteNames: string[], visibility?: string): Promise<SiteEntry[]> {
const sites: SiteEntry[] = [];
try {
if (siteNames && siteNames.length > 0) {
for (const siteName of siteNames) {
const site = await this.sitesApi.createSite({
title: siteName,
visibility: visibility || SITE_VISIBILITY.PUBLIC,
id: siteName
});
sites.push(site);
}
}
} catch (error) {
this.handleError(`User Actions - createSites failed : `, error);
}
return sites;
}
/**
* Delete multiple sites/libraries.
* @param siteIds The list of the site/library IDs to delete.