diff --git a/plugins/scaffolder/package.json b/plugins/scaffolder/package.json index 0b517671ba..20b8e934f7 100644 --- a/plugins/scaffolder/package.json +++ b/plugins/scaffolder/package.json @@ -77,6 +77,7 @@ "@types/jest": "^26.0.7", "@types/node": "^14.14.32", "cross-fetch": "^3.0.6", + "event-source-polyfill": "^1.0.25", "msw": "^0.35.0" }, "files": [ diff --git a/plugins/scaffolder/src/api.test.ts b/plugins/scaffolder/src/api.test.ts index cc4b70283c..f11b2cf06c 100644 --- a/plugins/scaffolder/src/api.test.ts +++ b/plugins/scaffolder/src/api.test.ts @@ -14,12 +14,18 @@ * limitations under the License. */ +import { ConfigReader } from '@backstage/core-app-api'; import { ScmIntegrations } from '@backstage/integration'; import { ScaffolderClient } from './api'; -import { ConfigReader } from '@backstage/core-app-api'; + +const MockedEventSource = global.EventSource as jest.MockedClass< + typeof EventSource +>; describe('api', () => { - const discoveryApi = {} as any; + const mockBaseUrl = 'http://backstage/api'; + + const discoveryApi = { getBaseUrl: async () => mockBaseUrl }; const identityApi = {} as any; const scmIntegrationsApi = ScmIntegrations.fromConfig( new ConfigReader({ @@ -32,10 +38,14 @@ describe('api', () => { }, }), ); - const apiClient = new ScaffolderClient({ - scmIntegrationsApi, - discoveryApi, - identityApi, + + let apiClient: ScaffolderClient; + beforeEach(() => { + apiClient = new ScaffolderClient({ + scmIntegrationsApi, + discoveryApi, + identityApi, + }); }); it('should return default and custom integrations', async () => { @@ -51,4 +61,58 @@ describe('api', () => { expect(allowedHosts).toContain(integration.host), ); }); + + describe('streamEvents', () => { + describe('eventsource', () => { + it('should work', async () => { + MockedEventSource.prototype.addEventListener.mockImplementation( + (type, fn) => { + if (typeof fn !== 'function') { + return; + } + + if (type === 'log') { + fn({ + data: '{"id":1,"taskId":"a-random-id","type":"log","createdAt":"","body":{"message":"My log message"}}', + } as any); + } else if (type === 'completion') { + fn({ + data: '{"id":2,"taskId":"a-random-id","type":"completion","createdAt":"","body":{"message":"Finished!"}}', + } as any); + } + }, + ); + + const next = jest.fn(); + + await new Promise(complete => { + apiClient + .streamLogs({ taskId: 'a-random-task-id' }) + .subscribe({ next, complete }); + }); + + expect(MockedEventSource).toBeCalledWith( + 'http://backstage/api/v2/tasks/a-random-task-id/eventstream', + { withCredentials: true }, + ); + expect(MockedEventSource.prototype.close).toBeCalled(); + + expect(next).toBeCalledTimes(2); + expect(next).toBeCalledWith({ + id: 1, + taskId: 'a-random-id', + type: 'log', + createdAt: '', + body: { message: 'My log message' }, + }); + expect(next).toBeCalledWith({ + id: 2, + taskId: 'a-random-id', + type: 'completion', + createdAt: '', + body: { message: 'Finished!' }, + }); + }); + }); + }); }); diff --git a/plugins/scaffolder/src/setupTests.ts b/plugins/scaffolder/src/setupTests.ts index 963c0f188b..84589060ec 100644 --- a/plugins/scaffolder/src/setupTests.ts +++ b/plugins/scaffolder/src/setupTests.ts @@ -15,3 +15,6 @@ */ import '@testing-library/jest-dom'; + +const { EventSourcePolyfill } = jest.requireMock('event-source-polyfill'); +global.EventSource = EventSourcePolyfill;