[DURACOM-191] Fix dso-edit-metadata.component which still used getDataServiceFor decorator

This commit is contained in:
Giuseppe Digilio
2024-03-18 13:45:42 +01:00
parent 58512b6eed
commit 7472e6939b
5 changed files with 97 additions and 51 deletions

View File

@@ -12,6 +12,8 @@ import { of as observableOf } from 'rxjs';
import { ItemTemplateDataService } from '../../core/data/item-template-data.service'; import { ItemTemplateDataService } from '../../core/data/item-template-data.service';
import { Collection } from '../../core/shared/collection.model'; import { Collection } from '../../core/shared/collection.model';
import { DsoEditMetadataComponent } from '../../dso-shared/dso-edit-metadata/dso-edit-metadata.component';
import { ThemedDsoEditMetadataComponent } from '../../dso-shared/dso-edit-metadata/themed-dso-edit-metadata.component';
import { getMockThemeService } from '../../shared/mocks/theme-service.mock'; import { getMockThemeService } from '../../shared/mocks/theme-service.mock';
import { NotificationsService } from '../../shared/notifications/notifications.service'; import { NotificationsService } from '../../shared/notifications/notifications.service';
import { import {
@@ -47,6 +49,10 @@ describe('EditItemTemplatePageComponent', () => {
{ provide: NotificationsService, useValue: new NotificationsServiceStub() }, { provide: NotificationsService, useValue: new NotificationsServiceStub() },
], ],
schemas: [NO_ERRORS_SCHEMA], schemas: [NO_ERRORS_SCHEMA],
}).overrideComponent(EditItemTemplatePageComponent, {
remove: {
imports: [ThemedDsoEditMetadataComponent, DsoEditMetadataComponent],
},
}).compileComponents(); }).compileComponents();
})); }));

View File

@@ -24,6 +24,7 @@ import { RemoteData } from '../../core/data/remote-data';
import { Collection } from '../../core/shared/collection.model'; import { Collection } from '../../core/shared/collection.model';
import { Item } from '../../core/shared/item.model'; import { Item } from '../../core/shared/item.model';
import { getFirstSucceededRemoteDataPayload } from '../../core/shared/operators'; import { getFirstSucceededRemoteDataPayload } from '../../core/shared/operators';
import { DsoEditMetadataComponent } from '../../dso-shared/dso-edit-metadata/dso-edit-metadata.component';
import { ThemedDsoEditMetadataComponent } from '../../dso-shared/dso-edit-metadata/themed-dso-edit-metadata.component'; import { ThemedDsoEditMetadataComponent } from '../../dso-shared/dso-edit-metadata/themed-dso-edit-metadata.component';
import { AlertComponent } from '../../shared/alert/alert.component'; import { AlertComponent } from '../../shared/alert/alert.component';
import { AlertType } from '../../shared/alert/alert-type'; import { AlertType } from '../../shared/alert/alert-type';
@@ -36,6 +37,7 @@ import { getCollectionEditRoute } from '../collection-page-routing-paths';
templateUrl: './edit-item-template-page.component.html', templateUrl: './edit-item-template-page.component.html',
imports: [ imports: [
ThemedDsoEditMetadataComponent, ThemedDsoEditMetadataComponent,
DsoEditMetadataComponent,
RouterLink, RouterLink,
AsyncPipe, AsyncPipe,
VarDirective, VarDirective,

View File

@@ -1,7 +1,6 @@
import { CommonModule } from '@angular/common';
import { import {
ChangeDetectionStrategy,
DebugElement, DebugElement,
Injectable,
NO_ERRORS_SCHEMA, NO_ERRORS_SCHEMA,
} from '@angular/core'; } from '@angular/core';
import { import {
@@ -9,15 +8,15 @@ import {
TestBed, TestBed,
waitForAsync, waitForAsync,
} from '@angular/core/testing'; } from '@angular/core/testing';
import { By } from '@angular/platform-browser'; import {
BrowserModule,
By,
} from '@angular/platform-browser';
import { RouterTestingModule } from '@angular/router/testing'; import { RouterTestingModule } from '@angular/router/testing';
import { TranslateModule } from '@ngx-translate/core'; import { TranslateModule } from '@ngx-translate/core';
import { Operation } from 'fast-json-patch';
import { Observable } from 'rxjs';
import { APP_DATA_SERVICES_MAP } from '../../../config/app-config.interface';
import { ArrayMoveChangeAnalyzer } from '../../core/data/array-move-change-analyzer.service'; import { ArrayMoveChangeAnalyzer } from '../../core/data/array-move-change-analyzer.service';
import { DATA_SERVICE_FACTORY } from '../../core/data/base/data-service.decorator';
import { RemoteData } from '../../core/data/remote-data';
import { DSpaceObject } from '../../core/shared/dspace-object.model'; import { DSpaceObject } from '../../core/shared/dspace-object.model';
import { Item } from '../../core/shared/item.model'; import { Item } from '../../core/shared/item.model';
import { ITEM } from '../../core/shared/item.resource-type'; import { ITEM } from '../../core/shared/item.resource-type';
@@ -25,7 +24,7 @@ import { MetadataValue } from '../../core/shared/metadata.models';
import { AlertComponent } from '../../shared/alert/alert.component'; import { AlertComponent } from '../../shared/alert/alert.component';
import { LoadingComponent } from '../../shared/loading/loading.component'; import { LoadingComponent } from '../../shared/loading/loading.component';
import { NotificationsService } from '../../shared/notifications/notifications.service'; import { NotificationsService } from '../../shared/notifications/notifications.service';
import { createSuccessfulRemoteDataObject$ } from '../../shared/remote-data.utils'; import { TestDataService } from '../../shared/testing/test-data-service.mock';
import { VarDirective } from '../../shared/utils/var.directive'; import { VarDirective } from '../../shared/utils/var.directive';
import { DsoEditMetadataComponent } from './dso-edit-metadata.component'; import { DsoEditMetadataComponent } from './dso-edit-metadata.component';
import { DsoEditMetadataFieldValuesComponent } from './dso-edit-metadata-field-values/dso-edit-metadata-field-values.component'; import { DsoEditMetadataFieldValuesComponent } from './dso-edit-metadata-field-values/dso-edit-metadata-field-values.component';
@@ -39,12 +38,9 @@ const REINSTATE_BTN = 'reinstate';
const SAVE_BTN = 'save'; const SAVE_BTN = 'save';
const DISCARD_BTN = 'discard'; const DISCARD_BTN = 'discard';
@Injectable() const mockDataServiceMap: any = {
class TestDataService { [ITEM.value]: () => import('../../shared/testing/test-data-service.mock').then(m => m.TestDataService),
patch(object: Item, operations: Operation[]): Observable<RemoteData<Item>> { };
return createSuccessfulRemoteDataObject$(object);
}
}
describe('DsoEditMetadataComponent', () => { describe('DsoEditMetadataComponent', () => {
let component: DsoEditMetadataComponent; let component: DsoEditMetadataComponent;
@@ -92,21 +88,18 @@ describe('DsoEditMetadataComponent', () => {
TestBed.configureTestingModule({ TestBed.configureTestingModule({
imports: [ imports: [
CommonModule,
BrowserModule,
TranslateModule.forRoot(), TranslateModule.forRoot(),
RouterTestingModule.withRoutes([]), RouterTestingModule.withRoutes([]),
DsoEditMetadataComponent, DsoEditMetadataComponent,
VarDirective, VarDirective,
], ],
providers: [ providers: [
TestDataService, { provide: APP_DATA_SERVICES_MAP, useValue: mockDataServiceMap },
{
provide: DATA_SERVICE_FACTORY,
useValue: jasmine
.createSpy('getDataServiceFor')
.and.returnValue(TestDataService),
},
{ provide: NotificationsService, useValue: notificationsService }, { provide: NotificationsService, useValue: notificationsService },
ArrayMoveChangeAnalyzer, ArrayMoveChangeAnalyzer,
TestDataService,
], ],
schemas: [NO_ERRORS_SCHEMA], schemas: [NO_ERRORS_SCHEMA],
}) })
@@ -122,19 +115,16 @@ describe('DsoEditMetadataComponent', () => {
LoadingComponent, LoadingComponent,
], ],
}, },
add: {
changeDetection: ChangeDetectionStrategy.Default,
},
}) })
.compileComponents(); .compileComponents();
})); }));
beforeEach(() => { beforeEach(waitForAsync(() => {
fixture = TestBed.createComponent(DsoEditMetadataComponent); fixture = TestBed.createComponent(DsoEditMetadataComponent);
component = fixture.componentInstance; component = fixture.componentInstance;
component.dso = dso; component.dso = dso;
fixture.detectChanges(); fixture.detectChanges();
}); }));
describe('when no changes have been made', () => { describe('when no changes have been made', () => {
assertButton(ADD_BTN, true, false); assertButton(ADD_BTN, true, false);

View File

@@ -4,8 +4,10 @@ import {
NgIf, NgIf,
} from '@angular/common'; } from '@angular/common';
import { import {
ChangeDetectorRef,
Component, Component,
Inject, Inject,
InjectionToken,
Injector, Injector,
Input, Input,
OnDestroy, OnDestroy,
@@ -23,18 +25,25 @@ import {
import { import {
BehaviorSubject, BehaviorSubject,
combineLatest as observableCombineLatest, combineLatest as observableCombineLatest,
EMPTY,
Observable, Observable,
Subscription, Subscription,
} from 'rxjs'; } from 'rxjs';
import { map } from 'rxjs/operators'; import {
map,
mergeMap,
tap,
} from 'rxjs/operators';
import {
APP_DATA_SERVICES_MAP,
LazyDataServicesMap,
} from '../../../config/app-config.interface';
import { ArrayMoveChangeAnalyzer } from '../../core/data/array-move-change-analyzer.service'; import { ArrayMoveChangeAnalyzer } from '../../core/data/array-move-change-analyzer.service';
import { DATA_SERVICE_FACTORY } from '../../core/data/base/data-service.decorator';
import { HALDataService } from '../../core/data/base/hal-data-service.interface';
import { RemoteData } from '../../core/data/remote-data'; import { RemoteData } from '../../core/data/remote-data';
import { UpdateDataService } from '../../core/data/update-data.service'; import { UpdateDataService } from '../../core/data/update-data.service';
import { lazyService } from '../../core/lazy-service';
import { DSpaceObject } from '../../core/shared/dspace-object.model'; import { DSpaceObject } from '../../core/shared/dspace-object.model';
import { GenericConstructor } from '../../core/shared/generic-constructor';
import { getFirstCompletedRemoteData } from '../../core/shared/operators'; import { getFirstCompletedRemoteData } from '../../core/shared/operators';
import { ResourceType } from '../../core/shared/resource-type'; import { ResourceType } from '../../core/shared/resource-type';
import { AlertComponent } from '../../shared/alert/alert.component'; import { AlertComponent } from '../../shared/alert/alert.component';
@@ -42,6 +51,7 @@ import { AlertType } from '../../shared/alert/alert-type';
import { import {
hasNoValue, hasNoValue,
hasValue, hasValue,
isNotEmpty,
} from '../../shared/empty.util'; } from '../../shared/empty.util';
import { LoadingComponent } from '../../shared/loading/loading.component'; import { LoadingComponent } from '../../shared/loading/loading.component';
import { NotificationsService } from '../../shared/notifications/notifications.service'; import { NotificationsService } from '../../shared/notifications/notifications.service';
@@ -141,7 +151,8 @@ export class DsoEditMetadataComponent implements OnInit, OnDestroy {
protected translateService: TranslateService, protected translateService: TranslateService,
protected parentInjector: Injector, protected parentInjector: Injector,
protected arrayMoveChangeAnalyser: ArrayMoveChangeAnalyzer<number>, protected arrayMoveChangeAnalyser: ArrayMoveChangeAnalyzer<number>,
@Inject(DATA_SERVICE_FACTORY) protected getDataServiceFor: (resourceType: ResourceType) => GenericConstructor<HALDataService<any>>) { protected cdr: ChangeDetectorRef,
@Inject(APP_DATA_SERVICES_MAP) private dataServiceMap: InjectionToken<LazyDataServicesMap>) {
} }
/** /**
@@ -152,15 +163,18 @@ export class DsoEditMetadataComponent implements OnInit, OnDestroy {
if (hasNoValue(this.dso)) { if (hasNoValue(this.dso)) {
this.dsoUpdateSubscription = observableCombineLatest([this.route.data, this.route.parent.data]).pipe( this.dsoUpdateSubscription = observableCombineLatest([this.route.data, this.route.parent.data]).pipe(
map(([data, parentData]: [Data, Data]) => Object.assign({}, data, parentData)), map(([data, parentData]: [Data, Data]) => Object.assign({}, data, parentData)),
map((data: any) => data.dso), tap((data: any) => this.initDSO(data.dso.payload)),
).subscribe((rd: RemoteData<DSpaceObject>) => { mergeMap(() => this.retrieveDataService()),
this.dso = rd.payload; ).subscribe((dataService: UpdateDataService<DSpaceObject>) => {
this.initDataService(); this.initDataService(dataService);
this.initForm(); this.initForm();
}); });
} else { } else {
this.initDataService(); this.initDSOType(this.dso);
this.initForm(); this.retrieveDataService().subscribe((dataService: UpdateDataService<DSpaceObject>) => {
this.initDataService(dataService);
this.initForm();
});
} }
this.savingOrLoadingFieldValidation$ = observableCombineLatest([this.saving$, this.loadingFieldValidation$]).pipe( this.savingOrLoadingFieldValidation$ = observableCombineLatest([this.saving$, this.loadingFieldValidation$]).pipe(
map(([saving, loading]: [boolean, boolean]) => saving || loading), map(([saving, loading]: [boolean, boolean]) => saving || loading),
@@ -168,25 +182,47 @@ export class DsoEditMetadataComponent implements OnInit, OnDestroy {
} }
/** /**
* Initialise (resolve) the data-service for the current DSpaceObject * Resolve the data-service for the current DSpaceObject and retrieve its instance
*/ */
initDataService(): void { retrieveDataService(): Observable<UpdateDataService<DSpaceObject>> {
let type: ResourceType;
if (typeof this.dso.type === 'string') {
type = new ResourceType(this.dso.type);
} else {
type = this.dso.type;
}
if (hasNoValue(this.updateDataService)) { if (hasNoValue(this.updateDataService)) {
const provider = this.getDataServiceFor(type); const lazyProvider$: Observable<UpdateDataService<DSpaceObject>> = lazyService(this.dataServiceMap[this.dsoType], this.parentInjector);
this.updateDataService = Injector.create({ return lazyProvider$;
providers: [], } else {
parent: this.parentInjector, return EMPTY;
}).get(provider); }
}
/**
* Initialise the current DSpaceObject
*/
initDSO(object: DSpaceObject) {
this.dso = object;
this.initDSOType(object);
}
/**
* Initialise the current DSpaceObject's type
*/
initDSOType(object: DSpaceObject) {
let type: ResourceType;
if (typeof object.type === 'string') {
type = new ResourceType(object.type);
} else {
type = object.type;
} }
this.dsoType = type.value; this.dsoType = type.value;
} }
/**
* Initialise the data-service for the current DSpaceObject
*/
initDataService(dataService: UpdateDataService<DSpaceObject>): void {
if (isNotEmpty(dataService)) {
this.updateDataService = dataService;
}
}
/** /**
* Initialise the dynamic form object by passing the DSpaceObject's metadata * Initialise the dynamic form object by passing the DSpaceObject's metadata
* Call onValueSaved() to update the form's state properties * Call onValueSaved() to update the form's state properties
@@ -194,6 +230,7 @@ export class DsoEditMetadataComponent implements OnInit, OnDestroy {
initForm(): void { initForm(): void {
this.form = new DsoEditMetadataForm(this.dso.metadata); this.form = new DsoEditMetadataForm(this.dso.metadata);
this.onValueSaved(); this.onValueSaved();
this.cdr.detectChanges();
} }
/** /**

View File

@@ -1,7 +1,14 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { of } from 'rxjs'; import { Operation } from 'fast-json-patch';
import {
Observable,
of,
} from 'rxjs';
import { FindListOptions } from '../../core/data/find-list-options.model'; import { FindListOptions } from '../../core/data/find-list-options.model';
import { RemoteData } from '../../core/data/remote-data';
import { Item } from '../../core/shared/item.model';
import { createSuccessfulRemoteDataObject$ } from '../remote-data.utils';
import { FollowLinkConfig } from '../utils/follow-link-config.model'; import { FollowLinkConfig } from '../utils/follow-link-config.model';
@Injectable() @Injectable()
@@ -13,4 +20,8 @@ export class TestDataService {
findByHref(href: string, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig<any>[]) { findByHref(href: string, useCachedVersionIfAvailable = true, reRequestOnStale = true, ...linksToFollow: FollowLinkConfig<any>[]) {
return of('findByHref'); return of('findByHref');
} }
patch(object: Item, operations: Operation[]): Observable<RemoteData<Item>> {
return createSuccessfulRemoteDataObject$(object);
}
} }