<commit_before>/* eslint-disable no-console */
const fs = require('fs');
const sources = require('editor-layer-index/imagery.json');
const prettyStringify = require('json-stringify-pretty-compact');

let imagery = [];

// ignore imagery more than 20 years old..
let cutoffDate = new Date();
cutoffDate.setFullYear(cutoffDate.getFullYear() - 20);

const keep = [
  // Add custom sources here if needed.
  {
    id: 'Maxar-Premium',
    name: 'Maxar Premium Imagery (Beta)',
    type: 'tms',
    default: true,
    attribution: {
      required: true,
      text: 'Terms & Feedback',
      url: 'https://wiki.openstreetmap.org/wiki/DigitalGlobe'
    },
    description: 'Maxar Premium is a mosaic composed of Maxar basemap with select regions filled with +Vivid or custom area of interest imagery, 50cm resolution or better, and refreshed more frequently with ongoing updates.',
    icon: 'https://osmlab.github.io/editor-layer-index/sources/world/Maxar.png',
    max_zoom: 22,
    url: '7586487389962e3f6e31ab2ed8ca321f2f3fe2cf87f1dedce8fc918b4692efd86fcd816ab8a35303effb1be9abe39b1cce3fe6db2c740044364ae68560822c88373d2c784325baf4e1fa007c6dbedab4cea3fa0dd86ee0ae4feeef032d33dcac28e4b16c90d55a42087c6b66526423ea1b4cc7e63c613940eb1c60f48270060bf41c5fcb6a628985ebe6801e9e71f041cc9f8df06b0345600376663e7dc1cdbc7df16876d8b5d006ed5782e6af4bfe2ff5a292',
    encrypted: true
  }, {
    id: 'Maxar-Standard',
    name: 'Maxar Standard Imagery (Beta)',
    type: 'tms',
    default: true,
    attribution: {
      required: true,
      text: 'Terms & Feedback',
      url: 'https://wiki.openstreetmap.org/wiki/DigitalGlobe'
    },
    description: 'Maxar Standard is a curated set of imagery covering 86% of the earth’s landmass, with 30-60cm resolution where available, backfilled by Landsat. Average age is 2.31 years, with some areas updated 2x per year.',
    icon: 'https://osmlab.github.io/editor-layer-index/sources/world/Maxar.png',
    max_zoom: 22,
    url: '7586487389962e3f6e31ab2ed8ca321f2f3fe2cf87f1dedce8fc918b4692efd86fcd816ab8a35303effb1be9abe39b1cce3fe6db2c740044364ae68560822c88373d2c784325baf4e1fa007c6dbedab4cea3fa0dd86ee0ae4feeef032d33dcac28e4b16c90d55a42087c6b66526423ea1b4cc7e63c613940eb1c60f48270060bf41c5fcb6a628985ebe6801e9e71f010c8c9d7fb6b534560012461377dc1cdb672f16827dfe0d005bf5685b7ac4ea97cf5f795',
    encrypted: true
  }
];

const discard = {
  'osmbe': true,                        // 'OpenStreetMap (Belgian Style)'
  'osmfr': true,                        // 'OpenStreetMap (French Style)'
  'osm-mapnik-german_style': true,      // 'OpenStreetMap (German Style)'
  'HDM_HOT': true,                      // 'OpenStreetMap (HOT Style)'
  'osm-mapnik-black_and_white': true,   // 'OpenStreetMap (Standard Black & White)'
  'osm-mapnik-no_labels': true,         // 'OpenStreetMap (Mapnik, no labels)'
  'OpenStreetMap-turistautak': true,    // 'OpenStreetMap (turistautak)'

  'hike_n_bike': true,                  // 'Hike & Bike'
  'landsat': true,                      // 'Landsat'
  'skobbler': true,                     // 'Skobbler'
  'public_transport_oepnv': true,       // 'Public Transport (ÖPNV)'
  'tf-cycle': true,                     // 'Thunderforest OpenCycleMap'
  'tf-landscape': true,                 // 'Thunderforest Landscape'
  'qa_no_address': true,                // 'QA No Address'
  'wikimedia-map': true,                // 'Wikimedia Map'

  'openinframap-petroleum': true,
  'openinframap-power': true,
  'openinframap-telecoms': true,
  'openpt_map': true,
  'openrailwaymap': true,
  'openseamap': true,
  'opensnowmap-overlay': true,

  'US-TIGER-Roads-2012': true,
  'US-TIGER-Roads-2014': true,

  'Waymarked_Trails-Cycling': true,
  'Waymarked_Trails-Hiking': true,
  'Waymarked_Trails-Horse_Riding': true,
  'Waymarked_Trails-MTB': true,
  'Waymarked_Trails-Skating': true,
  'Waymarked_Trails-Winter_Sports': true,

  'OSM_Inspector-Addresses': true,
  'OSM_Inspector-Geometry': true,
  'OSM_Inspector-Highways': true,
  'OSM_Inspector-Multipolygon': true,
  'OSM_Inspector-Places': true,
  'OSM_Inspector-Routing': true,
  'OSM_Inspector-Tagging': true,

  'EOXAT2018CLOUDLESS': true
};

const supportedWMSProjections = {
  'EPSG:4326': true,
  'EPSG:3857': true,
  'EPSG:900913': true,
  'EPSG:3587': true,
  'EPSG:54004': true,
  'EPSG:41001': true,
  'EPSG:102113': true,
  'EPSG:102100': true,
  'EPSG:3785': true
};

sources.concat(keep).forEach(source => {
  if (source.type !== 'tms' && source.type !== 'wms' && source.type !== 'bing') return;
  if (source.id in discard) return;

  let im = {
    id: source.id,
    name: source.name,
    type: source.type,
    template: source.url
  };

  // Some sources support 512px tiles
  if (source.id === 'Mapbox') {
    im.template = im.template.replace('.jpg', '@2x.jpg');
    im.tileSize = 512;
  } else if (source.id === 'mtbmap-no') {
    im.tileSize = 512;
  }

  // Some WMS sources are supported, check projection
  if (source.type === 'wms') {
    const projection = (source.available_projections || []).find(p => supportedWMSProjections[p]);
    if (!projection) return;
    if (sources.some(other => other.name === source.name && other.type !== source.type)) return;
    im.projection = projection;
  }

  let startDate, endDate, isValid;

  if (source.end_date) {
    endDate = new Date(source.end_date);
    isValid = !isNaN(endDate.getTime());
    if (isValid) {
      if (endDate <= cutoffDate) return;  // too old
      im.endDate = endDate;
    }
  }

  if (source.start_date) {
    startDate = new Date(source.start_date);
    isValid = !isNaN(startDate.getTime());
    if (isValid) {
      im.startDate = startDate;
    }
  }

  let extent = source.extent || {};
  if (extent.min_zoom || extent.max_zoom) {
    im.zoomExtent = [
      extent.min_zoom || 0,
      extent.max_zoom || 22
    ];
  }

  if (extent.polygon) {
    im.polygon = extent.polygon;
  } else if (extent.bbox) {
    im.polygon = [[
      [extent.bbox.min_lon, extent.bbox.min_lat],
      [extent.bbox.min_lon, extent.bbox.max_lat],
      [extent.bbox.max_lon, extent.bbox.max_lat],
      [extent.bbox.max_lon, extent.bbox.min_lat],
      [extent.bbox.min_lon, extent.bbox.min_lat]
    ]];
  }

  if (source.id === 'mapbox_locator_overlay') {
    im.overzoom = false;
  }

  const attribution = source.attribution || {};
  if (attribution.url) {
    im.terms_url = attribution.url;
  }
  if (attribution.text) {
    im.terms_text = attribution.text;
  }
  if (attribution.html) {
    im.terms_html = attribution.html;
  }

  ['best', 'default', 'description', 'encrypted', 'icon', 'overlay', 'tileSize'].forEach(prop => {
    if (source[prop]) {
      im[prop] = source[prop];
    }
  });

  imagery.push(im);
});

imagery.sort((a, b) => a.name.localeCompare(b.name));

fs.writeFileSync('data/imagery.json', prettyStringify(imagery));
fs.writeFileSync('dist/data/imagery.min.json', JSON.stringify(imagery));
<commit_msg>Ignore Thunderforest Outdoors layer<commit_after>/* eslint-disable no-console */
const fs = require('fs');
const sources = require('editor-layer-index/imagery.json');
const prettyStringify = require('json-stringify-pretty-compact');

let imagery = [];

// ignore imagery more than 20 years old..
let cutoffDate = new Date();
cutoffDate.setFullYear(cutoffDate.getFullYear() - 20);

const keep = [
  // Add custom sources here if needed.
  {
    id: 'Maxar-Premium',
    name: 'Maxar Premium Imagery (Beta)',
    type: 'tms',
    default: true,
    attribution: {
      required: true,
      text: 'Terms & Feedback',
      url: 'https://wiki.openstreetmap.org/wiki/DigitalGlobe'
    },
    description: 'Maxar Premium is a mosaic composed of Maxar basemap with select regions filled with +Vivid or custom area of interest imagery, 50cm resolution or better, and refreshed more frequently with ongoing updates.',
    icon: 'https://osmlab.github.io/editor-layer-index/sources/world/Maxar.png',
    max_zoom: 22,
    url: '7586487389962e3f6e31ab2ed8ca321f2f3fe2cf87f1dedce8fc918b4692efd86fcd816ab8a35303effb1be9abe39b1cce3fe6db2c740044364ae68560822c88373d2c784325baf4e1fa007c6dbedab4cea3fa0dd86ee0ae4feeef032d33dcac28e4b16c90d55a42087c6b66526423ea1b4cc7e63c613940eb1c60f48270060bf41c5fcb6a628985ebe6801e9e71f041cc9f8df06b0345600376663e7dc1cdbc7df16876d8b5d006ed5782e6af4bfe2ff5a292',
    encrypted: true
  }, {
    id: 'Maxar-Standard',
    name: 'Maxar Standard Imagery (Beta)',
    type: 'tms',
    default: true,
    attribution: {
      required: true,
      text: 'Terms & Feedback',
      url: 'https://wiki.openstreetmap.org/wiki/DigitalGlobe'
    },
    description: 'Maxar Standard is a curated set of imagery covering 86% of the earth’s landmass, with 30-60cm resolution where available, backfilled by Landsat. Average age is 2.31 years, with some areas updated 2x per year.',
    icon: 'https://osmlab.github.io/editor-layer-index/sources/world/Maxar.png',
    max_zoom: 22,
    url: '7586487389962e3f6e31ab2ed8ca321f2f3fe2cf87f1dedce8fc918b4692efd86fcd816ab8a35303effb1be9abe39b1cce3fe6db2c740044364ae68560822c88373d2c784325baf4e1fa007c6dbedab4cea3fa0dd86ee0ae4feeef032d33dcac28e4b16c90d55a42087c6b66526423ea1b4cc7e63c613940eb1c60f48270060bf41c5fcb6a628985ebe6801e9e71f010c8c9d7fb6b534560012461377dc1cdb672f16827dfe0d005bf5685b7ac4ea97cf5f795',
    encrypted: true
  }
];

const discard = {
  'osmbe': true,                        // 'OpenStreetMap (Belgian Style)'
  'osmfr': true,                        // 'OpenStreetMap (French Style)'
  'osm-mapnik-german_style': true,      // 'OpenStreetMap (German Style)'
  'HDM_HOT': true,                      // 'OpenStreetMap (HOT Style)'
  'osm-mapnik-black_and_white': true,   // 'OpenStreetMap (Standard Black & White)'
  'osm-mapnik-no_labels': true,         // 'OpenStreetMap (Mapnik, no labels)'
  'OpenStreetMap-turistautak': true,    // 'OpenStreetMap (turistautak)'

  'hike_n_bike': true,                  // 'Hike & Bike'
  'landsat': true,                      // 'Landsat'
  'skobbler': true,                     // 'Skobbler'
  'public_transport_oepnv': true,       // 'Public Transport (ÖPNV)'
  'tf-cycle': true,                     // 'Thunderforest OpenCycleMap'
  'tf-landscape': true,                 // 'Thunderforest Landscape'
  'tf-outdoors': true,                  // 'Thunderforest Outdoors'
  'qa_no_address': true,                // 'QA No Address'
  'wikimedia-map': true,                // 'Wikimedia Map'

  'openinframap-petroleum': true,
  'openinframap-power': true,
  'openinframap-telecoms': true,
  'openpt_map': true,
  'openrailwaymap': true,
  'openseamap': true,
  'opensnowmap-overlay': true,

  'US-TIGER-Roads-2012': true,
  'US-TIGER-Roads-2014': true,

  'Waymarked_Trails-Cycling': true,
  'Waymarked_Trails-Hiking': true,
  'Waymarked_Trails-Horse_Riding': true,
  'Waymarked_Trails-MTB': true,
  'Waymarked_Trails-Skating': true,
  'Waymarked_Trails-Winter_Sports': true,

  'OSM_Inspector-Addresses': true,
  'OSM_Inspector-Geometry': true,
  'OSM_Inspector-Highways': true,
  'OSM_Inspector-Multipolygon': true,
  'OSM_Inspector-Places': true,
  'OSM_Inspector-Routing': true,
  'OSM_Inspector-Tagging': true,

  'EOXAT2018CLOUDLESS': true
};

const supportedWMSProjections = {
  'EPSG:4326': true,
  'EPSG:3857': true,
  'EPSG:900913': true,
  'EPSG:3587': true,
  'EPSG:54004': true,
  'EPSG:41001': true,
  'EPSG:102113': true,
  'EPSG:102100': true,
  'EPSG:3785': true
};

sources.concat(keep).forEach(source => {
  if (source.type !== 'tms' && source.type !== 'wms' && source.type !== 'bing') return;
  if (source.id in discard) return;

  let im = {
    id: source.id,
    name: source.name,
    type: source.type,
    template: source.url
  };

  // Some sources support 512px tiles
  if (source.id === 'Mapbox') {
    im.template = im.template.replace('.jpg', '@2x.jpg');
    im.tileSize = 512;
  } else if (source.id === 'mtbmap-no') {
    im.tileSize = 512;
  }

  // Some WMS sources are supported, check projection
  if (source.type === 'wms') {
    const projection = (source.available_projections || []).find(p => supportedWMSProjections[p]);
    if (!projection) return;
    if (sources.some(other => other.name === source.name && other.type !== source.type)) return;
    im.projection = projection;
  }

  let startDate, endDate, isValid;

  if (source.end_date) {
    endDate = new Date(source.end_date);
    isValid = !isNaN(endDate.getTime());
    if (isValid) {
      if (endDate <= cutoffDate) return;  // too old
      im.endDate = endDate;
    }
  }

  if (source.start_date) {
    startDate = new Date(source.start_date);
    isValid = !isNaN(startDate.getTime());
    if (isValid) {
      im.startDate = startDate;
    }
  }

  let extent = source.extent || {};
  if (extent.min_zoom || extent.max_zoom) {
    im.zoomExtent = [
      extent.min_zoom || 0,
      extent.max_zoom || 22
    ];
  }

  if (extent.polygon) {
    im.polygon = extent.polygon;
  } else if (extent.bbox) {
    im.polygon = [[
      [extent.bbox.min_lon, extent.bbox.min_lat],
      [extent.bbox.min_lon, extent.bbox.max_lat],
      [extent.bbox.max_lon, extent.bbox.max_lat],
      [extent.bbox.max_lon, extent.bbox.min_lat],
      [extent.bbox.min_lon, extent.bbox.min_lat]
    ]];
  }

  if (source.id === 'mapbox_locator_overlay') {
    im.overzoom = false;
  }

  const attribution = source.attribution || {};
  if (attribution.url) {
    im.terms_url = attribution.url;
  }
  if (attribution.text) {
    im.terms_text = attribution.text;
  }
  if (attribution.html) {
    im.terms_html = attribution.html;
  }

  ['best', 'default', 'description', 'encrypted', 'icon', 'overlay', 'tileSize'].forEach(prop => {
    if (source[prop]) {
      im[prop] = source[prop];
    }
  });

  imagery.push(im);
});

imagery.sort((a, b) => a.name.localeCompare(b.name));

fs.writeFileSync('data/imagery.json', prettyStringify(imagery));
fs.writeFileSync('dist/data/imagery.min.json', JSON.stringify(imagery));
<|endoftext|>


<commit_before>'use strict';

const sinon = require('sinon');
const should = require('should');
const mockrequire = require('mock-require');
const rewire = require('rewire');
const Bluebird = require('bluebird');
const stringify = require('json-stable-stringify');

const KuzzleMock = require('../mocks/kuzzle.mock');
const MutexMock = require('../mocks/mutex.mock.js');
const Plugin = require('../../lib/core/plugin/plugin');
const kuzzleStateEnum = require('../../lib/kuzzle/kuzzleStateEnum');
const { sha256 } = require('../../lib/util/crypto');

const config = require('../../lib/config').loadConfig();

describe('/lib/kuzzle/kuzzle.js', () => {
  let kuzzle;
  let Kuzzle;
  let application;
  let clusterModuleInitStub;

  const mockedProperties = [
    'entryPoint',
    'funnel',
    'router',
    'notifier',
    'gc',
    'pluginsManager',
    'adminController',
    'services',
    'statistics',
    'validation',
    'emit',
    'vault',
    'log',
    'internalIndex',
    'dumpGenerator',
    'pipe',
    'ask',
    'tokenManager',
  ];

  function _mockKuzzle (KuzzleConstructor) {
    Reflect.deleteProperty(global, 'kuzzle');
    const k = new KuzzleConstructor(config);
    const mock = new KuzzleMock();

    mockedProperties.forEach(p => {
      k[p] = mock[p];
    });

    return k;
  }

  beforeEach(() => {
    clusterModuleInitStub = sinon.stub().resolves();
    const clusterModuleStub = function () {
      return { init: clusterModuleInitStub };
    };

    const coreModuleStub = function () {
      return { init: sinon.stub().resolves() };
    };

    mockrequire('../../lib/core/cache/cacheEngine', coreModuleStub);
    mockrequire('../../lib/core/storage/storageEngine', coreModuleStub);
    mockrequire('../../lib/core/security', coreModuleStub);
    mockrequire('../../lib/core/realtime', coreModuleStub);
    mockrequire('../../lib/cluster', clusterModuleStub);
    mockrequire('../../lib/util/mutex', { Mutex: MutexMock });

    mockrequire.reRequire('../../lib/kuzzle/kuzzle');
    Kuzzle = rewire('../../lib/kuzzle/kuzzle');
    Kuzzle.__set__('console', { log: () => {} });

    kuzzle = _mockKuzzle(Kuzzle);
    application = new Plugin(
      { init: sinon.stub() },
      { name: 'application', application: true, openApi: 'openApi' });
  });

  afterEach(() => {
    mockrequire.stopAll();
    Kuzzle.__set__('console', console);
  });

  it('should build a kuzzle server object with emit and listen event', done => {
    kuzzle.on('event', done);
    kuzzle.emit('event');
  });

  describe('#start', () => {
    it('should init the components in proper order', async () => {
      const Koncorde = sinon.stub();
      const stubbedKuzzle = Kuzzle.__with__({
        koncorde_1: { Koncorde },
        vault_1: { default: { load: () => {} } }
      });

      await stubbedKuzzle(async () => {
        kuzzle = _mockKuzzle(Kuzzle);

        kuzzle.install = sinon.stub().resolves();
        kuzzle.loadInitialState = sinon.stub().resolves();
        const options = {
          import: { something: 'here' },
          installations: [{ id: 'foo', handler: () => {} }],
          support: { something: 'here' }
        };

        kuzzle._waitForImportToFinish = sinon.stub().resolves();

        should(kuzzle.state).be.eql(kuzzleStateEnum.STARTING);

        await kuzzle.start(application, options);

        sinon.assert.callOrder(
          kuzzle.pipe, // kuzzle:state:start
          kuzzle.internalIndex.init,
          // clusterModuleInitStub,
          kuzzle.validation.init,
          kuzzle.tokenManager.init,
          kuzzle.funnel.init,
          kuzzle.statistics.init,
          kuzzle.validation.curateSpecification,
          kuzzle.entryPoint.init,
          kuzzle.pluginsManager.init,
          kuzzle.loadInitialState.withArgs(options.import, options.support),
          kuzzle.ask.withArgs('core:security:verify'),
          kuzzle.router.init,
          kuzzle.install.withArgs(options.installations),
          kuzzle.pipe.withArgs('kuzzle:start'),
          kuzzle.pipe.withArgs('kuzzle:state:live'),
          kuzzle.entryPoint.startListening,
          kuzzle.pipe.withArgs('kuzzle:state:ready'),
          kuzzle.emit.withArgs('core:kuzzleStart')
        );

        should(kuzzle.state).be.eql(kuzzleStateEnum.RUNNING);
      });
    });

    // @deprecated
    it('should instantiate Koncorde with PCRE support if asked to', async () => {
      const Koncorde = sinon.stub();
      const stubbedKuzzle = Kuzzle.__with__({
        koncorde_1: { Koncorde },
        vault_1: { default: { load: () => {} } }
      });

      await stubbedKuzzle(async () => {
        const baseKuzzle = _mockKuzzle(Kuzzle);

        baseKuzzle._waitForImportToFinish = sinon.stub().resolves();

        await baseKuzzle.start(application);

        const kuzzleWithPCRE = _mockKuzzle(Kuzzle);

        kuzzleWithPCRE.ask = sinon.stub().resolves();
        kuzzleWithPCRE.ask.withArgs('core:cache:internal:get').resolves(1);

        kuzzleWithPCRE.config =
          JSON.parse(JSON.stringify(kuzzleWithPCRE.config));

        kuzzleWithPCRE.config.realtime.pcreSupport = true;

        await kuzzleWithPCRE.start(application);
      });

      should(Koncorde.firstCall).calledWithMatch({ regExpEngine: 're2' });
      should(Koncorde.secondCall).calledWithMatch({ regExpEngine: 'js' });
    });

    it('should start all services and register errors handlers if enabled on kuzzle.start', () => {
      let processExitSpy = sinon.spy();
      let processOnSpy = sinon.spy();
      let processRemoveAllListenersSpy = sinon.spy();

      return Kuzzle.__with__({
        process: {
          ...process,
          env: {},
          exit: processExitSpy,
          on: processOnSpy,
          emit: sinon.stub(),
          removeAllListeners: processRemoveAllListenersSpy
        }
      })(() => {
        kuzzle = _mockKuzzle(Kuzzle);
        kuzzle._waitForImportToFinish = sinon.stub().resolves();

        return kuzzle.start(application);
      })
        .then(() => {
          should(processRemoveAllListenersSpy.getCall(0).args[0]).be.exactly('unhandledRejection');
          should(processOnSpy.getCall(0).args[0]).be.exactly('unhandledRejection');

          should(processRemoveAllListenersSpy.getCall(1).args[0]).be.exactly('uncaughtException');
          should(processOnSpy.getCall(1).args[0]).be.exactly('uncaughtException');

          should(processRemoveAllListenersSpy.getCall(2).args[0]).be.exactly('SIGQUIT');
          should(processOnSpy.getCall(2).args[0]).be.exactly('SIGQUIT');

          should(processRemoveAllListenersSpy.getCall(3).args[0]).be.exactly('SIGABRT');
          should(processOnSpy.getCall(3).args[0]).be.exactly('SIGABRT');

          should(processRemoveAllListenersSpy.getCall(4).args[0]).be.exactly('SIGTRAP');
          should(processOnSpy.getCall(4).args[0]).be.exactly('SIGTRAP');

          should(processRemoveAllListenersSpy.getCall(5).args[0]).be.exactly('SIGINT');
          should(processOnSpy.getCall(5).args[0]).be.exactly('SIGINT');

          should(processRemoveAllListenersSpy.getCall(6).args[0]).be.exactly('SIGTERM');
          should(processOnSpy.getCall(6).args[0]).be.exactly('SIGTERM');
        });
    });
  });

  describe('#generateId', () => {
    it('should not initialize the cluster if disabled', async () => {
      kuzzle.config.cluster.enabled = false;

      await kuzzle.start(application, {});

      should(clusterModuleInitStub).not.be.called();
    });
  });

  describe('#dump', () => {
    it('should calls dumpGenerator.dump', async () => {
      await kuzzle.dump();

      should(kuzzle.dumpGenerator.dump).be.calledOnce();
    });
  });

  describe('#shutdown', () => {
    it('should exit only when there is no request left in the funnel', async () => {
      sinon.stub(process, 'exit');

      // We cannot use sinon's fake timers: they do not work with async
      // functions
      sinon.stub(Bluebird, 'delay').callsFake(() => {
        // we must wait a bit: if we replace with stub.resolves(), V8 converts
        // that into a direct function call, and the event loop never rotates
        return new Promise(resolve => setTimeout(resolve, 10));
      });

      kuzzle.funnel.remainingRequests = 1;

      setTimeout(
        () => {
          kuzzle.funnel.remainingRequests = 0;
        },
        50);

      try {
        await kuzzle.shutdown();

        should(kuzzle.entryPoint.dispatch).calledOnce().calledWith('shutdown');
        should(kuzzle.pipe).calledWith('kuzzle:shutdown');
        should(Bluebird.delay.callCount).approximately(5, 1);

        // @deprecated
        should(kuzzle.emit).calledWith('core:shutdown');

        should(process.exit).calledOnce().calledWith(0);
      }
      finally {
        process.exit.restore();
        Bluebird.delay.restore();
      }
    });
  });

  describe('#install', () => {
    let handler;

    beforeEach(() => {
      handler = sinon.stub().resolves();
      sinon.stub(Date, 'now').returns(Date.now());

      kuzzle.ask = sinon.stub().withArgs(['core:storage:private:document:exist']).resolves(false);
      kuzzle.ask = sinon.stub().withArgs(['core:storage:private:document:create']).resolves();
    });

    afterEach(() => {
      Date.now.restore();
    });

    it('should call the handler and work properly', async () => {
      await kuzzle.install([{ id: 'id', handler, description: 'description' }]);

      should(kuzzle.ask).be.calledTwice();
      should(kuzzle.ask).be.calledWith(
        'core:storage:private:document:exist',
        'kuzzle',
        'installations',
        'id');
      should(kuzzle.ask).be.calledWith(
        'core:storage:private:document:create',
        'kuzzle',
        'installations',
        { description: 'description', handler: handler.toString(), installedAt: Date.now() },
        { id: 'id' });
      should(handler).be.calledOnce();
      should(kuzzle.log.info).be.calledOnce();
    });

    it('should handle situation when handler has already been executed', async () => {
      kuzzle.ask = sinon.stub().withArgs(['core:storage:private:document:exist']).resolves(true);

      await kuzzle.install([{ id: 'id', handler }]);

      should(kuzzle.ask).be.calledWith(
        'core:storage:private:document:exist',
        'kuzzle',
        'installations',
        'id');
      should(kuzzle.ask).be.neverCalledWith(
        'core:storage:private:document:create',
        'kuzzle',
        'installations',
        { handler: handler.toString(), installedAt: Date.now() },
        { id: 'id' });
      should(handler).not.be.called();
      should(kuzzle.log.info).not.be.called();
    });
  });

  describe('#import', () => {
    let toImport;
    let toSupport;

    beforeEach(() => {
      toImport = {
        mappings: { something: 'here' },
        onExistingUsers: 'skip',
        profiles: { something: 'here' },
        roles: { something: 'here' },
        userMappings: { something: 'here' },
        user: { something: 'here' },
      };
      toSupport = {
        mappings: { something: 'here' },
        fixtures: { something: 'here' },
        securities: {
          profiles: { something: 'here' },
          roles: { something: 'here' },
          user: { something: 'here' }
        }
      };

      kuzzle.internalIndex.updateMapping = sinon.stub().resolves();
      kuzzle.internalIndex.refreshCollection = sinon.stub().resolves();
    });

    it('should load correctly toImport mappings and permissions', async () => {
      kuzzle._waitForImportToFinish = sinon.stub().resolves();
      await kuzzle.loadInitialState(toImport, {});

      should(kuzzle.ask).be.calledWith(
        'core:cache:internal:get',
        'backend:init:import:mappings');

      should(kuzzle.ask).be.calledWith(
        'core:cache:internal:get',
        'backend:init:import:permissions');

      const mappingsPayload = {
        toImport: {
          mappings: toImport.mappings,
        },
        toSupport: {
          mappings: toSupport.mappings,
        }
      };

      should(kuzzle.ask).be.calledWith(
        'core:cache:internal:store',
        sha256(stringify(mappingsPayload)));

      const permissionsPayload = {
        toImport: {
          profiles: toImport.profiles,
          roles: toImport.roles,
          users: toImport.users,
        },
        toSupport: {
          securities: toSupport.securities,
        }
      };

      should(kuzzle.ask).be.calledWith(
        'core:cache:internal:store',
        sha256(stringify(permissionsPayload)));

      should(kuzzle.internalIndex.updateMapping).be.calledWith('users', toImport.userMappings);
      should(kuzzle.internalIndex.refreshCollection).be.calledWith('users');
      should(kuzzle.ask).calledWith('core:storage:public:mappings:import', toImport.mappings,
        {
          indexCacheOnly: false,
          propagate: false,
          refresh: true,
        });
      should(kuzzle.ask).calledWith('core:security:load',
        {
          profiles: toImport.profiles,
          roles: toImport.roles,
          users: toImport.users,
        },
        {
          onExistingUsers: toImport.onExistingUsers,
          onExistingUsersWarning: true,
          refresh: 'wait_for',
        });
    });

    it('should load correctly toSupport mappings, fixtures and securities', async () => {
      kuzzle._waitForImportToFinish = sinon.stub().resolves();
      await kuzzle.loadInitialState({}, toSupport);

      should(kuzzle.ask).be.calledWith(
        'core:cache:internal:get',
        'backend:init:import:mappings');

      should(kuzzle.ask).be.calledWith(
        'core:cache:internal:get',
        'backend:init:import:permissions');

      should(kuzzle.ask).be.calledWith(
        'core:cache:internal:get',
        'backend:init:import:fixtures');

      should(kuzzle.ask).be.calledWithMatch(
        'core:cache:internal:store');

      const mappingsPayload = {
        toImport: {
          mappings: toImport.mappings,
        },
        toSupport: {
          mappings: toSupport.mappings,
        }
      };

      should(kuzzle.ask).be.calledWith(
        'core:cache:internal:store',
        sha256(stringify(mappingsPayload)));

      const permissionsPayload = {
        toImport: {
          profiles: toImport.profiles,
          roles: toImport.roles,
          users: toImport.users,
        },
        toSupport: {
          securities: toSupport.securities,
        }
      };

      should(kuzzle.ask).be.calledWith(
        'core:cache:internal:store',
        sha256(stringify(permissionsPayload)));

      const fixturesPayload = {
        toSupport: {
          securities: toSupport.securities,
        }
      };

      should(kuzzle.ask).be.calledWith(
        'core:cache:internal:store',
        sha256(stringify(fixturesPayload)));

      should(kuzzle.ask).calledWith('core:storage:public:mappings:import', toSupport.mappings, {
        indexCacheOnly: false,
        propagate: false,
        rawMappings: true,
        refresh: true,
      });
      should(kuzzle.ask).calledWith('core:storage:public:document:import', toSupport.fixtures);
      should(kuzzle.ask).calledWith('core:security:load', toSupport.securities, {
        force: true,
        refresh: 'wait_for'
      });
    });

    it('should prevent mappings to be loaded from import and support simultaneously', () => {
      return should(kuzzle.loadInitialState(toImport, { mappings: { something: 'here' } }))
        .be.rejectedWith({ id: 'plugin.runtime.incompatible' });
    });

    it('should prevent permissions to be loaded from import and support simultaneously', () => {
      return should(
        kuzzle.loadInitialState(
          { profiles: { something: 'here' } },
          { securities: { roles: { something: 'here' } } }))
        .be.rejectedWith({ id: 'plugin.runtime.incompatible' });
    });
  });
});
<commit_msg>More test<commit_after>'use strict';

const sinon = require('sinon');
const should = require('should');
const mockrequire = require('mock-require');
const rewire = require('rewire');
const Bluebird = require('bluebird');
const stringify = require('json-stable-stringify');

const KuzzleMock = require('../mocks/kuzzle.mock');
const MutexMock = require('../mocks/mutex.mock.js');
const Plugin = require('../../lib/core/plugin/plugin');
const kuzzleStateEnum = require('../../lib/kuzzle/kuzzleStateEnum');
const { sha256 } = require('../../lib/util/crypto');
const { BACKEND_IMPORT_KEY } = require('../../lib/kuzzle/kuzzle')

const config = require('../../lib/config').loadConfig();

describe('/lib/kuzzle/kuzzle.js', () => {
  let kuzzle;
  let Kuzzle;
  let application;
  let clusterModuleInitStub;

  const mockedProperties = [
    'adminController',
    'ask',
    'dumpGenerator',
    'emit',
    'entryPoint',
    'funnel',
    'gc',
    'internalIndex',
    'log',
    'notifier',
    'pipe',
    'pluginsManager',
    'router',
    'services',
    'statistics',
    'tokenManager',
    'validation',
    'vault',
  ];

  function _mockKuzzle (KuzzleConstructor) {
    Reflect.deleteProperty(global, 'kuzzle');
    const k = new KuzzleConstructor(config);
    const mock = new KuzzleMock();

    mockedProperties.forEach(p => {
      k[p] = mock[p];
    });

    return k;
  }

  beforeEach(() => {
    clusterModuleInitStub = sinon.stub().resolves();
    const clusterModuleStub = function () {
      return { init: clusterModuleInitStub };
    };

    const coreModuleStub = function () {
      return { init: sinon.stub().resolves() };
    };

    mockrequire('../../lib/core/cache/cacheEngine', coreModuleStub);
    mockrequire('../../lib/core/storage/storageEngine', coreModuleStub);
    mockrequire('../../lib/core/security', coreModuleStub);
    mockrequire('../../lib/core/realtime', coreModuleStub);
    mockrequire('../../lib/cluster', clusterModuleStub);
    mockrequire('../../lib/util/mutex', { Mutex: MutexMock });

    mockrequire.reRequire('../../lib/kuzzle/kuzzle');
    Kuzzle = rewire('../../lib/kuzzle/kuzzle');
    Kuzzle.__set__('console', { log: () => {} });

    kuzzle = _mockKuzzle(Kuzzle);
    application = new Plugin(
      { init: sinon.stub() },
      { name: 'application', application: true, openApi: 'openApi' });
  });

  afterEach(() => {
    mockrequire.stopAll();
    Kuzzle.__set__('console', console);
  });

  it('should build a kuzzle server object with emit and listen event', done => {
    kuzzle.on('event', done);
    kuzzle.emit('event');
  });

  describe('#start', () => {
    it('should init the components in proper order', async () => {
      const Koncorde = sinon.stub();
      const stubbedKuzzle = Kuzzle.__with__({
        koncorde_1: { Koncorde },
        vault_1: { default: { load: () => {} } }
      });

      await stubbedKuzzle(async () => {
        kuzzle = _mockKuzzle(Kuzzle);

        kuzzle.install = sinon.stub().resolves();
        kuzzle.loadInitialState = sinon.stub().resolves();
        const options = {
          import: { something: 'here' },
          installations: [{ id: 'foo', handler: () => {} }],
          support: { something: 'here' }
        };

        kuzzle._waitForImportToFinish = sinon.stub().resolves();

        should(kuzzle.state).be.eql(kuzzleStateEnum.STARTING);

        await kuzzle.start(application, options);

        sinon.assert.callOrder(
          kuzzle.pipe, // kuzzle:state:start
          kuzzle.internalIndex.init,
          // clusterModuleInitStub,
          kuzzle.validation.init,
          kuzzle.tokenManager.init,
          kuzzle.funnel.init,
          kuzzle.statistics.init,
          kuzzle.validation.curateSpecification,
          kuzzle.entryPoint.init,
          kuzzle.pluginsManager.init,
          kuzzle.loadInitialState.withArgs(options.import, options.support),
          kuzzle.ask.withArgs('core:security:verify'),
          kuzzle.router.init,
          kuzzle.install.withArgs(options.installations),
          kuzzle.pipe.withArgs('kuzzle:start'),
          kuzzle.pipe.withArgs('kuzzle:state:live'),
          kuzzle.entryPoint.startListening,
          kuzzle.pipe.withArgs('kuzzle:state:ready'),
          kuzzle.emit.withArgs('core:kuzzleStart')
        );

        should(kuzzle.state).be.eql(kuzzleStateEnum.RUNNING);
      });
    });

    // @deprecated
    it('should instantiate Koncorde with PCRE support if asked to', async () => {
      const Koncorde = sinon.stub();
      const stubbedKuzzle = Kuzzle.__with__({
        koncorde_1: { Koncorde },
        vault_1: { default: { load: () => {} } }
      });

      await stubbedKuzzle(async () => {
        const baseKuzzle = _mockKuzzle(Kuzzle);

        baseKuzzle._waitForImportToFinish = sinon.stub().resolves();

        await baseKuzzle.start(application);

        const kuzzleWithPCRE = _mockKuzzle(Kuzzle);

        kuzzleWithPCRE.ask = sinon.stub().resolves();
        kuzzleWithPCRE.ask.withArgs('core:cache:internal:get').resolves(1);

        kuzzleWithPCRE.config =
          JSON.parse(JSON.stringify(kuzzleWithPCRE.config));

        kuzzleWithPCRE.config.realtime.pcreSupport = true;

        await kuzzleWithPCRE.start(application);
      });

      should(Koncorde.firstCall).calledWithMatch({ regExpEngine: 're2' });
      should(Koncorde.secondCall).calledWithMatch({ regExpEngine: 'js' });
    });

    it('should start all services and register errors handlers if enabled on kuzzle.start', () => {
      let processExitSpy = sinon.spy();
      let processOnSpy = sinon.spy();
      let processRemoveAllListenersSpy = sinon.spy();

      return Kuzzle.__with__({
        process: {
          ...process,
          env: {},
          exit: processExitSpy,
          on: processOnSpy,
          emit: sinon.stub(),
          removeAllListeners: processRemoveAllListenersSpy
        }
      })(() => {
        kuzzle = _mockKuzzle(Kuzzle);
        kuzzle._waitForImportToFinish = sinon.stub().resolves();

        return kuzzle.start(application);
      })
        .then(() => {
          should(processRemoveAllListenersSpy.getCall(0).args[0]).be.exactly('unhandledRejection');
          should(processOnSpy.getCall(0).args[0]).be.exactly('unhandledRejection');

          should(processRemoveAllListenersSpy.getCall(1).args[0]).be.exactly('uncaughtException');
          should(processOnSpy.getCall(1).args[0]).be.exactly('uncaughtException');

          should(processRemoveAllListenersSpy.getCall(2).args[0]).be.exactly('SIGQUIT');
          should(processOnSpy.getCall(2).args[0]).be.exactly('SIGQUIT');

          should(processRemoveAllListenersSpy.getCall(3).args[0]).be.exactly('SIGABRT');
          should(processOnSpy.getCall(3).args[0]).be.exactly('SIGABRT');

          should(processRemoveAllListenersSpy.getCall(4).args[0]).be.exactly('SIGTRAP');
          should(processOnSpy.getCall(4).args[0]).be.exactly('SIGTRAP');

          should(processRemoveAllListenersSpy.getCall(5).args[0]).be.exactly('SIGINT');
          should(processOnSpy.getCall(5).args[0]).be.exactly('SIGINT');

          should(processRemoveAllListenersSpy.getCall(6).args[0]).be.exactly('SIGTERM');
          should(processOnSpy.getCall(6).args[0]).be.exactly('SIGTERM');
        });
    });
  });

  describe('#generateId', () => {
    it('should not initialize the cluster if disabled', async () => {
      kuzzle.config.cluster.enabled = false;

      await kuzzle.start(application, {});

      should(clusterModuleInitStub).not.be.called();
    });
  });

  describe('#dump', () => {
    it('should calls dumpGenerator.dump', async () => {
      await kuzzle.dump();

      should(kuzzle.dumpGenerator.dump).be.calledOnce();
    });
  });

  describe('#shutdown', () => {
    it('should exit only when there is no request left in the funnel', async () => {
      sinon.stub(process, 'exit');

      // We cannot use sinon's fake timers: they do not work with async
      // functions
      sinon.stub(Bluebird, 'delay').callsFake(() => {
        // we must wait a bit: if we replace with stub.resolves(), V8 converts
        // that into a direct function call, and the event loop never rotates
        return new Promise(resolve => setTimeout(resolve, 10));
      });

      kuzzle.funnel.remainingRequests = 1;

      setTimeout(
        () => {
          kuzzle.funnel.remainingRequests = 0;
        },
        50);

      try {
        await kuzzle.shutdown();

        should(kuzzle.entryPoint.dispatch).calledOnce().calledWith('shutdown');
        should(kuzzle.pipe).calledWith('kuzzle:shutdown');
        should(Bluebird.delay.callCount).approximately(5, 1);

        // @deprecated
        should(kuzzle.emit).calledWith('core:shutdown');

        should(process.exit).calledOnce().calledWith(0);
      }
      finally {
        process.exit.restore();
        Bluebird.delay.restore();
      }
    });
  });

  describe('#install', () => {
    let handler;

    beforeEach(() => {
      handler = sinon.stub().resolves();
      sinon.stub(Date, 'now').returns(Date.now());

      kuzzle.ask = sinon.stub().withArgs(['core:storage:private:document:exist']).resolves(false);
      kuzzle.ask = sinon.stub().withArgs(['core:storage:private:document:create']).resolves();
    });

    afterEach(() => {
      Date.now.restore();
    });

    it('should call the handler and work properly', async () => {
      await kuzzle.install([{ id: 'id', handler, description: 'description' }]);

      should(kuzzle.ask).be.calledTwice();
      should(kuzzle.ask).be.calledWith(
        'core:storage:private:document:exist',
        'kuzzle',
        'installations',
        'id');
      should(kuzzle.ask).be.calledWith(
        'core:storage:private:document:create',
        'kuzzle',
        'installations',
        { description: 'description', handler: handler.toString(), installedAt: Date.now() },
        { id: 'id' });
      should(handler).be.calledOnce();
      should(kuzzle.log.info).be.calledOnce();
    });

    it('should handle situation when handler has already been executed', async () => {
      kuzzle.ask = sinon.stub().withArgs(['core:storage:private:document:exist']).resolves(true);

      await kuzzle.install([{ id: 'id', handler }]);

      should(kuzzle.ask).be.calledWith(
        'core:storage:private:document:exist',
        'kuzzle',
        'installations',
        'id');
      should(kuzzle.ask).be.neverCalledWith(
        'core:storage:private:document:create',
        'kuzzle',
        'installations',
        { handler: handler.toString(), installedAt: Date.now() },
        { id: 'id' });
      should(handler).not.be.called();
      should(kuzzle.log.info).not.be.called();
    });
  });

  describe('#import', () => {
    let toImport;
    let toSupport;

    beforeEach(() => {
      toImport = {
        mappings: { something: 'here' },
        onExistingUsers: 'skip',
        profiles: { something: 'here' },
        roles: { something: 'here' },
        userMappings: { something: 'here' },
        user: { something: 'here' },
      };
      toSupport = {
        mappings: { something: 'here' },
        fixtures: { something: 'here' },
        securities: {
          profiles: { something: 'here' },
          roles: { something: 'here' },
          user: { something: 'here' }
        }
      };

      kuzzle.internalIndex.updateMapping = sinon.stub().resolves();
      kuzzle.internalIndex.refreshCollection = sinon.stub().resolves();
    });

    it('should load correctly toImport mappings and permissions', async () => {
      kuzzle._waitForImportToFinish = sinon.stub().resolves();
      await kuzzle.loadInitialState(toImport, {});

      should(kuzzle.ask).be.calledWith(
        'core:cache:internal:get',
        'backend:init:import:mappings');

      should(kuzzle.ask).be.calledWith(
        'core:cache:internal:get',
        'backend:init:import:permissions');

      const mappingsPayload = {
        toImport: {
          mappings: toImport.mappings,
        },
        toSupport: {
          mappings: toSupport.mappings,
        }
      };

      should(kuzzle.ask).be.calledWith(
        'core:cache:internal:store',
        sha256(stringify(mappingsPayload)));

      const permissionsPayload = {
        toImport: {
          profiles: toImport.profiles,
          roles: toImport.roles,
          users: toImport.users,
        },
        toSupport: {
          securities: toSupport.securities,
        }
      };

      should(kuzzle.ask).be.calledWith(
        'core:cache:internal:store',
        sha256(stringify(permissionsPayload)));

      should(kuzzle.internalIndex.updateMapping).be.calledWith('users', toImport.userMappings);
      should(kuzzle.internalIndex.refreshCollection).be.calledWith('users');
      should(kuzzle.ask).calledWith('core:storage:public:mappings:import', toImport.mappings,
        {
          indexCacheOnly: false,
          propagate: false,
          refresh: true,
        });
      should(kuzzle.ask).calledWith('core:security:load',
        {
          profiles: toImport.profiles,
          roles: toImport.roles,
          users: toImport.users,
        },
        {
          onExistingUsers: toImport.onExistingUsers,
          onExistingUsersWarning: true,
          refresh: 'wait_for',
        });
    });

    it('should load correctly toSupport mappings, fixtures and securities', async () => {
      kuzzle._waitForImportToFinish = sinon.stub().resolves();
      await kuzzle.loadInitialState({}, toSupport);

      should(kuzzle.ask).be.calledWith(
        'core:cache:internal:get',
        'backend:init:import:mappings');

      should(kuzzle.ask).be.calledWith(
        'core:cache:internal:get',
        'backend:init:import:permissions');

      should(kuzzle.ask).be.calledWith(
        'core:cache:internal:get',
        'backend:init:import:fixtures');

      should(kuzzle.ask).be.calledWithMatch(
        'core:cache:internal:store');

      const mappingsPayload = {
        toImport: {
          mappings: toImport.mappings,
        },
        toSupport: {
          mappings: toSupport.mappings,
        }
      };

      should(kuzzle.ask).be.calledWith(
        'core:cache:internal:store',
        `${BACKEND_IMPORT_KEY}:mappings`,
        sha256(stringify(mappingsPayload)));

      const permissionsPayload = {
        toImport: {
          profiles: toImport.profiles,
          roles: toImport.roles,
          users: toImport.users,
        },
        toSupport: {
          securities: toSupport.securities,
        }
      };

      should(kuzzle.ask).be.calledWith(
        'core:cache:internal:store',
        `${BACKEND_IMPORT_KEY}:permissions`,
        sha256(stringify(permissionsPayload)));

      const fixturesPayload = {
        toSupport: {
          securities: toSupport.securities,
        }
      };

      should(kuzzle.ask).be.calledWith(
        'core:cache:internal:store',
        `${BACKEND_IMPORT_KEY}:fixtures`,
        sha256(stringify(fixturesPayload)));

      should(kuzzle.ask).calledWith('core:storage:public:mappings:import', toSupport.mappings, {
        indexCacheOnly: false,
        propagate: false,
        rawMappings: true,
        refresh: true,
      });
      should(kuzzle.ask).calledWith('core:storage:public:document:import', toSupport.fixtures);
      should(kuzzle.ask).calledWith('core:security:load', toSupport.securities, {
        force: true,
        refresh: 'wait_for'
      });
    });

    it('should prevent mappings to be loaded from import and support simultaneously', () => {
      return should(kuzzle.loadInitialState(toImport, { mappings: { something: 'here' } }))
        .be.rejectedWith({ id: 'plugin.runtime.incompatible' });
    });

    it('should prevent permissions to be loaded from import and support simultaneously', () => {
      return should(
        kuzzle.loadInitialState(
          { profiles: { something: 'here' } },
          { securities: { roles: { something: 'here' } } }))
        .be.rejectedWith({ id: 'plugin.runtime.incompatible' });
    });
  });
});
<|endoftext|>


<commit_before>'use strict';

/* global browserTrigger */

splitMoveTests('touch', 'touchstart', 'touchmove', 'touchend');
splitMoveTests('mouse', 'mousedown', 'mousemove', 'mouseup');

// Wrapper to abstract over using touch events or mouse events.
function splitMoveTests(description, startEvent, moveEvent, endEvent) {
  return describe('uiLayout with ' + description + ' events', function () {

    // declare these up here to be global to all tests
    var scope, $compile, element;

    /**
     * UTILS
     */

    function appendTemplate(tpl) {
      element = angular.element(tpl);
      angular.element(document.body).append(element);
      $compile(element)(scope);
      scope.$digest();
    }

    /**
     * TESTS
     */

    beforeEach(module('ui.layout'));

    // inject in angular constructs. Injector knows about leading/trailing underscores and does the right thing
    // otherwise, you would need to inject these into each test
    beforeEach(inject(function (_$rootScope_, _$compile_) {
      scope = _$rootScope_.$new();
      $compile = _$compile_;
    }));

    // jasmine matcher for expecting an element to have a css class
    // https://github.com/angular/angular.js/blob/master/test/matchers.js
    beforeEach(function () {
      this.addMatchers({
        toHaveClass: function (cls) {
          this.message = function () {
            return 'Expected "' + angular.mock.dump(this.actual) + '" to have class "' + cls + '".';
          };

          return this.actual.hasClass(cls);
        }
      });
    });

    describe('require', function () {
      it('requestAnimationFrame', function () {
        expect(window.requestAnimationFrame).toBeDefined();
      });
      it('cancelAnimationFrame', function () {
        expect(window.cancelAnimationFrame).toBeDefined();
      });
    });

    // Spy on the requestAnimationFrame to directly trigger it
    beforeEach(function () {
      spyOn(window, 'requestAnimationFrame').andCallFake(function (fct) {
        fct();
      });
    });

    afterEach(function () {
      if (element) element.remove();
    });

    describe('the slider', function () {

      var element_bb, $splitbar, splitbar_bb, splitbar_left_pos;

      beforeEach(function () {
        appendTemplate('

');

        element_bb = element[0].getBoundingClientRect();
        $splitbar = _jQuery(element[0]).find('.ui-splitbar');
        splitbar_bb = $splitbar[0].getBoundingClientRect();

        splitbar_left_pos = Math.ceil(splitbar_bb.left);
      });

      it('should do nothing when clicking on it', function () {

        // Click on the splitbar left
        browserTrigger($splitbar, startEvent, { x: splitbar_left_pos });
        browserTrigger($splitbar, endEvent);
        splitbar_bb = $splitbar[0].getBoundingClientRect();

        expect(window.requestAnimationFrame).not.toHaveBeenCalled();
        expect(Math.ceil(splitbar_bb.left)).toEqual(splitbar_left_pos);

      });

      it('should follow the ' + description, function () {
        browserTrigger($splitbar, startEvent, { y: splitbar_left_pos });

        browserTrigger($splitbar, moveEvent, { y: element_bb.height / 4});
        expect(window.requestAnimationFrame).toHaveBeenCalled();

        splitbar_bb = $splitbar[0].getBoundingClientRect();
        expect(Math.ceil(parseFloat($splitbar[0].style.top))).toEqual(25);

        browserTrigger(document.body, endEvent);
      });

    });

  });
}
<commit_msg>feat(test): test not moving before startevent or after endevent<commit_after>'use strict';

/* global browserTrigger */

splitMoveTests('touch', 'touchstart', 'touchmove', 'touchend');
splitMoveTests('mouse', 'mousedown', 'mousemove', 'mouseup');

// Wrapper to abstract over using touch events or mouse events.
function splitMoveTests(description, startEvent, moveEvent, endEvent) {
  return describe('uiLayout with ' + description + ' events', function () {

    // declare these up here to be global to all tests
    var scope, $compile, element;

    /**
     * UTILS
     */

    function appendTemplate(tpl) {
      element = angular.element(tpl);
      angular.element(document.body).append(element);
      $compile(element)(scope);
      scope.$digest();
    }

    /**
     * TESTS
     */

    beforeEach(module('ui.layout'));

    // inject in angular constructs. Injector knows about leading/trailing underscores and does the right thing
    // otherwise, you would need to inject these into each test
    beforeEach(inject(function (_$rootScope_, _$compile_) {
      scope = _$rootScope_.$new();
      $compile = _$compile_;
    }));

    // jasmine matcher for expecting an element to have a css class
    // https://github.com/angular/angular.js/blob/master/test/matchers.js
    beforeEach(function () {
      this.addMatchers({
        toHaveClass: function (cls) {
          this.message = function () {
            return 'Expected "' + angular.mock.dump(this.actual) + '" to have class "' + cls + '".';
          };

          return this.actual.hasClass(cls);
        }
      });
    });

    describe('require', function () {
      it('requestAnimationFrame', function () {
        expect(window.requestAnimationFrame).toBeDefined();
      });
      it('cancelAnimationFrame', function () {
        expect(window.cancelAnimationFrame).toBeDefined();
      });
    });

    // Spy on the requestAnimationFrame to directly trigger it
    beforeEach(function () {
      spyOn(window, 'requestAnimationFrame').andCallFake(function (fct) {
        fct();
      });
    });

    afterEach(function () {
      if (element) element.remove();
    });

    describe('the slider', function () {

      var element_bb, $splitbar, splitbar_bb, splitbar_left_pos;

      beforeEach(function () {
        appendTemplate('

');

        element_bb = element[0].getBoundingClientRect();
        $splitbar = _jQuery(element[0]).find('.ui-splitbar');
        splitbar_bb = $splitbar[0].getBoundingClientRect();

        splitbar_left_pos = Math.ceil(splitbar_bb.left);
      });

      it('should do nothing when clicking on it', function () {

        // Click on the splitbar left
        browserTrigger($splitbar, startEvent, { x: splitbar_left_pos });
        browserTrigger($splitbar, endEvent);
        splitbar_bb = $splitbar[0].getBoundingClientRect();

        expect(window.requestAnimationFrame).not.toHaveBeenCalled();
        expect(Math.ceil(splitbar_bb.left)).toEqual(splitbar_left_pos);

      });

      it('should follow the ' + description, function () {
        browserTrigger($splitbar, startEvent, { y: splitbar_left_pos });

        browserTrigger($splitbar, moveEvent, { y: element_bb.height / 4});
        expect(window.requestAnimationFrame).toHaveBeenCalled();

        splitbar_bb = $splitbar[0].getBoundingClientRect();
        expect(Math.ceil(parseFloat($splitbar[0].style.top))).toEqual(25);

        browserTrigger(document.body, endEvent);
      });

      it('should not follow the ' + description + ' before ' + startEvent, function () {
        expect(Math.ceil(parseFloat($splitbar[0].style.top))).toEqual(50); // Obvious...

        // Move without clicking on it
        browserTrigger($splitbar, moveEvent, { y: Math.random() * element_bb.width });
        browserTrigger($splitbar, endEvent);
        expect(window.requestAnimationFrame).not.toHaveBeenCalled();

        expect(Math.ceil(parseFloat($splitbar[0].style.top))).toEqual(50);
      });

      it('should not follow the ' + description + ' after ' + startEvent, function () {
        browserTrigger($splitbar, startEvent, { y: splitbar_left_pos });
        browserTrigger($splitbar, moveEvent, { y: element_bb.height / 4});
        browserTrigger($splitbar, endEvent);
        expect(window.requestAnimationFrame).toHaveBeenCalled();

        // Move after the end event
        browserTrigger($splitbar, moveEvent, { y: Math.random() * element_bb.width });
        browserTrigger($splitbar, endEvent);

        expect(window.requestAnimationFrame.callCount).toEqual(1);
        expect(Math.ceil(parseFloat($splitbar[0].style.top))).toEqual(25);
      });

    });

  });
}
<|endoftext|>


<commit_before>import should from 'should/as-function';
import Syncano from '../../src/syncano';

describe('Syncano', function() {
  let baseObject = null;
  const testKey = '123';
  const testUrl = 'http://api.syncano.rocks'
  const testInstance = 'my-instance';

  beforeEach(function() {
    baseObject = Syncano();
  });

  describe('#init()', function() {

    it('should have model factories automatically injected as properties', function() {
      should(baseObject).have.property('Instance').which.is.Function();
      should(baseObject).have.property('Class').which.is.Function();
      should(baseObject).have.property('Channel').which.is.Function();
      should(baseObject).have.property('DataObject').which.is.Function();
      should(baseObject).have.property('User').which.is.Function();
      should(baseObject).have.property('Group').which.is.Function();
      should(baseObject).have.property('Admin').which.is.Function();
      should(baseObject).have.property('ApiKey').which.is.Function();
      should(baseObject).have.property('InstanceInvitation').which.is.Function();
      should(baseObject).have.property('Invitation').which.is.Function();
      should(baseObject).have.property('Script').which.is.Function();
      should(baseObject).have.property('Schedule').which.is.Function();
      should(baseObject).have.property('Trigger').which.is.Function();
      should(baseObject).have.property('ScriptEndpoint').which.is.Function();
      should(baseObject).have.property('DataEndpoint').which.is.Function();
      should(baseObject).have.property('ScriptTrace').which.is.Function();
      should(baseObject).have.property('ScheduleTrace').which.is.Function();
      should(baseObject).have.property('TriggerTrace').which.is.Function();
      should(baseObject).have.property('ScriptEndpointTrace').which.is.Function();
      should(baseObject).have.property('GCMDevice').which.is.Function();
      should(baseObject).have.property('APNSDevice').which.is.Function();
      should(baseObject).have.property('GCMMessage').which.is.Function();
      should(baseObject).have.property('APNSMessage').which.is.Function();
    });

    it('shoud have baseUrl and accountKey properties', function() {
      should(baseObject).have.property('baseUrl').which.is.String();
      should(baseObject).have.property('accountKey').which.is.Null();
      should(baseObject).have.property('userKey').which.is.Null();
      should(baseObject).have.property('socialToken').which.is.Null();
      should(baseObject).have.property('defaults').which.is.Object();
    })

  });

  describe('#setAccountKey()', function() {

    it('should allow to set accountKey', function() {
      should(baseObject).have.property('setAccountKey').which.is.Function();

      baseObject.setAccountKey(testKey);

      should(baseObject.accountKey).is.equal(testKey);
    });

  });

  describe('#getAccountKey()', function() {

    it('should allow to get account key', function() {
      should(baseObject).have.property('getAccountKey').which.is.Function();

      baseObject.setAccountKey(testKey);

      should(baseObject.getAccountKey()).is.equal(testKey);

    });

  });

  describe('#setBaseUrl()', function() {

    it('should allow to set base url', function() {
      should(baseObject).have.property('setBaseUrl').which.is.Function();

      baseObject.setBaseUrl(testUrl);

      should(baseObject.baseUrl).is.equal(testUrl);
    });

  });

  describe('#getBaseUrl()', function() {

    it('should allow to get base url', function() {
      should(baseObject).have.property('getBaseUrl').which.is.Function();

      baseObject.setBaseUrl(testUrl);

      should(baseObject.getBaseUrl()).is.equal(testUrl);

    });

  });

  describe('#setInstanceName()', function() {

    it('should allow to set instance name', function() {
      should(baseObject).have.property('setInstanceName').which.is.Function();

      baseObject.setInstanceName(testInstance);

      should(baseObject.defaults.instanceName).is.equal(testInstance);
    });

  });

  describe('#getInstanceName()', function() {

    it('should allow to get instance name', function() {
      should(baseObject).have.property('getInstanceName').which.is.Function();

      baseObject.setInstanceName(testInstance);

      should(baseObject.getInstanceName()).is.equal(testInstance);
    });

  });

  describe('#setUserKey()', function() {

    it('should allow to set userKey', function() {
      should(baseObject).have.property('setUserKey').which.is.Function();

      baseObject.setUserKey(testKey);

      should(baseObject.userKey).is.equal(testKey);
    });

  });

  describe('#getUserKey()', function() {

    it('should allow to get user key', function() {
      should(baseObject).have.property('getUserKey').which.is.Function();

      baseObject.setUserKey(testKey);

      should(baseObject.getUserKey()).is.equal(testKey);

    });

  });

  describe('#setApiKey()', function() {

    it('should allow to set apiKey', function() {
      should(baseObject).have.property('setApiKey').which.is.Function();

      baseObject.setApiKey(testKey);

      should(baseObject.apiKey).is.equal(testKey);
    });

  });

  describe('#getApiKey()', function() {

    it('should allow to get user key', function() {
      should(baseObject).have.property('getApiKey').which.is.Function();

      baseObject.setApiKey(testKey);

      should(baseObject.getApiKey()).is.equal(testKey);

    });

  });

  describe('#setSocialToken()', function() {

    it('should allow to set socialToken', function() {
      should(baseObject).have.property('setSocialToken').which.is.Function();

      baseObject.setSocialToken(testKey);

      should(baseObject.socialToken).is.equal(testKey);
    });

  });

  describe('#getSocialToken()', function() {

    it('should allow to get social token', function() {
      should(baseObject).have.property('getSocialToken').which.is.Function();

      baseObject.setSocialToken(testKey);

      should(baseObject.getSocialToken()).is.equal(testKey);

    });

  });

});
<commit_msg>[LIB-621] Unit tests<commit_after>import should from 'should/as-function';
import Syncano from '../../src/syncano';

describe('Syncano', function() {
  let baseObject = null;
  const testKey = '123';
  const testUrl = 'http://api.syncano.rocks'
  const testInstance = 'my-instance';

  beforeEach(function() {
    baseObject = Syncano();
  });

  describe('#init()', function() {

    it('should have model factories automatically injected as properties', function() {
      should(baseObject).have.property('Instance').which.is.Function();
      should(baseObject).have.property('Class').which.is.Function();
      should(baseObject).have.property('Channel').which.is.Function();
      should(baseObject).have.property('DataObject').which.is.Function();
      should(baseObject).have.property('User').which.is.Function();
      should(baseObject).have.property('Group').which.is.Function();
      should(baseObject).have.property('Admin').which.is.Function();
      should(baseObject).have.property('ApiKey').which.is.Function();
      should(baseObject).have.property('InstanceInvitation').which.is.Function();
      should(baseObject).have.property('Invitation').which.is.Function();
      should(baseObject).have.property('Script').which.is.Function();
      should(baseObject).have.property('Schedule').which.is.Function();
      should(baseObject).have.property('Trigger').which.is.Function();
      should(baseObject).have.property('ScriptEndpoint').which.is.Function();
      should(baseObject).have.property('DataEndpoint').which.is.Function();
      should(baseObject).have.property('ScriptTrace').which.is.Function();
      should(baseObject).have.property('ScheduleTrace').which.is.Function();
      should(baseObject).have.property('TriggerTrace').which.is.Function();
      should(baseObject).have.property('ScriptEndpointTrace').which.is.Function();
      should(baseObject).have.property('GCMDevice').which.is.Function();
      should(baseObject).have.property('APNSDevice').which.is.Function();
      should(baseObject).have.property('GCMMessage').which.is.Function();
      should(baseObject).have.property('APNSMessage').which.is.Function();
      should(baseObject).have.property('Account').which.is.Object();
      should(baseObject).have.property('Monitor').which.is.Object();
    });

    it('shoud have baseUrl and accountKey properties', function() {
      should(baseObject).have.property('baseUrl').which.is.String();
      should(baseObject).have.property('accountKey').which.is.Null();
      should(baseObject).have.property('userKey').which.is.Null();
      should(baseObject).have.property('socialToken').which.is.Null();
      should(baseObject).have.property('defaults').which.is.Object();
    })
  });

  describe('#Account', function() {
    it('should have correct methods', function() {
      should(baseObject.Account).have.property('activate').which.is.Function();
      should(baseObject.Account).have.property('register').which.is.Function();
      should(baseObject.Account).have.property('login').which.is.Function();
      should(baseObject.Account).have.property('update').which.is.Function();
    });
  });

  describe('#Monitor', function() {
    it('should have correct methods', function() {
      should(baseObject.Monitor).have.property('startMonitoring').which.is.Function();
      should(baseObject.Monitor).have.property('stopMonitoring').which.is.Function();
    });
  });

  describe('#setAccountKey()', function() {

    it('should allow to set accountKey', function() {
      should(baseObject).have.property('setAccountKey').which.is.Function();

      baseObject.setAccountKey(testKey);

      should(baseObject.accountKey).is.equal(testKey);
    });

  });

  describe('#getAccountKey()', function() {

    it('should allow to get account key', function() {
      should(baseObject).have.property('getAccountKey').which.is.Function();

      baseObject.setAccountKey(testKey);

      should(baseObject.getAccountKey()).is.equal(testKey);

    });

  });

  describe('#setBaseUrl()', function() {

    it('should allow to set base url', function() {
      should(baseObject).have.property('setBaseUrl').which.is.Function();

      baseObject.setBaseUrl(testUrl);

      should(baseObject.baseUrl).is.equal(testUrl);
    });

  });

  describe('#getBaseUrl()', function() {

    it('should allow to get base url', function() {
      should(baseObject).have.property('getBaseUrl').which.is.Function();

      baseObject.setBaseUrl(testUrl);

      should(baseObject.getBaseUrl()).is.equal(testUrl);

    });

  });

  describe('#setInstanceName()', function() {

    it('should allow to set instance name', function() {
      should(baseObject).have.property('setInstanceName').which.is.Function();

      baseObject.setInstanceName(testInstance);

      should(baseObject.defaults.instanceName).is.equal(testInstance);
    });

  });

  describe('#getInstanceName()', function() {

    it('should allow to get instance name', function() {
      should(baseObject).have.property('getInstanceName').which.is.Function();

      baseObject.setInstanceName(testInstance);

      should(baseObject.getInstanceName()).is.equal(testInstance);
    });

  });

  describe('#setUserKey()', function() {

    it('should allow to set userKey', function() {
      should(baseObject).have.property('setUserKey').which.is.Function();

      baseObject.setUserKey(testKey);

      should(baseObject.userKey).is.equal(testKey);
    });

  });

  describe('#getUserKey()', function() {

    it('should allow to get user key', function() {
      should(baseObject).have.property('getUserKey').which.is.Function();

      baseObject.setUserKey(testKey);

      should(baseObject.getUserKey()).is.equal(testKey);

    });

  });

  describe('#setApiKey()', function() {

    it('should allow to set apiKey', function() {
      should(baseObject).have.property('setApiKey').which.is.Function();

      baseObject.setApiKey(testKey);

      should(baseObject.apiKey).is.equal(testKey);
    });

  });

  describe('#getApiKey()', function() {

    it('should allow to get user key', function() {
      should(baseObject).have.property('getApiKey').which.is.Function();

      baseObject.setApiKey(testKey);

      should(baseObject.getApiKey()).is.equal(testKey);

    });

  });

  describe('#setSocialToken()', function() {

    it('should allow to set socialToken', function() {
      should(baseObject).have.property('setSocialToken').which.is.Function();

      baseObject.setSocialToken(testKey);

      should(baseObject.socialToken).is.equal(testKey);
    });

  });

  describe('#getSocialToken()', function() {

    it('should allow to get social token', function() {
      should(baseObject).have.property('getSocialToken').which.is.Function();

      baseObject.setSocialToken(testKey);

      should(baseObject.getSocialToken()).is.equal(testKey);

    });

  });

});
<|endoftext|>


<commit_before>/**
 * @fileOverview Stub a Sequelize model.
 */
var exec = require('child_process').exec;

var Sequelize = require('sequelize');

var seq = module.exports = {};

var _init = false;

/**
 * Define the seq schema
 * @type {Object}
 */
seq.Schema = {
  name: {type: Sequelize.STRING, allowNull: false},
  _isActive: {type: Sequelize.BOOLEAN, allowNull: false, defaultValue: true},
};

/**
 * Define the seq schema relation
 * @type {Object}
 */
seq.SchemaRel = {
  darname: {type: Sequelize.STRING, allowNull: false},
};

/** @type {?Sequelize} The main Sequelize instance */
seq.instance = null;

/** @type {?Sequelize.Model} The sequelize model */
seq.Model = null;

/** @type {?Sequelize.Model} The sequelize model related */
seq.ModelRel = null;

/**
 * Create a connection with Postgres and init models.
 *
 * @param {Function} done callback.
 * @private
 */
seq.connect = function(done) {
  if (_init) {return done();}
  _init = true;

  var createUserCmd = 'createuser postgres --superuser --createdb';
  var createDbCmd = 'createdb -O postgres entity_test';
  exec(createUserCmd, {}, function(err) {
    if (err && err.message.indexOf('already exists') === -1) { return done(err);}
    exec(createDbCmd, {}, function(err) {
      if (err && err.message.indexOf('already exists') === -1) { return done(err);}

      seq.instance = new Sequelize(
        'entity_test',
        'postgres',
        '',
        {
          host: '127.0.0.1',
          port: '5432',
          dialect: 'postgres',
          logging: false,
        }
      );

      seq.Model = seq.instance.define('stubModel', seq.Schema);
      seq.ModelRel = seq.instance.define('stubModelRel', seq.SchemaRel);
      seq.ModelRel.hasMany(seq.Model);

      seq.syncDb(done);
    });
  });
};

/**
 * Nuke the stub database, force recreation.
 *
 * @param  {Function} done callback
 */
seq.syncDb = function(done) {
  seq.instance.sync({force: true})
    .success(done.bind(null, null))
    .error(done);
};
<commit_msg>restore name of nukedb on seq stub<commit_after>/**
 * @fileOverview Stub a Sequelize model.
 */
var exec = require('child_process').exec;

var Sequelize = require('sequelize');

var seq = module.exports = {};

var _init = false;

/**
 * Define the seq schema
 * @type {Object}
 */
seq.Schema = {
  name: {type: Sequelize.STRING, allowNull: false},
  _isActive: {type: Sequelize.BOOLEAN, allowNull: false, defaultValue: true},
};

/**
 * Define the seq schema relation
 * @type {Object}
 */
seq.SchemaRel = {
  darname: {type: Sequelize.STRING, allowNull: false},
};

/** @type {?Sequelize} The main Sequelize instance */
seq.instance = null;

/** @type {?Sequelize.Model} The sequelize model */
seq.Model = null;

/** @type {?Sequelize.Model} The sequelize model related */
seq.ModelRel = null;

/**
 * Create a connection with Postgres and init models.
 *
 * @param {Function} done callback.
 * @private
 */
seq.connect = function(done) {
  if (_init) {return done();}
  _init = true;

  var createUserCmd = 'createuser postgres --superuser --createdb';
  var createDbCmd = 'createdb -O postgres entity_test';
  exec(createUserCmd, {}, function(err) {
    if (err && err.message.indexOf('already exists') === -1) { return done(err);}
    exec(createDbCmd, {}, function(err) {
      if (err && err.message.indexOf('already exists') === -1) { return done(err);}

      seq.instance = new Sequelize(
        'entity_test',
        'postgres',
        '',
        {
          host: '127.0.0.1',
          port: '5432',
          dialect: 'postgres',
          logging: false,
        }
      );

      seq.Model = seq.instance.define('stubModel', seq.Schema);
      seq.ModelRel = seq.instance.define('stubModelRel', seq.SchemaRel);
      seq.ModelRel.hasMany(seq.Model);

      seq.nukedb(done);
    });
  });
};

/**
 * Nuke the stub database, force recreation.
 *
 * @param  {Function} done callback
 */
seq.nukedb = function(done) {
  seq.instance.sync({force: true})
    .success(done.bind(null, null))
    .error(done);
};
<|endoftext|>


<commit_before>/*
 * This file is part of the AlphaLemon CMS Application and it is distributed
 * under the GPL LICENSE Version 2.0. To use this application you must leave
 * intact this copyright notice.
 *
 * Copyright (c) AlphaLemon <webmaster@alphalemon.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * For extra documentation and help please visit http://www.alphalemon.com
 *
 * @license    GPL LICENSE Version 2.0
 *
 */

var isEditorOpened = false;

(function($){
    $.fn.ToggleBodyContents =function()
    {
        this.each(function()
        {
            $(this).click(function()
            {
                $('#slot_' + $(this).attr('ref')).animate({
                  height: 'toggle'
                }, 200);

                return false;
            });
        });

        return this;
    };

    $.fn.ShowBlockEditor =function()
    {
        this.each(function()
        {
            $(this).click(function()
            {
                $(this).OpenEditor();
            });
        });
    };

    $.fn.OpenEditor =function()
    {
        if(isEditorOpened)
        {
            return;
        }

        var editableData = $(this).metadata();
        var idBlock = editableData.id;
        var slotName = editableData.slotName;
        $.ajax({
            type: 'POST',
            url: frontController + 'backend/' + $('#al_available_languages').val() + '/al_showBlocksEditor',
            data: {'page' :  $('#al_pages_navigator option:selected').text(),
                   'language' : $('#al_languages_navigator option:selected').text(),
                   'idBlock' : idBlock,
                   'slotName' : slotName},
            beforeSend: function()
            {
                $('body').AddAjaxLoader();
            },
            success: function(response)
            {
                try
                {
                    $.parseJSON(response);
                    updateContentsJSon(response);
                }
                catch(e)
                {
                    showMediaLibrary(response);
                }

                $('body').data('idBlock', idBlock).data('slotName', slotName);
                isEditorOpened = true;
            },
            error: function(err)
            {
                $('#al_dialog').html(err.responseText);
                $('#al_dialog').dialog('open');
            },
            complete: function()
            {
                $('body').RemoveAjaxLoader();
            }
        });
    }

    $.fn.AddBlock =function(type)
    {
        this.each(function()
        {
            var data = $(this).metadata();
            var idBlock = data.id;
            var slotName = data.slotName;
            var contentType = (type == null) ? data.contentType : type;
            $.ajax({
                type: 'POST',
                url: frontController + 'backend/' + $('#al_available_languages').val() + '/addBlock',
                data: {'page' :  $('#al_pages_navigator option:selected').text(),
                       'language' : $('#al_languages_navigator option:selected').text(),
                       'idBlock' : idBlock,
                       'slotName' : slotName,
                       'contentType': contentType},
                beforeSend: function()
                {
                    $('body').AddAjaxLoader();
                },
                success: function(response)
                {
                    updateContentsJSon(response);
                },
                error: function(err)
                {
                    $('#al_dialog').html(err.responseText);
                    $('#al_dialog').dialog('open');
                },
                complete: function()
                {
                    $('body').RemoveAjaxLoader();
                }
            });

            return false;

        });
    };

    $.fn.EditBlock =function(key, value, options)
    {
        this.each(function()
        {
            value = (value == null) ? encodeURIComponent($(this).val()) : value;

            $.ajax({
                type: 'POST',
                url: frontController + 'backend/' + $('#al_available_languages').val() + '/editBlock',
                data: {'page'       :  $('#al_pages_navigator option:selected').text(),
                       'language'   : $('#al_languages_navigator option:selected').text(),
                       'idBlock'    : $('body').data('idBlock'),
                       'slotName'   : $('body').data("slotName"),
                       'key'        : key,
                       'value'      : value,
                       'options'    : options},
                beforeSend: function()
                {
                    $('body').AddAjaxLoader();
                },
                success: function(response)
                {
                    updateContentsJSon(response);
                },
                error: function(err)
                {
                    $('#al_dialog').html(err.responseText);
                    $('#al_dialog').dialog('open');
                },
                complete: function()
                {
                    $('body').RemoveAjaxLoader();
                }
            });

            return false;
        });
    };

    $.fn.ShowExternalFilesManager =function(key)
    {
        this.each(function()
        {
            $(this).click(function()
            {
                $.ajax({
                    type: 'POST',
                    url: frontController + 'backend/' + $('#al_available_languages').val() + '/showExternalFilesManager',
                    data: {'page' :  $('#al_pages_navigator option:selected').text(),
                           'language' : $('#al_languages_navigator option:selected').text(),
                           'key'      : key},
                    beforeSend: function()
                    {
                        $('body').AddAjaxLoader();
                    },
                    success: function(html)
                    {
                        showMediaLibrary(html);
                    },
                    error: function(err)
                    {
                        $('#al_dialog').html(err.responseText);
                        $('#al_dialog').dialog('open');
                    },
                    complete: function()
                    {
                        $('body').RemoveAjaxLoader();
                    }
                });

                return false;
            });
        });
    };

    $.fn.AddExternalFile =function(field, file)
    {
        this.each(function()
        {
            $.ajax({
                type: 'POST',
                url: frontController + 'backend/' + $('#al_available_languages').val() + '/addExternalFile',
                data: {'page' :  $('#al_pages_navigator option:selected').text(),
                       'language' : $('#al_languages_navigator option:selected').text(),
                       'idBlock' : $('body').data('idBlock'),
                       'slotName' : $('body').data("slotName"),
                       'field'       : field,
                       'file'     : file},
                beforeSend: function()
                {
                    $('body').AddAjaxLoader();
                },
                success: function(response)
                {
                    updateContentsJSon(response);
                },
                error: function(err)
                {
                    $('#al_dialog').html(err.responseText);
                    $('#al_dialog').dialog('open');
                },
                complete: function()
                {
                    $('body').RemoveAjaxLoader();
                }
            });

            return false;
        });
    };

    function showMediaLibrary(html)
    {
        if($('body').find("al_media_lib").length == 0)
        {
            $('

')
                    .css("display", "none")
                    .appendTo('body');
        }
        $('#al_media_lib').html(html);
    }

    $.fn.RemoveExternalFile =function(field, fileName)
    {
        this.each(function()
        {
            $(this).click(function()
            {
                $.ajax({
                    type: 'POST',
                    url: frontController + 'backend/' + $('#al_available_languages').val() + '/removeExternalFile',
                    data: {'page'     :  $('#al_pages_navigator option:selected').text(),
                           'language' : $('#al_languages_navigator option:selected').text(),
                           'idBlock'  : $('body').data('idBlock'),
                           'field'    : field,
                           'file'     : fileName},
                    beforeSend: function()
                    {
                        $('body').AddAjaxLoader();
                    },
                    success: function(response)
                    {
                        updateContentsJSon(response);
                    },
                    error: function(err)
                    {
                        $('#al_dialog').html(err.responseText);
                        $('#al_dialog').dialog('open');
                    },
                    complete: function()
                    {
                        $('body').RemoveAjaxLoader();
                    }
                });

                return false;
            });
        });
    };

    $.fn.Delete =function()
    {
        this.each(function()
        {
            $(this).click(function()
            {
                $(this).DeleteContent();

                return false;
            });
        });
    };

    $.fn.DeleteContent =function()
    {
        var editableData = $(this).metadata();
        var idBlock = editableData.id;
        var slotName = editableData.slotName;

        $.ajax({
            type: 'POST',
            url: frontController + 'backend/' + $('#al_available_languages').val() + '/deleteBlock',
            data: {'page' :  $('#al_pages_navigator option:selected').text(),
                   'language' : $('#al_languages_navigator option:selected').text(),
                   'slotName' : slotName,
                   'idBlock' : idBlock},
            beforeSend: function()
            {
                $('body').AddAjaxLoader();
            },
            success: function(response)
            {
                updateContentsJSon(response);
            },
            error: function(err)
            {
                $('#al_dialog').html(err.responseText);
                $('#al_dialog').dialog('open');
            },
            complete: function()
            {
                $('body').RemoveAjaxLoader();
            }
        });
    };

})($);

function updateContentsJSon(response)
{
    var slot;
    $(response).each(function(key, item)
    {
        switch(item.key)
        {
            case "message":
                $('#al_dialog').html(item.value);
                break;
            case "redraw-slot":
                slot = '.' + item.slotName;
                $(slot).html(item.value);
                $(slot).find('.al_editable').StartToEdit();
                break;
            case "add-block":
                slot = '.' + item.slotName;
                if(item.insertAfter == 'block_0')
                {
                    $(slot).empty().append(item.value);
                    $(slot).find('.al_editable').StartToEdit();
                }
                else
                {
                    $(item.value).insertAfter('#' + item.insertAfter).StartToEdit();
                }
                break;
            case "edit-block":
                $('#' + item.blockName).html(item.value).StartToEdit();
                break;
            case "remove-block":
                $('#' + item.blockName).remove();
                break;
            case "images-list":
                $('.al_images_list').html(item.value);
                break;
            case "editor":
                var openEditor = (item.openEditor != null) ? item.openEditor : true;
                if(openEditor) {
                    var dialogOptions = {
                        buttons:{},
                        close: function(event, ui)
                        {
                            isEditorOpened = false;
                            if(tinyMCE != null) $('#al_html_editor').RemoveTinyMCE();
                            $('#al_editor_dialog').dialog('destroy').remove();
                        }
                    };

                    InitDialog('al_editor_dialog', dialogOptions);
                    $('#al_editor_dialog').html(item.value);
                    $('#al_editor_dialog').dialog('open');
                }

                break;
            case "externalAssets":
                $('.al_' + item.section  + '_list').html(item.value);
                break;
            case "editorContents":
                $('.editor_contents').html(item.value);
                break;

        }
    });
}<commit_msg>fixed a bug when adding a new block<commit_after>/*
 * This file is part of the AlphaLemon CMS Application and it is distributed
 * under the GPL LICENSE Version 2.0. To use this application you must leave
 * intact this copyright notice.
 *
 * Copyright (c) AlphaLemon <webmaster@alphalemon.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 *
 * For extra documentation and help please visit http://www.alphalemon.com
 *
 * @license    GPL LICENSE Version 2.0
 *
 */

var isEditorOpened = false;

(function($){
    $.fn.ToggleBodyContents =function()
    {
        this.each(function()
        {
            $(this).click(function()
            {
                $('#slot_' + $(this).attr('ref')).animate({
                  height: 'toggle'
                }, 200);

                return false;
            });
        });

        return this;
    };

    $.fn.ShowBlockEditor =function()
    {
        this.each(function()
        {
            $(this).click(function()
            {
                $(this).OpenEditor();
            });
        });
    };

    $.fn.OpenEditor =function()
    {
        if(isEditorOpened)
        {
            return;
        }

        var editableData = $(this).metadata();
        var idBlock = editableData.id;
        var slotName = editableData.slotName;
        $.ajax({
            type: 'POST',
            url: frontController + 'backend/' + $('#al_available_languages').val() + '/al_showBlocksEditor',
            data: {'page' :  $('#al_pages_navigator option:selected').text(),
                   'language' : $('#al_languages_navigator option:selected').text(),
                   'idBlock' : idBlock,
                   'slotName' : slotName},
            beforeSend: function()
            {
                $('body').AddAjaxLoader();
            },
            success: function(response)
            {
                try
                {
                    $.parseJSON(response);
                    updateContentsJSon(response);
                }
                catch(e)
                {
                    showMediaLibrary(response);
                }

                $('body').data('idBlock', idBlock).data('slotName', slotName);
                isEditorOpened = true;
            },
            error: function(err)
            {
                $('#al_dialog').html(err.responseText);
                $('#al_dialog').dialog('open');
            },
            complete: function()
            {
                $('body').RemoveAjaxLoader();
            }
        });
    }

    $.fn.AddBlock =function(type)
    {
        this.each(function()
        {
            var data = $(this).metadata();
            var idBlock = data.id;
            var slotName = data.slotName;
            var contentType = (type == null) ? data.contentType : type;
            $.ajax({
                type: 'POST',
                url: frontController + 'backend/' + $('#al_available_languages').val() + '/addBlock',
                data: {'page' :  $('#al_pages_navigator option:selected').val(),
                       'language' : $('#al_languages_navigator option:selected').val(),
                       'idBlock' : idBlock,
                       'slotName' : slotName,
                       'contentType': contentType},
                beforeSend: function()
                {
                    $('body').AddAjaxLoader();
                },
                success: function(response)
                {
                    updateContentsJSon(response);
                },
                error: function(err)
                {
                    $('#al_dialog').html(err.responseText);
                    $('#al_dialog').dialog('open');
                },
                complete: function()
                {
                    $('body').RemoveAjaxLoader();
                }
            });

            return false;

        });
    };

    $.fn.EditBlock =function(key, value, options)
    {
        this.each(function()
        {
            value = (value == null) ? encodeURIComponent($(this).val()) : value;

            $.ajax({
                type: 'POST',
                url: frontController + 'backend/' + $('#al_available_languages').val() + '/editBlock',
                data: {'page'       :  $('#al_pages_navigator option:selected').text(),
                       'language'   : $('#al_languages_navigator option:selected').text(),
                       'idBlock'    : $('body').data('idBlock'),
                       'slotName'   : $('body').data("slotName"),
                       'key'        : key,
                       'value'      : value,
                       'options'    : options},
                beforeSend: function()
                {
                    $('body').AddAjaxLoader();
                },
                success: function(response)
                {
                    updateContentsJSon(response);
                },
                error: function(err)
                {
                    $('#al_dialog').html(err.responseText);
                    $('#al_dialog').dialog('open');
                },
                complete: function()
                {
                    $('body').RemoveAjaxLoader();
                }
            });

            return false;
        });
    };

    $.fn.ShowExternalFilesManager =function(key)
    {
        this.each(function()
        {
            $(this).click(function()
            {
                $.ajax({
                    type: 'POST',
                    url: frontController + 'backend/' + $('#al_available_languages').val() + '/showExternalFilesManager',
                    data: {'page' :  $('#al_pages_navigator option:selected').text(),
                           'language' : $('#al_languages_navigator option:selected').text(),
                           'key'      : key},
                    beforeSend: function()
                    {
                        $('body').AddAjaxLoader();
                    },
                    success: function(html)
                    {
                        showMediaLibrary(html);
                    },
                    error: function(err)
                    {
                        $('#al_dialog').html(err.responseText);
                        $('#al_dialog').dialog('open');
                    },
                    complete: function()
                    {
                        $('body').RemoveAjaxLoader();
                    }
                });

                return false;
            });
        });
    };

    $.fn.AddExternalFile =function(field, file)
    {
        this.each(function()
        {
            $.ajax({
                type: 'POST',
                url: frontController + 'backend/' + $('#al_available_languages').val() + '/addExternalFile',
                data: {'page' :  $('#al_pages_navigator option:selected').text(),
                       'language' : $('#al_languages_navigator option:selected').text(),
                       'idBlock' : $('body').data('idBlock'),
                       'slotName' : $('body').data("slotName"),
                       'field'       : field,
                       'file'     : file},
                beforeSend: function()
                {
                    $('body').AddAjaxLoader();
                },
                success: function(response)
                {
                    updateContentsJSon(response);
                },
                error: function(err)
                {
                    $('#al_dialog').html(err.responseText);
                    $('#al_dialog').dialog('open');
                },
                complete: function()
                {
                    $('body').RemoveAjaxLoader();
                }
            });

            return false;
        });
    };

    function showMediaLibrary(html)
    {
        if($('body').find("al_media_lib").length == 0)
        {
            $('

')
                    .css("display", "none")
                    .appendTo('body');
        }
        $('#al_media_lib').html(html);
    }

    $.fn.RemoveExternalFile =function(field, fileName)
    {
        this.each(function()
        {
            $(this).click(function()
            {
                $.ajax({
                    type: 'POST',
                    url: frontController + 'backend/' + $('#al_available_languages').val() + '/removeExternalFile',
                    data: {'page'     :  $('#al_pages_navigator option:selected').text(),
                           'language' : $('#al_languages_navigator option:selected').text(),
                           'idBlock'  : $('body').data('idBlock'),
                           'field'    : field,
                           'file'     : fileName},
                    beforeSend: function()
                    {
                        $('body').AddAjaxLoader();
                    },
                    success: function(response)
                    {
                        updateContentsJSon(response);
                    },
                    error: function(err)
                    {
                        $('#al_dialog').html(err.responseText);
                        $('#al_dialog').dialog('open');
                    },
                    complete: function()
                    {
                        $('body').RemoveAjaxLoader();
                    }
                });

                return false;
            });
        });
    };

    $.fn.Delete =function()
    {
        this.each(function()
        {
            $(this).click(function()
            {
                $(this).DeleteContent();

                return false;
            });
        });
    };

    $.fn.DeleteContent =function()
    {
        var editableData = $(this).metadata();
        var idBlock = editableData.id;
        var slotName = editableData.slotName;

        $.ajax({
            type: 'POST',
            url: frontController + 'backend/' + $('#al_available_languages').val() + '/deleteBlock',
            data: {'page' :  $('#al_pages_navigator option:selected').text(),
                   'language' : $('#al_languages_navigator option:selected').text(),
                   'slotName' : slotName,
                   'idBlock' : idBlock},
            beforeSend: function()
            {
                $('body').AddAjaxLoader();
            },
            success: function(response)
            {
                updateContentsJSon(response);
            },
            error: function(err)
            {
                $('#al_dialog').html(err.responseText);
                $('#al_dialog').dialog('open');
            },
            complete: function()
            {
                $('body').RemoveAjaxLoader();
            }
        });
    };

})($);

function updateContentsJSon(response)
{
    var slot;
    $(response).each(function(key, item)
    {
        switch(item.key)
        {
            case "message":
                $('#al_dialog').html(item.value);
                break;
            case "redraw-slot":
                slot = '.' + item.slotName;
                $(slot).html(item.value);
                $(slot).find('.al_editable').StartToEdit();
                break;
            case "add-block":
                slot = '.' + item.slotName;
                if(item.insertAfter == 'block_0')
                {
                    $(slot).empty().append(item.value);
                    $(slot).find('.al_editable').StartToEdit();
                }
                else
                {
                    $(item.value).insertAfter('#' + item.insertAfter).StartToEdit();
                }
                break;
            case "edit-block":
                $('#' + item.blockName).html(item.value).StartToEdit();
                break;
            case "remove-block":
                $('#' + item.blockName).remove();
                break;
            case "images-list":
                $('.al_images_list').html(item.value);
                break;
            case "editor":
                var openEditor = (item.openEditor != null) ? item.openEditor : true;
                if(openEditor) {
                    var dialogOptions = {
                        buttons:{},
                        close: function(event, ui)
                        {
                            isEditorOpened = false;
                            if(tinyMCE != null) $('#al_html_editor').RemoveTinyMCE();
                            $('#al_editor_dialog').dialog('destroy').remove();
                        }
                    };

                    InitDialog('al_editor_dialog', dialogOptions);
                    $('#al_editor_dialog').html(item.value);
                    $('#al_editor_dialog').dialog('open');
                }

                break;
            case "externalAssets":
                $('.al_' + item.section  + '_list').html(item.value);
                break;
            case "editorContents":
                $('.editor_contents').html(item.value);
                break;

        }
    });
}<|endoftext|>