@elisra-devops/docgen-data-provider 1.22.0 → 1.23.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/bin/helpers/helper.js.map +1 -1
  2. package/bin/helpers/test/tfs.test.d.ts +1 -0
  3. package/bin/helpers/test/tfs.test.js +613 -0
  4. package/bin/helpers/test/tfs.test.js.map +1 -0
  5. package/bin/helpers/tfs.js +1 -1
  6. package/bin/helpers/tfs.js.map +1 -1
  7. package/bin/modules/GitDataProvider.js.map +1 -1
  8. package/bin/modules/PipelinesDataProvider.js +3 -2
  9. package/bin/modules/PipelinesDataProvider.js.map +1 -1
  10. package/bin/modules/ResultDataProvider.d.ts +199 -17
  11. package/bin/modules/ResultDataProvider.js +611 -195
  12. package/bin/modules/ResultDataProvider.js.map +1 -1
  13. package/bin/modules/TestDataProvider.js +7 -7
  14. package/bin/modules/TestDataProvider.js.map +1 -1
  15. package/bin/modules/TicketsDataProvider.d.ts +1 -1
  16. package/bin/modules/TicketsDataProvider.js +3 -2
  17. package/bin/modules/TicketsDataProvider.js.map +1 -1
  18. package/bin/modules/test/JfrogDataProvider.test.d.ts +1 -0
  19. package/bin/modules/test/JfrogDataProvider.test.js +110 -0
  20. package/bin/modules/test/JfrogDataProvider.test.js.map +1 -0
  21. package/bin/modules/test/ResultDataProvider.test.d.ts +1 -0
  22. package/bin/modules/test/ResultDataProvider.test.js +478 -0
  23. package/bin/modules/test/ResultDataProvider.test.js.map +1 -0
  24. package/bin/modules/test/gitDataProvider.test.js +424 -120
  25. package/bin/modules/test/gitDataProvider.test.js.map +1 -1
  26. package/bin/modules/test/managmentDataProvider.test.js +283 -28
  27. package/bin/modules/test/managmentDataProvider.test.js.map +1 -1
  28. package/bin/modules/test/pipelineDataProvider.test.js +229 -45
  29. package/bin/modules/test/pipelineDataProvider.test.js.map +1 -1
  30. package/bin/modules/test/testDataProvider.test.js +225 -81
  31. package/bin/modules/test/testDataProvider.test.js.map +1 -1
  32. package/bin/modules/test/ticketsDataProvider.test.js +310 -82
  33. package/bin/modules/test/ticketsDataProvider.test.js.map +1 -1
  34. package/package.json +1 -1
  35. package/src/helpers/helper.ts +16 -14
  36. package/src/helpers/test/tfs.test.ts +748 -0
  37. package/src/helpers/tfs.ts +1 -1
  38. package/src/modules/GitDataProvider.ts +10 -10
  39. package/src/modules/PipelinesDataProvider.ts +2 -2
  40. package/src/modules/ResultDataProvider.ts +815 -260
  41. package/src/modules/TestDataProvider.ts +8 -8
  42. package/src/modules/TicketsDataProvider.ts +5 -9
  43. package/src/modules/test/JfrogDataProvider.test.ts +171 -0
  44. package/src/modules/test/ResultDataProvider.test.ts +581 -0
  45. package/src/modules/test/gitDataProvider.test.ts +671 -187
  46. package/src/modules/test/managmentDataProvider.test.ts +386 -26
  47. package/src/modules/test/pipelineDataProvider.test.ts +281 -52
  48. package/src/modules/test/testDataProvider.test.ts +307 -105
  49. package/src/modules/test/ticketsDataProvider.test.ts +425 -129
@@ -0,0 +1,581 @@
1
+ import { TFSServices } from '../../helpers/tfs';
2
+ import ResultDataProvider from '../ResultDataProvider';
3
+ import logger from '../../utils/logger';
4
+ import TestStepParserHelper from '../../utils/testStepParserHelper';
5
+
6
+ // Mock dependencies
7
+ jest.mock('../../helpers/tfs');
8
+ jest.mock('../../utils/logger');
9
+ jest.mock('../../utils/testStepParserHelper');
10
+ jest.mock('p-limit', () => () => (fn: Function) => fn());
11
+
12
+ describe('ResultDataProvider', () => {
13
+ let resultDataProvider: ResultDataProvider;
14
+ const mockOrgUrl = 'https://dev.azure.com/organization/';
15
+ const mockToken = 'mock-token';
16
+ const mockProjectName = 'test-project';
17
+ const mockTestPlanId = '12345';
18
+
19
+ beforeEach(() => {
20
+ jest.clearAllMocks();
21
+ resultDataProvider = new ResultDataProvider(mockOrgUrl, mockToken);
22
+ });
23
+
24
+ describe('Utility methods', () => {
25
+ describe('flattenSuites', () => {
26
+ it('should flatten a hierarchical suite structure into a single-level array', () => {
27
+ // Arrange
28
+ const suites = [
29
+ {
30
+ id: 1,
31
+ name: 'Parent 1',
32
+ children: [
33
+ { id: 2, name: 'Child 1' },
34
+ {
35
+ id: 3,
36
+ name: 'Child 2',
37
+ children: [{ id: 4, name: 'Grandchild 1' }]
38
+ }
39
+ ]
40
+ },
41
+ { id: 5, name: 'Parent 2' }
42
+ ];
43
+
44
+ // Act
45
+ const result: any[] = (resultDataProvider as any).flattenSuites(suites);
46
+
47
+ // Assert
48
+ expect(result).toHaveLength(5);
49
+ expect(result.map(s => s.id)).toEqual([1, 2, 3, 4, 5]);
50
+ });
51
+ });
52
+
53
+ describe('filterSuites', () => {
54
+ it('should filter suites based on selected suite IDs', () => {
55
+ // Arrange
56
+ const testSuites = [
57
+ { id: 1, name: 'Suite 1', parentSuite: { id: 0 } },
58
+ { id: 2, name: 'Suite 2', parentSuite: { id: 1 } },
59
+ { id: 3, name: 'Suite 3', parentSuite: { id: 1 } }
60
+ ];
61
+ const selectedSuiteIds = [1, 3];
62
+
63
+ // Act
64
+ const result: any[] = (resultDataProvider as any).filterSuites(testSuites, selectedSuiteIds);
65
+
66
+ // Assert
67
+ expect(result).toHaveLength(2);
68
+ expect(result.map(s => s.id)).toEqual([1, 3]);
69
+ });
70
+
71
+ it('should return all suites with parent when no suite IDs are selected', () => {
72
+ // Arrange
73
+ const testSuites = [
74
+ { id: 1, name: 'Suite 1', parentSuite: { id: 0 } },
75
+ { id: 2, name: 'Suite 2', parentSuite: { id: 1 } },
76
+ { id: 3, name: 'Suite 3', parentSuite: null }
77
+ ];
78
+
79
+ // Act
80
+ const result: any[] = (resultDataProvider as any).filterSuites(testSuites);
81
+
82
+ // Assert
83
+ expect(result).toHaveLength(2);
84
+ expect(result.map(s => s.id)).toEqual([1, 2]);
85
+ });
86
+ });
87
+
88
+ describe('buildTestGroupName', () => {
89
+ it('should return simple suite name when hierarchy is disabled', () => {
90
+ // Arrange
91
+ const suiteMap = new Map([
92
+ [1, { id: 1, name: 'Suite 1', parentSuite: { id: 0 } }]
93
+ ]);
94
+
95
+ // Act
96
+ const result = (resultDataProvider as any).buildTestGroupName(1, suiteMap, false);
97
+
98
+ // Assert
99
+ expect(result).toBe('Suite 1');
100
+ });
101
+
102
+ it('should build hierarchical name with parent info', () => {
103
+ // Arrange
104
+ const suiteMap = new Map([
105
+ [1, { id: 1, name: 'Parent', parentSuite: null }],
106
+ [2, { id: 2, name: 'Child', parentSuite: { id: 1 } }]
107
+ ]);
108
+
109
+ // Act
110
+ const result = (resultDataProvider as any).buildTestGroupName(2, suiteMap, true);
111
+
112
+ // Assert
113
+ expect(result).toBe('Child');
114
+ });
115
+
116
+ it('should abbreviate deep hierarchies', () => {
117
+ // Arrange
118
+ const suiteMap = new Map([
119
+ [1, { id: 1, name: 'Root', parentSuite: null }],
120
+ [2, { id: 2, name: 'Level1', parentSuite: { id: 1 } }],
121
+ [3, { id: 3, name: 'Level2', parentSuite: { id: 2 } }],
122
+ [4, { id: 4, name: 'Level3', parentSuite: { id: 3 } }]
123
+ ]);
124
+
125
+ // Act
126
+ const result = (resultDataProvider as any).buildTestGroupName(4, suiteMap, true);
127
+
128
+ // Assert
129
+ expect(result).toBe('Level1/.../Level3');
130
+ });
131
+ });
132
+
133
+ describe('convertRunStatus', () => {
134
+ it('should convert API status to readable format', () => {
135
+ // Arrange & Act & Assert
136
+ expect((resultDataProvider as any).convertRunStatus('passed')).toBe('Passed');
137
+ expect((resultDataProvider as any).convertRunStatus('failed')).toBe('Failed');
138
+ expect((resultDataProvider as any).convertRunStatus('notApplicable')).toBe('Not Applicable');
139
+ expect((resultDataProvider as any).convertRunStatus('unknown')).toBe('Not Run');
140
+ });
141
+ });
142
+
143
+ describe('setRunStatus', () => {
144
+ it('should return empty for shared step titles with Unspecified outcome', () => {
145
+ // Arrange
146
+ const actionResult = { outcome: 'Unspecified', isSharedStepTitle: true };
147
+
148
+ // Act
149
+ const result = (resultDataProvider as any).setRunStatus(actionResult);
150
+
151
+ // Assert
152
+ expect(result).toBe('');
153
+ });
154
+
155
+ it('should return "Not Run" for Unspecified outcome on regular steps', () => {
156
+ // Arrange
157
+ const actionResult = { outcome: 'Unspecified', isSharedStepTitle: false };
158
+
159
+ // Act
160
+ const result = (resultDataProvider as any).setRunStatus(actionResult);
161
+
162
+ // Assert
163
+ expect(result).toBe('Not Run');
164
+ });
165
+
166
+ it('should return the outcome for non-Unspecified outcomes', () => {
167
+ // Arrange
168
+ const actionResult = { outcome: 'Failed', isSharedStepTitle: false };
169
+
170
+ // Act
171
+ const result = (resultDataProvider as any).setRunStatus(actionResult);
172
+
173
+ // Assert
174
+ expect(result).toBe('Failed');
175
+ });
176
+ });
177
+
178
+ describe('compareActionResults', () => {
179
+ it('should compare version-like step positions correctly', () => {
180
+ // Act & Assert
181
+ const compare = (resultDataProvider as any).compareActionResults;
182
+ expect(compare('1', '2')).toBe(-1);
183
+ expect(compare('2', '1')).toBe(1);
184
+ expect(compare('1.1', '1.2')).toBe(-1);
185
+ expect(compare('1.2', '1.1')).toBe(1);
186
+ expect(compare('1.1', '1.1')).toBe(0);
187
+ expect(compare('1.1.1', '1.1')).toBe(1);
188
+ expect(compare('1.1', '1.1.1')).toBe(-1);
189
+ });
190
+ });
191
+ });
192
+
193
+ describe('Data fetching methods', () => {
194
+ describe('fetchTestSuites', () => {
195
+ it('should fetch and process test suites correctly', async () => {
196
+ // Arrange
197
+ const mockTestSuites = {
198
+ value: [
199
+ {
200
+ id: 1,
201
+ name: 'Root Suite',
202
+ children: [
203
+ { id: 2, name: 'Child Suite 1', parentSuite: { id: 1 } }
204
+ ]
205
+ }
206
+ ],
207
+ count: 1
208
+ };
209
+
210
+ (TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockTestSuites);
211
+
212
+ // Act
213
+ const result = await (resultDataProvider as any).fetchTestSuites(
214
+ mockTestPlanId,
215
+ mockProjectName
216
+ );
217
+
218
+ // Assert
219
+ expect(TFSServices.getItemContent).toHaveBeenCalledWith(
220
+ `${mockOrgUrl}${mockProjectName}/_apis/testplan/Plans/${mockTestPlanId}/Suites?asTreeView=true`,
221
+ mockToken
222
+ );
223
+ expect(result).toHaveLength(1);
224
+ expect(result[0]).toHaveProperty('testSuiteId', 2);
225
+ expect(result[0]).toHaveProperty('testGroupName');
226
+ });
227
+
228
+ it('should handle errors and return empty array', async () => {
229
+ // Arrange
230
+ const mockError = new Error('API error');
231
+ (TFSServices.getItemContent as jest.Mock).mockRejectedValueOnce(mockError);
232
+
233
+ // Act
234
+ const result = await (resultDataProvider as any).fetchTestSuites(
235
+ mockTestPlanId,
236
+ mockProjectName
237
+ );
238
+
239
+ // Assert
240
+ expect(logger.error).toHaveBeenCalled();
241
+ expect(result).toEqual([]);
242
+ });
243
+ });
244
+
245
+ describe('fetchTestPoints', () => {
246
+ it('should fetch and map test points correctly', async () => {
247
+ // Arrange
248
+ const mockSuiteId = '123';
249
+ const mockTestPoints = {
250
+ value: [
251
+ {
252
+ testCaseReference: { id: 1, name: 'Test Case 1' },
253
+ configuration: { name: 'Config 1' },
254
+ results: {
255
+ outcome: 'passed',
256
+ lastTestRunId: 100,
257
+ lastResultId: 200,
258
+ lastResultDetails: { dateCompleted: '2023-01-01', runBy: { displayName: 'Test User' } }
259
+ }
260
+ }
261
+ ],
262
+ count: 1
263
+ };
264
+
265
+ (TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockTestPoints);
266
+
267
+ // Act
268
+ const result = await (resultDataProvider as any).fetchTestPoints(
269
+ mockProjectName,
270
+ mockTestPlanId,
271
+ mockSuiteId
272
+ );
273
+
274
+ // Assert
275
+ expect(TFSServices.getItemContent).toHaveBeenCalledWith(
276
+ `${mockOrgUrl}${mockProjectName}/_apis/testplan/Plans/${mockTestPlanId}/Suites/${mockSuiteId}/TestPoint?includePointDetails=true`,
277
+ mockToken
278
+ );
279
+ expect(result).toHaveLength(1);
280
+ expect(result[0]).toEqual({
281
+ testCaseId: 1,
282
+ testCaseName: 'Test Case 1',
283
+ configurationName: 'Config 1',
284
+ outcome: 'passed',
285
+ lastRunId: 100,
286
+ lastResultId: 200,
287
+ lastResultDetails: { dateCompleted: '2023-01-01', runBy: { displayName: 'Test User' } }
288
+ });
289
+ });
290
+
291
+ it('should handle errors and return empty array', async () => {
292
+ // Arrange
293
+ const mockSuiteId = '123';
294
+ const mockError = new Error('API error');
295
+ (TFSServices.getItemContent as jest.Mock).mockRejectedValueOnce(mockError);
296
+
297
+ // Act
298
+ const result = await (resultDataProvider as any).fetchTestPoints(
299
+ mockProjectName,
300
+ mockTestPlanId,
301
+ mockSuiteId
302
+ );
303
+
304
+ // Assert
305
+ expect(logger.error).toHaveBeenCalled();
306
+ expect(result).toEqual([]);
307
+ });
308
+ });
309
+ });
310
+
311
+ describe('Data transformation methods', () => {
312
+ describe('mapTestPoint', () => {
313
+ it('should transform test point data correctly', () => {
314
+ // Arrange
315
+ const testPoint = {
316
+ testCaseReference: { id: 1, name: 'Test Case 1' },
317
+ configuration: { name: 'Config 1' },
318
+ results: {
319
+ outcome: 'passed',
320
+ lastTestRunId: 100,
321
+ lastResultId: 200,
322
+ lastResultDetails: { dateCompleted: '2023-01-01', runBy: { displayName: 'Test User' } }
323
+ }
324
+ };
325
+
326
+ // Act
327
+ const result = (resultDataProvider as any).mapTestPoint(testPoint);
328
+
329
+ // Assert
330
+ expect(result).toEqual({
331
+ testCaseId: 1,
332
+ testCaseName: 'Test Case 1',
333
+ configurationName: 'Config 1',
334
+ outcome: 'passed',
335
+ lastRunId: 100,
336
+ lastResultId: 200,
337
+ lastResultDetails: { dateCompleted: '2023-01-01', runBy: { displayName: 'Test User' } }
338
+ });
339
+ });
340
+
341
+ it('should handle missing fields', () => {
342
+ // Arrange
343
+ const testPoint = {
344
+ testCaseReference: { id: 1, name: 'Test Case 1' }
345
+ // No configuration or results
346
+ };
347
+
348
+ // Act
349
+ const result = (resultDataProvider as any).mapTestPoint(testPoint);
350
+
351
+ // Assert
352
+ expect(result).toEqual({
353
+ testCaseId: 1,
354
+ testCaseName: 'Test Case 1',
355
+ configurationName: undefined,
356
+ outcome: 'Not Run',
357
+ lastRunId: undefined,
358
+ lastResultId: undefined,
359
+ lastResultDetails: undefined
360
+ });
361
+ });
362
+ });
363
+
364
+ describe('calculateGroupResultSummary', () => {
365
+ it('should return empty strings when includeHardCopyRun is true', () => {
366
+ // Arrange
367
+ const testPoints = [
368
+ { outcome: 'passed' },
369
+ { outcome: 'failed' }
370
+ ];
371
+
372
+ // Act
373
+ const result = (resultDataProvider as any).calculateGroupResultSummary(testPoints, true);
374
+
375
+ // Assert
376
+ expect(result).toEqual({
377
+ passed: '',
378
+ failed: '',
379
+ notApplicable: '',
380
+ blocked: '',
381
+ notRun: '',
382
+ total: '',
383
+ successPercentage: ''
384
+ });
385
+ });
386
+
387
+ it('should calculate summary statistics correctly', () => {
388
+ // Arrange
389
+ const testPoints = [
390
+ { outcome: 'passed' },
391
+ { outcome: 'passed' },
392
+ { outcome: 'failed' },
393
+ { outcome: 'notApplicable' },
394
+ { outcome: 'blocked' },
395
+ { outcome: 'something else' }
396
+ ];
397
+
398
+ // Act
399
+ const result = (resultDataProvider as any).calculateGroupResultSummary(testPoints, false);
400
+
401
+ // Assert
402
+ expect(result).toEqual({
403
+ passed: 2,
404
+ failed: 1,
405
+ notApplicable: 1,
406
+ blocked: 1,
407
+ notRun: 1,
408
+ total: 6,
409
+ successPercentage: '33.33%'
410
+ });
411
+ });
412
+
413
+ it('should handle empty array', () => {
414
+ // Arrange
415
+ const testPoints: any[] = [];
416
+
417
+ // Act
418
+ const result = (resultDataProvider as any).calculateGroupResultSummary(testPoints, false);
419
+
420
+ // Assert
421
+ expect(result).toEqual({
422
+ passed: 0,
423
+ failed: 0,
424
+ notApplicable: 0,
425
+ blocked: 0,
426
+ notRun: 0,
427
+ total: 0,
428
+ successPercentage: '0.00%'
429
+ });
430
+ });
431
+ });
432
+
433
+ describe('mapAttachmentsUrl', () => {
434
+ it('should map attachment URLs correctly', () => {
435
+ // Arrange
436
+ const mockRunResults = [
437
+ {
438
+ testCaseId: 1,
439
+ lastRunId: 100,
440
+ lastResultId: 200,
441
+ iteration: {
442
+ attachments: [
443
+ { id: 1, name: 'attachment1.png', actionPath: 'path1' }
444
+ ],
445
+ actionResults: [
446
+ { actionPath: 'path1', stepPosition: '1.1' }
447
+ ]
448
+ },
449
+ analysisAttachments: [
450
+ { id: 2, fileName: 'analysis1.txt' }
451
+ ]
452
+ }
453
+ ];
454
+
455
+ // Act
456
+ const result = resultDataProvider.mapAttachmentsUrl(mockRunResults, mockProjectName);
457
+
458
+ // Assert
459
+ expect(result[0].iteration.attachments[0].downloadUrl).toBe(
460
+ `${mockOrgUrl}${mockProjectName}/_apis/test/runs/100/results/200/attachments/1/attachment1.png`
461
+ );
462
+ expect(result[0].iteration.attachments[0].stepNo).toBe('1.1');
463
+ expect(result[0].analysisAttachments[0].downloadUrl).toBe(
464
+ `${mockOrgUrl}${mockProjectName}/_apis/test/runs/100/results/200/attachments/2/analysis1.txt`
465
+ );
466
+ });
467
+
468
+ it('should handle missing iteration', () => {
469
+ // Arrange
470
+ const mockRunResults = [
471
+ {
472
+ testCaseId: 1,
473
+ lastRunId: 100,
474
+ lastResultId: 200,
475
+ // No iteration
476
+ analysisAttachments: [
477
+ { id: 2, fileName: 'analysis1.txt' }
478
+ ]
479
+ }
480
+ ];
481
+
482
+ // Act
483
+ const result = resultDataProvider.mapAttachmentsUrl(mockRunResults, mockProjectName);
484
+
485
+ // Assert
486
+ expect(result[0]).toEqual(mockRunResults[0]);
487
+ });
488
+ });
489
+ });
490
+
491
+ describe('getCombinedResultsSummary', () => {
492
+ it('should combine all results into expected format', async () => {
493
+ // Arrange
494
+ const mockTestSuites = {
495
+ value: [
496
+ {
497
+ id: 1,
498
+ name: 'Root Suite',
499
+ children: [
500
+ { id: 2, name: 'Child Suite 1', parentSuite: { id: 1 } }
501
+ ]
502
+ }
503
+ ],
504
+ count: 1
505
+ };
506
+
507
+ const mockTestPoints = {
508
+ value: [
509
+ {
510
+ testCaseReference: { id: 1, name: 'Test Case 1' },
511
+ configuration: { name: 'Config 1' },
512
+ results: {
513
+ outcome: 'passed',
514
+ lastTestRunId: 100,
515
+ lastResultId: 200,
516
+ lastResultDetails: { dateCompleted: '2023-01-01', runBy: { displayName: 'Test User' } }
517
+ }
518
+ }
519
+ ],
520
+ count: 1
521
+ };
522
+
523
+ const mockTestCases = {
524
+ value: [
525
+ {
526
+ workItem: {
527
+ id: 1,
528
+ workItemFields: [{ key: 'Steps', value: '<steps>...</steps>' }]
529
+ }
530
+ }
531
+ ]
532
+ };
533
+
534
+ const mockResult = {
535
+ testCase: { id: 1, name: 'Test Case 1' },
536
+ testSuite: { id: 2, name: 'Child Suite 1' },
537
+ iterationDetails: [
538
+ {
539
+ actionResults: [
540
+ { stepIdentifier: '1', outcome: 'Passed', errorMessage: '', actionPath: 'path1' }
541
+ ],
542
+ attachments: []
543
+ }
544
+ ],
545
+ testCaseRevision: 1,
546
+ failureType: null,
547
+ resolutionState: null,
548
+ comment: null
549
+ };
550
+
551
+ // Setup mocks for API calls
552
+ (TFSServices.getItemContent as jest.Mock)
553
+ .mockResolvedValueOnce(mockTestSuites) // fetchTestSuites
554
+ .mockResolvedValueOnce(mockTestPoints) // fetchTestPoints
555
+ .mockResolvedValueOnce(mockTestCases) // fetchTestCasesBySuiteId
556
+ .mockResolvedValueOnce(mockResult) // fetchResult
557
+ .mockResolvedValueOnce({ value: [] }) // fetchResult - attachments
558
+ .mockResolvedValueOnce({ fields: {} }); // fetchResult - wiByRevision
559
+
560
+ const mockTestStepParserHelper = (resultDataProvider as any).testStepParserHelper;
561
+ mockTestStepParserHelper.parseTestSteps.mockResolvedValueOnce([
562
+ { stepId: 1, stepPosition: '1', action: 'Do something', expected: 'Something happens', isSharedStepTitle: false }
563
+ ]);
564
+
565
+ // Act
566
+ const result = await resultDataProvider.getCombinedResultsSummary(
567
+ mockTestPlanId,
568
+ mockProjectName,
569
+ undefined,
570
+ true
571
+ );
572
+
573
+ // Assert
574
+ expect(result.length).toBeGreaterThan(0);
575
+ expect(result[0]).toHaveProperty('contentControl', 'test-group-summary-content-control');
576
+ expect(result[1]).toHaveProperty('contentControl', 'test-result-summary-content-control');
577
+ expect(result[2]).toHaveProperty('contentControl', 'detailed-test-result-content-control');
578
+ });
579
+
580
+ });
581
+ });