@elisra-devops/docgen-data-provider 1.22.0 → 1.24.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.
- package/bin/helpers/helper.js.map +1 -1
- package/bin/helpers/test/tfs.test.d.ts +1 -0
- package/bin/helpers/test/tfs.test.js +613 -0
- package/bin/helpers/test/tfs.test.js.map +1 -0
- package/bin/helpers/tfs.js +1 -1
- package/bin/helpers/tfs.js.map +1 -1
- package/bin/modules/GitDataProvider.js.map +1 -1
- package/bin/modules/PipelinesDataProvider.js +3 -2
- package/bin/modules/PipelinesDataProvider.js.map +1 -1
- package/bin/modules/ResultDataProvider.d.ts +200 -17
- package/bin/modules/ResultDataProvider.js +628 -195
- package/bin/modules/ResultDataProvider.js.map +1 -1
- package/bin/modules/TestDataProvider.js +7 -7
- package/bin/modules/TestDataProvider.js.map +1 -1
- package/bin/modules/TicketsDataProvider.d.ts +1 -1
- package/bin/modules/TicketsDataProvider.js +3 -2
- package/bin/modules/TicketsDataProvider.js.map +1 -1
- package/bin/modules/test/JfrogDataProvider.test.d.ts +1 -0
- package/bin/modules/test/JfrogDataProvider.test.js +110 -0
- package/bin/modules/test/JfrogDataProvider.test.js.map +1 -0
- package/bin/modules/test/ResultDataProvider.test.d.ts +1 -0
- package/bin/modules/test/ResultDataProvider.test.js +478 -0
- package/bin/modules/test/ResultDataProvider.test.js.map +1 -0
- package/bin/modules/test/gitDataProvider.test.js +424 -120
- package/bin/modules/test/gitDataProvider.test.js.map +1 -1
- package/bin/modules/test/managmentDataProvider.test.js +283 -28
- package/bin/modules/test/managmentDataProvider.test.js.map +1 -1
- package/bin/modules/test/pipelineDataProvider.test.js +229 -45
- package/bin/modules/test/pipelineDataProvider.test.js.map +1 -1
- package/bin/modules/test/testDataProvider.test.js +225 -81
- package/bin/modules/test/testDataProvider.test.js.map +1 -1
- package/bin/modules/test/ticketsDataProvider.test.js +310 -82
- package/bin/modules/test/ticketsDataProvider.test.js.map +1 -1
- package/package.json +1 -1
- package/src/helpers/helper.ts +16 -14
- package/src/helpers/test/tfs.test.ts +748 -0
- package/src/helpers/tfs.ts +1 -1
- package/src/modules/GitDataProvider.ts +10 -10
- package/src/modules/PipelinesDataProvider.ts +2 -2
- package/src/modules/ResultDataProvider.ts +834 -260
- package/src/modules/TestDataProvider.ts +8 -8
- package/src/modules/TicketsDataProvider.ts +5 -9
- package/src/modules/test/JfrogDataProvider.test.ts +171 -0
- package/src/modules/test/ResultDataProvider.test.ts +581 -0
- package/src/modules/test/gitDataProvider.test.ts +671 -187
- package/src/modules/test/managmentDataProvider.test.ts +386 -26
- package/src/modules/test/pipelineDataProvider.test.ts +281 -52
- package/src/modules/test/testDataProvider.test.ts +307 -105
- package/src/modules/test/ticketsDataProvider.test.ts +425 -129
|
@@ -44,21 +44,21 @@ export default class TestDataProvider {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
async GetTestSuiteByTestCase(testCaseId: string): Promise<any> {
|
|
47
|
-
let url = `${this.orgUrl}
|
|
48
|
-
return this.fetchWithCache(url);
|
|
47
|
+
let url = `${this.orgUrl.endsWith('/') ? this.orgUrl : `${this.orgUrl}/`}_apis/testplan/suites?testCaseId=${testCaseId}`;
|
|
48
|
+
return await this.fetchWithCache(url);
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
async GetTestPlans(project: string): Promise<string> {
|
|
52
52
|
let testPlanUrl: string = `${this.orgUrl}${project}/_apis/test/plans`;
|
|
53
|
-
return this.fetchWithCache(testPlanUrl);
|
|
53
|
+
return await this.fetchWithCache(testPlanUrl);
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
async GetTestSuites(project: string, planId: string): Promise<any> {
|
|
57
57
|
let testsuitesUrl: string = this.orgUrl + project + '/_apis/test/Plans/' + planId + '/suites';
|
|
58
58
|
try {
|
|
59
|
-
return this.fetchWithCache(testsuitesUrl);
|
|
60
|
-
} catch (e) {
|
|
61
|
-
logger.error(`Failed to get test suites: ${e}`);
|
|
59
|
+
return await this.fetchWithCache(testsuitesUrl);
|
|
60
|
+
} catch (e: any) {
|
|
61
|
+
logger.error(`Failed to get test suites: ${e.message}`);
|
|
62
62
|
return null;
|
|
63
63
|
}
|
|
64
64
|
}
|
|
@@ -72,7 +72,7 @@ export default class TestDataProvider {
|
|
|
72
72
|
}
|
|
73
73
|
let url =
|
|
74
74
|
this.orgUrl + '/' + project + '/_api/_testManagement/GetTestSuitesForPlan?__v=5&planId=' + planid;
|
|
75
|
-
return this.fetchWithCache(url);
|
|
75
|
+
return await this.fetchWithCache(url);
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
async GetTestSuitesByPlan(project: string, planId: string, recursive: boolean): Promise<any> {
|
|
@@ -314,7 +314,7 @@ export default class TestDataProvider {
|
|
|
314
314
|
|
|
315
315
|
async GetTestPoint(project: string, planId: string, suiteId: string, testCaseId: string): Promise<any> {
|
|
316
316
|
let testPointUrl: string = `${this.orgUrl}${project}/_apis/test/Plans/${planId}/Suites/${suiteId}/points?testCaseId=${testCaseId}`;
|
|
317
|
-
return this.fetchWithCache(testPointUrl);
|
|
317
|
+
return await this.fetchWithCache(testPointUrl);
|
|
318
318
|
}
|
|
319
319
|
|
|
320
320
|
async CreateTestRun(
|
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
import { TFSServices } from '../helpers/tfs';
|
|
2
2
|
import { Workitem, QueryTree } from '../models/tfs-data';
|
|
3
|
-
import { Helper,
|
|
4
|
-
import { Query
|
|
3
|
+
import { Helper, Links, Trace, Relations } from '../helpers/helper';
|
|
4
|
+
import { Query } from '../models/tfs-data';
|
|
5
5
|
import { QueryType } from '../models/tfs-data';
|
|
6
6
|
import { QueryAllTypes } from '../models/tfs-data';
|
|
7
7
|
import { Column } from '../models/tfs-data';
|
|
8
8
|
import { value } from '../models/tfs-data';
|
|
9
|
-
import { TestCase } from '../models/tfs-data';
|
|
10
|
-
import * as xml2js from 'xml2js';
|
|
11
9
|
|
|
12
10
|
import logger from '../utils/logger';
|
|
13
|
-
import { log } from 'console';
|
|
14
|
-
import { pid, title } from 'process';
|
|
15
11
|
|
|
16
12
|
export default class TicketsDataProvider {
|
|
17
13
|
orgUrl: string = '';
|
|
@@ -42,7 +38,7 @@ export default class TicketsDataProvider {
|
|
|
42
38
|
let traceItem: Trace; //= new Trace();
|
|
43
39
|
traceItem = await this.GetParentLink(project, wis[i]);
|
|
44
40
|
|
|
45
|
-
if (linksMap.get(wis[i].id)
|
|
41
|
+
if (linksMap.get(wis[i].id)?.rels.length > 0) {
|
|
46
42
|
relations = await this.PopulateWorkItemsByIds(linksMap.get(wis[i].id).rels, project);
|
|
47
43
|
traceItem.links = await this.GetLinks(project, wis[i], relations);
|
|
48
44
|
}
|
|
@@ -626,11 +622,11 @@ export default class TicketsDataProvider {
|
|
|
626
622
|
} //CreateNewWorkItem
|
|
627
623
|
|
|
628
624
|
async GetWorkitemAttachments(project: string, id: string) {
|
|
629
|
-
let attachmentList: Array<
|
|
625
|
+
let attachmentList: Array<any> = [];
|
|
630
626
|
let ticketsDataProvider = new TicketsDataProvider(this.orgUrl, this.token);
|
|
631
627
|
try {
|
|
632
628
|
let wi = await ticketsDataProvider.GetWorkItem(project, id);
|
|
633
|
-
if (!wi
|
|
629
|
+
if (!wi?.relations) return [];
|
|
634
630
|
await Promise.all(
|
|
635
631
|
wi.relations.map(async (relation: any) => {
|
|
636
632
|
if (relation.rel == 'AttachedFile') {
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { TFSServices } from '../../helpers/tfs';
|
|
2
|
+
import logger from '../../utils/logger';
|
|
3
|
+
import JfrogDataProvider from '../JfrogDataProvider';
|
|
4
|
+
|
|
5
|
+
jest.mock('../../helpers/tfs');
|
|
6
|
+
jest.mock('../../utils/logger');
|
|
7
|
+
|
|
8
|
+
describe('JfrogDataProvider', () => {
|
|
9
|
+
let jfrogDataProvider: JfrogDataProvider;
|
|
10
|
+
const mockOrgUrl = 'https://dev.azure.com/organization/';
|
|
11
|
+
const mockTfsToken = 'mock-tfs-token';
|
|
12
|
+
const mockJfrogToken = 'mock-jfrog-token';
|
|
13
|
+
|
|
14
|
+
beforeEach(() => {
|
|
15
|
+
jest.clearAllMocks();
|
|
16
|
+
jfrogDataProvider = new JfrogDataProvider(mockOrgUrl, mockTfsToken, mockJfrogToken);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
describe('getServiceConnectionUrlByConnectionId', () => {
|
|
20
|
+
it('should fetch service connection URL with correct parameters', async () => {
|
|
21
|
+
// Arrange
|
|
22
|
+
const mockTeamProject = 'test-project';
|
|
23
|
+
const mockConnectionId = 'connection-123';
|
|
24
|
+
const mockResponse = { url: 'https://jfrog.example.com' };
|
|
25
|
+
|
|
26
|
+
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockResponse);
|
|
27
|
+
|
|
28
|
+
// Act
|
|
29
|
+
const result = await jfrogDataProvider.getServiceConnectionUrlByConnectionId(
|
|
30
|
+
mockTeamProject,
|
|
31
|
+
mockConnectionId
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
// Assert
|
|
35
|
+
expect(TFSServices.getItemContent).toHaveBeenCalledWith(
|
|
36
|
+
`${mockOrgUrl}${mockTeamProject}/_apis/serviceendpoint/endpoints/${mockConnectionId}?api-version=6`,
|
|
37
|
+
mockTfsToken
|
|
38
|
+
);
|
|
39
|
+
expect(logger.debug).toHaveBeenCalledWith(
|
|
40
|
+
`service connection url "${mockResponse.url}"`
|
|
41
|
+
);
|
|
42
|
+
expect(result).toBe(mockResponse.url);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it('should propagate errors when API call fails', async () => {
|
|
46
|
+
// Arrange
|
|
47
|
+
const mockTeamProject = 'test-project';
|
|
48
|
+
const mockConnectionId = 'connection-123';
|
|
49
|
+
const mockError = new Error('API error');
|
|
50
|
+
|
|
51
|
+
(TFSServices.getItemContent as jest.Mock).mockRejectedValueOnce(mockError);
|
|
52
|
+
|
|
53
|
+
// Act & Assert
|
|
54
|
+
await expect(
|
|
55
|
+
jfrogDataProvider.getServiceConnectionUrlByConnectionId(mockTeamProject, mockConnectionId)
|
|
56
|
+
).rejects.toThrow('API error');
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
describe('getCiDataFromJfrog', () => {
|
|
61
|
+
it('should fetch JFrog data with token and format URLs correctly', async () => {
|
|
62
|
+
// Arrange
|
|
63
|
+
const mockJfrogUrl = 'https://jfrog.example.com';
|
|
64
|
+
const mockBuildName = 'build-name';
|
|
65
|
+
const mockBuildVersion = 'version-1.0';
|
|
66
|
+
const mockResponse = {
|
|
67
|
+
buildInfo: {
|
|
68
|
+
url: 'https://ci.example.com/build/123'
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
(TFSServices.getJfrogRequest as jest.Mock).mockResolvedValueOnce(mockResponse);
|
|
73
|
+
|
|
74
|
+
// Act
|
|
75
|
+
const result = await jfrogDataProvider.getCiDataFromJfrog(
|
|
76
|
+
mockJfrogUrl,
|
|
77
|
+
mockBuildName,
|
|
78
|
+
mockBuildVersion
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
// Assert
|
|
82
|
+
expect(TFSServices.getJfrogRequest).toHaveBeenCalledWith(
|
|
83
|
+
`${mockJfrogUrl}/api/build/${mockBuildName}/${mockBuildVersion}`,
|
|
84
|
+
{ 'Authorization': `Bearer ${mockJfrogToken}` }
|
|
85
|
+
);
|
|
86
|
+
expect(logger.info).toHaveBeenCalledWith(
|
|
87
|
+
`Querying Jfrog using url ${mockJfrogUrl}/api/build/${mockBuildName}/${mockBuildVersion}`
|
|
88
|
+
);
|
|
89
|
+
expect(logger.debug).toHaveBeenCalledWith(
|
|
90
|
+
`CI Url from JFROG: ${mockResponse.buildInfo.url}`
|
|
91
|
+
);
|
|
92
|
+
expect(result).toBe(mockResponse.buildInfo.url);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it('should handle build names and versions that already start with /', async () => {
|
|
96
|
+
// Arrange
|
|
97
|
+
const mockJfrogUrl = 'https://jfrog.example.com';
|
|
98
|
+
const mockBuildName = '/build-name';
|
|
99
|
+
const mockBuildVersion = '/version-1.0';
|
|
100
|
+
const mockResponse = {
|
|
101
|
+
buildInfo: {
|
|
102
|
+
url: 'https://ci.example.com/build/123'
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
(TFSServices.getJfrogRequest as jest.Mock).mockResolvedValueOnce(mockResponse);
|
|
107
|
+
|
|
108
|
+
// Act
|
|
109
|
+
const result = await jfrogDataProvider.getCiDataFromJfrog(
|
|
110
|
+
mockJfrogUrl,
|
|
111
|
+
mockBuildName,
|
|
112
|
+
mockBuildVersion
|
|
113
|
+
);
|
|
114
|
+
|
|
115
|
+
// Assert
|
|
116
|
+
expect(TFSServices.getJfrogRequest).toHaveBeenCalledWith(
|
|
117
|
+
`${mockJfrogUrl}/api/build${mockBuildName}${mockBuildVersion}`,
|
|
118
|
+
{ 'Authorization': `Bearer ${mockJfrogToken}` }
|
|
119
|
+
);
|
|
120
|
+
expect(result).toBe(mockResponse.buildInfo.url);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
it('should make request without token when jfrogToken is empty', async () => {
|
|
124
|
+
// Arrange
|
|
125
|
+
const mockJfrogUrl = 'https://jfrog.example.com';
|
|
126
|
+
const mockBuildName = 'build-name';
|
|
127
|
+
const mockBuildVersion = 'version-1.0';
|
|
128
|
+
const mockResponse = {
|
|
129
|
+
buildInfo: {
|
|
130
|
+
url: 'https://ci.example.com/build/123'
|
|
131
|
+
}
|
|
132
|
+
};
|
|
133
|
+
|
|
134
|
+
// Create provider with empty jfrog token
|
|
135
|
+
const jfrogDataProviderNoToken = new JfrogDataProvider(mockOrgUrl, mockTfsToken, '');
|
|
136
|
+
(TFSServices.getJfrogRequest as jest.Mock).mockResolvedValueOnce(mockResponse);
|
|
137
|
+
|
|
138
|
+
// Act
|
|
139
|
+
const result = await jfrogDataProviderNoToken.getCiDataFromJfrog(
|
|
140
|
+
mockJfrogUrl,
|
|
141
|
+
mockBuildName,
|
|
142
|
+
mockBuildVersion
|
|
143
|
+
);
|
|
144
|
+
|
|
145
|
+
// Assert
|
|
146
|
+
expect(TFSServices.getJfrogRequest).toHaveBeenCalledWith(
|
|
147
|
+
`${mockJfrogUrl}/api/build/${mockBuildName}/${mockBuildVersion}`
|
|
148
|
+
);
|
|
149
|
+
expect(result).toBe(mockResponse.buildInfo.url);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
it('should log and rethrow errors from JFrog API', async () => {
|
|
153
|
+
// Arrange
|
|
154
|
+
const mockJfrogUrl = 'https://jfrog.example.com';
|
|
155
|
+
const mockBuildName = 'build-name';
|
|
156
|
+
const mockBuildVersion = 'version-1.0';
|
|
157
|
+
const mockError = new Error('JFrog API error');
|
|
158
|
+
|
|
159
|
+
(TFSServices.getJfrogRequest as jest.Mock).mockRejectedValueOnce(mockError);
|
|
160
|
+
|
|
161
|
+
// Act & Assert
|
|
162
|
+
await expect(
|
|
163
|
+
jfrogDataProvider.getCiDataFromJfrog(mockJfrogUrl, mockBuildName, mockBuildVersion)
|
|
164
|
+
).rejects.toThrow('JFrog API error');
|
|
165
|
+
|
|
166
|
+
expect(logger.error).toHaveBeenCalledWith(
|
|
167
|
+
`Error occurred during querying JFrog using: JFrog API error`
|
|
168
|
+
);
|
|
169
|
+
});
|
|
170
|
+
});
|
|
171
|
+
});
|