mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-07-24 17:31:52 +00:00
[ACS-8694] Re-introduce visibility rules cleanup (#4516)
* [ACS-8694] Cleanup of visibility rules for extensions in ACA (#4140)
* [ACS-9369] Resolved issues where visibility rules with a single element array would log errors (#4416)
* [ACS-9369] Resolved issues where visibility rules with a single element array would log errors
* [ACS-9369] Improved rule array filtering logic
* [ACS-9369] Added type to variable
(cherry picked from commit 4e33f1126d
)
* [ACS-8694] Removed unneeded test cases
* [ACS-8694] Fixed 'Favorite' option showing up in toolbar when opening search page
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -15,7 +15,9 @@
|
||||
"id": "app.toolbar.rules.separator",
|
||||
"type": "separator",
|
||||
"rules": {
|
||||
"visible": "app.selection.folder"
|
||||
"visible": [
|
||||
"app.selection.folder"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -24,7 +26,9 @@
|
||||
"description": "ACA_FOLDER_RULES.MENU.CREATE_RULES_DESC",
|
||||
"icon": "add",
|
||||
"rules": {
|
||||
"visible": "rules.canCreateFolderRule"
|
||||
"visible": [
|
||||
"rules.canCreateFolderRule"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -33,7 +37,9 @@
|
||||
"description": "ACA_FOLDER_RULES.MENU.LINK_RULES_DESC",
|
||||
"icon": "link",
|
||||
"rules": {
|
||||
"visible": "rules.canLinkFolderRule"
|
||||
"visible": [
|
||||
"rules.canLinkFolderRule"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -45,7 +51,9 @@
|
||||
"id": "app.toolbar.rules.separator",
|
||||
"type": "separator",
|
||||
"rules": {
|
||||
"visible": "app.selection.folder"
|
||||
"visible": [
|
||||
"app.selection.folder"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -54,7 +62,9 @@
|
||||
"description": "ACA_FOLDER_RULES.MENU.CREATE_RULES_DESC",
|
||||
"icon": "add",
|
||||
"rules": {
|
||||
"visible": "rules.canCreateFolderRule"
|
||||
"visible": [
|
||||
"rules.canCreateFolderRule"
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -63,7 +73,9 @@
|
||||
"description": "ACA_FOLDER_RULES.MENU.LINK_RULES_DESC",
|
||||
"icon": "link",
|
||||
"rules": {
|
||||
"visible": "rules.canLinkFolderRule"
|
||||
"visible": [
|
||||
"rules.canLinkFolderRule"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@@ -77,7 +77,7 @@ export class AcaFolderRulesModule {
|
||||
translation.addTranslationFolder('folder-rules', 'assets/folder-rules');
|
||||
|
||||
extensions.setEvaluators({
|
||||
'rules.canManageFolderRules': rules.canManageFolderRules
|
||||
'rules.isFolderRulesEnabled': rules.isFolderRulesEnabled
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@@ -22,9 +22,7 @@
|
||||
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { AcaRuleContext } from '@alfresco/aca-shared/rules';
|
||||
import { canManageFolderRules, isFolderRulesEnabled } from './folder-rules.rules';
|
||||
import { NodeEntry } from '@alfresco/js-api';
|
||||
import { isFolderRulesEnabled } from './folder-rules.rules';
|
||||
|
||||
describe('Folder Rules Visibility Rules', () => {
|
||||
describe('isFolderRulesEnabled', () => {
|
||||
@@ -50,44 +48,4 @@ describe('Folder Rules Visibility Rules', () => {
|
||||
expect(result).toEqual(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('canManageFolderRules', () => {
|
||||
let context: AcaRuleContext;
|
||||
|
||||
beforeEach(() => {
|
||||
context = {
|
||||
appConfig: {
|
||||
get: () => true
|
||||
},
|
||||
selection: {
|
||||
folder: {} as any
|
||||
},
|
||||
navigation: {
|
||||
url: '/personal-files'
|
||||
},
|
||||
permissions: {
|
||||
check: () => true
|
||||
}
|
||||
} as any;
|
||||
});
|
||||
|
||||
it('should allow creating a rule for the selected folder', () => {
|
||||
const result = canManageFolderRules(context);
|
||||
expect(result).toEqual(true);
|
||||
});
|
||||
|
||||
it('should not allow creating a rule if no folder selected', () => {
|
||||
context.selection.folder = null;
|
||||
|
||||
const result = canManageFolderRules(context);
|
||||
expect(result).toEqual(false);
|
||||
});
|
||||
|
||||
it('should not allow creating a rule if the selected node is a smart folder', () => {
|
||||
context.selection.first = { entry: { aspectNames: ['smf:customConfigSmartFolder'], isFolder: true } } as NodeEntry;
|
||||
const result = canManageFolderRules(context);
|
||||
|
||||
expect(result).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -22,10 +22,6 @@
|
||||
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import { AcaRuleContext, canEditFolder, hasFolderSelected, isNotFavorites, isSmartFolder } from '@alfresco/aca-shared/rules';
|
||||
import { AcaRuleContext } from '@alfresco/aca-shared/rules';
|
||||
|
||||
export const isFolderRulesEnabled = (context: AcaRuleContext) => context.appConfig.get<boolean>('plugins.folderRules', false);
|
||||
export const isFolderRulesAllowed = (context: AcaRuleContext) =>
|
||||
isFolderRulesEnabled(context) && canEditFolder(context) && hasFolderSelected(context) && isNotFavorites(context) && !isSmartFolder(context);
|
||||
|
||||
export const canManageFolderRules = (context: AcaRuleContext): boolean => isFolderRulesAllowed(context);
|
||||
|
@@ -29,7 +29,9 @@
|
||||
"click": "aos.openWith.office"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "aos.canOpenWithOffice"
|
||||
"visible": [
|
||||
"aos.canOpenWithOffice"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -45,7 +47,9 @@
|
||||
"click": "aos.openWith.office"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "aos.canOpenWithOffice"
|
||||
"visible": [
|
||||
"aos.canOpenWithOffice"
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -63,7 +67,9 @@
|
||||
"click": "aos.openWith.office"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "aos.canOpenWithOffice"
|
||||
"visible": [
|
||||
"aos.canOpenWithOffice"
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
|
@@ -163,75 +163,43 @@ export class ContentServiceExtensionModule {
|
||||
});
|
||||
|
||||
extensions.setEvaluators({
|
||||
canCopyNode: rules.canCopyNode,
|
||||
canToggleJoinLibrary: rules.canToggleJoinLibrary,
|
||||
canEditFolder: rules.canEditFolder,
|
||||
isTrashcanItemSelected: rules.isTrashcanItemSelected,
|
||||
canViewFile: rules.canViewFile,
|
||||
canPrintFile: rules.canPrintFile,
|
||||
canLeaveLibrary: rules.canLeaveLibrary,
|
||||
canToggleSharedLink: rules.canToggleSharedLink,
|
||||
canShowInfoDrawer: rules.canShowInfoDrawer,
|
||||
canManageFileVersions: rules.canManageFileVersions,
|
||||
canManagePermissions: rules.canManagePermissions,
|
||||
canToggleEditOffline: rules.canToggleEditOffline,
|
||||
canToggleFileLock: rules.canToggleFileLock,
|
||||
canToggleFavorite: rules.canToggleFavorite,
|
||||
isLibraryManager: rules.isLibraryManager,
|
||||
canEditAspects: rules.canEditAspects,
|
||||
canShowExpand: rules.canShowExpand,
|
||||
canInfoPreview: rules.canInfoPreview,
|
||||
isSmartFolder: rules.isSmartFolder,
|
||||
isMultiSelection: rules.isMultiselection,
|
||||
canPrintFile: rules.canPrintFile,
|
||||
|
||||
'app.selection.canDelete': rules.canDeleteSelection,
|
||||
'app.selection.file.canUnlock': rules.canUnlockFile,
|
||||
'app.selection.file.canLock': rules.canLockFile,
|
||||
'app.selection.canDownload': rules.canDownloadSelection,
|
||||
'app.selection.notEmpty': rules.hasSelection,
|
||||
'app.selection.canUnshare': rules.canUnshareNodes,
|
||||
'app.selection.canAddFavorite': rules.canAddFavorite,
|
||||
'app.selection.canRemoveFavorite': rules.canRemoveFavorite,
|
||||
'app.selection.first.canUpdate': rules.canUpdateSelectedNode,
|
||||
'app.selection.file': rules.hasFileSelected,
|
||||
'app.selection.file.canShare': rules.canShareFile,
|
||||
'app.selection.file.isShared': rules.isShared,
|
||||
'app.selection.file.isLocked': rules.hasLockedFiles,
|
||||
'app.selection.file.isLockOwner': rules.isUserWriteLockOwner,
|
||||
'app.selection.file.canUploadVersion': rules.canUploadVersion,
|
||||
'app.selection.library': rules.hasLibrarySelected,
|
||||
'app.selection.isPrivateLibrary': rules.isPrivateLibrary,
|
||||
'app.selection.hasLibraryRole': rules.hasLibraryRole,
|
||||
'app.selection.hasNoLibraryRole': rules.hasNoLibraryRole,
|
||||
'app.selection.folder': rules.hasFolderSelected,
|
||||
'app.selection.folder.canUpdate': rules.canUpdateSelectedFolder,
|
||||
'app.selection.displayedKnowledgeRetrievalButton': rules.canDisplayKnowledgeRetrievalButton,
|
||||
|
||||
'app.navigation.folder.canCreate': rules.canCreateFolder,
|
||||
'app.navigation.folder.canUpload': rules.canUpload,
|
||||
'app.navigation.isTrashcan': rules.isTrashcan,
|
||||
'app.navigation.isNotTrashcan': rules.isNotTrashcan,
|
||||
'app.navigation.isLibraries': rules.isLibraries,
|
||||
'app.navigation.isLibraryFiles': rules.isLibraryFiles,
|
||||
'app.navigation.isPersonalFiles': rules.isPersonalFiles,
|
||||
'app.navigation.isNotLibraries': rules.isNotLibraries,
|
||||
'app.navigation.isSharedFiles': rules.isSharedFiles,
|
||||
'app.navigation.isNotSharedFiles': rules.isNotSharedFiles,
|
||||
'app.navigation.isFavorites': rules.isFavorites,
|
||||
'app.navigation.isNotFavorites': rules.isNotFavorites,
|
||||
'app.navigation.isRecentFiles': rules.isRecentFiles,
|
||||
'app.navigation.isNotRecentFiles': rules.isNotRecentFiles,
|
||||
'app.navigation.isSearchResults': rules.isSearchResults,
|
||||
'app.navigation.isNotSearchResults': rules.isNotSearchResults,
|
||||
'app.navigation.isPreview': rules.isPreview,
|
||||
'app.navigation.isSharedPreview': rules.isSharedPreview,
|
||||
'app.navigation.isFavoritesPreview': rules.isFavoritesPreview,
|
||||
'app.navigation.isSharedFileViewer': rules.isSharedFileViewer,
|
||||
'app.navigation.isNotDetails': rules.isNotDetails,
|
||||
'app.navigation.isDetails': rules.isDetails,
|
||||
|
||||
'repository.isQuickShareEnabled': rules.hasQuickShareEnabled,
|
||||
'user.isAdmin': rules.isAdmin,
|
||||
'app.canShowLogout': rules.canShowLogout,
|
||||
'app.isContentServiceEnabled': rules.isContentServiceEnabled,
|
||||
'app.isUploadSupported': rules.isUploadSupported,
|
||||
'app.canCreateLibrary': rules.canCreateLibrary,
|
||||
'app.areTagsEnabled': rules.areTagsEnabled,
|
||||
'app.areCategoriesEnabled': rules.areCategoriesEnabled
|
||||
});
|
||||
|
@@ -23,9 +23,10 @@
|
||||
*/
|
||||
|
||||
import * as app from './app.rules';
|
||||
import { getFileExtension } from './app.rules';
|
||||
import { TestRuleContext } from './test-rule-context';
|
||||
import { NodeEntry, RepositoryInfo, StatusInfo } from '@alfresco/js-api';
|
||||
import { getFileExtension } from './app.rules';
|
||||
import { ProfileState } from '@alfresco/adf-extensions';
|
||||
import { AppConfigService } from '@alfresco/adf-core';
|
||||
|
||||
describe('app.evaluators', () => {
|
||||
@@ -50,19 +51,6 @@ describe('app.evaluators', () => {
|
||||
});
|
||||
|
||||
describe('canDownloadSelection', () => {
|
||||
it('should return [false] if selection is empty', () => {
|
||||
context.selection.isEmpty = true;
|
||||
|
||||
expect(app.canDownloadSelection(context)).toBe(false);
|
||||
});
|
||||
|
||||
it('should return [false] for the trashcan entries', () => {
|
||||
context.selection.isEmpty = false;
|
||||
context.navigation = { url: '/trashcan' };
|
||||
|
||||
expect(app.canDownloadSelection(context)).toBe(false);
|
||||
});
|
||||
|
||||
it('should allow downloading files', () => {
|
||||
context.selection.isEmpty = false;
|
||||
context.selection.nodes = [{ entry: { isFile: true } } as NodeEntry];
|
||||
@@ -105,20 +93,6 @@ describe('app.evaluators', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('canShowExpand', () => {
|
||||
it('should return false when isLibraries returns true', () => {
|
||||
context.navigation.url = '/libraries';
|
||||
|
||||
expect(app.canShowExpand(context)).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false when isDetails returns true', () => {
|
||||
context.navigation.url = '/details';
|
||||
|
||||
expect(app.canShowExpand(context)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('hasLockedFiles', () => {
|
||||
it('should return [false] if selection not present', () => {
|
||||
context = {} as any;
|
||||
@@ -455,34 +429,6 @@ describe('app.evaluators', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('canManagePermissions', () => {
|
||||
it('should return false if user cannot update the selected node', () => {
|
||||
context.permissions.check = spyOn(context.permissions, 'check').and.returnValue(false);
|
||||
|
||||
expect(app.canManagePermissions(context)).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false if the context is trashcan', () => {
|
||||
context.navigation = { url: '/trashcan' };
|
||||
|
||||
expect(app.canManagePermissions(context)).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false if many nodes are selected', () => {
|
||||
context.selection.count = 2;
|
||||
expect(app.canManagePermissions(context)).toBe(false);
|
||||
});
|
||||
|
||||
it('should return false if the selected node is a smart folder', () => {
|
||||
context.selection.first = { entry: { aspectNames: ['smf:customConfigSmartFolder'], isFolder: true } } as NodeEntry;
|
||||
expect(app.canManagePermissions(context)).toBe(false);
|
||||
});
|
||||
|
||||
it('should return true if user can update the selected node and it is not a trashcan nor smart folder nor multiselect', () => {
|
||||
expect(app.canManagePermissions(context)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('areTagsEnabled', () => {
|
||||
it('should call context.appConfig.get with correct parameters', () => {
|
||||
context.appConfig = { get: jasmine.createSpy() } as any;
|
||||
@@ -691,34 +637,6 @@ describe('app.evaluators', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('canCopyNode', () => {
|
||||
it('should return false when nothing is selected', () => {
|
||||
context.selection.isEmpty = true;
|
||||
expect(app.canCopyNode(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return false when selection exists and user is in trashcan', () => {
|
||||
context.selection.isEmpty = false;
|
||||
context.navigation.url = '/trashcan/test';
|
||||
expect(app.canCopyNode(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return false when selection exists and user is in library', () => {
|
||||
context.selection.isEmpty = false;
|
||||
context.navigation.url = '/test/libraries';
|
||||
expect(app.canCopyNode(context)).toBeFalse();
|
||||
|
||||
context.navigation.url = '/search-libraries/test';
|
||||
expect(app.canCopyNode(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return true when selection exists and user is outside library and trashcan', () => {
|
||||
context.selection.isEmpty = false;
|
||||
context.navigation.url = '/personal-files';
|
||||
expect(app.canCopyNode(context)).toBeTrue();
|
||||
});
|
||||
});
|
||||
|
||||
describe('canAddFavorite', () => {
|
||||
it('should return false when nothing is selected', () => {
|
||||
context.selection.isEmpty = true;
|
||||
@@ -756,17 +674,6 @@ describe('app.evaluators', () => {
|
||||
});
|
||||
|
||||
describe('canRemoveFavorite', () => {
|
||||
it('should return false when nothing is selected', () => {
|
||||
context.selection.isEmpty = true;
|
||||
expect(app.canRemoveFavorite(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return false when selection exists but user is in trashcan', () => {
|
||||
context.selection.isEmpty = false;
|
||||
context.navigation.url = '/trashcan/test';
|
||||
expect(app.canRemoveFavorite(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return true when user is in favorites page', () => {
|
||||
context.selection.isEmpty = false;
|
||||
context.navigation.url = '/favorites/test';
|
||||
@@ -832,23 +739,12 @@ describe('app.evaluators', () => {
|
||||
context.profile = {} as any;
|
||||
});
|
||||
|
||||
it('should return false when no library is selected', () => {
|
||||
context.selection.library = null;
|
||||
expect(app.canToggleJoinLibrary(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return false when selected library is private and user is not admin', () => {
|
||||
context.selection.library = { entry: { visibility: 'PRIVATE' } } as any;
|
||||
context.profile.isAdmin = false;
|
||||
expect(app.canToggleJoinLibrary(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return false when user already has a library role', () => {
|
||||
context.selection.library = { entry: { role: 'test' } } as any;
|
||||
context.profile.isAdmin = false;
|
||||
expect(app.canToggleJoinLibrary(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return true when user has no role in not private library', () => {
|
||||
context.selection.library = { entry: { visibility: 'PUBLIC' } } as any;
|
||||
context.profile.isAdmin = false;
|
||||
@@ -903,23 +799,6 @@ describe('app.evaluators', () => {
|
||||
});
|
||||
|
||||
describe('canDeleteSelection', () => {
|
||||
it('should return false when selection is empty', () => {
|
||||
context.selection.isEmpty = true;
|
||||
expect(app.canDeleteSelection(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return false when user is in trashcan or library', () => {
|
||||
context.selection.isEmpty = false;
|
||||
context.navigation.url = '/trashcan/test';
|
||||
expect(app.canDeleteSelection(context)).toBeFalse();
|
||||
|
||||
context.navigation.url = '/test/libraries';
|
||||
expect(app.canDeleteSelection(context)).toBeFalse();
|
||||
|
||||
context.navigation.url = '/search-libraries/test';
|
||||
expect(app.canDeleteSelection(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return false when selection contain locked file', () => {
|
||||
context.selection.isEmpty = false;
|
||||
context.navigation.url = '/personal-files';
|
||||
@@ -966,35 +845,6 @@ describe('app.evaluators', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('canUnshareNodes', () => {
|
||||
it('should return false when selection is empty', () => {
|
||||
context.selection.isEmpty = true;
|
||||
expect(app.canUnshareNodes(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return false when permission check fails', () => {
|
||||
context.selection.isEmpty = false;
|
||||
context.selection.nodes = [{} as any];
|
||||
context.permissions = { check: () => false };
|
||||
expect(app.canUnshareNodes(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return true when permission requirements are met', () => {
|
||||
context.selection.isEmpty = false;
|
||||
context.selection.nodes = [{} as any];
|
||||
context.permissions = { check: () => true };
|
||||
expect(app.canUnshareNodes(context)).toBeTrue();
|
||||
});
|
||||
|
||||
it('should verify if user have delete permission on selected node', () => {
|
||||
context.selection.isEmpty = false;
|
||||
context.selection.nodes = [{ allowableOperationsOnTarget: ['delete'] } as any];
|
||||
spyOn(context.permissions, 'check');
|
||||
app.canUnshareNodes(context);
|
||||
expect(context.permissions.check).toHaveBeenCalledWith(context.selection.nodes, ['delete'], { target: 'allowableOperationsOnTarget' });
|
||||
});
|
||||
});
|
||||
|
||||
describe('hasSelection', () => {
|
||||
it('should return false when nothing is selected', () => {
|
||||
context.selection.isEmpty = true;
|
||||
@@ -1052,70 +902,6 @@ describe('app.evaluators', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('canCreateLibrary', () => {
|
||||
it('should return false when content service is disabled', () => {
|
||||
context.appConfig = { get: () => false } as any;
|
||||
expect(app.canCreateLibrary(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return false when user is outside libraries', () => {
|
||||
context.appConfig = { get: () => true } as any;
|
||||
context.navigation.url = '/favorite/test';
|
||||
expect(app.canCreateLibrary(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return true when content service is enabled and user is in libraries', () => {
|
||||
context.appConfig = { get: () => true } as any;
|
||||
context.navigation.url = '/test/libraries';
|
||||
expect(app.canCreateLibrary(context)).toBeTrue();
|
||||
});
|
||||
});
|
||||
|
||||
describe('canUpload', () => {
|
||||
it('should return false when content service is disabled', () => {
|
||||
context.appConfig = { get: () => false } as any;
|
||||
expect(app.canUpload(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return false when user is outside personal files or libraries', () => {
|
||||
context.appConfig = { get: () => true } as any;
|
||||
context.navigation.url = '/favorite/test';
|
||||
expect(app.canUpload(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return false when current folder does not exist', () => {
|
||||
context.appConfig = { get: () => true } as any;
|
||||
context.navigation.url = '/personal-files/test';
|
||||
context.navigation.currentFolder = null;
|
||||
expect(app.canUpload(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return false when permission check fails', () => {
|
||||
context.appConfig = { get: () => true } as any;
|
||||
context.navigation.url = '/personal-files/test';
|
||||
context.navigation.currentFolder = {} as any;
|
||||
context.permissions = { check: () => false };
|
||||
expect(app.canUpload(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return true when permission requirements are met', () => {
|
||||
context.appConfig = { get: () => true } as any;
|
||||
context.navigation.url = '/personal-files/test';
|
||||
context.navigation.currentFolder = {} as any;
|
||||
context.permissions = { check: () => true };
|
||||
expect(app.canUpload(context)).toBeTrue();
|
||||
});
|
||||
|
||||
it('should verify if user has create permission on current folder', () => {
|
||||
context.appConfig = { get: () => true } as any;
|
||||
context.navigation.url = '/personal-files/test';
|
||||
context.navigation.currentFolder = { allowableOperations: ['create'] } as any;
|
||||
spyOn(context.permissions, 'check');
|
||||
app.canCreateFolder(context);
|
||||
expect(context.permissions.check).toHaveBeenCalledWith(context.navigation.currentFolder, ['create']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('hasFileSelected', () => {
|
||||
it('should return false when no file is selected', () => {
|
||||
context.selection.file = null;
|
||||
@@ -1176,18 +962,6 @@ describe('app.evaluators', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('hasNoLibraryRole', () => {
|
||||
it('should return false when library has a role', () => {
|
||||
context.selection.library = { entry: { role: 'test' } } as any;
|
||||
expect(app.hasNoLibraryRole(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return true when library has no role', () => {
|
||||
context.selection.library = { entry: { role: '' } } as any;
|
||||
expect(app.hasNoLibraryRole(context)).toBeTrue();
|
||||
});
|
||||
});
|
||||
|
||||
describe('isMultiselection', () => {
|
||||
it('should return false when there is no or single selection', () => {
|
||||
context.selection.isEmpty = true;
|
||||
@@ -1322,41 +1096,35 @@ describe('app.evaluators', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('isTrashcanItemSelected', () => {
|
||||
it('should return false when user is not in trashcan', () => {
|
||||
context.navigation.url = '/personal-files/test';
|
||||
expect(app.isTrashcanItemSelected(context)).toBeFalse();
|
||||
describe('canToggleFileLock', () => {
|
||||
beforeEach(() => {
|
||||
context.profile = {} as ProfileState;
|
||||
});
|
||||
|
||||
it('should return false when nothing is selected', () => {
|
||||
context.navigation.url = '/trashcan/test';
|
||||
context.selection.isEmpty = true;
|
||||
expect(app.isTrashcanItemSelected(context)).toBeFalse();
|
||||
it('should return false when permission requirements are not met, regardless of file lock', () => {
|
||||
context.selection.file = { entry: { properties: { 'cm:lockType': 'WRITE_LOCK', 'cm:lockOwner': { id: 'test' } } } } as NodeEntry;
|
||||
context.permissions = { check: () => false };
|
||||
expect(app.canToggleFileLock(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return true when user is in trashcan and node is selected', () => {
|
||||
context.navigation.url = '/trashcan/test';
|
||||
context.selection.isEmpty = false;
|
||||
expect(app.isTrashcanItemSelected(context)).toBeTrue();
|
||||
});
|
||||
});
|
||||
|
||||
describe('canViewFile', () => {
|
||||
it('should return false when user is in trashcan', () => {
|
||||
context.navigation.url = '/trashcan/test';
|
||||
expect(app.canViewFile(context)).toBeFalse();
|
||||
it('should return true when file has no lock and permission requirements are met', () => {
|
||||
context.selection.file = { entry: { properties: {} } } as NodeEntry;
|
||||
context.permissions = { check: () => true };
|
||||
expect(app.canToggleFileLock(context)).toBeTrue();
|
||||
});
|
||||
|
||||
it('should return false when nothing is selected', () => {
|
||||
context.navigation.url = '/personal-files/test';
|
||||
context.selection.file = null;
|
||||
expect(app.canViewFile(context)).toBeFalse();
|
||||
it('should return true when file is locked and permission requirements are met', () => {
|
||||
context.selection.file = { entry: { properties: { 'cm:lockType': 'WRITE_LOCK', 'cm:lockOwner': { id: 'test' } } } } as NodeEntry;
|
||||
context.profile.id = 'test1';
|
||||
context.permissions = { check: () => true };
|
||||
expect(app.canToggleFileLock(context)).toBeTrue();
|
||||
});
|
||||
|
||||
it('should return true when user is not in trashcan and file is selected', () => {
|
||||
context.navigation.url = '/personal-files/test';
|
||||
context.selection.file = {} as any;
|
||||
expect(app.canViewFile(context)).toBeTrue();
|
||||
it('should return true when file is locked and user is the owner of the lock', () => {
|
||||
context.selection.file = { entry: { properties: { 'cm:lockType': 'WRITE_LOCK', 'cm:lockOwner': { id: 'test1' } } } } as NodeEntry;
|
||||
context.profile.id = 'test1';
|
||||
context.permissions = { check: () => false };
|
||||
expect(app.canToggleFileLock(context)).toBeTrue();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1372,23 +1140,6 @@ describe('app.evaluators', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('canLeaveLibrary', () => {
|
||||
it('should return false when no library is selected', () => {
|
||||
context.selection.library = null;
|
||||
expect(app.canLeaveLibrary(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return false when user does not have library role', () => {
|
||||
context.selection.library = { entry: { role: null } } as any;
|
||||
expect(app.canLeaveLibrary(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return true when user has a library role', () => {
|
||||
context.selection.library = { entry: { role: 'test' } } as any;
|
||||
expect(app.canLeaveLibrary(context)).toBeTrue();
|
||||
});
|
||||
});
|
||||
|
||||
describe('canToggleSharedLink', () => {
|
||||
beforeEach(() => {
|
||||
context.repository.status = new StatusInfo();
|
||||
@@ -1418,133 +1169,6 @@ describe('app.evaluators', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('canShowInfoDrawer', () => {
|
||||
it('should return false when nothing is selected', () => {
|
||||
context.selection.isEmpty = true;
|
||||
expect(app.canShowInfoDrawer(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return false when user is in libraries or trashcan', () => {
|
||||
context.selection.isEmpty = false;
|
||||
context.navigation.url = '/trashcan/test';
|
||||
expect(app.canShowInfoDrawer(context)).toBeFalse();
|
||||
|
||||
context.navigation.url = '/test/libraries';
|
||||
expect(app.canShowInfoDrawer(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return true when selection exists and user is not in trashcan, libraries', () => {
|
||||
context.navigation.url = '/personal-files/test';
|
||||
context.selection.isEmpty = false;
|
||||
expect(app.canShowInfoDrawer(context)).toBeTrue();
|
||||
});
|
||||
});
|
||||
|
||||
describe('canManageFileVersions', () => {
|
||||
it('should return false when no file is selected', () => {
|
||||
context.selection.file = null;
|
||||
expect(app.canManageFileVersions(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return false when user is in trashcan', () => {
|
||||
context.selection.file = {} as any;
|
||||
context.navigation.url = '/trashcan/test';
|
||||
expect(app.canManageFileVersions(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return false when locked file is selected', () => {
|
||||
context.selection.file = {} as any;
|
||||
context.selection.nodes = [{ entry: { isFile: true, isLocked: true } } as any];
|
||||
context.navigation.url = '/personal-files/test';
|
||||
expect(app.canManageFileVersions(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return true when non-locked file is selected', () => {
|
||||
context.selection.file = {} as any;
|
||||
context.selection.nodes = [{ entry: { isFile: true, isLocked: false } } as any];
|
||||
context.navigation.url = '/personal-files/test';
|
||||
expect(app.canManageFileVersions(context)).toBeTrue();
|
||||
});
|
||||
});
|
||||
|
||||
describe('canToggleEditOffline', () => {
|
||||
beforeEach(() => {
|
||||
context.profile = {} as any;
|
||||
});
|
||||
|
||||
it('should return false when no file is selected', () => {
|
||||
context.selection.file = null;
|
||||
expect(app.canToggleEditOffline(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return false when user is in trashcan', () => {
|
||||
context.selection.file = {} as any;
|
||||
context.navigation.url = '/trashcan/test';
|
||||
expect(app.canToggleEditOffline(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return false when user cannot lock or unlock files', () => {
|
||||
context.navigation.url = '/personal-files/test';
|
||||
context.selection.file = { entry: { properties: { 'cm:lockType': 'WRITE_LOCK', 'cm:lockOwner': { id: 'test' } } } } as any;
|
||||
context.profile.id = 'test1';
|
||||
context.permissions = { check: () => false };
|
||||
expect(app.canToggleEditOffline(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return true when user can lock file', () => {
|
||||
context.navigation.url = '/personal-files/test';
|
||||
context.selection.file = {} as any;
|
||||
context.permissions = { check: () => true };
|
||||
expect(app.canToggleEditOffline(context)).toBeTrue();
|
||||
});
|
||||
|
||||
it('should return true when user can unlock file', () => {
|
||||
context.navigation.url = '/personal-files/test';
|
||||
context.selection.file = { entry: { properties: { 'cm:lockType': 'WRITE_LOCK', 'cm:lockOwner': { id: 'test1' } } } } as any;
|
||||
context.profile.id = 'test1';
|
||||
expect(app.canToggleEditOffline(context)).toBeTrue();
|
||||
});
|
||||
});
|
||||
|
||||
describe('canInfoPreview', () => {
|
||||
it('should return false when user is not is search results page', () => {
|
||||
context.navigation.url = '/trashcan/test';
|
||||
expect(app.canInfoPreview(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return false when multiple nodes are selected', () => {
|
||||
context.navigation.url = '/search/test';
|
||||
context.selection.isEmpty = false;
|
||||
context.selection.count = 5;
|
||||
expect(app.canInfoPreview(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return false when folder is selected', () => {
|
||||
context.navigation.url = '/search/test';
|
||||
context.selection.isEmpty = false;
|
||||
context.selection.count = 1;
|
||||
context.selection.folder = {} as any;
|
||||
expect(app.canInfoPreview(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return false when user is in preview', () => {
|
||||
context.navigation.url = '/preview/test';
|
||||
context.selection.isEmpty = false;
|
||||
context.selection.count = 1;
|
||||
context.selection.folder = null;
|
||||
expect(app.canInfoPreview(context)).toBeFalse();
|
||||
});
|
||||
|
||||
it('should return true when user is in search results page and single file is selected', () => {
|
||||
context.navigation.url = '/search/test';
|
||||
context.selection.isEmpty = false;
|
||||
context.selection.count = 1;
|
||||
context.selection.folder = null;
|
||||
context.selection.file = {} as any;
|
||||
expect(app.canInfoPreview(context)).toBeTrue();
|
||||
});
|
||||
});
|
||||
|
||||
describe('isSmartFolder', () => {
|
||||
it('should return false when there is no selection', () => {
|
||||
context.selection.isEmpty = true;
|
||||
|
@@ -94,35 +94,15 @@ export const isContentServiceEnabled = (context: AcaRuleContext): boolean => {
|
||||
return flag === true || flag === 'true';
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if upload action is supported for the given context
|
||||
* JSON ref: `app.isUploadSupported`
|
||||
*
|
||||
* @param context Rule execution context
|
||||
*/
|
||||
export const isUploadSupported = (context: AcaRuleContext): boolean =>
|
||||
[isContentServiceEnabled(context), navigation.isPersonalFiles(context) || navigation.isLibraryContent(context), canUpload(context)].every(Boolean);
|
||||
/**
|
||||
* Checks if user can copy selected node.
|
||||
* JSON ref: `app.canCopyNode`
|
||||
*
|
||||
* @param context Rule execution context
|
||||
*/
|
||||
export const canCopyNode = (context: RuleContext): boolean =>
|
||||
[hasSelection(context), navigation.isNotTrashcan(context), navigation.isNotLibraries(context)].every(Boolean);
|
||||
|
||||
/**
|
||||
* Checks if user can mark selected nodes as **Favorite**.
|
||||
* JSON ref: `app.selection.canAddFavorite`
|
||||
*/
|
||||
export function canAddFavorite(context: RuleContext): boolean {
|
||||
if (hasSelection(context)) {
|
||||
if (navigation.isFavorites(context) || navigation.isLibraries(context) || navigation.isTrashcan(context)) {
|
||||
return false;
|
||||
}
|
||||
return context.selection.nodes.some((node) => !node.entry.isFavorite);
|
||||
if (navigation.isFavorites(context) || navigation.isLibraries(context) || navigation.isTrashcan(context)) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
return context.selection.nodes.some((node) => !node.entry.isFavorite);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -130,13 +110,10 @@ export function canAddFavorite(context: RuleContext): boolean {
|
||||
* JSON ref: `app.selection.canRemoveFavorite`
|
||||
*/
|
||||
export function canRemoveFavorite(context: RuleContext): boolean {
|
||||
if (hasSelection(context) && !navigation.isTrashcan(context)) {
|
||||
if (navigation.isFavorites(context)) {
|
||||
return true;
|
||||
}
|
||||
return context.selection.nodes.every((node) => node.entry.isFavorite);
|
||||
if (navigation.isFavorites(context)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return context.selection.nodes.every((node) => node.entry.isFavorite);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -144,15 +121,14 @@ export function canRemoveFavorite(context: RuleContext): boolean {
|
||||
* JSON ref: `app.selection.file.canShare`
|
||||
*/
|
||||
export const canShareFile = (context: RuleContext): boolean =>
|
||||
[context.selection.file, navigation.isNotTrashcan(context), repository.hasQuickShareEnabled(context), !isShared(context)].every(Boolean);
|
||||
[context.selection.file, !navigation.isTrashcan(context), repository.hasQuickShareEnabled(context), !isShared(context)].every(Boolean);
|
||||
|
||||
/**
|
||||
* Checks if user can perform "Join" or "Cancel Join Request" on a library.
|
||||
* JSON ref: `canToggleJoinLibrary`
|
||||
*/
|
||||
export const canToggleJoinLibrary = (context: RuleContext): boolean =>
|
||||
[hasLibrarySelected(context), !isPrivateLibrary(context), hasNoLibraryRole(context)].every(Boolean) ||
|
||||
[hasLibrarySelected(context), isPrivateLibrary(context), hasNoLibraryRole(context), isAdmin(context)].every(Boolean);
|
||||
!isPrivateLibrary(context) || [isPrivateLibrary(context), isAdmin(context)].every(Boolean);
|
||||
|
||||
/**
|
||||
* Checks if user can edit the selected folder.
|
||||
@@ -160,7 +136,7 @@ export const canToggleJoinLibrary = (context: RuleContext): boolean =>
|
||||
*
|
||||
* @param context Rule execution context
|
||||
*/
|
||||
export const canEditFolder = (context: RuleContext): boolean => [canUpdateSelectedFolder(context), navigation.isNotTrashcan(context)].every(Boolean);
|
||||
export const canEditFolder = (context: RuleContext): boolean => [canUpdateSelectedFolder(context), !navigation.isTrashcan(context)].every(Boolean);
|
||||
|
||||
/**
|
||||
* Checks if the selected file is already shared.
|
||||
@@ -171,7 +147,7 @@ export function isShared(context: RuleContext): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (navigation.isNotTrashcan(context) && hasSelection(context) && context.selection.file) {
|
||||
if (!navigation.isTrashcan(context) && hasSelection(context) && context.selection.file) {
|
||||
return !!context.selection.file.entry?.properties?.['qshare:sharedId'];
|
||||
}
|
||||
|
||||
@@ -183,43 +159,27 @@ export function isShared(context: RuleContext): boolean {
|
||||
* JSON ref: `app.selection.canDelete`
|
||||
*/
|
||||
export function canDeleteSelection(context: RuleContext): boolean {
|
||||
if (navigation.isNotTrashcan(context) && navigation.isNotLibraries(context) && hasSelection(context)) {
|
||||
if (hasLockedFiles(context)) {
|
||||
return false;
|
||||
}
|
||||
if (hasLockedFiles(context)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// temp workaround for Favorites api
|
||||
if (navigation.isFavorites(context)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (navigation.isPreview(context)) {
|
||||
return context.permissions.check(context.selection.nodes, ['delete']);
|
||||
}
|
||||
|
||||
// workaround for Shared Files
|
||||
if (navigation.isSharedFiles(context)) {
|
||||
return context.permissions.check(context.selection.nodes, ['delete'], {
|
||||
target: 'allowableOperationsOnTarget'
|
||||
});
|
||||
}
|
||||
// temp workaround for Favorites api
|
||||
if (navigation.isFavorites(context)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (navigation.isPreview(context)) {
|
||||
return context.permissions.check(context.selection.nodes, ['delete']);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if user can un-share selected nodes.
|
||||
* JSON ref: `app.selection.canUnshare`
|
||||
*/
|
||||
export function canUnshareNodes(context: RuleContext): boolean {
|
||||
if (hasSelection(context)) {
|
||||
// workaround for Shared Files
|
||||
if (navigation.isSharedFiles(context)) {
|
||||
return context.permissions.check(context.selection.nodes, ['delete'], {
|
||||
target: 'allowableOperationsOnTarget'
|
||||
});
|
||||
}
|
||||
return false;
|
||||
|
||||
return context.permissions.check(context.selection.nodes, ['delete']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -233,7 +193,7 @@ export const hasSelection = (context: RuleContext): boolean => !context.selectio
|
||||
* JSON ref: `app.navigation.folder.canCreate`
|
||||
*/
|
||||
export function canCreateFolder(context: AcaRuleContext): boolean {
|
||||
if (isContentServiceEnabled(context) && (navigation.isPersonalFiles(context) || navigation.isLibraryContent(context))) {
|
||||
if (navigation.isPersonalFiles(context) || navigation.isLibraryContent(context)) {
|
||||
const { currentFolder } = context.navigation;
|
||||
|
||||
if (currentFolder) {
|
||||
@@ -243,32 +203,12 @@ export function canCreateFolder(context: AcaRuleContext): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if user can create a Library
|
||||
* JSON ref: `app.canCreateLibrary`
|
||||
*
|
||||
* @param context Rule execution context
|
||||
*/
|
||||
export const canCreateLibrary = (context: AcaRuleContext): boolean =>
|
||||
[isContentServiceEnabled(context), navigation.isLibraries(context)].every(Boolean);
|
||||
|
||||
/**
|
||||
* Checks if user can upload content to current folder.
|
||||
* JSON ref: `app.navigation.folder.canUpload`
|
||||
*/
|
||||
export function canUpload(context: AcaRuleContext): boolean {
|
||||
return canCreateFolder(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if user can download selected nodes (either files or folders).
|
||||
* JSON ref: `app.selection.canDownload`
|
||||
*/
|
||||
export function canDownloadSelection(context: RuleContext): boolean {
|
||||
if (hasSelection(context) && navigation.isNotTrashcan(context)) {
|
||||
return context.selection.nodes.every((node: any) => node.entry && (node.entry.isFile || node.entry.isFolder || !!node.entry.nodeId));
|
||||
}
|
||||
return false;
|
||||
return context.selection.nodes.every((node: any) => node.entry && (node.entry.isFile || node.entry.isFolder || !!node.entry.nodeId));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -300,12 +240,6 @@ export function hasLibraryRole(context: RuleContext): boolean {
|
||||
return library ? !!library.entry?.role : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the selected library has no **role** property defined.
|
||||
* JSON ref: `app.selection.hasNoLibraryRole`
|
||||
*/
|
||||
export const hasNoLibraryRole = (context: RuleContext): boolean => !hasLibraryRole(context);
|
||||
|
||||
/**
|
||||
* Checks if user has selected a file.
|
||||
* JSON ref: `app.selection.file`
|
||||
@@ -416,27 +350,11 @@ export function canUploadVersion(context: RuleContext): boolean {
|
||||
|
||||
return [
|
||||
hasFileSelected(context),
|
||||
navigation.isNotTrashcan(context),
|
||||
!navigation.isTrashcan(context),
|
||||
isWriteLocked(context) ? isUserWriteLockOwner(context) : canUpdateSelectedNode(context)
|
||||
].every(Boolean);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if user has trashcan item selected.
|
||||
* JSON ref: `isTrashcanItemSelected`
|
||||
*
|
||||
* @param context Rule execution context
|
||||
*/
|
||||
export const isTrashcanItemSelected = (context: RuleContext): boolean => [navigation.isTrashcan(context), hasSelection(context)].every(Boolean);
|
||||
|
||||
/**
|
||||
* Checks if user can view the file.
|
||||
* JSON ref: `canViewFile`
|
||||
*
|
||||
* @param context Rule execution context
|
||||
*/
|
||||
export const canViewFile = (context: RuleContext): boolean => [hasFileSelected(context), navigation.isNotTrashcan(context)].every(Boolean);
|
||||
|
||||
/**
|
||||
* Checks if user can print the file.
|
||||
* JSON ref: `canPrintFile`
|
||||
@@ -449,40 +367,13 @@ export const canPrintFile = (context: RuleContext): boolean => {
|
||||
return !mediaMimeTypes.includes(nodeEntry.content.mimeType);
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if user can **Leave** selected library.
|
||||
* JSON ref: `canLeaveLibrary`
|
||||
*
|
||||
* @param context Rule execution context
|
||||
*/
|
||||
export const canLeaveLibrary = (context: RuleContext): boolean => [hasLibrarySelected(context), hasLibraryRole(context)].every(Boolean);
|
||||
|
||||
/**
|
||||
* Checks if user can toggle shared link mode.
|
||||
* JSON ref: `canToggleSharedLink`
|
||||
*
|
||||
* @param context Rule execution context
|
||||
*/
|
||||
export const canToggleSharedLink = (context: RuleContext): boolean =>
|
||||
[hasFileSelected(context), [canShareFile(context), isShared(context)].some(Boolean)].every(Boolean);
|
||||
|
||||
/**
|
||||
* Checks if user can show **Info Drawer** for the selected node.
|
||||
* JSON ref: `canShowInfoDrawer`
|
||||
*
|
||||
* @param context Rule execution context
|
||||
*/
|
||||
export const canShowInfoDrawer = (context: RuleContext): boolean =>
|
||||
[hasSelection(context), navigation.isNotLibraries(context), navigation.isNotTrashcan(context)].every(Boolean);
|
||||
|
||||
/**
|
||||
* Checks if user can manage file versions for the selected node.
|
||||
* JSON ref: `canManageFileVersions`
|
||||
*
|
||||
* @param context Rule execution context
|
||||
*/
|
||||
export const canManageFileVersions = (context: RuleContext): boolean =>
|
||||
[hasFileSelected(context), navigation.isNotTrashcan(context), !hasLockedFiles(context)].every(Boolean);
|
||||
export const canToggleSharedLink = (context: RuleContext): boolean => [canShareFile(context), isShared(context)].some(Boolean);
|
||||
|
||||
/**
|
||||
* Checks if user can edit aspects for the selected node.
|
||||
@@ -495,29 +386,11 @@ export const canEditAspects = (context: RuleContext): boolean =>
|
||||
!isMultiselection(context),
|
||||
canUpdateSelectedNode(context),
|
||||
!isWriteLocked(context),
|
||||
navigation.isNotTrashcan(context),
|
||||
!navigation.isTrashcan(context),
|
||||
repository.isMajorVersionAvailable(context, '7')
|
||||
].every(Boolean);
|
||||
|
||||
export const canShowExpand = (context: RuleContext): boolean => [!navigation.isLibraries(context), !navigation.isDetails(context)].every(Boolean);
|
||||
|
||||
/**
|
||||
* Checks if user can manage permissions for the selected node.
|
||||
* JSON ref: `canManagePermissions`
|
||||
*
|
||||
* @param context Rule execution context
|
||||
*/
|
||||
export const canManagePermissions = (context: RuleContext): boolean =>
|
||||
[canUpdateSelectedNode(context), navigation.isNotTrashcan(context), !isSmartFolder(context), !isMultiselection(context)].every(Boolean);
|
||||
|
||||
/**
|
||||
* Checks if user can toggle **Edit Offline** mode for selected node.
|
||||
* JSON ref: `canToggleEditOffline`
|
||||
*
|
||||
* @param context Rule execution context
|
||||
*/
|
||||
export const canToggleEditOffline = (context: RuleContext): boolean =>
|
||||
[hasFileSelected(context), navigation.isNotTrashcan(context), canLockFile(context) || canUnlockFile(context)].every(Boolean);
|
||||
export const canToggleFileLock = (context: RuleContext): boolean => [canLockFile(context) || canUnlockFile(context)].some(Boolean);
|
||||
|
||||
/**
|
||||
* @deprecated Uses workarounds for for recent files and search api issues.
|
||||
@@ -546,23 +419,7 @@ export const canShowLogout = (context: AcaRuleContext): boolean => !context.with
|
||||
*
|
||||
* @param context Rule execution context
|
||||
*/
|
||||
export const isLibraryManager = (context: RuleContext): boolean =>
|
||||
hasLibrarySelected(context) && (context.selection.library?.entry.role === 'SiteManager' || isAdmin(context));
|
||||
|
||||
/**
|
||||
* Checks if the preview button for search results can be showed
|
||||
* JSON ref: `canInfoPreview`
|
||||
*
|
||||
* @param context Rule execution context
|
||||
*/
|
||||
export const canInfoPreview = (context: RuleContext): boolean => {
|
||||
const isSearchResult = navigation.isSearchResults(context);
|
||||
const isNotMultiselect = !isMultiselection(context);
|
||||
const isFileSelected = !hasFolderSelected(context);
|
||||
const isPreview = !navigation.isPreview(context);
|
||||
|
||||
return isSearchResult && isNotMultiselect && isFileSelected && isPreview;
|
||||
};
|
||||
export const isLibraryManager = (context: RuleContext): boolean => context.selection.library?.entry.role === 'SiteManager' || isAdmin(context);
|
||||
|
||||
/**
|
||||
* Checks if the file can be opened with MS Office
|
||||
@@ -648,4 +505,4 @@ export const canDisplayKnowledgeRetrievalButton = (context: AcaRuleContext): boo
|
||||
navigation.isSharedFiles(context) ||
|
||||
navigation.isRecentFiles(context) ||
|
||||
navigation.isFavorites(context) ||
|
||||
((navigation.isSearchResults(context) || navigation.isLibraryContent(context)) && navigation.isNotLibraries(context)));
|
||||
((navigation.isSearchResults(context) || navigation.isLibraryContent(context)) && !navigation.isLibraries(context)));
|
||||
|
@@ -59,28 +59,6 @@ describe('navigation.evaluators', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('isNotFavorites', () => {
|
||||
it('should return [true] if url is not `/favorites`', () => {
|
||||
const context: any = {
|
||||
navigation: {
|
||||
url: '/some/path'
|
||||
}
|
||||
};
|
||||
|
||||
expect(app.isNotFavorites(context)).toBe(true);
|
||||
});
|
||||
|
||||
it('should return [false] if url starts with `/favorites`', () => {
|
||||
const context: any = {
|
||||
navigation: {
|
||||
url: '/favorites/path'
|
||||
}
|
||||
};
|
||||
|
||||
expect(app.isNotFavorites(context)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isSharedFiles', () => {
|
||||
it('should return [true] if path starts with `/shared`', () => {
|
||||
const context: any = {
|
||||
@@ -103,28 +81,6 @@ describe('navigation.evaluators', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('isNotSharedFiles', () => {
|
||||
it('should return [true] if path does not contain `/shared`', () => {
|
||||
const context: any = {
|
||||
navigation: {
|
||||
url: '/some/path/'
|
||||
}
|
||||
};
|
||||
|
||||
expect(app.isNotSharedFiles(context)).toBe(true);
|
||||
});
|
||||
|
||||
it('should return [false] if path contains `/shared`', () => {
|
||||
const context: any = {
|
||||
navigation: {
|
||||
url: '/shared/path/'
|
||||
}
|
||||
};
|
||||
|
||||
expect(app.isNotSharedFiles(context)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isTrashcan', () => {
|
||||
it('should return [true] if url starts with `/trashcan`', () => {
|
||||
const context: any = {
|
||||
@@ -147,28 +103,6 @@ describe('navigation.evaluators', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('isNotTrashcan', () => {
|
||||
it('should return [true] if url does not start with `/trashcan`', () => {
|
||||
const context: any = {
|
||||
navigation: {
|
||||
url: '/path/trashcan'
|
||||
}
|
||||
};
|
||||
|
||||
expect(app.isNotTrashcan(context)).toBe(true);
|
||||
});
|
||||
|
||||
it('should return [false] if url does start with `/trashcan`', () => {
|
||||
const context: any = {
|
||||
navigation: {
|
||||
url: '/trashcan'
|
||||
}
|
||||
};
|
||||
|
||||
expect(app.isNotTrashcan(context)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isPersonalFiles', () => {
|
||||
it('should return [true] if url starts with `/personal-files`', () => {
|
||||
const context: any = {
|
||||
@@ -213,18 +147,6 @@ describe('navigation.evaluators', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('isNotLibraries', () => {
|
||||
it('should return [true] if url does not end with `/libraries`', () => {
|
||||
const context: any = {
|
||||
navigation: {
|
||||
url: '/libraries/path'
|
||||
}
|
||||
};
|
||||
|
||||
expect(app.isNotLibraries(context)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isDetails', () => {
|
||||
it('should return true if url includes with `/details`', () => {
|
||||
const context: any = {
|
||||
@@ -247,28 +169,6 @@ describe('navigation.evaluators', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('isNotDetails', () => {
|
||||
it('should return true if url does not include `/details`', () => {
|
||||
const context: any = {
|
||||
navigation: {
|
||||
url: '/path'
|
||||
}
|
||||
};
|
||||
|
||||
expect(app.isNotDetails(context)).toBe(true);
|
||||
});
|
||||
|
||||
it('should return false if url includes `/details`', () => {
|
||||
const context: any = {
|
||||
navigation: {
|
||||
url: 'personal-files/details/path'
|
||||
}
|
||||
};
|
||||
|
||||
expect(app.isNotDetails(context)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isRecentFiles', () => {
|
||||
it('should return [true] if url starts with `/recent-files`', () => {
|
||||
const context: any = {
|
||||
@@ -312,90 +212,4 @@ describe('navigation.evaluators', () => {
|
||||
expect(app.isSearchResults(context)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isSharedPreview', () => {
|
||||
it('should return [true] if url starts with `/shared` and contains `viewer:view', () => {
|
||||
const context: any = {
|
||||
navigation: {
|
||||
url: '/shared/(viewer:view)'
|
||||
}
|
||||
};
|
||||
|
||||
expect(app.isSharedPreview(context)).toBe(true);
|
||||
});
|
||||
|
||||
it('should return [false] if url does not start with `/shared`', () => {
|
||||
const context: any = {
|
||||
navigation: {
|
||||
url: '/path/shared/(viewer:view)'
|
||||
}
|
||||
};
|
||||
|
||||
expect(app.isSharedPreview(context)).toBe(false);
|
||||
});
|
||||
|
||||
it('should return [false] if url starts with `/shared` and does not includes `viewer:view`', () => {
|
||||
const context: any = {
|
||||
navigation: {
|
||||
url: '/shared/something'
|
||||
}
|
||||
};
|
||||
|
||||
expect(app.isSharedPreview(context)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isFavoritesPreview', () => {
|
||||
it('should return [true] if url starts with `/favorites` and includes `viewer:view`', () => {
|
||||
const context: any = {
|
||||
navigation: {
|
||||
url: '/favorites/(viewer:view)'
|
||||
}
|
||||
};
|
||||
|
||||
expect(app.isFavoritesPreview(context)).toBe(true);
|
||||
});
|
||||
|
||||
it('should return [false] if url does not start with `/favorites`', () => {
|
||||
const context: any = {
|
||||
navigation: {
|
||||
url: '/path/favorites/(viewer:view)'
|
||||
}
|
||||
};
|
||||
|
||||
expect(app.isFavoritesPreview(context)).toBe(false);
|
||||
});
|
||||
|
||||
it('should return [false] if url starts with `/favorites` and does not include `viewer:view`', () => {
|
||||
const context: any = {
|
||||
navigation: {
|
||||
url: '/favorites/other'
|
||||
}
|
||||
};
|
||||
|
||||
expect(app.isFavoritesPreview(context)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isSharedFileViewer', () => {
|
||||
it('should return [true] if url starts with `/preview/s/`', () => {
|
||||
const context: any = {
|
||||
navigation: {
|
||||
url: '/preview/s/path'
|
||||
}
|
||||
};
|
||||
|
||||
expect(app.isSharedFileViewer(context)).toBe(true);
|
||||
});
|
||||
|
||||
it('should return [false] if url does not start with `/preview/s/`', () => {
|
||||
const context: any = {
|
||||
navigation: {
|
||||
url: '/path/preview/s/'
|
||||
}
|
||||
};
|
||||
|
||||
expect(app.isSharedFileViewer(context)).toBe(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -42,12 +42,6 @@ export function isFavorites(context: RuleContext): boolean {
|
||||
return url?.startsWith('/favorites') && !isPreview(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the activated route is not **Favorites**.
|
||||
* JSON ref: `app.navigation.isNotFavorites`
|
||||
*/
|
||||
export const isNotFavorites = (context: RuleContext): boolean => !isFavorites(context);
|
||||
|
||||
/**
|
||||
* Checks if a **Shared Files** route is activated.
|
||||
* JSON ref: `app.navigation.isSharedFiles`
|
||||
@@ -57,12 +51,6 @@ export function isSharedFiles(context: RuleContext): boolean {
|
||||
return url?.startsWith('/shared') && !isPreview(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the activated route is not **Shared Files**.
|
||||
* JSON ref: `app.navigation.isNotSharedFiles`
|
||||
*/
|
||||
export const isNotSharedFiles = (context: RuleContext): boolean => !isSharedFiles(context);
|
||||
|
||||
/**
|
||||
* Checks if a **Trashcan** route is activated.
|
||||
* JSON ref: `app.navigation.isTrashcan`
|
||||
@@ -72,12 +60,6 @@ export function isTrashcan(context: RuleContext): boolean {
|
||||
return url?.startsWith('/trashcan');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the activated route is not **Trashcan**.
|
||||
* JSON ref: `app.navigation.isNotTrashcan`
|
||||
*/
|
||||
export const isNotTrashcan = (context: RuleContext): boolean => !isTrashcan(context);
|
||||
|
||||
/**
|
||||
* Checks if a **Personal Files** route is activated.
|
||||
* JSON ref: `app.navigation.isPersonalFiles`
|
||||
@@ -87,15 +69,6 @@ export function isPersonalFiles(context: RuleContext): boolean {
|
||||
return url?.startsWith('/personal-files');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a **Library Files** route is activated.
|
||||
* JSON ref: `app.navigation.isLibraryFiles`
|
||||
*/
|
||||
export function isLibraryFiles(context: RuleContext): boolean {
|
||||
const { url } = context.navigation;
|
||||
return url?.startsWith('/libraries');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a **Library Files** or **Library Search Result** route is activated.
|
||||
* JSON ref: `app.navigation.isLibraryFiles`
|
||||
@@ -115,18 +88,6 @@ export function isDetails(context: RuleContext): boolean {
|
||||
return url?.includes('/details');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the activated route is not **Details**.
|
||||
* JSON ref: `app.navigation.isNotDetails`
|
||||
*/
|
||||
export const isNotDetails = (context: RuleContext): boolean => !isDetails(context);
|
||||
|
||||
/**
|
||||
* Checks if the activated route is neither **Libraries** nor **Library Search Results**.
|
||||
* JSON ref: `app.navigation.isNotLibraries`
|
||||
*/
|
||||
export const isNotLibraries = (context: RuleContext): boolean => !isLibraries(context);
|
||||
|
||||
/**
|
||||
* Checks if a **Recent Files** route is activated.
|
||||
* JSON ref: `app.navigation.isRecentFiles`
|
||||
@@ -136,12 +97,6 @@ export function isRecentFiles(context: RuleContext): boolean {
|
||||
return url?.startsWith('/recent-files');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the activated route is not **Recent Files**.
|
||||
* JSON ref: `app.navigation.isNotRecentFiles`
|
||||
*/
|
||||
export const isNotRecentFiles = (context: RuleContext): boolean => !isRecentFiles(context);
|
||||
|
||||
/**
|
||||
* Checks if a **Search Results** route is activated.
|
||||
* JSON ref: `app.navigation.isSearchResults`
|
||||
@@ -153,36 +108,3 @@ export function isSearchResults(
|
||||
const { url } = context.navigation;
|
||||
return url?.startsWith('/search');
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the activated route is not **Search Results**.
|
||||
* JSON ref: `app.navigation.isNotSearchResults`
|
||||
*/
|
||||
export const isNotSearchResults = (context: RuleContext): boolean => !isSearchResults(context);
|
||||
|
||||
/**
|
||||
* Checks if a **Shared Preview** route is activated.
|
||||
* JSON ref: `app.navigation.isSharedPreview`
|
||||
*/
|
||||
export function isSharedPreview(context: RuleContext): boolean {
|
||||
const { url } = context.navigation;
|
||||
return url?.startsWith('/shared/preview/') || (url?.startsWith('/shared') && url?.includes('viewer:view'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a **Favorites Preview** route is activated.
|
||||
* JSON ref: `app.navigation.isFavoritesPreview`
|
||||
*/
|
||||
export function isFavoritesPreview(context: RuleContext): boolean {
|
||||
const { url } = context.navigation;
|
||||
return url?.startsWith('/favorites/preview/') || (url?.startsWith('/favorites') && url?.includes('viewer:view'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a **Shared File Preview** route is activated.
|
||||
* JSON ref: `app.navigation.isFavoritesPreview`
|
||||
*/
|
||||
export function isSharedFileViewer(context: RuleContext): boolean {
|
||||
const { url } = context.navigation;
|
||||
return url?.startsWith('/preview/s/');
|
||||
}
|
||||
|
@@ -1087,6 +1087,16 @@ describe('AppExtensionService', () => {
|
||||
expect(service.evaluateRule('rule1')).toBeTrue();
|
||||
});
|
||||
|
||||
it('should evaluate list of rules', () => {
|
||||
extensions.setEvaluators({
|
||||
rule1: () => true,
|
||||
rule2: () => true,
|
||||
rule3: () => true
|
||||
});
|
||||
|
||||
expect(service.evaluateRule(['rule1', 'rule2', 'rule3'])).toBeTrue();
|
||||
});
|
||||
|
||||
it('should not evaluate missing rule and return [false] by default', () => {
|
||||
expect(service.evaluateRule('missing')).toBeFalse();
|
||||
});
|
||||
|
@@ -532,11 +532,18 @@ export class AppExtensionService implements RuleContext {
|
||||
}
|
||||
|
||||
// todo: move to ADF/RuleService
|
||||
evaluateRule(ruleId: string, ...args: any[]): boolean {
|
||||
const evaluator = this.getEvaluator(ruleId);
|
||||
|
||||
if (evaluator) {
|
||||
return evaluator(this, ...args);
|
||||
evaluateRule(ruleId: string | string[], ...args: any[]): boolean {
|
||||
let evaluatorList: RuleEvaluator[] = [];
|
||||
if (Array.isArray(ruleId)) {
|
||||
evaluatorList = ruleId.filter((rule) => !!this.getEvaluator(rule)).map((rule) => this.getEvaluator(rule));
|
||||
} else {
|
||||
const evaluator = this.getEvaluator(ruleId);
|
||||
if (evaluator) {
|
||||
evaluatorList.push(evaluator);
|
||||
}
|
||||
}
|
||||
if (evaluatorList?.length > 0) {
|
||||
return evaluatorList.every((evaluator) => evaluator(this, ...args));
|
||||
}
|
||||
|
||||
return false;
|
||||
|
Reference in New Issue
Block a user