<commit_before>define([
    'dojo/_base/declare',
    'dojo/_base/lang',
    'dojo/on',
    'dojo/dom',
    'dojo/_base/array',
    'dojo/Deferred',

    'esri/map',

    'esri/IdentityManager'

], function (
    declare,
    lang,
    on,
    dom,
    array,
    Deferred,

    Map
) {

    return declare(null, {

        postConfig: function () {
            this.mapDeferred = new Deferred();
            return this.inherited(arguments);
        },

        startup: function () {
            // ignore visibility of group layers in dynamic layers?
            this.ignoreDynamicGroupVisibility = (this.config.ignoreDynamicGroupVisibility === false) ? false : true;
            this.inherited(arguments);
            this.layoutDeferred.then(lang.hitch(this, 'initMapAsync'));
        },

        initMapAsync: function () {
            var returnDeferred = new Deferred();
            var returnWarnings = [];

            this.createMap(returnWarnings).then(
                lang.hitch(this, '_createMapResult', returnDeferred, returnWarnings)
            );
            returnDeferred.then(lang.hitch(this, 'initMapComplete'));
            return returnDeferred;
        },

        createMap: function (returnWarnings) {

            // mixins override the default createMap method and return a deferred
            var result = this.inherited(arguments);
            if (result) {
                return result;
            }

            // otherwise we can create the map
            var mapDeferred = new Deferred(),
                container = dom.byId(this.config.layout.map) || 'mapCenter';

            this.map = new Map(container, this.config.mapOptions);

            // let some other mixins modify or add map items async
            var wait = this.inherited(arguments);
            if (wait) {
                wait.then(function (warnings) {
                    if (warnings) {
                        returnWarnings = returnWarnings.concat(warnings);
                    }
                    mapDeferred.resolve(returnWarnings);
                });
            } else {
                mapDeferred.resolve(returnWarnings);
            }
            return mapDeferred;
        },

        _createMapResult: function (returnDeferred, returnWarnings) {
            if (this.map) {
                if (!this.config.webMapId && this.config.mapOptions && this.config.mapOptions.basemap) {
                    this.map.on('load', lang.hitch(this, '_initLayers', returnWarnings));
                } else {
                    this._initLayers(returnWarnings);
                }

                if (this.config.operationalLayers && this.config.operationalLayers.length > 0) {
                    on.once(this.map, 'layers-add-result', lang.hitch(this, '_onLayersAddResult', returnDeferred, returnWarnings));
                } else {
                    returnDeferred.resolve(returnWarnings);
                }
            } else {
                returnDeferred.resolve(returnWarnings);
            }
            return returnDeferred;
        },

        _onLayersAddResult: function (returnDeferred, returnWarnings, lyrsResult) {
            array.forEach(lyrsResult.layers, function (addedLayer) {
                if (addedLayer.success !== true) {
                    returnWarnings.push(addedLayer.error);
                }
            }, this);
            returnDeferred.resolve(returnWarnings);
        },

        _initLayers: function (returnWarnings) {
            this.layers = [];
            var layerTypes = {
                csv: 'esri/layers/CSVLayer',
                dataadapter: 'esri/layers/DataAdapterFeatureLayer', //untested
                dynamic: 'esri/layers/ArcGISDynamicMapServiceLayer',
                feature: 'esri/layers/FeatureLayer',
                georss: 'esri/layers/GeoRSSLayer',
                graphics: 'esri/layers/GraphicsLayer',
                image: 'esri/layers/ArcGISImageServiceLayer',
                imagevector: 'esri/layers/ArcGISImageServiceVectorLayer',
                kml: 'esri/layers/KMLLayer',
                mapimage: 'esri/layers/MapImageLayer', //untested
                osm: 'esri/layers/OpenStreetMapLayer',
                raster: 'esri/layers/RasterLayer',
                stream: 'esri/layers/StreamLayer',
                tiled: 'esri/layers/ArcGISTiledMapServiceLayer',
                vectortile: 'esri/layers/VectorTileLayer',
                webtiled: 'esri/layers/WebTiledLayer',
                wfs: 'esri/layers/WFSLayer',
                wms: 'esri/layers/WMSLayer',
                wmts: 'esri/layers/WMTSLayer' //untested
            };
            // add any user-defined layer types such as https://github.com/Esri/geojson-layer-js
            layerTypes = lang.mixin(layerTypes, this.config.layerTypes || {});
            // loading all the required modules first ensures the layer order is maintained
            var modules = [];
            array.forEach(this.config.operationalLayers, function (layer) {
                var type = layerTypes[layer.type];
                if (type) {
                    modules.push(type);
                } else {
                    returnWarnings.push('Layer type "' + layer.type + '" is not supported: ');
                }
            }, this);

            require(modules, lang.hitch(this, function () {
                array.forEach(this.config.operationalLayers, function (layer) {
                    var type = layerTypes[layer.type];
                    if (type) {
                        require([type], lang.hitch(this, '_initLayer', layer));
                    }
                }, this);
                this.map.addLayers(this.layers);
            }));
        },

        _initLayer: function (layer, Layer) {
            var l = null;
            if (layer.url) {
                l = new Layer(layer.url, layer.options);
            } else {
                l = new Layer(layer.options);
            }
            this.layers.unshift(l); //unshift instead of push to keep layer ordering on map intact

            //Legend LayerInfos array
            var excludeLayerFromLegend = false;
            if (typeof layer.legendLayerInfos !== 'undefined' && typeof layer.legendLayerInfos.exclude !== 'undefined') {
                excludeLayerFromLegend = layer.legendLayerInfos.exclude;
            }
            if (!excludeLayerFromLegend) {
                var configuredLayerInfo = {};
                if (typeof layer.legendLayerInfos !== 'undefined' && typeof layer.legendLayerInfos.layerInfo !== 'undefined') {
                    configuredLayerInfo = layer.legendLayerInfos.layerInfo;
                }
                var layerInfo = lang.mixin({
                    layer: l,
                    title: layer.title || null
                }, configuredLayerInfo);
                this.legendLayerInfos.unshift(layerInfo); //unshift instead of push to keep layer ordering in legend intact
            }

            //LayerControl LayerInfos array
            var layerControlOptions = lang.mixin({
                ignoreDynamicGroupVisibility: this.ignoreDynamicGroupVisibility
            }, layer.layerControlLayerInfos);
            this.layerControlLayerInfos.unshift({ //unshift instead of push to keep layer ordering in LayerControl intact
                layer: l,
                type: layer.type,
                title: layer.title,
                controlOptions: layerControlOptions
            });

            if (layer.type === 'feature') {
                var options = {
                    featureLayer: l
                };
                if (layer.editorLayerInfos) {
                    lang.mixin(options, layer.editorLayerInfos);
                }
                if (options.exclude !== true) {
                    this.editorLayerInfos.push(options);
                }
            }

            if (layer.type === 'dynamic' && this.ignoreDynamicGroupVisibility) {
                on(l, 'load', lang.hitch(this, 'removeGroupLayers'));
            }

            if (layer.type === 'dynamic' || layer.type === 'feature') {
                var idOptions = {
                    layer: l,
                    title: layer.title,
                    ignoreDynamicGroupVisibility: this.ignoreDynamicGroupVisibility
                };
                if (layer.identifyLayerInfos) {
                    lang.mixin(idOptions, layer.identifyLayerInfos);
                }
                if (idOptions.exclude !== true) {
                    this.identifyLayerInfos.push(idOptions);
                }
            }
        },

        removeGroupLayers: function (res) {
            var visibleLayers = [], groupRemoved = false, layer = res.layer,
                originalVisibleLayers = layer.visibleLayers || layer._defaultVisibleLayers;
            array.forEach(originalVisibleLayers, function (subLayerId) {
                var subLayerInfo = array.filter(layer.layerInfos, function (sli) {
                    return sli.id === subLayerId;
                })[0];
                if (subLayerInfo && subLayerInfo.subLayerIds === null) {
                    visibleLayers.push(subLayerId);
                } else {
                    groupRemoved = true;
                }
            });

            if (visibleLayers.length > 0 && groupRemoved) {
                layer.setVisibleLayers(visibleLayers);
            }
        },

        initMapComplete: function (warnings) {
            if (warnings && warnings.length > 0) {
                this.handleError({
                    source: 'Controller',
                    error: warnings.join(', ')
                });
            }

            if (this.map) {

                this.map.on('resize', function (evt) {
                    var pnt = evt.target.extent.getCenter();
                    setTimeout(function () {
                        evt.target.centerAt(pnt);
                    }, 100);
                });

                // resolve the map deferred
                this.mapDeferred.resolve(this.map);
            }

        },

        initMapError: function (err) {
            this.handleError({
                source: 'Controller',
                error: err
            });
        },

        resizeMap: function () {
            if (this.map) {
                this.map.resize();
            }
        },

        getMapHeight: function () {
            if (this.map) {
                return this.map.height;
            } else {
                return 0;
            }
        }
    });
});
<commit_msg>log layer creation errors<commit_after>define([
    'dojo/_base/declare',
    'dojo/_base/lang',
    'dojo/on',
    'dojo/dom',
    'dojo/_base/array',
    'dojo/Deferred',

    'esri/map',

    'esri/IdentityManager'

], function (
    declare,
    lang,
    on,
    dom,
    array,
    Deferred,

    Map
) {

    return declare(null, {

        postConfig: function () {
            this.mapDeferred = new Deferred();
            return this.inherited(arguments);
        },

        startup: function () {
            // ignore visibility of group layers in dynamic layers?
            this.ignoreDynamicGroupVisibility = (this.config.ignoreDynamicGroupVisibility === false) ? false : true;
            this.inherited(arguments);
            this.layoutDeferred.then(lang.hitch(this, 'initMapAsync'));
        },

        initMapAsync: function () {
            var returnDeferred = new Deferred();
            var returnWarnings = [];

            this.createMap(returnWarnings).then(
                lang.hitch(this, '_createMapResult', returnDeferred, returnWarnings)
            );
            returnDeferred.then(lang.hitch(this, 'initMapComplete'));
            return returnDeferred;
        },

        createMap: function (returnWarnings) {

            // mixins override the default createMap method and return a deferred
            var result = this.inherited(arguments);
            if (result) {
                return result;
            }

            // otherwise we can create the map
            var mapDeferred = new Deferred(),
                container = dom.byId(this.config.layout.map) || 'mapCenter';

            this.map = new Map(container, this.config.mapOptions);

            // let some other mixins modify or add map items async
            var wait = this.inherited(arguments);
            if (wait) {
                wait.then(function (warnings) {
                    if (warnings) {
                        returnWarnings = returnWarnings.concat(warnings);
                    }
                    mapDeferred.resolve(returnWarnings);
                });
            } else {
                mapDeferred.resolve(returnWarnings);
            }
            return mapDeferred;
        },

        _createMapResult: function (returnDeferred, returnWarnings) {
            if (this.map) {
                if (!this.config.webMapId && this.config.mapOptions && this.config.mapOptions.basemap) {
                    this.map.on('load', lang.hitch(this, '_initLayers', returnWarnings));
                } else {
                    this._initLayers(returnWarnings);
                }

                if (this.config.operationalLayers && this.config.operationalLayers.length > 0) {
                    on.once(this.map, 'layers-add-result', lang.hitch(this, '_onLayersAddResult', returnDeferred, returnWarnings));
                } else {
                    returnDeferred.resolve(returnWarnings);
                }
            } else {
                returnDeferred.resolve(returnWarnings);
            }
            return returnDeferred;
        },

        _onLayersAddResult: function (returnDeferred, returnWarnings, lyrsResult) {
            array.forEach(lyrsResult.layers, function (addedLayer) {
                if (addedLayer.success !== true) {
                    returnWarnings.push(addedLayer.error);
                }
            }, this);
            returnDeferred.resolve(returnWarnings);
        },

        _initLayers: function (returnWarnings) {
            this.layers = [];
            var layerTypes = {
                csv: 'esri/layers/CSVLayer',
                dataadapter: 'esri/layers/DataAdapterFeatureLayer', //untested
                dynamic: 'esri/layers/ArcGISDynamicMapServiceLayer',
                feature: 'esri/layers/FeatureLayer',
                georss: 'esri/layers/GeoRSSLayer',
                graphics: 'esri/layers/GraphicsLayer',
                image: 'esri/layers/ArcGISImageServiceLayer',
                imagevector: 'esri/layers/ArcGISImageServiceVectorLayer',
                kml: 'esri/layers/KMLLayer',
                mapimage: 'esri/layers/MapImageLayer', //untested
                osm: 'esri/layers/OpenStreetMapLayer',
                raster: 'esri/layers/RasterLayer',
                stream: 'esri/layers/StreamLayer',
                tiled: 'esri/layers/ArcGISTiledMapServiceLayer',
                vectortile: 'esri/layers/VectorTileLayer',
                webtiled: 'esri/layers/WebTiledLayer',
                wfs: 'esri/layers/WFSLayer',
                wms: 'esri/layers/WMSLayer',
                wmts: 'esri/layers/WMTSLayer' //untested
            };
            // add any user-defined layer types such as https://github.com/Esri/geojson-layer-js
            layerTypes = lang.mixin(layerTypes, this.config.layerTypes || {});
            // loading all the required modules first ensures the layer order is maintained
            var modules = [];
            array.forEach(this.config.operationalLayers, function (layer) {
                var type = layerTypes[layer.type];
                if (type) {
                    modules.push(type);
                } else {
                    returnWarnings.push('Layer type "' + layer.type + '" is not supported: ');
                }
            }, this);

            require(modules, lang.hitch(this, function () {
                array.forEach(this.config.operationalLayers, function (layer) {
                    var type = layerTypes[layer.type];
                    if (type) {
                        require([type], lang.hitch(this, '_initLayer', layer));
                    }
                }, this);
                this.map.addLayers(this.layers);
            }));
        },

        _initLayer: function (layer, Layer) {
            var l = null;
            try {
                if (layer.url) {
                    l = new Layer(layer.url, layer.options);
                } else {
                    l = new Layer(layer.options);
                }
                this.layers.unshift(l); //unshift instead of push to keep layer ordering on map intact
            } catch (e) {
                console.warn('_MapMixin::error creating layer ', layer, e.stack);
            }

            //Legend LayerInfos array
            var excludeLayerFromLegend = false;
            if (typeof layer.legendLayerInfos !== 'undefined' && typeof layer.legendLayerInfos.exclude !== 'undefined') {
                excludeLayerFromLegend = layer.legendLayerInfos.exclude;
            }
            if (!excludeLayerFromLegend) {
                var configuredLayerInfo = {};
                if (typeof layer.legendLayerInfos !== 'undefined' && typeof layer.legendLayerInfos.layerInfo !== 'undefined') {
                    configuredLayerInfo = layer.legendLayerInfos.layerInfo;
                }
                var layerInfo = lang.mixin({
                    layer: l,
                    title: layer.title || null
                }, configuredLayerInfo);
                this.legendLayerInfos.unshift(layerInfo); //unshift instead of push to keep layer ordering in legend intact
            }

            //LayerControl LayerInfos array
            var layerControlOptions = lang.mixin({
                ignoreDynamicGroupVisibility: this.ignoreDynamicGroupVisibility
            }, layer.layerControlLayerInfos);
            this.layerControlLayerInfos.unshift({ //unshift instead of push to keep layer ordering in LayerControl intact
                layer: l,
                type: layer.type,
                title: layer.title,
                controlOptions: layerControlOptions
            });

            if (layer.type === 'feature') {
                var options = {
                    featureLayer: l
                };
                if (layer.editorLayerInfos) {
                    lang.mixin(options, layer.editorLayerInfos);
                }
                if (options.exclude !== true) {
                    this.editorLayerInfos.push(options);
                }
            }

            if (layer.type === 'dynamic' && this.ignoreDynamicGroupVisibility) {
                on(l, 'load', lang.hitch(this, 'removeGroupLayers'));
            }

            if (layer.type === 'dynamic' || layer.type === 'feature') {
                var idOptions = {
                    layer: l,
                    title: layer.title,
                    ignoreDynamicGroupVisibility: this.ignoreDynamicGroupVisibility
                };
                if (layer.identifyLayerInfos) {
                    lang.mixin(idOptions, layer.identifyLayerInfos);
                }
                if (idOptions.exclude !== true) {
                    this.identifyLayerInfos.push(idOptions);
                }
            }
        },

        removeGroupLayers: function (res) {
            var visibleLayers = [], groupRemoved = false, layer = res.layer,
                originalVisibleLayers = layer.visibleLayers || layer._defaultVisibleLayers;
            array.forEach(originalVisibleLayers, function (subLayerId) {
                var subLayerInfo = array.filter(layer.layerInfos, function (sli) {
                    return sli.id === subLayerId;
                })[0];
                if (subLayerInfo && subLayerInfo.subLayerIds === null) {
                    visibleLayers.push(subLayerId);
                } else {
                    groupRemoved = true;
                }
            });

            if (visibleLayers.length > 0 && groupRemoved) {
                layer.setVisibleLayers(visibleLayers);
            }
        },

        initMapComplete: function (warnings) {
            if (warnings && warnings.length > 0) {
                this.handleError({
                    source: 'Controller',
                    error: warnings.join(', ')
                });
            }

            if (this.map) {

                this.map.on('resize', function (evt) {
                    var pnt = evt.target.extent.getCenter();
                    setTimeout(function () {
                        evt.target.centerAt(pnt);
                    }, 100);
                });

                // resolve the map deferred
                this.mapDeferred.resolve(this.map);
            }

        },

        initMapError: function (err) {
            this.handleError({
                source: 'Controller',
                error: err
            });
        },

        resizeMap: function () {
            if (this.map) {
                this.map.resize();
            }
        },

        getMapHeight: function () {
            if (this.map) {
                return this.map.height;
            }
            return 0;

        }
    });
});
<|endoftext|>


<commit_before>var Observable = require('../../../../lib/observable/')
var tracking = require('../../../../lib/tracking/')
var trackerEmitter = require('../../../../lib/tracking/emitter')
var Event = require('../../../../lib/event/')

trackerEmitter.inject(require('../../../../lib/tracking/service/log'))

// this is just to log stuff (.toString yields nicer result for events)
Event.prototype.inject(require('../../../../lib/event/toString'))

describe('direct tracking', function () {
  it('should contain all default keys', function (done) {
    var a = new Observable({
      key: 'a',
      b: {
        inject: tracking,
        on: {
          error: function (event, meta) {}
        },
        track: true
      }
    })

    trackerEmitter.services.test = function (obj) {
      expect(obj)
        .to.have.deep.property('eventobject')
      done()
    }
    a.b.emit('change')
  })

  it('should track an error event correctly', function (done) {
    var a = new Observable({
      key: 'a',
      b: {
        inject: tracking,
        on: {
          error: function () {}
        },
        track: true
      }
    })

    trackerEmitter.services.test = function (obj) {
      // check for error type (array || error)
      expect(obj.eventobject.eventType.val).to.equal('error')
      expect(obj.eventobject.metaMessage).to.be.ok
      done()
    }
    a.b.emit('error')
  })

  it('reference (other event origin)', function (done) {
    var exampleReference = new Observable({
      b: {
        key: 'aReference'
      }
    })

    var a = new Observable({
      key: 'a',
      b: {
        val: exampleReference.b,
        inject: tracking,
        on: {
          error: function (data, event) {}
        },
        track: true
      }
    })

    trackerEmitter.services.test = function (obj) {
      // check for change type
      expect(obj.eventobject.eventOriginator.val).to.equal('aReference')
      done()
    }
    exampleReference.b.val = 'rick'
  })

  it('should override id if tracking val is a string', function (done) {
    var a = new Observable({
      key: 'a',
      b: {
        inject: tracking,
        on: {
          change: function (event, meta) {}
        },
        track: 'test string'
      }
    })

    trackerEmitter.services.test = function (obj) {
      expect(obj.id.val).to.have.string('test string')
      done()
    }
    a.b.emit('change')
  })
})
<commit_msg>disable logs<commit_after>var Observable = require('../../../../lib/observable/')
var tracking = require('../../../../lib/tracking/')
var trackerEmitter = require('../../../../lib/tracking/emitter')
var Event = require('../../../../lib/event/')

// trackerEmitter.inject(require('../../../../lib/tracking/service/log'))

// this is just to log stuff (.toString yields nicer result for events)
Event.prototype.inject(require('../../../../lib/event/toString'))

describe('direct tracking', function () {
  it('should contain all default keys', function (done) {
    var a = new Observable({
      key: 'a',
      b: {
        inject: tracking,
        on: {
          error: function (event, meta) {}
        },
        track: true
      }
    })

    trackerEmitter.services.test = function (obj) {
      expect(obj)
        .to.have.deep.property('eventobject')
      done()
    }
    a.b.emit('change')
  })

  it('should track an error event correctly', function (done) {
    var a = new Observable({
      key: 'a',
      b: {
        inject: tracking,
        on: {
          error: function () {}
        },
        track: true
      }
    })

    trackerEmitter.services.test = function (obj) {
      // check for error type (array || error)
      expect(obj.eventobject.eventType.val).to.equal('error')
      expect(obj.eventobject.metaMessage).to.be.ok
      done()
    }
    a.b.emit('error')
  })

  it('reference (other event origin)', function (done) {
    var exampleReference = new Observable({
      b: {
        key: 'aReference'
      }
    })

    var a = new Observable({
      key: 'a',
      b: {
        val: exampleReference.b,
        inject: tracking,
        on: {
          error: function (data, event) {}
        },
        track: true
      }
    })

    trackerEmitter.services.test = function (obj) {
      // check for change type
      expect(obj.eventobject.eventOriginator.val).to.equal('aReference')
      done()
    }
    exampleReference.b.val = 'rick'
  })

  it('should override id if tracking val is a string', function (done) {
    var a = new Observable({
      key: 'a',
      b: {
        inject: tracking,
        on: {
          change: function (event, meta) {}
        },
        track: 'test string'
      }
    })

    trackerEmitter.services.test = function (obj) {
      expect(obj.id.val).to.have.string('test string')
      done()
    }
    a.b.emit('change')
  })
})
<|endoftext|>


<commit_before>/*
 * 2010-2020 Sellermania / Froggy Commerce / 23Prod SARL
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Academic Free License (AFL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/afl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to team@froggy-commerce.com so we can send you a copy immediately.
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade your module to newer
 * versions in the future.
 *
 *  @author         Froggy Commerce <team@froggy-commerce.com>
 *  @copyright      2010-2020 Sellermania / Froggy Commerce / 23Prod SARL
 *  @version        1.0
 *  @license        http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
 */

$(document).ready(function() {

    // Fill product details
    var nb_buttons = 0;
    for (i = 1; sellermania_block_products_list[i]; i++)
    {
        var sm_block_product = sellermania_block_products_list[i];

        var sku_short = sm_block_product.html().split('
');
        if (typeof sku_short[1] !== 'undefined') {
            sku_short = sku_short[1];
        } else {
            sku_short = sku_short[0];
        }
        sku_short = sku_short.replace(/(\r\n|\n|\r)/gm, "").replace(/\s+/g, ' ').trim()

		sku_short = sku_short.replace('Numéro de référence', 'Ref').replace('Reference number', 'Ref');
		var remove = sku_short.trim().split(' ');
        if (remove[1] == ':')
            sku_short = sku_short.replace(remove[0] + ' ' + remove[1], '').trim();
        else
            sku_short = sku_short.replace(remove[0], '').trim();

        if (sku_short != '' && typeof sellermania_products[sku_short] != 'undefined')
        {
            var html_order_line = '';
            if (sellermania_products[sku_short].insurance_price > 0)
                html_order_line += '
' + insurance_price_label + ' ' + sellermania_products[sku_short].insurance_price + ' ' + sellermania_products[sku_short].currency + '
';
            if (sellermania_products[sku_short].order_item_id != '') html_order_line += '
' + order_item_id_label + ' ' + sellermania_products[sku_short].order_item_id + '
';
            if (sellermania_products[sku_short].external_order_id != '') html_order_line += '
' + external_order_id_label + ' ' + sellermania_products[sku_short].external_order_id + '
';
            html_order_line += '' + sku_label + ' ' + sellermania_products[sku_short].sku + '
';
            if (sellermania_products[sku_short].ean != '') html_order_line += '' + ean_label + ' ' + sellermania_products[sku_short].ean + '
';
            if (sellermania_products[sku_short].product_id != '') html_order_line += '' + asin_label + ' ' + sellermania_products[sku_short].product_id + '
';
            if (sellermania_products[sku_short].item_condition != '')
                html_order_line += '' + condition_label + ' ' + sellermania_products[sku_short].item_condition + '
';
            else
                html_order_line += '' + condition_label + ' ' + unknown_label + '
';
            html_order_line += '' + status_label + ' ' + sellermania_products[sku_short].status + '
';
            if (sellermania_products[sku_short].status_id == 6)
            {
                html_order_line += '<input type="radio" id="status_confirm_' + i + '" name="status_' + i + '" value="9" class="status_order_line" data-toggle="' + sellermania_products[sku_short].sku + '" /> ' + confirm_label + ' ';
                html_order_line += '<input type="radio" id="status_cancel_' + i + '" name="status_' + i + '" value="4" class="status_order_line" data-toggle="' + sellermania_products[sku_short].sku + '" /> ' + cancel_label + ' ';
                nb_buttons++;
            }
            sm_block_product.append(html_order_line);
        }
    }

    // Add button check all
    if (nb_buttons > 0)
    {
        var sellermania_html_buttons_all = '<input type="button" value="Confirm all products" id="sellermania_confirm_all_products" class="button btn btn-default" />';
        sellermania_html_buttons_all += '<input type="button" value="Cancel all products" id="sellermania_cancel_all_products" class="button btn btn-default" />';
        sellermania_block_product_general_legend.html(sellermania_html_buttons_all);
        sellermania_block_product_general_legend.show();

        $('#sellermania_confirm_all_products').click(function() {
            for (i = 1; sellermania_block_products_list[i]; i++)
                $('#status_confirm_' + i).attr('checked', 'checked');
            sellermania_update_line_status();
        });
        $('#sellermania_cancel_all_products').click(function() {
            for (i = 1; sellermania_block_products_list[i]; i++)
                $('#status_cancel_' + i).attr('checked', 'checked');
            sellermania_update_line_status();
        });
    }

    // If status has changed
    if (sellermania_status_update_result !== 'undefined')
        sellermania_block_product_general_legend.after(sellermania_status_update_result);
    if (sellermania_error_result !== 'undefined')
        sellermania_block_product_general_legend.after(sellermania_error_result);

    // Check status
    $('.status_order_line').click(function() {
        sellermania_update_line_status();
    });

    function sellermania_update_line_status()
    {
        // Fill product details
        var line_max = 0;
        var sellermania_status_defined = 0;
        for (i = 1; sellermania_block_products_list[i]; i++)
        {
            // Status
            var order_line_status = 'Not defined';
            if ($('#status_confirm_' + i).attr('checked'))
                order_line_status = 'Confirmed';
            if ($('#status_cancel_' + i).attr('checked'))
                order_line_status = 'Cancelled';

            // Count not defined Status
            if (order_line_status != 'Not defined')
                sellermania_status_defined++;

            // Save the line max
            line_max = i;
        }

        // Check how many not defined status there is
        if (sellermania_status_defined > 0)
        {
            // Display submit
            sellermania_block_product_general_legend.html('<input type="button" id="sellermania_register_status" value="Register status" class="button btn btn-default" />');

            // Generate form and submit it
            $('#sellermania_register_status').click(function() {

                // Generate form
                var html_form = '<input type="hidden" name="sellermania_line_max" value="' + line_max + '" />';
                $('.status_order_line').each(function() {
                    if ($(this).attr('checked'))
                    {
                        html_form += '<input type="hidden" name="' + $(this).attr('name') + '" value="' + $(this).attr('value') + '" />';
                        html_form += '<input type="hidden" name="sku_' + $(this).attr('name') + '" value="' + $(this).attr('data-toggle') + '" />';
                    }
                });

                // Display form and submit
                $('#sellermania_status_form').html(html_form);
                document.forms["sellermania_status_form"].submit();

                return false;
            });
        }
    }
});
<commit_msg>#7006 radio button CONFIRMER for an item is leading to the catalog page of Sellermania Product<commit_after>/*
 * 2010-2020 Sellermania / Froggy Commerce / 23Prod SARL
 *
 * NOTICE OF LICENSE
 *
 * This source file is subject to the Academic Free License (AFL 3.0)
 * that is bundled with this package in the file LICENSE.txt.
 * It is also available through the world-wide-web at this URL:
 * http://opensource.org/licenses/afl-3.0.php
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to team@froggy-commerce.com so we can send you a copy immediately.
 *
 * DISCLAIMER
 *
 * Do not edit or add to this file if you wish to upgrade your module to newer
 * versions in the future.
 *
 *  @author         Froggy Commerce <team@froggy-commerce.com>
 *  @copyright      2010-2020 Sellermania / Froggy Commerce / 23Prod SARL
 *  @version        1.0
 *  @license        http://opensource.org/licenses/afl-3.0.php  Academic Free License (AFL 3.0)
 */

$(document).ready(function() {

    // Fill product details
    var nb_buttons = 0;
    for (i = 1; sellermania_block_products_list[i]; i++)
    {
        var sm_block_product = sellermania_block_products_list[i];

        var sku_short = sm_block_product.html().split('
');
        if (typeof sku_short[1] !== 'undefined') {
            sku_short = sku_short[1];
        } else {
            sku_short = sku_short[0];
        }
        sku_short = sku_short.replace(/(\r\n|\n|\r)/gm, "").replace(/\s+/g, ' ').trim()

		sku_short = sku_short.replace('Numéro de référence', 'Ref').replace('Reference number', 'Ref');
		var remove = sku_short.trim().split(' ');
        if (remove[1] == ':')
            sku_short = sku_short.replace(remove[0] + ' ' + remove[1], '').trim();
        else
            sku_short = sku_short.replace(remove[0], '').trim();

        if (sku_short != '' && typeof sellermania_products[sku_short] != 'undefined')
        {
            var html_order_line = '';
            if (sellermania_products[sku_short].insurance_price > 0)
                html_order_line += '
' + insurance_price_label + ' ' + sellermania_products[sku_short].insurance_price + ' ' + sellermania_products[sku_short].currency + '
';
            if (sellermania_products[sku_short].order_item_id != '') html_order_line += '
' + order_item_id_label + ' ' + sellermania_products[sku_short].order_item_id + '
';
            if (sellermania_products[sku_short].external_order_id != '') html_order_line += '
' + external_order_id_label + ' ' + sellermania_products[sku_short].external_order_id + '
';
            html_order_line += '' + sku_label + ' ' + sellermania_products[sku_short].sku + '
';
            if (sellermania_products[sku_short].ean != '') html_order_line += '' + ean_label + ' ' + sellermania_products[sku_short].ean + '
';
            if (sellermania_products[sku_short].product_id != '') html_order_line += '' + asin_label + ' ' + sellermania_products[sku_short].product_id + '
';
            if (sellermania_products[sku_short].item_condition != '')
                html_order_line += '' + condition_label + ' ' + sellermania_products[sku_short].item_condition + '
';
            else
                html_order_line += '' + condition_label + ' ' + unknown_label + '
';
            html_order_line += '' + status_label + ' ' + sellermania_products[sku_short].status + '
';
            if (sellermania_products[sku_short].status_id == 6)
            {
                html_order_line += '<input type="radio" id="status_confirm_' + i + '" name="status_' + i + '" value="9" class="status_order_line" data-toggle="' + sellermania_products[sku_short].sku + '" /> ' + confirm_label + ' ';
                html_order_line += '<input type="radio" id="status_cancel_' + i + '" name="status_' + i + '" value="4" class="status_order_line" data-toggle="' + sellermania_products[sku_short].sku + '" /> ' + cancel_label + ' ';
                nb_buttons++;
            }

            let attr_href = sm_block_product.parent().attr('href');
            if (typeof attr_href !== 'undefined' && attr_href !== false) {
                sm_block_product.parent().after(html_order_line);
            } else {
                sm_block_product.append(html_order_line);
            }
        }
    }

    // Add button check all
    if (nb_buttons > 0)
    {
        var sellermania_html_buttons_all = '<input type="button" value="Confirm all products" id="sellermania_confirm_all_products" class="button btn btn-default" />';
        sellermania_html_buttons_all += '<input type="button" value="Cancel all products" id="sellermania_cancel_all_products" class="button btn btn-default" />';
        sellermania_block_product_general_legend.html(sellermania_html_buttons_all);
        sellermania_block_product_general_legend.show();

        $('#sellermania_confirm_all_products').click(function() {
            for (i = 1; sellermania_block_products_list[i]; i++)
                $('#status_confirm_' + i).attr('checked', 'checked');
            sellermania_update_line_status();
        });
        $('#sellermania_cancel_all_products').click(function() {
            for (i = 1; sellermania_block_products_list[i]; i++)
                $('#status_cancel_' + i).attr('checked', 'checked');
            sellermania_update_line_status();
        });
    }

    // If status has changed
    if (sellermania_status_update_result !== 'undefined')
        sellermania_block_product_general_legend.after(sellermania_status_update_result);
    if (sellermania_error_result !== 'undefined')
        sellermania_block_product_general_legend.after(sellermania_error_result);

    // Check status
    $('.status_order_line').click(function() {
        sellermania_update_line_status();
    });

    function sellermania_update_line_status()
    {
        // Fill product details
        var line_max = 0;
        var sellermania_status_defined = 0;
        for (i = 1; sellermania_block_products_list[i]; i++)
        {
            // Status
            var order_line_status = 'Not defined';
            if ($('#status_confirm_' + i).attr('checked'))
                order_line_status = 'Confirmed';
            if ($('#status_cancel_' + i).attr('checked'))
                order_line_status = 'Cancelled';

            // Count not defined Status
            if (order_line_status != 'Not defined')
                sellermania_status_defined++;

            // Save the line max
            line_max = i;
        }

        // Check how many not defined status there is
        if (sellermania_status_defined > 0)
        {
            // Display submit
            sellermania_block_product_general_legend.html('<input type="button" id="sellermania_register_status" value="Register status" class="button btn btn-default" />');

            // Generate form and submit it
            $('#sellermania_register_status').click(function() {

                // Generate form
                var html_form = '<input type="hidden" name="sellermania_line_max" value="' + line_max + '" />';
                $('.status_order_line').each(function() {
                    if ($(this).attr('checked'))
                    {
                        html_form += '<input type="hidden" name="' + $(this).attr('name') + '" value="' + $(this).attr('value') + '" />';
                        html_form += '<input type="hidden" name="sku_' + $(this).attr('name') + '" value="' + $(this).attr('data-toggle') + '" />';
                    }
                });

                // Display form and submit
                $('#sellermania_status_form').html(html_form);
                document.forms["sellermania_status_form"].submit();

                return false;
            });
        }
    }
});
<|endoftext|>


<commit_before>/**
 * Test dependencies
 */
const chai = require('chai')

/**
 * Assertions
 */
chai.should()
const expect = chai.expect

/**
 * Code under test
 */
const {TextEncoder} = require('text-encoding')
const KeyAlgorithm = require('../../src/dictionaries/KeyAlgorithm')
const ShaKeyAlgorithm = require('../../src/dictionaries/ShaKeyAlgorithm')
const OperationError = require('../../src/errors/OperationError')

/**
 * Tests
 */
describe.only('ShaKeyAlgorithm', () => {
  describe('dictionaries getter', () => {
    it('should return an array', () => {
      ShaKeyAlgorithm.dictionaries.should.eql([
        KeyAlgorithm,
        ShaKeyAlgorithm
      ])
    })
  })

  describe('members getter', () => {
    it('should return an object', () => {
      ShaKeyAlgorithm.members.should.eql({})
    })
  })

  describe('digest', () => {
    it('should return an ArrayBuffer', () => {
      let algorithm = { name: 'SHA-256' }
      let data = new TextEncoder().encode('return an ArrayBuffer')
      let sha = new ShaKeyAlgorithm(algorithm)
      let result = sha.digest(algorithm, data)
      result.should.be.instanceof(ArrayBuffer)
    })

    it('should return a SHA-1 digest', () => {
      let algorithm = { name: 'SHA-1' }
      let data = new TextEncoder().encode('created with webcrypto in Chrome')
      let digest = new Uint8Array([
        240, 245, 162, 97, 158, 225, 111, 59, 198, 40,
        103, 60, 84, 159, 139, 205, 10, 116, 39, 41
      ])
      let sha = new ShaKeyAlgorithm(algorithm)
      let result = sha.digest(algorithm, data)
      Buffer.from(result).should.eql(Buffer.from(digest.buffer))
    })

    it('should return a SHA-256 digest', () => {
      let algorithm = { name: 'SHA-256' }
      let data = new TextEncoder().encode('created with webcrypto in Chrome')
      let digest = new Uint8Array([
        34, 103, 130, 78, 94, 197, 88, 55, 100, 33, 101,
        214, 153, 38, 251, 0, 246, 42, 150, 222, 243, 57,
        184, 244, 74, 187, 55, 10, 206, 17, 146, 65
      ])
      let sha = new ShaKeyAlgorithm(algorithm)
      let result = sha.digest(algorithm, data)
      Buffer.from(result).should.eql(Buffer.from(digest.buffer))
    })

    it('should return a SHA-384 digest', () => {
      let algorithm = { name: 'SHA-384' }
      let data = new TextEncoder().encode('created with webcrypto in Chrome')
      let digest = new Uint8Array([
        114, 126, 90, 78, 53, 164, 76, 208, 239, 167, 250, 77,
        174, 115, 146, 12, 35, 96, 15, 73, 222, 48, 186, 102,
        200, 91, 124, 153, 232, 76, 252, 143, 50, 251, 81, 152,
        45, 189, 41, 167, 139, 29, 52, 9, 140, 197, 5, 238
      ])
      let sha = new ShaKeyAlgorithm(algorithm)
      let result = sha.digest(algorithm, data)
      Buffer.from(result).should.eql(Buffer.from(digest.buffer))
    })

    it('should return a SHA-512 digest', () => {
      let algorithm = { name: 'SHA-512' }
      let data = new TextEncoder().encode('created with webcrypto in Chrome')
      let digest = new Uint8Array([
        101, 55, 12, 162, 223, 251, 198, 26, 154, 74, 173, 61,
        47, 45, 191, 105, 49, 36, 189, 141, 96, 145, 253, 102,
        28, 145, 34, 244, 192, 232, 147, 88, 251, 73, 145, 241,
        204, 213, 77, 129, 119, 107, 197, 94, 204, 57, 20, 153,
        181, 113, 113, 50, 249, 134, 126, 99, 254, 190, 84, 124,
        180, 216, 176, 112
      ])
      let sha = new ShaKeyAlgorithm(algorithm)
      let result = sha.digest(algorithm, data)
      Buffer.from(result).should.eql(Buffer.from(digest.buffer))
    })

    it('should throw an OperationError with unknown algorithm', () => {
      let algorithm = { name: 'SHA-UNKNOWN' }
      let data = new TextEncoder().encode('I am undigestable')
      let sha = new ShaKeyAlgorithm(algorithm)
      expect(() => {
        sha.digest(algorithm, data)
      }).to.throw('SHA-UNKNOWN is not a supported algorithm')
    })
  })
})
<commit_msg>test(ShaKeyAlgorithm): remove .only from describe block<commit_after>/**
 * Test dependencies
 */
const chai = require('chai')

/**
 * Assertions
 */
chai.should()
const expect = chai.expect

/**
 * Code under test
 */
const {TextEncoder} = require('text-encoding')
const KeyAlgorithm = require('../../src/dictionaries/KeyAlgorithm')
const ShaKeyAlgorithm = require('../../src/dictionaries/ShaKeyAlgorithm')
const OperationError = require('../../src/errors/OperationError')

/**
 * Tests
 */
describe('ShaKeyAlgorithm', () => {
  describe('dictionaries getter', () => {
    it('should return an array', () => {
      ShaKeyAlgorithm.dictionaries.should.eql([
        KeyAlgorithm,
        ShaKeyAlgorithm
      ])
    })
  })

  describe('members getter', () => {
    it('should return an object', () => {
      ShaKeyAlgorithm.members.should.eql({})
    })
  })

  describe('digest', () => {
    it('should return an ArrayBuffer', () => {
      let algorithm = { name: 'SHA-256' }
      let data = new TextEncoder().encode('return an ArrayBuffer')
      let sha = new ShaKeyAlgorithm(algorithm)
      let result = sha.digest(algorithm, data)
      result.should.be.instanceof(ArrayBuffer)
    })

    it('should return a SHA-1 digest', () => {
      let algorithm = { name: 'SHA-1' }
      let data = new TextEncoder().encode('created with webcrypto in Chrome')
      let digest = new Uint8Array([
        240, 245, 162, 97, 158, 225, 111, 59, 198, 40,
        103, 60, 84, 159, 139, 205, 10, 116, 39, 41
      ])
      let sha = new ShaKeyAlgorithm(algorithm)
      let result = sha.digest(algorithm, data)
      Buffer.from(result).should.eql(Buffer.from(digest.buffer))
    })

    it('should return a SHA-256 digest', () => {
      let algorithm = { name: 'SHA-256' }
      let data = new TextEncoder().encode('created with webcrypto in Chrome')
      let digest = new Uint8Array([
        34, 103, 130, 78, 94, 197, 88, 55, 100, 33, 101,
        214, 153, 38, 251, 0, 246, 42, 150, 222, 243, 57,
        184, 244, 74, 187, 55, 10, 206, 17, 146, 65
      ])
      let sha = new ShaKeyAlgorithm(algorithm)
      let result = sha.digest(algorithm, data)
      Buffer.from(result).should.eql(Buffer.from(digest.buffer))
    })

    it('should return a SHA-384 digest', () => {
      let algorithm = { name: 'SHA-384' }
      let data = new TextEncoder().encode('created with webcrypto in Chrome')
      let digest = new Uint8Array([
        114, 126, 90, 78, 53, 164, 76, 208, 239, 167, 250, 77,
        174, 115, 146, 12, 35, 96, 15, 73, 222, 48, 186, 102,
        200, 91, 124, 153, 232, 76, 252, 143, 50, 251, 81, 152,
        45, 189, 41, 167, 139, 29, 52, 9, 140, 197, 5, 238
      ])
      let sha = new ShaKeyAlgorithm(algorithm)
      let result = sha.digest(algorithm, data)
      Buffer.from(result).should.eql(Buffer.from(digest.buffer))
    })

    it('should return a SHA-512 digest', () => {
      let algorithm = { name: 'SHA-512' }
      let data = new TextEncoder().encode('created with webcrypto in Chrome')
      let digest = new Uint8Array([
        101, 55, 12, 162, 223, 251, 198, 26, 154, 74, 173, 61,
        47, 45, 191, 105, 49, 36, 189, 141, 96, 145, 253, 102,
        28, 145, 34, 244, 192, 232, 147, 88, 251, 73, 145, 241,
        204, 213, 77, 129, 119, 107, 197, 94, 204, 57, 20, 153,
        181, 113, 113, 50, 249, 134, 126, 99, 254, 190, 84, 124,
        180, 216, 176, 112
      ])
      let sha = new ShaKeyAlgorithm(algorithm)
      let result = sha.digest(algorithm, data)
      Buffer.from(result).should.eql(Buffer.from(digest.buffer))
    })

    it('should throw an OperationError with unknown algorithm', () => {
      let algorithm = { name: 'SHA-UNKNOWN' }
      let data = new TextEncoder().encode('I am undigestable')
      let sha = new ShaKeyAlgorithm(algorithm)
      expect(() => {
        sha.digest(algorithm, data)
      }).to.throw('SHA-UNKNOWN is not a supported algorithm')
    })
  })
})
<|endoftext|>


<commit_before>var test = require("tape");
var PicoQueue = require("./PicoQueue");

test("PicoQueue", function(t){

  var log = [];

  var pq = PicoQueue(function(pico_id, data, callback){
    log.push("working_0 [" + pico_id + "] " + data);
    process.nextTick(function(){
      log.push("working_1 [" + pico_id + "] " + data);
      process.nextTick(function(){
        log.push("working_2 [" + pico_id + "] " + data);
        callback();
      });
    });
  });

  var enqueue = function(pico_id, data, done){
    pq.enqueue(pico_id, data, function(){
      log.push("done [" + pico_id + "] " + data);
      if(done){
        done();
      }
    });
  };

  enqueue("A", 0);
  enqueue("A", 1);
  enqueue("B", 0);
  enqueue("A", 2, function(){
    t.deepEquals(log, [
      "working_0 [A] 0",
      "working_0 [B] 0",//different picos can be concurrent
      "working_1 [A] 0",
      "working_1 [B] 0",
      "working_2 [A] 0",//Now pico A finished work on event 0
      "working_2 [B] 0",
      "working_0 [A] 1",//Now pico A can start on event 1
      "done [A] 0",
      "done [B] 0",
      "working_1 [A] 1",
      "working_2 [A] 1",
      "working_0 [A] 2",
      "done [A] 1",
      "working_1 [A] 2",
      "working_2 [A] 2",
      "done [A] 2"
    ]);
    t.end();
  });
});
<commit_msg>adding enqueue log to PicoQueue.test<commit_after>var test = require("tape");
var PicoQueue = require("./PicoQueue");

test("PicoQueue", function(t){

  var log = [];

  var pq = PicoQueue(function(pico_id, data, callback){
    log.push("working_0 [" + pico_id + "] " + data);
    process.nextTick(function(){
      log.push("working_1 [" + pico_id + "] " + data);
      process.nextTick(function(){
        log.push("working_2 [" + pico_id + "] " + data);
        callback();
      });
    });
  });

  var enqueue = function(pico_id, data, done){
    log.push("enqueue [" + pico_id + "] " + data);
    pq.enqueue(pico_id, data, function(){
      log.push("done [" + pico_id + "] " + data);
      if(done){
        done();
      }
    });
  };

  enqueue("A", 0);
  enqueue("A", 1);
  enqueue("B", 0);
  enqueue("A", 2, function(){
    t.deepEquals(log, [
      "enqueue [A] 0",
      "enqueue [A] 1",
      "enqueue [B] 0",
      "enqueue [A] 2",
      "working_0 [A] 0",
      "working_0 [B] 0",//different picos can be concurrent
      "working_1 [A] 0",
      "working_1 [B] 0",
      "working_2 [A] 0",//Now pico A finished work on event 0
      "working_2 [B] 0",
      "working_0 [A] 1",//Now pico A can start on event 1
      "done [A] 0",
      "done [B] 0",
      "working_1 [A] 1",
      "working_2 [A] 1",
      "working_0 [A] 2",
      "done [A] 1",
      "working_1 [A] 2",
      "working_2 [A] 2",
      "done [A] 2"
    ]);
    t.end();
  });
});
<|endoftext|>


<commit_before>var assert = require('chai').assert;
var nodemock = require('nodemock');
var Deferred = require('jsdeferred').Deferred;

var utils = require('../test-utils');
var TypeOf = utils.TypeOf;
var InstanceOf = utils.InstanceOf;

var Connection = require('../../lib/droonga-protocol/connection').Connection;

suite('Connection', function() {
  suite('initialization', function() {
    var connection;

    teardown(function() {
      if (connection) {
        connection.close();
        connection = undefined;
      }
    });

    function assertEventEmitter(object) {
      assert.equal(typeof object,
                   'object',
                   'should be an instance of EventEmitter');
      assert.equal(typeof object.emit,
                   'function',
                   'should be an instance of EventEmitter');
    }

    test('sender', function() {
      connection = new Connection({ tag: 'test' });
      assertEventEmitter(connection._sender);
    });

    test('receiver', function(done) {
      connection = new Connection({ tag: 'test' });
      assertEventEmitter(connection._receiver);
      assert.equal(connection.receivePort,
                   undefined,
                   'should be not-initialized');

      Deferred
        .wait(0.01)
        .next(function() {
          assert.notEqual(connection.receivePort,
                          undefined,
                          'should be initialized');
          done();
        })
        .error(function(error) {
          done(error);
        });
    });
  });

  suite('simple communication', function() {
    var connection;
    var backend;

    setup(function(done) {
      utils.createBackend()
        .next(function(newBackend) {
          backend = newBackend;
          connection = new Connection({
            tag:      'test',
            defaultDataset: 'test-dataset',
            hostName: 'localhost',
            port:     utils.testSendPort,
            receivePort: utils.testReceivePort,
            maxRetyrCount: 3,
            retryDelay: 1
          });
          done();
        });
    });

    teardown(function() {
      if (backend) {
        backend.close();
        backend = undefined;
      }
      if (connection) {
        connection.close();
        connection = undefined;
      }
    });

    function createMockedMessageCallback() {
      var mockedCallback = nodemock;
      var callback = function() {
        mockedCallback.receive.apply(mockedCallback, arguments);
      };
      callback.takes = function() {
        callback.assert = function() {
          mockedCallback.assertThrows();
        };
        mockedCallback = mockedCallback.mock('receive');
        mockedCallback = mockedCallback.takes.apply(mockedCallback, arguments);
        return this;
      };
      callback.mock = mockedCallback;
      return callback;
    }

    function getBackendReceivedMessages() {
      return backend.received.map(function(packet) {
        return packet[2];
      });
    }

    suite('one way message', function() {
      test('from front to back', function(done) {
        var objectMessage = connection.emitMessage('object', { command: 'foobar' });
        assert.envelopeEqual(objectMessage,
                             utils.createExpectedEnvelope('object',
                                                    { command: 'foobar' }));

        var stringMessage = connection.emitMessage('string', 'string');
        assert.envelopeEqual(stringMessage,
                             utils.createExpectedEnvelope('string', 'string'));

        var numericMessage = connection.emitMessage('numeric', 1234);
        assert.envelopeEqual(numericMessage,
                             utils.createExpectedEnvelope('numeric', 1234));

        Deferred
          .wait(0.01)
          .next(function() {
            assert.deepEqual(getBackendReceivedMessages(),
                             [objectMessage,
                              stringMessage,
                              numericMessage]);
            done();
          })
          .error(function(error) {
            done(error);
          });
      });

      test('from back to front', function(done) {
        var callback = createMockedMessageCallback();
        connection.on('string', callback);
        connection.on('numeric', callback);
        connection.on('object', callback);
        connection.on('unknown, ignored', callback);

        var stringMessage = utils.createEnvelope('string', 'string');
        var numericMessage = utils.createEnvelope('numeric', 1234);
        var objectMessage = utils.createEnvelope('object', { value: true });
        callback
          .takes(stringMessage.body)
          .takes(numericMessage.body)
          .takes(objectMessage.body);

        utils
          .sendPacketTo(utils.createPacket(stringMessage), utils.testReceivePort)
          .sendPacketTo(utils.createPacket(numericMessage), utils.testReceivePort)
          .sendPacketTo(utils.createPacket(objectMessage), utils.testReceivePort)
          .sendPacketTo(utils.createPacket({}, 'unknown, ignored'), utils.testReceivePort)
          .next(function() {
            callback.assert();
            done();
          })
          .error(function(error) {
            done(error);
          });
      });
    });

    suite('request-response', function() {
      test('success', function(done) {
        var callback = createMockedMessageCallback();

        // this event should not be emitted, because it is supressed by reply:* event
        connection.on('result', callback);

        var messages = [
          connection.emitMessage('event', Math.random(), callback),
          connection.emitMessage('event', Math.random(), callback)
        ];
        var responses = [
          utils.createReplyEnvelope(messages[0], 'result', Math.random()),
          utils.createReplyEnvelope(messages[1], 'result', Math.random())
        ];
        callback
          .takes(null, responses[0])
          .takes(null, responses[1]);
        Deferred
          .wait(0.01)
          .next(function() {
            assert.deepEqual(getBackendReceivedMessages(), messages);
            assert.deepEqual(
              [connection.listeners('reply:' + messages[0].id).length,
               connection.listeners('reply:' + messages[1].id).length],
              [1,1],
              'response listeners should be registered'
            );
          })
          .sendPacketTo(utils.createPacket(responses[0]), utils.testReceivePort)
          .sendPacketTo(utils.createPacket(responses[1]), utils.testReceivePort)
          .wait(0.01)
          .next(function() {
            callback.assert();
            assert.deepEqual(
              [connection.listeners('reply:' + messages[0].id).length,
               connection.listeners('reply:' + messages[1].id).length],
              [0,0],
              'response listeners should be removed'
            );
            done();
          })
          .error(function(error) {
            done(error);
          });
      });

      test('error', function(done) {
        var callback = createMockedMessageCallback();

        // this event should not be emitted, because it is supressed by reply:* event
        connection.on('result', callback);

        var messages = [
          connection.emitMessage('event', Math.random(), callback),
          connection.emitMessage('event', Math.random(), callback)
        ];
        var responses = [
          utils.createReplyEnvelope(messages[0], 'result', Math.random()),
          utils.createReplyEnvelope(messages[1], 'result', Math.random())
        ];
        // make them error responses
        responses[0].statusCode = 502;
        responses[1].statusCode = 503;
        callback
          .takes(responses[0].statusCode, responses[0])
          .takes(responses[1].statusCode, responses[1]);
        Deferred
          .wait(0.01)
          .next(function() {
            assert.deepEqual(getBackendReceivedMessages(), messages);
            assert.deepEqual(
              [connection.listeners('reply:' + messages[0].id).length,
               connection.listeners('reply:' + messages[1].id).length],
              [1,1],
              'response listeners should be registered'
            );
          })
          .sendPacketTo(utils.createPacket(responses[0]), utils.testReceivePort)
          .sendPacketTo(utils.createPacket(responses[1]), utils.testReceivePort)
          .wait(0.01)
          .next(function() {
            callback.assert();
            assert.deepEqual(
              [connection.listeners('reply:' + messages[0].id).length,
               connection.listeners('reply:' + messages[1].id).length],
              [0,0],
              'response listeners should be removed'
            );
            done();
          })
          .error(function(error) {
            done(error);
          });
      });

      test('duplicated', function(done) {
        var callback = createMockedMessageCallback();

        // this event should not be emitted, because it is supressed by reply:* event
        connection.on('result', callback);

        var messages = [
          connection.emitMessage('event', Math.random(), callback),
          connection.emitMessage('event', Math.random(), callback)
        ];
        var responses = [
          utils.createReplyEnvelope(messages[0], 'result', Math.random()),
          utils.createReplyEnvelope(messages[1], 'result', Math.random()),
          utils.createReplyEnvelope(messages[0], 'result', 'duplicated, ignored'),
          utils.createReplyEnvelope(messages[1], 'result', 'duplicated, ignored')
        ];
        responses[1].statusCode = 503;
        callback
          .takes(null, responses[0])
          .takes(responses[1].statusCode, responses[1]);
        Deferred
          .wait(0.01)
          .next(function() {
            assert.deepEqual(getBackendReceivedMessages(), messages);
            assert.deepEqual(
              [connection.listeners('reply:' + messages[0].id).length,
               connection.listeners('reply:' + messages[1].id).length],
              [1,1],
              'response listeners should be registered'
            );
          })
          .sendPacketTo(utils.createPacket(responses[0]), utils.testReceivePort)
          .sendPacketTo(utils.createPacket(responses[1]), utils.testReceivePort)
          .sendPacketTo(utils.createPacket(responses[2]), utils.testReceivePort)
          .sendPacketTo(utils.createPacket(responses[3]), utils.testReceivePort)
          .wait(0.01)
          .next(function() {
            callback.assert();
            assert.deepEqual(
              [connection.listeners('reply:' + messages[0].id).length,
               connection.listeners('reply:' + messages[1].id).length],
              [0,0],
              'response listeners should be removed'
            );
            done();
          })
          .error(function(error) {
            done(error);
          });
      });

      test('timeout', function(done) {
        var callback = createMockedMessageCallback();
        var response;
        var packet;
        var messages = {
          notTimedOut:
            connection.emitMessage('not timed out',
                                   Math.random(),
                                   callback,
                                   { timeout: 1000 }),
          timedOut:
            connection.emitMessage('timed out',
                                   Math.random(),
                                   callback,
                                   { timeout: 20 }),
          permanent:
            connection.emitMessage('permanent',
                                   Math.random(),
                                   callback,
                                   { timeout: -1 })
        };
        var responses = {
          notTimedOut:
            utils.createReplyEnvelope(messages.notTimedOut, 'ok', Math.random()),
          timedOut:
            utils.createReplyEnvelope(messages.timedOut, 'ignored', Math.random())
        };
        callback
          .takes(Connection.ERROR_GATEWAY_TIMEOUT, null)
          .takes(null, responses.notTimedOut)
        Deferred
          .wait(0.01)
          .next(function() {
            assert.deepEqual(getBackendReceivedMessages(),
                             [messages.notTimedOut,
                              messages.timedOut,
                              messages.permanent]);
            assert.deepEqual(
              { notTimedOut:
                  connection.listeners('reply:' + messages.notTimedOut.id).length,
                timedOut:
                  connection.listeners('reply:' + messages.timedOut.id).length,
                permanent:
                  connection.listeners('reply:' + messages.permanent.id).length },
              { notTimedOut: 1, timedOut: 1, permanent: 1 },
              'response listeners should be registered'
            );
          })
          .wait(0.02)
          .sendPacketTo(utils.createPacket(responses.notTimedOut), utils.testReceivePort)
          .sendPacketTo(utils.createPacket(responses.timedOut), utils.testReceivePort)
          .wait(0.01)
          .next(function() {
            callback.assert();
            assert.deepEqual(
              { notTimedOut:
                  connection.listeners('reply:' + messages.notTimedOut.id).length,
                timedOut:
                  connection.listeners('reply:' + messages.timedOut.id).length,
                permanent:
                  connection.listeners('reply:' + messages.permanent.id).length },
              { notTimedOut: 0, timedOut: 0, permanent: 1 },
              'response listener should be removed even if it is timed out'
            );
            done();
          })
          .error(function(error) {
            done(error);
          });
      });
    });
  });

  suite('to backend', function() {
    var connection;
    var backend;
    var restartedBackend;

    setup(function(done) {
      restartedBackend = undefined;
      utils.createBackend()
        .next(function(newBackend) {
          backend = newBackend;
          connection = new Connection({
            tag:      utils.testTag,
            hostName: 'localhost',
            port:     utils.testSendPort,
            maxRetyrCount: 3,
            retryDelay: 1
          });
          done();
        });
    });

    teardown(function() {
      if (backend) {
        backend.close();
        backend = undefined;
      }
      if (restartedBackend) {
        restartedBackend.close();
        restartedBackend = undefined;
      }
      if (connection) {
        connection.close();
        connection = undefined;
      }
    });

    test('normal messaging', function(done) {
      var deferred = new Deferred();
      connection.emitMessage('type', { message: true });
      backend.once('receive', function() {
        deferred.call();
      });
      deferred
        .next(function() {
          assert.deepEqual(backend.getEvents(),
                           ['type']);
          done();
        })
        .error(function(error) {
          done(error);
        });
    });

    test('disconnected suddenly', function(done) {
      var errorHandler;
      Deferred
        .next(function() {
          var deferred = new Deferred();
          connection.emitMessage('type1', { message: true });
          backend.once('receive', function() {
            deferred.call();
          });
          return deferred;
        })
        .next(function() {
          assert.deepEqual(backend.getEvents(),
                           ['type1']);
          var deferred = new Deferred();
          backend.close(function() {
            deferred.call();
          });
          return deferred;
        })
        .next(function() {
          var deferred = new Deferred();

          errorHandler = nodemock
            .mock('handle')
              .takes({});
          connection.on('error', function(error) {
            errorHandler.handle(error);
            deferred.call();
          });

          connection.emitMessage('type2', { message: true });

          return deferred;
        })
        .next(function() {
          errorHandler.assertThrows();
        })
        .createBackend()
        .next(function(newBackend) {
          restartedBackend = newBackend;
          assert.deepEqual(backend.getEvents(),
                           ['type1']);
          assert.deepEqual(restartedBackend.getEvents(),
                           []);

          connection.emitMessage('type3', { message: true });

          var deferred = new Deferred();
          restartedBackend.once('receive', function() {
            restartedBackend.once('receive', function() {
              deferred.call();
            });
          });
          return deferred;
        })
        .next(function() {
          assert.deepEqual(backend.getEvents(),
                           ['type1']);
          assert.deepEqual(restartedBackend.getEvents(),
                           ['type2', 'type3']);
          done();
        })
        .error(function(error) {
          done(error);
        });
    });
  });
});
<commit_msg>Fix indent<commit_after>var assert = require('chai').assert;
var nodemock = require('nodemock');
var Deferred = require('jsdeferred').Deferred;

var utils = require('../test-utils');
var TypeOf = utils.TypeOf;
var InstanceOf = utils.InstanceOf;

var Connection = require('../../lib/droonga-protocol/connection').Connection;

suite('Connection', function() {
  suite('initialization', function() {
    var connection;

    teardown(function() {
      if (connection) {
        connection.close();
        connection = undefined;
      }
    });

    function assertEventEmitter(object) {
      assert.equal(typeof object,
                   'object',
                   'should be an instance of EventEmitter');
      assert.equal(typeof object.emit,
                   'function',
                   'should be an instance of EventEmitter');
    }

    test('sender', function() {
      connection = new Connection({ tag: 'test' });
      assertEventEmitter(connection._sender);
    });

    test('receiver', function(done) {
      connection = new Connection({ tag: 'test' });
      assertEventEmitter(connection._receiver);
      assert.equal(connection.receivePort,
                   undefined,
                   'should be not-initialized');

      Deferred
        .wait(0.01)
        .next(function() {
          assert.notEqual(connection.receivePort,
                          undefined,
                          'should be initialized');
          done();
        })
        .error(function(error) {
          done(error);
        });
    });
  });

  suite('simple communication', function() {
    var connection;
    var backend;

    setup(function(done) {
      utils.createBackend()
        .next(function(newBackend) {
          backend = newBackend;
          connection = new Connection({
            tag:      'test',
            defaultDataset: 'test-dataset',
            hostName: 'localhost',
            port:     utils.testSendPort,
            receivePort: utils.testReceivePort,
            maxRetyrCount: 3,
            retryDelay: 1
          });
          done();
        });
    });

    teardown(function() {
      if (backend) {
        backend.close();
        backend = undefined;
      }
      if (connection) {
        connection.close();
        connection = undefined;
      }
    });

    function createMockedMessageCallback() {
      var mockedCallback = nodemock;
      var callback = function() {
        mockedCallback.receive.apply(mockedCallback, arguments);
      };
      callback.takes = function() {
        callback.assert = function() {
          mockedCallback.assertThrows();
        };
        mockedCallback = mockedCallback.mock('receive');
        mockedCallback = mockedCallback.takes.apply(mockedCallback, arguments);
        return this;
      };
      callback.mock = mockedCallback;
      return callback;
    }

    function getBackendReceivedMessages() {
      return backend.received.map(function(packet) {
        return packet[2];
      });
    }

    suite('one way message', function() {
      test('from front to back', function(done) {
        var objectMessage = connection.emitMessage('object', { command: 'foobar' });
        assert.envelopeEqual(objectMessage,
                             utils.createExpectedEnvelope('object',
                                                          { command: 'foobar' }));

        var stringMessage = connection.emitMessage('string', 'string');
        assert.envelopeEqual(stringMessage,
                             utils.createExpectedEnvelope('string', 'string'));

        var numericMessage = connection.emitMessage('numeric', 1234);
        assert.envelopeEqual(numericMessage,
                             utils.createExpectedEnvelope('numeric', 1234));

        Deferred
          .wait(0.01)
          .next(function() {
            assert.deepEqual(getBackendReceivedMessages(),
                             [objectMessage,
                              stringMessage,
                              numericMessage]);
            done();
          })
          .error(function(error) {
            done(error);
          });
      });

      test('from back to front', function(done) {
        var callback = createMockedMessageCallback();
        connection.on('string', callback);
        connection.on('numeric', callback);
        connection.on('object', callback);
        connection.on('unknown, ignored', callback);

        var stringMessage = utils.createEnvelope('string', 'string');
        var numericMessage = utils.createEnvelope('numeric', 1234);
        var objectMessage = utils.createEnvelope('object', { value: true });
        callback
          .takes(stringMessage.body)
          .takes(numericMessage.body)
          .takes(objectMessage.body);

        utils
          .sendPacketTo(utils.createPacket(stringMessage), utils.testReceivePort)
          .sendPacketTo(utils.createPacket(numericMessage), utils.testReceivePort)
          .sendPacketTo(utils.createPacket(objectMessage), utils.testReceivePort)
          .sendPacketTo(utils.createPacket({}, 'unknown, ignored'), utils.testReceivePort)
          .next(function() {
            callback.assert();
            done();
          })
          .error(function(error) {
            done(error);
          });
      });
    });

    suite('request-response', function() {
      test('success', function(done) {
        var callback = createMockedMessageCallback();

        // this event should not be emitted, because it is supressed by reply:* event
        connection.on('result', callback);

        var messages = [
          connection.emitMessage('event', Math.random(), callback),
          connection.emitMessage('event', Math.random(), callback)
        ];
        var responses = [
          utils.createReplyEnvelope(messages[0], 'result', Math.random()),
          utils.createReplyEnvelope(messages[1], 'result', Math.random())
        ];
        callback
          .takes(null, responses[0])
          .takes(null, responses[1]);
        Deferred
          .wait(0.01)
          .next(function() {
            assert.deepEqual(getBackendReceivedMessages(), messages);
            assert.deepEqual(
              [connection.listeners('reply:' + messages[0].id).length,
               connection.listeners('reply:' + messages[1].id).length],
              [1,1],
              'response listeners should be registered'
            );
          })
          .sendPacketTo(utils.createPacket(responses[0]), utils.testReceivePort)
          .sendPacketTo(utils.createPacket(responses[1]), utils.testReceivePort)
          .wait(0.01)
          .next(function() {
            callback.assert();
            assert.deepEqual(
              [connection.listeners('reply:' + messages[0].id).length,
               connection.listeners('reply:' + messages[1].id).length],
              [0,0],
              'response listeners should be removed'
            );
            done();
          })
          .error(function(error) {
            done(error);
          });
      });

      test('error', function(done) {
        var callback = createMockedMessageCallback();

        // this event should not be emitted, because it is supressed by reply:* event
        connection.on('result', callback);

        var messages = [
          connection.emitMessage('event', Math.random(), callback),
          connection.emitMessage('event', Math.random(), callback)
        ];
        var responses = [
          utils.createReplyEnvelope(messages[0], 'result', Math.random()),
          utils.createReplyEnvelope(messages[1], 'result', Math.random())
        ];
        // make them error responses
        responses[0].statusCode = 502;
        responses[1].statusCode = 503;
        callback
          .takes(responses[0].statusCode, responses[0])
          .takes(responses[1].statusCode, responses[1]);
        Deferred
          .wait(0.01)
          .next(function() {
            assert.deepEqual(getBackendReceivedMessages(), messages);
            assert.deepEqual(
              [connection.listeners('reply:' + messages[0].id).length,
               connection.listeners('reply:' + messages[1].id).length],
              [1,1],
              'response listeners should be registered'
            );
          })
          .sendPacketTo(utils.createPacket(responses[0]), utils.testReceivePort)
          .sendPacketTo(utils.createPacket(responses[1]), utils.testReceivePort)
          .wait(0.01)
          .next(function() {
            callback.assert();
            assert.deepEqual(
              [connection.listeners('reply:' + messages[0].id).length,
               connection.listeners('reply:' + messages[1].id).length],
              [0,0],
              'response listeners should be removed'
            );
            done();
          })
          .error(function(error) {
            done(error);
          });
      });

      test('duplicated', function(done) {
        var callback = createMockedMessageCallback();

        // this event should not be emitted, because it is supressed by reply:* event
        connection.on('result', callback);

        var messages = [
          connection.emitMessage('event', Math.random(), callback),
          connection.emitMessage('event', Math.random(), callback)
        ];
        var responses = [
          utils.createReplyEnvelope(messages[0], 'result', Math.random()),
          utils.createReplyEnvelope(messages[1], 'result', Math.random()),
          utils.createReplyEnvelope(messages[0], 'result', 'duplicated, ignored'),
          utils.createReplyEnvelope(messages[1], 'result', 'duplicated, ignored')
        ];
        responses[1].statusCode = 503;
        callback
          .takes(null, responses[0])
          .takes(responses[1].statusCode, responses[1]);
        Deferred
          .wait(0.01)
          .next(function() {
            assert.deepEqual(getBackendReceivedMessages(), messages);
            assert.deepEqual(
              [connection.listeners('reply:' + messages[0].id).length,
               connection.listeners('reply:' + messages[1].id).length],
              [1,1],
              'response listeners should be registered'
            );
          })
          .sendPacketTo(utils.createPacket(responses[0]), utils.testReceivePort)
          .sendPacketTo(utils.createPacket(responses[1]), utils.testReceivePort)
          .sendPacketTo(utils.createPacket(responses[2]), utils.testReceivePort)
          .sendPacketTo(utils.createPacket(responses[3]), utils.testReceivePort)
          .wait(0.01)
          .next(function() {
            callback.assert();
            assert.deepEqual(
              [connection.listeners('reply:' + messages[0].id).length,
               connection.listeners('reply:' + messages[1].id).length],
              [0,0],
              'response listeners should be removed'
            );
            done();
          })
          .error(function(error) {
            done(error);
          });
      });

      test('timeout', function(done) {
        var callback = createMockedMessageCallback();
        var response;
        var packet;
        var messages = {
          notTimedOut:
            connection.emitMessage('not timed out',
                                   Math.random(),
                                   callback,
                                   { timeout: 1000 }),
          timedOut:
            connection.emitMessage('timed out',
                                   Math.random(),
                                   callback,
                                   { timeout: 20 }),
          permanent:
            connection.emitMessage('permanent',
                                   Math.random(),
                                   callback,
                                   { timeout: -1 })
        };
        var responses = {
          notTimedOut:
            utils.createReplyEnvelope(messages.notTimedOut, 'ok', Math.random()),
          timedOut:
            utils.createReplyEnvelope(messages.timedOut, 'ignored', Math.random())
        };
        callback
          .takes(Connection.ERROR_GATEWAY_TIMEOUT, null)
          .takes(null, responses.notTimedOut)
        Deferred
          .wait(0.01)
          .next(function() {
            assert.deepEqual(getBackendReceivedMessages(),
                             [messages.notTimedOut,
                              messages.timedOut,
                              messages.permanent]);
            assert.deepEqual(
              { notTimedOut:
                  connection.listeners('reply:' + messages.notTimedOut.id).length,
                timedOut:
                  connection.listeners('reply:' + messages.timedOut.id).length,
                permanent:
                  connection.listeners('reply:' + messages.permanent.id).length },
              { notTimedOut: 1, timedOut: 1, permanent: 1 },
              'response listeners should be registered'
            );
          })
          .wait(0.02)
          .sendPacketTo(utils.createPacket(responses.notTimedOut), utils.testReceivePort)
          .sendPacketTo(utils.createPacket(responses.timedOut), utils.testReceivePort)
          .wait(0.01)
          .next(function() {
            callback.assert();
            assert.deepEqual(
              { notTimedOut:
                  connection.listeners('reply:' + messages.notTimedOut.id).length,
                timedOut:
                  connection.listeners('reply:' + messages.timedOut.id).length,
                permanent:
                  connection.listeners('reply:' + messages.permanent.id).length },
              { notTimedOut: 0, timedOut: 0, permanent: 1 },
              'response listener should be removed even if it is timed out'
            );
            done();
          })
          .error(function(error) {
            done(error);
          });
      });
    });
  });

  suite('to backend', function() {
    var connection;
    var backend;
    var restartedBackend;

    setup(function(done) {
      restartedBackend = undefined;
      utils.createBackend()
        .next(function(newBackend) {
          backend = newBackend;
          connection = new Connection({
            tag:      utils.testTag,
            hostName: 'localhost',
            port:     utils.testSendPort,
            maxRetyrCount: 3,
            retryDelay: 1
          });
          done();
        });
    });

    teardown(function() {
      if (backend) {
        backend.close();
        backend = undefined;
      }
      if (restartedBackend) {
        restartedBackend.close();
        restartedBackend = undefined;
      }
      if (connection) {
        connection.close();
        connection = undefined;
      }
    });

    test('normal messaging', function(done) {
      var deferred = new Deferred();
      connection.emitMessage('type', { message: true });
      backend.once('receive', function() {
        deferred.call();
      });
      deferred
        .next(function() {
          assert.deepEqual(backend.getEvents(),
                           ['type']);
          done();
        })
        .error(function(error) {
          done(error);
        });
    });

    test('disconnected suddenly', function(done) {
      var errorHandler;
      Deferred
        .next(function() {
          var deferred = new Deferred();
          connection.emitMessage('type1', { message: true });
          backend.once('receive', function() {
            deferred.call();
          });
          return deferred;
        })
        .next(function() {
          assert.deepEqual(backend.getEvents(),
                           ['type1']);
          var deferred = new Deferred();
          backend.close(function() {
            deferred.call();
          });
          return deferred;
        })
        .next(function() {
          var deferred = new Deferred();

          errorHandler = nodemock
            .mock('handle')
              .takes({});
          connection.on('error', function(error) {
            errorHandler.handle(error);
            deferred.call();
          });

          connection.emitMessage('type2', { message: true });

          return deferred;
        })
        .next(function() {
          errorHandler.assertThrows();
        })
        .createBackend()
        .next(function(newBackend) {
          restartedBackend = newBackend;
          assert.deepEqual(backend.getEvents(),
                           ['type1']);
          assert.deepEqual(restartedBackend.getEvents(),
                           []);

          connection.emitMessage('type3', { message: true });

          var deferred = new Deferred();
          restartedBackend.once('receive', function() {
            restartedBackend.once('receive', function() {
              deferred.call();
            });
          });
          return deferred;
        })
        .next(function() {
          assert.deepEqual(backend.getEvents(),
                           ['type1']);
          assert.deepEqual(restartedBackend.getEvents(),
                           ['type2', 'type3']);
          done();
        })
        .error(function(error) {
          done(error);
        });
    });
  });
});
<|endoftext|>