[TLC-674] Tidy up components, WIP spec tests

This commit is contained in:
Kim Shepherd
2024-01-23 14:00:14 +13:00
parent b672668e15
commit 0e4ad5e674
8 changed files with 267 additions and 24 deletions

View File

@@ -1,5 +1,5 @@
/*
* Object model for the data returned by the REST API to present minted identifiers in a submission section
* Object model for the data returned by the REST API to present potential duplicates in a submission section
*/
import { Duplicate } from '../../../shared/object-list/duplicate-data/duplicate.model';

View File

@@ -5,6 +5,7 @@ import { WorkspaceitemSectionUploadObject } from './workspaceitem-section-upload
import { WorkspaceitemSectionCcLicenseObject } from './workspaceitem-section-cc-license.model';
import {WorkspaceitemSectionIdentifiersObject} from './workspaceitem-section-identifiers.model';
import { WorkspaceitemSectionSherpaPoliciesObject } from './workspaceitem-section-sherpa-policies.model';
import {WorkspaceitemSectionDuplicatesObject} from "./workspaceitem-section-duplicates.model";
/**
* An interface to represent submission's section object.
@@ -25,6 +26,7 @@ export type WorkspaceitemSectionDataType
| WorkspaceitemSectionAccessesObject
| WorkspaceitemSectionSherpaPoliciesObject
| WorkspaceitemSectionIdentifiersObject
| WorkspaceitemSectionDuplicatesObject
| string;

View File

@@ -10,9 +10,9 @@ export class Duplicate {
@autoserialize
uuid: string;
@autoserialize
workflowItemId: bigint;
workflowItemId: number;
@autoserialize
workspaceItemId: bigint;
workspaceItemId: number;
@autoserialize
owningCollection: string;

View File

@@ -35,6 +35,7 @@ const mockResultObject: PoolTaskSearchResult = new PoolTaskSearchResult();
mockResultObject.hitHighlights = {};
const item = Object.assign(new Item(), {
duplicates: observableOf([]),
bundles: observableOf({}),
metadata: {
'dc.title': [

View File

@@ -114,7 +114,6 @@ export class PoolSearchResultListElementComponent extends SearchResultListElemen
console.dir(remoteData);
if (remoteData.hasSucceeded) {
if (remoteData.payload.page) {
console.dir(remoteData.payload.page);
return remoteData.payload.page;
}
}

View File

@@ -2,14 +2,14 @@
Template for the detect duplicates submission section component
@author Kim Shepherd
-->
<div class="text-sm-left" *ngVar="(this.data$ | async) as data">
<div class="text-sm-left" *ngVar="(this.getDuplicateData() | async) as data">
<ng-container *ngIf="data.potentialDuplicates.length == 0">
<p>{{ 'submission.sections.duplicates.none' }}</p>
</ng-container>
<ng-container *ngIf="data.potentialDuplicates.length > 0">
<p>{{ 'submission.sections.duplicates.detected' | translate }}</p>
<div *ngFor="let dupe of data.potentialDuplicates" class="ds-duplicate">
<a target="_blank" [href]="'/items/'+dupe.uuid">{{dupe.title}}</a>
<a target="_blank" [href]="getItemLink(dupe.uuid)">{{dupe.title}}</a>
<div *ngFor="let metadatum of Metadata.toViewModelList(dupe.metadata)">
{{('item.preview.' + metadatum.key) | translate}} {{metadatum.value}}
</div>

View File

@@ -0,0 +1,252 @@
import { ChangeDetectorRef, Component, NO_ERRORS_SCHEMA } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { CommonModule } from '@angular/common';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { ComponentFixture, inject, TestBed, waitForAsync } from '@angular/core/testing';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { NgxPaginationModule } from 'ngx-pagination';
import { cold } from 'jasmine-marbles';
import { of as observableOf } from 'rxjs';
import { TranslateModule } from '@ngx-translate/core';
import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
import { createTestComponent } from '../../../shared/testing/utils.test';
import { NotificationsService } from '../../../shared/notifications/notifications.service';
import { NotificationsServiceStub } from '../../../shared/testing/notifications-service.stub';
import { SubmissionService } from '../../submission.service';
import { SubmissionServiceStub } from '../../../shared/testing/submission-service.stub';
import { SectionsService } from '../sections.service';
import { SectionsServiceStub } from '../../../shared/testing/sections-service.stub';
import { FormBuilderService } from '../../../shared/form/builder/form-builder.service';
import { getMockFormOperationsService } from '../../../shared/mocks/form-operations-service.mock';
import { getMockFormService } from '../../../shared/mocks/form-service.mock';
import { FormService } from '../../../shared/form/form.service';
import { SubmissionFormsConfigDataService } from '../../../core/config/submission-forms-config-data.service';
import { SectionsType } from '../sections-type';
import { mockSubmissionCollectionId, mockSubmissionId } from '../../../shared/mocks/submission.mock';
import { JsonPatchOperationPathCombiner } from '../../../core/json-patch/builder/json-patch-operation-path-combiner';
import { SubmissionSectionDuplicatesComponent } from './section-duplicates.component';
import { CollectionDataService } from '../../../core/data/collection-data.service';
import { JsonPatchOperationsBuilder } from '../../../core/json-patch/builder/json-patch-operations-builder';
import { SectionFormOperationsService } from '../form/section-form-operations.service';
import { SubmissionScopeType } from '../../../core/submission/submission-scope-type';
import { License } from '../../../core/shared/license.model';
import { Collection } from '../../../core/shared/collection.model';
import { ObjNgFor } from '../../../shared/utils/object-ngfor.pipe';
import { VarDirective } from '../../../shared/utils/var.directive';
import { PaginationService } from '../../../core/pagination/pagination.service';
import { PaginationServiceStub } from '../../../shared/testing/pagination-service.stub';
import {Duplicate} from "../../../shared/object-list/duplicate-data/duplicate.model";
import {MetadataValue} from "../../../core/shared/metadata.models";
import {
WorkspaceitemSectionDuplicatesObject
} from "../../../core/submission/models/workspaceitem-section-duplicates.model";
import {SectionDataObject} from "../models/section-data.model";
import {defaultUUID} from "../../../shared/mocks/uuid.service.mock";
function getMockSubmissionFormsConfigService(): SubmissionFormsConfigDataService {
return jasmine.createSpyObj('FormOperationsService', {
getConfigAll: jasmine.createSpy('getConfigAll'),
getConfigByHref: jasmine.createSpy('getConfigByHref'),
getConfigByName: jasmine.createSpy('getConfigByName'),
getConfigBySearch: jasmine.createSpy('getConfigBySearch')
});
}
function getMockCollectionDataService(): CollectionDataService {
return jasmine.createSpyObj('CollectionDataService', {
findById: jasmine.createSpy('findById'),
findByHref: jasmine.createSpy('findByHref')
});
}
const duplicates: Duplicate[]= [{
title: 'Unique title',
uuid: defaultUUID,
workflowItemId: 1,
workspaceItemId: 2,
owningCollection: 'Test Collection',
metadata: {
'dc.title': [
Object.assign(new MetadataValue(), {
'value': 'Unique title',
'language': null,
'authority': null,
'confidence': -1,
'place': 0
})]
}
}];
const potentialDuplicates: WorkspaceitemSectionDuplicatesObject = {
potentialDuplicates: duplicates
};
const sectionObject: SectionDataObject = {
header: 'submission.sections.submit.progressbar.duplicates',
config: 'https://dspace.org/api/config/submissionforms/duplicates',
mandatory: true,
opened: true,
data: potentialDuplicates,
errorsToShow: [],
serverValidationErrors: [],
id: 'duplicates',
sectionType: SectionsType.Duplicates,
sectionVisibility: null
};
describe('SubmissionSectionDuplicatesComponent test suite', () => {
let comp: SubmissionSectionDuplicatesComponent;
let compAsAny: any;
let fixture: ComponentFixture<SubmissionSectionDuplicatesComponent>;
let submissionServiceStub: any = new SubmissionServiceStub();
const sectionsServiceStub: any = new SectionsServiceStub();
let formService: any;
let formOperationsService: any;
let formBuilderService: any;
let collectionDataService: any;
const submissionId = mockSubmissionId;
const collectionId = mockSubmissionCollectionId;
const jsonPatchOpBuilder: any = jasmine.createSpyObj('jsonPatchOpBuilder', {
add: jasmine.createSpy('add'),
replace: jasmine.createSpy('replace'),
remove: jasmine.createSpy('remove'),
});
const licenseText = 'License text';
const mockCollection = Object.assign(new Collection(), {
name: 'Community 1-Collection 1',
id: collectionId,
metadata: [
{
key: 'dc.title',
language: 'en_US',
value: 'Community 1-Collection 1'
}],
license: createSuccessfulRemoteDataObject$(Object.assign(new License(), { text: licenseText }))
});
const paginationService = new PaginationServiceStub();
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [
BrowserModule,
CommonModule,
FormsModule,
ReactiveFormsModule,
NgxPaginationModule,
NoopAnimationsModule,
TranslateModule.forRoot(),
],
declarations: [
SubmissionSectionDuplicatesComponent,
TestComponent,
ObjNgFor,
VarDirective,
],
providers: [
{ provide: CollectionDataService, useValue: getMockCollectionDataService() },
{ provide: SectionFormOperationsService, useValue: getMockFormOperationsService() },
{ provide: FormService, useValue: getMockFormService() },
{ provide: JsonPatchOperationsBuilder, useValue: jsonPatchOpBuilder },
{ provide: SubmissionFormsConfigDataService, useValue: getMockSubmissionFormsConfigService() },
{ provide: NotificationsService, useClass: NotificationsServiceStub },
{ provide: SectionsService, useClass: SectionsServiceStub },
{ provide: SubmissionService, useClass: SubmissionServiceStub },
{ provide: 'collectionIdProvider', useValue: collectionId },
{ provide: 'sectionDataProvider', useValue: sectionObject },
{ provide: 'submissionIdProvider', useValue: submissionId },
{ provide: PaginationService, useValue: paginationService },
ChangeDetectorRef,
FormBuilderService,
SubmissionSectionDuplicatesComponent
],
schemas: [NO_ERRORS_SCHEMA]
}).compileComponents().then();
}));
// First test to check the correct component creation
describe('', () => {
let testComp: TestComponent;
let testFixture: ComponentFixture<TestComponent>;
// synchronous beforeEach
beforeEach(() => {
sectionsServiceStub.isSectionReadOnly.and.returnValue(observableOf(false));
sectionsServiceStub.getSectionErrors.and.returnValue(observableOf([]));
sectionsServiceStub.getSectionData.and.returnValue(observableOf(sectionObject));
const html = `<ds-submission-section-duplicates></ds-submission-section-duplicates>`;
testFixture = createTestComponent(html, TestComponent) as ComponentFixture<TestComponent>;
testComp = testFixture.componentInstance;
});
afterEach(() => {
testFixture.destroy();
});
it('should create SubmissionSectionDuplicatesComponent', () => {
expect(testComp).toBeDefined();
});
});
describe('', () => {
beforeEach(() => {
fixture = TestBed.createComponent(SubmissionSectionDuplicatesComponent);
comp = fixture.componentInstance;
compAsAny = comp;
submissionServiceStub = TestBed.inject(SubmissionService);
formService = TestBed.inject(FormService);
formBuilderService = TestBed.inject(FormBuilderService);
formOperationsService = TestBed.inject(SectionFormOperationsService);
collectionDataService = TestBed.inject(CollectionDataService);
compAsAny.pathCombiner = new JsonPatchOperationPathCombiner('sections', sectionObject.id);
});
afterEach(() => {
fixture.destroy();
comp = null;
compAsAny = null;
});
// Test initialisation of the submission section
it('Should init section properly', () => {
collectionDataService.findById.and.returnValue(createSuccessfulRemoteDataObject$(mockCollection));
sectionsServiceStub.getSectionErrors.and.returnValue(observableOf([]));
sectionsServiceStub.isSectionReadOnly.and.returnValue(observableOf(false));
compAsAny.submissionService.getSubmissionScope.and.returnValue(SubmissionScopeType.WorkspaceItem);
spyOn(comp, 'getSectionStatus').and.returnValue(observableOf(true));
spyOn(comp, 'getDuplicateData').and.returnValue(observableOf(potentialDuplicates));
expect(comp.isLoading).toBeTruthy();
comp.onSectionInit();
fixture.detectChanges();
expect(comp.isLoading).toBeFalsy();
});
// The following tests look for proper logic in the getSectionStatus() implementation
// These are very simple as we don't really have a 'false' state unless we're still loading
it('Should return TRUE if the isLoading is FALSE', () => {
compAsAny.isLoading = false;
expect(compAsAny.getSectionStatus()).toBeObservable(cold('(a|)', {
a: true
}));
});
it('Should return FALSE', () => {
compAsAny.isLoadin = true;
expect(compAsAny.getSectionStatus()).toBeObservable(cold('(a|)', {
a: false
}));
});
});
});
// declare a test component
@Component({
selector: 'ds-test-cmp',
template: ``
})
class TestComponent {
}

View File

@@ -9,12 +9,12 @@ import { SectionDataObject } from '../models/section-data.model';
import { SubmissionService } from '../../submission.service';
import { AlertType } from '../../../shared/alert/alert-type';
import { SectionsService } from '../sections.service';
import {map} from "rxjs/operators";
import {ItemDataService} from "../../../core/data/item-data.service";
import {
WorkspaceitemSectionDuplicatesObject
} from "../../../core/submission/models/workspaceitem-section-duplicates.model";
import {Metadata} from "../../../core/shared/metadata.utils";
import {URLCombiner} from "../../../core/url-combiner/url-combiner";
import {getItemModuleRoute} from "../../../item-page/item-page-routing-paths";
/**
* Detect duplicates step
@@ -47,19 +47,12 @@ export class SubmissionSectionDuplicatesComponent extends SectionModelComponent
*/
protected subs: Subscription[] = [];
/**
* Section data observable
*/
public data$: Observable<WorkspaceitemSectionDuplicatesObject>;
/**
* Initialize instance variables.
*
* @param {TranslateService} translate
* @param {SectionsService} sectionService
* @param {SubmissionService} submissionService
* @param itemDataService
* @param nameService
* @param {string} injectedCollectionId
* @param {SectionDataObject} injectedSectionData
* @param {string} injectedSubmissionId
@@ -67,8 +60,6 @@ export class SubmissionSectionDuplicatesComponent extends SectionModelComponent
constructor(protected translate: TranslateService,
protected sectionService: SectionsService,
protected submissionService: SubmissionService,
private itemDataService: ItemDataService,
// private nameService: DSONameService,
@Inject('collectionIdProvider') public injectedCollectionId: string,
@Inject('sectionDataProvider') public injectedSectionData: SectionDataObject,
@Inject('submissionIdProvider') public injectedSubmissionId: string) {
@@ -84,13 +75,7 @@ export class SubmissionSectionDuplicatesComponent extends SectionModelComponent
*/
onSectionInit() {
this.isLoading = false;
this.data$ = this.getDuplicateData().pipe(
map((data: WorkspaceitemSectionDuplicatesObject) => {
console.dir(data);
return data;
})
);
}
}
/**
* Check if identifier section has read-only visibility
@@ -123,5 +108,9 @@ export class SubmissionSectionDuplicatesComponent extends SectionModelComponent
Observable<WorkspaceitemSectionDuplicatesObject>;
}
public getItemLink(uuid: any) {
return new URLCombiner(getItemModuleRoute(), uuid).toString();
}
protected readonly Metadata = Metadata;
}