Merge pull request #597 from 4Science/#592-miscellaneous-fixes

fix Submission cannot be completed #592
This commit is contained in:
Tim Donohue
2020-02-27 15:20:48 -06:00
committed by GitHub
19 changed files with 63 additions and 50 deletions

View File

@@ -230,10 +230,10 @@ describe('BitstreamFormatsComponent', () => {
comp.deleteFormats();
expect(bitstreamFormatService.clearBitStreamFormatRequests).toHaveBeenCalled();
expect(bitstreamFormatService.delete).toHaveBeenCalledWith(bitstreamFormat1);
expect(bitstreamFormatService.delete).toHaveBeenCalledWith(bitstreamFormat2);
expect(bitstreamFormatService.delete).toHaveBeenCalledWith(bitstreamFormat3);
expect(bitstreamFormatService.delete).toHaveBeenCalledWith(bitstreamFormat4);
expect(bitstreamFormatService.delete).toHaveBeenCalledWith(bitstreamFormat1.id);
expect(bitstreamFormatService.delete).toHaveBeenCalledWith(bitstreamFormat2.id);
expect(bitstreamFormatService.delete).toHaveBeenCalledWith(bitstreamFormat3.id);
expect(bitstreamFormatService.delete).toHaveBeenCalledWith(bitstreamFormat4.id);
expect(notificationsServiceStub.success).toHaveBeenCalledWith('admin.registries.bitstream-formats.delete.success.head',
'admin.registries.bitstream-formats.delete.success.amount');
@@ -276,10 +276,10 @@ describe('BitstreamFormatsComponent', () => {
comp.deleteFormats();
expect(bitstreamFormatService.clearBitStreamFormatRequests).toHaveBeenCalled();
expect(bitstreamFormatService.delete).toHaveBeenCalledWith(bitstreamFormat1);
expect(bitstreamFormatService.delete).toHaveBeenCalledWith(bitstreamFormat2);
expect(bitstreamFormatService.delete).toHaveBeenCalledWith(bitstreamFormat3);
expect(bitstreamFormatService.delete).toHaveBeenCalledWith(bitstreamFormat4);
expect(bitstreamFormatService.delete).toHaveBeenCalledWith(bitstreamFormat1.id);
expect(bitstreamFormatService.delete).toHaveBeenCalledWith(bitstreamFormat2.id);
expect(bitstreamFormatService.delete).toHaveBeenCalledWith(bitstreamFormat3.id);
expect(bitstreamFormatService.delete).toHaveBeenCalledWith(bitstreamFormat4.id);
expect(notificationsServiceStub.error).toHaveBeenCalledWith('admin.registries.bitstream-formats.delete.failure.head',
'admin.registries.bitstream-formats.delete.failure.amount');

View File

@@ -64,7 +64,7 @@ export class BitstreamFormatsComponent implements OnInit {
const tasks$ = [];
for (const format of formats) {
if (hasValue(format.id)) {
tasks$.push(this.bitstreamFormatService.delete(format));
tasks$.push(this.bitstreamFormatService.delete(format.id));
}
}
zip(...tasks$).subscribe((results: boolean[]) => {

View File

@@ -220,7 +220,7 @@ describe('ItemDeleteComponent', () => {
spyOn(comp, 'notify');
comp.performAction();
expect(mockItemDataService.delete)
.toHaveBeenCalledWith(mockItem, types.filter((type) => typesSelection[type]).map((type) => type.id));
.toHaveBeenCalledWith(mockItem.id, types.filter((type) => typesSelection[type]).map((type) => type.id));
expect(comp.notify).toHaveBeenCalled();
});
});

View File

@@ -312,7 +312,7 @@ export class ItemDeleteComponent
)
),
).subscribe((types) => {
this.itemDataService.delete(this.item, types).pipe(first()).subscribe(
this.itemDataService.delete(this.item.id, types).pipe(first()).subscribe(
(succeeded: boolean) => {
this.notify(succeeded);
}
@@ -322,7 +322,7 @@ export class ItemDeleteComponent
/**
* When the item is successfully delete, navigate to the homepage, otherwise navigate back to the item edit page
* @param response
* @param succeeded
*/
notify(succeeded: boolean) {
if (succeeded) {

View File

@@ -3,12 +3,11 @@ import { HttpClientModule } from '@angular/common/http';
import { NgModule } from '@angular/core';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { EffectsModule } from '@ngrx/effects';
import { RouterStateSerializer, StoreRouterConnectingModule } from '@ngrx/router-store';
import { META_REDUCERS, MetaReducer, StoreModule, USER_PROVIDED_META_REDUCERS } from '@ngrx/store';
import { MetaReducer, StoreModule, USER_PROVIDED_META_REDUCERS } from '@ngrx/store';
import { StoreDevtoolsModule } from '@ngrx/store-devtools';
import { DYNAMIC_MATCHER_PROVIDERS } from '@ng-dynamic-forms/core';
import { TranslateModule } from '@ngx-translate/core';
import { ScrollToModule } from '@nicky-lenaers/ngx-scroll-to';
@@ -21,7 +20,7 @@ import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { appEffects } from './app.effects';
import { appMetaReducers, debugMetaReducers, universalMetaReducer } from './app.metareducers';
import { appMetaReducers, debugMetaReducers } from './app.metareducers';
import { appReducers, AppState } from './app.reducer';
import { CoreModule } from './core/core.module';
@@ -97,7 +96,8 @@ const PROVIDERS = [
provide: RouterStateSerializer,
useClass: DSpaceRouterStateSerializer
},
ClientCookieService
ClientCookieService,
...DYNAMIC_MATCHER_PROVIDERS,
];
const DECLARATIONS = [

View File

@@ -282,7 +282,7 @@ describe('BitstreamFormatDataService', () => {
format.id = 'format-id';
const expected = cold('(b|)', {b: true});
const result = service.delete(format);
const result = service.delete(format.id);
expect(result).toBeObservable(expected);
});

View File

@@ -154,19 +154,19 @@ export class BitstreamFormatDataService extends DataService<BitstreamFormat> {
/**
* Delete an existing DSpace Object on the server
* @param format The DSpace Object to be removed
* @param formatID The DSpace Object'id to be removed
* Return an observable that emits true when the deletion was successful, false when it failed
*/
delete(format: BitstreamFormat): Observable<boolean> {
delete(formatID: string): Observable<boolean> {
const requestId = this.requestService.generateRequestId();
const hrefObs = this.halService.getEndpoint(this.linkPath).pipe(
map((endpoint: string) => this.getIDHref(endpoint, format.id)));
map((endpoint: string) => this.getIDHref(endpoint, formatID)));
hrefObs.pipe(
find((href: string) => hasValue(href)),
map((href: string) => {
const request = new DeleteByIDRequest(requestId, href, format.id);
const request = new DeleteByIDRequest(requestId, href, formatID);
this.requestService.configure(request);
})
).subscribe();

View File

@@ -152,7 +152,11 @@ export abstract class DataService<T extends CacheableObject> {
/**
* Returns {@link RemoteData} of all object with a list of {@link FollowLinkConfig}, to indicate which embedded
* info should be added to the objects
*
* @param options Find list options object
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
* @return {Observable<RemoteData<PaginatedList<T>>>}
* Return an observable that emits object list
*/
findAll(options: FindListOptions = {}, ...linksToFollow: Array<FollowLinkConfig<T>>): Observable<RemoteData<PaginatedList<T>>> {
return this.findList(this.getFindAllHref(options), options, ...linksToFollow);
@@ -162,6 +166,7 @@ export abstract class DataService<T extends CacheableObject> {
* Returns an observable of {@link RemoteData} of an object, based on href observable,
* with a list of {@link FollowLinkConfig}, to automatically resolve {@link HALLink}s of the object
* @param href$ Observable of href of object we want to retrieve
* @param options Find list options object
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
*/
protected findList(href$, options: FindListOptions, ...linksToFollow: Array<FollowLinkConfig<T>>) {
@@ -231,6 +236,7 @@ export abstract class DataService<T extends CacheableObject> {
* Returns a list of observables of {@link RemoteData} of objects, based on an href, with a list of {@link FollowLinkConfig},
* to automatically resolve {@link HALLink}s of the object
* @param href The url of object we want to retrieve
* @param findListOptions Find list options object
* @param linksToFollow List of {@link FollowLinkConfig} that indicate which {@link HALLink}s should be automatically resolved
*/
findAllByHref(href: string, findListOptions: FindListOptions = {}, ...linksToFollow: Array<FollowLinkConfig<T>>): Observable<RemoteData<PaginatedList<T>>> {
@@ -259,6 +265,7 @@ export abstract class DataService<T extends CacheableObject> {
*
* @param searchMethod The search method for the object
* @param options The [[FindListOptions]] object
* @param linksToFollow The array of [[FollowLinkConfig]]
* @return {Observable<RemoteData<PaginatedList<T>>}
* Return an observable that emits response from the server
*/
@@ -367,16 +374,16 @@ export abstract class DataService<T extends CacheableObject> {
/**
* Delete an existing DSpace Object on the server
* @param dso The DSpace Object to be removed
* @param dsoID The DSpace Object' id to be removed
* @param copyVirtualMetadata (optional parameter) the identifiers of the relationship types for which the virtual
* metadata should be saved as real metadata
* @return an observable that emits true when the deletion was successful, false when it failed
*/
delete(dso: T, copyVirtualMetadata?: string[]): Observable<boolean> {
delete(dsoID: string, copyVirtualMetadata?: string[]): Observable<boolean> {
const requestId = this.requestService.generateRequestId();
const hrefObs = this.halService.getEndpoint(this.linkPath).pipe(
map((endpoint: string) => this.getIDHref(endpoint, dso.uuid)));
map((endpoint: string) => this.getIDHref(endpoint, dsoID)));
hrefObs.pipe(
find((href: string) => hasValue(href)),
@@ -388,7 +395,7 @@ export abstract class DataService<T extends CacheableObject> {
+ id
);
}
const request = new DeleteByIDRequest(requestId, href, dso.uuid);
const request = new DeleteByIDRequest(requestId, href, dsoID);
this.requestService.configure(request);
})
).subscribe();

View File

@@ -125,7 +125,7 @@ describe('DeleteComColPageComponent', () => {
it('should call delete on the data service', () => {
comp.onConfirm(data1);
fixture.detectChanges();
expect(dsoDataService.delete).toHaveBeenCalledWith(data1);
expect(dsoDataService.delete).toHaveBeenCalledWith(data1.id);
});
});

View File

@@ -43,7 +43,7 @@ export class DeleteComColPageComponent<TDomain extends DSpaceObject> implements
* Deletes an existing DSO and redirects to the home page afterwards, showing a notification that states whether or not the deletion was successful
*/
onConfirm(dso: TDomain) {
this.dsoDataService.delete(dso)
this.dsoDataService.delete(dso.id)
.pipe(first())
.subscribe((success: boolean) => {
if (success) {

View File

@@ -1,5 +1,5 @@
import { ChangeDetectionStrategy, Injector, NO_ERRORS_SCHEMA } from '@angular/core';
import { async, ComponentFixture, fakeAsync, TestBed } from '@angular/core/testing';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { Router } from '@angular/router';
import { By } from '@angular/platform-browser';
@@ -141,7 +141,7 @@ describe('WorkspaceitemActionsComponent', () => {
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(mockDataService.delete).toHaveBeenCalledWith(mockObject);
expect(mockDataService.delete).toHaveBeenCalledWith(mockObject.id);
});
});

View File

@@ -1,4 +1,4 @@
import { Component, Injector, Input, OnDestroy } from '@angular/core';
import { Component, Injector, Input } from '@angular/core';
import { Router } from '@angular/router';
import { BehaviorSubject } from 'rxjs';
@@ -62,7 +62,7 @@ export class WorkspaceitemActionsComponent extends MyDSpaceActionsComponent<Work
(result) => {
if (result === 'ok') {
this.processingDelete$.next(true);
this.objectDataService.delete(this.object)
this.objectDataService.delete(this.object.id)
.subscribe((response: boolean) => {
this.processingDelete$.next(false);
this.handleActionResponse(response);

View File

@@ -74,7 +74,7 @@ describe('SubmissionEditComponent Component', () => {
expect(comp.submissionId).toBe(submissionId);
expect(comp.collectionId).toBe(submissionObject.collection.id);
expect(comp.selfUrl).toBe(submissionObject.self);
expect(comp.selfUrl).toBe(submissionObject._links.self.href);
expect(comp.sections).toBe(submissionObject.sections);
expect(comp.submissionDefinition).toBe(submissionObject.submissionDefinition);

View File

@@ -94,7 +94,7 @@ export class SubmissionEditComponent implements OnDestroy, OnInit {
} else {
this.submissionId = submissionObjectRD.payload.id.toString();
this.collectionId = (submissionObjectRD.payload.collection as Collection).id;
this.selfUrl = submissionObjectRD.payload.self;
this.selfUrl = submissionObjectRD.payload._links.self.href;
this.sections = submissionObjectRD.payload.sections;
this.submissionDefinition = (submissionObjectRD.payload.submissionDefinition as SubmissionDefinitionsModel);
this.changeDetectorRef.detectChanges();

View File

@@ -10,7 +10,9 @@ import {
DynamicFormControlEvent,
DynamicFormControlModel,
DynamicFormGroupModel,
DynamicSelectModel
DynamicSelectModel,
MATCH_ENABLED,
OR_OPERATOR
} from '@ng-dynamic-forms/core';
import { WorkspaceitemSectionUploadFileObject } from '../../../../../core/submission/models/workspaceitem-section-upload-file.model';
@@ -206,9 +208,9 @@ export class SubmissionSectionUploadFileEditComponent implements OnChanges {
hasGroups.push({ id: 'name', value: condition.name });
}
});
const confStart = { relation: [{ action: 'ENABLE', connective: 'OR', when: hasStart }] };
const confEnd = { relation: [{ action: 'ENABLE', connective: 'OR', when: hasEnd }] };
const confGroup = { relation: [{ action: 'ENABLE', connective: 'OR', when: hasGroups }] };
const confStart = { relations: [{ match: MATCH_ENABLED, operator: OR_OPERATOR, when: hasStart }] };
const confEnd = { relations: [{ match: MATCH_ENABLED, operator: OR_OPERATOR, when: hasEnd }] };
const confGroup = { relations: [{ match: MATCH_ENABLED, operator: OR_OPERATOR, when: hasGroups }] };
accessConditionsArrayConfig.groupFactory = () => {
const type = new DynamicSelectModel(accessConditionTypeModelConfig, BITSTREAM_FORM_ACCESS_CONDITION_TYPE_LAYOUT);

View File

@@ -1,8 +1,11 @@
import {
DynamicDatePickerModelConfig,
DynamicFormArrayModelConfig,
DynamicFormControlLayout,
DynamicFormGroupModelConfig,
DynamicSelectModelConfig,
DynamicFormGroupModelConfig, DynamicFormControlLayout,
MATCH_ENABLED,
OR_OPERATOR,
} from '@ng-dynamic-forms/core';
export const BITSTREAM_METADATA_FORM_GROUP_CONFIG: DynamicFormGroupModelConfig = {
@@ -15,7 +18,7 @@ export const BITSTREAM_METADATA_FORM_GROUP_LAYOUT: DynamicFormControlLayout = {
label: 'col-form-label'
},
grid: {
label: 'col-sm-3'
label: 'col-sm-3'
}
};
@@ -52,8 +55,8 @@ export const BITSTREAM_FORM_ACCESS_CONDITION_START_DATE_CONFIG: DynamicDatePicke
toggleIcon: 'far fa-calendar-alt',
relations: [
{
match: 'ENABLE',
operator: 'OR',
match: MATCH_ENABLED,
operator: OR_OPERATOR,
when: []
}
],
@@ -83,8 +86,8 @@ export const BITSTREAM_FORM_ACCESS_CONDITION_END_DATE_CONFIG: DynamicDatePickerM
toggleIcon: 'far fa-calendar-alt',
relations: [
{
match: 'ENABLE',
operator: 'OR',
match: MATCH_ENABLED,
operator: OR_OPERATOR,
when: []
}
],
@@ -112,8 +115,8 @@ export const BITSTREAM_FORM_ACCESS_CONDITION_GROUPS_CONFIG: DynamicSelectModelCo
options: [],
relations: [
{
match: 'ENABLE',
operator: 'OR',
match: MATCH_ENABLED,
operator: OR_OPERATOR,
when: []
}
],

View File

@@ -164,7 +164,8 @@ export class SubmissionSectionUploadComponent extends SectionModelComponent {
flatMap((submissionObject: SubmissionObjectEntry) => this.collectionDataService.findById(submissionObject.collection)),
filter((rd: RemoteData<Collection>) => isNotUndefined((rd.payload))),
tap((collectionRemoteData: RemoteData<Collection>) => this.collectionName = collectionRemoteData.payload.name),
flatMap((collectionRemoteData: RemoteData<Collection>) => {
// TODO review this part when https://github.com/DSpace/dspace-angular/issues/575 is resolved
/* flatMap((collectionRemoteData: RemoteData<Collection>) => {
return this.resourcePolicyService.findByHref(
(collectionRemoteData.payload as any)._links.defaultAccessConditions.href
);
@@ -176,7 +177,7 @@ export class SubmissionSectionUploadComponent extends SectionModelComponent {
this.collectionDefaultAccessConditions = Array.isArray(defaultAccessConditionsRemoteData.payload)
? defaultAccessConditionsRemoteData.payload : [defaultAccessConditionsRemoteData.payload];
}
}),
}),*/
flatMap(() => config$),
flatMap((config: SubmissionUploadsModel) => {
this.required$.next(config.required);

View File

@@ -68,7 +68,7 @@ describe('SubmissionSubmitComponent Component', () => {
expect(comp.submissionId.toString()).toEqual(submissionId);
expect(comp.collectionId).toBe(submissionObject.collection.id);
expect(comp.selfUrl).toBe(submissionObject.self);
expect(comp.selfUrl).toBe(submissionObject._links.self.href);
expect(comp.submissionDefinition).toBe(submissionObject.submissionDefinition);
}));

View File

@@ -95,7 +95,7 @@ export class SubmissionSubmitComponent implements OnDestroy, OnInit {
this.router.navigate(['/mydspace']);
} else {
this.collectionId = (submissionObject.collection as Collection).id;
this.selfUrl = submissionObject.self;
this.selfUrl = submissionObject._links.self.href;
this.submissionDefinition = (submissionObject.submissionDefinition as SubmissionDefinitionsModel);
this.submissionId = submissionObject.id;
this.changeDetectorRef.detectChanges();