|
| 1 | +import { EventEmitter } from 'events'; |
1 | 2 | import { logPolling as cliUtilitiesJestMock } from '../test/mocks/cli-utilities'; |
| 3 | +import LogPolling from './logs-polling-utilities'; |
| 4 | +import defaultConfig from '../config'; |
2 | 5 |
|
3 | 6 | type LogPollingCtor = typeof import('./logs-polling-utilities').default; |
4 | 7 |
|
5 | 8 | jest.mock('@contentstack/cli-utilities', () => cliUtilitiesJestMock); |
| 9 | +jest.mock('timers/promises', () => ({ setTimeout: jest.fn().mockResolvedValue(undefined) })); |
| 10 | + |
| 11 | +function makeWatchQuery() { |
| 12 | + let subscriber: (result: any) => void = () => {}; |
| 13 | + return { |
| 14 | + subscribe: jest.fn((cb: (result: any) => void) => { |
| 15 | + subscriber = cb; |
| 16 | + return { unsubscribe: jest.fn() }; |
| 17 | + }), |
| 18 | + setVariables: jest.fn(), |
| 19 | + stopPolling: jest.fn(), |
| 20 | + emit: (result: any) => subscriber(result), |
| 21 | + }; |
| 22 | +} |
6 | 23 |
|
7 | 24 | const CONFIG = { |
8 | 25 | deployment: 'd1', |
@@ -115,3 +132,66 @@ describe('LogPolling Apollo deprecation regression', () => { |
115 | 132 | expect(watchQuery).toHaveBeenCalledTimes(1); |
116 | 133 | }); |
117 | 134 | }); |
| 135 | + |
| 136 | +describe('cancelled deployment stops log polling', () => { |
| 137 | + function buildInstance(deploymentStatus: string[]) { |
| 138 | + const statusWatchQuery = makeWatchQuery(); |
| 139 | + const logsWatchQuery = makeWatchQuery(); |
| 140 | + const config = { |
| 141 | + deployment: 'd1', |
| 142 | + environment: 'e1', |
| 143 | + pollingInterval: 1000, |
| 144 | + deploymentStatus, |
| 145 | + }; |
| 146 | + const instance = new LogPolling({ |
| 147 | + apolloManageClient: { watchQuery: jest.fn().mockReturnValue(statusWatchQuery) } as any, |
| 148 | + apolloLogsClient: { watchQuery: jest.fn().mockReturnValue(logsWatchQuery) } as any, |
| 149 | + config: config as any, |
| 150 | + $event: new EventEmitter(), |
| 151 | + }); |
| 152 | + return { instance, statusWatchQuery, logsWatchQuery, config }; |
| 153 | + } |
| 154 | + |
| 155 | + it('stops status polling once the deployment status is CANCELLED', async () => { |
| 156 | + const { instance, statusWatchQuery } = buildInstance(['LIVE', 'FAILED', 'SKIPPED', 'DEPLOYED', 'CANCELLED']); |
| 157 | + |
| 158 | + await instance.deploymentLogs(); |
| 159 | + statusWatchQuery.emit({ data: { Deployment: { status: 'CANCELLED' } } }); |
| 160 | + |
| 161 | + expect(instance.deploymentStatus).toBe('CANCELLED'); |
| 162 | + expect(statusWatchQuery.stopPolling).toHaveBeenCalledTimes(1); |
| 163 | + }); |
| 164 | + |
| 165 | + it('stops deployment-logs polling and emits DONE once status is CANCELLED', async () => { |
| 166 | + const { instance, statusWatchQuery, logsWatchQuery } = buildInstance([ |
| 167 | + 'LIVE', |
| 168 | + 'FAILED', |
| 169 | + 'SKIPPED', |
| 170 | + 'DEPLOYED', |
| 171 | + 'CANCELLED', |
| 172 | + ]); |
| 173 | + const events: string[] = []; |
| 174 | + (instance as any).$event.on('deployment-logs', (e: any) => events.push(e.message)); |
| 175 | + |
| 176 | + await instance.deploymentLogs(); |
| 177 | + statusWatchQuery.emit({ data: { Deployment: { status: 'CANCELLED' } } }); |
| 178 | + await logsWatchQuery.emit({ data: { getLogs: [] } }); |
| 179 | + |
| 180 | + expect(logsWatchQuery.stopPolling).toHaveBeenCalledTimes(1); |
| 181 | + expect(events).toContain('DONE'); |
| 182 | + }); |
| 183 | + |
| 184 | + it('regression guard: keeps polling forever if CANCELLED is missing from deploymentStatus', async () => { |
| 185 | + const { instance, statusWatchQuery } = buildInstance(['LIVE', 'FAILED', 'SKIPPED', 'DEPLOYED']); |
| 186 | + |
| 187 | + await instance.deploymentLogs(); |
| 188 | + statusWatchQuery.emit({ data: { Deployment: { status: 'CANCELLED' } } }); |
| 189 | + |
| 190 | + expect(instance.deploymentStatus).toBe('CANCELLED'); |
| 191 | + expect(statusWatchQuery.stopPolling).not.toHaveBeenCalled(); |
| 192 | + }); |
| 193 | + |
| 194 | + it('real app config (src/config) lists CANCELLED as a terminal deployment status', () => { |
| 195 | + expect(defaultConfig.deploymentStatus).toContain('CANCELLED'); |
| 196 | + }); |
| 197 | +}); |
0 commit comments