/** @jest-environment jsdom */ import { baseJourneyDef, useJourneyTestRuntime } from '../../__test-utils__/test-runtime'; import { singleInFlightJourneyStep, completeJourney, journeyStep, JourneyStepStamp, } from '../../core'; import { moduleRuntime } from '../../core/runtime'; const emitMock = jest.fn(); const baseDef = { ...baseJourneyDef, name: 'ambient-a' }; const otherDef = { ...baseJourneyDef, name: 'ambient-b' }; describe('[journey] singleInFlightJourneyStep', () => { useJourneyTestRuntime(emitMock); describe('around a single step', () => { beforeEach(() => { moduleRuntime.startJourney(baseDef); }); test('is set only while the step is running', async () => { expect(singleInFlightJourneyStep()).toBeNull(); await journeyStep(baseDef.name, 'do-work', () => { expect(singleInFlightJourneyStep()).toBeInstanceOf(JourneyStepStamp); }); expect(singleInFlightJourneyStep()).toBeNull(); completeJourney(baseDef.name); }); }); describe('when two steps overlap', () => { let releaseA!: () => void; let stepA: Promise; beforeEach(() => { moduleRuntime.startJourney(baseDef); moduleRuntime.startJourney(otherDef); const gateA = new Promise(r => { releaseA = r; }); stepA = journeyStep(baseDef.name, 'load', async () => { await gateA; }); }); afterEach(async () => { releaseA(); await stepA; completeJourney(baseDef.name); completeJourney(otherDef.name); }); const subject = () => journeyStep(otherDef.name, 'book', () => singleInFlightJourneyStep()); test('returns null', async () => { await expect(subject()).resolves.toBeNull(); }); }); describe('when the first-finishing sibling ends first', () => { let releaseB!: () => void; let stepB: Promise; let ambientWhileBAlone: ReturnType | 'unset'; beforeEach(() => { moduleRuntime.startJourney(baseDef); moduleRuntime.startJourney(otherDef); ambientWhileBAlone = 'unset'; const gateB = new Promise(r => { releaseB = r; }); stepB = journeyStep(otherDef.name, 'book', async () => { await gateB; ambientWhileBAlone = singleInFlightJourneyStep(); }); }); afterEach(async () => { releaseB(); await stepB; completeJourney(baseDef.name); completeJourney(otherDef.name); }); test('keeps ambient on the remaining step', async () => { await journeyStep(baseDef.name, 'load', () => { expect(singleInFlightJourneyStep()).toBeNull(); }); releaseB(); await stepB; expect(ambientWhileBAlone).not.toBeNull(); expect(ambientWhileBAlone).not.toBe('unset'); if (ambientWhileBAlone === 'unset' || ambientWhileBAlone == null) { throw new Error('expected ambient step'); } expect(ambientWhileBAlone).toBeInstanceOf(JourneyStepStamp); expect(ambientWhileBAlone.step.name).toBe('book'); }); }); });