From f4b8d4fe41753c95db77576fefcc91e0eb1147b5 Mon Sep 17 00:00:00 2001 From: Yura Bondarenko Date: Tue, 15 Feb 2022 11:53:21 +0100 Subject: [PATCH] 87242: Fix forced re-init due to out-of-scope fields --- .../form/section-form.component.spec.ts | 81 ++++++++++++++++++- .../sections/form/section-form.component.ts | 26 +++++- 2 files changed, 103 insertions(+), 4 deletions(-) diff --git a/src/app/submission/sections/form/section-form.component.spec.ts b/src/app/submission/sections/form/section-form.component.spec.ts index 592691e677..9dd3984ea3 100644 --- a/src/app/submission/sections/form/section-form.component.spec.ts +++ b/src/app/submission/sections/form/section-form.component.spec.ts @@ -23,9 +23,7 @@ import { SubmissionFormsConfigService } from '../../../core/config/submission-fo import { SectionDataObject } from '../models/section-data.model'; import { SectionsType } from '../sections-type'; import { - mockSubmissionCollectionId, - mockSubmissionId, - mockUploadResponse1ParsedErrors + mockSubmissionCollectionId, mockSubmissionId, mockUploadResponse1ParsedErrors, } from '../../../shared/mocks/submission.mock'; import { BrowserModule } from '@angular/platform-browser'; import { CommonModule } from '@angular/common'; @@ -45,6 +43,7 @@ import { ObjectCacheService } from '../../../core/cache/object-cache.service'; import { RequestService } from '../../../core/data/request.service'; import { createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils'; import { cold } from 'jasmine-marbles'; +import { WorkflowItem } from '../../../core/submission/models/workflowitem.model'; function getMockSubmissionFormsConfigService(): SubmissionFormsConfigService { return jasmine.createSpyObj('FormOperationsService', { @@ -296,8 +295,10 @@ describe('SubmissionSectionFormComponent test suite', () => { }; compAsAny.formData = {}; compAsAny.sectionMetadata = ['dc.title']; + spyOn(compAsAny, 'inCurrentSubmissionScope').and.callThrough(); expect(comp.hasMetadataEnrichment(newSectionData)).toBeTruthy(); + expect(compAsAny.inCurrentSubmissionScope).toHaveBeenCalledWith('dc.title'); }); it('should return false when has not Metadata Enrichment', () => { @@ -306,7 +307,10 @@ describe('SubmissionSectionFormComponent test suite', () => { }; compAsAny.formData = newSectionData; compAsAny.sectionMetadata = ['dc.title']; + spyOn(compAsAny, 'inCurrentSubmissionScope').and.callThrough(); + expect(comp.hasMetadataEnrichment(newSectionData)).toBeFalsy(); + expect(compAsAny.inCurrentSubmissionScope).toHaveBeenCalledWith('dc.title'); }); it('should return false when metadata has Metadata Enrichment but not belonging to sectionMetadata', () => { @@ -318,6 +322,77 @@ describe('SubmissionSectionFormComponent test suite', () => { expect(comp.hasMetadataEnrichment(newSectionData)).toBeFalsy(); }); + describe('inCurrentSubmissionScope', () => { + beforeEach(() => { + // @ts-ignore + comp.formConfig = { + rows: [ + { + fields: [ + { + selectableMetadata: [{ metadata: 'scoped.workflow' }], + scope: 'WORKFLOW', + } as FormFieldModel + ] + }, + { + fields: [ + { + selectableMetadata: [{ metadata: 'scoped.workspace' }], + scope: 'WORKSPACE', + } as FormFieldModel + ] + }, + { + fields: [ + { + selectableMetadata: [{ metadata: 'dc.title' }], + } as FormFieldModel + ] + } + ] + }; + }); + + describe('in workspace scope', () => { + beforeEach(() => { + // @ts-ignore + comp.workspaceItem = { type: WorkspaceItem.type }; + }); + + it('should return true for unscoped fields', () => { + expect((comp as any).inCurrentSubmissionScope('dc.title')).toBe(true); + }); + + it('should return true for fields scoped to workflow', () => { + expect((comp as any).inCurrentSubmissionScope('scoped.workspace')).toBe(true); + }); + + it('should return false for fields scoped to workspace', () => { + expect((comp as any).inCurrentSubmissionScope('scoped.workflow')).toBe(false); + }); + }); + + describe('in workflow scope', () => { + beforeEach(() => { + // @ts-ignore + comp.workspaceItem = { type: WorkflowItem.type }; + }); + + it('should return true when field is unscoped', () => { + expect((comp as any).inCurrentSubmissionScope('dc.title')).toBe(true); + }); + + it('should return true for fields scoped to workflow', () => { + expect((comp as any).inCurrentSubmissionScope('scoped.workflow')).toBe(true); + }); + + it('should return false for fields scoped to workspace', () => { + expect((comp as any).inCurrentSubmissionScope('scoped.workspace')).toBe(false); + }); + }); + }); + it('should update form properly', () => { spyOn(comp, 'initForm'); spyOn(comp, 'checksForErrors'); diff --git a/src/app/submission/sections/form/section-form.component.ts b/src/app/submission/sections/form/section-form.component.ts index 9d9fe361de..ccb1867fee 100644 --- a/src/app/submission/sections/form/section-form.component.ts +++ b/src/app/submission/sections/form/section-form.component.ts @@ -34,6 +34,8 @@ import { followLink } from '../../../shared/utils/follow-link-config.model'; import { environment } from '../../../../environments/environment'; import { ConfigObject } from '../../../core/config/models/config.model'; import { RemoteData } from '../../../core/data/remote-data'; +import { SubmissionScopeType } from '../../../core/submission/submission-scope-type'; +import { WorkflowItem } from '../../../core/submission/models/workflowitem.model'; /** * This component represents a section that contains a Form. @@ -223,7 +225,7 @@ export class SubmissionSectionFormComponent extends SectionModelComponent { const sectionDataToCheck = {}; Object.keys(sectionData).forEach((key) => { - if (this.sectionMetadata && this.sectionMetadata.includes(key)) { + if (this.sectionMetadata && this.sectionMetadata.includes(key) && this.inCurrentSubmissionScope(key)) { sectionDataToCheck[key] = sectionData[key]; } }); @@ -246,6 +248,28 @@ export class SubmissionSectionFormComponent extends SectionModelComponent { return isNotEmpty(diffResult); } + /** + * Whether a specific field is editable in the current scope. Unscoped fields always return true. + * @private + */ + private inCurrentSubmissionScope(field: string): boolean { + const scope = this.formConfig?.rows.find(row => { + return row.fields?.[0]?.selectableMetadata?.[0]?.metadata === field; + }).fields?.[0]?.scope; + + switch (scope) { + case SubmissionScopeType.WorkspaceItem: { + return this.workspaceItem.type === WorkspaceItem.type; + } + case SubmissionScopeType.WorkflowItem: { + return this.workspaceItem.type === WorkflowItem.type; + } + default: { + return true; + } + } + } + /** * Initialize form model *