Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into fix-versioning-button
Browse files Browse the repository at this point in the history
  • Loading branch information
ybnd committed Mar 7, 2024
2 parents 0f465ac + a9c58a1 commit c8954da
Show file tree
Hide file tree
Showing 161 changed files with 5,126 additions and 572 deletions.
64 changes: 63 additions & 1 deletion config/config.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,10 @@ submission:
# NOTE: after how many time (milliseconds) submission is saved automatically
# eg. timer: 5 * (1000 * 60); // 5 minutes
timer: 0
# Always show the duplicate detection section if enabled, even if there are no potential duplicates detected
# (a message will be displayed to indicate no matches were found)
duplicateDetection:
alwaysShowSection: false
icons:
metadata:
# NOTE: example of configuration
Expand Down Expand Up @@ -427,9 +431,67 @@ comcolSelectionSort:


# Search settings
search:
search:
# Settings to enable/disable or configure advanced search filters.
advancedFilters:
enabled: false
# List of filters to enable in "Advanced Search" dropdown
filter: [ 'title', 'author', 'subject', 'entityType' ]


# Notify metrics
# Configuration for Notify Admin Dashboard for metrics visualization
notifyMetrics:
# Configuration for received messages
- title: 'admin-notify-dashboard.received-ldn'
boxes:
- color: '#B8DAFF'
title: 'admin-notify-dashboard.NOTIFY.incoming.accepted'
config: 'NOTIFY.incoming.accepted'
description: 'admin-notify-dashboard.NOTIFY.incoming.accepted.description'
- color: '#D4EDDA'
title: 'admin-notify-dashboard.NOTIFY.incoming.processed'
config: 'NOTIFY.incoming.processed'
description: 'admin-notify-dashboard.NOTIFY.incoming.processed.description'
- color: '#FDBBC7'
title: 'admin-notify-dashboard.NOTIFY.incoming.failure'
config: 'NOTIFY.incoming.failure'
description: 'admin-notify-dashboard.NOTIFY.incoming.failure.description'
- color: '#FDBBC7'
title: 'admin-notify-dashboard.NOTIFY.incoming.untrusted'
config: 'NOTIFY.incoming.untrusted'
description: 'admin-notify-dashboard.NOTIFY.incoming.untrusted.description'
- color: '#43515F'
title: 'admin-notify-dashboard.NOTIFY.incoming.involvedItems'
textColor: '#fff'
config: 'NOTIFY.incoming.involvedItems'
description: 'admin-notify-dashboard.NOTIFY.incoming.involvedItems.description'
# Configuration for outgoing messages
- title: 'admin-notify-dashboard.generated-ldn'
boxes:
- color: '#B8DAFF'
title: 'admin-notify-dashboard.NOTIFY.outgoing.queued'
config: 'NOTIFY.outgoing.queued'
description: 'admin-notify-dashboard.NOTIFY.outgoing.queued.description'
- color: '#FDEEBB'
title: 'admin-notify-dashboard.NOTIFY.outgoing.queued_for_retry'
config: 'NOTIFY.outgoing.queued_for_retry'
description: 'admin-notify-dashboard.NOTIFY.outgoing.queued_for_retry.description'
- color: '#FDBBC7'
title: 'admin-notify-dashboard.NOTIFY.outgoing.failure'
config: 'NOTIFY.outgoing.failure'
description: 'admin-notify-dashboard.NOTIFY.outgoing.failure.description'
- color: '#43515F'
title: 'admin-notify-dashboard.NOTIFY.outgoing.involvedItems'
textColor: '#fff'
config: 'NOTIFY.outgoing.involvedItems'
description: 'admin-notify-dashboard.NOTIFY.outgoing.involvedItems.description'
- color: '#D4EDDA'
title: 'admin-notify-dashboard.NOTIFY.outgoing.delivered'
config: 'NOTIFY.outgoing.delivered'
description: 'admin-notify-dashboard.NOTIFY.outgoing.delivered.description'





5 changes: 4 additions & 1 deletion karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ module.exports = function (config) {
],
client: {
clearContext: false, // leave Jasmine Spec Runner output visible in browser
captureConsole: false
captureConsole: false,
jasmine: {
failSpecWithNoExpectations: true
}
},
coverageIstanbulReporter: {
dir: require('path').join(__dirname, './coverage/dspace-angular'),
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@
"react-copy-to-clipboard": "^5.1.0",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.8.0",
"sanitize-html": "^2.10.0",
"sanitize-html": "^2.12.1",
"sortablejs": "1.15.0",
"uuid": "^8.3.2",
"webfontloader": "1.6.28",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ import { DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
import { ComponentFixture, fakeAsync, TestBed, tick, waitForAsync } from '@angular/core/testing';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { BrowserModule, By } from '@angular/platform-browser';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core';
import { NgbModule, NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { TranslateModule } from '@ngx-translate/core';
import { buildPaginatedList, PaginatedList } from '../../core/data/paginated-list.model';
import { RemoteData } from '../../core/data/remote-data';
import { EPersonDataService } from '../../core/eperson/eperson-data.service';
Expand All @@ -18,8 +18,6 @@ import { EPeopleRegistryComponent } from './epeople-registry.component';
import { EPersonMock, EPersonMock2 } from '../../shared/testing/eperson.mock';
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils';
import { getMockFormBuilderService } from '../../shared/mocks/form-builder-service.mock';
import { getMockTranslateService } from '../../shared/mocks/translate.service.mock';
import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock';
import { NotificationsServiceStub } from '../../shared/testing/notifications-service.stub';
import { RouterStub } from '../../shared/testing/router.stub';
import { AuthorizationDataService } from '../../core/data/feature-authorization/authorization-data.service';
Expand All @@ -31,17 +29,15 @@ import { FindListOptions } from '../../core/data/find-list-options.model';
describe('EPeopleRegistryComponent', () => {
let component: EPeopleRegistryComponent;
let fixture: ComponentFixture<EPeopleRegistryComponent>;
let translateService: TranslateService;
let builderService: FormBuilderService;

let mockEPeople;
let mockEPeople: EPerson[];
let ePersonDataServiceStub: any;
let authorizationService: AuthorizationDataService;
let modalService;
let modalService: NgbModal;
let paginationService: PaginationServiceStub;

let paginationService;

beforeEach(waitForAsync(() => {
beforeEach(waitForAsync(async () => {
jasmine.getEnv().allowRespy(true);
mockEPeople = [EPersonMock, EPersonMock2];
ePersonDataServiceStub = {
Expand Down Expand Up @@ -99,7 +95,7 @@ describe('EPeopleRegistryComponent', () => {
deleteEPerson(ePerson: EPerson): Observable<boolean> {
this.allEpeople = this.allEpeople.filter((ePerson2: EPerson) => {
return (ePerson2.uuid !== ePerson.uuid);
});
});
return observableOf(true);
},
editEPerson(ePerson: EPerson) {
Expand All @@ -119,17 +115,11 @@ describe('EPeopleRegistryComponent', () => {
isAuthorized: observableOf(true)
});
builderService = getMockFormBuilderService();
translateService = getMockTranslateService();

paginationService = new PaginationServiceStub();
TestBed.configureTestingModule({
await TestBed.configureTestingModule({
imports: [CommonModule, NgbModule, FormsModule, ReactiveFormsModule, BrowserModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useClass: TranslateLoaderMock
}
}),
TranslateModule.forRoot(),
],
declarations: [EPeopleRegistryComponent],
providers: [
Expand All @@ -148,7 +138,7 @@ describe('EPeopleRegistryComponent', () => {
beforeEach(() => {
fixture = TestBed.createComponent(EPeopleRegistryComponent);
component = fixture.componentInstance;
modalService = (component as any).modalService;
modalService = TestBed.inject(NgbModal);
spyOn(modalService, 'open').and.returnValue(Object.assign({ componentInstance: Object.assign({ response: observableOf(true) }) }));
fixture.detectChanges();
});
Expand All @@ -158,18 +148,18 @@ describe('EPeopleRegistryComponent', () => {
});

it('should display list of ePeople', () => {
const ePeopleIdsFound = fixture.debugElement.queryAll(By.css('#epeople tr td:first-child'));
const ePeopleIdsFound: DebugElement[] = fixture.debugElement.queryAll(By.css('#epeople tr td:first-child'));
expect(ePeopleIdsFound.length).toEqual(2);
mockEPeople.map((ePerson: EPerson) => {
expect(ePeopleIdsFound.find((foundEl) => {
expect(ePeopleIdsFound.find((foundEl: DebugElement) => {
return (foundEl.nativeElement.textContent.trim() === ePerson.uuid);
})).toBeTruthy();
});
});

describe('search', () => {
describe('when searching with scope/query (scope metadata)', () => {
let ePeopleIdsFound;
let ePeopleIdsFound: DebugElement[];
beforeEach(fakeAsync(() => {
component.search({ scope: 'metadata', query: EPersonMock2.name });
tick();
Expand All @@ -179,14 +169,14 @@ describe('EPeopleRegistryComponent', () => {

it('should display search result', () => {
expect(ePeopleIdsFound.length).toEqual(1);
expect(ePeopleIdsFound.find((foundEl) => {
expect(ePeopleIdsFound.find((foundEl: DebugElement) => {
return (foundEl.nativeElement.textContent.trim() === EPersonMock2.uuid);
})).toBeTruthy();
});
});

describe('when searching with scope/query (scope email)', () => {
let ePeopleIdsFound;
let ePeopleIdsFound: DebugElement[];
beforeEach(fakeAsync(() => {
component.search({ scope: 'email', query: EPersonMock.email });
tick();
Expand All @@ -196,7 +186,7 @@ describe('EPeopleRegistryComponent', () => {

it('should display search result', () => {
expect(ePeopleIdsFound.length).toEqual(1);
expect(ePeopleIdsFound.find((foundEl) => {
expect(ePeopleIdsFound.find((foundEl: DebugElement) => {
return (foundEl.nativeElement.textContent.trim() === EPersonMock.uuid);
})).toBeTruthy();
});
Expand Down Expand Up @@ -228,19 +218,12 @@ describe('EPeopleRegistryComponent', () => {
});
});

describe('delete EPerson button when the isAuthorized returns false', () => {
let ePeopleDeleteButton;
beforeEach(() => {
spyOn(authorizationService, 'isAuthorized').and.returnValue(observableOf(false));
component.initialisePage();
fixture.detectChanges();
});

it('should be disabled', () => {
ePeopleDeleteButton = fixture.debugElement.queryAll(By.css('#epeople tr td div button.delete-button'));
ePeopleDeleteButton.forEach((deleteButton: DebugElement) => {
expect(deleteButton.nativeElement.disabled).toBe(true);
});
});
it('should hide delete EPerson button when the isAuthorized returns false', () => {
spyOn(authorizationService, 'isAuthorized').and.returnValue(observableOf(false));
component.initialisePage();
fixture.detectChanges();

expect(fixture.debugElement.query(By.css('#epeople tr td div button.delete-button'))).toBeNull();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,13 @@ <h1 class="flex-grow-1">{{ isNewService ? ('ldn-create-service.title' | translat
id="ldnUrl"
name="ldnUrl"
type="text">
<div *ngIf="formModel.get('ldnUrl').invalid && formModel.get('ldnUrl').touched" class="error-text">
{{ 'ldn-new-service.form.error.ldnurl' | translate }}
<div *ngIf="formModel.get('ldnUrl').invalid && formModel.get('ldnUrl').touched" >
<div *ngIf="formModel.get('ldnUrl').errors['required']" class="error-text">
{{ 'ldn-new-service.form.error.ldnurl' | translate }}
</div>
<div *ngIf="formModel.get('ldnUrl').errors['ldnUrlAlreadyAssociated']" class="error-text">
{{ 'ldn-new-service.form.error.ldnurl.ldnUrlAlreadyAssociated' | translate }}
</div>
</div>
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,12 @@ import {
TemplateRef,
ViewChild
} from '@angular/core';
import {FormArray, FormBuilder, FormGroup, Validators} from '@angular/forms';
import {
FormArray,
FormBuilder,
FormGroup,
Validators
} from '@angular/forms';
import {LDN_SERVICE} from '../ldn-services-model/ldn-service.resource-type';
import {ActivatedRoute, Router} from '@angular/router';
import {LdnServicesService} from '../ldn-services-data/ldn-services-data.service';
Expand Down Expand Up @@ -167,6 +172,9 @@ export class LdnServiceFormComponent implements OnInit, OnDestroy {
this.closeModal();
this.sendBack();
} else {
if (!this.formModel.errors) {
this.setLdnUrlError();
}
this.notificationService.error(this.translateService.get('ldn-service-notification.created.failure.title'),
this.translateService.get('ldn-service-notification.created.failure.body'));
this.closeModal();
Expand Down Expand Up @@ -405,6 +413,9 @@ export class LdnServiceFormComponent implements OnInit, OnDestroy {
this.notificationService.success(this.translateService.get('admin.registries.services-formats.modify.success.head'),
this.translateService.get('admin.registries.services-formats.modify.success.content'));
} else {
if (!this.formModel.errors) {
this.setLdnUrlError();
}
this.notificationService.error(this.translateService.get('admin.registries.services-formats.modify.failure.head'),
this.translateService.get('admin.registries.services-formats.modify.failure.content'));
this.closeModal();
Expand Down Expand Up @@ -554,4 +565,14 @@ export class LdnServiceFormComponent implements OnInit, OnDestroy {
automatic: '',
});
}


/**
* set ldnUrl error in case of unprocessable entity and provided value
*/
private setLdnUrlError(): void {
const control = this.formModel.controls.ldnUrl;
const controlErrors = control.errors || {};
control.setErrors({...controlErrors, ldnUrlAlreadyAssociated: true });
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ describe('LdnServicesService test', () => {

rdbService = jasmine.createSpyObj('rdbService', {
buildSingle: createSuccessfulRemoteDataObject$({}, 500),
buildFromRequestUUID: createSuccessfulRemoteDataObject$({}, 500),
buildList: cold('a', { a: remoteDataMocks.Success })
});

Expand Down Expand Up @@ -111,6 +112,20 @@ describe('LdnServicesService test', () => {
done();
});
});

it('should invoke service', (done) => {
const constraints = [{void: true}];
const files = [new File([],'fileName')];
spyOn(service as any, 'getInvocationFormData');
spyOn(service, 'getBrowseEndpoint').and.returnValue(observableOf('testEndpoint'));
service.invoke('serviceName', 'serviceId', constraints, files).subscribe(result => {
expect((service as any).getInvocationFormData).toHaveBeenCalledWith(constraints, files);
expect(service.getBrowseEndpoint).toHaveBeenCalled();
expect(result).toBeInstanceOf(RemoteData);
done();
});

});
});

});
Loading

0 comments on commit c8954da

Please sign in to comment.