diff --git a/designer/server/src/lib/dead-letter-queue.js b/designer/server/src/lib/dead-letter-queue.js index b38c27b30..b17dff687 100644 --- a/designer/server/src/lib/dead-letter-queue.js +++ b/designer/server/src/lib/dead-letter-queue.js @@ -45,8 +45,9 @@ export function getEndpoint(dlq) { /** * @param {DeadLetterQueues} dlq * @param {string} token + * @param {{ visibilityTimeout: number | undefined, waitTimeSeconds: number | undefined}} [options] */ -export async function getDeadLetterQueueMessages(dlq, token) { +export async function getDeadLetterQueueMessages(dlq, token, options) { const getJsonByType = /** @type {typeof getJson<{ messages: any[] }>} */ ( getJson ) @@ -55,6 +56,20 @@ export async function getDeadLetterQueueMessages(dlq, token) { const requestUrl = new URL(`./admin/deadletter${qualifier}/view`, endpoint) + if (options?.visibilityTimeout) { + requestUrl.searchParams.set( + 'visibilityTimeout', + options.visibilityTimeout.toString() + ) + } + + if (options?.waitTimeSeconds) { + requestUrl.searchParams.set( + 'waitTimeSeconds', + options.waitTimeSeconds.toString() + ) + } + const { body } = await getJsonByType(requestUrl, getHeaders(token)) // Dedupe in case of duplicate messages @@ -65,6 +80,49 @@ export async function getDeadLetterQueueMessages(dlq, token) { return uniqueMessages.values().toArray() } +/** + * @param {DeadLetterQueues} dlq + * @param {string} messageId + * @param {string} token + * @param {{ visibilityTimeout: number | undefined, waitTimeSeconds: number | undefined}} [options] + * @returns {Promise} + */ +export async function getDeadLetterQueueMessage( + dlq, + messageId, + token, + options +) { + const getJsonByType = /** @type {typeof getJson<{ message: any }>} */ ( + getJson + ) + + const { endpoint, qualifier } = getEndpoint(dlq) + + const requestUrl = new URL( + `./admin/deadletter${qualifier}/view/${messageId}`, + endpoint + ) + + if (options?.visibilityTimeout) { + requestUrl.searchParams.set( + 'visibilityTimeout', + options.visibilityTimeout.toString() + ) + } + + if (options?.waitTimeSeconds) { + requestUrl.searchParams.set( + 'waitTimeSeconds', + options.waitTimeSeconds.toString() + ) + } + + const { body } = await getJsonByType(requestUrl, getHeaders(token)) + + return body.message ?? undefined +} + /** * @param {DeadLetterQueues} dlq * @param {string} token diff --git a/designer/server/src/lib/dead-letter-queue.test.js b/designer/server/src/lib/dead-letter-queue.test.js index 4ba745831..c58796c89 100644 --- a/designer/server/src/lib/dead-letter-queue.test.js +++ b/designer/server/src/lib/dead-letter-queue.test.js @@ -2,6 +2,7 @@ import { DeadLetterQueues } from '@defra/forms-model' import { deleteDeadLetterQueueMessage, + getDeadLetterQueueMessage, getDeadLetterQueueMessages, getEndpoint, redriveDeadLetterQueueMessages, @@ -60,6 +61,62 @@ describe('dead-letter queue lib functions', () => { ) expect(res).toEqual(['message1']) }) + + it('should call endpoint with extra query params', async () => { + jest + .mocked(getJson) + // @ts-expect-error - partial mock of response + .mockResolvedValueOnce({ body: { messages: ['message1'] } }) + const dlq = DeadLetterQueues.SubmissionsApiFormSubmissions + const res = await getDeadLetterQueueMessages(dlq, 'token', { + visibilityTimeout: 5, + waitTimeSeconds: 10 + }) + expect(getJson).toHaveBeenCalledWith( + new URL( + 'http://localhost:3002/admin/deadletter/form-submissions/view?visibilityTimeout=5&waitTimeSeconds=10' + ), + expect.anything() + ) + expect(res).toEqual(['message1']) + }) + }) + + describe('getDeadLetterQueueMessage', () => { + it('should call endpoint', async () => { + jest + .mocked(getJson) + // @ts-expect-error - partial mock of response + .mockResolvedValueOnce({ body: { message: 'message1' } }) + const dlq = DeadLetterQueues.SubmissionsApiFormSubmissions + const res = await getDeadLetterQueueMessage(dlq, 'message-id', 'token') + expect(getJson).toHaveBeenCalledWith( + new URL( + 'http://localhost:3002/admin/deadletter/form-submissions/view/message-id' + ), + expect.anything() + ) + expect(res).toBe('message1') + }) + + it('should call endpoint with extra query params', async () => { + jest + .mocked(getJson) + // @ts-expect-error - partial mock of response + .mockResolvedValueOnce({ body: { message: 'message1' } }) + const dlq = DeadLetterQueues.SubmissionsApiFormSubmissions + const res = await getDeadLetterQueueMessage(dlq, 'message-id', 'token', { + visibilityTimeout: 5, + waitTimeSeconds: 10 + }) + expect(getJson).toHaveBeenCalledWith( + new URL( + 'http://localhost:3002/admin/deadletter/form-submissions/view/message-id?visibilityTimeout=5&waitTimeSeconds=10' + ), + expect.anything() + ) + expect(res).toBe('message1') + }) }) describe('redriveDeadLetterQueueMessages', () => { diff --git a/designer/server/src/routes/admin/__snapshots__/dead-letter-queues.test.js.snap b/designer/server/src/routes/admin/__snapshots__/dead-letter-queues.test.js.snap index 741ada13b..5e4b1a539 100644 --- a/designer/server/src/routes/admin/__snapshots__/dead-letter-queues.test.js.snap +++ b/designer/server/src/routes/admin/__snapshots__/dead-letter-queues.test.js.snap @@ -215,7 +215,11 @@ exports[`Dead-letter queues routes Journey should render form with messages and