Skip to content

Commit 353df79

Browse files
fix(Jira Software Node): Get custom fields(RLC) in update operation for server deployment type (#12719)
1 parent d410b8f commit 353df79

File tree

2 files changed

+150
-0
lines changed

2 files changed

+150
-0
lines changed

Diff for: packages/nodes-base/nodes/Jira/Jira.node.ts

+24
Original file line numberDiff line numberDiff line change
@@ -276,8 +276,12 @@ export class Jira implements INodeType {
276276
async getCustomFields(this: ILoadOptionsFunctions): Promise<INodeListSearchResult> {
277277
const returnData: INodeListSearchItems[] = [];
278278
const operation = this.getCurrentNodeParameter('operation') as string;
279+
const jiraVersion = this.getNodeParameter('jiraVersion', 0) as string;
280+
279281
let projectId: string;
280282
let issueTypeId: string;
283+
let issueId: string = ''; // /editmeta endpoint requires issueId
284+
281285
if (operation === 'create') {
282286
projectId = this.getCurrentNodeParameter('project', { extractValue: true }) as string;
283287
issueTypeId = this.getCurrentNodeParameter('issueType', { extractValue: true }) as string;
@@ -292,6 +296,26 @@ export class Jira implements INodeType {
292296
);
293297
projectId = res.fields.project.id;
294298
issueTypeId = res.fields.issuetype.id;
299+
issueId = res.id;
300+
}
301+
302+
if (jiraVersion === 'server' && operation === 'update' && issueId) {
303+
// https://developer.atlassian.com/server/jira/platform/jira-rest-api-example-edit-issues-6291632/?utm_source=chatgpt.com
304+
const { fields } = await jiraSoftwareCloudApiRequest.call(
305+
this,
306+
`/api/2/issue/${issueId}/editmeta`,
307+
'GET',
308+
);
309+
310+
for (const field of Object.keys(fields || {})) {
311+
if (field.startsWith('customfield_')) {
312+
returnData.push({
313+
name: fields[field].name,
314+
value: field,
315+
});
316+
}
317+
}
318+
return { results: returnData };
295319
}
296320

297321
const res = await jiraSoftwareCloudApiRequest.call(
+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
import type { MockProxy } from 'jest-mock-extended';
2+
import { mock } from 'jest-mock-extended';
3+
import type { IHttpRequestMethods, ILoadOptionsFunctions } from 'n8n-workflow';
4+
5+
import { Jira } from '../Jira.node';
6+
7+
const ISSUE_KEY = 'KEY-1';
8+
9+
jest.mock('../GenericFunctions', () => {
10+
const originalModule = jest.requireActual('../GenericFunctions');
11+
return {
12+
...originalModule,
13+
jiraSoftwareCloudApiRequest: jest.fn(async function (
14+
endpoint: string,
15+
method: IHttpRequestMethods,
16+
) {
17+
if (method === 'GET' && endpoint === `/api/2/issue/${ISSUE_KEY}`) {
18+
return {
19+
id: 10000,
20+
fields: {
21+
project: {
22+
id: 10001,
23+
},
24+
issuetype: {
25+
id: 10002,
26+
},
27+
},
28+
};
29+
} else if (method === 'GET' && endpoint === '/api/2/issue/10000/editmeta') {
30+
return {
31+
fields: {
32+
customfield_123: {
33+
name: 'Field 123',
34+
},
35+
customfield_456: {
36+
name: 'Field 456',
37+
},
38+
},
39+
};
40+
} else if (
41+
method === 'GET' &&
42+
endpoint ===
43+
'/api/2/issue/createmeta?projectIds=10001&issueTypeIds=10002&expand=projects.issuetypes.fields'
44+
) {
45+
return {
46+
projects: [
47+
{
48+
id: 10001,
49+
issuetypes: [
50+
{
51+
id: 10002,
52+
fields: {
53+
customfield_abc: {
54+
name: 'Field ABC',
55+
schema: { customId: 'customfield_abc' },
56+
fieldId: 'customfield_abc',
57+
},
58+
customfield_def: {
59+
name: 'Field DEF',
60+
schema: { customId: 'customfield_def' },
61+
fieldId: 'customfield_def',
62+
},
63+
},
64+
},
65+
],
66+
},
67+
],
68+
};
69+
}
70+
}),
71+
};
72+
});
73+
74+
describe('Jira Node, methods', () => {
75+
let jira: Jira;
76+
let loadOptionsFunctions: MockProxy<ILoadOptionsFunctions>;
77+
78+
beforeEach(() => {
79+
jira = new Jira();
80+
loadOptionsFunctions = mock<ILoadOptionsFunctions>();
81+
});
82+
83+
describe('listSearch.getCustomFields', () => {
84+
it('should call correct endpoint and return custom fields for server version', async () => {
85+
loadOptionsFunctions.getCurrentNodeParameter.mockReturnValueOnce('update');
86+
loadOptionsFunctions.getNodeParameter.mockReturnValue('server');
87+
loadOptionsFunctions.getCurrentNodeParameter.mockReturnValueOnce(ISSUE_KEY);
88+
89+
const { results } = await jira.methods.listSearch.getCustomFields.call(
90+
loadOptionsFunctions as ILoadOptionsFunctions,
91+
);
92+
93+
expect(results).toEqual([
94+
{
95+
name: 'Field 123',
96+
value: 'customfield_123',
97+
},
98+
{
99+
name: 'Field 456',
100+
value: 'customfield_456',
101+
},
102+
]);
103+
});
104+
105+
it('should call correct endpoint and return custom fields for cloud version', async () => {
106+
loadOptionsFunctions.getCurrentNodeParameter.mockReturnValueOnce('update');
107+
loadOptionsFunctions.getNodeParameter.mockReturnValue('cloud');
108+
loadOptionsFunctions.getCurrentNodeParameter.mockReturnValueOnce(ISSUE_KEY);
109+
110+
const { results } = await jira.methods.listSearch.getCustomFields.call(
111+
loadOptionsFunctions as ILoadOptionsFunctions,
112+
);
113+
114+
expect(results).toEqual([
115+
{
116+
name: 'Field ABC',
117+
value: 'customfield_abc',
118+
},
119+
{
120+
name: 'Field DEF',
121+
value: 'customfield_def',
122+
},
123+
]);
124+
});
125+
});
126+
});

0 commit comments

Comments
 (0)