diff --git a/projects/common/services/sanitization.service.spec.ts b/projects/common/services/sanitization.service.spec.ts index 913a18f2e54efd4c15496029554bfa7580578d36..5a2905e983699368bbdab89d52b56ddf95b88ca8 100644 --- a/projects/common/services/sanitization.service.spec.ts +++ b/projects/common/services/sanitization.service.spec.ts @@ -1,6 +1,4 @@ import { TestBed } from '@angular/core/testing'; -import { SanitizationService } from './sanitization.service'; -import packageJSON from '../../../package.json'; import * as sampleUnit100 from 'test-data/unit-definitions/test100.json'; import * as sampleUnit126 from 'test-data/unit-definitions/test126.json'; import * as sampleUnit129 from 'test-data/unit-definitions/test129.json'; @@ -12,6 +10,8 @@ import * as sampleUnit112TextFields from 'test-data/unit-definitions/test112-Tex import * as sampleUnit130TextFields from 'test-data/unit-definitions/test130-textfields.json'; import { Unit } from 'common/models/unit'; import { ClozeElement } from 'common/models/elements/compound-elements/cloze/cloze'; +import { SanitizationService } from './sanitization.service'; +import packageJSON from '../../../package.json'; describe('SanitizationService', () => { let service: SanitizationService; @@ -26,27 +26,27 @@ describe('SanitizationService', () => { it('isUnitDefinitionOutdated should return false on current version', () => { const basicUnitDefinition: Partial<Unit> = { - 'type': 'aspect-unit-definition', - 'version': packageJSON.config.unit_definition_version, - 'pages': [] + type: 'aspect-unit-definition', + version: packageJSON.config.unit_definition_version, + pages: [] }; expect(SanitizationService.isUnitDefinitionOutdated(basicUnitDefinition)).toBe(false); }); it('isUnitDefinitionOutdated should return true on older version', () => { const unitDefinition: Partial<Unit> = { - 'type': 'aspect-unit-definition', - 'version': '3.3.0', - 'pages': [] + type: 'aspect-unit-definition', + version: '3.3.0', + pages: [] }; expect(SanitizationService.isUnitDefinitionOutdated(unitDefinition)).toBe(true); }); it('sanitizeUnitDefinition should return basic unit definition', () => { const basicUnitDefinition: Partial<Unit> = { - 'type': 'aspect-unit-definition', - 'version': packageJSON.config.unit_definition_version, - 'pages': [] + type: 'aspect-unit-definition', + version: packageJSON.config.unit_definition_version, + pages: [] }; expect(service.sanitizeUnitDefinition(basicUnitDefinition)).toEqual(basicUnitDefinition); }); @@ -54,21 +54,21 @@ describe('SanitizationService', () => { it('sanitizeUnitDefinition should return position', () => { const testData130 = JSON.parse(JSON.stringify(sampleUnit130)); const expectedPositionProps = { - 'position': { - 'fixedSize': false, - 'dynamicPositioning': true, - 'xPosition': 0, - 'yPosition': 0, - 'useMinHeight': false, - 'gridColumn': 1, - 'gridColumnRange': 1, - 'gridRow': 1, - 'gridRowRange': 1, - 'marginLeft': 0, - 'marginRight': 0, - 'marginTop': 0, - 'marginBottom': 0, - 'zIndex': 0 + position: { + fixedSize: false, + dynamicPositioning: true, + xPosition: 0, + yPosition: 0, + useMinHeight: false, + gridColumn: 1, + gridColumnRange: 1, + gridRow: 1, + gridRowRange: 1, + marginLeft: 0, + marginRight: 0, + marginTop: 0, + marginBottom: 0, + zIndex: 0 } }; expect(service.sanitizeUnitDefinition(testData130).pages![0].sections[0].elements[0]) @@ -77,12 +77,12 @@ describe('SanitizationService', () => { it('sanitizeUnitDefinition should repair positionProps', () => { const expectedPositionProps = { - 'xPosition': 0, - 'yPosition': 0, - 'gridColumn': 1, - 'gridColumnRange': 1, - 'gridRow': 1, - 'gridRowRange': 1 + xPosition: 0, + yPosition: 0, + gridColumn: 1, + gridColumnRange: 1, + gridRow: 1, + gridRowRange: 1 }; const sanitizedUnit126 = service.sanitizeUnitDefinition(JSON.parse(JSON.stringify(sampleUnit126))); expect(Object.keys(sanitizedUnit126.pages![0].sections[0].elements[0])) @@ -94,12 +94,12 @@ describe('SanitizationService', () => { // very old stuff it('sanitizeUnitDefinition should repair position properties outside sub-elements', () => { const expectedPositionProps = { - 'xPosition': 420, - 'yPosition': 69, - 'gridColumn': 2, - 'gridColumnRange': 2, - 'gridRow': 3, - 'gridRowRange': 1 + xPosition: 420, + yPosition: 69, + gridColumn: 2, + gridColumnRange: 2, + gridRow: 3, + gridRowRange: 1 }; const sanitizedUnit100 = service.sanitizeUnitDefinition(JSON.parse(JSON.stringify(sampleUnit100))); expect(Object.keys(sanitizedUnit100.pages![0].sections[0].elements[0])) @@ -115,27 +115,27 @@ describe('SanitizationService', () => { const sanitizedUnit = service.sanitizeUnitDefinition(JSON.parse(JSON.stringify(unit))); expect(sanitizedUnit.pages![0].sections[0].elements[0].position) .toEqual(jasmine.objectContaining({ - 'dynamicPositioning': true + dynamicPositioning: true })); // no change necessary const sanitizedUnit129 = service.sanitizeUnitDefinition(JSON.parse(JSON.stringify(sampleUnit129))); expect(sanitizedUnit129.pages![0].sections[0].elements[0].position) .toEqual(jasmine.objectContaining({ - 'dynamicPositioning': false + dynamicPositioning: false })); }); it('sanitizeUnitDefinition should return styling', () => { const expectedStylingProps = { - 'fontColor': '#000000', - 'font': 'Roboto', - 'fontSize': 20, - 'bold': false, - 'italic': false, - 'underline': false, - 'backgroundColor': 'transparent', - 'lineHeight': 135 + fontColor: '#000000', + font: 'Roboto', + fontSize: 20, + bold: false, + italic: false, + underline: false, + backgroundColor: 'transparent', + lineHeight: 135 }; const sanitizedUnit130 = service.sanitizeUnitDefinition(JSON.parse(JSON.stringify(sampleUnit130))); expect(Object.keys(sanitizedUnit130.pages![0].sections[0].elements[0])) @@ -146,14 +146,14 @@ describe('SanitizationService', () => { it('sanitizeUnitDefinition should repair fontProps and surfaceProps', () => { const expectedStylingProps = { - 'fontColor': '#000000', - 'font': 'Roboto', - 'fontSize': 20, - 'lineHeight': 135, - 'bold': false, - 'italic': false, - 'underline': false, - 'backgroundColor': 'red' + fontColor: '#000000', + font: 'Roboto', + fontSize: 20, + lineHeight: 135, + bold: false, + italic: false, + underline: false, + backgroundColor: 'red' }; const sanitizedUnit126 = service.sanitizeUnitDefinition(JSON.parse(JSON.stringify(sampleUnit126))); expect(Object.keys(sanitizedUnit126.pages![0].sections[0].elements[0])) @@ -166,14 +166,14 @@ describe('SanitizationService', () => { const sanitizedUnit130Audio = service.sanitizeUnitDefinition(JSON.parse(JSON.stringify(sampleUnit130Audio))); const expectedPlayerProps = { - 'autostart': false, - 'autostartDelay': 0, - 'loop': false, - 'startControl': true, - 'pauseControl': false, - 'progressBar': true, - 'interactiveProgressbar': false, - 'volumeControl': true + autostart: false, + autostartDelay: 0, + loop: false, + startControl: true, + pauseControl: false, + progressBar: true, + interactiveProgressbar: false, + volumeControl: true }; expect(Object.keys(sanitizedUnit130Audio.pages![0].sections[0].elements[0])) .toContain('player'); @@ -185,17 +185,17 @@ describe('SanitizationService', () => { const sanitizedUnit126Audio = service.sanitizeUnitDefinition(JSON.parse(JSON.stringify(sampleUnit126Audio))); const expectedPlayerProps = { - 'autostart': false, - 'autostartDelay': 0, - 'loop': false, - 'startControl': true, - 'pauseControl': false, - 'progressBar': true, - 'interactiveProgressbar': false, - 'volumeControl': true, - 'defaultVolume': 0.8, - 'minVolume': 0, - 'muteControl': true + autostart: false, + autostartDelay: 0, + loop: false, + startControl: true, + pauseControl: false, + progressBar: true, + interactiveProgressbar: false, + volumeControl: true, + defaultVolume: 0.8, + minVolume: 0, + muteControl: true }; expect(Object.keys(sanitizedUnit126Audio.pages![0].sections[0].elements[0])) .toContain('player'); @@ -244,21 +244,21 @@ describe('SanitizationService', () => { service.sanitizeUnitDefinition(JSON.parse(JSON.stringify(sampleUnit130TextFields))); expect(sanitizedUnit130TextFields.pages![0].sections[0].elements[0]) .toEqual(jasmine.objectContaining({ - 'inputAssistancePreset': null, - 'inputAssistancePosition': 'floating', - 'restrictedToInputAssistanceChars': false + inputAssistancePreset: null, + inputAssistancePosition: 'floating', + restrictedToInputAssistanceChars: false })); expect(sanitizedUnit130TextFields.pages![0].sections[0].elements[1]) .toEqual(jasmine.objectContaining({ - 'inputAssistancePreset': 'french', - 'inputAssistancePosition': 'floating', - 'restrictedToInputAssistanceChars': true + inputAssistancePreset: 'french', + inputAssistancePosition: 'floating', + restrictedToInputAssistanceChars: true })); expect(sanitizedUnit130TextFields.pages![0].sections[0].elements[2]) .toEqual(jasmine.objectContaining({ - 'inputAssistancePreset': 'numbers', - 'inputAssistancePosition': 'floating', - 'restrictedToInputAssistanceChars': false + inputAssistancePreset: 'numbers', + inputAssistancePosition: 'floating', + restrictedToInputAssistanceChars: false })); }); @@ -268,122 +268,136 @@ describe('SanitizationService', () => { service.sanitizeUnitDefinition(JSON.parse(JSON.stringify(sampleUnit112TextFields))); expect(sanitizedUnit112TextFields.pages![0].sections[0].elements[0]) .toEqual(jasmine.objectContaining({ - 'inputAssistancePreset': null, - 'inputAssistancePosition': 'floating' + inputAssistancePreset: null, + inputAssistancePosition: 'floating' })); expect(sanitizedUnit112TextFields.pages![0].sections[0].elements[0]) .not.toEqual(jasmine.objectContaining({ - 'restrictedToInputAssistanceChars': false + restrictedToInputAssistanceChars: false })); expect(sanitizedUnit112TextFields.pages![0].sections[0].elements[1]) .toEqual(jasmine.objectContaining({ - 'inputAssistancePreset': 'french', - 'inputAssistancePosition': 'right', - 'restrictedToInputAssistanceChars': false + inputAssistancePreset: 'french', + inputAssistancePosition: 'right', + restrictedToInputAssistanceChars: false })); expect(sanitizedUnit112TextFields.pages![0].sections[0].elements[2]) .toEqual(jasmine.objectContaining({ - 'inputAssistancePreset': 'numbers', - 'inputAssistancePosition': 'floating' + inputAssistancePreset: 'numbers', + inputAssistancePosition: 'floating' })); expect(sanitizedUnit112TextFields.pages![0].sections[0].elements[2]) .not.toEqual(jasmine.objectContaining({ - 'restrictedToInputAssistanceChars': false + restrictedToInputAssistanceChars: false })); // text areas expect(sanitizedUnit112TextFields.pages![0].sections[0].elements[3]) .toEqual(jasmine.objectContaining({ - 'inputAssistancePreset': null, - 'inputAssistancePosition': 'floating' + inputAssistancePreset: null, + inputAssistancePosition: 'floating' })); expect(sanitizedUnit112TextFields.pages![0].sections[0].elements[3]) .not.toEqual(jasmine.objectContaining({ - 'restrictedToInputAssistanceChars': false + restrictedToInputAssistanceChars: false })); expect(sanitizedUnit112TextFields.pages![0].sections[0].elements[4]) .toEqual(jasmine.objectContaining({ - 'inputAssistancePreset': 'french', - 'inputAssistancePosition': 'floating', - 'restrictedToInputAssistanceChars': false + inputAssistancePreset: 'french', + inputAssistancePosition: 'floating', + restrictedToInputAssistanceChars: false })); }); it('should rename cloze children with "simple" affix', () => { const unitDefStub: Record<string, any> = { - 'type': 'aspect-unit-definition', - 'version': '3.4.0', - 'pages': [{ - 'sections': [ + type: 'aspect-unit-definition', + version: '3.4.0', + pages: [{ + sections: [ { - 'elements': [] + elements: [] }] }] }; const unitDef = { ...unitDefStub, - 'pages': [{ - 'sections': [ + pages: [{ + sections: [ { - 'elements': [{ - 'id': 'cloze_1', - 'type': 'cloze', - 'document': { - 'type': 'doc', - 'content': [ + elements: [{ + id: 'cloze_1', + type: 'cloze', + document: { + type: 'doc', + content: [ { - 'type': 'paragraph', - 'content': [ + type: 'paragraph', + content: [ { - 'type': 'TextField', - 'attrs': { - 'model': { - 'id': 'text-field_1', - 'type': 'text-field' } } }, + type: 'TextField', + attrs: { + model: { + id: 'text-field_1', + type: 'text-field' + } + } + }, { - 'type': 'DropList', - 'attrs': { - 'model': { - 'id': 'drop-list_1', - 'type': 'drop-list' } } }, + type: 'DropList', + attrs: { + model: { + id: 'drop-list_1', + type: 'drop-list' + } + } + }, { - 'type': 'ToggleButton', - 'attrs': { - 'model': { - 'id': 'toggle_button_1', - 'type': 'toggle-button' } } }] }] } } - ] }] }] + type: 'ToggleButton', + attrs: { + model: { + id: 'toggle_button_1', + type: 'toggle-button' + } + } + }] + }] + } + } + ] + }] + }] }; const sanitizedUnitDefinition = service.sanitizeUnitDefinition(unitDef as unknown as Unit); expect(sanitizedUnitDefinition.pages![0].sections[0].elements[0]) .toEqual(jasmine.objectContaining({ - 'id': 'cloze_1', - 'type': 'cloze' + id: 'cloze_1', + type: 'cloze' })); const sanatizedClozeChild1 = (sanitizedUnitDefinition.pages![0].sections[0].elements[0] as ClozeElement) .document.content[0].content[0]?.attrs?.model; expect(sanatizedClozeChild1) .toEqual(jasmine.objectContaining({ - 'id': 'text-field_1', - 'type': 'text-field-simple' + id: 'text-field_1', + type: 'text-field-simple' })); const sanatizedClozeChild2 = (sanitizedUnitDefinition.pages![0].sections[0].elements[0] as ClozeElement) .document.content[0].content[1]?.attrs?.model; expect(sanatizedClozeChild2) .toEqual(jasmine.objectContaining({ - 'id': 'drop-list_1', - 'type': 'drop-list-simple' + id: 'drop-list_1', + type: 'drop-list-simple' })); const sanatizedClozeChild3 = (sanitizedUnitDefinition.pages![0].sections[0].elements[0] as ClozeElement) .document.content[0].content[2]?.attrs?.model; expect(sanatizedClozeChild3) .toEqual(jasmine.objectContaining({ - 'id': 'toggle_button_1', - 'type': 'toggle-button' + id: 'toggle_button_1', + type: 'toggle-button' })); }); }); diff --git a/projects/common/services/sanitization.service.ts b/projects/common/services/sanitization.service.ts index 7dc31bf8c4a3690e7cb698cdd8e28f8f05117577..eff170a8a89dd253f3694c206a0d48ced62cbb0a 100644 --- a/projects/common/services/sanitization.service.ts +++ b/projects/common/services/sanitization.service.ts @@ -355,7 +355,7 @@ export class SanitizationService { newElement.value = newValues; } - if ((newElement.value as any)[0]?.stringValue !== undefined) { + if (newElement.value && (newElement.value as any)[0]?.stringValue !== undefined) { type OldDragNDropValueObject = { id: string; stringValue?: string;