Skip to content

Commit c1bddb8

Browse files
authored
Merge pull request #1461 from Cofinity-X/fix/sig-release#1440-upstream-coverage
chore: eclipse-tractusx/sig-release#1440 increase frontend coverage
2 parents d87cdf0 + 4303527 commit c1bddb8

7 files changed

+405
-172
lines changed
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
/********************************************************************************
2+
* Copyright (c) 2025 Contributors to the Eclipse Foundation
3+
*
4+
* See the NOTICE file(s) distributed with this work for additional
5+
* information regarding copyright ownership.
6+
*
7+
* This program and the accompanying materials are made available under the
8+
* terms of the Apache License, Version 2.0 which is available at
9+
* https://www.apache.org/licenses/LICENSE-2.0.
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
* License for the specific language governing permissions and limitations
15+
* under the License.
16+
*
17+
* SPDX-License-Identifier: Apache-2.0
18+
********************************************************************************/
19+
20+
import { AbbreviateNumberPipe } from './abbreviate-number.pipe';
21+
22+
describe('AbbreviateNumberPipe', () => {
23+
let pipe: AbbreviateNumberPipe;
24+
25+
beforeEach(() => {
26+
pipe = new AbbreviateNumberPipe();
27+
});
28+
29+
it('should create an instance', () => {
30+
expect(pipe).toBeTruthy();
31+
});
32+
33+
it('should return undefined for null value', () => {
34+
expect(pipe.transform(null)).toBeUndefined();
35+
});
36+
37+
it('should return undefined for undefined value', () => {
38+
expect(pipe.transform(undefined)).toBeUndefined();
39+
});
40+
41+
it('should return "Out of Range" for numbers greater than 9999999', () => {
42+
expect(pipe.transform('10,000,000')).toBe('Out of Range');
43+
expect(pipe.transform('10000000')).toBe('Out of Range');
44+
});
45+
46+
it('should convert numbers >= 1,000,000 and <= 9,999,999 to abbreviated format', () => {
47+
expect(pipe.transform('1,000,000')).toBe('1.0');
48+
expect(pipe.transform('1500000')).toBe('1.5');
49+
expect(pipe.transform('9,999,999')).toBe('10.0');
50+
});
51+
52+
it('should return original string for numbers less than 1,000,000', () => {
53+
expect(pipe.transform('999,999')).toBe('999,999');
54+
expect(pipe.transform('500000')).toBe('500000');
55+
});
56+
57+
it('should handle value with periods as thousand separators', () => {
58+
expect(pipe.transform('1.000.000')).toBe('1.0');
59+
});
60+
61+
it('should handle mixed comma and period', () => {
62+
expect(pipe.transform('1,000.000')).toBe('1.0');
63+
});
64+
});

frontend/src/app/modules/shared/pipes/format-date.pipe.spec.ts

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/********************************************************************************
22
* Copyright (c) 2022, 2023 Bayerische Motoren Werke Aktiengesellschaft (BMW AG)
33
* Copyright (c) 2022, 2023 ZF Friedrichshafen AG
4-
* Copyright (c) 2022, 2023 Contributors to the Eclipse Foundation
4+
* Copyright (c) 2022, 2025 Contributors to the Eclipse Foundation
55
*
66
* See the NOTICE file(s) distributed with this work for additional
77
* information regarding copyright ownership.
@@ -20,11 +20,17 @@
2020
********************************************************************************/
2121

2222
import { CalendarDateModel } from '@core/model/calendar-date.model';
23+
import { FlattenObjectPipe } from '@shared/pipes/flatten-object.pipe';
2324
import { screen } from '@testing-library/angular';
2425
import { renderComponent } from '@tests/test-render.utils';
2526
import { SharedModule } from '..';
2627

2728
describe('FormatDatePipe', () => {
29+
let pipe: FlattenObjectPipe;
30+
31+
beforeEach(() => {
32+
pipe = new FlattenObjectPipe();
33+
});
2834
it('should format date having the 1970 value for the year', async () => {
2935
const date = new CalendarDateModel(null);
3036
await renderComponent(`{{ date | formatDate }}`, {
@@ -62,4 +68,73 @@ describe('FormatDatePipe', () => {
6268

6369
expect(screen.getByText('--')).toBeInTheDocument();
6470
});
71+
it('should create an instance', () => {
72+
expect(pipe).toBeTruthy();
73+
});
74+
75+
it('should return non-object input as is', () => {
76+
expect(pipe.transform(null)).toBe(null);
77+
expect(pipe.transform(undefined)).toBe(undefined);
78+
expect(pipe.transform(123)).toBe(123);
79+
expect(pipe.transform('test')).toBe('test');
80+
expect(pipe.transform(true)).toBe(true);
81+
});
82+
83+
it('should flatten a simple nested object', () => {
84+
const input = { a: { b: { c: 1 } } };
85+
const result = pipe.transform(input);
86+
expect(result).toEqual({ 'a.b.c': 1 });
87+
});
88+
89+
it('should handle objects with arrays', () => {
90+
const input = { a: [1, 2, 3] };
91+
const result = pipe.transform(input);
92+
expect(result).toEqual({
93+
a: [
94+
{ 'a[0]': 1 },
95+
{ 'a[1]': 2 },
96+
{ 'a[2]': 3 }
97+
]
98+
});
99+
});
100+
101+
it('should preserve "children" and "parents" properties', () => {
102+
const input = {
103+
name: 'node',
104+
children: [{ id: 1 }],
105+
parents: [{ id: 0 }],
106+
details: { type: 'leaf' }
107+
};
108+
const result = pipe.transform(input);
109+
expect(result.children).toEqual([{ id: 1 }]);
110+
expect(result.parents).toEqual([{ id: 0 }]);
111+
expect(result['details.type']).toEqual('leaf');
112+
});
113+
114+
it('should skip undefined properties', () => {
115+
const input = { a: undefined, b: 2 };
116+
const result = pipe.transform(input);
117+
expect(result).toEqual({ 'b': 2 });
118+
});
119+
120+
it('should flatten mixed content correctly', () => {
121+
const input = {
122+
a: 1,
123+
b: {
124+
c: 'text',
125+
d: [true, false],
126+
e: { f: null }
127+
}
128+
};
129+
const result = pipe.transform(input);
130+
expect(result).toEqual({
131+
'a': 1,
132+
'b.c': 'text',
133+
'b.d': [
134+
{ 'b.d[0]': true },
135+
{ 'b.d[1]': false }
136+
],
137+
'b.e.f': null
138+
});
139+
});
65140
});
Lines changed: 88 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/********************************************************************************
2-
* Copyright (c) 2023 Contributors to the Eclipse Foundation
2+
* Copyright (c) 2023, 2025 Contributors to the Eclipse Foundation
33
*
44
* See the NOTICE file(s) distributed with this work for additional
55
* information regarding copyright ownership.
@@ -17,68 +17,101 @@
1717
* SPDX-License-Identifier: Apache-2.0
1818
********************************************************************************/
1919

20-
import { TestBed } from '@angular/core/testing';
20+
21+
import { SemanticDataModelInCamelCase } from '@page/parts/model/parts.model';
2122
import { Pagination } from '@core/model/pagination.model';
22-
import { MainAspectType } from '@page/parts/model/mainAspectType.enum';
23-
import { SemanticDataModel } from '@page/parts/model/parts.model';
24-
import { PartsAssembler } from '@shared/assembler/parts.assembler';
2523
import { FormatPaginationSemanticDataModelToCamelCasePipe } from '@shared/pipes/format-pagination-semantic-data-model-to-camelcase.pipe';
26-
import { MOCK_part_1, MOCK_part_2 } from '../../../mocks/services/parts-mock/partsAsPlanned/partsAsPlanned.test.model';
2724

2825
describe('FormatPaginationSemanticDataModelToCamelCasePipe', () => {
29-
let formatPaginationSemanticDataModelToCamelCasePipe: FormatPaginationSemanticDataModelToCamelCasePipe;
26+
let pipe: FormatPaginationSemanticDataModelToCamelCasePipe;
3027

3128
beforeEach(() => {
32-
TestBed.configureTestingModule({
33-
providers: [
34-
FormatPaginationSemanticDataModelToCamelCasePipe,
29+
pipe = new FormatPaginationSemanticDataModelToCamelCasePipe();
30+
});
31+
32+
it('should create an instance', () => {
33+
expect(pipe).toBeTruthy();
34+
});
35+
36+
it('should transform all known semanticDataModel values to camel case', () => {
37+
const input: Pagination<any> = {
38+
content: [
39+
{ semanticDataModel: 'batch' },
40+
{ semanticDataModel: 'SerialPart' },
41+
{ semanticDataModel: 'partAsPlanned' },
42+
{ semanticDataModel: 'JUSTINSEQUENCE' }
3543
],
36-
});
37-
formatPaginationSemanticDataModelToCamelCasePipe = TestBed.inject(FormatPaginationSemanticDataModelToCamelCasePipe);
44+
page: 0,
45+
pageCount: 1,
46+
pageSize: 10,
47+
totalItems: 4
48+
};
49+
50+
const result = pipe.transform(input);
51+
52+
expect(result.content[0].semanticDataModel).toBe(SemanticDataModelInCamelCase.BATCH);
53+
expect(result.content[1].semanticDataModel).toBe(SemanticDataModelInCamelCase.SERIALPART);
54+
expect(result.content[2].semanticDataModel).toBe(SemanticDataModelInCamelCase.PARTASPLANNED);
55+
expect(result.content[3].semanticDataModel).toBe(SemanticDataModelInCamelCase.JUSTINSEQUENCE);
56+
});
57+
58+
it('should convert unknown semanticDataModel values to UNKNOWN', () => {
59+
const input: Pagination<any> = {
60+
content: [{ semanticDataModel: 'undefinedModel' }],
61+
page: 1,
62+
pageCount: 1,
63+
pageSize: 5,
64+
totalItems: 1
65+
};
66+
67+
const result = pipe.transform(input);
68+
69+
expect(result.content[0].semanticDataModel).toBe(SemanticDataModelInCamelCase.UNKNOWN);
70+
});
71+
72+
it('should preserve non-semanticDataModel properties', () => {
73+
const input: Pagination<any> = {
74+
content: [{ semanticDataModel: 'batch', id: '123', name: 'TestPart' }],
75+
page: 0,
76+
pageCount: 1,
77+
pageSize: 1,
78+
totalItems: 1
79+
};
80+
81+
const result = pipe.transform(input);
82+
83+
expect(result.content[0].id).toBe('123');
84+
expect(result.content[0].name).toBe('TestPart');
85+
expect(result.content[0].semanticDataModel).toBe(SemanticDataModelInCamelCase.BATCH);
3886
});
3987

40-
[
41-
{
42-
option: SemanticDataModel.BATCH,
43-
expected: 'Batch',
44-
},
45-
{
46-
option: SemanticDataModel.SERIALPART,
47-
expected: 'SerialPart',
48-
},
49-
{
50-
option: SemanticDataModel.PARTASPLANNED,
51-
expected: 'PartAsPlanned',
52-
},
53-
].forEach(object => {
54-
55-
it(`should transform semanticDataModel from ${ object.option } to ${ object.expected }`, function() {
56-
57-
let partList = [ PartsAssembler.assemblePart(MOCK_part_1, MainAspectType.AS_BUILT), PartsAssembler.assemblePart(MOCK_part_2, MainAspectType.AS_BUILT) ];
58-
59-
let paginationData: Pagination<any> = {
60-
page: 0,
61-
pageCount: 1,
62-
pageSize: 50,
63-
totalItems: 1,
64-
content: partList,
65-
};
66-
67-
paginationData.content.forEach(part => {
68-
part.semanticDataModel = object.option;
69-
});
70-
71-
partList.map(part => {
72-
expect(part.semanticDataModel).toEqual(object.option);
73-
});
74-
75-
76-
let transformedPartData = formatPaginationSemanticDataModelToCamelCasePipe.transform(paginationData);
77-
78-
transformedPartData.content.map(part => {
79-
expect(part.semanticDataModel).toEqual(object.expected);
80-
});
81-
82-
});
88+
it('should return unchanged pagination metadata', () => {
89+
const input: Pagination<any> = {
90+
content: [{ semanticDataModel: 'serialpart' }],
91+
page: 2,
92+
pageCount: 5,
93+
pageSize: 10,
94+
totalItems: 50
95+
};
96+
97+
const result = pipe.transform(input);
98+
99+
expect(result.page).toBe(2);
100+
expect(result.pageCount).toBe(5);
101+
expect(result.pageSize).toBe(10);
102+
expect(result.totalItems).toBe(50);
103+
});
104+
105+
it('should handle empty content arrays gracefully', () => {
106+
const input: Pagination<any> = {
107+
content: [],
108+
page: 0,
109+
pageCount: 0,
110+
pageSize: 10,
111+
totalItems: 0
112+
};
113+
114+
const result = pipe.transform(input);
115+
expect(result.content).toEqual([]);
83116
});
84117
});

0 commit comments

Comments
 (0)