diff --git a/src/lib/ParseApp.js b/src/lib/ParseApp.js index f173f5cc8..feed6d04c 100644 --- a/src/lib/ParseApp.js +++ b/src/lib/ParseApp.js @@ -585,12 +585,22 @@ export default class ParseApp { }); } - runJob(job) { + async runJob(job) { + let description = 'Executing from job schedule web console.'; + try { + const response = await fetch(window.PARSE_DASHBOARD_PATH || '/'); + const dashboardUser = response.headers.get('username'); + if (dashboardUser) { + description = `Executing from job schedule web console by ${dashboardUser}.`; + } + } catch { + // If the dashboard user cannot be determined, fall back to the default description. + } return Parse._request( 'POST', 'jobs', { - description: 'Executing from job schedule web console.', + description, input: JSON.parse(job.params || '{}'), jobName: job.jobName, when: 0, diff --git a/src/lib/tests/ParseApp.test.js b/src/lib/tests/ParseApp.test.js new file mode 100644 index 000000000..2aed63e0f --- /dev/null +++ b/src/lib/tests/ParseApp.test.js @@ -0,0 +1,61 @@ +/** + * @jest-environment jsdom + */ +/* + * Copyright (c) 2016-present, Parse, LLC + * All rights reserved. + * + * This source code is licensed under the license found in the LICENSE file in + * the root directory of this source tree. + */ +jest.dontMock('../ParseApp'); + +const Parse = require('parse'); +const ParseApp = require('../ParseApp').default; + +function newApp() { + return new ParseApp({ + appName: 'test', + appId: 'appId', + supportedPushLocales: [], + }); +} + +function mockFetchWithUser(username) { + global.fetch = jest.fn(() => + Promise.resolve({ + headers: { get: header => (header === 'username' ? username : null) }, + }) + ); +} + +describe('ParseApp.runJob', () => { + beforeEach(() => { + Parse._request = jest.fn(() => Promise.resolve({})); + window.PARSE_DASHBOARD_PATH = '/'; + }); + + it('includes the dashboard user in the description when available', async () => { + mockFetchWithUser('alice'); + await newApp().runJob({ jobName: 'myJob', params: '{}' }); + expect(Parse._request.mock.calls[0][2].description).toBe( + 'Executing from job schedule web console by alice.' + ); + }); + + it('falls back to the default description when no dashboard user is set', async () => { + mockFetchWithUser(null); + await newApp().runJob({ jobName: 'myJob', params: '{}' }); + expect(Parse._request.mock.calls[0][2].description).toBe( + 'Executing from job schedule web console.' + ); + }); + + it('falls back to the default description when the user lookup fails', async () => { + global.fetch = jest.fn(() => Promise.reject(new Error('network error'))); + await newApp().runJob({ jobName: 'myJob', params: '{}' }); + expect(Parse._request.mock.calls[0][2].description).toBe( + 'Executing from job schedule web console.' + ); + }); +});