mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2026-09-16 18:13:06 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf62196fc4 | ||
|
|
22d3179a55 | ||
|
|
17323b0abb | ||
|
|
81787d5202 | ||
|
|
e5ca7d2069 | ||
|
|
6787ef4582 | ||
|
|
6988c1f458 | ||
|
|
15fdbc7e29 | ||
|
|
e2c116c25a | ||
|
|
f2df3c4143 | ||
|
|
168bb0b6ca | ||
|
|
c0194029c7 | ||
|
|
625cf2b85a | ||
|
|
622cf8bdee | ||
|
|
f0a11fdab0 | ||
|
|
479cc8b545 | ||
|
|
54fa5d8864 | ||
|
|
0891a60f4d | ||
|
|
a01a1b9e9a | ||
|
|
34c82f4a49 | ||
|
|
41a788d974 | ||
|
|
00c05315a2 | ||
|
|
10361b9065 | ||
|
|
08da9ae2c3 | ||
|
|
057e0bcd7c | ||
|
|
bac7cc98e1 | ||
|
|
7c127eb957 | ||
|
|
fe8f4a5e74 | ||
|
|
adf5a5e008 | ||
|
|
a29f63cd9b | ||
|
|
94fb61541c | ||
|
|
3687cc58e0 | ||
|
|
93fd0bec6c | ||
|
|
9278d9296f | ||
|
|
85ddcdf22c | ||
|
|
0b677e7189 | ||
|
|
0b56a4858f | ||
|
|
15f82c812c | ||
|
|
54e95bc5f7 | ||
|
|
81f0df3da1 | ||
|
|
5d72597d7d |
+188
@@ -0,0 +1,188 @@
|
||||
module.exports = {
|
||||
root: true,
|
||||
ignorePatterns: [
|
||||
'projects/**/*',
|
||||
'**/node_modules/**/*',
|
||||
'lib/cli/node_modules/**/*',
|
||||
'**/node_modules',
|
||||
'**/docker',
|
||||
'**/assets',
|
||||
'**/scripts',
|
||||
'**/docs'
|
||||
],
|
||||
plugins: ['@nrwl/nx'],
|
||||
overrides: [
|
||||
{
|
||||
files: ['*.ts'],
|
||||
parserOptions: {
|
||||
project: ['tsconfig.json', 'e2e/tsconfig.e2e.json'],
|
||||
createDefaultProgram: true
|
||||
},
|
||||
extends: [
|
||||
'plugin:@nrwl/nx/typescript',
|
||||
'plugin:@nrwl/nx/angular',
|
||||
'plugin:@cspell/recommended',
|
||||
'plugin:@angular-eslint/ng-cli-compat',
|
||||
'plugin:@angular-eslint/ng-cli-compat--formatting-add-on',
|
||||
'plugin:@angular-eslint/template/process-inline-templates',
|
||||
'plugin:jsdoc/recommended-typescript-error'
|
||||
],
|
||||
plugins: [
|
||||
'eslint-plugin-unicorn',
|
||||
'eslint-plugin-rxjs',
|
||||
'prettier',
|
||||
'ban',
|
||||
'license-header',
|
||||
'@cspell',
|
||||
'eslint-plugin-import',
|
||||
'@angular-eslint/eslint-plugin',
|
||||
'@typescript-eslint',
|
||||
'jsdoc'
|
||||
],
|
||||
rules: {
|
||||
// Uncomment this to enable prettier checks as part of the ESLint
|
||||
// 'prettier/prettier': 'error',
|
||||
'ban/ban': [
|
||||
'error',
|
||||
{ name: 'eval', message: 'Calls to eval is not allowed.' },
|
||||
{ name: 'fdescribe', message: 'Calls to fdescribe is not allowed' },
|
||||
{ name: 'fit', message: 'Calls to fit is not allowed' },
|
||||
{ name: 'xit', message: 'Calls to xit is not allowed' },
|
||||
{ name: 'xdescribe', message: 'Calls to xdescribe is not allowed' },
|
||||
{ name: ['test', 'only'], message: 'Calls to test.only is not allowed' },
|
||||
{ name: ['describe', 'only'], message: 'Calls to describe.only is not allowed' }
|
||||
],
|
||||
'@angular-eslint/component-selector': [
|
||||
'error',
|
||||
{
|
||||
type: 'element',
|
||||
prefix: ['adf', 'app'],
|
||||
style: 'kebab-case'
|
||||
}
|
||||
],
|
||||
'@angular-eslint/directive-selector': [
|
||||
'error',
|
||||
{
|
||||
type: ['element', 'attribute'],
|
||||
prefix: ['adf', 'app'],
|
||||
style: 'kebab-case'
|
||||
}
|
||||
],
|
||||
'@angular-eslint/no-host-metadata-property': 'off',
|
||||
'@angular-eslint/no-input-prefix': 'error',
|
||||
'@typescript-eslint/consistent-type-definitions': 'error',
|
||||
'@typescript-eslint/dot-notation': 'off',
|
||||
'@typescript-eslint/explicit-member-accessibility': [
|
||||
'off',
|
||||
{
|
||||
accessibility: 'explicit'
|
||||
}
|
||||
],
|
||||
'@typescript-eslint/await-thenable': 'error',
|
||||
'@typescript-eslint/prefer-optional-chain': 'warn',
|
||||
'@typescript-eslint/no-inferrable-types': 'off',
|
||||
'@typescript-eslint/no-require-imports': 'off',
|
||||
'@typescript-eslint/no-var-requires': 'error',
|
||||
'@typescript-eslint/naming-convention': [
|
||||
'error',
|
||||
{
|
||||
selector: [
|
||||
'classProperty',
|
||||
'objectLiteralProperty',
|
||||
'typeProperty',
|
||||
'classMethod',
|
||||
'objectLiteralMethod',
|
||||
'typeMethod',
|
||||
'accessor',
|
||||
'enumMember'
|
||||
],
|
||||
format: null,
|
||||
modifiers: ['requiresQuotes']
|
||||
}
|
||||
],
|
||||
'@typescript-eslint/member-ordering': 'off',
|
||||
'prefer-arrow/prefer-arrow-functions': 'off',
|
||||
'prefer-promise-reject-errors': 'error',
|
||||
'brace-style': 'off',
|
||||
'@typescript-eslint/brace-style': 'error',
|
||||
'comma-dangle': 'error',
|
||||
'default-case': 'error',
|
||||
'import/order': 'off',
|
||||
'max-len': [
|
||||
'error',
|
||||
{
|
||||
code: 240
|
||||
}
|
||||
],
|
||||
'no-bitwise': 'off',
|
||||
'no-console': [
|
||||
'error',
|
||||
{
|
||||
allow: [
|
||||
'warn',
|
||||
'dir',
|
||||
'timeLog',
|
||||
'assert',
|
||||
'clear',
|
||||
'count',
|
||||
'countReset',
|
||||
'group',
|
||||
'groupEnd',
|
||||
'table',
|
||||
'dirxml',
|
||||
'error',
|
||||
'groupCollapsed',
|
||||
'Console',
|
||||
'profile',
|
||||
'profileEnd',
|
||||
'timeStamp',
|
||||
'context'
|
||||
]
|
||||
}
|
||||
],
|
||||
'no-duplicate-imports': 'error',
|
||||
'no-multiple-empty-lines': 'error',
|
||||
'no-redeclare': 'error',
|
||||
'no-return-await': 'error',
|
||||
'rxjs/no-create': 'error',
|
||||
'rxjs/no-subject-unsubscribe': 'error',
|
||||
'rxjs/no-subject-value': 'error',
|
||||
'rxjs/no-unsafe-takeuntil': 'error',
|
||||
'unicorn/filename-case': 'error',
|
||||
'@typescript-eslint/no-unused-expressions': [
|
||||
'error',
|
||||
{
|
||||
allowShortCircuit: true,
|
||||
allowTernary: true
|
||||
}
|
||||
],
|
||||
'license-header/header': [
|
||||
'error',
|
||||
[
|
||||
'/*!',
|
||||
' * @license',
|
||||
' * Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.',
|
||||
' *',
|
||||
' * Licensed under the Apache License, Version 2.0 (the "License");',
|
||||
' * you may not use this file except in compliance with the License.',
|
||||
' * You may obtain a copy of the License at',
|
||||
' *',
|
||||
' * http://www.apache.org/licenses/LICENSE-2.0',
|
||||
' *',
|
||||
' * Unless required by applicable law or agreed to in writing, software',
|
||||
' * distributed under the License is distributed on an "AS IS" BASIS,',
|
||||
' * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.',
|
||||
' * See the License for the specific language governing permissions and',
|
||||
' * limitations under the License.',
|
||||
' */'
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
files: ['*.html'],
|
||||
extends: ['plugin:@angular-eslint/template/recommended'],
|
||||
rules: {}
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -60,8 +60,9 @@ runs:
|
||||
echo "Setting up CI flags for Push develop patch"
|
||||
else
|
||||
echo "Setting up CI flags for Push on develop branch"
|
||||
base=$(git describe --tags $(git rev-list --tags --max-count=1))
|
||||
echo "NX_CALCULATION_FLAGS=--base=$base --head=$HEAD_HASH" >> $GITHUB_ENV
|
||||
# base=$(git describe --tags $(git rev-list --tags --max-count=1))
|
||||
# we publish always all the libs until we don't handle partial release
|
||||
echo "NX_CALCULATION_FLAGS=--all" >> $GITHUB_ENV
|
||||
fi
|
||||
echo "BREAK_ACTION=true" >> $GITHUB_ENV
|
||||
|
||||
|
||||
@@ -153,7 +153,7 @@ runs:
|
||||
echo $PROXY_HOST_BPM
|
||||
echo "GIT_HASH=$GIT_HASH" >> $GITHUB_ENV
|
||||
|
||||
- name: run test
|
||||
- name: run test
|
||||
id: e2e_run
|
||||
if: ${{ steps.determine-affected.outputs.isAffected == 'true' }}
|
||||
env:
|
||||
|
||||
@@ -392,15 +392,6 @@ jobs:
|
||||
check-cs-env: "true"
|
||||
check-ps-cloud-env: "true"
|
||||
deps: "testing"
|
||||
- description: "Process Cloud: People"
|
||||
test-id: "process-services-cloud"
|
||||
folder: "process-services-cloud/people"
|
||||
provider: "ALL"
|
||||
auth: "OAUTH"
|
||||
apa-proxy: true
|
||||
check-cs-env: "true"
|
||||
check-ps-cloud-env: "true"
|
||||
deps: "testing"
|
||||
- description: "Process Cloud: Process"
|
||||
test-id: "process-services-cloud"
|
||||
folder: "process-services-cloud/process"
|
||||
|
||||
Vendored
+1
-1
@@ -10,7 +10,7 @@
|
||||
"name": "e2e",
|
||||
"program": "${workspaceFolder}/node_modules/protractor/bin/protractor",
|
||||
"args": [
|
||||
"`${workspaceFolder}/.vscode/closest-config-finder.sh ${file} e2e/protractor.conf.js`",
|
||||
"./e2e/protractor.conf.js",
|
||||
"--specs=${file}"
|
||||
],
|
||||
"envFile": "${workspaceFolder}/.env",
|
||||
|
||||
+3
-4
@@ -1019,11 +1019,10 @@
|
||||
"prefix": "adf",
|
||||
"architect": {
|
||||
"build": {
|
||||
"builder": "@nrwl/workspace:run-commands",
|
||||
"builder": "nx:run-commands",
|
||||
"options": {
|
||||
"commands": [
|
||||
"cd lib/cli && npm i && npm run dist"
|
||||
],
|
||||
"command":
|
||||
"cd lib/cli && npm i && npm run dist",
|
||||
"stylePreprocessorOptions": {
|
||||
"includePaths": [
|
||||
"lib", "lib/core/src/lib"
|
||||
|
||||
+2
-1
@@ -141,7 +141,8 @@
|
||||
"webscript",
|
||||
"Whitespaces",
|
||||
"xdescribe",
|
||||
"xsrf"
|
||||
"xsrf",
|
||||
"BPMECM"
|
||||
],
|
||||
"dictionaries": [
|
||||
"html",
|
||||
|
||||
@@ -25,7 +25,7 @@ const fs = require("fs");
|
||||
const os = require("os");
|
||||
const cp = require("child_process");
|
||||
const isWindows = os.platform() === "win32";
|
||||
const { output } = require("@nrwl/workspace");
|
||||
const output = require('nx/src/utils/output').output;
|
||||
|
||||
/**
|
||||
* Paths to files being patched
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "Alfresco-ADF-Angular-Demo",
|
||||
"description": "Demo shell for Alfresco Angular components",
|
||||
"version": "6.4.0",
|
||||
"version": "6.5.2",
|
||||
"author": "Hyland Software, Inc. and its affiliates",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -18,11 +18,11 @@
|
||||
import { Component, ViewEncapsulation, OnInit } from '@angular/core';
|
||||
import {
|
||||
AuthenticationService,
|
||||
AlfrescoApiService,
|
||||
PageTitleService
|
||||
} from '@alfresco/adf-core';
|
||||
import { Router } from '@angular/router';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { AdfHttpClient } from '@alfresco/adf-core/api';
|
||||
|
||||
@Component({
|
||||
selector: 'app-root',
|
||||
@@ -33,7 +33,7 @@ import { MatDialog } from '@angular/material/dialog';
|
||||
export class AppComponent implements OnInit {
|
||||
|
||||
constructor(private pageTitleService: PageTitleService,
|
||||
private alfrescoApiService: AlfrescoApiService,
|
||||
private adfHttpClient: AdfHttpClient,
|
||||
private authenticationService: AuthenticationService,
|
||||
private router: Router,
|
||||
private dialogRef: MatDialog) {
|
||||
@@ -43,7 +43,7 @@ export class AppComponent implements OnInit {
|
||||
ngOnInit() {
|
||||
this.pageTitleService.setTitle('title');
|
||||
|
||||
this.alfrescoApiService.getInstance().on('error', (error) => {
|
||||
this.adfHttpClient.on('error', (error) => {
|
||||
if (error.status === 401) {
|
||||
if (!this.authenticationService.isLoggedIn()) {
|
||||
this.dialogRef.closeAll();
|
||||
|
||||
@@ -74,7 +74,7 @@ import { UserInfoComponent } from './components/app-layout/user-info/user-info.c
|
||||
environment.e2e ? NoopAnimationsModule : BrowserAnimationsModule,
|
||||
ReactiveFormsModule,
|
||||
RouterModule.forRoot(appRoutes, { useHash: true, relativeLinkResolution: 'legacy' }),
|
||||
...(environment.oidc ? [AuthModule.forRoot({ useHash: true })] : []),
|
||||
AuthModule.forRoot({ useHash: true }),
|
||||
FormsModule,
|
||||
HttpClientModule,
|
||||
MaterialModule,
|
||||
|
||||
@@ -17,7 +17,13 @@
|
||||
|
||||
import { EcmUserModel, PeopleContentService } from '@alfresco/adf-content-services';
|
||||
import { BpmUserModel, PeopleProcessService } from '@alfresco/adf-process-services';
|
||||
import { AuthenticationService, IdentityUserModel, IdentityUserService, UserInfoMode } from '@alfresco/adf-core';
|
||||
import {
|
||||
AuthenticationService,
|
||||
BasicAlfrescoAuthService,
|
||||
IdentityUserModel,
|
||||
IdentityUserService,
|
||||
UserInfoMode
|
||||
} from '@alfresco/adf-core';
|
||||
import { Component, OnInit, Input } from '@angular/core';
|
||||
import { MenuPositionX, MenuPositionY } from '@angular/material/menu';
|
||||
import { Observable, of } from 'rxjs';
|
||||
@@ -46,6 +52,7 @@ export class UserInfoComponent implements OnInit {
|
||||
constructor(private peopleContentService: PeopleContentService,
|
||||
private peopleProcessService: PeopleProcessService,
|
||||
private identityUserService: IdentityUserService,
|
||||
private basicAlfrescoAuthService: BasicAlfrescoAuthService,
|
||||
private authService: AuthenticationService) {
|
||||
}
|
||||
|
||||
@@ -77,7 +84,7 @@ export class UserInfoComponent implements OnInit {
|
||||
}
|
||||
|
||||
get isLoggedIn(): boolean {
|
||||
if (this.authService.isKerberosEnabled()) {
|
||||
if (this.basicAlfrescoAuthService.isKerberosEnabled()) {
|
||||
return true;
|
||||
}
|
||||
return this.authService.isLoggedIn();
|
||||
@@ -96,15 +103,15 @@ export class UserInfoComponent implements OnInit {
|
||||
}
|
||||
|
||||
private isAllLoggedIn() {
|
||||
return (this.authService.isEcmLoggedIn() && this.authService.isBpmLoggedIn()) || (this.authService.isALLProvider() && this.authService.isKerberosEnabled());
|
||||
return (this.authService.isEcmLoggedIn() && this.authService.isBpmLoggedIn()) || (this.authService.isALLProvider() && this.basicAlfrescoAuthService.isKerberosEnabled());
|
||||
}
|
||||
|
||||
private isBpmLoggedIn() {
|
||||
return this.authService.isBpmLoggedIn() || (this.authService.isECMProvider() && this.authService.isKerberosEnabled());
|
||||
return this.authService.isBpmLoggedIn() || (this.authService.isECMProvider() && this.basicAlfrescoAuthService.isKerberosEnabled());
|
||||
}
|
||||
|
||||
private isEcmLoggedIn() {
|
||||
return this.authService.isEcmLoggedIn() || (this.authService.isECMProvider() && this.authService.isKerberosEnabled());
|
||||
return this.authService.isEcmLoggedIn() || (this.authService.isECMProvider() && this.basicAlfrescoAuthService.isKerberosEnabled());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,17 +1,15 @@
|
||||
<div class="app-main-content">
|
||||
<h1>CardView Component</h1>
|
||||
|
||||
<mat-card class="app-card-view">
|
||||
<adf-card-view
|
||||
[properties]="properties"
|
||||
[editable]="isEditable"
|
||||
[displayClearAction]="showClearDateAction"
|
||||
[displayNoneOption]="showNoneOption"
|
||||
[displayLabelForChips]="showLabelForChips">
|
||||
</adf-card-view>
|
||||
</mat-card>
|
||||
<adf-card-view
|
||||
[properties]="properties"
|
||||
[editable]="isEditable"
|
||||
[displayClearAction]="showClearDateAction"
|
||||
[displayNoneOption]="showNoneOption"
|
||||
[displayLabelForChips]="showLabelForChips">
|
||||
</adf-card-view>
|
||||
|
||||
<div class="app-console" #console>
|
||||
<div class="app-console">
|
||||
<h3>Changes log:</h3>
|
||||
<p *ngFor="let log of logs">{{ log }}</p>
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
padding: 0 15px;
|
||||
}
|
||||
|
||||
.app-card-view {
|
||||
adf-card-view {
|
||||
width: 30%;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, OnInit, ElementRef, ViewChild, OnDestroy } from '@angular/core';
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import {
|
||||
CardViewTextItemModel,
|
||||
CardViewDateItemModel,
|
||||
@@ -39,9 +39,6 @@ import { takeUntil } from 'rxjs/operators';
|
||||
styleUrls: ['./card-view.component.scss']
|
||||
})
|
||||
export class CardViewComponent implements OnInit, OnDestroy {
|
||||
|
||||
@ViewChild('console', { static: true }) console: ElementRef;
|
||||
|
||||
isEditable = true;
|
||||
properties: any;
|
||||
logs: string[];
|
||||
@@ -51,8 +48,7 @@ export class CardViewComponent implements OnInit, OnDestroy {
|
||||
|
||||
private onDestroy$ = new Subject<boolean>();
|
||||
|
||||
constructor(private cardViewUpdateService: CardViewUpdateService,
|
||||
private decimalNumberPipe: DecimalNumberPipe) {
|
||||
constructor(private cardViewUpdateService: CardViewUpdateService, private decimalNumberPipe: DecimalNumberPipe) {
|
||||
this.logs = [];
|
||||
this.createCard();
|
||||
}
|
||||
@@ -62,9 +58,7 @@ export class CardViewComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.cardViewUpdateService.itemUpdated$
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe(this.onItemChange.bind(this));
|
||||
this.cardViewUpdateService.itemUpdated$.pipe(takeUntil(this.onDestroy$)).subscribe(this.onItemChange.bind(this));
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
@@ -192,20 +186,29 @@ export class CardViewComponent implements OnInit, OnDestroy {
|
||||
}),
|
||||
new CardViewKeyValuePairsItemModel({
|
||||
label: 'CardView Key-Value Pairs Item',
|
||||
value: [{ name: 'hey', value: 'you' }, { name: 'hey', value: 'you' }],
|
||||
value: [
|
||||
{ name: 'hey', value: 'you' },
|
||||
{ name: 'hey', value: 'you' }
|
||||
],
|
||||
key: 'key-value-pairs',
|
||||
editable: this.isEditable
|
||||
}),
|
||||
new CardViewKeyValuePairsItemModel({
|
||||
label: 'CardView Key-Value Pairs Item',
|
||||
value: [{ name: 'hey', value: 'you' }, { name: 'hey', value: 'you' }],
|
||||
value: [
|
||||
{ name: 'hey', value: 'you' },
|
||||
{ name: 'hey', value: 'you' }
|
||||
],
|
||||
key: 'key-value-pairs',
|
||||
editable: false
|
||||
}),
|
||||
new CardViewSelectItemModel({
|
||||
label: 'CardView Select Item',
|
||||
value: 'one',
|
||||
options$: of([{ key: 'one', label: 'One' }, { key: 'two', label: 'Two' }]),
|
||||
options$: of([
|
||||
{ key: 'one', label: 'One' },
|
||||
{ key: 'two', label: 'Two' }
|
||||
]),
|
||||
key: 'select',
|
||||
editable: this.isEditable
|
||||
}),
|
||||
@@ -253,7 +256,6 @@ export class CardViewComponent implements OnInit, OnDestroy {
|
||||
}
|
||||
|
||||
this.logs.push(`[${notification.target.label}] - ${value}`);
|
||||
this.console.nativeElement.scrollTop = this.console.nativeElement.scrollHeight;
|
||||
}
|
||||
|
||||
toggleEditable() {
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
<mat-slide-toggle [checked]="processDetailsRedirection" (change)="toggleProcessDetailsRedirection()" data-automation-id="processDetailsRedirection">
|
||||
Display process details on process click
|
||||
</mat-slide-toggle>
|
||||
<mat-form-field data-automation-id="selectionMode">
|
||||
|
||||
<mat-form-field data-automation-id="selectionMode" class="adf-cloud-settings-selection-mode">
|
||||
<mat-label>Selection Mode</mat-label>
|
||||
<mat-select [(ngModel)]="selectionMode" (selectionChange)="onSelectionModeChange()">
|
||||
<mat-option *ngFor="let option of selectionModeOptions" [value]="option.value">
|
||||
@@ -24,32 +25,29 @@
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
<mat-card *ngIf="actionMenu || contextMenu">
|
||||
<mat-card-header>
|
||||
<mat-card-title>Add Action</mat-card-title>
|
||||
</mat-card-header>
|
||||
<mat-card-content>
|
||||
<form class="app-cloud-settings-form" [formGroup]="actionMenuForm">
|
||||
<mat-form-field>
|
||||
<input matInput formControlName="key" placeholder="Key">
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input matInput formControlName="title" placeholder="Title">
|
||||
</mat-form-field>
|
||||
<mat-form-field>
|
||||
<input matInput formControlName="icon" placeholder="Icon">
|
||||
</mat-form-field>
|
||||
<mat-checkbox formControlName="visible">Visible</mat-checkbox>
|
||||
<mat-checkbox formControlName="disabled">Disable</mat-checkbox>
|
||||
<button mat-raised-button (click)="addAction()">Add</button>
|
||||
</form>
|
||||
<div *ngIf="actions.length > 0">
|
||||
<mat-chip-list>
|
||||
<mat-chip *ngFor="let action of actions" [removable]="true">
|
||||
{{action.title}}
|
||||
<mat-icon matChipRemove (click)="removeAction(action)">cancel</mat-icon>
|
||||
</mat-chip>
|
||||
</mat-chip-list>
|
||||
</div>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
|
||||
<div class="app-cloud-actions" *ngIf="actionMenu || contextMenu">
|
||||
<h2>Add Action</h2>
|
||||
<form class="app-cloud-settings-form" [formGroup]="actionMenuForm">
|
||||
<mat-form-field class="app-cloud-settings-form-input">
|
||||
<input matInput formControlName="key" placeholder="Key">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="app-cloud-settings-form-input">
|
||||
<input matInput formControlName="title" placeholder="Title">
|
||||
</mat-form-field>
|
||||
<mat-form-field class="app-cloud-settings-form-input">
|
||||
<input matInput formControlName="icon" placeholder="Icon">
|
||||
</mat-form-field>
|
||||
<mat-checkbox formControlName="visible">Visible</mat-checkbox>
|
||||
<mat-checkbox formControlName="disabled">Disable</mat-checkbox>
|
||||
<button mat-raised-button (click)="addAction()">Add</button>
|
||||
</form>
|
||||
<div *ngIf="actions.length > 0">
|
||||
<mat-chip-list>
|
||||
<mat-chip *ngFor="let action of actions" [removable]="true">
|
||||
{{action.title}}
|
||||
<mat-icon matChipRemove (click)="removeAction(action)">cancel</mat-icon>
|
||||
</mat-chip>
|
||||
</mat-chip-list>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,11 @@ app-cloud-settings {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
|
||||
mat-form-field {
|
||||
.app-cloud-actions {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.adf-cloud-settings-selection-mode {
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
@@ -13,13 +17,9 @@ app-cloud-settings {
|
||||
place-content: center space-around;
|
||||
align-items: center;
|
||||
|
||||
mat-form-field {
|
||||
.app-cloud-settings-form-input {
|
||||
flex: 1 1 100%;
|
||||
max-width: 23%;
|
||||
}
|
||||
|
||||
mat-form-field, mat-checkbox {
|
||||
margin-right: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,14 +110,10 @@
|
||||
</adf-info-drawer-tab>
|
||||
|
||||
<adf-info-drawer-tab label="Versions">
|
||||
<mat-card>
|
||||
<mat-card-content>
|
||||
<adf-version-manager [node]="node"
|
||||
(uploadError)="onUploadError($event)"
|
||||
(viewVersion)="onViewVersion($event)">
|
||||
</adf-version-manager>
|
||||
</mat-card-content>
|
||||
</mat-card>
|
||||
<adf-version-manager [node]="node"
|
||||
(uploadError)="onUploadError($event)"
|
||||
(viewVersion)="onViewVersion($event)">
|
||||
</adf-version-manager>
|
||||
</adf-info-drawer-tab>
|
||||
</adf-info-drawer>
|
||||
</ng-template>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<a mat-fab class="app-setting-button" data-automation-id="settings" href="" routerLink="/settings">
|
||||
<a class="app-setting-button" data-automation-id="settings" href="" routerLink="/settings">
|
||||
<mat-icon>settings</mat-icon>
|
||||
</a>
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
.app-setting-button.mat-fab {
|
||||
.app-setting-button {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 10px;
|
||||
z-index: 1;
|
||||
color: white;
|
||||
}
|
||||
|
||||
@@ -1,120 +1,106 @@
|
||||
<div class="adf-setting-container">
|
||||
<mat-card class="adf-setting-card">
|
||||
<form id="host-form" [formGroup]="form" (submit)="onSubmit(form.value)" (keydown)="keyDownFunction($event)">
|
||||
<mat-form-field *ngIf="showSelectProviders">
|
||||
<mat-select id="adf-provider-selector" [formControl]="providersControl">
|
||||
<mat-option *ngFor="let provider of providers" [value]="provider">
|
||||
{{ provider }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
<form id="host-form" [formGroup]="form" (submit)="onSubmit(form.value)" (keydown)="keyDownFunction($event)">
|
||||
<mat-form-field *ngIf="showSelectProviders">
|
||||
<mat-select id="adf-provider-selector" [formControl]="providersControl">
|
||||
<mat-option *ngFor="let provider of providers" [value]="provider">
|
||||
{{ provider }}
|
||||
</mat-option>
|
||||
</mat-select>
|
||||
</mat-form-field>
|
||||
|
||||
<div class="adf-authentication-type">
|
||||
<div>Authentication type:</div>
|
||||
<mat-radio-group formControlName="authType" class="adf-authentication-radio-group">
|
||||
<mat-radio-button value="BASIC" class="adf-authentication-radio-button">Basic Authentication</mat-radio-button>
|
||||
<mat-radio-button value="OAUTH" class="adf-authentication-radio-button">SSO</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
</div>
|
||||
|
||||
<mat-form-field *ngIf="isALL() || isECM()" class="adf-full-width">
|
||||
<mat-label>Content Services URL</mat-label>
|
||||
<input matInput [formControl]="ecmHost" data-automation-id="ecmHost" type="text" id="ecmHost" [placeholder]="PLACEHOLDER_URL">
|
||||
<mat-error *ngIf="ecmHost.hasError('pattern')">{{ ERR_INVALID_URL }}</mat-error>
|
||||
<mat-error *ngIf="ecmHost.hasError('required')">{{ ERR_REQUIRED }}</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field *ngIf="isALL() || isBPM()" class="adf-full-width">
|
||||
<mat-label>Process Services URL</mat-label>
|
||||
<input matInput [formControl]="bpmHost" data-automation-id="bpmHost" type="text" id="bpmHost" [placeholder]="PLACEHOLDER_URL">
|
||||
<mat-error *ngIf="bpmHost.hasError('pattern')">{{ ERR_INVALID_URL }}</mat-error>
|
||||
<mat-error *ngIf="bpmHost.hasError('required')">{{ ERR_REQUIRED }}</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field *ngIf="isOAUTH()" class="adf-full-width">
|
||||
<mat-label>Identity Host</mat-label>
|
||||
<input matInput name="identityHost" id="identityHost" formControlName="identityHost" [placeholder]="PLACEHOLDER_URL">
|
||||
<mat-error *ngIf="identityHost.hasError('pattern')">{{ ERR_INVALID_URL }}</mat-error>
|
||||
<mat-error *ngIf="identityHost.hasError('required')">{{ ERR_REQUIRED }}</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<div *ngIf="isOAUTH()" formGroupName="oauthConfig">
|
||||
<mat-form-field class="adf-full-width">
|
||||
<mat-label>Auth Host</mat-label>
|
||||
<input matInput name="host" id="oauthHost" formControlName="host" [placeholder]="PLACEHOLDER_URL">
|
||||
<mat-error *ngIf="host.hasError('pattern')">{{ ERR_INVALID_URL }}</mat-error>
|
||||
<mat-error *ngIf="host.hasError('required')">{{ ERR_REQUIRED }}</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<div class="adf-authentication-type">
|
||||
<div>Authentication type :</div>
|
||||
<mat-radio-group formControlName="authType" >
|
||||
<mat-radio-button value="BASIC">Basic Authentication</mat-radio-button>
|
||||
<mat-radio-button value="OAUTH">SSO</mat-radio-button>
|
||||
</mat-radio-group>
|
||||
</div>
|
||||
<mat-form-field class="adf-full-width">
|
||||
<mat-label>Client ID</mat-label>
|
||||
<input matInput name="clientId" id="clientId" formControlName="clientId">
|
||||
<mat-error *ngIf="clientId.hasError('required')">{{ ERR_REQUIRED }}</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<ng-container *ngIf="isALL() || isECM()">
|
||||
<mat-card-content>
|
||||
<mat-form-field class="adf-full-width">
|
||||
<mat-label>Content Services URL</mat-label>
|
||||
<input matInput [formControl]="ecmHost" data-automation-id="ecmHost" type="text" id="ecmHost" [placeholder]="PLACEHOLDER_URL">
|
||||
<mat-error *ngIf="ecmHost.hasError('pattern')">{{ ERR_INVALID_URL }}</mat-error>
|
||||
<mat-error *ngIf="ecmHost.hasError('required')">{{ ERR_REQUIRED }}</mat-error>
|
||||
</mat-form-field>
|
||||
</mat-card-content>
|
||||
<mat-form-field class="adf-full-width">
|
||||
<mat-label>Scope Id</mat-label>
|
||||
<input matInput name="Scope" formControlName="scope">
|
||||
<mat-error *ngIf="scope.hasError('required')">{{ ERR_REQUIRED }}</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="adf-full-width">
|
||||
<mat-label>Secret</mat-label>
|
||||
<input matInput name="Secret" formControlName="secret">
|
||||
<mat-error *ngIf="secret.hasError('required')">{{ ERR_REQUIRED }}</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-label>Silent Login</mat-label>
|
||||
<mat-slide-toggle class="adf-full-width" name="silentLogin" formControlName="silentLogin">
|
||||
</mat-slide-toggle>
|
||||
|
||||
<mat-label>Implicit Flow</mat-label>
|
||||
<mat-slide-toggle class="adf-full-width" name="implicitFlow" formControlName="implicitFlow">
|
||||
</mat-slide-toggle>
|
||||
|
||||
<ng-container *ngIf="isOAUTH">
|
||||
<mat-label>Code Flow</mat-label>
|
||||
<mat-slide-toggle class="adf-full-width" name="codeFlow" formControlName="codeFlow">
|
||||
</mat-slide-toggle>
|
||||
</ng-container>
|
||||
|
||||
<ng-container *ngIf="isALL() || isBPM()">
|
||||
<mat-card-content>
|
||||
<mat-form-field class="adf-full-width">
|
||||
<mat-label>Process Services URL</mat-label>
|
||||
<input matInput [formControl]="bpmHost" data-automation-id="bpmHost" type="text" id="bpmHost" [placeholder]="PLACEHOLDER_URL">
|
||||
<mat-error *ngIf="bpmHost.hasError('pattern')">{{ ERR_INVALID_URL }}</mat-error>
|
||||
<mat-error *ngIf="bpmHost.hasError('required')">{{ ERR_REQUIRED }}</mat-error>
|
||||
</mat-form-field>
|
||||
</mat-card-content>
|
||||
</ng-container>
|
||||
<mat-form-field class="adf-full-width">
|
||||
<mat-label>Redirect URI</mat-label>
|
||||
<input matInput name="redirectUri" formControlName="redirectUri">
|
||||
<mat-error *ngIf="redirectUri.hasError('required')">{{ ERR_REQUIRED }}</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<ng-container *ngIf="isOAUTH()">
|
||||
<mat-card-content>
|
||||
<mat-form-field class="adf-full-width">
|
||||
<mat-label>Identity Host</mat-label>
|
||||
<input matInput name="identityHost" id="identityHost" formControlName="identityHost" [placeholder]="PLACEHOLDER_URL">
|
||||
<mat-error *ngIf="identityHost.hasError('pattern')">{{ ERR_INVALID_URL }}</mat-error>
|
||||
<mat-error *ngIf="identityHost.hasError('required')">{{ ERR_REQUIRED }}</mat-error>
|
||||
</mat-form-field>
|
||||
</mat-card-content>
|
||||
</ng-container>
|
||||
<mat-form-field class="adf-full-width">
|
||||
<mat-label>Redirect URI Logout</mat-label>
|
||||
<input id="logout-url" matInput name="redirectUriLogout" formControlName="redirectUriLogout">
|
||||
</mat-form-field>
|
||||
|
||||
<ng-container *ngIf="isOAUTH()">
|
||||
<div formGroupName="oauthConfig">
|
||||
<mat-form-field class="adf-full-width">
|
||||
<mat-label>Auth Host</mat-label>
|
||||
<input matInput name="host" id="oauthHost" formControlName="host" [placeholder]="PLACEHOLDER_URL">
|
||||
<mat-error *ngIf="host.hasError('pattern')">{{ ERR_INVALID_URL }}</mat-error>
|
||||
<mat-error *ngIf="host.hasError('required')">{{ ERR_REQUIRED }}</mat-error>
|
||||
</mat-form-field>
|
||||
<mat-form-field class="adf-full-width">
|
||||
<mat-label>Public urls silent Login</mat-label>
|
||||
<input id="public-url" matInput name="publicUrls" formControlName="publicUrls">
|
||||
</mat-form-field>
|
||||
</div>
|
||||
|
||||
<mat-form-field class="adf-full-width">
|
||||
<mat-label>Client ID</mat-label>
|
||||
<input matInput name="clientId" id="clientId" formControlName="clientId">
|
||||
<mat-error *ngIf="clientId.hasError('required')">{{ ERR_REQUIRED }}</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="adf-full-width">
|
||||
<mat-label>Scope Id</mat-label>
|
||||
<input matInput name="Scope" formControlName="scope">
|
||||
<mat-error *ngIf="scope.hasError('required')">{{ ERR_REQUIRED }}</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="adf-full-width">
|
||||
<mat-label>Secret</mat-label>
|
||||
<input matInput name="Secret" formControlName="secret">
|
||||
<mat-error *ngIf="secret.hasError('required')">{{ ERR_REQUIRED }}</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-label>Silent Login</mat-label>
|
||||
<mat-slide-toggle class="adf-full-width" name="silentLogin" formControlName="silentLogin">
|
||||
</mat-slide-toggle>
|
||||
|
||||
<mat-label>Implicit Flow</mat-label>
|
||||
<mat-slide-toggle class="adf-full-width" name="implicitFlow" formControlName="implicitFlow">
|
||||
</mat-slide-toggle>
|
||||
|
||||
<ng-container *ngIf="supportsCodeFlow">
|
||||
<mat-label>Code Flow</mat-label>
|
||||
<mat-slide-toggle class="adf-full-width" name="codeFlow" formControlName="codeFlow">
|
||||
</mat-slide-toggle>
|
||||
</ng-container>
|
||||
|
||||
<mat-form-field class="adf-full-width">
|
||||
<mat-label>Redirect URI</mat-label>
|
||||
<input matInput name="redirectUri" formControlName="redirectUri">
|
||||
<mat-error *ngIf="redirectUri.hasError('required')">{{ ERR_REQUIRED }}</mat-error>
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="adf-full-width">
|
||||
<mat-label>Redirect URI Logout</mat-label>
|
||||
<input id="logout-url" matInput name="redirectUriLogout" formControlName="redirectUriLogout">
|
||||
</mat-form-field>
|
||||
|
||||
<mat-form-field class="adf-full-width">
|
||||
<mat-label>Public urls silent Login</mat-label>
|
||||
<input id="public-url" matInput name="publicUrls" formControlName="publicUrls">
|
||||
</mat-form-field>
|
||||
|
||||
</div>
|
||||
</ng-container>
|
||||
<mat-card-actions align="end">
|
||||
<button mat-button (click)="onCancel()">Back</button>
|
||||
<button type="submit" class="adf-login-button" mat-button
|
||||
color="primary" data-automation-id="settings-apply-button"
|
||||
[disabled]="!form.valid">Apply</button>
|
||||
</mat-card-actions>
|
||||
</form>
|
||||
</mat-card>
|
||||
<div class="adf-host-settings-actions">
|
||||
<button mat-button (click)="onCancel()">Back</button>
|
||||
<button type="submit"
|
||||
mat-button
|
||||
color="primary"
|
||||
data-automation-id="settings-apply-button"
|
||||
[disabled]="!form.valid">Apply</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -3,11 +3,26 @@
|
||||
min-height: 100%;
|
||||
align-items: center;
|
||||
|
||||
.adf-host-settings-actions {
|
||||
text-align: end;
|
||||
}
|
||||
|
||||
.adf-authentication-type {
|
||||
margin-bottom: 20px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.adf-authentication-radio-group {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin: 15px 0;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.adf-authentication-radio-button {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.adf-setting-container {
|
||||
width: 800px;
|
||||
display: table;
|
||||
|
||||
@@ -65,7 +65,7 @@ export class HostSettingsComponent implements OnInit {
|
||||
private storageService: StorageService,
|
||||
private alfrescoApiService: AlfrescoApiService,
|
||||
private appConfig: AppConfigService,
|
||||
private auth: AuthenticationService
|
||||
private authenticationService: AuthenticationService
|
||||
) {}
|
||||
|
||||
ngOnInit() {
|
||||
@@ -191,8 +191,8 @@ export class HostSettingsComponent implements OnInit {
|
||||
this.storageService.setItem(AppConfigValues.AUTHTYPE, values.authType);
|
||||
|
||||
this.alfrescoApiService.reset();
|
||||
this.auth.reset();
|
||||
this.alfrescoApiService.getInstance().invalidateSession();
|
||||
this.authenticationService.reset();
|
||||
this.authenticationService.logout();
|
||||
this.success.emit(true);
|
||||
}
|
||||
|
||||
@@ -235,10 +235,6 @@ export class HostSettingsComponent implements OnInit {
|
||||
return this.form.get('authType').value === 'OAUTH';
|
||||
}
|
||||
|
||||
get supportsCodeFlow(): boolean {
|
||||
return this.auth.supportCodeFlow;
|
||||
}
|
||||
|
||||
get providersControl(): UntypedFormControl {
|
||||
return this.form.get('providersControl') as UntypedFormControl;
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import { NgModule } from '@angular/core';
|
||||
import { TaskListDemoComponent } from './task-list-demo.component';
|
||||
import { Routes, RouterModule } from '@angular/router';
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { CoreModule } from '@alfresco/adf-core';
|
||||
import { CoreModule, LocalizedDatePipe } from '@alfresco/adf-core';
|
||||
import { ProcessModule } from '@alfresco/adf-process-services';
|
||||
|
||||
const routes: Routes = [
|
||||
@@ -38,7 +38,8 @@ const routes: Routes = [
|
||||
CommonModule,
|
||||
RouterModule.forChild(routes),
|
||||
CoreModule,
|
||||
ProcessModule.forChild()
|
||||
ProcessModule.forChild(),
|
||||
LocalizedDatePipe
|
||||
],
|
||||
declarations: [TaskListDemoComponent]
|
||||
})
|
||||
|
||||
@@ -60,6 +60,7 @@ Displays the documents from a repository.
|
||||
| ---- | ---- | ------------- | ----------- |
|
||||
| additionalSorting | [`DataSorting`](../../../lib/core/src/lib/datatable/data/data-sorting.model.ts) | | Defines default sorting. The format is an array of strings `[key direction, otherKey otherDirection]` i.e. `['name desc', 'nodeType asc']` or `['name asc']`. Set this value if you want a base rule to be added to the sorting apart from the one driven by the header. |
|
||||
| allowDropFiles | `boolean` | false | When true, this enables you to drop files directly into subfolders shown as items in the list or into another file to trigger updating it's version. When false, the dropped file will be added to the current folder (ie, the one containing all the items shown in the list). See the [Upload directive](../../core/directives/upload.directive.md) for further details about how the file drop is handled. |
|
||||
| blurOnResize | `boolean` | true | Toggles blur when columns of the list are being resized. |
|
||||
| columnsPresetKey | `string` | | Key of columns preset set in extension.json|
|
||||
| contentActions | `boolean` | false | Toggles content actions for each row |
|
||||
| contentActionsPosition | `string` | "right" | Position of the content actions dropdown menu. Can be set to "left" or "right". |
|
||||
@@ -71,6 +72,7 @@ Displays the documents from a repository.
|
||||
| headerFilters | `boolean` | false | Toggles the header filters mode. |
|
||||
| imageResolver | `any \| null` | null | Custom function to choose image file paths to show. See the [Image Resolver Model](image-resolver.model.md) page for more information. |
|
||||
| includeFields | `string[]` | | Include additional information about the node in the server request. For example: association, isLink, isLocked and others. |
|
||||
| isResizingEnabled | `boolean` | false | Toggles column resizing for document list. |
|
||||
| loading | `boolean` | false | Toggles the loading state and animated spinners for the component. Used in combination with `navigate=false` to perform custom navigation and loading state indication. |
|
||||
| locationFormat | `string` | "/" | The default route for all the location-based columns (if declared). |
|
||||
| maxColumnsVisible | `number` | | Limit of possible visible columns, including "$thumbnail" column if provided |
|
||||
|
||||
@@ -63,6 +63,7 @@ Defines column properties for DataTable, Tasklist, Document List and other compo
|
||||
| order | `number` | | Sets position of column. |
|
||||
| currencyConfig | `CurrencyConfig` | [Default currency config](#default-currency-config) | Currency configuration to customize the formatting and display of currency values within the component. |
|
||||
| decimalConfig | `DecimalConfig` | [Default decimal config](#default-decimal-config) | Decimal configuration to customize the formatting and display of decimal values within the component. |
|
||||
| dateConfig | `DateConfig` | [Default date config](#default-date-config) | Date configuration to customize the formatting and localization of date values within the component. |
|
||||
|
||||
## Properties configuration
|
||||
|
||||
@@ -72,8 +73,10 @@ The `type` input allows us to specify the type of hosted values for a given colu
|
||||
|
||||
- `text` - The given values are represented as a strings (default option).
|
||||
- `boolean` - The column expects true / false (boolean values) and in addition accepts two strings - 'false' and 'true'. Other values are not recognized by the column, and the cell remains empty.
|
||||
- `date` - This column is responsible for displaying dates. It expects date represented by a string, number or Date object. This type comes with [`dateConfig`](#default-date-config),
|
||||
- `amount` - This column is responsible for displaying currencies. It expects numerals represented by a string or a number. This type comes with [`currencyConfig`](#default-currency-config),
|
||||
- `number` - This column is responsible for displaying numbers (integers and decimals). It expects numerals represented by a string or a number. This type comes with [`decimalConfig`](#default-decimal-config)
|
||||
- `location` - This column displays a clickable location link pointing to the parent path of the node. **Note:** This type is strongly related to the document list component ([document-list.component.md](../../content-services/components/document-list.component.md)).
|
||||
|
||||
### `currencyConfig` Input
|
||||
|
||||
@@ -119,6 +122,28 @@ These properties offer flexibility in customizing how decimal values are present
|
||||
|
||||
For more details on the possible use cases of the above properties, see the [official Angular documents](https://angular.io/api/common/DecimalPipe).
|
||||
|
||||
### `dateConfig` Input
|
||||
|
||||
The `dateConfig` input allows you to configure date formatting and localization for a component. It accepts an object of type `DateConfig` with optional properties for specifying the format of displayed date, tooltip and locale.
|
||||
|
||||
#### Properties
|
||||
|
||||
- `format` (optional): A string specifying the date format ([pre-defined formats](https://angular.io/api/common/DatePipe#pre-defined-format-options)).
|
||||
- `tooltipFormat` (optional): A string specifying the date format for tooltips.
|
||||
- `locale` (optional): A string indicating the locale or region-specific formatting to use for the currency.
|
||||
|
||||
#### Default date config
|
||||
|
||||
By default, the `dateConfig` object is not required. If not provided, the component will use the following default values:
|
||||
|
||||
- `format`: "medium"
|
||||
- `tooltipFormat`: "medium"
|
||||
- `locale`: undefined
|
||||
|
||||
These properties offer flexibility in customizing how date values are presented within the component.
|
||||
|
||||
For more details on the possible use cases of the above properties, see the [official Angular documents](https://angular.io/api/common/DatePipe).
|
||||
|
||||
## Details
|
||||
|
||||
### Conditional visibility
|
||||
|
||||
@@ -423,6 +423,7 @@ Learm more about styling your datatable: [Customizing the component's styles](#c
|
||||
| actionsPosition | `string` | "right" | Position of the actions dropdown menu. Can be "left" or "right". |
|
||||
| actionsVisibleOnHover | `boolean` | false | Toggles whether the actions dropdown should only be visible if the row is hovered over or the dropdown menu is open. |
|
||||
| allowFiltering | `boolean` | false | Flag that indicate if the datatable allow the use [facet widget](../../../lib/content-services/src/lib/search/models/facet-widget.interface.ts) search for filtering. |
|
||||
| blurOnResize | `boolean` | true | Toggles blur when columns of the datatable are being resized. |
|
||||
| columns | `any[]` | \[] | The columns that the datatable will show. |
|
||||
| contextMenu | `boolean` | false | Toggles custom context menu for the component. |
|
||||
| data | [`DataTableAdapter`](../../../lib/core/src/lib/datatable/data/datatable-adapter.ts) | | Data source for the table |
|
||||
|
||||
@@ -41,3 +41,6 @@ The pages linked below contain the licenses for all third party dependencies of
|
||||
- [ADF 6.2.0](license-info-6.2.0.md)
|
||||
- [ADF 6.3.0](license-info-6.3.0.md)
|
||||
- [ADF 6.4.0](license-info-6.4.0.md)
|
||||
- [ADF 6.5.0](license-info-6.5.0.md)
|
||||
- [ADF 6.5.1](license-info-6.5.1.md)
|
||||
- [ADF 6.5.2](license-info-6.5.2.md)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -9,6 +9,9 @@ The first **General Availability** release was v2.0.0.
|
||||
|
||||
## General Availability
|
||||
|
||||
- [6.5.2](RelNote-6.5.2.md)
|
||||
- [6.5.1](RelNote-6.5.1.md)
|
||||
- [6.5.0](RelNote-6.5.0.md)
|
||||
- [6.4.0](RelNote-6.4.0.md)
|
||||
- [6.3.0](RelNote-6.3.0.md)
|
||||
- [6.2.0](RelNote-6.2.0.md)
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
---
|
||||
Title: Release notes v6.5.0
|
||||
---
|
||||
|
||||
# Alfresco Application Development Framework (ADF) version 6.5.0 Release Note
|
||||
|
||||
This document provides information on the Alfresco Application Development Framework **v6.5.0**.
|
||||
|
||||
You can find release artifacts on [GitHub](https://github.com/Alfresco/alfresco-ng2-components/releases/tag/6.5.0).
|
||||
|
||||
## Contents
|
||||
|
||||
- [New Package Versions](#new-package-versions)
|
||||
- [Features](#features)
|
||||
- [Changelog](#changelog)
|
||||
- [See Also](#see-also)
|
||||
|
||||
## New Package Versions
|
||||
|
||||
| Name | Version |
|
||||
|--------------------------------|---------|
|
||||
| @alfresco/js-api | 7.2.0 |
|
||||
| @alfresco/adf-content-services | 6.5.0 |
|
||||
| @alfresco/adf-process-services | 6.5.0 |
|
||||
| @alfresco/adf-core | 6.5.0 |
|
||||
| @alfresco/adf-insights | 6.5.0 |
|
||||
| @alfresco/adf-extensions | 6.5.0 |
|
||||
| @alfresco/adf-testing | 6.5.0 |
|
||||
| @alfresco/adf-cli | 6.5.0 |
|
||||
|
||||
## Features
|
||||
|
||||
The suggested stack is:
|
||||
|
||||
| Name | Version |
|
||||
|------------|---------|
|
||||
| Node | 18.x |
|
||||
| npm | 8.x |
|
||||
| Angular | 14.x |
|
||||
| Typescript | 4.7 |
|
||||
|
||||
For a complete list of changes, supported browsers and new feature please refer to the official documentation
|
||||
|
||||
## Changelog
|
||||
|
||||
- [54fa5d886](https://github.com/Alfresco/alfresco-ng2-components/commit/54fa5d886) Update init-aae-env.ts (#9073)
|
||||
- [a01a1b9e9](https://github.com/Alfresco/alfresco-ng2-components/commit/a01a1b9e9) [AAE-17804] Fix login redirection, add redirectUri from the app.config (#9066)
|
||||
- [34c82f4a4](https://github.com/Alfresco/alfresco-ng2-components/commit/34c82f4a4) [AAE-17807] fix for header background color (#9067)
|
||||
- [41a788d97](https://github.com/Alfresco/alfresco-ng2-components/commit/41a788d97) [AAE-17475] Fix process for call activities (#9068)
|
||||
- [10361b906](https://github.com/Alfresco/alfresco-ng2-components/commit/10361b906) fix broken expression code in people cloud (#9065)
|
||||
- [08da9ae2c](https://github.com/Alfresco/alfresco-ng2-components/commit/08da9ae2c) [AAE-12501] move auth in ADF (#8689)
|
||||
- [057e0bcd7](https://github.com/Alfresco/alfresco-ng2-components/commit/057e0bcd7) [AAE-17746] Remove secret from required prop from app.config.schema.json (#9063)
|
||||
- [bac7cc98e](https://github.com/Alfresco/alfresco-ng2-components/commit/bac7cc98e) [ACS-6210] - ACA column alinement shifted when we have very long file/folder name (#9060)
|
||||
- [7c127eb95](https://github.com/Alfresco/alfresco-ng2-components/commit/7c127eb95) [AAE-17669] Custom theme should use default font (#9062)
|
||||
- [fe8f4a5e7](https://github.com/Alfresco/alfresco-ng2-components/commit/fe8f4a5e7) [ACS-6251] remove dead code and imports from insights (#9059)
|
||||
- [adf5a5e00](https://github.com/Alfresco/alfresco-ng2-components/commit/adf5a5e00) [AAE-17476] update default app by missing process (#9061)
|
||||
- [a29f63cd9](https://github.com/Alfresco/alfresco-ng2-components/commit/a29f63cd9) [AAE-17551] added backgroundImage property for header (#9058)
|
||||
- [94fb61541](https://github.com/Alfresco/alfresco-ng2-components/commit/94fb61541) [ACS-5311] Notification History Bug Fix (#9011)
|
||||
- [93fd0bec6](https://github.com/Alfresco/alfresco-ng2-components/commit/93fd0bec6) [ACS-6140] reduce access to internal material classes (#9053)
|
||||
- [9278d9296](https://github.com/Alfresco/alfresco-ng2-components/commit/9278d9296) [AAE-16965] Improve data table date column (#9038)
|
||||
- [85ddcdf22](https://github.com/Alfresco/alfresco-ng2-components/commit/85ddcdf22) Fix missing primary scss variable (#9056)
|
||||
- [0b56a4858](https://github.com/Alfresco/alfresco-ng2-components/commit/0b56a4858) [AAE-16579] upgrade nrwl dep solve critical webpack loader-utils issue in develop (#9030)
|
||||
- [15f82c812](https://github.com/Alfresco/alfresco-ng2-components/commit/15f82c812) [AAE-15296] added design tokens to InfoDrawerComponent (#9051)
|
||||
- [54e95bc5f](https://github.com/Alfresco/alfresco-ng2-components/commit/54e95bc5f) [AAE-16970] Custom colors are not calculating correctly in default UI (#9054)
|
||||
- [81f0df3da](https://github.com/Alfresco/alfresco-ng2-components/commit/81f0df3da) [AAE-16995] Code refactor of LocationCellComponent (#9033)
|
||||
- [5d72597d7](https://github.com/Alfresco/alfresco-ng2-components/commit/5d72597d7) [ACS-6245] remove mat-card and internal styling from demo shell (#9050)
|
||||
|
||||
## See Also
|
||||
|
||||
- [Issue Tracker](https://github.com/Alfresco/alfresco-ng2-components/issues/new)
|
||||
- [Discussion forum](http://gitter.im/Alfresco/alfresco-ng2-components)
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
Title: Release notes v6.5.1
|
||||
---
|
||||
|
||||
# Alfresco Application Development Framework (ADF) version 6.5.1 Release Note
|
||||
|
||||
This document provides information on the Alfresco Application Development Framework **v6.5.1**.
|
||||
|
||||
You can find release artifacts on [GitHub](https://github.com/Alfresco/alfresco-ng2-components/releases/tag/6.5.1).
|
||||
|
||||
## Contents
|
||||
|
||||
- [Changelog](#changelog)
|
||||
- [See Also](#see-also)
|
||||
|
||||
## Changelog
|
||||
|
||||
- [f2df3c414](git@github.com:Alfresco/alfresco-ng2-components/commit/f2df3c414) [AAE-17909][AAE-17964] fix silent-refresh url is not set with the value - fix background image set to undefined (#9080)
|
||||
- [168bb0b6c](git@github.com:Alfresco/alfresco-ng2-components/commit/168bb0b6c) [AAE-17258] Update storybook for datatable and datacolumn (#9052)
|
||||
- [c0194029c](git@github.com:Alfresco/alfresco-ng2-components/commit/c0194029c) [AAE-17865] Remove few already covered e2es from ADF (#9078)
|
||||
- [625cf2b85](git@github.com:Alfresco/alfresco-ng2-components/commit/625cf2b85) [ADF-5561] Remove unused dep (#9064)
|
||||
- [f0a11fdab](git@github.com:Alfresco/alfresco-ng2-components/commit/f0a11fdab) [ACS-6140] migrate tests to harness (#9071)
|
||||
|
||||
## See Also
|
||||
|
||||
- [Issue Tracker](https://github.com/Alfresco/alfresco-ng2-components/issues/new)
|
||||
- [Discussion forum](http://gitter.im/Alfresco/alfresco-ng2-components)
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
Title: Release notes v6.5.2
|
||||
---
|
||||
|
||||
# Alfresco Application Development Framework (ADF) version 6.5.2 Release Note
|
||||
|
||||
This document provides information on the Alfresco Application Development Framework **v6.5.2**.
|
||||
|
||||
You can find release artifacts on [GitHub](https://github.com/Alfresco/alfresco-ng2-components/releases/tag/6.5.2).
|
||||
|
||||
## Contents
|
||||
|
||||
- [Changelog](#changelog)
|
||||
- [See Also](#see-also)
|
||||
|
||||
## Changelog
|
||||
|
||||
- [22d3179a5](git@github.com:Alfresco/alfresco-ng2-components/commit/22d3179a5) Revert "[AAE-18105] Fix release workflow: release-npm step doesn't publish al…" (#9092)
|
||||
- [17323b0ab](git@github.com:Alfresco/alfresco-ng2-components/commit/17323b0ab) [AAE-18105] Fix release workflow: release-npm step doesn't publish all the packages (#9091)
|
||||
- [81787d520](git@github.com:Alfresco/alfresco-ng2-components/commit/81787d520) [MNT-23166] Add resize flag to document list with option to disable blur (#9090)
|
||||
- [e5ca7d206](git@github.com:Alfresco/alfresco-ng2-components/commit/e5ca7d206) [AAE-18057] Fix token is not refreshed after silent-refresh is called. Get another token from the auth server. (#9089)
|
||||
- [6787ef458](git@github.com:Alfresco/alfresco-ng2-components/commit/6787ef458) [ACS-6225] Removed extra gray area around share link dialog (#9086)
|
||||
- [6988c1f45](git@github.com:Alfresco/alfresco-ng2-components/commit/6988c1f45) [ACS-6067] viewer thumbnails not refresh on file change (#9075)
|
||||
- [15fdbc7e2](git@github.com:Alfresco/alfresco-ng2-components/commit/15fdbc7e2) [ACS-4794] ES query migration changes (#8773)
|
||||
|
||||
## See Also
|
||||
|
||||
- [Issue Tracker](https://github.com/Alfresco/alfresco-ng2-components/issues/new)
|
||||
- [Discussion forum](http://gitter.im/Alfresco/alfresco-ng2-components)
|
||||
@@ -38,3 +38,6 @@ The pages linked below contain the audit for all third party dependencies of ADF
|
||||
- [ADF 6.2.0](audit-info-6.2.0.md)
|
||||
- [ADF 6.3.0](audit-info-6.3.0.md)
|
||||
- [ADF 6.4.0](audit-info-6.4.0.md)
|
||||
- [ADF 6.5.0](audit-info-6.5.0.md)
|
||||
- [ADF 6.5.1](audit-info-6.5.1.md)
|
||||
- [ADF 6.5.2](audit-info-6.5.2.md)
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
---
|
||||
Title: Audit info, alfresco-ng2-components 6.5.0
|
||||
---
|
||||
|
||||
# Audit information for alfresco-ng2-components 6.5.0
|
||||
|
||||
This page lists the security audit of the dependencies this project depends on.
|
||||
|
||||
## Risks
|
||||
|
||||
- Critical risk: 0
|
||||
- High risk: 17
|
||||
- Moderate risk: 12
|
||||
- Low risk: 0
|
||||
|
||||
Dependencies analyzed:
|
||||
|
||||
## Libraries
|
||||
|
||||
| Severity | Module | Vulnerable versions |
|
||||
| --- | --- | --- |
|
||||
|high | @mdx-js/mdx | "<=1.6.22" |
|
||||
|moderate | @storybook/builder-webpack4 | "*" |
|
||||
|high | @storybook/core-server | "<=7.0.0-rc.11" |
|
||||
|high | @storybook/csf-tools | "6.5.0-alpha.1 - 6.5.17-alpha.0" |
|
||||
|moderate | @storybook/manager-webpack4 | "*" |
|
||||
|high | @storybook/mdx1-csf | "*" |
|
||||
|moderate | autoprefixer | "1.0.20131222 - 9.8.8" |
|
||||
|high | chokidar | "1.0.0-rc1 - 2.1.8" |
|
||||
|high | cpy | "7.0.0 - 8.1.2" |
|
||||
|moderate | css-loader | "0.15.0 - 4.3.0" |
|
||||
|high | fast-glob | "<=2.2.7" |
|
||||
|high | glob-parent | "<5.1.2" |
|
||||
|high | globby | "8.0.0 - 9.2.0" |
|
||||
|moderate | icss-utils | "<=4.1.1" |
|
||||
|high | meow | "3.4.0 - 5.0.0" |
|
||||
|moderate | postcss | "<8.4.31" |
|
||||
|moderate | postcss-flexbugs-fixes | "<=4.2.1" |
|
||||
|moderate | postcss-modules-extract-imports | "<=2.0.0" |
|
||||
|moderate | postcss-modules-local-by-default | "<=4.0.0-rc.4" |
|
||||
|moderate | postcss-modules-scope | "<=2.2.0" |
|
||||
|moderate | postcss-modules-values | "<=4.0.0-rc.5" |
|
||||
|high | remark-mdx | "<=1.6.22" |
|
||||
|high | remark-parse | "<=8.0.3" |
|
||||
|moderate | semver | "7.0.0 - 7.5.1" |
|
||||
|high | trim | "<0.0.3" |
|
||||
|high | trim-newlines | "<3.0.1" |
|
||||
|high | watchpack | "1.7.2 - 1.7.5" |
|
||||
|high | watchpack-chokidar2 | "*" |
|
||||
|high | webpack | "4.44.0 - 4.47.0" |
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
---
|
||||
Title: Audit info, alfresco-ng2-components 6.5.1
|
||||
---
|
||||
|
||||
# Audit information for alfresco-ng2-components 6.5.1
|
||||
|
||||
This page lists the security audit of the dependencies this project depends on.
|
||||
|
||||
## Risks
|
||||
|
||||
- Critical risk: 0
|
||||
- High risk: 17
|
||||
- Moderate risk: 12
|
||||
- Low risk: 0
|
||||
|
||||
Dependencies analyzed:
|
||||
|
||||
## Libraries
|
||||
|
||||
| Severity | Module | Vulnerable versions |
|
||||
| --- | --- | --- |
|
||||
|high | @mdx-js/mdx | "<=1.6.22" |
|
||||
|moderate | @storybook/builder-webpack4 | "*" |
|
||||
|high | @storybook/core-server | "<=7.0.0-rc.11" |
|
||||
|high | @storybook/csf-tools | "6.5.0-alpha.1 - 6.5.17-alpha.0" |
|
||||
|moderate | @storybook/manager-webpack4 | "*" |
|
||||
|high | @storybook/mdx1-csf | "*" |
|
||||
|moderate | autoprefixer | "1.0.20131222 - 9.8.8" |
|
||||
|high | chokidar | "1.0.0-rc1 - 2.1.8" |
|
||||
|high | cpy | "7.0.0 - 8.1.2" |
|
||||
|moderate | css-loader | "0.15.0 - 4.3.0" |
|
||||
|high | fast-glob | "<=2.2.7" |
|
||||
|high | glob-parent | "<5.1.2" |
|
||||
|high | globby | "8.0.0 - 9.2.0" |
|
||||
|moderate | icss-utils | "<=4.1.1" |
|
||||
|high | meow | "3.4.0 - 5.0.0" |
|
||||
|moderate | postcss | "<8.4.31" |
|
||||
|moderate | postcss-flexbugs-fixes | "<=4.2.1" |
|
||||
|moderate | postcss-modules-extract-imports | "<=2.0.0" |
|
||||
|moderate | postcss-modules-local-by-default | "<=4.0.0-rc.4" |
|
||||
|moderate | postcss-modules-scope | "<=2.2.0" |
|
||||
|moderate | postcss-modules-values | "<=4.0.0-rc.5" |
|
||||
|high | remark-mdx | "<=1.6.22" |
|
||||
|high | remark-parse | "<=8.0.3" |
|
||||
|moderate | semver | "7.0.0 - 7.5.1" |
|
||||
|high | trim | "<0.0.3" |
|
||||
|high | trim-newlines | "<3.0.1" |
|
||||
|high | watchpack | "1.7.2 - 1.7.5" |
|
||||
|high | watchpack-chokidar2 | "*" |
|
||||
|high | webpack | "4.44.0 - 4.47.0" |
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
---
|
||||
Title: Audit info, alfresco-ng2-components 6.5.2
|
||||
---
|
||||
|
||||
# Audit information for alfresco-ng2-components 6.5.2
|
||||
|
||||
This page lists the security audit of the dependencies this project depends on.
|
||||
|
||||
## Risks
|
||||
|
||||
- Critical risk: 0
|
||||
- High risk: 17
|
||||
- Moderate risk: 12
|
||||
- Low risk: 0
|
||||
|
||||
Dependencies analyzed:
|
||||
|
||||
## Libraries
|
||||
|
||||
| Severity | Module | Vulnerable versions |
|
||||
| --- | --- | --- |
|
||||
|high | @mdx-js/mdx | "<=1.6.22" |
|
||||
|moderate | @storybook/builder-webpack4 | "*" |
|
||||
|high | @storybook/core-server | "<=7.0.0-rc.11" |
|
||||
|high | @storybook/csf-tools | "6.5.0-alpha.1 - 6.5.17-alpha.0" |
|
||||
|moderate | @storybook/manager-webpack4 | "*" |
|
||||
|high | @storybook/mdx1-csf | "*" |
|
||||
|moderate | autoprefixer | "1.0.20131222 - 9.8.8" |
|
||||
|high | chokidar | "1.0.0-rc1 - 2.1.8" |
|
||||
|high | cpy | "7.0.0 - 8.1.2" |
|
||||
|moderate | css-loader | "0.15.0 - 4.3.0" |
|
||||
|high | fast-glob | "<=2.2.7" |
|
||||
|high | glob-parent | "<5.1.2" |
|
||||
|high | globby | "8.0.0 - 9.2.0" |
|
||||
|moderate | icss-utils | "<=4.1.1" |
|
||||
|high | meow | "3.4.0 - 5.0.0" |
|
||||
|moderate | postcss | "<8.4.31" |
|
||||
|moderate | postcss-flexbugs-fixes | "<=4.2.1" |
|
||||
|moderate | postcss-modules-extract-imports | "<=2.0.0" |
|
||||
|moderate | postcss-modules-local-by-default | "<=4.0.0-rc.4" |
|
||||
|moderate | postcss-modules-scope | "<=2.2.0" |
|
||||
|moderate | postcss-modules-values | "<=4.0.0-rc.5" |
|
||||
|high | remark-mdx | "<=1.6.22" |
|
||||
|high | remark-parse | "<=8.0.3" |
|
||||
|moderate | semver | "7.0.0 - 7.5.1" |
|
||||
|high | trim | "<0.0.3" |
|
||||
|high | trim-newlines | "<3.0.1" |
|
||||
|high | watchpack | "1.7.2 - 1.7.5" |
|
||||
|high | watchpack-chokidar2 | "*" |
|
||||
|high | webpack | "4.44.0 - 4.47.0" |
|
||||
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ import { ContentServicesPage } from '../../core/pages/content-services.page';
|
||||
import { FileModel } from '../../models/ACS/file.model';
|
||||
import { NavigationBarPage } from '../../core/pages/navigation-bar.page';
|
||||
import { VersionManagePage } from '../pages/version-manager.page';
|
||||
import { MetadataViewPage } from '../pages/metadata-view.page';
|
||||
import { MetadataViewPage } from '../../core/pages/metadata-view.page';
|
||||
|
||||
describe('Content Services Viewer', () => {
|
||||
const acsUser = new UserModel();
|
||||
@@ -0,0 +1,94 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { browser } from 'protractor';
|
||||
import { createApiService, FileBrowserUtil, LoginPage, UploadActions, UserModel, UsersActions, ViewerPage } from '@alfresco/adf-testing';
|
||||
import { ContentServicesPage } from '../../core/pages/content-services.page';
|
||||
import { FileModel } from '../../models/ACS/file.model';
|
||||
import { NavigationBarPage } from '../../core/pages/navigation-bar.page';
|
||||
import { VersionManagePage } from '../pages/version-manager.page';
|
||||
|
||||
describe('Viewer', () => {
|
||||
|
||||
const navigationBarPage = new NavigationBarPage();
|
||||
const viewerPage = new ViewerPage();
|
||||
const loginPage = new LoginPage();
|
||||
const contentServicesPage = new ContentServicesPage();
|
||||
|
||||
const apiService = createApiService();
|
||||
const uploadActions = new UploadActions(apiService);
|
||||
const usersActions = new UsersActions(apiService);
|
||||
|
||||
const versionManagePage = new VersionManagePage();
|
||||
const acsUser = new UserModel();
|
||||
let txtFileUploaded;
|
||||
|
||||
const txtFileInfo = new FileModel({
|
||||
name: browser.params.resources.Files.ADF_DOCUMENTS.TXT.file_name,
|
||||
location: browser.params.resources.Files.ADF_DOCUMENTS.TXT.file_path
|
||||
});
|
||||
|
||||
const fileModelVersionTwo = new FileModel({
|
||||
name: browser.params.resources.Files.ADF_DOCUMENTS.TXT.file_name,
|
||||
location: browser.params.resources.Files.ADF_DOCUMENTS.TXT.file_location
|
||||
});
|
||||
|
||||
beforeAll(async () => {
|
||||
await apiService.loginWithProfile('admin');
|
||||
await usersActions.createUser(acsUser);
|
||||
|
||||
await apiService.login(acsUser.username, acsUser.password);
|
||||
|
||||
txtFileUploaded = await uploadActions.uploadFile(txtFileInfo.location, txtFileInfo.name, '-my-');
|
||||
|
||||
await loginPage.login(acsUser.username, acsUser.password);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await apiService.loginWithProfile('admin');
|
||||
await uploadActions.deleteFileOrFolder(txtFileUploaded.entry.id);
|
||||
await navigationBarPage.clickLogoutButton();
|
||||
});
|
||||
|
||||
beforeEach(async () => {
|
||||
await contentServicesPage.goToDocumentList();
|
||||
await contentServicesPage.doubleClickRow(txtFileUploaded.entry.name);
|
||||
await viewerPage.waitTillContentLoaded();
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await viewerPage.clickCloseButton();
|
||||
});
|
||||
|
||||
it('[C362242] Should the Viewer be able to view a previous version of a file', async () => {
|
||||
await contentServicesPage.versionManagerContent(txtFileInfo.name);
|
||||
await versionManagePage.showNewVersionButton.click();
|
||||
await versionManagePage.uploadNewVersionFile(fileModelVersionTwo.location);
|
||||
await versionManagePage.closeVersionDialog();
|
||||
await contentServicesPage.doubleClickRow(txtFileUploaded.entry.name);
|
||||
await viewerPage.waitTillContentLoaded();
|
||||
await viewerPage.clickInfoButton();
|
||||
await viewerPage.clickOnTab('Versions');
|
||||
await versionManagePage.viewFileVersion('1.0');
|
||||
await viewerPage.expectUrlToContain('1.0');
|
||||
});
|
||||
|
||||
it('[C362265] Should the Viewer be able to download a previous version of a file', async () => {
|
||||
await viewerPage.clickDownloadButton();
|
||||
await FileBrowserUtil.isFileDownloaded(txtFileInfo.name);
|
||||
});
|
||||
});
|
||||
@@ -31,7 +31,7 @@ import { NavigationBarPage } from '../../core/pages/navigation-bar.page';
|
||||
import { FolderModel } from '../../models/ACS/folder.model';
|
||||
import { browser } from 'protractor';
|
||||
import { FileModel } from '../../models/ACS/file.model';
|
||||
import { UploadDialogPage } from '../../core/pages/dialog/upload-dialog.page';
|
||||
import { UploadDialogPage } from '../pages/upload-dialog.page';
|
||||
|
||||
describe('Document List - Pagination', () => {
|
||||
const pagination = {
|
||||
|
||||
+6
-8
@@ -19,21 +19,19 @@ import { by, browser, ElementFinder, $, $$ } from 'protractor';
|
||||
import { BrowserVisibility, BrowserActions } from '@alfresco/adf-testing';
|
||||
|
||||
export class UploadDialogPage {
|
||||
|
||||
closeButton = $('footer[class*="upload-dialog__actions"] button[id="adf-upload-dialog-close"]');
|
||||
closeButton = $('#adf-upload-dialog-close');
|
||||
dialog = $('div[id="upload-dialog"]');
|
||||
minimizedDialog = $('div[class*="upload-dialog--minimized"]');
|
||||
uploadedStatusIcon = 'mat-icon[class*="status--done"]';
|
||||
uploadedStatusIcon = '.adf-file-uploading-row__status--done';
|
||||
cancelledStatusIcon = 'div[class*="status--cancelled"]';
|
||||
errorStatusIcon = 'div[class*="status--error"] mat-icon';
|
||||
rowByRowName = by.xpath('ancestor::adf-file-uploading-list-row');
|
||||
title = $('span[class*="upload-dialog__title"]');
|
||||
minimizeButton = $('mat-icon[title="Minimize"]');
|
||||
maximizeButton = $('mat-icon[title="Maximize"]');
|
||||
toggleMinimizeButton = $(`[data-automation-id='adf-upload-dialog__toggle-minimize']`);
|
||||
|
||||
async clickOnCloseButton(): Promise<void> {
|
||||
await this.checkCloseButtonIsDisplayed();
|
||||
await BrowserActions.clickExecuteScript('footer[class*="upload-dialog__actions"] button[id="adf-upload-dialog-close"]');
|
||||
await BrowserActions.click(this.closeButton);
|
||||
}
|
||||
|
||||
async checkCloseButtonIsDisplayed(): Promise<void> {
|
||||
@@ -107,11 +105,11 @@ export class UploadDialogPage {
|
||||
}
|
||||
|
||||
async minimizeUploadDialog(): Promise<void> {
|
||||
await BrowserActions.click(this.minimizeButton);
|
||||
await BrowserActions.click(this.toggleMinimizeButton);
|
||||
}
|
||||
|
||||
async maximizeUploadDialog(): Promise<void> {
|
||||
await BrowserActions.click(this.maximizeButton);
|
||||
await BrowserActions.click(this.toggleMinimizeButton);
|
||||
}
|
||||
|
||||
async displayTooltip(): Promise<void> {
|
||||
@@ -18,7 +18,7 @@
|
||||
import { browser } from 'protractor';
|
||||
import { createApiService, LoginPage, UploadActions, UserModel, UsersActions } from '@alfresco/adf-testing';
|
||||
import { ContentServicesPage } from '../../core/pages/content-services.page';
|
||||
import { UploadDialogPage } from '../../core/pages/dialog/upload-dialog.page';
|
||||
import { UploadDialogPage } from '../pages/upload-dialog.page';
|
||||
import { UploadTogglesPage } from '../../core/pages/dialog/upload-toggles.page';
|
||||
import { FileModel } from '../../models/ACS/file.model';
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ import { createApiService,
|
||||
UsersActions
|
||||
} from '@alfresco/adf-testing';
|
||||
import { ContentServicesPage } from '../../core/pages/content-services.page';
|
||||
import { UploadDialogPage } from '../../core/pages/dialog/upload-dialog.page';
|
||||
import { UploadDialogPage } from '../pages/upload-dialog.page';
|
||||
import { UploadTogglesPage } from '../../core/pages/dialog/upload-toggles.page';
|
||||
import { FileModel } from '../../models/ACS/file.model';
|
||||
import { NavigationBarPage } from '../../core/pages/navigation-bar.page';
|
||||
|
||||
@@ -17,11 +17,11 @@
|
||||
|
||||
import { createApiService, LoginPage, UploadActions, UserModel, UsersActions } from '@alfresco/adf-testing';
|
||||
import { ContentServicesPage } from '../../core/pages/content-services.page';
|
||||
import { UploadDialogPage } from '../../core/pages/dialog/upload-dialog.page';
|
||||
import { UploadDialogPage } from '../pages/upload-dialog.page';
|
||||
import { UploadTogglesPage } from '../../core/pages/dialog/upload-toggles.page';
|
||||
import { FileModel } from '../../models/ACS/file.model';
|
||||
import { browser } from 'protractor';
|
||||
import { VersionManagePage } from '../../core/pages/version-manager.page';
|
||||
import { VersionManagePage } from '../pages/version-manager.page';
|
||||
|
||||
describe('Upload component', () => {
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ import { browser, by, element } from 'protractor';
|
||||
|
||||
import { createApiService, DropActions, LoginPage, StringUtil, UploadActions, UserModel, UsersActions } from '@alfresco/adf-testing';
|
||||
import { ContentServicesPage } from '../../core/pages/content-services.page';
|
||||
import { UploadDialogPage } from '../../core/pages/dialog/upload-dialog.page';
|
||||
import { UploadDialogPage } from '../pages/upload-dialog.page';
|
||||
import { UploadTogglesPage } from '../../core/pages/dialog/upload-toggles.page';
|
||||
import { FileModel } from '../../models/ACS/file.model';
|
||||
import { NavigationBarPage } from '../../core/pages/navigation-bar.page';
|
||||
@@ -139,7 +139,6 @@ describe('Upload component', () => {
|
||||
|
||||
it('[C260172] Should be possible to enable versioning', async () => {
|
||||
await uploadToggles.enableVersioning();
|
||||
await uploadToggles.checkVersioningToggleIsEnabled();
|
||||
|
||||
await contentServicesPage.uploadFile(pdfFileModel.location);
|
||||
await contentServicesPage.checkContentIsDisplayed(pdfFileModel.name);
|
||||
@@ -164,7 +163,6 @@ describe('Upload component', () => {
|
||||
await contentServicesPage.goToDocumentList();
|
||||
|
||||
await uploadToggles.enableMaxSize();
|
||||
await uploadToggles.checkMaxSizeToggleIsEnabled();
|
||||
await uploadToggles.addMaxSize('400');
|
||||
|
||||
await contentServicesPage.uploadFile(fileWithSpecificSize.location);
|
||||
@@ -190,7 +188,6 @@ describe('Upload component', () => {
|
||||
it('[C272796] Should be possible to set max size to 0', async () => {
|
||||
await contentServicesPage.goToDocumentList();
|
||||
await uploadToggles.enableMaxSize();
|
||||
await uploadToggles.checkMaxSizeToggleIsEnabled();
|
||||
await uploadToggles.addMaxSize('0');
|
||||
await contentServicesPage.uploadFile(fileWithSpecificSize.location);
|
||||
// await expect(await contentServicesPage.getErrorMessage()).toEqual('File ' + fileWithSpecificSize.name + ' is larger than the allowed file size');
|
||||
@@ -207,7 +204,6 @@ describe('Upload component', () => {
|
||||
|
||||
it('[C272797] Should be possible to set max size to 1', async () => {
|
||||
await uploadToggles.enableMaxSize();
|
||||
await uploadToggles.checkMaxSizeToggleIsEnabled();
|
||||
await browser.sleep(1000);
|
||||
await uploadToggles.addMaxSize('1');
|
||||
await uploadToggles.disableMaxSize();
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
import { browser } from 'protractor';
|
||||
import { createApiService, LoginPage, SnackbarPage, StringUtil, UserModel, UsersActions } from '@alfresco/adf-testing';
|
||||
import { ContentServicesPage } from '../../core/pages/content-services.page';
|
||||
import { UploadDialogPage } from '../../core/pages/dialog/upload-dialog.page';
|
||||
import { UploadDialogPage } from '../pages/upload-dialog.page';
|
||||
import { NavigationBarPage } from '../../core/pages/navigation-bar.page';
|
||||
import { FileModel } from '../../models/ACS/file.model';
|
||||
import CONSTANTS = require('../../util/constants');
|
||||
|
||||
@@ -28,9 +28,9 @@ import { createApiService,
|
||||
import { browser, by, element } from 'protractor';
|
||||
import { FileModel } from '../../models/ACS/file.model';
|
||||
import { ContentServicesPage } from '../../core/pages/content-services.page';
|
||||
import { UploadDialogPage } from '../../core/pages/dialog/upload-dialog.page';
|
||||
import { UploadDialogPage } from '../pages/upload-dialog.page';
|
||||
import { NavigationBarPage } from '../../core/pages/navigation-bar.page';
|
||||
import { VersionManagePage } from '../../core/pages/version-manager.page';
|
||||
import { VersionManagePage } from '../pages/version-manager.page';
|
||||
|
||||
describe('Version component actions', () => {
|
||||
|
||||
|
||||
@@ -26,8 +26,8 @@ import {
|
||||
UsersActions
|
||||
} from '@alfresco/adf-testing';
|
||||
import { NavigationBarPage } from '../../core/pages/navigation-bar.page';
|
||||
import { VersionManagePage } from '../../core/pages/version-manager.page';
|
||||
import { UploadDialogPage } from '../../core/pages/dialog/upload-dialog.page';
|
||||
import { VersionManagePage } from '../pages/version-manager.page';
|
||||
import { UploadDialogPage } from '../pages/upload-dialog.page';
|
||||
import { ContentServicesPage } from '../../core/pages/content-services.page';
|
||||
import { FileModel } from '../../models/ACS/file.model';
|
||||
import CONSTANTS = require('../../util/constants');
|
||||
|
||||
@@ -24,7 +24,7 @@ import { createApiService,
|
||||
UsersActions, ViewerPage
|
||||
} from '@alfresco/adf-testing';
|
||||
import { ContentServicesPage } from '../../core/pages/content-services.page';
|
||||
import { VersionManagePage } from '../../core/pages/version-manager.page';
|
||||
import { VersionManagePage } from '../pages/version-manager.page';
|
||||
import { FileModel } from '../../models/ACS/file.model';
|
||||
import { NavigationBarPage } from '../../core/pages/navigation-bar.page';
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
import { browser } from 'protractor';
|
||||
import { createApiService, LoginPage, UploadActions, UserModel, UsersActions } from '@alfresco/adf-testing';
|
||||
import { ContentServicesPage } from '../../core/pages/content-services.page';
|
||||
import { VersionManagePage } from '../../core/pages/version-manager.page';
|
||||
import { VersionManagePage } from '../pages/version-manager.page';
|
||||
import { FileModel } from '../../models/ACS/file.model';
|
||||
import { NavigationBarPage } from '../../core/pages/navigation-bar.page';
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { $, browser } from 'protractor';
|
||||
import { $ } from 'protractor';
|
||||
import { BrowserActions, BrowserVisibility, TogglePage } from '@alfresco/adf-testing';
|
||||
|
||||
export class UploadTogglesPage {
|
||||
@@ -25,16 +25,14 @@ export class UploadTogglesPage {
|
||||
extensionFilterToggle = $('#adf-extension-filter-upload-switch');
|
||||
maxSizeToggle = $('#adf-max-size-filter-upload-switch');
|
||||
versioningToggle = $('#adf-version-upload-switch');
|
||||
extensionAcceptedField = $('input[data-automation-id="accepted-files-type"]');
|
||||
maxSizeField = $('input[data-automation-id="max-files-size"]');
|
||||
extensionAcceptedField = $('[data-automation-id="accepted-files-type"]');
|
||||
maxSizeField = $('[data-automation-id="max-files-size"]');
|
||||
|
||||
async enableMultipleFileUpload(): Promise<void> {
|
||||
await browser.executeScript('arguments[0].scrollIntoView()', this.multipleFileUploadToggle);
|
||||
await this.togglePage.enableToggle(this.multipleFileUploadToggle);
|
||||
}
|
||||
|
||||
async disableMultipleFileUpload(): Promise<void> {
|
||||
await browser.executeScript('arguments[0].scrollIntoView()', this.multipleFileUploadToggle);
|
||||
await this.togglePage.disableToggle(this.multipleFileUploadToggle);
|
||||
}
|
||||
|
||||
@@ -42,23 +40,11 @@ export class UploadTogglesPage {
|
||||
await this.togglePage.enableToggle(this.uploadFolderToggle);
|
||||
}
|
||||
|
||||
async checkMaxSizeToggleIsEnabled(): Promise<void> {
|
||||
const enabledToggle = $('mat-slide-toggle[id="adf-max-size-filter-upload-switch"][class*="mat-checked"]');
|
||||
await BrowserVisibility.waitUntilElementIsVisible(enabledToggle);
|
||||
}
|
||||
|
||||
async checkVersioningToggleIsEnabled(): Promise<void> {
|
||||
const enabledToggle = $('mat-slide-toggle[id="adf-version-upload-switch"][class*="mat-checked"]');
|
||||
await BrowserVisibility.waitUntilElementIsVisible(enabledToggle);
|
||||
}
|
||||
|
||||
async enableExtensionFilter(): Promise<void> {
|
||||
await browser.executeScript('arguments[0].scrollIntoView()', this.extensionFilterToggle);
|
||||
await this.togglePage.enableToggle(this.extensionFilterToggle);
|
||||
}
|
||||
|
||||
async disableExtensionFilter(): Promise<void> {
|
||||
await browser.executeScript('arguments[0].scrollIntoView()', this.extensionFilterToggle);
|
||||
await this.togglePage.disableToggle(this.extensionFilterToggle);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,9 +46,9 @@ export class MetadataViewPage {
|
||||
resetMetadataButton = $(`[data-automation-id='reset-metadata']`);
|
||||
|
||||
private getMetadataGroupLocator = async (groupName: string): Promise<ElementFinder> =>
|
||||
$(`mat-expansion-panel[data-automation-id="adf-metadata-group-${groupName}"]`);
|
||||
$(`[data-automation-id="adf-metadata-group-${groupName}"]`);
|
||||
private getExpandedMetadataGroupLocator = async (groupName: string): Promise<ElementFinder> =>
|
||||
$(`mat-expansion-panel[data-automation-id="adf-metadata-group-${groupName}"] > mat-expansion-panel-header`);
|
||||
$(`[data-automation-id="adf-metadata-group-${groupName}"] > mat-expansion-panel-header`);
|
||||
|
||||
async getTitle(): Promise<string> {
|
||||
return BrowserActions.getText(this.title);
|
||||
|
||||
@@ -151,18 +151,6 @@ describe('Process list cloud', () => {
|
||||
await processList.getDataTable().waitTillContentLoaded();
|
||||
}
|
||||
|
||||
it('[C290069] Should display processes ordered by name when Name is selected from sort dropdown', async () => {
|
||||
await setFilter({ status: PROCESS_STATUS.RUNNING });
|
||||
await setFilter({ sort: 'Name' });
|
||||
await setFilter({ order: SORT_DIRECTION.ASC });
|
||||
|
||||
await expect(await processList.getDataTable().checkListIsSorted(SORT_DIRECTION.ASC, 'Process Name')).toBe(true);
|
||||
|
||||
await setFilter({ order: SORT_DIRECTION.DESC});
|
||||
|
||||
await expect(await processList.getDataTable().checkListIsSorted(SORT_DIRECTION.DESC, 'Process Name')).toBe(true);
|
||||
});
|
||||
|
||||
it('[C291783] Should display processes ordered by id when Id is selected from sort dropdown', async () => {
|
||||
await setFilter({ status: PROCESS_STATUS.RUNNING });
|
||||
await setFilter({ sort: 'Id'});
|
||||
@@ -185,39 +173,6 @@ describe('Process list cloud', () => {
|
||||
await expect(await processList.getDataTable().checkListIsSorted(SORT_DIRECTION.DESC, 'Status')).toBe(true);
|
||||
});
|
||||
|
||||
it('[C305054] Should display processes ordered by started by when Started By is selected from sort dropdown', async () => {
|
||||
await setFilter({ status: PROCESS_STATUS.ALL });
|
||||
await setFilter({ sort: 'Started by' });
|
||||
await setFilter({ order: SORT_DIRECTION.ASC });
|
||||
|
||||
await expect(await processList.getDataTable().checkListIsSorted(SORT_DIRECTION.ASC, 'Started by')).toBe(true);
|
||||
|
||||
await setFilter({ order: SORT_DIRECTION.DESC});
|
||||
await expect(await processList.getDataTable().checkListIsSorted(SORT_DIRECTION.DESC, 'Started by')).toBe(true);
|
||||
});
|
||||
|
||||
it('[C305054] Should display processes ordered by processdefinitionid date when ProcessDefinitionId is selected from sort dropdown', async () => {
|
||||
await setFilter({ status: PROCESS_STATUS.ALL });
|
||||
await setFilter({ sort: 'ProcessDefinitionId' });
|
||||
await setFilter({ order: SORT_DIRECTION.ASC });
|
||||
|
||||
await expect(await processList.getDataTable().checkListIsSorted(SORT_DIRECTION.ASC, 'Process Definition Id')).toBe(true);
|
||||
|
||||
await setFilter({ order: SORT_DIRECTION.DESC});
|
||||
await expect(await processList.getDataTable().checkListIsSorted(SORT_DIRECTION.DESC, 'Process Definition Id')).toBe(true);
|
||||
});
|
||||
|
||||
it('[C305054] Should display processes ordered by processdefinitionkey date when ProcessDefinitionKey is selected from sort dropdown', async () => {
|
||||
await setFilter({ status: PROCESS_STATUS.ALL });
|
||||
await setFilter({ sort: 'ProcessDefinitionKey' });
|
||||
await setFilter({ order: SORT_DIRECTION.ASC });
|
||||
|
||||
await expect(await processList.getDataTable().checkListIsSorted(SORT_DIRECTION.ASC, 'Process Definition Key')).toBe(true);
|
||||
|
||||
await setFilter({ order: SORT_DIRECTION.DESC});
|
||||
await expect(await processList.getDataTable().checkListIsSorted(SORT_DIRECTION.DESC, 'Process Definition Key')).toBe(true);
|
||||
});
|
||||
|
||||
it('[C305054] Should display processes ordered by last modified date when Last Modified is selected from sort dropdown', async () => {
|
||||
await setFilter({ status: PROCESS_STATUS.ALL });
|
||||
await setFilter({ sort: 'Last Modified' });
|
||||
|
||||
@@ -1,178 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { browser } from 'protractor';
|
||||
import { createApiService,
|
||||
AppListCloudPage,
|
||||
ContentNodeSelectorDialogPage,
|
||||
GroupIdentityService,
|
||||
IdentityService,
|
||||
LoginPage,
|
||||
QueryService,
|
||||
ProcessCloudWidgetPage,
|
||||
ProcessDefinitionsService,
|
||||
ProcessInstancesService,
|
||||
StringUtil,
|
||||
TaskFormCloudComponent,
|
||||
TasksService,
|
||||
UploadActions,
|
||||
ViewerPage
|
||||
} from '@alfresco/adf-testing';
|
||||
import { ProcessCloudDemoPage } from './../pages/process-cloud-demo.page';
|
||||
import { NavigationBarPage } from '../../core/pages/navigation-bar.page';
|
||||
import { TasksCloudDemoPage } from './../pages/tasks-cloud-demo.page';
|
||||
import CONSTANTS = require('../../util/constants');
|
||||
|
||||
describe('Process Task - Attach content file', () => {
|
||||
|
||||
const loginSSOPage = new LoginPage();
|
||||
const navigationBarPage = new NavigationBarPage();
|
||||
const appListCloudComponent = new AppListCloudPage();
|
||||
|
||||
const processCloudDemoPage = new ProcessCloudDemoPage();
|
||||
const editProcessFilter = processCloudDemoPage.editProcessFilterCloudComponent();
|
||||
const processList = processCloudDemoPage.processListCloudComponent();
|
||||
|
||||
const tasksCloudDemoPage = new TasksCloudDemoPage();
|
||||
const taskFilter = tasksCloudDemoPage.taskFilterCloudComponent;
|
||||
const taskList = tasksCloudDemoPage.taskListCloudComponent();
|
||||
|
||||
const taskFormCloudComponent = new TaskFormCloudComponent();
|
||||
const processCloudWidget = new ProcessCloudWidgetPage();
|
||||
const contentNodeSelectorDialog = new ContentNodeSelectorDialogPage();
|
||||
|
||||
const apiService = createApiService();
|
||||
const uploadActions = new UploadActions(apiService);
|
||||
const processDefinitionService = new ProcessDefinitionsService(apiService);
|
||||
const processInstancesService = new ProcessInstancesService(apiService);
|
||||
const identityService = new IdentityService(apiService);
|
||||
const groupIdentityService = new GroupIdentityService(apiService);
|
||||
const queryService = new QueryService(apiService);
|
||||
const tasksService = new TasksService(apiService);
|
||||
|
||||
const viewerPage = new ViewerPage();
|
||||
const simpleApp = browser.params.resources.ACTIVITI_CLOUD_APPS.SIMPLE_APP.name;
|
||||
const processDefinitionName = browser.params.resources.ACTIVITI_CLOUD_APPS.SIMPLE_APP.processes.uploadSingleMultipleFiles;
|
||||
const uploadWidgetId = browser.params.resources.ACTIVITI_CLOUD_APPS.SIMPLE_APP.forms.uploadSingleMultiple.widgets.contentMultipleAttachFileId;
|
||||
const taskName = browser.params.resources.ACTIVITI_CLOUD_APPS.SIMPLE_APP.tasks.uploadSingleMultipleFiles;
|
||||
const folderName = StringUtil.generateRandomString(5);
|
||||
|
||||
let uploadedFolder: any;
|
||||
let processInstance: any;
|
||||
let testUser: any;
|
||||
let groupInfo: any;
|
||||
|
||||
const pdfFileOne = {
|
||||
name: browser.params.resources.Files.ADF_DOCUMENTS.PNG.file_name,
|
||||
location: browser.params.resources.Files.ADF_DOCUMENTS.PNG.file_path
|
||||
};
|
||||
|
||||
const pdfFileTwo = {
|
||||
name: browser.params.resources.Files.ADF_DOCUMENTS.PNG_B.file_name,
|
||||
location: browser.params.resources.Files.ADF_DOCUMENTS.PNG_B.file_path
|
||||
};
|
||||
|
||||
beforeAll(async () => {
|
||||
await apiService.loginWithProfile('identityAdmin');
|
||||
|
||||
testUser = await identityService.createIdentityUserWithRole([identityService.ROLES.ACTIVITI_USER]);
|
||||
groupInfo = await groupIdentityService.getGroupInfoByGroupName('hr');
|
||||
await identityService.addUserToGroup(testUser.idIdentityService, groupInfo.id);
|
||||
|
||||
await apiService.login(testUser.username, testUser.password);
|
||||
const processDefinition = await processDefinitionService.getProcessDefinitionByName(processDefinitionName, simpleApp);
|
||||
processInstance = await processInstancesService.createProcessInstance(processDefinition.entry.key, simpleApp, { name: 'upload process' });
|
||||
|
||||
const task = await queryService.getProcessInstanceTasks(processInstance.entry.id, simpleApp);
|
||||
await tasksService.claimTask(task.list.entries[0].entry.id, simpleApp);
|
||||
await apiService.login(testUser.username, testUser.password);
|
||||
uploadedFolder = await uploadActions.createFolder(folderName, '-my-');
|
||||
await uploadActions.uploadFile(pdfFileOne.location, pdfFileOne.name, uploadedFolder.entry.id);
|
||||
await uploadActions.uploadFile(pdfFileTwo.location, pdfFileTwo.name, uploadedFolder.entry.id);
|
||||
|
||||
await loginSSOPage.login(testUser.username, testUser.password);
|
||||
await navigationBarPage.navigateToProcessServicesCloudPage();
|
||||
await appListCloudComponent.checkApsContainer();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await uploadActions.deleteFileOrFolder(uploadedFolder.entry.id);
|
||||
await apiService.loginWithProfile('identityAdmin');
|
||||
await identityService.deleteIdentityUser(testUser.idIdentityService);
|
||||
});
|
||||
|
||||
it('[C311290] Should be able to attach multiple files when widget allows multiple files to be attached from content', async () => {
|
||||
await appListCloudComponent.checkAppIsDisplayed(simpleApp);
|
||||
await appListCloudComponent.goToApp(simpleApp);
|
||||
|
||||
await processCloudDemoPage.processFilterCloudComponent.clickOnProcessFilters();
|
||||
await processCloudDemoPage.processFilterCloudComponent.clickRunningProcessesFilter();
|
||||
await editProcessFilter.openFilter();
|
||||
await editProcessFilter.setProcessName('upload process');
|
||||
await editProcessFilter.closeFilter();
|
||||
await expect(await processCloudDemoPage.processFilterCloudComponent.getActiveFilterName()).toBe(CONSTANTS.PROCESS_FILTERS.RUNNING);
|
||||
|
||||
await processList.checkContentIsDisplayedById(processInstance.entry.id);
|
||||
await processList.selectRowById(processInstance.entry.id);
|
||||
await taskList.checkTaskListIsLoaded();
|
||||
await taskList.selectRow(taskName);
|
||||
|
||||
await taskFormCloudComponent.formFields().checkFormIsDisplayed();
|
||||
await taskFormCloudComponent.formFields().checkWidgetIsVisible(uploadWidgetId);
|
||||
const contentUploadFileWidget = processCloudWidget.attachFileWidgetCloud(uploadWidgetId);
|
||||
await contentUploadFileWidget.clickAttachContentFile(uploadWidgetId);
|
||||
|
||||
await contentNodeSelectorDialog.attachFileFromContentNode(folderName, pdfFileOne.name);
|
||||
await viewAttachedFile(contentUploadFileWidget, pdfFileOne.name);
|
||||
|
||||
await taskFormCloudComponent.formFields().checkWidgetIsVisible(uploadWidgetId);
|
||||
await contentUploadFileWidget.clickAttachContentFile(uploadWidgetId);
|
||||
|
||||
await contentNodeSelectorDialog.attachFileFromContentNode(folderName, pdfFileTwo.name);
|
||||
await viewAttachedFile(contentUploadFileWidget, pdfFileTwo.name);
|
||||
await taskFormCloudComponent.clickCompleteButton();
|
||||
|
||||
await expect(await taskFilter.getActiveFilterName()).toBe('My Tasks');
|
||||
await taskList.checkContentIsNotDisplayedByName(taskName);
|
||||
|
||||
await taskFilter.clickTaskFilter('completed-tasks');
|
||||
await taskList.getDataTable().waitTillContentLoaded();
|
||||
await taskList.checkContentIsDisplayedByName(taskName);
|
||||
|
||||
await processCloudDemoPage.processFilterCloudComponent.clickOnProcessFilters();
|
||||
await processCloudDemoPage.processFilterCloudComponent.clickCompletedProcessesFilter();
|
||||
|
||||
await editProcessFilter.openFilter();
|
||||
await editProcessFilter.setProcessName('upload process');
|
||||
await editProcessFilter.closeFilter();
|
||||
|
||||
await expect(await processCloudDemoPage.processFilterCloudComponent.getActiveFilterName()).toBe(CONSTANTS.PROCESS_FILTERS.COMPLETED);
|
||||
await processList.checkContentIsDisplayedById(processInstance.entry.id);
|
||||
});
|
||||
|
||||
async function viewAttachedFile(contentUploadWidget: any, fileName: string): Promise<void> {
|
||||
await contentUploadWidget.checkFileIsAttached(fileName);
|
||||
await contentUploadWidget.viewFile(fileName);
|
||||
|
||||
await viewerPage.checkToolbarIsDisplayed();
|
||||
await viewerPage.checkInfoButtonIsDisplayed();
|
||||
await viewerPage.checkDownloadButtonIsDisplayed();
|
||||
await viewerPage.checkFileThumbnailIsDisplayed();
|
||||
await viewerPage.checkFileNameIsDisplayed(fileName);
|
||||
await viewerPage.clickCloseButton();
|
||||
}
|
||||
});
|
||||
@@ -1,79 +0,0 @@
|
||||
/*!
|
||||
* @license
|
||||
* Copyright © 2005-2023 Hyland Software, Inc. and its affiliates. All rights reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { createApiService, Application, AppListCloudPage, IdentityService, LocalStorageUtil, LoginPage } from '@alfresco/adf-testing';
|
||||
import { browser } from 'protractor';
|
||||
import { NavigationBarPage } from '../../core/pages/navigation-bar.page';
|
||||
|
||||
describe('Applications list', () => {
|
||||
|
||||
const simpleApp = browser.params.resources.ACTIVITI_CLOUD_APPS.SIMPLE_APP.name;
|
||||
|
||||
const loginSSOPage = new LoginPage();
|
||||
const navigationBarPage = new NavigationBarPage();
|
||||
const appListCloudPage = new AppListCloudPage();
|
||||
|
||||
const apiService = createApiService();
|
||||
const applicationsService = new Application(apiService);
|
||||
const identityService = new IdentityService(apiService);
|
||||
|
||||
let testUser;
|
||||
const appNames = [];
|
||||
|
||||
beforeAll(async () => {
|
||||
await apiService.loginWithProfile('identityAdmin');
|
||||
testUser = await identityService.createIdentityUserWithRole( [identityService.ROLES.ACTIVITI_USER, identityService.ROLES.ACTIVITI_DEVOPS]);
|
||||
|
||||
await loginSSOPage.login(testUser.username, testUser.password);
|
||||
await apiService.login(testUser.username, testUser.password);
|
||||
|
||||
const applications = await applicationsService.getApplicationsByStatus('RUNNING');
|
||||
|
||||
applications.list.entries.forEach(app => {
|
||||
appNames.push(app.entry.name.toLowerCase());
|
||||
});
|
||||
|
||||
await LocalStorageUtil.setConfigField('alfresco-deployed-apps', '[]');
|
||||
await LocalStorageUtil.apiReset();
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await apiService.loginWithProfile('identityAdmin');
|
||||
await identityService.deleteIdentityUser(testUser.idIdentityService);
|
||||
});
|
||||
|
||||
it('[C310373] Should all the app with running state be displayed on dashboard when alfresco-deployed-apps is not used in config file', async () => {
|
||||
await navigationBarPage.navigateToProcessServicesCloudPage();
|
||||
await appListCloudPage.checkApsContainer();
|
||||
|
||||
const list = await appListCloudPage.getNameOfTheApplications();
|
||||
|
||||
await expect(JSON.stringify(list)).toEqual(JSON.stringify(appNames));
|
||||
});
|
||||
|
||||
it('[C289910] Should the app be displayed on dashboard when is deployed on APS', async () => {
|
||||
await browser.refresh();
|
||||
await navigationBarPage.navigateToProcessServicesCloudPage();
|
||||
await appListCloudPage.checkApsContainer();
|
||||
|
||||
await appListCloudPage.checkAppIsDisplayed(simpleApp);
|
||||
await appListCloudPage.checkAppIsDisplayed(browser.params.resources.ACTIVITI_CLOUD_APPS.CANDIDATE_BASE_APP.name);
|
||||
await appListCloudPage.checkAppIsDisplayed(browser.params.resources.ACTIVITI_CLOUD_APPS.SUB_PROCESS_APP.name);
|
||||
|
||||
await expect(await appListCloudPage.countAllApps()).toEqual(3);
|
||||
});
|
||||
});
|
||||
@@ -73,7 +73,7 @@ export class TaskDetailsPage {
|
||||
}
|
||||
|
||||
async checkDueDatePickerButtonIsNotDisplayed(): Promise<void> {
|
||||
const dueDatePickerButton = $('mat-datetimepicker-toggle[data-automation-id="datepickertoggle-dueDate"]');
|
||||
const dueDatePickerButton = $('[data-automation-id="datepickertoggle-dueDate"]');
|
||||
await BrowserVisibility.waitUntilElementIsNotVisible(dueDatePickerButton);
|
||||
}
|
||||
|
||||
|
||||
@@ -285,7 +285,7 @@ exports.config = {
|
||||
|
||||
// @ts-ignore
|
||||
if (browser.params.testConfig.appConfig.authType === 'OAUTH') {
|
||||
|
||||
Logger.info(`Configure demo shell OAUTH`);
|
||||
// @ts-ignore
|
||||
await LocalStorageUtil.setStorageItem('identityHost', browser.params.testConfig.appConfig.identityHost);
|
||||
// @ts-ignore
|
||||
|
||||
Binary file not shown.
@@ -270,7 +270,7 @@ describe('Search Number Range Filter', () => {
|
||||
for (const currentResult of results) {
|
||||
const currentSize = await BrowserActions.getAttribute(currentResult, 'title');
|
||||
if (currentSize && currentSize.trim() !== '') {
|
||||
await expect(currentSize === '0').toBe(true);
|
||||
await expect((currentSize === '0' || currentSize === '1')).toBe(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -19,7 +19,6 @@ import { ElementFinder, protractor, $ } from 'protractor';
|
||||
import { BrowserVisibility, BrowserActions, TestElement } from '@alfresco/adf-testing';
|
||||
|
||||
export class SearchBarPage {
|
||||
|
||||
searchIcon = $(`button[class*='adf-search-button']`);
|
||||
searchBar = $(`adf-search-control input`);
|
||||
searchBarExpanded: TestElement = TestElement.byCss(`adf-search-control mat-form-field[class*="mat-focused"] input`);
|
||||
@@ -29,7 +28,7 @@ export class SearchBarPage {
|
||||
highlightName = `.adf-highlight`;
|
||||
searchBarPage = $(`mat-list[id='autocomplete-search-result-list']`);
|
||||
|
||||
getRowByRowName = (name: string): ElementFinder => $(`mat-list-item[data-automation-id='autocomplete_for_${name}']`);
|
||||
getRowByRowName = (name: string): ElementFinder => $(`[data-automation-id='autocomplete_for_${name}']`);
|
||||
|
||||
async clickOnSearchIcon(): Promise<void> {
|
||||
await BrowserActions.click(this.searchIcon);
|
||||
|
||||
@@ -15,29 +15,38 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { BrowserVisibility, DateRangeFilterPage, NumberRangeFilterPage, SearchCategoriesPage, SearchCheckListPage, SearchRadioPage, SearchSliderPage, SearchTextPage } from '@alfresco/adf-testing';
|
||||
import {
|
||||
BrowserVisibility,
|
||||
DateRangeFilterPage,
|
||||
NumberRangeFilterPage,
|
||||
SearchCategoriesPage,
|
||||
SearchCheckListPage,
|
||||
SearchRadioPage,
|
||||
SearchSliderPage,
|
||||
SearchTextPage
|
||||
} from '@alfresco/adf-testing';
|
||||
import { $, by } from 'protractor';
|
||||
|
||||
export class SearchFiltersPage {
|
||||
|
||||
searchCategoriesPage: SearchCategoriesPage = new SearchCategoriesPage();
|
||||
|
||||
searchFilters = $('adf-search-filter');
|
||||
fileTypeFilter = $('mat-expansion-panel[data-automation-id="expansion-panel-SEARCH.FACET_FIELDS.TYPE"]');
|
||||
creatorFilter = $('mat-expansion-panel[data-automation-id="expansion-panel-SEARCH.FILTER.PEOPLE"]');
|
||||
fileSizeFilter = $('mat-expansion-panel[data-automation-id="expansion-panel-SEARCH.FACET_FIELDS.SIZE"]');
|
||||
nameFilter = $('mat-expansion-panel[data-automation-id="expansion-panel-Name"]');
|
||||
checkListFilter = $('mat-expansion-panel[data-automation-id="expansion-panel-Check List"]');
|
||||
createdDateRangeFilter = $('mat-expansion-panel[data-automation-id="expansion-panel-Created Date (range)"]');
|
||||
typeFilter = $('mat-expansion-panel[data-automation-id="expansion-panel-Type"]');
|
||||
sizeRangeFilter = $('mat-expansion-panel[data-automation-id="expansion-panel-Content Size (range)"]');
|
||||
sizeSliderFilter = $('mat-expansion-panel[data-automation-id="expansion-panel-Content Size"]');
|
||||
facetQueriesDefaultGroup = $('mat-expansion-panel[data-automation-id="expansion-panel-SEARCH.FACET_QUERIES.MY_FACET_QUERIES"],' +
|
||||
'mat-expansion-panel[data-automation-id="expansion-panel-My facet queries"]');
|
||||
facetQueriesTypeGroup = $('mat-expansion-panel[data-automation-id="expansion-panel-Type facet queries"]');
|
||||
facetQueriesSizeGroup = $('mat-expansion-panel[data-automation-id="expansion-panel-Size facet queries"]');
|
||||
facetIntervalsByCreated = $('mat-expansion-panel[data-automation-id="expansion-panel-The Created"]');
|
||||
facetIntervalsByModified = $('mat-expansion-panel[data-automation-id="expansion-panel-TheModified"]');
|
||||
fileTypeFilter = $('[data-automation-id="expansion-panel-SEARCH.FACET_FIELDS.TYPE"]');
|
||||
creatorFilter = $('[data-automation-id="expansion-panel-SEARCH.FILTER.PEOPLE"]');
|
||||
fileSizeFilter = $('[data-automation-id="expansion-panel-SEARCH.FACET_FIELDS.SIZE"]');
|
||||
nameFilter = $('[data-automation-id="expansion-panel-Name"]');
|
||||
checkListFilter = $('[data-automation-id="expansion-panel-Check List"]');
|
||||
createdDateRangeFilter = $('[data-automation-id="expansion-panel-Created Date (range)"]');
|
||||
typeFilter = $('[data-automation-id="expansion-panel-Type"]');
|
||||
sizeRangeFilter = $('[data-automation-id="expansion-panel-Content Size (range)"]');
|
||||
sizeSliderFilter = $('[data-automation-id="expansion-panel-Content Size"]');
|
||||
facetQueriesDefaultGroup = $(
|
||||
'[data-automation-id="expansion-panel-SEARCH.FACET_QUERIES.MY_FACET_QUERIES"],' + '[data-automation-id="expansion-panel-My facet queries"]'
|
||||
);
|
||||
facetQueriesTypeGroup = $('[data-automation-id="expansion-panel-Type facet queries"]');
|
||||
facetQueriesSizeGroup = $('[data-automation-id="expansion-panel-Size facet queries"]');
|
||||
facetIntervalsByCreated = $('[data-automation-id="expansion-panel-The Created"]');
|
||||
facetIntervalsByModified = $('[data-automation-id="expansion-panel-TheModified"]');
|
||||
|
||||
async checkSearchFiltersIsDisplayed(): Promise<void> {
|
||||
await BrowserVisibility.waitUntilElementIsVisible(this.searchFilters);
|
||||
@@ -72,7 +81,7 @@ export class SearchFiltersPage {
|
||||
}
|
||||
|
||||
async checkCustomFacetFieldLabelIsDisplayed(fieldLabel: string): Promise<void> {
|
||||
await BrowserVisibility.waitUntilElementIsVisible($(`mat-expansion-panel[data-automation-id="expansion-panel-${fieldLabel}"]`));
|
||||
await BrowserVisibility.waitUntilElementIsVisible($(`[data-automation-id="expansion-panel-${fieldLabel}"]`));
|
||||
}
|
||||
|
||||
sizeSliderFilterPage(): SearchSliderPage {
|
||||
@@ -234,5 +243,4 @@ export class SearchFiltersPage {
|
||||
async checkFileTypeFacetLabelIsNotDisplayed(fileType: string | RegExp): Promise<void> {
|
||||
await BrowserVisibility.waitUntilElementIsNotVisible(this.fileTypeFilter.element(by.cssContainingText('.adf-facet-label', fileType)));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+4
-4
@@ -9,14 +9,14 @@ const HOST = process.env.URL_HOST_ADF;
|
||||
|
||||
const LOG = process.env.E2E_LOG_LEVEL;
|
||||
|
||||
const HOST_ECM = process.env.PROXY_HOST_ECM || HOST || 'ecm';
|
||||
const HOST_BPM = process.env.PROXY_HOST_BPM || HOST || 'bpm';
|
||||
const HOST_ECM = process.env.PROXY_HOST_ECM || process.env.PROXY_HOST_ADF || HOST || 'ecm';
|
||||
const HOST_BPM = process.env.PROXY_HOST_BPM || process.env.PROXY_HOST_ADF || HOST || 'bpm';
|
||||
const HOST_SSO = process.env.HOST_SSO || process.env.PROXY_HOST_ADF || HOST || 'oauth';
|
||||
const IDENTITY_HOST = process.env.IDENTITY_HOST || process.env.HOST_SSO + '/auth/admin/realms/alfresco';
|
||||
|
||||
const PROVIDER = process.env.PROVIDER ? process.env.PROVIDER : 'ALL';
|
||||
const AUTH_TYPE = process.env.AUTH_TYPE ? process.env.AUTH_TYPE : 'BASIC';
|
||||
|
||||
const HOST_SSO = process.env.HOST_SSO || process.env.PROXY_HOST_ADF || HOST || 'oauth';
|
||||
const IDENTITY_HOST = process.env.IDENTITY_HOST || process.env.HOST_SSO + '/auth/admin/realms/alfresco';
|
||||
const OAUTH_CLIENT_ID = process.env.OAUTH_CLIENDID || 'alfresco';
|
||||
|
||||
const IDENTITY_ADMIN_EMAIL = process.env.IDENTITY_ADMIN_EMAIL || "defaultadmin";
|
||||
|
||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@alfresco/adf-cli",
|
||||
"version": "6.4.0",
|
||||
"version": "6.5.2",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@alfresco/adf-cli",
|
||||
"version": "6.4.0",
|
||||
"version": "6.5.2",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"@alfresco/js-api": ">=7.1.0-1372",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@alfresco/adf-cli",
|
||||
"description": "Alfresco ADF cli and utils",
|
||||
"version": "6.4.0",
|
||||
"version": "6.5.2",
|
||||
"author": "Hyland Software, Inc. and its affiliates",
|
||||
"bin": {
|
||||
"adf-cli": "./bin/adf-cli",
|
||||
@@ -20,7 +20,7 @@
|
||||
"dist": "rm -rf ../../dist/libs/cli && npm run build && cp -R ./bin ../../dist/libs/cli && cp -R ./resources ../../dist/libs/cli && cp -R ./templates ../../dist/libs/cli && cp ./package.json ../../dist/libs/cli"
|
||||
},
|
||||
"dependencies": {
|
||||
"@alfresco/js-api": ">=7.1.0",
|
||||
"@alfresco/js-api": ">=7.2.0",
|
||||
"commander": "^6.2.1",
|
||||
"ejs": "^3.1.9",
|
||||
"license-checker": "^25.0.1",
|
||||
|
||||
@@ -568,6 +568,7 @@ async function deployWithPayload(currentAbsentApp: any, projectRelease: any, env
|
||||
security: currentAbsentApp.security,
|
||||
infrastructure: currentAbsentApp.infrastructure,
|
||||
variables: currentAbsentApp.variables,
|
||||
enableLocalDevelopment: currentAbsentApp.enableLocalDevelopment,
|
||||
environmentId: envId
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@alfresco/adf-content-services",
|
||||
"description": "Alfresco ADF content services",
|
||||
"version": "6.4.0",
|
||||
"version": "6.5.2",
|
||||
"author": "Hyland Software, Inc. and its affiliates",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -21,9 +21,9 @@
|
||||
"@angular/platform-browser": ">=14.1.3",
|
||||
"@angular/platform-browser-dynamic": ">=14.1.3",
|
||||
"@angular/router": ">=14.1.3",
|
||||
"@alfresco/js-api": ">=7.1.0",
|
||||
"@alfresco/js-api": ">=7.2.0",
|
||||
"@ngx-translate/core": ">=14.0.0",
|
||||
"@alfresco/adf-core": ">=6.4.0"
|
||||
"@alfresco/adf-core": ">=6.5.2"
|
||||
},
|
||||
"keywords": [
|
||||
"content-services",
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
(click)="onCheckBoxClick($event)"
|
||||
(change)="onChange($event, aspect?.entry?.id)">
|
||||
<p class="adf-aspect-list-element-title">{{getTitle(aspect)}}</p>
|
||||
</mat-checkbox>
|
||||
</mat-checkbox>
|
||||
</mat-panel-title>
|
||||
<mat-panel-description [id]="'aspect-list-'+colIndex+'-title'"
|
||||
[matTooltip]="getTitle(aspect)">
|
||||
@@ -39,6 +39,6 @@
|
||||
|
||||
<ng-template #loading>
|
||||
<div class="adf-aspect-list-spinner">
|
||||
<mat-spinner id="adf-aspect-spinner"></mat-spinner>
|
||||
<mat-progress-spinner mode="indeterminate" id="adf-aspect-spinner"></mat-progress-spinner>
|
||||
</div>
|
||||
</ng-template>
|
||||
|
||||
@@ -24,86 +24,96 @@ import { AspectListService } from './services/aspect-list.service';
|
||||
import { of } from 'rxjs';
|
||||
import { AspectEntry } from '@alfresco/js-api';
|
||||
import { delay } from 'rxjs/operators';
|
||||
import { HarnessLoader } from '@angular/cdk/testing';
|
||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||
import { MatExpansionPanelHarness } from '@angular/material/expansion/testing';
|
||||
import { MatTableHarness } from '@angular/material/table/testing';
|
||||
import { MatCheckboxHarness } from '@angular/material/checkbox/testing';
|
||||
import { MatProgressSpinnerHarness } from '@angular/material/progress-spinner/testing';
|
||||
|
||||
const aspectListMock: AspectEntry[] = [{
|
||||
entry: {
|
||||
parentId: 'frs:aspectZero',
|
||||
id: 'frs:AspectOne',
|
||||
description: 'First Aspect with random description',
|
||||
title: 'FirstAspect',
|
||||
properties: [
|
||||
{
|
||||
id: 'channelPassword',
|
||||
title: 'The authenticated channel password',
|
||||
dataType: 'd:propA'
|
||||
},
|
||||
{
|
||||
id: 'channelUsername',
|
||||
title: 'The authenticated channel username',
|
||||
dataType: 'd:propB'
|
||||
}
|
||||
]
|
||||
const aspectListMock: AspectEntry[] = [
|
||||
{
|
||||
entry: {
|
||||
parentId: 'frs:aspectZero',
|
||||
id: 'frs:AspectOne',
|
||||
description: 'First Aspect with random description',
|
||||
title: 'FirstAspect',
|
||||
properties: [
|
||||
{
|
||||
id: 'channelPassword',
|
||||
title: 'The authenticated channel password',
|
||||
dataType: 'd:propA'
|
||||
},
|
||||
{
|
||||
id: 'channelUsername',
|
||||
title: 'The authenticated channel username',
|
||||
dataType: 'd:propB'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
entry: {
|
||||
parentId: 'frs:AspectZer',
|
||||
id: 'frs:SecondAspect',
|
||||
description: 'Second Aspect description',
|
||||
title: 'SecondAspect',
|
||||
properties: [
|
||||
{
|
||||
id: 'assetId',
|
||||
title: 'Published Asset Id',
|
||||
dataType: 'd:text'
|
||||
},
|
||||
{
|
||||
id: 'assetUrl',
|
||||
title: 'Published Asset URL',
|
||||
dataType: 'd:text'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
entry: {
|
||||
parentId: 'frs:AspectZer',
|
||||
id: 'frs:SecondAspect',
|
||||
description: 'Second Aspect description',
|
||||
title: 'SecondAspect',
|
||||
properties: [
|
||||
{
|
||||
id: 'assetId',
|
||||
title: 'Published Asset Id',
|
||||
dataType: 'd:text'
|
||||
},
|
||||
{
|
||||
id: 'assetUrl',
|
||||
title: 'Published Asset URL',
|
||||
dataType: 'd:text'
|
||||
}
|
||||
]
|
||||
}
|
||||
}];
|
||||
];
|
||||
|
||||
const customAspectListMock: AspectEntry[] = [{
|
||||
entry: {
|
||||
parentId: 'cst:parentAspect',
|
||||
id: 'cst:customAspect',
|
||||
description: 'Custom Aspect with random description',
|
||||
title: 'CustomAspect',
|
||||
properties: [
|
||||
{
|
||||
id: 'channelPassword',
|
||||
title: 'The authenticated channel password',
|
||||
dataType: 'd:propA'
|
||||
},
|
||||
{
|
||||
id: 'channelUsername',
|
||||
title: 'The authenticated channel username',
|
||||
dataType: 'd:propB'
|
||||
}
|
||||
]
|
||||
const customAspectListMock: AspectEntry[] = [
|
||||
{
|
||||
entry: {
|
||||
parentId: 'cst:parentAspect',
|
||||
id: 'cst:customAspect',
|
||||
description: 'Custom Aspect with random description',
|
||||
title: 'CustomAspect',
|
||||
properties: [
|
||||
{
|
||||
id: 'channelPassword',
|
||||
title: 'The authenticated channel password',
|
||||
dataType: 'd:propA'
|
||||
},
|
||||
{
|
||||
id: 'channelUsername',
|
||||
title: 'The authenticated channel username',
|
||||
dataType: 'd:propB'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
entry: {
|
||||
parentId: 'cst:commonaspect',
|
||||
id: 'cst:nonamedAspect',
|
||||
description: '',
|
||||
title: '',
|
||||
properties: [
|
||||
{
|
||||
id: 'channelPassword',
|
||||
title: 'The authenticated channel password',
|
||||
dataType: 'd:propA'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
entry: {
|
||||
parentId: 'cst:commonaspect',
|
||||
id: 'cst:nonamedAspect',
|
||||
description: '',
|
||||
title: '',
|
||||
properties: [
|
||||
{
|
||||
id: 'channelPassword',
|
||||
title: 'The authenticated channel password',
|
||||
dataType: 'd:propA'
|
||||
}
|
||||
]
|
||||
}
|
||||
}];
|
||||
];
|
||||
|
||||
describe('AspectListComponent', () => {
|
||||
|
||||
let loader: HarnessLoader;
|
||||
let component: AspectListComponent;
|
||||
let fixture: ComponentFixture<AspectListComponent>;
|
||||
let aspectListService: AspectListService;
|
||||
@@ -111,36 +121,31 @@ describe('AspectListComponent', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
TranslateModule.forRoot(),
|
||||
ContentTestingModule
|
||||
],
|
||||
imports: [TranslateModule.forRoot(), ContentTestingModule],
|
||||
providers: [AspectListService]
|
||||
});
|
||||
});
|
||||
|
||||
describe('Loading', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AspectListComponent);
|
||||
component = fixture.componentInstance;
|
||||
nodeService = TestBed.inject(NodesApiService);
|
||||
aspectListService = TestBed.inject(AspectListService);
|
||||
loader = TestbedHarnessEnvironment.loader(fixture);
|
||||
});
|
||||
|
||||
it('should show the loading spinner when result is loading', () => {
|
||||
it('should show the loading spinner when result is loading', async () => {
|
||||
const delayResult = of(null).pipe(delay(0));
|
||||
spyOn(nodeService, 'getNode').and.returnValue(delayResult);
|
||||
spyOn(aspectListService, 'getAspects').and.returnValue(delayResult);
|
||||
fixture.detectChanges();
|
||||
const spinner = fixture.nativeElement.querySelector('#adf-aspect-spinner');
|
||||
expect(spinner).toBeDefined();
|
||||
expect(spinner).not.toBeNull();
|
||||
|
||||
expect(await loader.hasHarness(MatProgressSpinnerHarness)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('When passing a node id', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(AspectListComponent);
|
||||
component = fixture.componentInstance;
|
||||
@@ -152,6 +157,7 @@ describe('AspectListComponent', () => {
|
||||
spyOn(nodeService, 'getNode').and.returnValue(of({ id: 'fake-node-id', aspectNames: ['frs:AspectOne'] } as any));
|
||||
component.nodeId = 'fake-node-id';
|
||||
fixture.detectChanges();
|
||||
loader = TestbedHarnessEnvironment.loader(fixture);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -167,106 +173,80 @@ describe('AspectListComponent', () => {
|
||||
expect(component.hasEqualAspect).toBe(false);
|
||||
});
|
||||
|
||||
it('should show all the aspects', () => {
|
||||
const firstElement = fixture.nativeElement.querySelector('#aspect-list-FirstAspect');
|
||||
const secondElement = fixture.nativeElement.querySelector('#aspect-list-SecondAspect');
|
||||
|
||||
expect(firstElement).not.toBeNull();
|
||||
expect(firstElement).toBeDefined();
|
||||
expect(secondElement).not.toBeNull();
|
||||
expect(secondElement).toBeDefined();
|
||||
it('should show all the aspects', async () => {
|
||||
expect(await loader.hasHarness(MatExpansionPanelHarness.with({ selector: '#aspect-list-FirstAspect' }))).toBe(true);
|
||||
expect(await loader.hasHarness(MatExpansionPanelHarness.with({ selector: '#aspect-list-SecondAspect' }))).toBe(true);
|
||||
});
|
||||
|
||||
it('should show aspect id when name or title is not set', () => {
|
||||
const noNameAspect: HTMLElement = fixture.nativeElement.querySelector('#aspect-list-cst-nonamedAspect .adf-aspect-list-element-title');
|
||||
const noNameAspect = fixture.nativeElement.querySelector('#aspect-list-cst-nonamedAspect .adf-aspect-list-element-title');
|
||||
expect(noNameAspect).toBeDefined();
|
||||
expect(noNameAspect).not.toBeNull();
|
||||
expect(noNameAspect.innerText).toBe('cst:nonamedAspect');
|
||||
});
|
||||
|
||||
it('should show the details when a row is clicked', () => {
|
||||
const firstElement = fixture.nativeElement.querySelector('#aspect-list-FirstAspect');
|
||||
firstElement.click();
|
||||
fixture.detectChanges();
|
||||
const firstElementDesc = fixture.nativeElement.querySelector('#aspect-list-0-description');
|
||||
expect(firstElementDesc).not.toBeNull();
|
||||
expect(firstElementDesc).toBeDefined();
|
||||
it('should show the details when a row is clicked', async () => {
|
||||
const panel = await loader.getHarness(MatExpansionPanelHarness);
|
||||
await panel.expand();
|
||||
expect(await panel.getDescription()).not.toBeNull();
|
||||
|
||||
const firstElementPropertyTable = fixture.nativeElement.querySelector('#aspect-list-0-properties-table');
|
||||
expect(firstElementPropertyTable).not.toBeNull();
|
||||
expect(firstElementPropertyTable).toBeDefined();
|
||||
const nameProperties = fixture.nativeElement.querySelectorAll('#aspect-list-0-properties-table tbody .mat-column-name');
|
||||
expect(nameProperties[0]).not.toBeNull();
|
||||
expect(nameProperties[0]).toBeDefined();
|
||||
expect(nameProperties[0].innerText).toBe('channelPassword');
|
||||
expect(nameProperties[1]).not.toBeNull();
|
||||
expect(nameProperties[1]).toBeDefined();
|
||||
expect(nameProperties[1].innerText).toBe('channelUsername');
|
||||
const table = await panel.getHarness(MatTableHarness);
|
||||
const [row1, row2] = await table.getRows();
|
||||
const [r1c1, r1c2, r1c3] = await row1.getCells();
|
||||
expect(await r1c1.getText()).toBe('channelPassword');
|
||||
expect(await r1c2.getText()).toBe('The authenticated channel password');
|
||||
expect(await r1c3.getText()).toBe('d:propA');
|
||||
|
||||
const titleProperties = fixture.nativeElement.querySelectorAll('#aspect-list-0-properties-table tbody .mat-column-title');
|
||||
expect(titleProperties[0]).not.toBeNull();
|
||||
expect(titleProperties[0]).toBeDefined();
|
||||
expect(titleProperties[0].innerText).toBe('The authenticated channel password');
|
||||
expect(titleProperties[1]).not.toBeNull();
|
||||
expect(titleProperties[1]).toBeDefined();
|
||||
expect(titleProperties[1].innerText).toBe('The authenticated channel username');
|
||||
|
||||
const dataTypeProperties = fixture.nativeElement.querySelectorAll('#aspect-list-0-properties-table tbody .mat-column-dataType');
|
||||
expect(dataTypeProperties[0]).not.toBeNull();
|
||||
expect(dataTypeProperties[0]).toBeDefined();
|
||||
expect(dataTypeProperties[0].innerText).toBe('d:propA');
|
||||
expect(dataTypeProperties[1]).not.toBeNull();
|
||||
expect(dataTypeProperties[1]).toBeDefined();
|
||||
expect(dataTypeProperties[1].innerText).toBe('d:propB');
|
||||
const [r2c1, r2c2, r2c3] = await row2.getCells();
|
||||
expect(await r2c1.getText()).toBe('channelUsername');
|
||||
expect(await r2c2.getText()).toBe('The authenticated channel username');
|
||||
expect(await r2c3.getText()).toBe('d:propB');
|
||||
});
|
||||
|
||||
it('should show as checked the node properties', () => {
|
||||
const firstAspectCheckbox: HTMLInputElement = fixture.nativeElement.querySelector('#aspect-list-0-check-input');
|
||||
expect(firstAspectCheckbox).toBeDefined();
|
||||
expect(firstAspectCheckbox).not.toBeNull();
|
||||
expect(firstAspectCheckbox.checked).toBeTruthy();
|
||||
it('should show as checked the node properties', async () => {
|
||||
const panel = await loader.getHarness(MatExpansionPanelHarness);
|
||||
await panel.expand();
|
||||
|
||||
const checkbox = await panel.getHarness(MatCheckboxHarness);
|
||||
expect(await checkbox.isChecked()).toBe(true);
|
||||
});
|
||||
|
||||
it('should remove aspects unchecked', (done) => {
|
||||
const secondElement = fixture.nativeElement.querySelector('#aspect-list-1-check-input');
|
||||
expect(secondElement).toBeDefined();
|
||||
expect(secondElement).not.toBeNull();
|
||||
expect(secondElement.checked).toBeFalsy();
|
||||
secondElement.click();
|
||||
fixture.detectChanges();
|
||||
it('should remove aspects unchecked', async () => {
|
||||
const panel = await loader.getAllHarnesses(MatExpansionPanelHarness);
|
||||
await panel[1].expand();
|
||||
|
||||
const checkbox = await panel[1].getHarness(MatCheckboxHarness);
|
||||
expect(await checkbox.isChecked()).toBe(false);
|
||||
|
||||
await checkbox.toggle();
|
||||
|
||||
expect(component.nodeAspects.length).toBe(2);
|
||||
expect(component.nodeAspects[1]).toBe('frs:SecondAspect');
|
||||
component.valueChanged.subscribe((aspects) => {
|
||||
expect(aspects.length).toBe(1);
|
||||
expect(aspects[0]).toBe('frs:AspectOne');
|
||||
done();
|
||||
});
|
||||
secondElement.click();
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should reset the properties on reset', (done) => {
|
||||
const secondElement = fixture.nativeElement.querySelector('#aspect-list-1-check-input');
|
||||
expect(secondElement).toBeDefined();
|
||||
expect(secondElement).not.toBeNull();
|
||||
expect(secondElement.checked).toBeFalsy();
|
||||
secondElement.click();
|
||||
fixture.detectChanges();
|
||||
expect(component.nodeAspects.length).toBe(2);
|
||||
component.valueChanged.subscribe((aspects) => {
|
||||
expect(aspects.length).toBe(1);
|
||||
done();
|
||||
});
|
||||
component.reset();
|
||||
});
|
||||
await checkbox.toggle();
|
||||
|
||||
it('should clear all the properties on clear', (done) => {
|
||||
expect(component.nodeAspects.length).toBe(1);
|
||||
component.valueChanged.subscribe((aspects) => {
|
||||
expect(aspects.length).toBe(0);
|
||||
done();
|
||||
});
|
||||
expect(component.nodeAspects[0]).toBe('frs:AspectOne');
|
||||
});
|
||||
|
||||
it('should reset the properties on reset', async () => {
|
||||
const panel = await loader.getAllHarnesses(MatExpansionPanelHarness);
|
||||
await panel[1].expand();
|
||||
|
||||
const checkbox = await panel[1].getHarness(MatCheckboxHarness);
|
||||
expect(await checkbox.isChecked()).toBe(false);
|
||||
|
||||
await checkbox.toggle();
|
||||
|
||||
expect(component.nodeAspects.length).toBe(2);
|
||||
component.reset();
|
||||
expect(component.nodeAspects.length).toBe(1);
|
||||
});
|
||||
|
||||
it('should clear all the properties on clear', async () => {
|
||||
expect(component.nodeAspects.length).toBe(1);
|
||||
component.clear();
|
||||
expect(component.nodeAspects.length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -277,21 +257,16 @@ describe('AspectListComponent', () => {
|
||||
aspectListService = TestBed.inject(AspectListService);
|
||||
spyOn(aspectListService, 'getAspects').and.returnValue(of(aspectListMock));
|
||||
fixture.detectChanges();
|
||||
loader = TestbedHarnessEnvironment.loader(fixture);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
fixture.destroy();
|
||||
});
|
||||
|
||||
it('should show all the aspects', () => {
|
||||
const firstElement = fixture.nativeElement.querySelector('#aspect-list-FirstAspect');
|
||||
const secondElement = fixture.nativeElement.querySelector('#aspect-list-SecondAspect');
|
||||
|
||||
expect(firstElement).not.toBeNull();
|
||||
expect(firstElement).toBeDefined();
|
||||
expect(secondElement).not.toBeNull();
|
||||
expect(secondElement).toBeDefined();
|
||||
it('should show all the aspects', async () => {
|
||||
expect(await loader.hasHarness(MatExpansionPanelHarness.with({ selector: '#aspect-list-FirstAspect' }))).toBe(true);
|
||||
expect(await loader.hasHarness(MatExpansionPanelHarness.with({ selector: '#aspect-list-SecondAspect' }))).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -26,7 +26,6 @@ import { of } from 'rxjs';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
|
||||
describe('DropdownBreadcrumb', () => {
|
||||
|
||||
let component: DropdownBreadcrumbComponent;
|
||||
let fixture: ComponentFixture<DropdownBreadcrumbComponent>;
|
||||
let documentList: DocumentListComponent;
|
||||
@@ -34,10 +33,7 @@ describe('DropdownBreadcrumb', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
TranslateModule.forRoot(),
|
||||
ContentTestingModule
|
||||
],
|
||||
imports: [TranslateModule.forRoot(), ContentTestingModule],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
||||
providers: [{ provide: DocumentListService, useValue: documentListService }]
|
||||
});
|
||||
@@ -64,7 +60,7 @@ describe('DropdownBreadcrumb', () => {
|
||||
};
|
||||
|
||||
const clickOnTheFirstOption = () => {
|
||||
const option: any = document.querySelector('[id^="mat-option"]');
|
||||
const option: any = document.querySelector(`[data-automation-class="dropdown-breadcrumb-path-option"]`);
|
||||
option.click();
|
||||
};
|
||||
|
||||
@@ -75,7 +71,6 @@ describe('DropdownBreadcrumb', () => {
|
||||
triggerComponentChange(fakeNodeWithCreatePermissionInstance);
|
||||
|
||||
fixture.whenStable().then(() => {
|
||||
|
||||
openSelect();
|
||||
|
||||
const currentFolder = fixture.debugElement.query(By.css('[data-automation-id="current-folder"]'));
|
||||
@@ -99,7 +94,6 @@ describe('DropdownBreadcrumb', () => {
|
||||
triggerComponentChange(fakeNodeWithCreatePermissionInstance);
|
||||
|
||||
fixture.whenStable().then(() => {
|
||||
|
||||
openSelect();
|
||||
|
||||
const path = fixture.debugElement.query(By.css('[data-automation-id="dropdown-breadcrumb-path"]'));
|
||||
@@ -110,7 +104,6 @@ describe('DropdownBreadcrumb', () => {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should update document list when clicking on an option', async () => {
|
||||
component.target = documentList;
|
||||
const fakeNodeWithCreatePermissionInstance = JSON.parse(JSON.stringify(fakeNodeWithCreatePermission));
|
||||
|
||||
+2
-1
@@ -71,7 +71,8 @@
|
||||
[value]="category">
|
||||
{{ category.name }}
|
||||
</mat-list-option>
|
||||
<p *ngIf="!existingCategories?.length && !existingCategoriesLoading">
|
||||
<p *ngIf="!existingCategories?.length && !existingCategoriesLoading"
|
||||
data-automation-id="no-categories-message">
|
||||
{{ 'CATEGORIES_MANAGEMENT.NO_EXISTING_CATEGORIES' | translate }}
|
||||
</p>
|
||||
</mat-selection-list>
|
||||
|
||||
+33
-37
@@ -16,7 +16,6 @@
|
||||
*/
|
||||
|
||||
import { Category, CategoryPaging, ResultNode, ResultSetPaging } from '@alfresco/js-api';
|
||||
import { DebugElement } from '@angular/core';
|
||||
import { ComponentFixture, discardPeriodicTasks, fakeAsync, flush, TestBed, tick } from '@angular/core/testing';
|
||||
import { Validators } from '@angular/forms';
|
||||
import { MatError } from '@angular/material/form-field';
|
||||
@@ -28,8 +27,12 @@ import { ContentTestingModule } from '../../testing/content.testing.module';
|
||||
import { CategoriesManagementMode } from './categories-management-mode';
|
||||
import { CategoryService } from '../services/category.service';
|
||||
import { CategoriesManagementComponent } from './categories-management.component';
|
||||
import { HarnessLoader } from '@angular/cdk/testing';
|
||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||
import { MatProgressSpinnerHarness } from '@angular/material/progress-spinner/testing';
|
||||
|
||||
describe('CategoriesManagementComponent', () => {
|
||||
let loader: HarnessLoader;
|
||||
let component: CategoriesManagementComponent;
|
||||
let fixture: ComponentFixture<CategoriesManagementComponent>;
|
||||
let categoryService: CategoryService;
|
||||
@@ -38,18 +41,15 @@ describe('CategoriesManagementComponent', () => {
|
||||
const category2 = new Category({ id: 'test2', name: 'testCat2' });
|
||||
const category3 = new Category({ id: 'test3', name: 'testCat3' });
|
||||
const category4 = new Category({ id: 'test4', name: 'testCat4' });
|
||||
const resultCat1 = new ResultNode({ id: 'test', name: 'testCat', path: { name: 'general/categories' }});
|
||||
const resultCat2 = new ResultNode({ id: 'test2', name: 'testCat2', path: { name: 'general/categories' }});
|
||||
const categoryPagingResponse: CategoryPaging = { list: { pagination: {}, entries: [ { entry: category1 }, { entry: category2 }]}};
|
||||
const categorySearchResponse: ResultSetPaging = { list: { pagination: {}, entries: [ { entry: resultCat1 }, { entry: resultCat2 }]}};
|
||||
const resultCat1 = new ResultNode({ id: 'test', name: 'testCat', path: { name: 'general/categories' } });
|
||||
const resultCat2 = new ResultNode({ id: 'test2', name: 'testCat2', path: { name: 'general/categories' } });
|
||||
const categoryPagingResponse: CategoryPaging = { list: { pagination: {}, entries: [{ entry: category1 }, { entry: category2 }] } };
|
||||
const categorySearchResponse: ResultSetPaging = { list: { pagination: {}, entries: [{ entry: resultCat1 }, { entry: resultCat2 }] } };
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
declarations: [CategoriesManagementComponent],
|
||||
imports: [
|
||||
TranslateModule.forRoot(),
|
||||
ContentTestingModule
|
||||
],
|
||||
imports: [TranslateModule.forRoot(), ContentTestingModule],
|
||||
providers: [
|
||||
{
|
||||
provide: CategoryService,
|
||||
@@ -65,6 +65,7 @@ describe('CategoriesManagementComponent', () => {
|
||||
fixture = TestBed.createComponent(CategoriesManagementComponent);
|
||||
component = fixture.componentInstance;
|
||||
categoryService = TestBed.inject(CategoryService);
|
||||
loader = TestbedHarnessEnvironment.loader(fixture);
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -138,7 +139,9 @@ describe('CategoriesManagementComponent', () => {
|
||||
* @returns list of native elements
|
||||
*/
|
||||
function getRemoveCategoryButtons(): HTMLButtonElement[] {
|
||||
return fixture.debugElement.queryAll(By.css(`[data-automation-id="categories-remove-category-button"]`)).map((debugElem) => debugElem.nativeElement);
|
||||
return fixture.debugElement
|
||||
.queryAll(By.css(`[data-automation-id="categories-remove-category-button"]`))
|
||||
.map((debugElem) => debugElem.nativeElement);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -261,39 +264,28 @@ describe('CategoriesManagementComponent', () => {
|
||||
});
|
||||
|
||||
describe('Spinner', () => {
|
||||
/**
|
||||
* Get the spinner element
|
||||
*
|
||||
* @returns debug element
|
||||
*/
|
||||
function getSpinner(): DebugElement {
|
||||
return fixture.debugElement.query(By.css(`.mat-progress-spinner`));
|
||||
}
|
||||
it('should not be displayed when existing categories stopped loading', async () => {
|
||||
component.categoryNameControlVisible = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
it('should be displayed with correct diameter when existing categories are loading', fakeAsync(() => {
|
||||
typeCategory('Category 1', 0);
|
||||
const categoryControlInput = getCategoryControlInput();
|
||||
categoryControlInput.value = 'Category 1';
|
||||
categoryControlInput.dispatchEvent(new InputEvent('input'));
|
||||
|
||||
const spinner = getSpinner();
|
||||
expect(spinner).toBeTruthy();
|
||||
expect(spinner.componentInstance.diameter).toBe(50);
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
discardPeriodicTasks();
|
||||
flush();
|
||||
}));
|
||||
|
||||
it('should not be displayed when existing categories stopped loading', fakeAsync(() => {
|
||||
typeCategory('Category 1');
|
||||
|
||||
const spinner = getSpinner();
|
||||
expect(spinner).toBeFalsy();
|
||||
}));
|
||||
expect(await loader.hasHarness(MatProgressSpinnerHarness)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
it('should display correct message when there are no existing categories', fakeAsync(() => {
|
||||
spyOn(categoryService, 'getSubcategories').and.returnValue(of({list: { pagination: {}, entries: []}}));
|
||||
spyOn(categoryService, 'getSubcategories').and.returnValue(of({ list: { pagination: {}, entries: [] } }));
|
||||
typeCategory('test');
|
||||
|
||||
const noExistingCategoriesMsg = fixture.debugElement.query(By.css('mat-selection-list p'))?.nativeElement.textContent.trim();
|
||||
const noExistingCategoriesMsg = fixture.debugElement
|
||||
.query(By.css(`[data-automation-id="no-categories-message"]`))
|
||||
?.nativeElement.textContent.trim();
|
||||
expect(noExistingCategoriesMsg).toBe('CATEGORIES_MANAGEMENT.NO_EXISTING_CATEGORIES');
|
||||
}));
|
||||
});
|
||||
@@ -328,7 +320,9 @@ describe('CategoriesManagementComponent', () => {
|
||||
|
||||
it('should have correct remove category title', () => {
|
||||
const removeButtons = getRemoveCategoryButtons();
|
||||
const isTitleCorrect = removeButtons.every((removeBtn) => removeBtn.attributes.getNamedItem('title').textContent === 'CATEGORIES_MANAGEMENT.UNASSIGN_CATEGORY');
|
||||
const isTitleCorrect = removeButtons.every(
|
||||
(removeBtn) => removeBtn.attributes.getNamedItem('title').textContent === 'CATEGORIES_MANAGEMENT.UNASSIGN_CATEGORY'
|
||||
);
|
||||
expect(isTitleCorrect).toBeTrue();
|
||||
});
|
||||
|
||||
@@ -434,7 +428,9 @@ describe('CategoriesManagementComponent', () => {
|
||||
|
||||
it('should have correct remove category title', () => {
|
||||
const removeButtons = getRemoveCategoryButtons();
|
||||
const isTitleCorrect = removeButtons.every((removeBtn) => removeBtn.attributes.getNamedItem('title').textContent === 'CATEGORIES_MANAGEMENT.DELETE_CATEGORY');
|
||||
const isTitleCorrect = removeButtons.every(
|
||||
(removeBtn) => removeBtn.attributes.getNamedItem('title').textContent === 'CATEGORIES_MANAGEMENT.DELETE_CATEGORY'
|
||||
);
|
||||
expect(isTitleCorrect).toBeTrue();
|
||||
});
|
||||
|
||||
|
||||
@@ -21,16 +21,11 @@ import { AppConfigService, AuthenticationService, StorageService, CoreTestingMod
|
||||
import { Node, PermissionsInfo } from '@alfresco/js-api';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
|
||||
declare let jasmine: any;
|
||||
|
||||
describe('ContentService', () => {
|
||||
|
||||
let contentService: ContentService;
|
||||
let authService: AuthenticationService;
|
||||
let storage: StorageService;
|
||||
let node: any;
|
||||
|
||||
const nodeId = 'fake-node-id';
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
@@ -44,14 +39,6 @@ describe('ContentService', () => {
|
||||
storage = TestBed.inject(StorageService);
|
||||
storage.clear();
|
||||
|
||||
node = {
|
||||
entry: {
|
||||
id: nodeId
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.Ajax.install();
|
||||
|
||||
const appConfig: AppConfigService = TestBed.inject(AppConfigService);
|
||||
appConfig.config = {
|
||||
ecmHost: 'http://localhost:9876/ecm',
|
||||
@@ -59,24 +46,6 @@ describe('ContentService', () => {
|
||||
};
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jasmine.Ajax.uninstall();
|
||||
});
|
||||
|
||||
it('should return a valid content URL', (done) => {
|
||||
authService.login('fake-username', 'fake-password').subscribe(() => {
|
||||
expect(contentService.getContentUrl(node)).toContain('/ecm/alfresco/api/' +
|
||||
'-default-/public/alfresco/versions/1/nodes/fake-node-id/content?attachment=false&alf_ticket=fake-post-ticket');
|
||||
done();
|
||||
});
|
||||
|
||||
jasmine.Ajax.requests.mostRecent().respondWith({
|
||||
status: 201,
|
||||
contentType: 'application/json',
|
||||
responseText: JSON.stringify({ entry: { id: 'fake-post-ticket', userId: 'admin' } })
|
||||
});
|
||||
});
|
||||
|
||||
describe('AllowableOperations', () => {
|
||||
|
||||
it('should hasAllowableOperations be false if allowableOperation is not present in the node', () => {
|
||||
|
||||
@@ -18,16 +18,27 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { from, Observable, throwError, Subject } from 'rxjs';
|
||||
import { catchError, map, switchMap, filter, take } from 'rxjs/operators';
|
||||
import { RepositoryInfo, SystemPropertiesRepresentation } from '@alfresco/js-api';
|
||||
import {
|
||||
RepositoryInfo,
|
||||
SystemPropertiesRepresentation,
|
||||
DiscoveryApi,
|
||||
AboutApi,
|
||||
SystemPropertiesApi
|
||||
} from '@alfresco/js-api';
|
||||
|
||||
import { BpmProductVersionModel, AuthenticationService } from '@alfresco/adf-core';
|
||||
import { ApiClientsService } from '@alfresco/adf-core/api';
|
||||
import { AlfrescoApiService, BpmProductVersionModel, AuthenticationService } from '@alfresco/adf-core';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root'
|
||||
})
|
||||
export class DiscoveryApiService {
|
||||
|
||||
private _discoveryApi: DiscoveryApi;
|
||||
get discoveryApi(): DiscoveryApi {
|
||||
this._discoveryApi = this._discoveryApi ?? new DiscoveryApi(this.alfrescoApiService.getInstance());
|
||||
return this._discoveryApi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets product information for Content Services.
|
||||
*/
|
||||
@@ -35,15 +46,17 @@ export class DiscoveryApiService {
|
||||
|
||||
constructor(
|
||||
private authenticationService: AuthenticationService,
|
||||
private apiClientsService: ApiClientsService
|
||||
private alfrescoApiService: AlfrescoApiService
|
||||
) {
|
||||
this.authenticationService.onLogin
|
||||
.pipe(
|
||||
this.authenticationService.onLogin.subscribe(() => {
|
||||
this.alfrescoApiService.alfrescoApiInitialized.pipe(
|
||||
filter(() => this.authenticationService.isEcmLoggedIn()),
|
||||
take(1),
|
||||
switchMap(() => this.getEcmProductInfo())
|
||||
)
|
||||
.subscribe((info) => this.ecmProductInfo$.next(info));
|
||||
.subscribe((info) => this.ecmProductInfo$.next(info));
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -53,9 +66,8 @@ export class DiscoveryApiService {
|
||||
* @returns ProductVersionModel containing product details
|
||||
*/
|
||||
getEcmProductInfo(): Observable<RepositoryInfo> {
|
||||
const discoveryApi = this.apiClientsService.get('DiscoveryClient.discovery');
|
||||
|
||||
return from(discoveryApi.getRepositoryInformation())
|
||||
return from(this.discoveryApi.getRepositoryInformation())
|
||||
.pipe(
|
||||
map((res) => res.entry.repository),
|
||||
catchError((err) => throwError(err))
|
||||
@@ -68,7 +80,7 @@ export class DiscoveryApiService {
|
||||
* @returns ProductVersionModel containing product details
|
||||
*/
|
||||
getBpmProductInfo(): Observable<BpmProductVersionModel> {
|
||||
const aboutApi = this.apiClientsService.get('ActivitiClient.about');
|
||||
const aboutApi = new AboutApi(this.alfrescoApiService.getInstance());
|
||||
|
||||
return from(aboutApi.getAppVersion())
|
||||
.pipe(
|
||||
@@ -78,7 +90,7 @@ export class DiscoveryApiService {
|
||||
}
|
||||
|
||||
getBPMSystemProperties(): Observable<SystemPropertiesRepresentation> {
|
||||
const systemPropertiesApi = this.apiClientsService.get('ActivitiClient.system-properties');
|
||||
const systemPropertiesApi = new SystemPropertiesApi(this.alfrescoApiService.getInstance());
|
||||
|
||||
return from(systemPropertiesApi.getProperties())
|
||||
.pipe(
|
||||
|
||||
@@ -25,7 +25,6 @@ import {
|
||||
import {
|
||||
AlfrescoApiService,
|
||||
AlfrescoApiServiceMock,
|
||||
AuthenticationService,
|
||||
CoreTestingModule
|
||||
} from '@alfresco/adf-core';
|
||||
import { PeopleContentQueryRequestModel, PeopleContentService } from './people-content.service';
|
||||
@@ -34,7 +33,6 @@ import { TestBed } from '@angular/core/testing';
|
||||
|
||||
describe('PeopleContentService', () => {
|
||||
let peopleContentService: PeopleContentService;
|
||||
let authenticationService: AuthenticationService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
@@ -47,7 +45,6 @@ describe('PeopleContentService', () => {
|
||||
]
|
||||
});
|
||||
|
||||
authenticationService = TestBed.inject(AuthenticationService);
|
||||
peopleContentService = TestBed.inject(PeopleContentService);
|
||||
});
|
||||
|
||||
@@ -130,17 +127,6 @@ describe('PeopleContentService', () => {
|
||||
expect(getCurrentPersonSpy.calls.count()).toEqual(1);
|
||||
});
|
||||
|
||||
it('should reset the admin cache upon logout', async () => {
|
||||
spyOn(peopleContentService.peopleApi, 'getPerson').and.returnValue(Promise.resolve({ entry: fakeEcmAdminUser } as any));
|
||||
|
||||
const user = await peopleContentService.getCurrentUserInfo().toPromise();
|
||||
expect(user.id).toEqual('fake-id');
|
||||
expect(peopleContentService.isCurrentUserAdmin()).toBe(true);
|
||||
|
||||
authenticationService.onLogout.next(true);
|
||||
expect(peopleContentService.isCurrentUserAdmin()).toBe(false);
|
||||
});
|
||||
|
||||
it('should not change current user on every getPerson call', async () => {
|
||||
const getCurrentPersonSpy = spyOn(peopleContentService.peopleApi, 'getPerson').and.returnValue(Promise.resolve({entry: fakeEcmAdminUser} as any));
|
||||
await peopleContentService.getCurrentUserInfo().toPromise();
|
||||
|
||||
+2
-2
@@ -607,7 +607,7 @@ describe('ContentMetadataComponent', () => {
|
||||
it('should hide metadata fields if displayDefaultProperties is set to false', () => {
|
||||
component.displayDefaultProperties = false;
|
||||
fixture.detectChanges();
|
||||
const metadataContainer = fixture.debugElement.query(By.css('mat-expansion-panel[data-automation-id="adf-metadata-group-properties"]'));
|
||||
const metadataContainer = fixture.debugElement.query(By.css('[data-automation-id="adf-metadata-group-properties"]'));
|
||||
fixture.detectChanges();
|
||||
expect(metadataContainer).toBeNull();
|
||||
});
|
||||
@@ -615,7 +615,7 @@ describe('ContentMetadataComponent', () => {
|
||||
it('should display metadata fields if displayDefaultProperties is set to true', () => {
|
||||
component.displayDefaultProperties = true;
|
||||
fixture.detectChanges();
|
||||
const metadataContainer = fixture.debugElement.query(By.css('mat-expansion-panel[data-automation-id="adf-metadata-group-properties"]'));
|
||||
const metadataContainer = fixture.debugElement.query(By.css('[data-automation-id="adf-metadata-group-properties"]'));
|
||||
fixture.detectChanges();
|
||||
expect(metadataContainer).toBeDefined();
|
||||
});
|
||||
|
||||
+77
-70
@@ -24,7 +24,6 @@ import { By } from '@angular/platform-browser';
|
||||
import { FileModel } from '../common/models/file.model';
|
||||
import { FileUploadEvent } from '../common/events/file.event';
|
||||
import { UploadService } from '../common/services/upload.service';
|
||||
|
||||
import { of } from 'rxjs';
|
||||
import { ContentTestingModule } from '../testing/content.testing.module';
|
||||
import { DocumentListService } from '../document-list/services/document-list.service';
|
||||
@@ -58,12 +57,7 @@ describe('ContentNodeSelectorComponent', () => {
|
||||
};
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
TranslateModule.forRoot(),
|
||||
ContentTestingModule,
|
||||
MatDialogModule,
|
||||
UploadModule
|
||||
],
|
||||
imports: [TranslateModule.forRoot(), ContentTestingModule, MatDialogModule, UploadModule],
|
||||
providers: [
|
||||
{ provide: MAT_DIALOG_DATA, useValue: data },
|
||||
{
|
||||
@@ -118,6 +112,8 @@ describe('ContentNodeSelectorComponent', () => {
|
||||
fixture.destroy();
|
||||
});
|
||||
|
||||
const getTabInfoButton = () => fixture.debugElement.query(By.css('[data-automation-id="adf-content-node-selector-disabled-tab-info-icon"]'));
|
||||
|
||||
const enableLocalUpload = () => {
|
||||
component.data.showLocalUploadButton = true;
|
||||
component.hasAllowableOperations = true;
|
||||
@@ -125,15 +121,16 @@ describe('ContentNodeSelectorComponent', () => {
|
||||
component.isLoading = false;
|
||||
};
|
||||
|
||||
const getTabLabel = (idx: number) => fixture.debugElement.queryAll(By.css('.mat-tab-label'))[idx];
|
||||
|
||||
const selectTabByIndex = (tabIndex: number) => {
|
||||
const uploadFromLocalTab = fixture.debugElement.queryAll(By.css('.mat-tab-label'))[tabIndex];
|
||||
const uploadFromLocalTab = getTabLabel(tabIndex);
|
||||
const attributes = uploadFromLocalTab.nativeNode.attributes as NamedNodeMap;
|
||||
const tabPositionInSet = Number(attributes.getNamedItem('aria-posinset').value) - 1;
|
||||
component.onTabSelectionChange(tabPositionInSet);
|
||||
};
|
||||
|
||||
describe('Data injecting with the "Material dialog way"', () => {
|
||||
|
||||
it('should show the INJECTED title', () => {
|
||||
const titleElement = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-title"]'));
|
||||
expect(titleElement).not.toBeNull();
|
||||
@@ -149,101 +146,105 @@ describe('ContentNodeSelectorComponent', () => {
|
||||
|
||||
it('should pass through the injected currentFolderId to the documentList', () => {
|
||||
const documentList = fixture.debugElement.query(By.directive(DocumentListComponent));
|
||||
expect(documentList).not.toBeNull('Document list should be shown');
|
||||
expect(documentList).not.toBeNull();
|
||||
expect(documentList.componentInstance.currentFolderId).toBe('cat-girl-nuku-nuku');
|
||||
});
|
||||
|
||||
it('should pass through the injected rowFilter to the documentList', () => {
|
||||
const documentList = fixture.debugElement.query(By.directive(DocumentListComponent));
|
||||
expect(documentList).not.toBeNull('Document list should be shown');
|
||||
expect(documentList.componentInstance.rowFilter({
|
||||
node: {
|
||||
entry: new Node({
|
||||
name: 'impossible-name',
|
||||
id: 'name'
|
||||
})
|
||||
}
|
||||
}))
|
||||
.toBe(data.rowFilter({
|
||||
expect(documentList).not.toBeNull();
|
||||
expect(
|
||||
documentList.componentInstance.rowFilter({
|
||||
node: {
|
||||
entry: new Node({
|
||||
name: 'impossible-name',
|
||||
id: 'name'
|
||||
})
|
||||
}
|
||||
}));
|
||||
})
|
||||
).toBe(
|
||||
data.rowFilter({
|
||||
node: {
|
||||
entry: new Node({
|
||||
name: 'impossible-name',
|
||||
id: 'name'
|
||||
})
|
||||
}
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
it('should pass through the injected imageResolver to the documentList', () => {
|
||||
const documentList = fixture.debugElement.query(By.directive(DocumentListComponent));
|
||||
expect(documentList).not.toBeNull('Document list should be shown');
|
||||
expect(documentList).not.toBeNull();
|
||||
expect(documentList.componentInstance.imageResolver).toBe(data.imageResolver);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Cancel button', () => {
|
||||
const getCancelButton = () => fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-cancel"]'));
|
||||
|
||||
it('should not be shown if dialogRef is NOT injected', () => {
|
||||
const closeButton = fixture.debugElement.query(By.css('[content-node-selector-actions-cancel]'));
|
||||
expect(closeButton).toBeNull();
|
||||
});
|
||||
|
||||
it('should close the dialog', () => {
|
||||
let cancelButton = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-cancel"]'));
|
||||
let cancelButton = getCancelButton();
|
||||
cancelButton.triggerEventHandler('click', {});
|
||||
expect(dialog.close).toHaveBeenCalled();
|
||||
|
||||
fixture.detectChanges();
|
||||
cancelButton = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-cancel"]'));
|
||||
cancelButton = getCancelButton();
|
||||
expect(cancelButton).not.toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Action button for the chosen node', () => {
|
||||
const getActionButton = () =>
|
||||
fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-choose"]'))?.nativeElement as HTMLButtonElement;
|
||||
|
||||
it('should be disabled by default', () => {
|
||||
fixture.detectChanges();
|
||||
|
||||
const actionButton = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-choose"]'));
|
||||
expect(actionButton.nativeElement.disabled).toBeTruthy();
|
||||
const actionButton = getActionButton();
|
||||
expect(actionButton.disabled).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should be enabled when a node is chosen', () => {
|
||||
component.onSelect([new Node({ id: 'fake' })]);
|
||||
fixture.detectChanges();
|
||||
|
||||
const actionButton = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-choose"]'));
|
||||
expect(actionButton.nativeElement.disabled).toBeFalsy();
|
||||
const actionButton = getActionButton();
|
||||
expect(actionButton.disabled).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should be disabled when no node chosen', () => {
|
||||
component.onSelect([new Node({ id: 'fake' })]);
|
||||
fixture.detectChanges();
|
||||
|
||||
const actionButtonWithNodeSelected = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-choose"]'));
|
||||
|
||||
expect(actionButtonWithNodeSelected.nativeElement.disabled).toBe(false);
|
||||
const actionButtonWithNodeSelected = getActionButton();
|
||||
expect(actionButtonWithNodeSelected.disabled).toBe(false);
|
||||
|
||||
component.onSelect([]);
|
||||
fixture.detectChanges();
|
||||
|
||||
const actionButtonWithoutNodeSelected = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-choose"]'));
|
||||
|
||||
expect(actionButtonWithoutNodeSelected.nativeElement.disabled).toBe(true);
|
||||
const actionButtonWithoutNodeSelected = getActionButton();
|
||||
expect(actionButtonWithoutNodeSelected.disabled).toBe(true);
|
||||
});
|
||||
|
||||
it('should close the dialog when action button is clicked', async () => {
|
||||
it('should close the dialog when action button is clicked', () => {
|
||||
component.onSelect([new Node({ id: 'fake' })]);
|
||||
fixture.detectChanges();
|
||||
|
||||
const actionButton = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-actions-choose"]'));
|
||||
await actionButton.nativeElement.click();
|
||||
const actionButton = getActionButton();
|
||||
actionButton.click();
|
||||
|
||||
expect(dialog.close).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Title', () => {
|
||||
|
||||
it('should be updated when a site is chosen', () => {
|
||||
const fakeSiteTitle = 'My fake site';
|
||||
const contentNodePanel = fixture.debugElement.query(By.directive(ContentNodeSelectorPanelComponent));
|
||||
@@ -253,17 +254,18 @@ describe('ContentNodeSelectorComponent', () => {
|
||||
const titleElement = fixture.debugElement.query(By.css('[data-automation-id="content-node-selector-title"]'));
|
||||
expect(titleElement).not.toBeNull();
|
||||
expect(titleElement.nativeElement.innerText).toBe('NODE_SELECTOR.CHOOSE_ITEM');
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Upload button', () => {
|
||||
const getUploadButton = () => fixture.debugElement.query(By.css('adf-upload-button button'))?.nativeElement as HTMLButtonElement;
|
||||
|
||||
it('Should not be able to upload a file whilst a search is still running', () => {
|
||||
enableLocalUpload();
|
||||
fixture.detectChanges();
|
||||
|
||||
let infoMatIcon = fixture.debugElement.query(By.css('[data-automation-id="adf-content-node-selector-disabled-tab-info-icon"]'));
|
||||
let uploadFromLocalTab = fixture.debugElement.queryAll(By.css('.mat-tab-label'))[1];
|
||||
let infoMatIcon = getTabInfoButton();
|
||||
let uploadFromLocalTab = getTabLabel(1);
|
||||
|
||||
expect(uploadFromLocalTab.nativeElement.getAttribute('aria-disabled')).toBe('false');
|
||||
expect(infoMatIcon).toBeFalsy();
|
||||
@@ -271,8 +273,8 @@ describe('ContentNodeSelectorComponent', () => {
|
||||
component.showingSearch = true;
|
||||
fixture.detectChanges();
|
||||
|
||||
uploadFromLocalTab = fixture.debugElement.queryAll(By.css('.mat-tab-label'))[1];
|
||||
infoMatIcon = fixture.debugElement.query(By.css('[data-automation-id="adf-content-node-selector-disabled-tab-info-icon"]'));
|
||||
uploadFromLocalTab = getTabLabel(1);
|
||||
infoMatIcon = getTabInfoButton();
|
||||
|
||||
expect(uploadFromLocalTab.nativeElement.getAttribute('aria-disabled')).toBe('true');
|
||||
expect(infoMatIcon).toBeTruthy();
|
||||
@@ -281,8 +283,8 @@ describe('ContentNodeSelectorComponent', () => {
|
||||
component.showingSearch = false;
|
||||
fixture.detectChanges();
|
||||
|
||||
uploadFromLocalTab = fixture.debugElement.queryAll(By.css('.mat-tab-label'))[1];
|
||||
infoMatIcon = fixture.debugElement.query(By.css('[data-automation-id="adf-content-node-selector-disabled-tab-info-icon"]'));
|
||||
uploadFromLocalTab = getTabLabel(1);
|
||||
infoMatIcon = getTabInfoButton();
|
||||
|
||||
expect(uploadFromLocalTab.nativeElement.getAttribute('aria-disabled')).toBe('false');
|
||||
expect(infoMatIcon).toBeFalsy();
|
||||
@@ -305,10 +307,10 @@ describe('ContentNodeSelectorComponent', () => {
|
||||
component.hasAllowableOperations = true;
|
||||
|
||||
fixture.detectChanges();
|
||||
const adfUploadButton = fixture.debugElement.query(By.css('adf-upload-button button'));
|
||||
const adfUploadButton = getUploadButton();
|
||||
|
||||
expect(adfUploadButton).not.toBeNull();
|
||||
expect(adfUploadButton.nativeElement.disabled).toBe(true);
|
||||
expect(adfUploadButton.disabled).toBe(true);
|
||||
});
|
||||
|
||||
it('should be able to enable UploadButton if showingSearch set to false', () => {
|
||||
@@ -317,10 +319,10 @@ describe('ContentNodeSelectorComponent', () => {
|
||||
component.hasAllowableOperations = true;
|
||||
|
||||
fixture.detectChanges();
|
||||
const adfUploadButton = fixture.debugElement.query(By.css('adf-upload-button button'));
|
||||
const adfUploadButton = getUploadButton();
|
||||
|
||||
expect(adfUploadButton).not.toBeNull();
|
||||
expect(adfUploadButton.nativeElement.disabled).toBe(false);
|
||||
expect(adfUploadButton.disabled).toBe(false);
|
||||
});
|
||||
|
||||
it('should be able to show warning message while searching', () => {
|
||||
@@ -330,7 +332,7 @@ describe('ContentNodeSelectorComponent', () => {
|
||||
selectTabByIndex(1);
|
||||
|
||||
fixture.detectChanges();
|
||||
const infoMatIcon = fixture.debugElement.query(By.css('[data-automation-id="adf-content-node-selector-disabled-tab-info-icon"]'));
|
||||
const infoMatIcon = getTabInfoButton();
|
||||
const iconTooltipMessage = infoMatIcon.attributes['ng-reflect-message'];
|
||||
|
||||
const expectedMessage = 'NODE_SELECTOR.UPLOAD_BUTTON_SEARCH_WARNING_MESSAGE';
|
||||
@@ -354,10 +356,10 @@ describe('ContentNodeSelectorComponent', () => {
|
||||
selectTabByIndex(1);
|
||||
|
||||
fixture.detectChanges();
|
||||
const adfUploadButton = fixture.debugElement.query(By.css('adf-upload-button button'));
|
||||
const adfUploadButton = getUploadButton();
|
||||
|
||||
expect(adfUploadButton).not.toBeNull();
|
||||
expect(adfUploadButton.nativeElement.disabled).toBe(true);
|
||||
expect(adfUploadButton.disabled).toBe(true);
|
||||
});
|
||||
|
||||
it('should be able to enable UploadButton if user has allowable operations', () => {
|
||||
@@ -365,10 +367,10 @@ describe('ContentNodeSelectorComponent', () => {
|
||||
component.hasAllowableOperations = true;
|
||||
|
||||
fixture.detectChanges();
|
||||
const adfUploadButton = fixture.debugElement.query(By.css('adf-upload-button button'));
|
||||
const adfUploadButton = getUploadButton();
|
||||
|
||||
expect(adfUploadButton).not.toBeNull();
|
||||
expect(adfUploadButton.nativeElement.disabled).toBe(false);
|
||||
expect(adfUploadButton.disabled).toBe(false);
|
||||
});
|
||||
|
||||
it('should not be able to show warning message if user has allowable operations', () => {
|
||||
@@ -388,7 +390,7 @@ describe('ContentNodeSelectorComponent', () => {
|
||||
selectTabByIndex(1);
|
||||
|
||||
fixture.detectChanges();
|
||||
const infoMatIcon = fixture.debugElement.query(By.css('[data-automation-id="adf-content-node-selector-disabled-tab-info-icon"]'));
|
||||
const infoMatIcon = getTabInfoButton();
|
||||
const iconTooltipMessage = infoMatIcon.attributes['ng-reflect-message'];
|
||||
const expectedMessage = 'NODE_SELECTOR.UPLOAD_BUTTON_PERMISSION_WARNING_MESSAGE';
|
||||
|
||||
@@ -424,11 +426,11 @@ describe('ContentNodeSelectorComponent', () => {
|
||||
});
|
||||
|
||||
it('should tabs be headless when local upload is not enabled', () => {
|
||||
component.data.showLocalUploadButton = false;
|
||||
fixture.detectChanges();
|
||||
const tabGroup = fixture.debugElement.queryAll(By.css('.adf-content-node-selector-headless-tabs'))[0];
|
||||
component.data.showLocalUploadButton = false;
|
||||
fixture.detectChanges();
|
||||
const tabGroup = fixture.debugElement.queryAll(By.css('.adf-content-node-selector-headless-tabs'))[0];
|
||||
|
||||
expect(tabGroup).not.toBe(undefined);
|
||||
expect(tabGroup).not.toBe(undefined);
|
||||
});
|
||||
|
||||
it('should tabs show headers when local upload is enabled', () => {
|
||||
@@ -441,12 +443,14 @@ describe('ContentNodeSelectorComponent', () => {
|
||||
});
|
||||
|
||||
describe('Drag and drop area', () => {
|
||||
const getEmptyList = () => fixture.nativeElement.querySelector('[data-automation-id="adf-empty-list"]');
|
||||
|
||||
it('should uploadStarted be false by default', () => {
|
||||
expect(component.uploadStarted).toBe(false);
|
||||
});
|
||||
|
||||
it('should uploadStarted become true when the first upload gets started', () => {
|
||||
const fileUploadEvent = new FileUploadEvent(new FileModel({ name: 'fake-name', size: 100 } as File));
|
||||
const fileUploadEvent = new FileUploadEvent(new FileModel({ name: 'fake-name', size: 100 } as File));
|
||||
uploadService.fileUploadStarting.next(fileUploadEvent);
|
||||
|
||||
expect(component.uploadStarted).toBe(true);
|
||||
@@ -454,12 +458,13 @@ describe('ContentNodeSelectorComponent', () => {
|
||||
|
||||
it('should show drag and drop area with the empty list template when no upload has started', async () => {
|
||||
enableLocalUpload();
|
||||
const uploadFromLocalTab = fixture.debugElement.queryAll(By.css('.mat-tab-label'))[1];
|
||||
const uploadFromLocalTab = getTabLabel(1);
|
||||
uploadFromLocalTab.nativeElement.click();
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenRenderingDone();
|
||||
const emptyListTemplate = fixture.nativeElement.querySelector('[data-automation-id="adf-empty-list"]');
|
||||
|
||||
const emptyListTemplate = getEmptyList();
|
||||
const dragAndDropArea = fixture.debugElement.query(By.css('.adf-upload-drag-area'));
|
||||
|
||||
expect(emptyListTemplate).not.toBeNull();
|
||||
@@ -468,19 +473,21 @@ describe('ContentNodeSelectorComponent', () => {
|
||||
|
||||
it('should not show the empty list template when an upload has started', async () => {
|
||||
enableLocalUpload();
|
||||
const uploadFromLocalTab = fixture.debugElement.queryAll(By.css('.mat-tab-label'))[1];
|
||||
const uploadFromLocalTab = getTabLabel(1);
|
||||
uploadFromLocalTab.nativeElement.click();
|
||||
|
||||
component.uploadStarted = true;
|
||||
fixture.detectChanges();
|
||||
await fixture.whenRenderingDone();
|
||||
const emptyListTemplate = fixture.nativeElement.querySelector('[data-automation-id="adf-empty-list"]');
|
||||
|
||||
const emptyListTemplate = getEmptyList();
|
||||
expect(emptyListTemplate).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Selected nodes counter', () => {
|
||||
const getNodeCounter = () => fixture.debugElement.nativeElement.querySelector('adf-node-counter');
|
||||
|
||||
it('should getSelectedCount return 0 by default', () => {
|
||||
expect(component.getSelectedCount()).toBe(0);
|
||||
});
|
||||
@@ -494,19 +501,19 @@ describe('ContentNodeSelectorComponent', () => {
|
||||
it('should show the counter depending on the action', () => {
|
||||
component.action = NodeAction.ATTACH;
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement.querySelector('adf-node-counter')).not.toBe(null);
|
||||
expect(getNodeCounter()).not.toBe(null);
|
||||
|
||||
component.action = NodeAction.CHOOSE;
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement.querySelector('adf-node-counter')).not.toBe(null);
|
||||
expect(getNodeCounter()).not.toBe(null);
|
||||
|
||||
component.action = NodeAction.COPY;
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement.querySelector('adf-node-counter')).toBe(null);
|
||||
expect(getNodeCounter()).toBe(null);
|
||||
|
||||
component.action = NodeAction.MOVE;
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.nativeElement.querySelector('adf-node-counter')).toBe(null);
|
||||
expect(getNodeCounter()).toBe(null);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+49
-29
@@ -15,9 +15,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Component, Inject, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { Component, Inject, OnDestroy, OnInit, ViewEncapsulation } from '@angular/core';
|
||||
import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
|
||||
import { TranslationService, NotificationService} from '@alfresco/adf-core';
|
||||
import { TranslationService, NotificationService } from '@alfresco/adf-core';
|
||||
import { Node } from '@alfresco/js-api';
|
||||
import { AllowableOperationsEnum } from '../common/models/allowable-operations.enum';
|
||||
import { ContentService } from '../common/services/content.service';
|
||||
@@ -26,6 +26,8 @@ import { ContentNodeSelectorComponentData } from './content-node-selector.compon
|
||||
import { NodeEntryEvent } from '../document-list/components/node.event';
|
||||
import { NodeAction } from '../document-list/models/node-action.enum';
|
||||
import { OverlayContainer } from '@angular/cdk/overlay';
|
||||
import { Subject } from 'rxjs';
|
||||
import { takeUntil } from 'rxjs/operators';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-content-node-selector',
|
||||
@@ -33,7 +35,9 @@ import { OverlayContainer } from '@angular/cdk/overlay';
|
||||
styleUrls: ['./content-node-selector.component.scss'],
|
||||
encapsulation: ViewEncapsulation.None
|
||||
})
|
||||
export class ContentNodeSelectorComponent implements OnInit {
|
||||
export class ContentNodeSelectorComponent implements OnInit, OnDestroy {
|
||||
private onDestroy$ = new Subject<void>();
|
||||
|
||||
title: string;
|
||||
action: NodeAction;
|
||||
buttonActionName: string;
|
||||
@@ -48,13 +52,15 @@ export class ContentNodeSelectorComponent implements OnInit {
|
||||
emptyFolderImageUrl: string = './assets/images/empty_doc_lib.svg';
|
||||
breadcrumbFolderNode: Node;
|
||||
|
||||
constructor(private translation: TranslationService,
|
||||
private contentService: ContentService,
|
||||
private notificationService: NotificationService,
|
||||
private uploadService: UploadService,
|
||||
private dialog: MatDialogRef<ContentNodeSelectorComponent>,
|
||||
private overlayContainer: OverlayContainer,
|
||||
@Inject(MAT_DIALOG_DATA) public data: ContentNodeSelectorComponentData) {
|
||||
constructor(
|
||||
private translation: TranslationService,
|
||||
private contentService: ContentService,
|
||||
private notificationService: NotificationService,
|
||||
private uploadService: UploadService,
|
||||
private dialog: MatDialogRef<ContentNodeSelectorComponent>,
|
||||
private overlayContainer: OverlayContainer,
|
||||
@Inject(MAT_DIALOG_DATA) public data: ContentNodeSelectorComponentData
|
||||
) {
|
||||
this.action = data.actionName ?? NodeAction.CHOOSE;
|
||||
this.buttonActionName = `NODE_SELECTOR.${this.action}`;
|
||||
this.title = data.title;
|
||||
@@ -62,28 +68,41 @@ export class ContentNodeSelectorComponent implements OnInit {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.dialog.keydownEvents().subscribe(event => {
|
||||
// Esc
|
||||
if (event.keyCode === 27) {
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
this.dialog
|
||||
.keydownEvents()
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe((event) => {
|
||||
if (event?.key === 'Escape') {
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
this.close();
|
||||
}
|
||||
});
|
||||
|
||||
this.dialog
|
||||
.backdropClick()
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe(() => {
|
||||
this.close();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
this.dialog.backdropClick().subscribe(() => {
|
||||
this.close();
|
||||
});
|
||||
this.dialog
|
||||
.afterOpened()
|
||||
.pipe(takeUntil(this.onDestroy$))
|
||||
.subscribe(() => {
|
||||
this.overlayContainer.getContainerElement().setAttribute('role', 'main');
|
||||
});
|
||||
|
||||
this.dialog.afterOpened().subscribe(() => {
|
||||
this.overlayContainer.getContainerElement().setAttribute('role', 'main');
|
||||
});
|
||||
|
||||
this.uploadService.fileUploadStarting.subscribe(() => {
|
||||
this.uploadService.fileUploadStarting.pipe(takeUntil(this.onDestroy$)).subscribe(() => {
|
||||
this.uploadStarted = true;
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
this.onDestroy$.next();
|
||||
this.onDestroy$.complete();
|
||||
}
|
||||
|
||||
close() {
|
||||
this.dialog.close();
|
||||
this.overlayContainer.getContainerElement().setAttribute('role', 'region');
|
||||
@@ -179,16 +198,17 @@ export class ContentNodeSelectorComponent implements OnInit {
|
||||
}
|
||||
|
||||
getWarningMessage(): string {
|
||||
return this.showingSearch ? 'NODE_SELECTOR.UPLOAD_BUTTON_SEARCH_WARNING_MESSAGE' :
|
||||
(this.hasNoPermissionToUpload() ? 'NODE_SELECTOR.UPLOAD_BUTTON_PERMISSION_WARNING_MESSAGE' : '');
|
||||
if (this.showingSearch) {
|
||||
return 'NODE_SELECTOR.UPLOAD_BUTTON_SEARCH_WARNING_MESSAGE';
|
||||
}
|
||||
return this.hasNoPermissionToUpload() ? 'NODE_SELECTOR.UPLOAD_BUTTON_PERMISSION_WARNING_MESSAGE' : '';
|
||||
}
|
||||
|
||||
hasNoPermissionToUpload(): boolean {
|
||||
return (!this.hasAllowableOperations && !this.showingSearch) && !this.isLoading;
|
||||
return !this.hasAllowableOperations && !this.showingSearch && !this.isLoading;
|
||||
}
|
||||
|
||||
hasUploadError(): boolean {
|
||||
return this.showingSearch || this.hasNoPermissionToUpload();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
&__dialog-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 24px;
|
||||
background-color: var(--theme-grey-text-background-color);
|
||||
}
|
||||
|
||||
&__dialog-container {
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { TestBed, fakeAsync, ComponentFixture, tick } from '@angular/core/testing';
|
||||
import { TestBed, ComponentFixture } from '@angular/core/testing';
|
||||
import { MatDialogRef, MAT_DIALOG_DATA, MatDialog } from '@angular/material/dialog';
|
||||
import { of } from 'rxjs';
|
||||
import { NotificationService, AppConfigService } from '@alfresco/adf-core';
|
||||
@@ -28,8 +28,12 @@ import { TranslateModule } from '@ngx-translate/core';
|
||||
import { format, endOfDay } from 'date-fns';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { NodeEntry } from '@alfresco/js-api';
|
||||
import { HarnessLoader } from '@angular/cdk/testing';
|
||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||
import { MatSlideToggleHarness } from '@angular/material/slide-toggle/testing';
|
||||
|
||||
describe('ShareDialogComponent', () => {
|
||||
let loader: HarnessLoader;
|
||||
let node: NodeEntry;
|
||||
let matDialog: MatDialog;
|
||||
const notificationServiceMock = {
|
||||
@@ -45,8 +49,6 @@ describe('ShareDialogComponent', () => {
|
||||
const shareToggleId = '[data-automation-id="adf-share-toggle"]';
|
||||
const expireToggle = '[data-automation-id="adf-expire-toggle"]';
|
||||
|
||||
const getShareToggleLinkedClasses = (): DOMTokenList => fixture.nativeElement.querySelector(shareToggleId).classList;
|
||||
|
||||
const fillInDatepickerInput = (value: string) => {
|
||||
const input = fixture.debugElement.query(By.css('.adf-share-link__input')).nativeElement;
|
||||
input.value = value;
|
||||
@@ -55,10 +57,6 @@ describe('ShareDialogComponent', () => {
|
||||
fixture.detectChanges();
|
||||
};
|
||||
|
||||
const clickExpireToggleButton = () => fixture.nativeElement.querySelector(`${expireToggle} label`).dispatchEvent(new MouseEvent('click'));
|
||||
|
||||
const clickShareToggleButton = () => fixture.nativeElement.querySelector(`${shareToggleId} label`).dispatchEvent(new MouseEvent('click'));
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [TranslateModule.forRoot(), ContentTestingModule],
|
||||
@@ -99,6 +97,7 @@ describe('ShareDialogComponent', () => {
|
||||
};
|
||||
|
||||
spyOn(nodesApiService, 'updateNode').and.returnValue(of(null));
|
||||
loader = TestbedHarnessEnvironment.loader(fixture);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -133,7 +132,7 @@ describe('ShareDialogComponent', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it(`should toggle share action when property 'sharedId' does not exists`, () => {
|
||||
it(`should toggle share action when property 'sharedId' does not exists`, async () => {
|
||||
spyOn(sharedLinksApiService, 'createSharedLinks').and.returnValue(
|
||||
of({
|
||||
entry: { id: 'sharedId', sharedId: 'sharedId' }
|
||||
@@ -151,7 +150,9 @@ describe('ShareDialogComponent', () => {
|
||||
expect(sharedLinksApiService.createSharedLinks).toHaveBeenCalled();
|
||||
expect(renditionService.getNodeRendition).toHaveBeenCalled();
|
||||
expect(fixture.nativeElement.querySelector('input[formcontrolname="sharedUrl"]').value).toBe('some-url/sharedId');
|
||||
expect(getShareToggleLinkedClasses()).toContain('mat-checked');
|
||||
|
||||
const toggle = await loader.getHarness(MatSlideToggleHarness.with({ selector: shareToggleId }));
|
||||
expect(await toggle.isChecked()).toBe(true);
|
||||
});
|
||||
|
||||
it(`should not toggle share action when file has 'sharedId' property`, async () => {
|
||||
@@ -176,10 +177,12 @@ describe('ShareDialogComponent', () => {
|
||||
|
||||
expect(sharedLinksApiService.createSharedLinks).not.toHaveBeenCalled();
|
||||
expect(fixture.nativeElement.querySelector('input[formcontrolname="sharedUrl"]').value).toBe('some-url/sharedId');
|
||||
expect(getShareToggleLinkedClasses()).toContain('mat-checked');
|
||||
|
||||
const toggle = await loader.getHarness(MatSlideToggleHarness.with({ selector: shareToggleId }));
|
||||
expect(await toggle.isChecked()).toBe(true);
|
||||
});
|
||||
|
||||
it('should open a confirmation dialog when unshare button is triggered', () => {
|
||||
it('should open a confirmation dialog when unshare button is triggered', async () => {
|
||||
spyOn(matDialog, 'open').and.returnValue({ beforeClosed: () => of(false) } as any);
|
||||
spyOn(sharedLinksApiService, 'deleteSharedLink').and.callThrough();
|
||||
|
||||
@@ -192,14 +195,13 @@ describe('ShareDialogComponent', () => {
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
clickShareToggleButton();
|
||||
|
||||
fixture.detectChanges();
|
||||
const toggle = await loader.getHarness(MatSlideToggleHarness.with({ selector: shareToggleId }));
|
||||
await toggle.toggle();
|
||||
|
||||
expect(matDialog.open).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should unshare file when confirmation dialog returns true', fakeAsync(() => {
|
||||
it('should unshare file when confirmation dialog returns true', async () => {
|
||||
spyOn(matDialog, 'open').and.returnValue({ beforeClosed: () => of(true) } as any);
|
||||
spyOn(sharedLinksApiService, 'deleteSharedLink').and.returnValue(of({}));
|
||||
node.entry.properties['qshare:sharedId'] = 'sharedId';
|
||||
@@ -211,14 +213,13 @@ describe('ShareDialogComponent', () => {
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
clickShareToggleButton();
|
||||
|
||||
fixture.detectChanges();
|
||||
const toggle = await loader.getHarness(MatSlideToggleHarness.with({ selector: shareToggleId }));
|
||||
await toggle.toggle();
|
||||
|
||||
expect(sharedLinksApiService.deleteSharedLink).toHaveBeenCalled();
|
||||
}));
|
||||
});
|
||||
|
||||
it('should not unshare file when confirmation dialog returns false', fakeAsync(() => {
|
||||
it('should not unshare file when confirmation dialog returns false', async () => {
|
||||
spyOn(matDialog, 'open').and.returnValue({ beforeClosed: () => of(false) } as any);
|
||||
spyOn(sharedLinksApiService, 'deleteSharedLink').and.callThrough();
|
||||
node.entry.properties['qshare:sharedId'] = 'sharedId';
|
||||
@@ -230,14 +231,13 @@ describe('ShareDialogComponent', () => {
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
clickShareToggleButton();
|
||||
|
||||
fixture.detectChanges();
|
||||
const toggle = await loader.getHarness(MatSlideToggleHarness.with({ selector: shareToggleId }));
|
||||
await toggle.toggle();
|
||||
|
||||
expect(sharedLinksApiService.deleteSharedLink).not.toHaveBeenCalled();
|
||||
}));
|
||||
});
|
||||
|
||||
it('should not allow unshare when node has no update permission', () => {
|
||||
it('should not allow unshare when node has no update permission', async () => {
|
||||
node.entry.properties['qshare:sharedId'] = 'sharedId';
|
||||
node.entry.allowableOperations = [];
|
||||
|
||||
@@ -248,7 +248,8 @@ describe('ShareDialogComponent', () => {
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(getShareToggleLinkedClasses()).toContain('mat-disabled');
|
||||
const toggle = await loader.getHarness(MatSlideToggleHarness.with({ selector: shareToggleId }));
|
||||
expect(await toggle.isChecked()).toBe(true);
|
||||
});
|
||||
|
||||
it('should delete the current link generated with expiry date and generate a new link without expiry date when toggle is unchecked', async () => {
|
||||
@@ -266,9 +267,9 @@ describe('ShareDialogComponent', () => {
|
||||
fixture.detectChanges();
|
||||
component.form.controls['time'].setValue(new Date());
|
||||
fixture.detectChanges();
|
||||
clickExpireToggleButton();
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const toggle = await loader.getHarness(MatSlideToggleHarness.with({ selector: expireToggle }));
|
||||
await toggle.toggle();
|
||||
|
||||
expect(sharedLinksApiService.deleteSharedLink).toHaveBeenCalled();
|
||||
expect(sharedLinksApiService.createSharedLinks).toHaveBeenCalledWith('nodeId', undefined);
|
||||
@@ -286,7 +287,9 @@ describe('ShareDialogComponent', () => {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(fixture.nativeElement.querySelector('.mat-slide-toggle[data-automation-id="adf-expire-toggle"]').classList).toContain('mat-disabled');
|
||||
const toggle = await loader.getHarness(MatSlideToggleHarness.with({ selector: `[data-automation-id="adf-expire-toggle"]` }));
|
||||
expect(await toggle.isDisabled()).toBe(true);
|
||||
|
||||
expect(fixture.nativeElement.querySelector('[data-automation-id="adf-slide-toggle-checked"]').style.display).toEqual('none');
|
||||
});
|
||||
|
||||
@@ -303,18 +306,19 @@ describe('ShareDialogComponent', () => {
|
||||
};
|
||||
});
|
||||
|
||||
it('should update node with input date and end of day time when type is `date`', fakeAsync(() => {
|
||||
it('should update node with input date and end of day time when type is `date`', async () => {
|
||||
const dateTimePickerType = 'date';
|
||||
const date = new Date('2525-01-01');
|
||||
spyOn(appConfigService, 'get').and.callFake(() => dateTimePickerType as any);
|
||||
|
||||
fixture.detectChanges();
|
||||
clickExpireToggleButton();
|
||||
|
||||
const toggle = await loader.getHarness(MatSlideToggleHarness.with({ selector: expireToggle }));
|
||||
await toggle.toggle();
|
||||
|
||||
fixture.componentInstance.time.setValue(date);
|
||||
component.onTimeChanged();
|
||||
fixture.detectChanges();
|
||||
tick(500);
|
||||
|
||||
const expiryDate = format(endOfDay(date as Date), `yyyy-MM-dd'T'HH:mm:ss.SSSxx`);
|
||||
|
||||
@@ -323,11 +327,14 @@ describe('ShareDialogComponent', () => {
|
||||
nodeId: 'nodeId',
|
||||
expiresAt: expiryDate
|
||||
});
|
||||
}));
|
||||
});
|
||||
|
||||
it('should not update node when provided date is less than minDate', () => {
|
||||
it('should not update node when provided date is less than minDate', async () => {
|
||||
fixture.detectChanges();
|
||||
clickExpireToggleButton();
|
||||
|
||||
const toggle = await loader.getHarness(MatSlideToggleHarness.with({ selector: expireToggle }));
|
||||
await toggle.toggle();
|
||||
|
||||
fillInDatepickerInput('01.01.2010');
|
||||
|
||||
expect(component.form.invalid).toBeTrue();
|
||||
@@ -335,9 +342,12 @@ describe('ShareDialogComponent', () => {
|
||||
expect(sharedLinksApiService.createSharedLinks).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not accept alphabets in the datepicker input', () => {
|
||||
it('should not accept alphabets in the datepicker input', async () => {
|
||||
fixture.detectChanges();
|
||||
clickExpireToggleButton();
|
||||
|
||||
const toggle = await loader.getHarness(MatSlideToggleHarness.with({ selector: expireToggle }));
|
||||
await toggle.toggle();
|
||||
|
||||
fillInDatepickerInput('test');
|
||||
|
||||
expect(component.form.invalid).toBeTrue();
|
||||
@@ -346,7 +356,10 @@ describe('ShareDialogComponent', () => {
|
||||
|
||||
it('should show an error if provided date is invalid', async () => {
|
||||
fixture.detectChanges();
|
||||
clickExpireToggleButton();
|
||||
|
||||
const toggle = await loader.getHarness(MatSlideToggleHarness.with({ selector: expireToggle }));
|
||||
await toggle.toggle();
|
||||
|
||||
fillInDatepickerInput('incorrect');
|
||||
|
||||
fixture.detectChanges();
|
||||
@@ -358,9 +371,12 @@ describe('ShareDialogComponent', () => {
|
||||
expect(component.time.hasError('invalidDate')).toBeTrue();
|
||||
});
|
||||
|
||||
it('should not show an error when provided date is valid', () => {
|
||||
it('should not show an error when provided date is valid', async () => {
|
||||
fixture.detectChanges();
|
||||
clickExpireToggleButton();
|
||||
|
||||
const toggle = await loader.getHarness(MatSlideToggleHarness.with({ selector: expireToggle }));
|
||||
await toggle.toggle();
|
||||
|
||||
fillInDatepickerInput('12.12.2525');
|
||||
const error = fixture.debugElement.query(By.css('[data-automation-id="adf-share-link-input-warning"]'));
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<h2 mat-dialog-title>
|
||||
<h2 data-automation-id="adf-folder-dialog-title" mat-dialog-title>
|
||||
{{ (editing ? editTitle : createTitle) | translate }}
|
||||
</h2>
|
||||
|
||||
|
||||
@@ -35,13 +35,8 @@ describe('FolderDialogComponent', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
TranslateModule.forRoot(),
|
||||
ContentTestingModule
|
||||
],
|
||||
providers: [
|
||||
{ provide: MatDialogRef, useValue: dialogRef }
|
||||
]
|
||||
imports: [TranslateModule.forRoot(), ContentTestingModule],
|
||||
providers: [{ provide: MatDialogRef, useValue: dialogRef }]
|
||||
});
|
||||
dialogRef.close.calls.reset();
|
||||
fixture = TestBed.createComponent(FolderDialogComponent);
|
||||
@@ -53,8 +48,9 @@ describe('FolderDialogComponent', () => {
|
||||
fixture.destroy();
|
||||
});
|
||||
|
||||
describe('Edit', () => {
|
||||
const getTitle = () => fixture.debugElement.query(By.css('[data-automation-id="adf-folder-dialog-title"]'));
|
||||
|
||||
describe('Edit', () => {
|
||||
beforeEach(() => {
|
||||
component.data = {
|
||||
folder: {
|
||||
@@ -76,8 +72,8 @@ describe('FolderDialogComponent', () => {
|
||||
});
|
||||
|
||||
it('should have the proper title', () => {
|
||||
const title = fixture.debugElement.query(By.css('[mat-dialog-title]'));
|
||||
expect(title === null).toBe(false);
|
||||
const title = getTitle();
|
||||
expect(title).not.toBeNull();
|
||||
expect(title.nativeElement.innerText.trim()).toBe('CORE.FOLDER_DIALOG.EDIT_FOLDER_TITLE');
|
||||
});
|
||||
|
||||
@@ -100,16 +96,13 @@ describe('FolderDialogComponent', () => {
|
||||
|
||||
component.submit();
|
||||
|
||||
expect(nodesApi.updateNode).toHaveBeenCalledWith(
|
||||
'node-id',
|
||||
{
|
||||
name: 'folder-name-update',
|
||||
properties: {
|
||||
'cm:title': 'folder-title-update',
|
||||
'cm:description': 'folder-description-update'
|
||||
}
|
||||
expect(nodesApi.updateNode).toHaveBeenCalledWith('node-id', {
|
||||
name: 'folder-name-update',
|
||||
properties: {
|
||||
'cm:title': 'folder-title-update',
|
||||
'cm:description': 'folder-description-update'
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('should call dialog to close with form data when submit is successfully', () => {
|
||||
@@ -174,10 +167,10 @@ describe('FolderDialogComponent', () => {
|
||||
});
|
||||
|
||||
it('should have the proper title', () => {
|
||||
const title = fixture.debugElement.query(By.css('[mat-dialog-title]'));
|
||||
expect(title === null).toBe(false);
|
||||
const title = getTitle();
|
||||
expect(title).not.toBeNull();
|
||||
expect(title.nativeElement.innerText.trim()).toBe('CORE.FOLDER_DIALOG.CREATE_FOLDER_TITLE');
|
||||
});
|
||||
});
|
||||
|
||||
it('should init form with empty inputs', () => {
|
||||
expect(component.name).toBe('');
|
||||
@@ -201,17 +194,14 @@ describe('FolderDialogComponent', () => {
|
||||
|
||||
component.submit();
|
||||
|
||||
expect(nodesApi.createFolder).toHaveBeenCalledWith(
|
||||
'parentNodeId',
|
||||
{
|
||||
name: 'folder-name-update',
|
||||
properties: {
|
||||
'cm:title': 'folder-title-update',
|
||||
'cm:description': 'folder-description-update'
|
||||
},
|
||||
nodeType: 'cm:folder'
|
||||
}
|
||||
);
|
||||
expect(nodesApi.createFolder).toHaveBeenCalledWith('parentNodeId', {
|
||||
name: 'folder-name-update',
|
||||
properties: {
|
||||
'cm:title': 'folder-title-update',
|
||||
'cm:description': 'folder-description-update'
|
||||
},
|
||||
nodeType: 'cm:folder'
|
||||
});
|
||||
});
|
||||
|
||||
it('should submit updated values if form is valid (with custom nodeType)', () => {
|
||||
@@ -224,17 +214,14 @@ describe('FolderDialogComponent', () => {
|
||||
|
||||
component.submit();
|
||||
|
||||
expect(nodesApi.createFolder).toHaveBeenCalledWith(
|
||||
'parentNodeId',
|
||||
{
|
||||
name: 'folder-name-update',
|
||||
properties: {
|
||||
'cm:title': 'folder-title-update',
|
||||
'cm:description': 'folder-description-update'
|
||||
},
|
||||
nodeType: 'cm:sushi'
|
||||
}
|
||||
);
|
||||
expect(nodesApi.createFolder).toHaveBeenCalledWith('parentNodeId', {
|
||||
name: 'folder-name-update',
|
||||
properties: {
|
||||
'cm:title': 'folder-title-update',
|
||||
'cm:description': 'folder-description-update'
|
||||
},
|
||||
nodeType: 'cm:sushi'
|
||||
});
|
||||
});
|
||||
|
||||
it('should call dialog to close with form data when submit is successfully', () => {
|
||||
@@ -315,5 +302,5 @@ describe('FolderDialogComponent', () => {
|
||||
component.submit();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -18,8 +18,7 @@
|
||||
import { Component, ViewChild } from '@angular/core';
|
||||
import { LibraryFavoriteDirective } from './library-favorite.directive';
|
||||
import { TestBed, ComponentFixture } from '@angular/core/testing';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { AlfrescoApiServiceMock, CoreModule, AlfrescoApiService } from '@alfresco/adf-core';
|
||||
import { CoreTestingModule } from '@alfresco/adf-core';
|
||||
import { LibraryEntity } from '../interfaces/library-entity.interface';
|
||||
|
||||
@Component({
|
||||
@@ -40,10 +39,7 @@ describe('LibraryFavoriteDirective', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [TranslateModule.forRoot(), CoreModule.forRoot()],
|
||||
providers: [
|
||||
{ provide: AlfrescoApiService, useClass: AlfrescoApiServiceMock }
|
||||
],
|
||||
imports: [CoreTestingModule],
|
||||
declarations: [TestComponent, LibraryFavoriteDirective]
|
||||
});
|
||||
fixture = TestBed.createComponent(TestComponent);
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
[rowMenuCacheEnabled]="false"
|
||||
[stickyHeader]="stickyHeader"
|
||||
[allowFiltering]="allowFiltering"
|
||||
[isResizingEnabled]="isResizingEnabled"
|
||||
[blurOnResize]="blurOnResize"
|
||||
(showRowContextMenu)="onShowRowContextMenu($event)"
|
||||
(showRowActionsMenu)="onShowRowActionsMenu($event)"
|
||||
(executeRowAction)="onExecuteRowAction($event)"
|
||||
|
||||
+25
-16
@@ -18,7 +18,6 @@
|
||||
import { CUSTOM_ELEMENTS_SCHEMA, SimpleChange, QueryList, Component, ViewChild, SimpleChanges } from '@angular/core';
|
||||
import { ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
|
||||
import {
|
||||
AlfrescoApiService,
|
||||
DataColumnListComponent,
|
||||
DataColumnComponent,
|
||||
DataColumn,
|
||||
@@ -27,7 +26,8 @@ import {
|
||||
ObjectDataTableAdapter,
|
||||
ShowHeaderMode,
|
||||
ThumbnailService,
|
||||
AppConfigService
|
||||
AppConfigService,
|
||||
AuthenticationService
|
||||
} from '@alfresco/adf-core';
|
||||
import { ContentService } from '../../common/services/content.service';
|
||||
import { Subject, of, throwError } from 'rxjs';
|
||||
@@ -62,15 +62,18 @@ import { domSanitizerMock } from '../../testing/dom-sanitizer-mock';
|
||||
import { MatDialog } from '@angular/material/dialog';
|
||||
import { FileAutoDownloadComponent } from './file-auto-download/file-auto-download.component';
|
||||
import { ShareDataTableAdapter } from '../data/share-datatable-adapter';
|
||||
import { HarnessLoader } from '@angular/cdk/testing';
|
||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||
import { MatProgressSpinnerHarness } from '@angular/material/progress-spinner/testing';
|
||||
|
||||
const mockDialog = {
|
||||
open: jasmine.createSpy('open')
|
||||
};
|
||||
|
||||
describe('DocumentList', () => {
|
||||
let loader: HarnessLoader;
|
||||
let documentList: DocumentListComponent;
|
||||
let documentListService: DocumentListService;
|
||||
let apiService: AlfrescoApiService;
|
||||
let customResourcesService: CustomResourcesService;
|
||||
let thumbnailService: ThumbnailService;
|
||||
let contentService: ContentService;
|
||||
@@ -82,6 +85,7 @@ describe('DocumentList', () => {
|
||||
let spyFavorite: any;
|
||||
let spyFolder: any;
|
||||
let spyFolderNode: any;
|
||||
let authenticationService: AuthenticationService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
@@ -99,11 +103,11 @@ describe('DocumentList', () => {
|
||||
documentList = fixture.componentInstance;
|
||||
|
||||
documentListService = TestBed.inject(DocumentListService);
|
||||
apiService = TestBed.inject(AlfrescoApiService);
|
||||
customResourcesService = TestBed.inject(CustomResourcesService);
|
||||
thumbnailService = TestBed.inject(ThumbnailService);
|
||||
contentService = TestBed.inject(ContentService);
|
||||
appConfigService = TestBed.inject(AppConfigService);
|
||||
authenticationService = TestBed.inject(AuthenticationService);
|
||||
|
||||
spyFolder = spyOn(documentListService, 'getFolder').and.returnValue(of({ list: {} }));
|
||||
spyFolderNode = spyOn(documentListService, 'getFolderNode').and.returnValue(of(new NodeEntry({ entry: new Node() })));
|
||||
@@ -116,6 +120,8 @@ describe('DocumentList', () => {
|
||||
spyFavorite = spyOn(customResourcesService.favoritesApi, 'listFavorites').and.returnValue(
|
||||
Promise.resolve(new FavoritePaging({ list: new FavoritePagingList({ entries: [] }) }))
|
||||
);
|
||||
|
||||
loader = TestbedHarnessEnvironment.loader(fixture);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -219,7 +225,7 @@ describe('DocumentList', () => {
|
||||
|
||||
it('should show the header when there are no records in the table but filter is active', () => {
|
||||
documentList.data = new ShareDataTableAdapter(thumbnailService, contentService, []);
|
||||
documentList.filterValue = { $thumbnail: 'TYPE:"cm:folder"' };
|
||||
documentList.filterValue = { $thumbnail: 'TYPE:"cm:folder"' };
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
@@ -611,7 +617,7 @@ describe('DocumentList', () => {
|
||||
title: 'FileAction'
|
||||
});
|
||||
|
||||
spyOn(apiService.getInstance(), 'getEcmUsername').and.returnValue('lockOwner');
|
||||
spyOn(authenticationService, 'getEcmUsername').and.returnValue('lockOwner');
|
||||
|
||||
documentList.actions = [documentMenu];
|
||||
|
||||
@@ -642,7 +648,7 @@ describe('DocumentList', () => {
|
||||
title: 'FileAction'
|
||||
});
|
||||
|
||||
spyOn(apiService.getInstance(), 'getEcmUsername').and.returnValue('jerryTheKillerCow');
|
||||
spyOn(authenticationService, 'getEcmUsername').and.returnValue('jerryTheKillerCow');
|
||||
|
||||
documentList.actions = [documentMenu];
|
||||
|
||||
@@ -1075,10 +1081,11 @@ describe('DocumentList', () => {
|
||||
expect(fixture.debugElement.query(By.css('.adf-no-permission__template'))).not.toBeNull();
|
||||
});
|
||||
|
||||
it('should display loading template when data is loading', () => {
|
||||
it('should display loading template when data is loading', async () => {
|
||||
documentList.loading = true;
|
||||
fixture.detectChanges();
|
||||
expect(fixture.debugElement.query(By.css('mat-progress-spinner'))).not.toBeNull();
|
||||
|
||||
expect(await loader.hasHarness(MatProgressSpinnerHarness)).toBe(true);
|
||||
});
|
||||
|
||||
it('should empty folder NOT show the pagination', () => {
|
||||
@@ -1406,14 +1413,16 @@ describe('DocumentList', () => {
|
||||
expect(documentList.reload).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not show loading state if pagination is updated with merge setting as true', fakeAsync (() => {
|
||||
it('should not show loading state if pagination is updated with merge setting as true', fakeAsync(() => {
|
||||
spyFolderNode = spyOn(documentListService, 'loadFolderByNodeId').and.callFake(() =>
|
||||
of(new DocumentLoaderNode(null, {
|
||||
list: {
|
||||
pagination: {},
|
||||
entries: mockPreselectedNodes
|
||||
}
|
||||
}))
|
||||
of(
|
||||
new DocumentLoaderNode(null, {
|
||||
list: {
|
||||
pagination: {},
|
||||
entries: mockPreselectedNodes
|
||||
}
|
||||
})
|
||||
)
|
||||
);
|
||||
fixture.detectChanges();
|
||||
const fakeDatatableRows = [
|
||||
|
||||
@@ -323,6 +323,14 @@ export class DocumentListComponent extends DataTableSchema implements OnInit, On
|
||||
@Input()
|
||||
maxColumnsVisible?: number;
|
||||
|
||||
/** Enables column resizing for datatable */
|
||||
@Input()
|
||||
isResizingEnabled = false;
|
||||
|
||||
/** Enables blur when resizing datatable columns */
|
||||
@Input()
|
||||
blurOnResize = true;
|
||||
|
||||
/** Emitted when the user clicks a list node */
|
||||
@Output()
|
||||
nodeClick = new EventEmitter<NodeEntityEvent>();
|
||||
|
||||
@@ -98,7 +98,7 @@ export class CustomResourcesService {
|
||||
getRecentFiles(personId: string, pagination: PaginationModel, filters?: string[]): Observable<ResultSetPaging> {
|
||||
const defaultFilter = [
|
||||
'TYPE:"content"',
|
||||
'-PNAME:"0/wiki"',
|
||||
'-PATH:"//cm:wiki/*"',
|
||||
'-TYPE:"app:filelink"',
|
||||
'-TYPE:"cm:thumbnail"',
|
||||
'-TYPE:"cm:failedThumbnail"',
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { LockService } from './lock.service';
|
||||
import { CoreTestingModule, AlfrescoApiService } from '@alfresco/adf-core';
|
||||
import { CoreTestingModule, AuthenticationService } from '@alfresco/adf-core';
|
||||
import { Node } from '@alfresco/js-api';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { addDays, subDays } from 'date-fns';
|
||||
@@ -25,7 +25,7 @@ import { addDays, subDays } from 'date-fns';
|
||||
describe('PeopleProcessService', () => {
|
||||
|
||||
let service: LockService;
|
||||
let apiService: AlfrescoApiService;
|
||||
let authenticationService: AuthenticationService;
|
||||
|
||||
const fakeNodeUnlocked: Node = { name: 'unlocked', isLocked: false, isFile: true } as Node;
|
||||
const fakeFolderNode: Node = { name: 'unlocked', isLocked: false, isFile: false, isFolder: true } as Node;
|
||||
@@ -39,7 +39,7 @@ describe('PeopleProcessService', () => {
|
||||
]
|
||||
});
|
||||
service = TestBed.inject(LockService);
|
||||
apiService = TestBed.inject(AlfrescoApiService);
|
||||
authenticationService = TestBed.inject(AuthenticationService);
|
||||
});
|
||||
|
||||
it('should return false when no lock is configured', () => {
|
||||
@@ -145,22 +145,22 @@ describe('PeopleProcessService', () => {
|
||||
} as Node;
|
||||
|
||||
it('should return false when the user is the lock owner', () => {
|
||||
spyOn(apiService.getInstance(), 'getEcmUsername').and.returnValue('lock-owner-user');
|
||||
spyOn(authenticationService, 'getEcmUsername').and.returnValue('lock-owner-user');
|
||||
expect(service.isLocked(nodeOwnerAllowedLock)).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should return true when the user is not the lock owner', () => {
|
||||
spyOn(apiService.getInstance(), 'getEcmUsername').and.returnValue('banana-user');
|
||||
spyOn(authenticationService, 'getEcmUsername').and.returnValue('banana-user');
|
||||
expect(service.isLocked(nodeOwnerAllowedLock)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should return false when the user is not the lock owner but the lock is expired', () => {
|
||||
spyOn(apiService.getInstance(), 'getEcmUsername').and.returnValue('banana-user');
|
||||
spyOn(authenticationService, 'getEcmUsername').and.returnValue('banana-user');
|
||||
expect(service.isLocked(nodeOwnerAllowedLockWithExpiredDate)).toBeFalsy();
|
||||
});
|
||||
|
||||
it('should return true when is not the lock owner and the expiration date is valid', () => {
|
||||
spyOn(apiService.getInstance(), 'getEcmUsername').and.returnValue('banana-user');
|
||||
spyOn(authenticationService, 'getEcmUsername').and.returnValue('banana-user');
|
||||
expect(service.isLocked(nodeOwnerAllowedLockWithActiveExpiration)).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<h1 mat-dialog-title>{{ title | translate }}</h1>
|
||||
<h1 mat-dialog-title data-automation-id="new-version-uploader-dialog-title">{{ title | translate }}</h1>
|
||||
<section mat-dialog-content *ngIf="!data.showVersionsOnly">
|
||||
<adf-version-comparison id="adf-version-comparison" [newFileVersion]="data.file" [node]="data.node"></adf-version-comparison>
|
||||
<adf-version-upload
|
||||
|
||||
+11
-22
@@ -28,13 +28,13 @@ import { NewVersionUploaderDialogComponent } from './new-version-uploader.dialog
|
||||
describe('NewVersionUploaderDialog', () => {
|
||||
let component: NewVersionUploaderDialogComponent;
|
||||
let fixture: ComponentFixture<NewVersionUploaderDialogComponent>;
|
||||
let nativeElement;
|
||||
let nativeElement: HTMLElement;
|
||||
|
||||
const cssSelectors = {
|
||||
adfVersionUploadButton: '#adf-version-upload-button',
|
||||
adfVersionComparison: '#adf-version-comparison',
|
||||
adfVersionList: '.adf-version-list',
|
||||
matDialogTitle: '.mat-dialog-title'
|
||||
title: '[data-automation-id="new-version-uploader-dialog-title"]'
|
||||
};
|
||||
|
||||
const mockDialogRef = {
|
||||
@@ -45,10 +45,7 @@ describe('NewVersionUploaderDialog', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
TranslateModule.forRoot(),
|
||||
ContentTestingModule
|
||||
],
|
||||
imports: [TranslateModule.forRoot(), ContentTestingModule],
|
||||
declarations: [
|
||||
NewVersionUploaderDialogComponent,
|
||||
VersionListComponent,
|
||||
@@ -59,7 +56,8 @@ describe('NewVersionUploaderDialog', () => {
|
||||
providers: [
|
||||
{ provide: MAT_DIALOG_DATA, useValue: { node: mockNode, showVersionsOnly, file: mockFile } },
|
||||
{
|
||||
provide: MatDialogRef, useValue: mockDialogRef
|
||||
provide: MatDialogRef,
|
||||
useValue: mockDialogRef
|
||||
}
|
||||
]
|
||||
});
|
||||
@@ -72,12 +70,7 @@ describe('NewVersionUploaderDialog', () => {
|
||||
fixture.destroy();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
|
||||
describe('Upload New Version', () => {
|
||||
|
||||
const expectedUploadNewVersionTitle = 'ADF-NEW-VERSION-UPLOADER.DIALOG_UPLOAD.TITLE';
|
||||
|
||||
it('should display adf version upload button if showVersionsOnly is passed as false from parent component', () => {
|
||||
@@ -104,7 +97,7 @@ describe('NewVersionUploaderDialog', () => {
|
||||
it('should show default title if title is not provided from parent component', () => {
|
||||
component.data.showVersionsOnly = false;
|
||||
fixture.detectChanges();
|
||||
const matDialogTitle = nativeElement.querySelector(cssSelectors.matDialogTitle);
|
||||
const matDialogTitle = nativeElement.querySelector(cssSelectors.title);
|
||||
expect(matDialogTitle.innerHTML).toEqual(expectedUploadNewVersionTitle);
|
||||
});
|
||||
|
||||
@@ -112,7 +105,7 @@ describe('NewVersionUploaderDialog', () => {
|
||||
component.data.showVersionsOnly = false;
|
||||
component.data.title = '';
|
||||
fixture.detectChanges();
|
||||
const matDialogTitle = nativeElement.querySelector(cssSelectors.matDialogTitle);
|
||||
const matDialogTitle = nativeElement.querySelector(cssSelectors.title);
|
||||
expect(matDialogTitle.innerHTML).toEqual(expectedUploadNewVersionTitle);
|
||||
});
|
||||
|
||||
@@ -120,7 +113,7 @@ describe('NewVersionUploaderDialog', () => {
|
||||
component.data.showVersionsOnly = false;
|
||||
component.data.title = 'TEST_TITLE';
|
||||
fixture.detectChanges();
|
||||
const matDialogTitle = nativeElement.querySelector(cssSelectors.matDialogTitle);
|
||||
const matDialogTitle = nativeElement.querySelector(cssSelectors.title);
|
||||
expect(matDialogTitle.innerHTML).toEqual('TEST_TITLE');
|
||||
});
|
||||
|
||||
@@ -150,11 +143,9 @@ describe('NewVersionUploaderDialog', () => {
|
||||
component.handleCancel();
|
||||
expect(mockDialogRef.close).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('Manage Versions', () => {
|
||||
|
||||
const expectedManageVersionsTitle = 'ADF-NEW-VERSION-UPLOADER.DIALOG_LIST.TITLE';
|
||||
|
||||
it('should display adf version list if showVersionsOnly is passed as true from parent component', () => {
|
||||
@@ -182,7 +173,7 @@ describe('NewVersionUploaderDialog', () => {
|
||||
component.data.showVersionsOnly = true;
|
||||
component.data.title = undefined;
|
||||
fixture.detectChanges();
|
||||
const matDialogTitle = nativeElement.querySelector(cssSelectors.matDialogTitle);
|
||||
const matDialogTitle = nativeElement.querySelector(cssSelectors.title);
|
||||
expect(matDialogTitle.innerHTML).toEqual(expectedManageVersionsTitle);
|
||||
});
|
||||
|
||||
@@ -190,7 +181,7 @@ describe('NewVersionUploaderDialog', () => {
|
||||
component.data.showVersionsOnly = true;
|
||||
component.data.title = '';
|
||||
fixture.detectChanges();
|
||||
const matDialogTitle = nativeElement.querySelector(cssSelectors.matDialogTitle);
|
||||
const matDialogTitle = nativeElement.querySelector(cssSelectors.title);
|
||||
expect(matDialogTitle.innerHTML).toEqual(expectedManageVersionsTitle);
|
||||
});
|
||||
|
||||
@@ -198,10 +189,8 @@ describe('NewVersionUploaderDialog', () => {
|
||||
component.data.showVersionsOnly = true;
|
||||
component.data.title = 'TEST_TITLE';
|
||||
fixture.detectChanges();
|
||||
const matDialogTitle = nativeElement.querySelector(cssSelectors.matDialogTitle);
|
||||
const matDialogTitle = nativeElement.querySelector(cssSelectors.title);
|
||||
expect(matDialogTitle.innerHTML).toEqual('TEST_TITLE');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
+46
-51
@@ -26,9 +26,12 @@ import { ContentTestingModule } from '../../../testing/content.testing.module';
|
||||
import { AddPermissionDialogComponent } from './add-permission-dialog.component';
|
||||
import { AddPermissionDialogData } from './add-permission-dialog-data.interface';
|
||||
import { fakeAuthorityResults } from '../../../mock/add-permission.component.mock';
|
||||
import { HarnessLoader } from '@angular/cdk/testing';
|
||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||
import { MatSelectHarness } from '@angular/material/select/testing';
|
||||
|
||||
describe('AddPermissionDialog', () => {
|
||||
|
||||
let loader: HarnessLoader;
|
||||
let fixture: ComponentFixture<AddPermissionDialogComponent>;
|
||||
let component: AddPermissionDialogComponent;
|
||||
let element: HTMLElement;
|
||||
@@ -53,7 +56,7 @@ describe('AddPermissionDialog', () => {
|
||||
role: 'Consumer'
|
||||
}
|
||||
],
|
||||
confirm: new Subject<PermissionElement[]> ()
|
||||
confirm: new Subject<PermissionElement[]>()
|
||||
};
|
||||
const dialogRef = {
|
||||
close: jasmine.createSpy('close')
|
||||
@@ -61,10 +64,7 @@ describe('AddPermissionDialog', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
TranslateModule.forRoot(),
|
||||
ContentTestingModule
|
||||
],
|
||||
imports: [TranslateModule.forRoot(), ContentTestingModule],
|
||||
providers: [
|
||||
{ provide: MatDialogRef, useValue: dialogRef },
|
||||
{ provide: MAT_DIALOG_DATA, useValue: data }
|
||||
@@ -74,12 +74,15 @@ describe('AddPermissionDialog', () => {
|
||||
component = fixture.componentInstance;
|
||||
element = fixture.nativeElement;
|
||||
fixture.detectChanges();
|
||||
loader = TestbedHarnessEnvironment.loader(fixture);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
fixture.destroy();
|
||||
});
|
||||
|
||||
const getConfirmButton = () => element.querySelector<HTMLButtonElement>('[data-automation-id="add-permission-dialog-confirm-button"]');
|
||||
|
||||
it('should show the INJECTED title', () => {
|
||||
const titleElement = fixture.debugElement.query(By.css('#add-permission-dialog-title'));
|
||||
expect(titleElement).not.toBeNull();
|
||||
@@ -94,27 +97,31 @@ describe('AddPermissionDialog', () => {
|
||||
});
|
||||
|
||||
it('should disable the confirm button when no selection is applied', () => {
|
||||
const confirmButton = element.querySelector<HTMLButtonElement>('[data-automation-id="add-permission-dialog-confirm-button"]');
|
||||
const confirmButton = getConfirmButton();
|
||||
expect(confirmButton.disabled).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should enable the button when a selection is done', async () => {
|
||||
const addPermissionPanelComponent: AddPermissionPanelComponent = fixture.debugElement.query(By.directive(AddPermissionPanelComponent)).componentInstance;
|
||||
const addPermissionPanelComponent: AddPermissionPanelComponent = fixture.debugElement.query(
|
||||
By.directive(AddPermissionPanelComponent)
|
||||
).componentInstance;
|
||||
addPermissionPanelComponent.select.emit(fakeAuthorityResults);
|
||||
let confirmButton = element.querySelector<HTMLButtonElement>('[data-automation-id="add-permission-dialog-confirm-button"]');
|
||||
let confirmButton = getConfirmButton();
|
||||
expect(confirmButton.disabled).toBeTruthy();
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
confirmButton = element.querySelector<HTMLButtonElement>('[data-automation-id="add-permission-dialog-confirm-button"]');
|
||||
confirmButton = getConfirmButton();
|
||||
expect(confirmButton.disabled).toBe(false);
|
||||
});
|
||||
|
||||
it('should update the role after selection', async () => {
|
||||
spyOn(component, 'onMemberUpdate').and.callThrough();
|
||||
const addPermissionPanelComponent: AddPermissionPanelComponent = fixture.debugElement.query(By.directive(AddPermissionPanelComponent)).componentInstance;
|
||||
let confirmButton = element.querySelector<HTMLButtonElement>('[data-automation-id="add-permission-dialog-confirm-button"]');
|
||||
const addPermissionPanelComponent: AddPermissionPanelComponent = fixture.debugElement.query(
|
||||
By.directive(AddPermissionPanelComponent)
|
||||
).componentInstance;
|
||||
let confirmButton = getConfirmButton();
|
||||
expect(confirmButton.disabled).toBe(true);
|
||||
addPermissionPanelComponent.select.emit([fakeAuthorityResults[0]]);
|
||||
|
||||
@@ -127,17 +134,12 @@ describe('AddPermissionDialog', () => {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const selectBox = fixture.debugElement.query(By.css(('[id="adf-select-role-permission"] .mat-select-trigger')));
|
||||
selectBox.nativeElement.dispatchEvent(new Event('click'));
|
||||
fixture.detectChanges();
|
||||
const select = await loader.getHarness(MatSelectHarness.with({ ancestor: `#adf-select-role-permission` }));
|
||||
await select.open();
|
||||
|
||||
const options = fixture.debugElement.queryAll(By.css('mat-option'));
|
||||
expect(options).not.toBeNull();
|
||||
const options = await select.getOptions();
|
||||
expect(options.length).toBe(2);
|
||||
options[0].triggerEventHandler('click', {});
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await options[0].click();
|
||||
|
||||
expect(component.onMemberUpdate).toHaveBeenCalled();
|
||||
|
||||
@@ -147,7 +149,7 @@ describe('AddPermissionDialog', () => {
|
||||
currentSelection = selection;
|
||||
});
|
||||
|
||||
confirmButton = element.querySelector<HTMLButtonElement>('[data-automation-id="add-permission-dialog-confirm-button"]');
|
||||
confirmButton = getConfirmButton();
|
||||
expect(confirmButton.disabled).toBe(false);
|
||||
confirmButton.click();
|
||||
|
||||
@@ -156,8 +158,10 @@ describe('AddPermissionDialog', () => {
|
||||
|
||||
it('should update all the user role on header column update', async () => {
|
||||
spyOn(component, 'onBulkUpdate').and.callThrough();
|
||||
const addPermissionPanelComponent: AddPermissionPanelComponent = fixture.debugElement.query(By.directive(AddPermissionPanelComponent)).componentInstance;
|
||||
let confirmButton = element.querySelector<HTMLButtonElement>('[data-automation-id="add-permission-dialog-confirm-button"]');
|
||||
const addPermissionPanelComponent: AddPermissionPanelComponent = fixture.debugElement.query(
|
||||
By.directive(AddPermissionPanelComponent)
|
||||
).componentInstance;
|
||||
let confirmButton = getConfirmButton();
|
||||
expect(confirmButton.disabled).toBe(true);
|
||||
addPermissionPanelComponent.select.emit(fakeAuthorityResults);
|
||||
|
||||
@@ -170,19 +174,12 @@ describe('AddPermissionDialog', () => {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const selectBox = fixture.debugElement.query(By.css(('[id="adf-bulk-select-role-permission"] .mat-select-trigger')));
|
||||
selectBox.nativeElement.dispatchEvent(new Event('click'));
|
||||
const select = await loader.getHarness(MatSelectHarness.with({ ancestor: `#adf-bulk-select-role-permission` }));
|
||||
await select.open();
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const options = fixture.debugElement.queryAll(By.css('mat-option'));
|
||||
expect(options).not.toBeNull();
|
||||
const options = await select.getOptions();
|
||||
expect(options.length).toBe(2);
|
||||
options[0].triggerEventHandler('click', {});
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await options[0].click();
|
||||
|
||||
expect(component.onBulkUpdate).toHaveBeenCalled();
|
||||
|
||||
@@ -190,7 +187,7 @@ describe('AddPermissionDialog', () => {
|
||||
expect(selection.length).toBe(3);
|
||||
});
|
||||
|
||||
confirmButton = element.querySelector<HTMLButtonElement>('[data-automation-id="add-permission-dialog-confirm-button"]');
|
||||
confirmButton = getConfirmButton();
|
||||
expect(confirmButton.disabled).toBe(false);
|
||||
confirmButton.click();
|
||||
});
|
||||
@@ -198,8 +195,10 @@ describe('AddPermissionDialog', () => {
|
||||
it('should delete the user after selection', async () => {
|
||||
spyOn(component, 'onMemberUpdate').and.callThrough();
|
||||
spyOn(component, 'onMemberDelete').and.callThrough();
|
||||
const addPermissionPanelComponent: AddPermissionPanelComponent = fixture.debugElement.query(By.directive(AddPermissionPanelComponent)).componentInstance;
|
||||
let confirmButton = element.querySelector<HTMLButtonElement>('[data-automation-id="add-permission-dialog-confirm-button"]');
|
||||
const addPermissionPanelComponent: AddPermissionPanelComponent = fixture.debugElement.query(
|
||||
By.directive(AddPermissionPanelComponent)
|
||||
).componentInstance;
|
||||
let confirmButton = getConfirmButton();
|
||||
expect(confirmButton.disabled).toBe(true);
|
||||
addPermissionPanelComponent.select.emit(fakeAuthorityResults);
|
||||
|
||||
@@ -212,22 +211,16 @@ describe('AddPermissionDialog', () => {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const selectBox = fixture.debugElement.query(By.css(('[id="adf-select-role-permission"] .mat-select-trigger')));
|
||||
selectBox.nativeElement.dispatchEvent(new Event('click'));
|
||||
const select = await loader.getHarness(MatSelectHarness.with({ ancestor: `#adf-select-role-permission` }));
|
||||
await select.open();
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
const options = fixture.debugElement.queryAll(By.css('mat-option'));
|
||||
expect(options).not.toBeNull();
|
||||
const options = await select.getOptions();
|
||||
expect(options.length).toBe(2);
|
||||
options[0].triggerEventHandler('click', {});
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
await options[0].click();
|
||||
|
||||
expect(component.onMemberUpdate).toHaveBeenCalled();
|
||||
|
||||
confirmButton = element.querySelector<HTMLButtonElement>('[data-automation-id="add-permission-dialog-confirm-button"]');
|
||||
confirmButton = getConfirmButton();
|
||||
expect(confirmButton.disabled).toBe(true);
|
||||
const deleteButton = element.querySelectorAll('[data-automation-id="adf-delete-permission-button"]') as any;
|
||||
deleteButton[1].click();
|
||||
@@ -246,7 +239,9 @@ describe('AddPermissionDialog', () => {
|
||||
});
|
||||
|
||||
it('should stream the confirmed selection on the confirm subject', async () => {
|
||||
const addPermissionPanelComponent: AddPermissionPanelComponent = fixture.debugElement.query(By.directive(AddPermissionPanelComponent)).componentInstance;
|
||||
const addPermissionPanelComponent: AddPermissionPanelComponent = fixture.debugElement.query(
|
||||
By.directive(AddPermissionPanelComponent)
|
||||
).componentInstance;
|
||||
addPermissionPanelComponent.select.emit(fakeAuthorityResults);
|
||||
|
||||
fixture.detectChanges();
|
||||
@@ -255,7 +250,7 @@ describe('AddPermissionDialog', () => {
|
||||
let authorityResult = fixture.debugElement.query(By.css('[data-automation-id="datatable-row-0"]'));
|
||||
expect(authorityResult).toBeNull();
|
||||
|
||||
const confirmButton = element.querySelector<HTMLButtonElement>('[data-automation-id="add-permission-dialog-confirm-button"]');
|
||||
const confirmButton = getConfirmButton();
|
||||
confirmButton.click();
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ export class SearchPermissionConfigurationService implements SearchConfiguration
|
||||
if (this.queryProvider?.query) {
|
||||
query = this.queryProvider.query.replace(new RegExp(/\${([^}]+)}/g), searchTerm);
|
||||
} else {
|
||||
query = `(email:*${searchTerm}* OR firstName:*${searchTerm}* OR lastName:*${searchTerm}* OR displayName:*${searchTerm}* OR authorityName:*${searchTerm}* OR authorityDisplayName:*${searchTerm}*) AND ANAME:("0/APP.DEFAULT")`;
|
||||
query = `(userName:*${searchTerm}* OR email:*${searchTerm}* OR firstName:*${searchTerm}* OR lastName:*${searchTerm}* OR authorityName:*${searchTerm}* OR authorityDisplayName:*${searchTerm}*) AND PATH:"//cm:APP.DEFAULT/*"`;
|
||||
}
|
||||
return query;
|
||||
}
|
||||
|
||||
+17
-18
@@ -16,23 +16,23 @@
|
||||
*/
|
||||
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { PermissionContainerComponent } from './permission-container.component';
|
||||
import { ContentTestingModule } from '../../../testing/content.testing.module';
|
||||
import { HarnessLoader } from '@angular/cdk/testing';
|
||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||
import { MatSelectHarness } from '@angular/material/select/testing';
|
||||
import { MatButtonHarness } from '@angular/material/button/testing';
|
||||
|
||||
describe('PermissionContainerComponent', () => {
|
||||
|
||||
let loader: HarnessLoader;
|
||||
let fixture: ComponentFixture<PermissionContainerComponent>;
|
||||
let component: PermissionContainerComponent;
|
||||
let element: HTMLElement;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
TranslateModule.forRoot(),
|
||||
ContentTestingModule
|
||||
]
|
||||
imports: [TranslateModule.forRoot(), ContentTestingModule]
|
||||
});
|
||||
fixture = TestBed.createComponent(PermissionContainerComponent);
|
||||
component = fixture.componentInstance;
|
||||
@@ -60,6 +60,7 @@ describe('PermissionContainerComponent', () => {
|
||||
];
|
||||
|
||||
fixture.detectChanges();
|
||||
loader = TestbedHarnessEnvironment.loader(fixture);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -72,26 +73,24 @@ describe('PermissionContainerComponent', () => {
|
||||
expect(element.querySelector('#adf-select-role-permission').textContent).toContain('consumer');
|
||||
});
|
||||
|
||||
it('should emit update event on role change', () => {
|
||||
it('should emit update event on role change', async () => {
|
||||
spyOn(component.update, 'emit');
|
||||
|
||||
const selectBox = fixture.debugElement.query(By.css(('[id="adf-select-role-permission"] .mat-select-trigger')));
|
||||
selectBox.triggerEventHandler('click', null);
|
||||
fixture.detectChanges();
|
||||
const select = await loader.getHarness(MatSelectHarness.with({ ancestor: `#adf-select-role-permission` }));
|
||||
await select.open();
|
||||
|
||||
const options = fixture.debugElement.queryAll(By.css('mat-option'));
|
||||
expect(options).not.toBeNull();
|
||||
const options = await select.getOptions();
|
||||
expect(options.length).toBe(2);
|
||||
options[0].triggerEventHandler('click', {});
|
||||
fixture.detectChanges();
|
||||
await options[0].click();
|
||||
expect(component.update.emit).toHaveBeenCalledWith({ role: 'Test', permission: component.permissions[0] });
|
||||
});
|
||||
|
||||
it('should delete update event on row delete', () => {
|
||||
it('should delete update event on row delete', async () => {
|
||||
spyOn(component.delete, 'emit');
|
||||
const deleteButton: HTMLButtonElement = element.querySelector('[data-automation-id="adf-delete-permission-button-GROUP_EVERYONE"]');
|
||||
deleteButton.click();
|
||||
fixture.detectChanges();
|
||||
const deleteButton = await loader.getHarness(
|
||||
MatButtonHarness.with({ selector: `[data-automation-id="adf-delete-permission-button-GROUP_EVERYONE"]` })
|
||||
);
|
||||
await deleteButton.click();
|
||||
expect(component.delete.emit).toHaveBeenCalledWith(component.permissions[0]);
|
||||
});
|
||||
});
|
||||
|
||||
+30
-32
@@ -16,7 +16,6 @@
|
||||
*/
|
||||
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { of, throwError } from 'rxjs';
|
||||
import { SearchService } from '../../../search/services/search.service';
|
||||
@@ -36,8 +35,13 @@ import {
|
||||
import { ContentTestingModule } from '../../../testing/content.testing.module';
|
||||
import { Node } from '@alfresco/js-api';
|
||||
import { NodesApiService } from '../../../common/services/nodes-api.service';
|
||||
import { HarnessLoader } from '@angular/cdk/testing';
|
||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||
import { MatSlideToggleHarness } from '@angular/material/slide-toggle/testing';
|
||||
import { MatSelectHarness } from '@angular/material/select/testing';
|
||||
|
||||
describe('PermissionListComponent', () => {
|
||||
let loader: HarnessLoader;
|
||||
let fixture: ComponentFixture<PermissionListComponent>;
|
||||
let component: PermissionListComponent;
|
||||
let element: HTMLElement;
|
||||
@@ -64,6 +68,7 @@ describe('PermissionListComponent', () => {
|
||||
searchQuerySpy = spyOn(searchApiService, 'searchByQueryBody').and.returnValue(of(fakeEmptyResponse));
|
||||
component.nodeId = 'fake-node-id';
|
||||
fixture.detectChanges();
|
||||
loader = TestbedHarnessEnvironment.loader(fixture);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
@@ -117,7 +122,9 @@ describe('PermissionListComponent', () => {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(element.querySelector('.adf-inherit-container .mat-checked')).toBeDefined();
|
||||
const toggle = await loader.getHarness(MatSlideToggleHarness);
|
||||
expect(await toggle.isChecked()).toBe(true);
|
||||
|
||||
expect(element.querySelector('.adf-inherit-container h3').textContent.trim()).toBe(
|
||||
'PERMISSION_MANAGER.LABELS.INHERITED-PERMISSIONS PERMISSION_MANAGER.LABELS.ON'
|
||||
);
|
||||
@@ -127,10 +134,11 @@ describe('PermissionListComponent', () => {
|
||||
it('should toggle the inherited button', async () => {
|
||||
getNodeSpy.and.returnValue(of(fakeNodeInheritedOnly));
|
||||
component.ngOnInit();
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(element.querySelector('.adf-inherit-container .mat-checked')).toBeDefined();
|
||||
const toggle = await loader.getHarness(MatSlideToggleHarness);
|
||||
expect(await toggle.isChecked()).toBe(true);
|
||||
|
||||
expect(element.querySelector('.adf-inherit-container h3').textContent.trim()).toBe(
|
||||
'PERMISSION_MANAGER.LABELS.INHERITED-PERMISSIONS PERMISSION_MANAGER.LABELS.ON'
|
||||
);
|
||||
@@ -138,12 +146,8 @@ describe('PermissionListComponent', () => {
|
||||
|
||||
spyOn(nodeService, 'updateNode').and.returnValue(of(fakeLocalPermission));
|
||||
|
||||
const slider = fixture.debugElement.query(By.css('mat-slide-toggle'));
|
||||
slider.triggerEventHandler('change', { source: { checked: false } });
|
||||
await toggle.uncheck();
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(element.querySelector('.adf-inherit-container .mat-checked')).toBe(null);
|
||||
expect(element.querySelector('.adf-inherit-container h3').textContent.trim()).toBe(
|
||||
'PERMISSION_MANAGER.LABELS.INHERITED-PERMISSIONS PERMISSION_MANAGER.LABELS.OFF'
|
||||
);
|
||||
@@ -157,7 +161,9 @@ describe('PermissionListComponent', () => {
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(element.querySelector('.adf-inherit-container .mat-checked')).toBeDefined();
|
||||
const toggle = await loader.getHarness(MatSlideToggleHarness);
|
||||
expect(await toggle.isChecked()).toBe(true);
|
||||
|
||||
expect(element.querySelector('.adf-inherit-container h3').textContent.trim()).toBe(
|
||||
'PERMISSION_MANAGER.LABELS.INHERITED-PERMISSIONS PERMISSION_MANAGER.LABELS.ON'
|
||||
);
|
||||
@@ -165,13 +171,8 @@ describe('PermissionListComponent', () => {
|
||||
|
||||
spyOn(nodeService, 'updateNode').and.returnValue(of(fakeLocalPermission));
|
||||
|
||||
const slider = fixture.debugElement.query(By.css('mat-slide-toggle'));
|
||||
slider.triggerEventHandler('change', { source: { checked: false } });
|
||||
await toggle.uncheck();
|
||||
|
||||
fixture.detectChanges();
|
||||
await fixture.whenStable();
|
||||
|
||||
expect(element.querySelector('.adf-inherit-container .mat-checked')).toBeDefined();
|
||||
expect(element.querySelector('.adf-inherit-container h3').textContent.trim()).toBe(
|
||||
'PERMISSION_MANAGER.LABELS.INHERITED-PERMISSIONS PERMISSION_MANAGER.LABELS.ON'
|
||||
);
|
||||
@@ -206,17 +207,16 @@ describe('PermissionListComponent', () => {
|
||||
expect(element.querySelector('adf-user-name-column').textContent).toContain('GROUP_EVERYONE');
|
||||
expect(element.querySelector('#adf-select-role-permission').textContent).toContain('Contributor');
|
||||
|
||||
const selectBox = fixture.debugElement.query(By.css('[id="adf-select-role-permission"] .mat-select-trigger'));
|
||||
selectBox.triggerEventHandler('click', null);
|
||||
fixture.detectChanges();
|
||||
const select = await loader.getHarness(MatSelectHarness.with({ ancestor: `#adf-select-role-permission` }));
|
||||
await select.open();
|
||||
|
||||
const options = fixture.debugElement.queryAll(By.css('mat-option'));
|
||||
expect(options).not.toBeNull();
|
||||
const options = await select.getOptions();
|
||||
expect(options.length).toBe(4);
|
||||
expect(options[0].nativeElement.innerText).toContain('ADF.ROLES.SITECOLLABORATOR');
|
||||
expect(options[1].nativeElement.innerText).toContain('ADF.ROLES.SITECONSUMER');
|
||||
expect(options[2].nativeElement.innerText).toContain('ADF.ROLES.SITECONTRIBUTOR');
|
||||
expect(options[3].nativeElement.innerText).toContain('ADF.ROLES.SITEMANAGER');
|
||||
|
||||
expect(await options[0].getText()).toContain('ADF.ROLES.SITECOLLABORATOR');
|
||||
expect(await options[1].getText()).toContain('ADF.ROLES.SITECONSUMER');
|
||||
expect(await options[2].getText()).toContain('ADF.ROLES.SITECONTRIBUTOR');
|
||||
expect(await options[3].getText()).toContain('ADF.ROLES.SITEMANAGER');
|
||||
});
|
||||
|
||||
it('should show readonly member for site manager to toggle the inherit permission', async () => {
|
||||
@@ -247,14 +247,12 @@ describe('PermissionListComponent', () => {
|
||||
expect(element.querySelector('adf-user-name-column').textContent).toContain('GROUP_EVERYONE');
|
||||
expect(element.querySelector('#adf-select-role-permission').textContent).toContain('Contributor');
|
||||
|
||||
const selectBox = fixture.debugElement.query(By.css('[id="adf-select-role-permission"] .mat-select-trigger'));
|
||||
selectBox.triggerEventHandler('click', null);
|
||||
fixture.detectChanges();
|
||||
const options = fixture.debugElement.queryAll(By.css('mat-option'));
|
||||
expect(options).not.toBeNull();
|
||||
const select = await loader.getHarness(MatSelectHarness.with({ ancestor: `#adf-select-role-permission` }));
|
||||
await select.open();
|
||||
|
||||
const options = await select.getOptions();
|
||||
expect(options.length).toBe(5);
|
||||
options[3].triggerEventHandler('click', {});
|
||||
fixture.detectChanges();
|
||||
await options[3].click();
|
||||
expect(nodeService.updateNode).toHaveBeenCalledWith('f472543f-7218-403d-917b-7a5861257244', {
|
||||
permissions: { locallySet: [{ accessStatus: 'ALLOWED', name: 'Editor', authorityId: 'GROUP_EVERYONE' }] }
|
||||
});
|
||||
|
||||
+17
-17
@@ -22,35 +22,33 @@ import { UserIconColumnComponent } from './user-icon-column.component';
|
||||
import { NodeEntry } from '@alfresco/js-api';
|
||||
|
||||
describe('UserIconColumnComponent', () => {
|
||||
|
||||
let fixture: ComponentFixture<UserIconColumnComponent>;
|
||||
let component: UserIconColumnComponent;
|
||||
let element: HTMLElement;
|
||||
const person = {
|
||||
const person = {
|
||||
firstName: 'fake',
|
||||
lastName: 'user',
|
||||
email: 'fake@test.com'
|
||||
};
|
||||
|
||||
const group = {
|
||||
const group = {
|
||||
id: 'fake-id',
|
||||
displayName: 'fake authority'
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
TranslateModule.forRoot(),
|
||||
ContentTestingModule
|
||||
]
|
||||
imports: [TranslateModule.forRoot(), ContentTestingModule]
|
||||
});
|
||||
fixture = TestBed.createComponent(UserIconColumnComponent);
|
||||
fixture = TestBed.createComponent(UserIconColumnComponent);
|
||||
component = fixture.componentInstance;
|
||||
element = fixture.nativeElement;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
describe('person initial', () => {
|
||||
const getInitials = () => element.querySelector('[data-automation-id="user-initials-image"]')?.textContent;
|
||||
|
||||
it('should render person value from context', () => {
|
||||
component.context = {
|
||||
row: {
|
||||
@@ -61,7 +59,7 @@ describe('UserIconColumnComponent', () => {
|
||||
};
|
||||
component.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
expect(element.querySelector('[data-automation-id="user-initials-image"]').textContent).toContain('fu');
|
||||
expect(getInitials()).toContain('fu');
|
||||
});
|
||||
|
||||
it('should render person value from node', () => {
|
||||
@@ -69,8 +67,8 @@ describe('UserIconColumnComponent', () => {
|
||||
entry: {
|
||||
nodeType: 'cm:person',
|
||||
properties: {
|
||||
'cm:firstName': 'Fake',
|
||||
'cm:lastName': 'User',
|
||||
'cm:firstName': 'Fake',
|
||||
'cm:lastName': 'User',
|
||||
'cm:email': 'fake-user@test.com',
|
||||
'cm:userName': 'fake-user'
|
||||
}
|
||||
@@ -78,11 +76,13 @@ describe('UserIconColumnComponent', () => {
|
||||
} as NodeEntry;
|
||||
component.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
expect(element.querySelector('[data-automation-id="user-initials-image"]').textContent).toContain('FU');
|
||||
expect(getInitials()).toContain('FU');
|
||||
});
|
||||
});
|
||||
|
||||
describe('group initial', () => {
|
||||
const getGroupIcon = () => element.querySelector('[id="group-icon"] .adf-group-icon');
|
||||
|
||||
it('should render group value from context', () => {
|
||||
component.context = {
|
||||
row: {
|
||||
@@ -93,8 +93,8 @@ describe('UserIconColumnComponent', () => {
|
||||
};
|
||||
component.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
expect(element.querySelector('[id="group-icon"] mat-icon')).toBeDefined();
|
||||
expect(element.querySelector('[id="group-icon"] mat-icon').textContent).toContain('people_alt_outline');
|
||||
expect(getGroupIcon()).toBeDefined();
|
||||
expect(getGroupIcon().textContent).toContain('people_alt_outline');
|
||||
});
|
||||
|
||||
it('should render person value from node', () => {
|
||||
@@ -102,14 +102,14 @@ describe('UserIconColumnComponent', () => {
|
||||
entry: {
|
||||
nodeType: 'cm:authorityContainer',
|
||||
properties: {
|
||||
'cm:authorityName': 'Fake authorityN'
|
||||
'cm:authorityName': 'Fake authorityN'
|
||||
}
|
||||
}
|
||||
} as NodeEntry;
|
||||
component.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
expect(element.querySelector('[id="group-icon"] mat-icon')).toBeDefined();
|
||||
expect(element.querySelector('[id="group-icon"] mat-icon').textContent).toContain('people_alt_outline');
|
||||
expect(getGroupIcon()).toBeDefined();
|
||||
expect(getGroupIcon().textContent).toContain('people_alt_outline');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
+33
-38
@@ -20,22 +20,24 @@ import { SearchFilterList } from '../../models/search-filter-list.model';
|
||||
import { ContentTestingModule } from '../../../testing/content.testing.module';
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
import { sizeOptions, stepOne, stepThree } from '../../../mock';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { HarnessLoader, TestKey } from '@angular/cdk/testing';
|
||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||
import { MatCheckboxHarness } from '@angular/material/checkbox/testing';
|
||||
import { MatButtonHarness } from '@angular/material/button/testing';
|
||||
|
||||
describe('SearchCheckListComponent', () => {
|
||||
let loader: HarnessLoader;
|
||||
let fixture: ComponentFixture<SearchCheckListComponent>;
|
||||
let component: SearchCheckListComponent;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
TranslateModule.forRoot(),
|
||||
ContentTestingModule
|
||||
]
|
||||
imports: [TranslateModule.forRoot(), ContentTestingModule]
|
||||
});
|
||||
fixture = TestBed.createComponent(SearchCheckListComponent);
|
||||
component = fixture.componentInstance;
|
||||
loader = TestbedHarnessEnvironment.loader(fixture);
|
||||
});
|
||||
|
||||
it('should setup options from settings', () => {
|
||||
@@ -49,7 +51,7 @@ describe('SearchCheckListComponent', () => {
|
||||
expect(component.options.items).toEqual(options);
|
||||
});
|
||||
|
||||
it('should handle enter key as click on checkboxes', () => {
|
||||
it('should handle enter key as click on checkboxes', async () => {
|
||||
component.options = new SearchFilterList<SearchListOption>([
|
||||
{ name: 'Folder', value: `TYPE:'cm:folder'`, checked: false },
|
||||
{ name: 'Document', value: `TYPE:'cm:content'`, checked: false }
|
||||
@@ -58,13 +60,13 @@ describe('SearchCheckListComponent', () => {
|
||||
component.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
|
||||
const optionElements = fixture.debugElement.queryAll(By.css('mat-checkbox'));
|
||||
const option = await loader.getHarness(MatCheckboxHarness);
|
||||
|
||||
optionElements[0].triggerEventHandler('keydown.enter', {});
|
||||
expect(component.options.items[0].checked).toBeTruthy();
|
||||
await (await option.host()).sendKeys(TestKey.ENTER);
|
||||
expect(await option.isChecked()).toBe(true);
|
||||
|
||||
optionElements[0].triggerEventHandler('keydown.enter', {});
|
||||
expect(component.options.items[0].checked).toBeFalsy();
|
||||
await (await option.host()).sendKeys(TestKey.ENTER);
|
||||
expect(await option.isChecked()).toBe(false);
|
||||
});
|
||||
|
||||
it('should setup operator from the settings', () => {
|
||||
@@ -95,21 +97,13 @@ describe('SearchCheckListComponent', () => {
|
||||
|
||||
spyOn(component.context, 'update').and.stub();
|
||||
|
||||
component.changeHandler(
|
||||
{ checked: true } as any,
|
||||
component.options.items[0]
|
||||
);
|
||||
component.changeHandler({ checked: true } as any, component.options.items[0]);
|
||||
|
||||
expect(component.context.queryFragments[component.id]).toEqual(`TYPE:'cm:folder'`);
|
||||
|
||||
component.changeHandler(
|
||||
{ checked: true } as any,
|
||||
component.options.items[1]
|
||||
);
|
||||
component.changeHandler({ checked: true } as any, component.options.items[1]);
|
||||
|
||||
expect(component.context.queryFragments[component.id]).toEqual(
|
||||
`TYPE:'cm:folder' OR TYPE:'cm:content'`
|
||||
);
|
||||
expect(component.context.queryFragments[component.id]).toEqual(`TYPE:'cm:folder' OR TYPE:'cm:content'`);
|
||||
});
|
||||
|
||||
it('should reset selected boxes', () => {
|
||||
@@ -147,7 +141,7 @@ describe('SearchCheckListComponent', () => {
|
||||
});
|
||||
|
||||
describe('Pagination', () => {
|
||||
it('should show 5 items when pageSize not defined', () => {
|
||||
it('should show 5 items when pageSize not defined', async () => {
|
||||
component.id = 'checklist';
|
||||
component.context = {
|
||||
queryFragments: {
|
||||
@@ -160,13 +154,14 @@ describe('SearchCheckListComponent', () => {
|
||||
component.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
|
||||
const optionElements = fixture.debugElement.queryAll(By.css('mat-checkbox'));
|
||||
expect(optionElements.length).toEqual(5);
|
||||
const labels = Array.from(optionElements).map(element => element.nativeElement.innerText);
|
||||
const options = await loader.getAllHarnesses(MatCheckboxHarness);
|
||||
expect(options.length).toBe(5);
|
||||
|
||||
const labels = await Promise.all(options.map((element) => element.getLabelText()));
|
||||
expect(labels).toEqual(stepOne);
|
||||
});
|
||||
|
||||
it('should show all items when pageSize is high', () => {
|
||||
it('should show all items when pageSize is high', async () => {
|
||||
component.id = 'checklist';
|
||||
component.context = {
|
||||
queryFragments: {
|
||||
@@ -178,14 +173,15 @@ describe('SearchCheckListComponent', () => {
|
||||
component.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
|
||||
const optionElements = fixture.debugElement.queryAll(By.css('mat-checkbox'));
|
||||
expect(optionElements.length).toEqual(13);
|
||||
const labels = Array.from(optionElements).map(element => element.nativeElement.innerText);
|
||||
const options = await loader.getAllHarnesses(MatCheckboxHarness);
|
||||
expect(options.length).toBe(13);
|
||||
|
||||
const labels = await Promise.all(options.map((element) => element.getLabelText()));
|
||||
expect(labels).toEqual(stepThree);
|
||||
});
|
||||
});
|
||||
|
||||
it('should able to check/reset the checkbox', () => {
|
||||
it('should able to check/reset the checkbox', async () => {
|
||||
component.id = 'checklist';
|
||||
component.context = {
|
||||
queryFragments: {
|
||||
@@ -198,16 +194,15 @@ describe('SearchCheckListComponent', () => {
|
||||
component.ngOnInit();
|
||||
fixture.detectChanges();
|
||||
|
||||
const optionElements = fixture.debugElement.query(By.css('mat-checkbox'));
|
||||
optionElements.triggerEventHandler('change', { checked: true });
|
||||
const option = await loader.getHarness(MatCheckboxHarness);
|
||||
await option.check();
|
||||
|
||||
expect(component.submitValues).toHaveBeenCalled();
|
||||
|
||||
const clearAllElement = fixture.debugElement.query(By.css('button[title="SEARCH.FILTER.ACTIONS.CLEAR-ALL"]'));
|
||||
clearAllElement.triggerEventHandler('click', {} );
|
||||
fixture.detectChanges();
|
||||
const clearButton = await loader.getHarness(MatButtonHarness.with({ selector: `[title="SEARCH.FILTER.ACTIONS.CLEAR-ALL"]` }));
|
||||
await clearButton.click();
|
||||
|
||||
const selectedElements = fixture.debugElement.queryAll(By.css('.mat-checkbox-checked'));
|
||||
expect(selectedElements.length).toBe(0);
|
||||
const checkedElements = await loader.getAllHarnesses(MatCheckboxHarness.with({ checked: true }));
|
||||
expect(checkedElements.length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
+35
-38
@@ -21,15 +21,13 @@ import { By } from '@angular/platform-browser';
|
||||
import { SearchFacetFiltersService } from '../../services/search-facet-filters.service';
|
||||
import { ContentTestingModule } from '../../../testing/content.testing.module';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { HarnessLoader } from '@angular/cdk/testing';
|
||||
import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed';
|
||||
import { MatChipHarness, MatChipRemoveHarness } from '@angular/material/chips/testing';
|
||||
|
||||
@Component({
|
||||
selector: 'adf-test-component',
|
||||
template: `
|
||||
<adf-search-chip-list
|
||||
[searchFilter]="searchFilter"
|
||||
[clearAll]="allowClear">
|
||||
</adf-search-chip-list>
|
||||
`
|
||||
template: ` <adf-search-chip-list [searchFilter]="searchFilter" [clearAll]="allowClear"> </adf-search-chip-list> `
|
||||
})
|
||||
class TestComponent {
|
||||
allowClear = true;
|
||||
@@ -40,23 +38,22 @@ class TestComponent {
|
||||
}
|
||||
|
||||
describe('SearchChipListComponent', () => {
|
||||
let loader: HarnessLoader;
|
||||
let fixture: ComponentFixture<TestComponent>;
|
||||
let component: TestComponent;
|
||||
let searchFacetFiltersService: SearchFacetFiltersService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
TranslateModule.forRoot(),
|
||||
ContentTestingModule
|
||||
],
|
||||
declarations: [
|
||||
TestComponent
|
||||
]
|
||||
imports: [TranslateModule.forRoot(), ContentTestingModule],
|
||||
declarations: [TestComponent]
|
||||
});
|
||||
fixture = TestBed.createComponent(TestComponent);
|
||||
component = fixture.componentInstance;
|
||||
searchFacetFiltersService = TestBed.inject(SearchFacetFiltersService);
|
||||
|
||||
fixture.detectChanges();
|
||||
loader = TestbedHarnessEnvironment.loader(fixture);
|
||||
});
|
||||
|
||||
it('should display clear button only when entries present', () => {
|
||||
@@ -65,24 +62,26 @@ describe('SearchChipListComponent', () => {
|
||||
let clearButton = fixture.debugElement.query(By.css(`[data-automation-id="reset-filter"]`));
|
||||
expect(clearButton).toBeNull();
|
||||
|
||||
searchFacetFiltersService.selectedBuckets = [{
|
||||
bucket: {
|
||||
count: 1,
|
||||
label: 'test',
|
||||
filterQuery: 'query'
|
||||
},
|
||||
field: null
|
||||
}];
|
||||
searchFacetFiltersService.selectedBuckets = [
|
||||
{
|
||||
bucket: {
|
||||
count: 1,
|
||||
label: 'test',
|
||||
filterQuery: 'query'
|
||||
},
|
||||
field: null
|
||||
}
|
||||
];
|
||||
fixture.detectChanges();
|
||||
clearButton = fixture.debugElement.query(By.css(`[data-automation-id="reset-filter"]`));
|
||||
expect(clearButton).toBeDefined();
|
||||
});
|
||||
|
||||
it('should reflect changes in the search filter', () => {
|
||||
it('should reflect changes in the search filter', async () => {
|
||||
const selectedBuckets = searchFacetFiltersService.selectedBuckets;
|
||||
fixture.detectChanges();
|
||||
|
||||
let chips = fixture.debugElement.queryAll(By.css(`[data-automation-id="chip-list-entry"]`));
|
||||
let chips = await loader.getAllHarnesses(MatChipHarness.with({ selector: '[data-automation-id="chip-list-entry"]' }));
|
||||
expect(chips.length).toBe(0);
|
||||
|
||||
selectedBuckets.push({
|
||||
@@ -95,7 +94,7 @@ describe('SearchChipListComponent', () => {
|
||||
});
|
||||
|
||||
fixture.detectChanges();
|
||||
chips = fixture.debugElement.queryAll(By.css(`[data-automation-id="chip-list-entry"]`));
|
||||
chips = await loader.getAllHarnesses(MatChipHarness.with({ selector: '[data-automation-id="chip-list-entry"]' }));
|
||||
expect(chips.length).toBe(1);
|
||||
});
|
||||
|
||||
@@ -115,32 +114,30 @@ describe('SearchChipListComponent', () => {
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
const chips = fixture.debugElement.queryAll(By.css(`[data-automation-id="chip-list-entry"] .mat-chip-remove`));
|
||||
chips[0].nativeElement.click();
|
||||
const removeButton = await loader.getHarness(MatChipRemoveHarness.with({ ancestor: `[data-automation-id="chip-list-entry"]` }));
|
||||
await removeButton.click();
|
||||
|
||||
await fixture.whenStable();
|
||||
expect(searchFacetFiltersService.unselectFacetBucket).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should remove items from the search filter on clear button click', () => {
|
||||
it('should remove items from the search filter on clear button click', async () => {
|
||||
spyOn(searchFacetFiltersService, 'unselectFacetBucket').and.stub();
|
||||
|
||||
const selectedBucket1: any = { field: { id: 1 }, bucket: {label: 'bucket1'} };
|
||||
const selectedBucket2: any = { field: { id: 2 }, bucket: {label: 'bucket2'} };
|
||||
const selectedBucket1: any = { field: { id: 1 }, bucket: { label: 'bucket1' } };
|
||||
const selectedBucket2: any = { field: { id: 2 }, bucket: { label: 'bucket2' } };
|
||||
searchFacetFiltersService.selectedBuckets = [selectedBucket1, selectedBucket2];
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
const closeButtons = fixture.debugElement.nativeElement.querySelectorAll('.mat-chip-remove');
|
||||
const closeButtons = await loader.getAllHarnesses(MatChipRemoveHarness);
|
||||
expect(closeButtons.length).toBe(2);
|
||||
|
||||
closeButtons[0].click();
|
||||
fixture.detectChanges();
|
||||
await closeButtons[0].click();
|
||||
|
||||
expect(searchFacetFiltersService.unselectFacetBucket).toHaveBeenCalledWith(selectedBucket1.field, selectedBucket1.bucket);
|
||||
});
|
||||
|
||||
it('should disable clear mode via input properties', () => {
|
||||
it('should disable clear mode via input properties', async () => {
|
||||
spyOn(component.searchFilter, 'unselectFacetBucket').and.callThrough();
|
||||
|
||||
component.allowClear = false;
|
||||
@@ -157,10 +154,10 @@ describe('SearchChipListComponent', () => {
|
||||
|
||||
fixture.detectChanges();
|
||||
|
||||
const chips = fixture.debugElement.queryAll(By.css(`[data-automation-id="chip-list-entry"] .mat-chip-remove`));
|
||||
expect(chips.length).toBe(1);
|
||||
const closeButtons = await loader.getAllHarnesses(MatChipRemoveHarness.with({ ancestor: `[data-automation-id="chip-list-entry"]` }));
|
||||
expect(closeButtons.length).toBe(1);
|
||||
|
||||
const clearButton = fixture.debugElement.query(By.css(`[data-automation-id="reset-filter"]`));
|
||||
expect(clearButton).toBeNull();
|
||||
const hasClearButton = await loader.hasHarness(MatChipRemoveHarness.with({ selector: `[data-automation-id="reset-filter"]` }));
|
||||
expect(hasClearButton).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
+19
-17
@@ -32,10 +32,7 @@ describe('SearchDateRangeComponent', () => {
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
TranslateModule.forRoot(),
|
||||
ContentTestingModule
|
||||
]
|
||||
imports: [TranslateModule.forRoot(), ContentTestingModule]
|
||||
});
|
||||
fixture = TestBed.createComponent(SearchDateRangeComponent);
|
||||
component = fixture.componentInstance;
|
||||
@@ -43,6 +40,9 @@ describe('SearchDateRangeComponent', () => {
|
||||
|
||||
afterEach(() => fixture.destroy());
|
||||
|
||||
const getFromInput = () => fixture.debugElement.nativeElement.querySelector('[data-automation-id="date-range-from-input"]');
|
||||
const getToInput = () => fixture.debugElement.nativeElement.querySelector('[data-automation-id="date-range-to-input"]');
|
||||
|
||||
it('should setup form elements on init', () => {
|
||||
fixture.detectChanges();
|
||||
|
||||
@@ -74,7 +74,6 @@ describe('SearchDateRangeComponent', () => {
|
||||
});
|
||||
|
||||
it('should reset form', () => {
|
||||
|
||||
fixture.detectChanges();
|
||||
component.form.setValue({ from: fromDate, to: toDate });
|
||||
|
||||
@@ -129,10 +128,13 @@ describe('SearchDateRangeComponent', () => {
|
||||
spyOn(context, 'update').and.stub();
|
||||
|
||||
fixture.detectChanges();
|
||||
component.apply({
|
||||
from: fromDate,
|
||||
to: toDate
|
||||
}, true);
|
||||
component.apply(
|
||||
{
|
||||
from: fromDate,
|
||||
to: toDate
|
||||
},
|
||||
true
|
||||
);
|
||||
|
||||
const startDate = startOfDay(fromDate).toISOString();
|
||||
const endDate = endOfDay(toDate).toISOString();
|
||||
@@ -146,7 +148,7 @@ describe('SearchDateRangeComponent', () => {
|
||||
it('should show date-format error when Invalid found', async () => {
|
||||
fixture.detectChanges();
|
||||
|
||||
const input = fixture.debugElement.nativeElement.querySelector('[data-automation-id="date-range-from-input"]');
|
||||
const input = getFromInput();
|
||||
input.value = '10-f-18';
|
||||
input.dispatchEvent(new Event('input'));
|
||||
|
||||
@@ -159,7 +161,7 @@ describe('SearchDateRangeComponent', () => {
|
||||
it('should hide date-format error when correcting input', async () => {
|
||||
fixture.detectChanges();
|
||||
|
||||
const input = fixture.debugElement.nativeElement.querySelector('[data-automation-id="date-range-from-input"]');
|
||||
const input = getFromInput();
|
||||
input.value = '10-f-18';
|
||||
input.dispatchEvent(new Event('input'));
|
||||
|
||||
@@ -181,7 +183,7 @@ describe('SearchDateRangeComponent', () => {
|
||||
component.settings = { field: 'cm:created', maxDate: 'today' };
|
||||
fixture.detectChanges();
|
||||
|
||||
const input = fixture.debugElement.nativeElement.querySelector('[data-automation-id="date-range-from-input"]');
|
||||
const input = getFromInput();
|
||||
input.value = format(addDays(new Date(), 1), 'dd-MM-yyyy');
|
||||
input.dispatchEvent(new Event('input'));
|
||||
|
||||
@@ -194,11 +196,11 @@ describe('SearchDateRangeComponent', () => {
|
||||
it('should show error for required constraint', async () => {
|
||||
fixture.detectChanges();
|
||||
|
||||
const fromInput = fixture.debugElement.nativeElement.querySelector('[data-automation-id="date-range-from-input"]');
|
||||
const fromInput = getFromInput();
|
||||
fromInput.value = '';
|
||||
fromInput.dispatchEvent(new Event('input'));
|
||||
|
||||
const toInput = fixture.debugElement.nativeElement.querySelector('[data-automation-id="date-range-to-input"]');
|
||||
const toInput = getToInput();
|
||||
toInput.value = '';
|
||||
toInput.dispatchEvent(new Event('input'));
|
||||
|
||||
@@ -212,11 +214,11 @@ describe('SearchDateRangeComponent', () => {
|
||||
it('should show error for incorrect date range', async () => {
|
||||
fixture.detectChanges();
|
||||
|
||||
const fromInput = fixture.debugElement.nativeElement.querySelector('[data-automation-id="date-range-from-input"]');
|
||||
const fromInput = getFromInput();
|
||||
fromInput.value = '11-10-2018';
|
||||
fromInput.dispatchEvent(new Event('input'));
|
||||
|
||||
const toInput = fixture.debugElement.nativeElement.querySelector('[data-automation-id="date-range-to-input"]');
|
||||
const toInput = getToInput();
|
||||
toInput.value = '10-10-2018';
|
||||
toInput.dispatchEvent(new Event('input'));
|
||||
|
||||
@@ -230,7 +232,7 @@ describe('SearchDateRangeComponent', () => {
|
||||
it('should not show date-format error when valid found', async () => {
|
||||
fixture.detectChanges();
|
||||
|
||||
const input = fixture.debugElement.nativeElement.querySelector('[data-automation-id="date-range-from-input"]');
|
||||
const input = getFromInput();
|
||||
input.value = '10-10-2018';
|
||||
input.dispatchEvent(new Event('input'));
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user