fix(Jira Software Node): Get All Issues operation with Return All hangs (#17825)

This commit is contained in:
RomanDavydchuk
2025-08-07 10:55:56 +03:00
committed by GitHub
parent 523a55d5ee
commit 2792b6cb0a
2 changed files with 127 additions and 20 deletions

View File

@@ -76,6 +76,7 @@ export async function jiraSoftwareCloudApiRequest(
}
export function handlePagination(
method: IHttpRequestMethods,
body: any,
query: IDataObject,
paginationType: 'offset' | 'token',
@@ -83,10 +84,23 @@ export function handlePagination(
): boolean {
if (!responseData) {
if (paginationType === 'offset') {
query.startAt = 0;
query.maxResults = 100;
if (method === 'GET') {
// Example: https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-issue-search/#api-rest-api-2-search-get
query.startAt = 0;
query.maxResults = 100;
} else {
// Example: https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-issue-search/#api-rest-api-2-search-post
body.startAt = 0;
body.maxResults = 100;
}
} else {
body.maxResults = 100;
if (method === 'GET') {
// Example: https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-issue-search/#api-rest-api-2-search-jql-get
query.maxResults = 100;
} else {
// Example: https://developer.atlassian.com/cloud/jira/platform/rest/v2/api-group-issue-search/#api-rest-api-2-search-jql-post
body.maxResults = 100;
}
}
return true;
@@ -94,10 +108,20 @@ export function handlePagination(
if (paginationType === 'offset') {
const nextStartAt = (responseData.startAt as number) + (responseData.maxResults as number);
query.startAt = nextStartAt;
if (method === 'GET') {
query.startAt = nextStartAt;
} else {
body.startAt = nextStartAt;
}
return nextStartAt < responseData.total;
} else {
body.nextPageToken = responseData.nextPageToken as string;
if (method === 'GET') {
query.nextPageToken = responseData.nextPageToken as string;
} else {
body.nextPageToken = responseData.nextPageToken as string;
}
return !!responseData.nextPageToken;
}
}
@@ -114,11 +138,11 @@ export async function jiraSoftwareCloudApiRequestAllItems(
const returnData: IDataObject[] = [];
let responseData;
let hasNextPage = handlePagination(body, query, paginationType);
let hasNextPage = handlePagination(method, body, query, paginationType);
do {
responseData = await jiraSoftwareCloudApiRequest.call(this, endpoint, method, body, query);
returnData.push.apply(returnData, responseData[propertyName] as IDataObject[]);
hasNextPage = handlePagination(body, query, paginationType, responseData);
hasNextPage = handlePagination(method, body, query, paginationType, responseData);
} while (hasNextPage);
return returnData;

View File

@@ -56,11 +56,11 @@ describe('Jira -> GenericFunctions', () => {
});
describe('handlePagination', () => {
it('should initialize offset pagination parameters when responseData is not provided', () => {
const body = {};
it('should initialize offset pagination parameters with GET when responseData is not provided', () => {
const body: IDataObject = {};
const query: IDataObject = {};
const result = handlePagination(body, query, 'offset');
const result = handlePagination('GET', body, query, 'offset');
expect(result).toBe(true);
expect(query.startAt).toBe(0);
@@ -68,18 +68,41 @@ describe('Jira -> GenericFunctions', () => {
expect(body).toEqual({});
});
it('should initialize token pagination parameters when responseData is not provided', () => {
it('should initialize offset pagination parameters with POST when responseData is not provided', () => {
const body: IDataObject = {};
const query: IDataObject = {};
const result = handlePagination(body, query, 'token');
const result = handlePagination('POST', body, query, 'offset');
expect(result).toBe(true);
expect(body.startAt).toBe(0);
expect(body.maxResults).toBe(100);
expect(query).toEqual({});
});
it('should initialize token pagination parameters with GET when responseData is not provided', () => {
const body: IDataObject = {};
const query: IDataObject = {};
const result = handlePagination('GET', body, query, 'token');
expect(result).toBe(true);
expect(query.maxResults).toBe(100);
expect(body).toEqual({});
});
it('should initialize token pagination parameters with POST when responseData is not provided', () => {
const body: IDataObject = {};
const query: IDataObject = {};
const result = handlePagination('POST', body, query, 'token');
expect(result).toBe(true);
expect(query).toEqual({});
expect(body.maxResults).toBe(100);
});
it('should handle offset pagination with more pages available', () => {
it('should handle offset pagination with GET and more pages available', () => {
const body: IDataObject = {};
const query: IDataObject = {};
const responseData = {
@@ -88,14 +111,30 @@ describe('Jira -> GenericFunctions', () => {
total: 250,
};
const result = handlePagination(body, query, 'offset', responseData);
const result = handlePagination('GET', body, query, 'offset', responseData);
expect(result).toBe(true);
expect(query.startAt).toBe(100);
expect(body).toEqual({});
});
it('should handle offset pagination with no more pages available', () => {
it('should handle offset pagination with POST and more pages available', () => {
const body: IDataObject = {};
const query: IDataObject = {};
const responseData = {
startAt: 0,
maxResults: 100,
total: 250,
};
const result = handlePagination('POST', body, query, 'offset', responseData);
expect(result).toBe(true);
expect(body.startAt).toBe(100);
expect(query).toEqual({});
});
it('should handle offset pagination with GET and no more pages available', () => {
const body: IDataObject = {};
const query: IDataObject = {};
const responseData = {
@@ -104,35 +143,79 @@ describe('Jira -> GenericFunctions', () => {
total: 250,
};
const result = handlePagination(body, query, 'offset', responseData);
const result = handlePagination('GET', body, query, 'offset', responseData);
expect(result).toBe(false);
expect(query.startAt).toBe(300);
expect(body).toEqual({});
});
it('should handle token pagination with more pages available', () => {
it('should handle offset pagination with POST and no more pages available', () => {
const body: IDataObject = {};
const query: IDataObject = {};
const responseData = {
startAt: 200,
maxResults: 100,
total: 250,
};
const result = handlePagination('POST', body, query, 'offset', responseData);
expect(result).toBe(false);
expect(body.startAt).toBe(300);
expect(query).toEqual({});
});
it('should handle token pagination with GET and more pages available', () => {
const body: IDataObject = {};
const query: IDataObject = {};
const responseData = {
nextPageToken: 'someToken123',
};
const result = handlePagination(body, query, 'token', responseData);
const result = handlePagination('GET', body, query, 'token', responseData);
expect(result).toBe(true);
expect(query.nextPageToken).toBe('someToken123');
expect(body).toEqual({});
});
it('should handle token pagination with POST and more pages available', () => {
const body: IDataObject = {};
const query: IDataObject = {};
const responseData = {
nextPageToken: 'someToken123',
};
const result = handlePagination('POST', body, query, 'token', responseData);
expect(result).toBe(true);
expect(body.nextPageToken).toBe('someToken123');
expect(query).toEqual({});
});
it('should handle token pagination with no more pages available', () => {
it('should handle token pagination with GET and no more pages available', () => {
const body: IDataObject = {};
const query: IDataObject = {};
const responseData = {
nextPageToken: '',
};
const result = handlePagination(body, query, 'token', responseData);
const result = handlePagination('GET', body, query, 'token', responseData);
expect(result).toBe(false);
expect(query.nextPageToken).toBe('');
expect(body).toEqual({});
});
it('should handle token pagination with POST and no more pages available', () => {
const body: IDataObject = {};
const query: IDataObject = {};
const responseData = {
nextPageToken: '',
};
const result = handlePagination('POST', body, query, 'token', responseData);
expect(result).toBe(false);
expect(body.nextPageToken).toBe('');