import {PlanPaygController} from './PlanPayg'; import {QuoteService} from '../../common/services/QuoteService'; import {UserDataState} from '../../common/state/UserDataState'; import {LayoutState} from "../../common/state/LayoutState"; import {AnalyticsService} from '../../common/services/AnalyticsService'; import {ModalService} from '../../common/services/ModalService'; import {EligibilityService} from '../../common/services/EligibilityService'; import {PropertyQuestionsService} from '../../common/services/PropertyQuestionsService'; import {HostExtractor} from '../../common/util/HostExtractor'; import {QuoteWithMeters, SaveQuoteResponse} from '../../common/entities/Quote'; import {paygQuoteWithMeters} from '../../common/entities/Quote.fixture'; import {Eligibility, Availability} from "../../common/entities/Eligibility" import {eligibility, availability} from "../../common/entities/Eligibility.fixture" import {Mock, IMock, It, Times} from 'typemoq'; import {expect} from 'chai'; describe('Paym plan page controller', () => { let $state: IMock; let $window: IMock; let layoutState: IMock; let quoteService: IMock; let analyticsService: IMock; let modal: IMock; let userDataState: UserDataState; let eligibilityService: IMock; let propertyQuestionsService: IMock; let host: IMock; function newController() { return new PlanPaygController( $state.object, $window.object, layoutState.object, userDataState, quoteService.object, analyticsService.object, modal.object, eligibilityService.object, propertyQuestionsService.object, host.object, ); } beforeEach(() => { $state = Mock.ofType(); $window = Mock.ofType(); layoutState = Mock.ofType(); userDataState = {} as UserDataState; quoteService = Mock.ofType(); analyticsService = Mock.ofType(); modal = Mock.ofType(); eligibilityService = Mock.ofType(); propertyQuestionsService = Mock.ofType(); host = Mock.ofType(); }); it('should navigate to the get-quote page if there is an error loading the quote', () => { const ctrl = newController(); quoteService.setup(x => x.getQuote()).returns(() => Promise.reject('error')); return ctrl.$onInit().then(() => $state.verify(x => x.go(It.isValue('^.get-quote')), Times.once()) ); }); it('should not check eligibility for communities', () => { const ctrl = newController(); host.setup(x => x.retailer).returns(() => "Fairerpower"); quoteService.setup(x => x.getQuote()).returns(() => Promise.resolve(paygQuoteWithMeters)); return ctrl.$onInit().then(() => eligibilityService.verify(x => x.checkSupplyAddress(), Times.never()) ); }); it('should check eligibility for OVO', () => { const ctrl = newController(); host.setup(x => x.retailer).returns(() => "OVO"); quoteService.setup(x => x.getQuote()).returns(() => Promise.resolve(paygQuoteWithMeters)); eligibilityService.setup(x => x.checkSupplyAddress()).returns(() => Promise.resolve({ ...eligibility, status: 'MeterNotEligible' })); return ctrl.$onInit().then(() => { expect(ctrl.eligibility.status).to.equal('MeterNotEligible'); propertyQuestionsService.verify(x => x.getEligibilityStatus(), Times.never()); }); }); it('should default to eligible on error', () => { const ctrl = newController(); host.setup(x => x.retailer).returns(() => "OVO"); quoteService.setup(x => x.getQuote()).returns(() => Promise.resolve(paygQuoteWithMeters)); eligibilityService.setup(x => x.checkSupplyAddress()).returns(() => Promise.reject('error')); return expect(ctrl.$onInit().then(() => ctrl.eligibility.status)).to.eventually.equal('Eligible'); }); it('should not check property status if smart meter not required', () => { const ctrl = newController(); host.setup(x => x.retailer).returns(() => "OVO"); quoteService.setup(x => x.getQuote()).returns(() => Promise.resolve(paygQuoteWithMeters)); eligibilityService.setup(x => x.checkSupplyAddress()).returns(() => Promise.resolve({ ...eligibility, smartMeterRequired: false })); return ctrl.$onInit().then(() => { expect(ctrl.eligibility.status).to.equal('Eligible'); propertyQuestionsService.verify(x => x.getEligibilityStatus(), Times.never()); }); }); it('should check property questions if eligible and smart meter required', () => { const ctrl = newController(); host.setup(x => x.retailer).returns(() => "OVO"); quoteService.setup(x => x.getQuote()).returns(() => Promise.resolve(paygQuoteWithMeters)); eligibilityService.setup(x => x.checkSupplyAddress()).returns(() => Promise.resolve(eligibility)); propertyQuestionsService.setup(x => x.getEligibilityStatus()).returns(() => 'PropertyNotEligible'); return ctrl.$onInit().then(() => { expect(ctrl.eligibility.status).to.equal('PropertyNotEligible'); expect(ctrl.propertyQuestionsAnswered).to.be.true; }); }); it('should check availability if completely eligible and smart meter required', () => { const ctrl = newController(); host.setup(x => x.retailer).returns(() => "OVO"); quoteService.setup(x => x.getQuote()).returns(() => Promise.resolve(paygQuoteWithMeters)); eligibilityService.setup(x => x.checkSupplyAddress()).returns(() => Promise.resolve(eligibility)); propertyQuestionsService.setup(x => x.getEligibilityStatus()).returns(() => 'Eligible'); eligibilityService.setup(x => x.checkAvailability()).returns(() => Promise.resolve(availability)); return ctrl.$onInit().then(() => { expect(ctrl.eligibility.status).to.equal('Eligible'); expect(ctrl.propertyQuestionsAnswered).to.be.true; expect(ctrl.availability).to.deep.equal(availability); }); }); it('should default to high availability on error', () => { const ctrl = newController(); host.setup(x => x.retailer).returns(() => "OVO"); quoteService.setup(x => x.getQuote()).returns(() => Promise.resolve(paygQuoteWithMeters)); eligibilityService.setup(x => x.checkSupplyAddress()).returns(() => Promise.resolve(eligibility)); propertyQuestionsService.setup(x => x.getEligibilityStatus()).returns(() => 'Eligible'); eligibilityService.setup(x => x.checkAvailability()).returns(() => Promise.reject({})); return ctrl.$onInit().then(() => { expect(ctrl.eligibility.status).to.equal('Eligible'); expect(ctrl.propertyQuestionsAnswered).to.be.true; expect(ctrl.availability.appointmentAvailability).to.equal('High'); }); }); it('should handle errors when saving a quote', () => { quoteService.setup(x => x.saveQuote(It.isAny())).returns(() => Promise.reject>('error')); userDataState.tariffId = 'Fixed'; userDataState.emailAddress = 'test@test.com'; const ctrl = newController(); return expect(ctrl.saveQuote().then(() => ctrl.error)).to.eventually.equal('Sorry, we could not save your quote. Please try again later.'); }); it('should be able to save a quote', () => { const ctrl = newController(); ctrl.email = 'test@test.com'; quoteService.setup(x => x.saveQuote(It.isAny())).returns(() => Promise.resolve({data: {id: '1'}})); return expect(ctrl.saveQuote().then(() => ctrl.saved)).to.eventually.equal(true); }); it('should transition to the switch form for communities', () => { const ctrl = newController(); ctrl.eligibility = undefined; ctrl.submit(); $state.verify(x => x.go(It.isValue('^.switch')), Times.once()); }); it('should transition to the switch form if ineligible', () => { const ctrl = newController(); ctrl.eligibility = { ...eligibility, status: 'AreaNotEligible' }; ctrl.submit(); $state.verify(x => x.go(It.isValue('^.switch')), Times.once()); }); it('should transition to the switch form if customer has a smart meter already', () => { const ctrl = newController(); ctrl.eligibility = { ...eligibility, smartMeterRequired: false }; ctrl.submit(); $state.verify(x => x.go(It.isValue('^.switch')), Times.once()); }); it('should transition to the switch form if customer has answered the property questions', () => { const ctrl = newController(); ctrl.eligibility = eligibility; ctrl.propertyQuestionsAnswered = true; ctrl.submit(); $state.verify(x => x.go(It.isValue('^.switch')), Times.once()); }); it('should transition to the property questions otherwise', () => { const ctrl = newController(); ctrl.eligibility = eligibility; ctrl.submit(); $state.verify(x => x.go(It.isValue('^.property-questions')), Times.once()); }); });