import { OnboardingClient } from '../clients/OnboardingClient'; import { OnboardingService } from './OnboardingService'; import { OnboardingStatusRequestParams, OnboardingStatusResponse } from '../entities/Onboarding'; import { onboardingStatusRequestParams } from '../entities/Onboarding.fixture'; import { appConfig } from '../entities/AppConfig.fixture'; import { Mock, It, IMock, Times } from 'typemoq'; import { $q, $timeout } from '../util/PromiseUtils'; import { expect } from 'chai'; describe('Onboarding service', () => { let onboardingClient: IMock; let onboardingService: OnboardingService; beforeEach(() => { onboardingClient = Mock.ofType(); onboardingService = new OnboardingService(onboardingClient.object, $q, $timeout); }); it('should return immediately if endpoint is successful', () => { onboardingClient.setup(_ => _.getOnboardingStatus(It.isAny(), It.isAny())).returns(_ => Promise.resolve({ data: { allAccountsExist: true } })).verifiable(Times.once()); const pollOnboarding = onboardingService.pollOnboarding(onboardingStatusRequestParams, 1) onboardingClient.verifyAll(); return expect(pollOnboarding).to.eventually.deep.equal({ allAccountsExist: true }); }); it('should call the endpoint again if endpoint fails', () => { onboardingClient.setup(_ => _.getOnboardingStatus(It.isAny(), It.isAny())).returns(_ => Promise.reject>({})).verifiable(Times.once()); onboardingClient.setup(_ => _.getOnboardingStatus(It.isAny(), It.isAny())).returns(_ => Promise.resolve({ data: { allAccountsExist: true } })).verifiable(Times.once()); const pollOnboarding = onboardingService.pollOnboarding(onboardingStatusRequestParams, 1); onboardingClient.verifyAll(); return expect(pollOnboarding).to.eventually.deep.equal({ allAccountsExist: true }); }); it("should call the endpoint again if accounts don't exist yet", () => { onboardingClient.setup(_ => _.getOnboardingStatus(It.isAny(), It.isAny())).returns(_ => Promise.resolve({ data: { allAccountsExist: false } })).verifiable(Times.once()); onboardingClient.setup(_ => _.getOnboardingStatus(It.isAny(), It.isAny())).returns(_ => Promise.resolve({ data: { allAccountsExist: true } })).verifiable(Times.once()); const pollOnboarding = onboardingService.pollOnboarding(onboardingStatusRequestParams, 1); onboardingClient.verifyAll(); return expect(pollOnboarding).to.eventually.deep.equal({ allAccountsExist: true }); }); it('should wait for the minimum interval before retrying the endpoint', () => { onboardingClient.setup(_ => _.getOnboardingStatus(It.isAny(), It.isAny())).returns(_ => Promise.reject>({})) .verifiable(Times.exactly(3)); // We know that it waited for the minimum interval, because if it didn't there would have been many more calls here return onboardingService.pollOnboarding(onboardingStatusRequestParams, 40, 100).catch(() => onboardingClient.verifyAll()); }); it("should fail if the endpoint doesn't return before the timeout", () => { onboardingClient.setup(_ => _.getOnboardingStatus(It.isAny(), It.isAny())).returns(_ => $timeout(() => ({ data: { allAccountsExist: false } }), 50)) .verifiable(Times.once()); // Overall timeout is less than the API response time above return onboardingService.pollOnboarding(onboardingStatusRequestParams, 1, 10).catch(() => onboardingClient.verifyAll()); }); it("should fail if the accounts don't exist before the timeout", () => { onboardingClient.setup(_ => _.getOnboardingStatus(It.isAny(), It.isAny())).returns(_ => Promise.resolve({ data: { allAccountsExist: false } })) .verifiable(Times.exactly(2)); return onboardingService.pollOnboarding(onboardingStatusRequestParams, 20, 30).catch(() => onboardingClient.verifyAll()); }); });