Skip to content

Commit ea230a2

Browse files
committed
Merge branch 'main' into tender_qa_fixing
2 parents 34f2064 + cee311c commit ea230a2

8 files changed

Lines changed: 633 additions & 150 deletions

File tree

src/app/pages/seller-offerings/offerings/seller-product-spec/create-product-spec/create-product-spec.component.html

Lines changed: 29 additions & 25 deletions
Large diffs are not rendered by default.

src/app/pages/seller-offerings/offerings/seller-product-spec/create-product-spec/create-product-spec.component.spec.ts

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,18 +136,40 @@ describe('CreateProductSpecComponent', () => {
136136

137137
it('ngOnInit should configure steps with bundle enabled', () => {
138138
component.BUNDLE_ENABLED = true;
139+
component.DATA_SPACE_ENABLED = false;
139140
const initSpy = spyOn(component, 'initPartyInfo');
140141
component.ngOnInit();
141142
expect(component.steps.length).toBe(9);
142143
expect(component.steps).toContain('Bundle');
144+
expect(component.steps).not.toContain('Dataspace Configuration');
143145
expect(initSpy).toHaveBeenCalled();
144146
});
145147

146148
it('ngOnInit should configure steps without bundle', () => {
147149
component.BUNDLE_ENABLED = false;
150+
component.DATA_SPACE_ENABLED = false;
148151
component.ngOnInit();
149152
expect(component.steps.length).toBe(8);
150153
expect(component.steps).not.toContain('Bundle');
154+
expect(component.steps).not.toContain('Dataspace Configuration');
155+
});
156+
157+
it('ngOnInit should configure steps with dataspace enabled and bundle enabled', () => {
158+
component.BUNDLE_ENABLED = true;
159+
component.DATA_SPACE_ENABLED = true;
160+
component.ngOnInit();
161+
expect(component.steps.length).toBe(10);
162+
expect(component.steps).toContain('Bundle');
163+
expect(component.steps).toContain('Dataspace Configuration');
164+
});
165+
166+
it('ngOnInit should configure steps with dataspace enabled and no bundle', () => {
167+
component.BUNDLE_ENABLED = false;
168+
component.DATA_SPACE_ENABLED = true;
169+
component.ngOnInit();
170+
expect(component.steps.length).toBe(9);
171+
expect(component.steps).not.toContain('Bundle');
172+
expect(component.steps).toContain('Dataspace Configuration');
151173
});
152174

153175
it('initPartyInfo should set partyId when logged directly', () => {
@@ -643,6 +665,36 @@ describe('CreateProductSpecComponent', () => {
643665
expect(component.creatingChars).toEqual([]);
644666
});
645667

668+
it('refreshChars should use dataspace default type in dataspace step', () => {
669+
component.BUNDLE_ENABLED = false;
670+
component.DATA_SPACE_ENABLED = true;
671+
component.ngOnInit();
672+
component.currentStep = 3;
673+
component.charTypeSelected = 'number';
674+
675+
component.refreshChars();
676+
677+
expect(component.charTypeSelected).toBe('endpointUrl');
678+
});
679+
680+
it('getFilteredCharacteristicsForCurrentStep should split default and dataspace characteristics', () => {
681+
component.BUNDLE_ENABLED = false;
682+
component.DATA_SPACE_ENABLED = true;
683+
component.ngOnInit();
684+
component.prodChars = [
685+
{ id: '1', name: 'Latency', valueType: 'string' },
686+
{ id: '2', name: 'Compliance: ISO 27001', valueType: 'string' },
687+
{ id: '3', name: 'DCP endpoint', valueType: 'endpointUrl' },
688+
{ id: '4', name: 'Policy', valueType: 'authorizationPolicy' }
689+
] as any;
690+
691+
component.currentStep = 2;
692+
expect(component.getFilteredCharacteristicsForCurrentStep().map(char => char.name)).toEqual(['Latency']);
693+
694+
component.currentStep = 3;
695+
expect(component.getFilteredCharacteristicsForCurrentStep().map(char => char.name)).toEqual(['DCP endpoint', 'Policy']);
696+
});
697+
646698
it('removeClass and addClass should update className', () => {
647699
const elem = { className: 'a b c' } as HTMLElement;
648700
component.removeClass(elem, 'b');
@@ -737,6 +789,17 @@ describe('CreateProductSpecComponent', () => {
737789
expect(component.creatingChars[1].isDefault).toBeFalse();
738790
});
739791

792+
it('addCharValue should treat endpointUrl as text type', () => {
793+
component.charTypeSelected = 'endpointUrl';
794+
component.stringValue = 'https://example.org/api/dsp/2025-1';
795+
796+
component.addCharValue();
797+
798+
expect(component.creatingChars.length).toBe(1);
799+
expect(component.creatingChars[0].value as any).toBe('https://example.org/api/dsp/2025-1');
800+
expect(component.stringValue).toBe('');
801+
});
802+
740803
it('addCharValue should add number values with units', () => {
741804
component.charTypeSelected = 'number';
742805
component.numberValue = '100';
@@ -822,6 +885,20 @@ describe('CreateProductSpecComponent', () => {
822885
expect(component.creatingChars).toEqual([]);
823886
});
824887

888+
it('addCharValue should parse and add JSON values for targetSpecification', () => {
889+
component.charTypeSelected = 'targetSpecification';
890+
component.jsonValue = '{"@type":"AssetCollection","refinement":[]}';
891+
892+
component.addCharValue();
893+
894+
expect(component.creatingChars.length).toBe(1);
895+
expect(component.creatingChars[0].isDefault).toBeTrue();
896+
expect(component.creatingChars[0].value as any).toEqual({
897+
'@type': 'AssetCollection',
898+
refinement: []
899+
});
900+
});
901+
825902
it('removeCharValue and selectDefaultChar should manage created char values', () => {
826903
component.creatingChars = [
827904
{ isDefault: true, value: 'A' } as any,
@@ -911,6 +988,31 @@ describe('CreateProductSpecComponent', () => {
911988
expect((component.prodChars[0] as any)['@schemaLocation']).toContain('policyCharacteristic.json');
912989
});
913990

991+
it('saveChar should persist serviceConfiguration valueType without schema location', () => {
992+
component.charTypeSelected = 'serviceConfiguration';
993+
component.charsForm.patchValue({ name: 'Service Configuration', description: 'desc' });
994+
component.creatingChars = [{ isDefault: true, value: { defaultOidcScope: 'openid' } } as any];
995+
component.isOptional = true;
996+
997+
component.saveChar();
998+
999+
expect(component.prodChars.length).toBe(1);
1000+
expect((component.prodChars[0] as any).valueType).toBe('serviceConfiguration');
1001+
expect((component.prodChars[0] as any)['@schemaLocation']).toBeUndefined();
1002+
expect(component.prodChars.find(char => char.name === 'Service Configuration - enabled')).toBeUndefined();
1003+
});
1004+
1005+
it('saveChar should persist endpointUrl valueType', () => {
1006+
component.charTypeSelected = 'endpointUrl';
1007+
component.charsForm.patchValue({ name: 'DCP Endpoint', description: 'desc' });
1008+
component.creatingChars = [{ isDefault: true, value: 'https://example.org/api' } as any];
1009+
1010+
component.saveChar();
1011+
1012+
expect(component.prodChars.length).toBe(1);
1013+
expect((component.prodChars[0] as any).valueType).toBe('endpointUrl');
1014+
});
1015+
9141016
it('deleteChar should remove characteristic and its related enabled one', () => {
9151017
const detectSpy = spyOn((component as any).cdr, 'detectChanges');
9161018
component.prodChars = [
@@ -1002,6 +1104,36 @@ describe('CreateProductSpecComponent', () => {
10021104
expect(component.productSpecToCreate?.productSpecCharacteristic?.some((c: any) => c.name === 'B')).toBeTrue();
10031105
});
10041106

1107+
it('showFinish should include self attestation even when it is not in prodChars', () => {
1108+
component.partyId = 'party-1';
1109+
component.generalForm.patchValue({
1110+
name: 'My Product',
1111+
description: 'Desc',
1112+
version: '1.0',
1113+
brand: 'Brand',
1114+
number: 'PN-1'
1115+
});
1116+
component.selectedISOS = [];
1117+
component.additionalISOS = [];
1118+
component.prodRelationships = [];
1119+
component.prodAttachments = [];
1120+
component.selectedResourceSpecs = [];
1121+
component.selectedServiceSpecs = [];
1122+
component.prodChars = [{ id: 'char-1', name: 'Feature', productSpecCharacteristicValue: [{ value: 'x' }] } as any];
1123+
component.selfAtt = {
1124+
id: 'self-att-1',
1125+
name: 'Compliance:SelfAtt',
1126+
productSpecCharacteristicValue: [{ isDefault: true, value: 'https://self-att' }]
1127+
};
1128+
1129+
component.showFinish();
1130+
1131+
const selfAtt = component.productSpecToCreate?.productSpecCharacteristic?.find((c: any) => c.name === 'Compliance:SelfAtt');
1132+
const selfAttValue = (selfAtt as any)?.productSpecCharacteristicValue?.[0]?.value;
1133+
expect(selfAtt).toBeDefined();
1134+
expect(selfAttValue).toBe('https://self-att');
1135+
});
1136+
10051137
it('createProduct should call API and go back on success', () => {
10061138
const backSpy = spyOn(component, 'goBack');
10071139
component.productSpecToCreate = { name: 'Prod' } as any;

0 commit comments

Comments
 (0)