update-service.test.js 6.73 KB
/*
 * ADOBE CONFIDENTIAL
 * __________________
 *
 *  Copyright 2016 Adobe Systems Incorporated
 *  All Rights Reserved.
 *
 * NOTICE:  All information contained herein is, and remains
 * the property of Adobe Systems Incorporated and its suppliers,
 * if any.  The intellectual and technical concepts contained
 * herein are proprietary to Adobe Systems Incorporated and its
 * suppliers and are protected by trade secret or copyright law.
 * Dissemination of this information or reproduction of this material
 * is strictly forbidden unless prior written permission is obtained
 * from Adobe Systems Incorporated.
 */

/* eslint max-nested-callbacks: [2, 10]*/
/* eslint no-new: 0 */

/* globals describe, it, beforeEach, expect, afterEach, Promise */
define([
    'screens/player/firmware/update/impl/update-service',
    'screens/player/shared/serviceadmin',
    'screens/player/firmware/preferences/preferences',
    'screens/player/firmware/update/update',
    'screens/player/firmware/update/spi/update',
    'screens/player/store/store',
    'screens/player/store/statemachine-adapter',
    'screens/player/shared/test-helper/stub-service-interface',
    'screens/player/shared/test-helper/mock-store-service'
], function(UpdateService, ServiceAdmin, Preferences, Update, UpdateSpi, Store, StateMachineAdapter, stubServiceInterface, mockStoreService) {
    'use strict';

    function createTransitionAction(prop) {
        return {
            type: StateMachineAdapter.EVENTS.CHANGE,
            payload: { transitionTo: prop }
        };
    }

    function createUpdateStoreState(state) {
        return {
            progress: state
        };
    }

    function createSpiParams(serverUrl) {
        return {
            serverURL: serverUrl,
            id: 'firmware',
            idPrefix: '',
            trustAllHosts: true,
            requestHeaders: { 'X-Requested-With': 'XMLHttpRequest' }
        };
    }

    describe('screens/player/firmware/update/impl/update-service', function() {

        var updateService;
        var mockedStoreService;
        var stubUpdateSpiService;

        beforeEach(function() {
            mockedStoreService = mockStoreService(stubServiceInterface(ServiceAdmin, Store));
            stubUpdateSpiService = stubServiceInterface(ServiceAdmin, UpdateSpi);
            updateService = new UpdateService();
        });

        afterEach(function() {
            mockedStoreService.restore();
            stubUpdateSpiService.restore();
        });

        it('should have an id', function() {
            expect(updateService.serviceId).to.be.ok;
        });

        describe('activation', function() {
            it('returns a resolved Promise', function() {
                return updateService.activate();
            });
            it('dispatches "undefined" action', function() {
                return updateService.activate().then(function() {
                    expect(mockedStoreService.api.dispatch.calledWithMatch({
                        type: StateMachineAdapter.EVENTS.CHANGE,
                        payload: {
                            transitionTo: void 0
                        }
                    })).to.be.ok;
                });
            });
        });

        describe('API (after activation)', function() {
            beforeEach(function() {
                return updateService.activate().then(function() {
                    // Track events as of now. Ignore events that happened previously.
                    mockedStoreService.api.dispatch.reset();
                    mockedStoreService.publish(Preferences.NAMESPACE, { server: 'some server' });
                });
            });

            describe('hasStepByStepSupport()', function() {
                it('returns false when SPI returns false', function() {
                    stubUpdateSpiService.api.hasStepByStepSupport.returns(false);
                    expect(updateService.hasStepByStepSupport()).to.be.false;
                });
                it('returns true when SPI returns true', function() {
                    stubUpdateSpiService.api.hasStepByStepSupport.returns(true);
                    expect(updateService.hasStepByStepSupport()).to.be.true;
                });
            });

            describe('update()', function() {

                it('returns a Promise', function() {
                    expect(updateService.update()).to.be.an.instanceof(Promise);
                });

                it('rejects follow-up calls', function() {
                    updateService.update();
                    return updateService.update().catch(function(e) {
                        expect(e).to.eql('Update task still running.');
                    });
                });

                it('initially transitions to "check"', function() {
                    updateService.update();
                    expect(mockedStoreService.api.dispatch.calledWithMatch(createTransitionAction('check'))).to.be.ok;
                });

                it('handles "START" and calls UpdateSPIs "start" method', function() {
                    updateService.update();
                    stubUpdateSpiService.api.start.returns(Promise.resolve());
                    mockedStoreService.publish(Update.NAMESPACE, createUpdateStoreState(Update.STATES.START));
                    expect(stubUpdateSpiService.api.start.calledWithMatch(createSpiParams('some server'))).to.be.ok;
                });

                it('handles "START" and transitions to "ok" on success', function(done) {
                    var resolvedStart = Promise.resolve();
                    updateService.update();
                    mockedStoreService.api.dispatch.reset();
                    stubUpdateSpiService.api.start.returns(resolvedStart);
                    mockedStoreService.publish(Update.NAMESPACE, createUpdateStoreState(Update.STATES.START));
                    resolvedStart.then(function() {
                        expect(mockedStoreService.api.dispatch.calledWithMatch(createTransitionAction('ok'))).to.be.ok;
                        done();
                    });
                });

                it('handles "START" and transitions to "error" on failure', function(done) {
                    var rejectedStart = Promise.reject();
                    updateService.update();
                    mockedStoreService.api.dispatch.reset();
                    stubUpdateSpiService.api.start.returns(rejectedStart);
                    mockedStoreService.publish(Update.NAMESPACE, createUpdateStoreState(Update.STATES.START));
                    rejectedStart.catch(function() {
                        expect(mockedStoreService.api.dispatch.calledWithMatch(createTransitionAction('error'))).to.be.ok;
                        done();
                    });
                });

            });
        });

    });
});