<commit_before>var Q = require( 'q' )
  , spawn = require( 'child_process' ).spawn
  , path  = require( 'path' )
  , fs    = require( 'fs' )
  , ncp   = require('ncp').ncp;

//install clever-orm module to test project
function installORM () {
    var defered = Q.defer()
      , proc = spawn ( 'clever', [ 'install', 'clever-orm' ], { cwd: path.resolve( path.join( __dirname, '..' ) ) } );

    console.log( 'step #1 - install clever-orm module - begin\n' );

    proc.stdout.on('data', function (data) {
        var str = data.toString()
          , objs = [
                { reg: /Database username/ , write: 'travis\n' },
                { reg: /Database password/ , write: '\n' },
                { reg: /Database name/     , write: 'test_db\n' },
                { reg: /Database dialect/  , write: '\n' },
                { reg: /Database port/     , write: '3306\n' },
                { reg: /Database host/     , write: '127.0.0.1\n' },
            ];

        if ( str.match( /ing/ ) !== null ) {
            console.log( str )
        }

        objs.forEach ( function ( obj ) {
            if ( str.match( obj.reg ) !== null ) {
                proc.stdin.write( obj.write );
            }
        });
    });

    proc.stderr.on('data', function (data) {
        console.log( 'Error in step #1 - ' + data.toString() + '\n');
        defered.reject ( data.toString() );
    });

    proc.on('close', function (code) {
        console.log('step #1 process exited with code ' + code + '\n' );
        defered.resolve();
    });

    return defered.promise;
}

//create and update config files
function configFiles(  ) {
    var deferred = Q.defer()
      , comFile = path.join( __dirname, '..', 'config', 'test.json' )
      , comData = {
            "environmentName": "TEST",
            "memcacheHost": "127.0.0.1:11211",
            "clever-orm": {
                "db": {
                    "username": "travis",
                    "password": "",
                    "database": "test_db",
                    "options": {
                        "dialect": "mysql",
                        "host": "127.0.0.1",
                        "port": "3306"
                    }
                }
            }
        };

    console.log( 'step #2 - create and update config files - begin\n' );
    fs.writeFile ( comFile, JSON.stringify ( comData ), function ( err ) {

        if ( err ) {
            console.log( 'Error in step #2 - ' + err + '\n');
            return deferred.reject ( err );
        }

        console.log('step #2 process exited with code 0\n' );
        deferred.resolve();
    });

    return deferred.promise;
}

//added clever-orm module in bundledDependencies
function bundled() {
    var deferred = Q.defer()
      , file = path.join( __dirname, '..', 'package.json' );

    console.log( 'step #3 - added clever-orm module in bundledDependencies\n' );

    fs.readFile ( file, function ( err, data ) {

        if ( err ) {
            console.log( 'Error in step #3 - ' + err + '\n');
            return deferred.reject ( err );
        }

        data = JSON.parse ( data );

        data.bundledDependencies.push ( 'clever-orm' );

        fs.writeFile ( file, JSON.stringify ( data ), function ( err ) {

            if ( err ) {
                console.log( 'Error in step #3 - ' + err + '\n');
                return deferred.reject ( err );
            }

            console.log('step #3 process exited with code 0\n' );
            deferred.resolve();
        });
    });

    return deferred.promise;
}

installORM()
    .then ( configFiles )
    .then ( bundled )
    .fail ( function (err) {
        console.log('Error - ' + err );
    });<commit_msg>refactor(tests): Travis before script was not rebasing the db correctly<commit_after>var Q = require( 'q' )
  , spawn = require( 'child_process' ).spawn
  , path  = require( 'path' )
  , fs    = require( 'fs' )
  , ncp   = require('ncp').ncp;

//install clever-orm module to test project
function installORM () {
    var defered = Q.defer()
      , proc = spawn ( 'clever', [ 'install', 'clever-orm' ], { cwd: path.resolve( path.join( __dirname, '..' ) ) } );

    console.log( 'step #1 - install clever-orm module - begin\n' );

    proc.stdout.on('data', function (data) {
        var str = data.toString()
          , objs = [
                { reg: /Database username/ , write: 'travis\n' },
                { reg: /Database password/ , write: '\n' },
                { reg: /Database name/     , write: 'test_db\n' },
                { reg: /Database dialect/  , write: '\n' },
                { reg: /Database port/     , write: '3306\n' },
                { reg: /Database host/     , write: '127.0.0.1\n' },
            ];

        if ( str.match( /ing/ ) !== null ) {
            console.log( str )
        }

        objs.forEach ( function ( obj ) {
            if ( str.match( obj.reg ) !== null ) {
                proc.stdin.write( obj.write );
            }
        });
    });

    proc.stderr.on('data', function (data) {
        console.log( 'Error in step #1 - ' + data.toString() + '\n');
        defered.reject ( data.toString() );
    });

    proc.on('close', function (code) {
        console.log('step #1 process exited with code ' + code + '\n' );
        defered.resolve();
    });

    return defered.promise;
}

//create and update config files
function configFiles(  ) {
    var deferred = Q.defer()
      , comFile = path.join( __dirname, '..', 'config', 'test.json' )
      , comData = {
            "environmentName": "TEST",
            "memcacheHost": "127.0.0.1:11211",
            "clever-orm": {
                "db": {
                    "username": "travis",
                    "password": "",
                    "database": "test_db",
                    "options": {
                        "dialect": "mysql",
                        "host": "127.0.0.1",
                        "port": "3306"
                    }
                }
            }
        };

    console.log( 'step #2 - create and update config files - begin\n' );
    fs.writeFile ( comFile, JSON.stringify ( comData ), function ( err ) {

        if ( err ) {
            console.log( 'Error in step #2 - ' + err + '\n');
            return deferred.reject ( err );
        }

        console.log('step #2 process exited with code 0\n' );
        deferred.resolve();
    });

    return deferred.promise;
}

//added clever-orm module in bundledDependencies
function bundled() {
    var deferred = Q.defer()
      , file = path.join( __dirname, '..', 'package.json' );

    console.log( 'step #3 - added clever-orm module in bundledDependencies\n' );

    fs.readFile ( file, function ( err, data ) {

        if ( err ) {
            console.log( 'Error in step #3 - ' + err + '\n');
            return deferred.reject ( err );
        }

        data = JSON.parse ( data );

        data.bundledDependencies.push ( 'clever-orm' );

        fs.writeFile ( file, JSON.stringify ( data ), function ( err ) {

            if ( err ) {
                console.log( 'Error in step #3 - ' + err + '\n');
                return deferred.reject ( err );
            }

            console.log('step #3 process exited with code 0\n' );
            deferred.resolve();
        });
    });

    return deferred.promise;
}

function rebase() {
    var deferred = Q.defer()
      , proc = spawn( 'grunt', [ 'db' ], { cwd: path.resolve( path.join( __dirname, '..' ) ) } );

    proc.stderr.on('data', function (data) {
        console.log( 'Error in step #4 - ' + data.toString() + '\n');
        defered.reject ( data.toString() );
    });

    proc.on('close', function (code) {
        console.log('step #4 process exited with code ' + code + '\n' );
        defered.resolve();
    });

    return deferred.promise;
}

installORM()
    .then( configFiles )
    .then( bundled )
    .then( rebase )
    .fail( function (err) {
        console.log('Error - ' + err );
    });<|endoftext|>


<commit_before>'use strict';

/* global _, $, ace, marked, hljs, CartUtility */
module.exports = function() {
    // markd
    var renderer = new marked.Renderer();
    renderer.heading = function(text, level) { // add anchor link
        return '' +
            '<h' + level + '>' +
                '' +
                text +
            '</h' + level + '>';
    };
    marked.setOptions({
        renderer: renderer,
        gfm: true,
        tables: true,
        breaks: true,
        pedantic: false,
        sanitize: true,
        smartLists: true,
        smartypants: false,
        highlight: function (code, lang) {
            // since the highlight class name added with highlight lib itself not working, have to wrap code tag by self
            return '' + hljs.highlightAuto(code, [lang]).value + '';
        }
    });

    var createEditor = function(editElementId, previewElementId, baseUrl) {
        // ACE
        if (typeof editElementId === 'undefined' || editElementId === null || editElementId === '') {
            editElementId = 'markdown-edit';
        }
        if (typeof previewElementId === 'undefined' || previewElementId === null || previewElementId === '') {
            previewElementId = 'markdown-preview';
        }
        if (typeof baseUrl === 'undefined' || baseUrl === null) {
            baseUrl = '';
        }

        var aceEditor = ace.edit(editElementId);

        aceEditor.setOption("showPrintMargin", false);
        aceEditor.setTheme('ace/theme/earthsong');
        aceEditor.setHighlightActiveLine(true);
        aceEditor.setBehavioursEnabled(true);

        aceEditor.getSession().setMode('ace/mode/markdown');
        aceEditor.getSession().on('change', function() {
            previewMd(aceEditor);
        });

        aceEditor.session.setUseWrapMode(true);
        aceEditor.session.setNewLineMode("unix");
        aceEditor.session.setScrollTop(false);
        aceEditor.renderer.setShowGutter(true);
        aceEditor.renderer.setPrintMarginColumn(true);
        aceEditor.renderer.setPadding(15);
        aceEditor.renderer.setScrollMargin(20);
        aceEditor.resize(true);

        aceEditor.editElement = $('#' + editElementId);
        aceEditor.previewElement = $('#' + previewElementId);
        aceEditor.baseUrl = baseUrl;

        return aceEditor;
    };

    var previewMd = function(editor) {
        var content = editor.getSession().getValue();
        var converted = marked(content);

        editor.previewElement.html(converted);

        var editHeight = parseInt(editor.editElement.css('height'));
        var previewHeight = parseInt(editor.previewElement.css('height'));
        if (editHeight > previewHeight) {
            editor.previewElement.css('height', editHeight);
        } else if (editHeight < previewHeight) {
            editor.editElement.css('height', previewHeight);
        }

        var toc = CartUtility.buildToc(converted, editor.baseUrl);
        $('.markdown-toc-content').html(toc);
    };

    return {
        'createEditor': createEditor,
        'previewMd': previewMd
    };
};<commit_msg>Add comments.<commit_after>'use strict';

/* global _, $, ace, marked, hljs, CartUtility */
module.exports = function() {
    // markd
    var renderer = new marked.Renderer();
    renderer.heading = function(text, level) { // add anchor link
        return '' +
            '<h' + level + '>' +
                '' +
                text +
            '</h' + level + '>';
    };
    marked.setOptions({
        renderer: renderer,
        gfm: true,
        tables: true,
        breaks: true,
        pedantic: false,
        sanitize: true,
        smartLists: true,
        smartypants: false,
        highlight: function (code, lang) {
            // since the highlight class name added with highlight lib itself not working, have to wrap code tag by self
            return '' + hljs.highlightAuto(code, [lang]).value + '';
        }
    });

    var createEditor = function(editElementId, previewElementId, baseUrl) {
        // ACE
        if (typeof editElementId === 'undefined' || editElementId === null || editElementId === '') {
            editElementId = 'markdown-edit';
        }
        if (typeof previewElementId === 'undefined' || previewElementId === null || previewElementId === '') {
            previewElementId = 'markdown-preview';
        }
        if (typeof baseUrl === 'undefined' || baseUrl === null) {
            baseUrl = '';
        }

        var aceEditor = ace.edit(editElementId);

        aceEditor.setOption("showPrintMargin", false);
        aceEditor.setTheme('ace/theme/earthsong');
        aceEditor.setHighlightActiveLine(true);
        aceEditor.setBehavioursEnabled(true);

        aceEditor.getSession().setMode('ace/mode/markdown');
        aceEditor.getSession().on('change', function() {
            previewMd(aceEditor);
        });

        aceEditor.session.setUseWrapMode(true);
        aceEditor.session.setNewLineMode("unix");
        aceEditor.session.setScrollTop(false);
        aceEditor.renderer.setShowGutter(true);
        aceEditor.renderer.setPrintMarginColumn(true);
        aceEditor.renderer.setPadding(15);
        aceEditor.renderer.setScrollMargin(20);
        aceEditor.resize(true);

        aceEditor.editElement = $('#' + editElementId);
        aceEditor.previewElement = $('#' + previewElementId);
        aceEditor.baseUrl = baseUrl;

        // TODO add keyboard binding for shortcuts, command + s, command + p, etc ...

        return aceEditor;
    };

    var previewMd = function(editor) {
        var content = editor.getSession().getValue();
        var converted = marked(content);

        editor.previewElement.html(converted);

        var editHeight = parseInt(editor.editElement.css('height'));
        var previewHeight = parseInt(editor.previewElement.css('height'));
        if (editHeight > previewHeight) {
            editor.previewElement.css('height', editHeight);
        } else if (editHeight < previewHeight) {
            editor.editElement.css('height', previewHeight);
        }

        var toc = CartUtility.buildToc(converted, editor.baseUrl);
        $('.markdown-toc-content').html(toc);
    };

    return {
        'createEditor': createEditor,
        'previewMd': previewMd
    };
};<|endoftext|>


<commit_before>/*
*
* Copyright (C) 2011, The Locker Project
* All rights reserved.
*
* Please see the LICENSE file for more information.
*
*/

var vows = require("vows");
var assert = require("assert");
require.paths.push(__dirname + "/../Common/node");
var lpquery = require("lpquery");

vows.describe("Query System").addBatch({
    "Parsing a basic query" : {
        topic:lpquery.parse("/getPhotos?terms=[keyword:'test']"),
        "generates a valid parse tree":function(topic) {
            assert.equal(topic[0], "Photos");
            assert.isObject(topic[1]);
            assert.isArray(topic[1]["terms"]);
            assert.isArray(topic[1]["terms"][0]);
            assert.equal(topic[1]["terms"][0][0], "keyValue");
            assert.equal(topic[1]["terms"][0][1], "keyword");
            assert.equal(topic[1]["terms"][0][2], "test");
        },
        "can be turned into a mongoDB query":function(topic) {
            var mongoQuery = lpquery.buildMongoQuery(topic);
            assert.deepEqual(mongoQuery, {collection:"photos", query:{keyword:"test"}});
        }
    },
    "Parsing an invalid query" : {
        "results in a parse error": function() {
            try {
                var res = lpquery.parse("/invalid");
            } catch(E) {
                assert.instanceOf(E, Error);
            }
        }
    },
    "Defining fields in the query" : {
        topic: lpquery.parse("/getPhotos?fields=['_id','title']&offset=0"),
        "generates a proper mongo query" : function(topic) {
            var mongoQuery = lpquery.buildMongoQuery(topic);
            assert.deepEqual(mongoQuery, {collection:"photos", fields:{'_id' : 1, 'title' : 1}, skip: 0, query: {}});
        }
    },
    "Advanced query operators" : {
        topic:lpquery.parse("/getPhotos?terms=[gt:21+, gte:22+., lt:20-, lte:19-., (key:1 OR key:2)]&limit=10"),
        "generate a valid parse tree":function(topic) {
            assert.deepEqual(topic, [ 'Photos',
              { terms:
                 [ [ 'keyValue', 'gt', [ '+', 21 ] ],
                   [ 'keyValue', 'gte', [ '+.', 22 ] ],
                   [ 'keyValue', 'lt', [ '-', 20 ] ],
                   [ 'keyValue', 'lte', [ '-.', 19 ] ],
                   [ 'subset',
                     [ [ 'OR',
                         [ [ 'keyValue', 'key', 1 ], [ 'keyValue', 'key', 2 ] ] ] ] ] ],
                limit: 10 } ]);
        },
        "can be turned into a mongo query":function(topic) {
            assert.deepEqual(lpquery.buildMongoQuery(topic), {
                collection: 'photos',
                query: {
                    gt: { $gt: 21 },
                    gte: { $gte: 22 },
                    lt: { $lt: 20 },
                    lte: { $lte: 19 },
                    $or: [
                        { key: 1 },
                        { key: 2 }
                    ]
                },
                limit: 10
            });
        }
    }
}).export(module);
<commit_msg>add test for boolean and number query filters<commit_after>/*
*
* Copyright (C) 2011, The Locker Project
* All rights reserved.
*
* Please see the LICENSE file for more information.
*
*/

var vows = require("vows");
var assert = require("assert");
require.paths.push(__dirname + "/../Common/node");
var lpquery = require("lpquery");

vows.describe("Query System").addBatch({
    "Parsing a basic query" : {
        topic:lpquery.parse("/getPhotos?terms=[keyword:'test']"),
        "generates a valid parse tree":function(topic) {
            assert.equal(topic[0], "Photos");
            assert.isObject(topic[1]);
            assert.isArray(topic[1]["terms"]);
            assert.isArray(topic[1]["terms"][0]);
            assert.equal(topic[1]["terms"][0][0], "keyValue");
            assert.equal(topic[1]["terms"][0][1], "keyword");
            assert.equal(topic[1]["terms"][0][2], "test");
        },
        "can be turned into a mongoDB query":function(topic) {
            var mongoQuery = lpquery.buildMongoQuery(topic);
            assert.deepEqual(mongoQuery, {collection:"photos", query:{keyword:"test"}});
        }
    },
    "Parsing an invalid query" : {
        "results in a parse error": function() {
            try {
                var res = lpquery.parse("/invalid");
            } catch(E) {
                assert.instanceOf(E, Error);
            }
        }
    },
    "Parsing a query with non-string fields" : {
        topic:lpquery.parse("/getPhotos?terms=[anumber:7, aboolean:false]"),
        "generates a valid parse tree":function(topic) {
            assert.deepEqual(topic, [ 'Photos',
              { terms:
                 [ [ 'keyValue', 'anumber', 7 ],
                   [ 'keyValue', 'aboolean', false ] ] } ]);
        },
        "can be turned into a mongoDB query":function(topic) {
            var mongoQuery = lpquery.buildMongoQuery(topic);
            assert.deepEqual(mongoQuery, {
                collection: "photos",
                query: {
                    anumber: 7,
                    aboolean: false
                }
            });
        }
    },
    "Defining fields in the query" : {
        topic: lpquery.parse("/getPhotos?fields=['_id','title']&offset=0"),
        "generates a proper mongo query" : function(topic) {
            var mongoQuery = lpquery.buildMongoQuery(topic);
            assert.deepEqual(mongoQuery, {collection:"photos", fields:{'_id' : 1, 'title' : 1}, skip: 0, query: {}});
        }
    },
    "Advanced query operators" : {
        topic:lpquery.parse("/getPhotos?terms=[gt:21+, gte:22+., lt:20-, lte:19-., (key:1 OR key:2)]&limit=10"),
        "generate a valid parse tree":function(topic) {
            assert.deepEqual(topic, [ 'Photos',
              { terms:
                 [ [ 'keyValue', 'gt', [ '+', 21 ] ],
                   [ 'keyValue', 'gte', [ '+.', 22 ] ],
                   [ 'keyValue', 'lt', [ '-', 20 ] ],
                   [ 'keyValue', 'lte', [ '-.', 19 ] ],
                   [ 'subset',
                     [ [ 'OR',
                         [ [ 'keyValue', 'key', 1 ], [ 'keyValue', 'key', 2 ] ] ] ] ] ],
                limit: 10 } ]);
        },
        "can be turned into a mongo query":function(topic) {
            assert.deepEqual(lpquery.buildMongoQuery(topic), {
                collection: 'photos',
                query: {
                    gt: { $gt: 21 },
                    gte: { $gte: 22 },
                    lt: { $lt: 20 },
                    lte: { $lte: 19 },
                    $or: [
                        { key: 1 },
                        { key: 2 }
                    ]
                },
                limit: 10
            });
        }
    }
}).export(module);
<|endoftext|>


<commit_before>'use strict'

import _ from 'lodash'
import Reflux from 'reflux'
import moment from 'moment'

import api from 'data/api'
import builtins from 'dashboard/builtin'
import DashboardInit from 'data/dashboardInit'

import RegionStore from 'stores/RegionStore'
import CampaignStore from 'stores/CampaignStore'
import IndicatorStore from 'stores/IndicatorStore'

var HomepageDashboardsStore = Reflux.createStore({
  listenables: [require('actions/HomepageDashboardsActions')],

  onInitialize () {
    this.onFetchDashboards()
  },

  getDashboardByName: function (dashboardDef) {
    var obj = _.find(builtins, d => _.kebabCase(d.title) === dashboardDef.name)

    obj.location = dashboardDef.location
    obj.date = dashboardDef.date

    obj.indicators = IndicatorStore.getById.apply(
      IndicatorStore,
      _(_.get(dashboardDef, 'charts', []))
        .pluck('indicators')
        .flatten()
        .uniq()
        .value()
    )

    return obj
  },

  melt: function (d) {
    var base = _.omit(d, 'indicators')

    return d.indicators.map(i => {
      return _.assign({
        indicator: i.indicator,
        value: i.value
      }, base)
    })
  },

  fetchData: function (dashboard) {
    var campaign = dashboard.campaign
    var location = dashboard.location
    var charts = dashboard.charts

    var start = moment(campaign.start_date, 'YYYY-MM-DD')
    var end = campaign.end_date

    var promises = _.map(charts, function (def) {
      var query = {
        indicator__in: def.indicators,
        campaign_end: end
      }

      if (!_.isNull(_.get(def, 'timeRange', null)) || def.hasOwnProperty('startOf')) {
        query.campaign_start = start.clone()
          .startOf(def.startOf)
          .subtract(def.timeRange)
          .format('YYYY-MM-DD')
      }

      switch (def.locations) {
        case 'sublocations':
          query.parent_location__in = location.id
          break

        case 'type':
          var parent = _.get(location, 'parent.id')
          if (!_.isUndefined(parent)) {
            query.parent_location__in = parent
          }

          query.location_type = location.location_type
          break
        default:
          query.location__in = location.id
          break
      }

      if (def.level) {
        query.level = def.level
      }

      return api.datapoints(query)
    })

    return Promise.all(promises)
  },

  prepareQuery: function (locations, campaigns, locationsTypes, dashboard) {
    var locationIdx = _.indexBy(locations, 'id')
    var types = _.indexBy(locationsTypes, 'id')

    _.each(this.locations, function (r) {
      r.location_type = _.get(types[r.location_type_id], 'name')
      r.parent = locationIdx[r.parent_location_id]
    })

    var indicators = _.reduce(dashboard.charts, this.generateIndicator, {})
    var query = this.getQueriesByIndicators(indicators)

    var topLevelLocations = _(locations)
        .filter(function (r) {
          return !locationIdx.hasOwnProperty(r.parent_location_id)
        })
        .sortBy('name')

    var location = _.find(locations, function (r) {
      return r.name === dashboard.location
    })

    if (!location) {
      location = topLevelLocations.first()
    }

    var campaign = _(campaigns)
      .filter(function (c) {
        return c.office_id === location.office_id &&
          (!dashboard.date || _.startsWith(c.start_date, dashboard.date))
      })
      .sortBy('start_date')
      .last()

    var hasMap = _(dashboard.charts)
    .pluck('type')
    .any(t => _.endsWith(t, 'Map'))

    return {
      campaign: campaign,
      dashboard: dashboard,
      charts: query,
      location: location,
      hasMap: hasMap
    }
  },

  countriesPromise: function (list) {
    return api.geo({ parent_location__in: list.join(','), with_parent: true }, null, { 'cache-control': 'max-age=604800, public' }).then(response => {
      var locations = _(response.objects.features).flatten().groupBy('parent_location_id').value()
      return list.map(item => locations[item])
    })
  },

  onFetchDashboards: function () {
    var dashboardDefs = [
      {
        name: 'homepage-afghanistan',
        date: '2015-08',
        location: 'Afgh anistan',
        id: 2
      },
      {
        name: 'homepage-pakistan',
        date: '2015-09',
        location: 'Pakistan',
        id: 3
      },
      {
        name: 'homepage-nigeria',
        date: '2015-09',
        location: 'Nigeria',
        id: 1
      }
    ]

    Promise.all([
      RegionStore.getlocationsPromise(),
      RegionStore.getLocationTypesPromise(),
      CampaignStore.getCampaignsPromise(),
      IndicatorStore.getIndicatorsPromise(),
      this.countriesPromise(dashboardDefs.map(item => item.id))
    ])
    .then(_.spread((locations, locationsTypes, campaigns, indicators, countries) => {
      var partialPrepare = _.partial((dashboard) => {
        return this.prepareQuery(locations, campaigns, locationsTypes, dashboard)
      })

      var enhanced = dashboardDefs
        .map(this.getDashboardByName)
        .map(partialPrepare)

      var partialDashboardInit = _.partial((country, data) => {
        var dashboardDef = _.find(enhanced, (item) => {
          return country === item.location.name.toLowerCase()
        })

        return _.extend({
          campaign: dashboardDef.campaign,
          location: dashboardDef.location,
          indicators: indicators
        },
        _.pick(dashboardDef.dashboard, ['location', 'date']), {
          data: DashboardInit.dashboardInit(
            dashboardDef.dashboard,
            data.data,
            dashboardDef.location,
            dashboardDef.campaign,
            locations,
            campaigns,
            indicators,
            data.features
          )
        })
      })

      var queries = enhanced
        .map(this.fetchData)

      Promise.all(queries).then(_.spread((d1, d2, d3) => {
        var dashboards = _.zip([d1, d2, d3], countries)
          .map((item) => {
            return {
              data: item[0],
              features: item[1]
            }
          }).map((item) => {
            return {
              data: _(item.data)
              .pluck('objects')
              .flatten()
              .sortBy(_.method('campaign.start_date.getTime'))
              .map(this.melt)
              .flatten()
              .value(),
              features: item.features
            }
          }).map(function (item) {
            var country = item.data[0].campaign.slug.split('-')[0]
            return partialDashboardInit(country, item)
          })
        this.trigger({
          dashboards: dashboards
        })
      }))
    }))
  },

  getQueriesByIndicators: function (indicators) {
    var qs = _.groupBy(indicators, function (def) {
      return [def.duration, def.startOf, def.locations].join('-')
    })

    return _.map(qs, function (arr) {
      return _.merge.apply(null, arr.concat(function (a, b) {
        if (_.isArray(a)) {
          return a.concat(b)
        }
      }))
    })
  },

  generateIndicator: function (indicators, chart) {
    var base = _.omit(chart, 'indicators', 'title')

    _.each(chart.indicators, function (id) {
      var duration = !_.isNull(_.get(chart, 'timeRange', null)) ? moment.duration(chart.timeRange) : Infinity
      var hash = [id, chart.startOf, chart.locations].join('-')

      if (!indicators.hasOwnProperty(hash) || duration > indicators[hash].duration) {
        indicators[hash] = _.defaults({
          duration: duration,
          indicators: [id]
        }, base)
      }
    })

    return indicators
  }
})

export default HomepageDashboardsStore
<commit_msg>update the location name.<commit_after>'use strict'

import _ from 'lodash'
import Reflux from 'reflux'
import moment from 'moment'

import api from 'data/api'
import builtins from 'dashboard/builtin'
import DashboardInit from 'data/dashboardInit'

import RegionStore from 'stores/RegionStore'
import CampaignStore from 'stores/CampaignStore'
import IndicatorStore from 'stores/IndicatorStore'

var HomepageDashboardsStore = Reflux.createStore({
  listenables: [require('actions/HomepageDashboardsActions')],

  onInitialize () {
    this.onFetchDashboards()
  },

  getDashboardByName: function (dashboardDef) {
    var obj = _.find(builtins, d => _.kebabCase(d.title) === dashboardDef.name)

    obj.location = dashboardDef.location
    obj.date = dashboardDef.date

    obj.indicators = IndicatorStore.getById.apply(
      IndicatorStore,
      _(_.get(dashboardDef, 'charts', []))
        .pluck('indicators')
        .flatten()
        .uniq()
        .value()
    )

    return obj
  },

  melt: function (d) {
    var base = _.omit(d, 'indicators')

    return d.indicators.map(i => {
      return _.assign({
        indicator: i.indicator,
        value: i.value
      }, base)
    })
  },

  fetchData: function (dashboard) {
    var campaign = dashboard.campaign
    var location = dashboard.location
    var charts = dashboard.charts

    var start = moment(campaign.start_date, 'YYYY-MM-DD')
    var end = campaign.end_date

    var promises = _.map(charts, function (def) {
      var query = {
        indicator__in: def.indicators,
        campaign_end: end
      }

      if (!_.isNull(_.get(def, 'timeRange', null)) || def.hasOwnProperty('startOf')) {
        query.campaign_start = start.clone()
          .startOf(def.startOf)
          .subtract(def.timeRange)
          .format('YYYY-MM-DD')
      }

      switch (def.locations) {
        case 'sublocations':
          query.parent_location__in = location.id
          break

        case 'type':
          var parent = _.get(location, 'parent.id')
          if (!_.isUndefined(parent)) {
            query.parent_location__in = parent
          }

          query.location_type = location.location_type
          break
        default:
          query.location__in = location.id
          break
      }

      if (def.level) {
        query.level = def.level
      }

      return api.datapoints(query)
    })

    return Promise.all(promises)
  },

  prepareQuery: function (locations, campaigns, locationsTypes, dashboard) {
    var locationIdx = _.indexBy(locations, 'id')
    var types = _.indexBy(locationsTypes, 'id')

    _.each(this.locations, function (r) {
      r.location_type = _.get(types[r.location_type_id], 'name')
      r.parent = locationIdx[r.parent_location_id]
    })

    var indicators = _.reduce(dashboard.charts, this.generateIndicator, {})
    var query = this.getQueriesByIndicators(indicators)

    var topLevelLocations = _(locations)
        .filter(function (r) {
          return !locationIdx.hasOwnProperty(r.parent_location_id)
        })
        .sortBy('name')

    var location = _.find(locations, function (r) {
      return r.name === dashboard.location
    })

    if (!location) {
      location = topLevelLocations.first()
    }

    var campaign = _(campaigns)
      .filter(function (c) {
        return c.office_id === location.office_id &&
          (!dashboard.date || _.startsWith(c.start_date, dashboard.date))
      })
      .sortBy('start_date')
      .last()

    var hasMap = _(dashboard.charts)
    .pluck('type')
    .any(t => _.endsWith(t, 'Map'))

    return {
      campaign: campaign,
      dashboard: dashboard,
      charts: query,
      location: location,
      hasMap: hasMap
    }
  },

  countriesPromise: function (list) {
    return api.geo({ parent_location__in: list.join(','), with_parent: true }, null, { 'cache-control': 'max-age=604800, public' }).then(response => {
      var locations = _(response.objects.features).flatten().groupBy('parent_location_id').value()
      return list.map(item => locations[item])
    })
  },

  onFetchDashboards: function () {
    var dashboardDefs = [
      {
        name: 'homepage-afghanistan',
        date: '2015-08',
        location: 'Afghanistan',
        id: 2
      },
      {
        name: 'homepage-pakistan',
        date: '2015-09',
        location: 'Pakistan',
        id: 3
      },
      {
        name: 'homepage-nigeria',
        date: '2015-09',
        location: 'Nigeria',
        id: 1
      }
    ]

    Promise.all([
      RegionStore.getlocationsPromise(),
      RegionStore.getLocationTypesPromise(),
      CampaignStore.getCampaignsPromise(),
      IndicatorStore.getIndicatorsPromise(),
      this.countriesPromise(dashboardDefs.map(item => item.id))
    ])
    .then(_.spread((locations, locationsTypes, campaigns, indicators, countries) => {
      var partialPrepare = _.partial((dashboard) => {
        return this.prepareQuery(locations, campaigns, locationsTypes, dashboard)
      })

      var enhanced = dashboardDefs
        .map(this.getDashboardByName)
        .map(partialPrepare)

      var partialDashboardInit = _.partial((country, data) => {
        var dashboardDef = _.find(enhanced, (item) => {
          return country === item.location.name.toLowerCase()
        })

        return _.extend({
          campaign: dashboardDef.campaign,
          location: dashboardDef.location,
          indicators: indicators
        },
        _.pick(dashboardDef.dashboard, ['location', 'date']), {
          data: DashboardInit.dashboardInit(
            dashboardDef.dashboard,
            data.data,
            dashboardDef.location,
            dashboardDef.campaign,
            locations,
            campaigns,
            indicators,
            data.features
          )
        })
      })

      var queries = enhanced
        .map(this.fetchData)

      Promise.all(queries).then(_.spread((d1, d2, d3) => {
        var dashboards = _.zip([d1, d2, d3], countries)
          .map((item) => {
            return {
              data: item[0],
              features: item[1]
            }
          }).map((item) => {
            return {
              data: _(item.data)
              .pluck('objects')
              .flatten()
              .sortBy(_.method('campaign.start_date.getTime'))
              .map(this.melt)
              .flatten()
              .value(),
              features: item.features
            }
          }).map(function (item) {
            var country = item.data[0].campaign.slug.split('-')[0]
            return partialDashboardInit(country, item)
          })
        this.trigger({
          dashboards: dashboards
        })
      }))
    }))
  },

  getQueriesByIndicators: function (indicators) {
    var qs = _.groupBy(indicators, function (def) {
      return [def.duration, def.startOf, def.locations].join('-')
    })

    return _.map(qs, function (arr) {
      return _.merge.apply(null, arr.concat(function (a, b) {
        if (_.isArray(a)) {
          return a.concat(b)
        }
      }))
    })
  },

  generateIndicator: function (indicators, chart) {
    var base = _.omit(chart, 'indicators', 'title')

    _.each(chart.indicators, function (id) {
      var duration = !_.isNull(_.get(chart, 'timeRange', null)) ? moment.duration(chart.timeRange) : Infinity
      var hash = [id, chart.startOf, chart.locations].join('-')

      if (!indicators.hasOwnProperty(hash) || duration > indicators[hash].duration) {
        indicators[hash] = _.defaults({
          duration: duration,
          indicators: [id]
        }, base)
      }
    })

    return indicators
  }
})

export default HomepageDashboardsStore
<|endoftext|>


<commit_before>// SuperSleight, version 1.1.0
// version 1.1.0 by Jeffrey Barke <http://themechanism.com/> 20071218
// Essential (99% of the) code by Drew McLellan <http://24ways.org/2007/supersleight-transparent-png-in-ie6>
var supersleight = function() {

	// local vars
	var root = false;
	var applyPositioning = true;
	// path to a transparent GIF image
	var shim = './images/x.gif';

	var fnLoadPngs = function() {
		// if supersleight.limitTo called, limit to specified id
		if (root) { root = document.getElementById(root); } else { root = document; }
		// loop
		for (var i = root.all.length - 1, obj = null; (obj = root.all[i]); i--) {
			// background pngs
			if (obj.currentStyle.backgroundImage.match(/\.png/i) !== null) {
				bg_fnFixPng(obj);
			}
			// image elements
			if (obj.tagName == 'IMG' && obj.src.match(/\.png$/i) !== null) {
				el_fnFixPng(obj);
			}
			// apply position to 'active' elements
			if (applyPositioning && (obj.tagName == 'A' || obj.tagName == 'INPUT') && obj.style.position === '') {
				obj.style.position = 'relative';
			}
		}
	};

	var bg_fnFixPng = function(obj) {
		var mode = 'scale';
		var bg = obj.currentStyle.backgroundImage;
		var src = bg.substring(5,bg.length-2);
		if (obj.currentStyle.backgroundRepeat == 'no-repeat') {
			mode = 'crop';
		}
		obj.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + src + "', sizingMethod='" + mode + "')";
		obj.style.backgroundImage = 'url(' + shim + ')';
	};

	var el_fnFixPng = function(img) {
		var src = img.src;
		img.style.width = img.width + 'px';
		img.style.height = img.height + 'px';
		img.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + src + "', sizingMethod='scale')";
		img.src = shim;
	};

	var addLoadEvent = function(func) {
		var oldonload = window.onload;
		if (typeof window.onload != 'function') {
			window.onload = func;
		} else {
			window.onload = function() {
				if (oldonload) {
					oldonload();
				}
				func();
			};
		}
	};

	// supersleight object
	return {
		init: function(strPath, blnPos, strId) {
			if (document.getElementById) {
				if (typeof(strPath) != 'undefined' && null !== strPath) { shim = strPath; }
				if (typeof(blnPos) != 'undefined' && null !== blnPos) { applyPositioning = blnPos; }
				if (typeof(strId) != 'undefined' && null !== strId) { root = strId; }
				addLoadEvent(fnLoadPngs);
			} else {
				return false;
			}
		},
		limitTo: function(el) {
			root = el;
		},
		run: function(strPath, blnPos, strId) {
			if (document.getElementById) {
				if (typeof(strPath) != 'undefined' && null !== strPath) { shim = strPath; }
				if (typeof(blnPos) != 'undefined' && null !== blnPos) { applyPositioning = blnPos; }
				if (typeof(strId) != 'undefined' && null !== strId) { root = strId; }
				fnLoadPngs();
			} else {
				return false;
			}
		}
	};

}();

// limit to part of the page ... pass an ID to limitTo:
// supersleight.limitTo('top');
// optional path to a transparent GIF image, apply positioning, limitTo
supersleight.init();<commit_msg>NIHVIVO-1838: In IE6 some content (text) disappear after loading individual pages for foaf person or generic. Changing var applyPositioning = false in supersleight.js change the behavior and content doesn't   disappear (text) anymore. Still working on why PNG images disappear. Also I have fixed some layout issues in IE 6 and IE 7.<commit_after>// SuperSleight, version 1.1.0
// version 1.1.0 by Jeffrey Barke <http://themechanism.com/> 20071218
// Essential (99% of the) code by Drew McLellan <http://24ways.org/2007/supersleight-transparent-png-in-ie6>
var supersleight = function() {

	// local vars
	var root = false;
	var applyPositioning = false;
	// path to a transparent GIF image
	var shim = './images/x.gif';

	var fnLoadPngs = function() {
		// if supersleight.limitTo called, limit to specified id
		if (root) { root = document.getElementById(root); } else { root = document; }
		// loop
		for (var i = root.all.length - 1, obj = null; (obj = root.all[i]); i--) {
			// background pngs
			if (obj.currentStyle.backgroundImage.match(/\.png/i) !== null) {
				bg_fnFixPng(obj);
			}
			// image elements
			if (obj.tagName == 'IMG' && obj.src.match(/\.png$/i) !== null) {
				el_fnFixPng(obj);
			}
			// apply position to 'active' elements
			if (applyPositioning && (obj.tagName == 'A' || obj.tagName == 'INPUT') && obj.style.position === '') {
				obj.style.position = 'relative';
			}
		}
	};

	var bg_fnFixPng = function(obj) {
		var mode = 'scale';
		var bg = obj.currentStyle.backgroundImage;
		var src = bg.substring(5,bg.length-2);
		if (obj.currentStyle.backgroundRepeat == 'no-repeat') {
			mode = 'crop';
		}
		obj.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + src + "', sizingMethod='" + mode + "')";
		obj.style.backgroundImage = 'url(' + shim + ')';
	};

	var el_fnFixPng = function(img) {
		var src = img.src;
		img.style.width = img.width + 'px';
		img.style.height = img.height + 'px';
		img.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + src + "', sizingMethod='scale')";
		img.src = shim;
	};

	var addLoadEvent = function(func) {
		var oldonload = window.onload;
		if (typeof window.onload != 'function') {
			window.onload = func;
		} else {
			window.onload = function() {
				if (oldonload) {
					oldonload();
				}
				func();
			};
		}
	};

	// supersleight object
	return {
		init: function(strPath, blnPos, strId) {
			if (document.getElementById) {
				if (typeof(strPath) != 'undefined' && null !== strPath) { shim = strPath; }
				if (typeof(blnPos) != 'undefined' && null !== blnPos) { applyPositioning = blnPos; }
				if (typeof(strId) != 'undefined' && null !== strId) { root = strId; }
				addLoadEvent(fnLoadPngs);
			} else {
				return false;
			}
		},
		limitTo: function(el) {
			root = el;
		},
		run: function(strPath, blnPos, strId) {
			if (document.getElementById) {
				if (typeof(strPath) != 'undefined' && null !== strPath) { shim = strPath; }
				if (typeof(blnPos) != 'undefined' && null !== blnPos) { applyPositioning = blnPos; }
				if (typeof(strId) != 'undefined' && null !== strId) { root = strId; }
				fnLoadPngs();
			} else {
				return false;
			}
		}
	};

}();

// limit to part of the page ... pass an ID to limitTo:
// supersleight.limitTo('top');
// optional path to a transparent GIF image, apply positioning, limitTo
supersleight.init();<|endoftext|>


<commit_before>import Sidebar from './sidebar'
import Browser from './browser'

export default () => {
  return `

      ${Sidebar({ providers: [{ name: 'Local' }, { name: 'Google Drive' }]})}
      ${Browser({
        files: [{ image: '123.png', name: '123.png' }],
        provider: 'Dropbox',
        currentDirectory: '/'
      })}

  `
}
<commit_msg>Fixed formatting<commit_after>import Sidebar from './sidebar'
import Browser from './browser'

export default () => {
  return `

      ${Sidebar({
        providers: [{
          name: 'Local'
        },
        {
          name: 'Google Drive'
        }]
      })}
      ${Browser({
        files: [{ image: '123.png', name: '123.png' }],
        provider: 'Dropbox',
        currentDirectory: '/'
      })}

  `
}
<|endoftext|>


<commit_before>angular.module('opal.controllers').controller(
  'ExtractCtrl',
  function(
    $scope, $http, $window, $modal, $timeout, PatientSummary, Paginator,
    referencedata, ngProgressLite, profile, filters, schema
  ){
    "use strict";

    var underscoreToCapWords = function(str) {
        return str.toLowerCase().replace(/_/g, ' ').replace(
                /(?:\b)(\w)/g, function(s, p){ return p.toUpperCase(); });
    };

    $scope.profile = profile;
    $scope.limit = 10;
    $scope.JSON = window.JSON;
    $scope.filters = filters;
    $scope.columns = schema.getAdvancedSearchColumns();
    $scope.columnToDisplayName = _.reduce($scope.columns,function(a,b) {
      a[b.name] = b.display_name;
      return a;
    },{});
    $scope.searched = false;
    $scope.currentPageNumber = 1;
    $scope.paginator = new Paginator($scope.search);

    // todo, remove symptom from here
    var NOT_ADVANCED_SEARCHABLE = [
        "created", "updated", "created_by_id", "updated_by_id"
    ];
    _.extend($scope, referencedata.toLookuplists());

    $scope.combinations = ["all", "any"];
    $scope.anyOrAll = $scope.combinations[0];

    $scope.model = {
        column     : null,
        field      : null,
        queryType  : null,
        query      : null,
        lookup_list: []
    };

    $scope.criteria = [_.clone($scope.model)];

    $scope.readableQuery = function(someQuery){
      if(!someQuery){
        return undefined;
      }
      var result = someQuery;
      if(someQuery === "Equals"){
        result = "is";
      }
      if(someQuery === "Before" || someQuery === "After"){
        result = "is " + result;
      }

      return result.toLowerCase();
    };

    $scope.completeCriteria =  function(){
      var combine;

      // queries can look at either all of the options, or any of them
      // ie 'and' conjunctions or 'or'
      if($scope.anyOrAll === 'all'){
        combine = "and";
      }
      else{
        combine = 'or';
      }

      // remove incomplete criteria
      var criteria = _.filter($scope.criteria, function(c){
          // Teams are a special case - they are essentially boolean
          if(c.column == 'tagging' && c.field){
              return true;
          }
          // Ensure we have a query otherwise
          if(c.column &&  c.field &&  c.query){
              return true;
          }
          c.combine = combine;
          // If not, we ignore this clause
          return false;
      });

      _.each(criteria, function(c){
        c.combine = combine;
      });

      return criteria;
    };

    $scope.searchableFields = function(column){
        // TODO - don't hard-code this
        if(column.name == 'microbiology_test'){
            return [
                'Test',
                'Date Ordered',
                'Details',
                'Microscopy',
                'Organism',
                'Sensitive Antibiotics',
                'Resistant Antibiotics'
            ]
        }
        return _.map(
            _.reject(
                column.fields,
                function(c){
                    if(_.contains(NOT_ADVANCED_SEARCHABLE, c.name)){
                        return true;
                    }
                    return c.type == 'token' ||  c.type ==  'list';
                }),
            function(c){ return underscoreToCapWords(c.name); }
        ).sort();
    };

    $scope.isType = function(column, field, type){
        if(!column || !field){
            return false;
        }
        var col = _.find(
            $scope.columns,
            function(item){
                return item.name == column.toLowerCase().replace( / /g,  '_')
            });
        var theField =  _.find(
            col.fields,
            function(f){
                return f.name == field.toLowerCase().replace( / /g,  '_')
            });
        if(!theField){ return false }
        if (_.isArray(type)){
            var match = false;
            _.each(type, function(t){ if(t == theField.type){ match = true} });
            return match;
        }else{
            return theField.type == type;
        }
    };

    $scope.isBoolean = function(column, field){
        return $scope.isType(column, field, ["boolean", "null_boolean"]);
    };

    $scope.isText = function(column, field){
        return $scope.isType(column, field, "string") || $scope.isType(column, field, "text");
    }

    $scope.isSelect = function(column, field){
        return $scope.isType(column, field, "many_to_many");
    };

    $scope.isDate = function(column, field){
        return $scope.isType(column, field, "date");
    };

    $scope.addFilter = function(){
        $scope.criteria.push(_.clone($scope.model));
    };

    $scope.removeFilter = function(index){
        if($scope.criteria.length == 1){
            $scope.removeCriteria();
        }
        else{
            $scope.criteria.splice(index, 1);
        }
    };

    $scope.resetFilter = function(query){
      // when we change the column, reset the rest of the query
      _.each(query, function(v, k){
        if(k !== 'column' && k in $scope.model){
          query[k] = $scope.model[k];
        }
      });
    };

    $scope.removeCriteria = function(){
        $scope.criteria = [_.clone($scope.model)];
    };

    //
    // Determine the appropriate lookup list for this field if
    // one exists.
    //
    $scope._lookuplist_watch = function(){
        _.map($scope.criteria, function(c){
            var column = _.findWhere($scope.columns, {name: c.column});
            if(!column){return;}
            if(!c.field){return;}
            var field = _.findWhere(
                column.fields, {name: c.field.toLowerCase().replace(/ /g, '_')});
            if(!field){return; }
            if(field.lookup_list){
                c.lookup_list = $scope[field.lookup_list + '_list'];
            }
        });
        $scope.async_waiting = false;
        $scope.async_ready = false;
        $scope.searched = false;
        $scope.results = [];
    }

    $scope.$watch('criteria', $scope._lookuplist_watch, true);

    $scope.search = function(pageNumber){
        if(!pageNumber){
            pageNumber = 1;
        }

        var queryParams = $scope.completeCriteria();

        if(queryParams.length){
            queryParams[0].page_number = pageNumber;
            ngProgressLite.set(0);
            ngProgressLite.start();
            $http.post('/search/extract/', queryParams).success(
                function(response){
                    $scope.results = _.map(response.object_list, function(o){
                        return new PatientSummary(o);
                    });
                    $scope.searched = true;
                    $scope.paginator = new Paginator($scope.search, response);
                    ngProgressLite.done();
                }).error(function(e){
                    ngProgressLite.set(0);
                    $window.alert('ERROR: Could not process this search. Please report it to the OPAL team');
                });
        }
        else{
          $scope.searched = true;
        }
    };

    $scope.async_extract = function(){
        if($scope.async_ready){
            $window.open('/search/extract/download/' + $scope.extract_id, '_blank');
            return null;
        }
        if($scope.async_waiting){
            return null;
        }

        var ping_until_success = function(){
            if(!$scope.extract_id){
                $timeout(ping_until_success, 1000);
                return;
            }
            $http.get('/search/extract/result/'+ $scope.extract_id).then(function(result){
                if(result.data.state == 'FAILURE'){
                    $window.alert('FAILURE');
                    $scope.async_waiting = false;
                    return;
                }
                if(result.data.state == 'SUCCESS'){
                    $scope.async_ready = true;
                }else{
                    if($scope.async_waiting){
                        $timeout(ping_until_success, 1000);
                    }
                }
            });
        }
        $scope.async_waiting = true;
        $http.post(
            '/search/extract/download',
            {criteria: JSON.stringify($scope.criteria)}
        ).then(function(result){
            $scope.extract_id = result.data.extract_id;
            ping_until_success();
        });
    };

    $scope.jumpToFilter = function($event, filter){
        $event.preventDefault();
        $scope.criteria = filter.criteria;
    };

    $scope.editFilter = function($event, filter, $index){
      $event.preventDefault();
      var modal = $modal.open({
        templateUrl: '/search/templates/modals/save_filter_modal.html/',
        controller: 'SaveFilterCtrl',
        resolve: {
          params: function() { return $scope.filters[$index]; }
        }
      }).result.then(function(result){
        $scope.filters[$index] = result;
      });
    };

    $scope.save = function(){
      $modal.open({
        templateUrl: '/search/templates/modals/save_filter_modal.html/',
        controller: 'SaveFilterCtrl',
        resolve: {
          params: function() { return {name: null, criteria: $scope.completeCriteria()}; }
        }
      }).result.then(function(result){
        $scope.filters.push(result);
      });
    };

    $scope.jumpToEpisode = function(episode){
        window.open('#/episode/'+episode.id, '_blank');
    };

});
<commit_msg>if passed null, return null<commit_after>angular.module('opal.controllers').controller(
  'ExtractCtrl',
  function(
    $scope, $http, $window, $modal, $timeout, PatientSummary, Paginator,
    referencedata, ngProgressLite, profile, filters, schema
  ){
    "use strict";

    var underscoreToCapWords = function(str) {
        return str.toLowerCase().replace(/_/g, ' ').replace(
                /(?:\b)(\w)/g, function(s, p){ return p.toUpperCase(); });
    };

    $scope.profile = profile;
    $scope.limit = 10;
    $scope.JSON = window.JSON;
    $scope.filters = filters;
    $scope.columns = schema.getAdvancedSearchColumns();
    $scope.columnToDisplayName = _.reduce($scope.columns,function(a,b) {
      a[b.name] = b.display_name;
      return a;
    },{});
    $scope.searched = false;
    $scope.currentPageNumber = 1;
    $scope.paginator = new Paginator($scope.search);

    // todo, remove symptom from here
    var NOT_ADVANCED_SEARCHABLE = [
        "created", "updated", "created_by_id", "updated_by_id"
    ];
    _.extend($scope, referencedata.toLookuplists());

    $scope.combinations = ["all", "any"];
    $scope.anyOrAll = $scope.combinations[0];

    $scope.model = {
        column     : null,
        field      : null,
        queryType  : null,
        query      : null,
        lookup_list: []
    };

    $scope.criteria = [_.clone($scope.model)];

    $scope.readableQuery = function(someQuery){
      if(!someQuery){
        return someQuery;
      }
      var result = someQuery;
      if(someQuery === "Equals"){
        result = "is";
      }
      if(someQuery === "Before" || someQuery === "After"){
        result = "is " + result;
      }

      return result.toLowerCase();
    };

    $scope.completeCriteria =  function(){
      var combine;

      // queries can look at either all of the options, or any of them
      // ie 'and' conjunctions or 'or'
      if($scope.anyOrAll === 'all'){
        combine = "and";
      }
      else{
        combine = 'or';
      }

      // remove incomplete criteria
      var criteria = _.filter($scope.criteria, function(c){
          // Teams are a special case - they are essentially boolean
          if(c.column == 'tagging' && c.field){
              return true;
          }
          // Ensure we have a query otherwise
          if(c.column &&  c.field &&  c.query){
              return true;
          }
          c.combine = combine;
          // If not, we ignore this clause
          return false;
      });

      _.each(criteria, function(c){
        c.combine = combine;
      });

      return criteria;
    };

    $scope.searchableFields = function(column){
        // TODO - don't hard-code this
        if(column.name == 'microbiology_test'){
            return [
                'Test',
                'Date Ordered',
                'Details',
                'Microscopy',
                'Organism',
                'Sensitive Antibiotics',
                'Resistant Antibiotics'
            ]
        }
        return _.map(
            _.reject(
                column.fields,
                function(c){
                    if(_.contains(NOT_ADVANCED_SEARCHABLE, c.name)){
                        return true;
                    }
                    return c.type == 'token' ||  c.type ==  'list';
                }),
            function(c){ return underscoreToCapWords(c.name); }
        ).sort();
    };

    $scope.isType = function(column, field, type){
        if(!column || !field){
            return false;
        }
        var col = _.find(
            $scope.columns,
            function(item){
                return item.name == column.toLowerCase().replace( / /g,  '_')
            });
        var theField =  _.find(
            col.fields,
            function(f){
                return f.name == field.toLowerCase().replace( / /g,  '_')
            });
        if(!theField){ return false }
        if (_.isArray(type)){
            var match = false;
            _.each(type, function(t){ if(t == theField.type){ match = true} });
            return match;
        }else{
            return theField.type == type;
        }
    };

    $scope.isBoolean = function(column, field){
        return $scope.isType(column, field, ["boolean", "null_boolean"]);
    };

    $scope.isText = function(column, field){
        return $scope.isType(column, field, "string") || $scope.isType(column, field, "text");
    }

    $scope.isSelect = function(column, field){
        return $scope.isType(column, field, "many_to_many");
    };

    $scope.isDate = function(column, field){
        return $scope.isType(column, field, "date");
    };

    $scope.addFilter = function(){
        $scope.criteria.push(_.clone($scope.model));
    };

    $scope.removeFilter = function(index){
        if($scope.criteria.length == 1){
            $scope.removeCriteria();
        }
        else{
            $scope.criteria.splice(index, 1);
        }
    };

    $scope.resetFilter = function(query){
      // when we change the column, reset the rest of the query
      _.each(query, function(v, k){
        if(k !== 'column' && k in $scope.model){
          query[k] = $scope.model[k];
        }
      });
    };

    $scope.removeCriteria = function(){
        $scope.criteria = [_.clone($scope.model)];
    };

    //
    // Determine the appropriate lookup list for this field if
    // one exists.
    //
    $scope._lookuplist_watch = function(){
        _.map($scope.criteria, function(c){
            var column = _.findWhere($scope.columns, {name: c.column});
            if(!column){return;}
            if(!c.field){return;}
            var field = _.findWhere(
                column.fields, {name: c.field.toLowerCase().replace(/ /g, '_')});
            if(!field){return; }
            if(field.lookup_list){
                c.lookup_list = $scope[field.lookup_list + '_list'];
            }
        });
        $scope.async_waiting = false;
        $scope.async_ready = false;
        $scope.searched = false;
        $scope.results = [];
    }

    $scope.$watch('criteria', $scope._lookuplist_watch, true);

    $scope.search = function(pageNumber){
        if(!pageNumber){
            pageNumber = 1;
        }

        var queryParams = $scope.completeCriteria();

        if(queryParams.length){
            queryParams[0].page_number = pageNumber;
            ngProgressLite.set(0);
            ngProgressLite.start();
            $http.post('/search/extract/', queryParams).success(
                function(response){
                    $scope.results = _.map(response.object_list, function(o){
                        return new PatientSummary(o);
                    });
                    $scope.searched = true;
                    $scope.paginator = new Paginator($scope.search, response);
                    ngProgressLite.done();
                }).error(function(e){
                    ngProgressLite.set(0);
                    $window.alert('ERROR: Could not process this search. Please report it to the OPAL team');
                });
        }
        else{
          $scope.searched = true;
        }
    };

    $scope.async_extract = function(){
        if($scope.async_ready){
            $window.open('/search/extract/download/' + $scope.extract_id, '_blank');
            return null;
        }
        if($scope.async_waiting){
            return null;
        }

        var ping_until_success = function(){
            if(!$scope.extract_id){
                $timeout(ping_until_success, 1000);
                return;
            }
            $http.get('/search/extract/result/'+ $scope.extract_id).then(function(result){
                if(result.data.state == 'FAILURE'){
                    $window.alert('FAILURE');
                    $scope.async_waiting = false;
                    return;
                }
                if(result.data.state == 'SUCCESS'){
                    $scope.async_ready = true;
                }else{
                    if($scope.async_waiting){
                        $timeout(ping_until_success, 1000);
                    }
                }
            });
        }
        $scope.async_waiting = true;
        $http.post(
            '/search/extract/download',
            {criteria: JSON.stringify($scope.criteria)}
        ).then(function(result){
            $scope.extract_id = result.data.extract_id;
            ping_until_success();
        });
    };

    $scope.jumpToFilter = function($event, filter){
        $event.preventDefault();
        $scope.criteria = filter.criteria;
    };

    $scope.editFilter = function($event, filter, $index){
      $event.preventDefault();
      var modal = $modal.open({
        templateUrl: '/search/templates/modals/save_filter_modal.html/',
        controller: 'SaveFilterCtrl',
        resolve: {
          params: function() { return $scope.filters[$index]; }
        }
      }).result.then(function(result){
        $scope.filters[$index] = result;
      });
    };

    $scope.save = function(){
      $modal.open({
        templateUrl: '/search/templates/modals/save_filter_modal.html/',
        controller: 'SaveFilterCtrl',
        resolve: {
          params: function() { return {name: null, criteria: $scope.completeCriteria()}; }
        }
      }).result.then(function(result){
        $scope.filters.push(result);
      });
    };

    $scope.jumpToEpisode = function(episode){
        window.open('#/episode/'+episode.id, '_blank');
    };

});
<|endoftext|>


<commit_before>const rewire = require('rewire');
const express = require('express');
const chai = require('chai');
const should = chai.should();
const chaiHttp = require('chai-http');
chai.use(chaiHttp);

describe('reddit-wallpapers-module', function() {
    var redditModule;
    var app;
    before(function(done) {
        app = express();
        redditModule = rewire('../modules/reddit-wallpapers-module/src/reddit.js');
        redditModule(app).then(() => {
            redditModule.__set__({
                settingsDir: './testsettings.json'
            })
            done();
        });
    });
    it('Should have all settings loaded', () => {
        var settings = redditModule.__get__('settings');
        settings.current.should.have.property('subreddits').and.not.be.empty;
        settings.current.should.have.property('refresh').and.not.be.empty;
        settings.current.should.have.property('links').and.not.be.empty;
        settings.current.should.have.property('checkUrls');
    });
    it('Should have meaningful values in current settings', () => {
        var settings = redditModule.__get__('settings');
        settings.current.refresh.should.be.above(0);
        settings.current.links.should.be.above(0);
    });
    it('Should be able to return new random wallpaper', () => {
        var getRandomWallpaper = redditModule.__get__('getRandomWallpaper');
        var wallUrl = getRandomWallpaper();
        wallUrl.should.have.property('url').and.not.be.empty;
        wallUrl.should.have.property('permalink').and.not.be.empty;
        wallUrl.should.have.property('subreddit').and.not.be.empty;
        wallUrl.should.have.property('title').and.not.be.empty;
    });
    it('Should be able to fetch wallpapers from single subreddit', () => {
        var getUrlsFromSubreddit = redditModule.__get__('getUrlsFromSubreddit')('EarthPorn');
        getUrlsFromSubreddit.then((urls) => {
            urls.should.have.length.above(0);
            urls.forEach((url) => {
                wallUrl.should.have.property('url').and.not.be.empty;
                wallUrl.should.have.property('permalink').and.not.be.empty;
                wallUrl.should.have.property('subreddit').and.not.be.empty;
                wallUrl.should.have.property('title').and.not.be.empty;
            });
        });
    });
    it('Should be able to fetch wallpaper from multiple subreddits', () => {
        redditModule.__with__({
            settings: {
                current: {
                    subreddits: ['EarthPorn', 'VillagePorn'],
                    refresh: 120,
                    links: 50,
                    checkUrls: false
                }
            }
        })(() => {
            var fetchURLs = redditModule.__get__('fetchURLs')();
            fetchURLs.then((urls) => {
                urls.forEach((url) => {
                    wallUrl.should.have.property('url').and.not.be.empty;
                    wallUrl.should.have.property('permalink').and.not.be.empty;
                    wallUrl.should.have.property('subreddit').and.not.be.empty;
                    wallUrl.should.have.property('title').and.not.be.empty;
                });
            });
        });
    });
    it('Should be able to send new wallpaper', (done) => {
        var fakeUrls = [{
            url: 'url1',
            permalink: 'perma1',
            subreddit: 'subreddit1',
            title: 'title1'
        }];
        redditModule.__set__({
            readyUrls: fakeUrls
        })
        chai.request(app)
            .get('/randomWallpaper')
            .end((err, res) => {
                res.should.have.status(200);
                res.body.should.have.property('wallUrl').and.equal(fakeUrls[0].url);
                res.body.should.have.property('info').and.not.be.empty;
                done();
            });
    });
    it('Should be able to set refresh', (done) => {
        chai.request(app)
            .post('/redditWallpaper/setRefresh')
            .set('content-type', 'application/x-www-form-urlencoded')
            .send({
                refresh: 420
            })
            .end((err, res) => {
                res.should.have.status(200);
                redditModule.__get__('settings').current.refresh.should.be.equal(420);
                done();
            });
    });
    it('Should be able to set number of links to fetch from subreddits', (done) => {
        chai.request(app)
            .post('/redditWallpaper/setLinks')
            .set('content-type', 'application/x-www-form-urlencoded')
            .send({
                links: 420
            })
            .end((err, res) => {
                res.should.have.status(200);
                redditModule.__get__('settings').current.links.should.be.equal(420);
                done();
            });
    });
    it('Should be able to set subreddits', (done) => {
        chai.request(app)
            .post('/redditWallpaper/setSubreddits')
            .set('content-type', 'application/x-www-form-urlencoded')
            .send({
                subs: JSON.stringify(['reddit1', 'reddit2'])
            })
            .end((err, res) => {
                res.should.have.status(200);
                redditModule.__get__('settings').current.subreddits.should.be.eql(['reddit1', 'reddit2']);
                done();
            });
    });
});
<commit_msg>Changed test settings directory<commit_after>const rewire = require('rewire');
const express = require('express');
const chai = require('chai');
const should = chai.should();
const chaiHttp = require('chai-http');
chai.use(chaiHttp);

describe('reddit-wallpapers-module', function() {
    var redditModule;
    var app;
    before(function(done) {
        app = express();
        redditModule = rewire('../modules/reddit-wallpapers-module/src/reddit.js');
        redditModule(app).then(() => {
            redditModule.__set__({
                settingsDir: './reddittestsettings.json'
            })
            done();
        });
    });
    it('Should have all settings loaded', () => {
        var settings = redditModule.__get__('settings');
        settings.current.should.have.property('subreddits').and.not.be.empty;
        settings.current.should.have.property('refresh').and.not.be.empty;
        settings.current.should.have.property('links').and.not.be.empty;
        settings.current.should.have.property('checkUrls');
    });
    it('Should have meaningful values in current settings', () => {
        var settings = redditModule.__get__('settings');
        settings.current.refresh.should.be.above(0);
        settings.current.links.should.be.above(0);
    });
    it('Should be able to return new random wallpaper', () => {
        var getRandomWallpaper = redditModule.__get__('getRandomWallpaper');
        var wallUrl = getRandomWallpaper();
        wallUrl.should.have.property('url').and.not.be.empty;
        wallUrl.should.have.property('permalink').and.not.be.empty;
        wallUrl.should.have.property('subreddit').and.not.be.empty;
        wallUrl.should.have.property('title').and.not.be.empty;
    });
    it('Should be able to fetch wallpapers from single subreddit', () => {
        var getUrlsFromSubreddit = redditModule.__get__('getUrlsFromSubreddit')('EarthPorn');
        getUrlsFromSubreddit.then((urls) => {
            urls.should.have.length.above(0);
            urls.forEach((url) => {
                wallUrl.should.have.property('url').and.not.be.empty;
                wallUrl.should.have.property('permalink').and.not.be.empty;
                wallUrl.should.have.property('subreddit').and.not.be.empty;
                wallUrl.should.have.property('title').and.not.be.empty;
            });
        });
    });
    it('Should be able to fetch wallpaper from multiple subreddits', () => {
        redditModule.__with__({
            settings: {
                current: {
                    subreddits: ['EarthPorn', 'VillagePorn'],
                    refresh: 120,
                    links: 50,
                    checkUrls: false
                }
            }
        })(() => {
            var fetchURLs = redditModule.__get__('fetchURLs')();
            fetchURLs.then((urls) => {
                urls.forEach((url) => {
                    wallUrl.should.have.property('url').and.not.be.empty;
                    wallUrl.should.have.property('permalink').and.not.be.empty;
                    wallUrl.should.have.property('subreddit').and.not.be.empty;
                    wallUrl.should.have.property('title').and.not.be.empty;
                });
            });
        });
    });
    it('Should be able to send new wallpaper', (done) => {
        var fakeUrls = [{
            url: 'url1',
            permalink: 'perma1',
            subreddit: 'subreddit1',
            title: 'title1'
        }];
        redditModule.__set__({
            readyUrls: fakeUrls
        })
        chai.request(app)
            .get('/randomWallpaper')
            .end((err, res) => {
                res.should.have.status(200);
                res.body.should.have.property('wallUrl').and.equal(fakeUrls[0].url);
                res.body.should.have.property('info').and.not.be.empty;
                done();
            });
    });
    it('Should be able to set refresh', (done) => {
        chai.request(app)
            .post('/redditWallpaper/setRefresh')
            .set('content-type', 'application/x-www-form-urlencoded')
            .send({
                refresh: 420
            })
            .end((err, res) => {
                res.should.have.status(200);
                redditModule.__get__('settings').current.refresh.should.be.equal(420);
                done();
            });
    });
    it('Should be able to set number of links to fetch from subreddits', (done) => {
        chai.request(app)
            .post('/redditWallpaper/setLinks')
            .set('content-type', 'application/x-www-form-urlencoded')
            .send({
                links: 420
            })
            .end((err, res) => {
                res.should.have.status(200);
                redditModule.__get__('settings').current.links.should.be.equal(420);
                done();
            });
    });
    it('Should be able to set subreddits', (done) => {
        chai.request(app)
            .post('/redditWallpaper/setSubreddits')
            .set('content-type', 'application/x-www-form-urlencoded')
            .send({
                subs: JSON.stringify(['reddit1', 'reddit2'])
            })
            .end((err, res) => {
                res.should.have.status(200);
                redditModule.__get__('settings').current.subreddits.should.be.eql(['reddit1', 'reddit2']);
                done();
            });
    });
});
<|endoftext|>


<commit_before>/*
 * Licensed to Cloudkick, Inc ('Cloudkick') under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * Cloudkick licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var sys = require('sys');
var fs = require('fs');
var path = require('path');
var exec = require('child_process').exec;
var ps = require('util/pubsub');
var misc = require('util/misc');
var async = require('extern/async');

var BASE_TEMPLATE;

var runit;

function getServer()
{
  return require('services/http')._serverOnly();
}

// For now these need to all be in the same test, this blows
exports["service management"] = function(assert, beforeExit) {
  var n = 0;
  var tasks = [];
  var svcdir = new runit.RunitServiceDirectory('.tests/services');

  // Add a bunch of tasks
  // These all happen serially in the order they are added

  // Make sure the list call works and returns an empty array
  tasks.push(function(callback) {
    assert.response(getServer(), {
      url: '/services/',
      method: 'GET'
    },
    function(res) {
      n++;
      try {
        assert.equal(res.statusCode, 200);
        var data = JSON.parse(res.body);
        assert.ok(data instanceof Array);
        assert.equal(data.length, 0);
      }
      catch (err) {
        return callback(err);
      }
      return callback();
    });
  });

  // Create a basic services layout
  tasks.push(function(callback) {
    svcdir.create_service_layout('foo', BASE_TEMPLATE, function(err) {
      n++;
      if (err) {
        return callback(err);
      }
      return callback();
    });
  });

  tasks.push(function(callback) {
    var fakerun_path = path.join(__dirname, 'fake_service', 'run');
    exec('cp "' + fakerun_path + '" .tests/services/available/foo/run', function(err) {
      n++;
      if (err) {
        return callback(err);
      }
      return callback();
    });
  });

  tasks.push(function(callback) {
    assert.response(getServer(), {
      url: '/services/',
      method: 'GET'
    },
    function(res) {
      n++;
      try {
        assert.equal(res.statusCode, 200);
        var data = JSON.parse(res.body);
        assert.ok(data instanceof Array);
        assert.equal(data.length, 1);
      }
      catch (err) {
        return callback(err);
      }
      return callback();
    });
  });

  tasks.push(function(callback) {
    assert.response(getServer(), {
      url: '/services/foo/',
      method: 'GET'
    },
    function(res) {
      n++;
      try {
        assert.equal(res.statusCode, 200);
        var data = JSON.parse(res.body);
        assert.ok(data instanceof Object);
        assert.equal(data.name, "foo");
        assert.equal(data.enabled, false);
        assert.equal(data.normally, "down");
      }
      catch (err) {
        return callback(err);
      }
      return callback();
    });
  });

  tasks.push(function(callback) {
    assert.response(getServer(), {
      url: '/services/bar/',
      method: 'GET'
    },
    function(res) {
      n++;
      try {
        assert.equal(res.statusCode, 404);
      }
      catch (err) {
        return callback(err);
      }
      return callback();
    });
  });

  tasks.push(function(callback) {
    assert.response(getServer(), {
      url: '/services/foo/restart/',
      method: 'PUT'
    },
    function(res) {
      n++;
      try {
        assert.equal(res.statusCode, 500);
        var data = JSON.parse(res.body);
        assert.ok(data instanceof Object);
        assert.equal(data.code, 500);
        assert.ok(data.message);
      }
      catch (err) {
        return callback(err);
      }
      return callback();
    });
  });

  tasks.push(function(callback) {
    assert.response(getServer(), {
      url: '/services/foo/enable/',
      method: 'PUT'
    },
    function(res) {
      n++;
      try {
        assert.equal(res.statusCode, 200);
      }
      catch (err) {
        callback(err);
      }
      return callback();
    });
  });

  tasks.push(function(callback) {
    assert.response(getServer(), {
      url: '/services/foo/',
      method: 'GET'
    },
    function(res) {
      n++;
      try {
        assert.equal(res.statusCode, 200);
        var data = JSON.parse(res.body);
        assert.ok(data instanceof Object);
        assert.equal(data.name, "foo");
        assert.equal(data.enabled, true);
        assert.equal(data.normally, "down");
      }
      catch (err) {
        return callback(err);
      }
      return callback();
    });
  });

  // We have to wait (at most) 5 seconds for runit to poll
  tasks.push(function(callback) {
    setTimeout(callback, 5000);
  });

  tasks.push(function(callback) {
    assert.response(getServer(), {
      url: '/services/foo/',
      method: 'GET'
    },
    function(res) {
      n++;
      try {
        assert.equal(res.statusCode, 200);
        var data = JSON.parse(res.body);
        assert.ok(data instanceof Object);
        assert.equal(data.name, "foo");
        assert.equal(data.enabled, true);
        assert.equal(data.normally, "down");
        var sstatus = data.status;
        assert.isDefined(sstatus);
        assert.isDefined(sstatus.time);
        assert.isDefined(sstatus.pid);
        assert.isDefined(sstatus.paused);
        assert.isDefined(sstatus.term);
        assert.isDefined(sstatus.state);
      }
      catch (err) {
        return callback(err);
      }
      return callback();
    });
  });

  tasks.push(function(callback) {
    assert.response(getServer(), {
      url: '/services/foo/stop/',
      method: 'PUT'
    },
    function(res) {
      n++;
      try {
        assert.equal(res.statusCode, 200);
      }
      catch (err) {
        callback(err);
      }
      return callback();
    });
  });

  tasks.push(function(callback) {
    assert.response(getServer(), {
      url: '/services/foo/start/',
      method: 'PUT'
    },
    function(res) {
      n++;
      try {
        assert.equal(res.statusCode, 200);
      }
      catch (err) {
        callback(err);
      }
      return callback();
    });
  });

  tasks.push(function(callback) {
    assert.response(getServer(), {
      url: '/services/foo/restart/',
      method: 'PUT'
    },
    function(res) {
      n++;
      try {
        assert.equal(res.statusCode, 200);
      }
      catch (err) {
        callback(err);
      }
      return callback();
    });
  });

  tasks.push(function(callback) {
    assert.response(getServer(), {
      url: '/services/bar/restart/',
      method: 'PUT'
    },
    function(res) {
      n++;
      try {
        assert.equal(res.statusCode, 404);
      }
      catch (err) {
        callback(err);
      }
      return callback();
    });
  });

  // We have to stop this to make expresso decide to exit
  tasks.push(function(callback) {
    assert.response(getServer(), {
      url: '/services/foo/stop/',
      method: 'PUT'
    },
    function(res) {
      n++;
      try {
        assert.equal(res.statusCode, 200);
      }
      catch (err) {
        callback(err);
      }
      return callback();
    });
  });

  tasks.push(function(callback) {
    assert.response(getServer(), {
      url: '/services/foo/disable/',
      method: 'PUT'
    },
    function(res) {
      n++;
      try {
        assert.equal(res.statusCode, 200);
      }
      catch (err) {
        callback(err);
      }
      return callback();
    });
  });

  tasks.push(function(callback) {
    path.exists('.tests/services/enabled/foo', function(exists) {
      n++;
      try {
        assert.ok(!exists);
      }
      catch (err) {
        callback(err);
      }
      return callback();
    });
  });

  // Execute the tasks
  async.series(tasks, function(err) {
    ps.emit(ps.AGENT_STATE_STOP);
    assert.ifError(err);
  });

  beforeExit(function(){
    assert.equal(17, n, 'Tests Completed');
  });
};

exports.setup = function(done) {
  async.series([
    async.apply(ps.ensure, "config"),
    async.apply(exec, "mkdir .tests/services"),
    async.apply(exec, "mkdir .tests/services/available"),
    async.apply(exec, "mkdir .tests/services/enabled"),
    function(callback) {
      BASE_TEMPLATE = require('runit/templates/base').BASE_TEMPLATE;
      runit = require('runit/services');
      require('services/runit').load();
      ps.emit(ps.AGENT_STATE_START);
      callback();
    },
    async.apply(ps.ensure, "cast.agent.services.runit.started")
  ],
  done);
};
<commit_msg>Add test for get_application_template<commit_after>/*
 * Licensed to Cloudkick, Inc ('Cloudkick') under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * Cloudkick licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

var sys = require('sys');
var fs = require('fs');
var path = require('path');
var exec = require('child_process').exec;
var ps = require('util/pubsub');
var misc = require('util/misc');
var async = require('extern/async');

var runit_templates;
var BASE_TEMPLATE;

var runit;

function getServer()
{
  return require('services/http')._serverOnly();
}

// For now these need to all be in the same test, this blows
exports["service management"] = function(assert, beforeExit) {
  var n = 0;
  var tasks = [];
  var svcdir = new runit.RunitServiceDirectory('.tests/services');

  // Add a bunch of tasks
  // These all happen serially in the order they are added

  // Make sure the list call works and returns an empty array
  tasks.push(function(callback) {
    assert.response(getServer(), {
      url: '/services/',
      method: 'GET'
    },
    function(res) {
      n++;
      try {
        assert.equal(res.statusCode, 200);
        var data = JSON.parse(res.body);
        assert.ok(data instanceof Array);
        assert.equal(data.length, 0);
      }
      catch (err) {
        return callback(err);
      }
      return callback();
    });
  });

  // Create a basic services layout
  tasks.push(function(callback) {
    svcdir.create_service_layout('foo', BASE_TEMPLATE, function(err) {
      n++;
      if (err) {
        return callback(err);
      }
      return callback();
    });
  });

  tasks.push(function(callback) {
    var fakerun_path = path.join(__dirname, 'fake_service', 'run');
    exec('cp "' + fakerun_path + '" .tests/services/available/foo/run', function(err) {
      n++;
      if (err) {
        return callback(err);
      }
      return callback();
    });
  });

  tasks.push(function(callback) {
    assert.response(getServer(), {
      url: '/services/',
      method: 'GET'
    },
    function(res) {
      n++;
      try {
        assert.equal(res.statusCode, 200);
        var data = JSON.parse(res.body);
        assert.ok(data instanceof Array);
        assert.equal(data.length, 1);
      }
      catch (err) {
        return callback(err);
      }
      return callback();
    });
  });

  tasks.push(function(callback) {
    assert.response(getServer(), {
      url: '/services/foo/',
      method: 'GET'
    },
    function(res) {
      n++;
      try {
        assert.equal(res.statusCode, 200);
        var data = JSON.parse(res.body);
        assert.ok(data instanceof Object);
        assert.equal(data.name, "foo");
        assert.equal(data.enabled, false);
        assert.equal(data.normally, "down");
      }
      catch (err) {
        return callback(err);
      }
      return callback();
    });
  });

  tasks.push(function(callback) {
    assert.response(getServer(), {
      url: '/services/bar/',
      method: 'GET'
    },
    function(res) {
      n++;
      try {
        assert.equal(res.statusCode, 404);
      }
      catch (err) {
        return callback(err);
      }
      return callback();
    });
  });

  tasks.push(function(callback) {
    assert.response(getServer(), {
      url: '/services/foo/restart/',
      method: 'PUT'
    },
    function(res) {
      n++;
      try {
        assert.equal(res.statusCode, 500);
        var data = JSON.parse(res.body);
        assert.ok(data instanceof Object);
        assert.equal(data.code, 500);
        assert.ok(data.message);
      }
      catch (err) {
        return callback(err);
      }
      return callback();
    });
  });

  tasks.push(function(callback) {
    assert.response(getServer(), {
      url: '/services/foo/enable/',
      method: 'PUT'
    },
    function(res) {
      n++;
      try {
        assert.equal(res.statusCode, 200);
      }
      catch (err) {
        callback(err);
      }
      return callback();
    });
  });

  tasks.push(function(callback) {
    assert.response(getServer(), {
      url: '/services/foo/',
      method: 'GET'
    },
    function(res) {
      n++;
      try {
        assert.equal(res.statusCode, 200);
        var data = JSON.parse(res.body);
        assert.ok(data instanceof Object);
        assert.equal(data.name, "foo");
        assert.equal(data.enabled, true);
        assert.equal(data.normally, "down");
      }
      catch (err) {
        return callback(err);
      }
      return callback();
    });
  });

  // We have to wait (at most) 5 seconds for runit to poll
  tasks.push(function(callback) {
    setTimeout(callback, 5000);
  });

  tasks.push(function(callback) {
    assert.response(getServer(), {
      url: '/services/foo/',
      method: 'GET'
    },
    function(res) {
      n++;
      try {
        assert.equal(res.statusCode, 200);
        var data = JSON.parse(res.body);
        assert.ok(data instanceof Object);
        assert.equal(data.name, "foo");
        assert.equal(data.enabled, true);
        assert.equal(data.normally, "down");
        var sstatus = data.status;
        assert.isDefined(sstatus);
        assert.isDefined(sstatus.time);
        assert.isDefined(sstatus.pid);
        assert.isDefined(sstatus.paused);
        assert.isDefined(sstatus.term);
        assert.isDefined(sstatus.state);
      }
      catch (err) {
        return callback(err);
      }
      return callback();
    });
  });

  tasks.push(function(callback) {
    assert.response(getServer(), {
      url: '/services/foo/stop/',
      method: 'PUT'
    },
    function(res) {
      n++;
      try {
        assert.equal(res.statusCode, 200);
      }
      catch (err) {
        callback(err);
      }
      return callback();
    });
  });

  tasks.push(function(callback) {
    assert.response(getServer(), {
      url: '/services/foo/start/',
      method: 'PUT'
    },
    function(res) {
      n++;
      try {
        assert.equal(res.statusCode, 200);
      }
      catch (err) {
        callback(err);
      }
      return callback();
    });
  });

  tasks.push(function(callback) {
    assert.response(getServer(), {
      url: '/services/foo/restart/',
      method: 'PUT'
    },
    function(res) {
      n++;
      try {
        assert.equal(res.statusCode, 200);
      }
      catch (err) {
        callback(err);
      }
      return callback();
    });
  });

  tasks.push(function(callback) {
    assert.response(getServer(), {
      url: '/services/bar/restart/',
      method: 'PUT'
    },
    function(res) {
      n++;
      try {
        assert.equal(res.statusCode, 404);
      }
      catch (err) {
        callback(err);
      }
      return callback();
    });
  });

  // We have to stop this to make expresso decide to exit
  tasks.push(function(callback) {
    assert.response(getServer(), {
      url: '/services/foo/stop/',
      method: 'PUT'
    },
    function(res) {
      n++;
      try {
        assert.equal(res.statusCode, 200);
      }
      catch (err) {
        callback(err);
      }
      return callback();
    });
  });

  tasks.push(function(callback) {
    assert.response(getServer(), {
      url: '/services/foo/disable/',
      method: 'PUT'
    },
    function(res) {
      n++;
      try {
        assert.equal(res.statusCode, 200);
      }
      catch (err) {
        callback(err);
      }
      return callback();
    });
  });

  tasks.push(function(callback) {
    path.exists('.tests/services/enabled/foo', function(exists) {
      n++;
      try {
        assert.ok(!exists);
      }
      catch (err) {
        callback(err);
      }
      return callback();
    });
  });

  // Execute the tasks
  async.series(tasks, function(err) {
    ps.emit(ps.AGENT_STATE_STOP);
    assert.ifError(err);
  });

  beforeExit(function(){
    assert.equal(17, n, 'Tests Completed');
  });
};

exports['test get application template'] = function(assert, beforeExit) {
  var n = 0;
  runit_templates.get_application_template('test instance', '/path/to/instance', 'entry.js', 'unknownapplicationtype', function(error, template) {
    n++;

    assert.notEqual(error, undefined);
    assert.match(error.message, /invalid application type/i);
  });

  runit_templates.get_application_template('test instance', '/path/to/instance', 'entry.js', 'nodejs', function(error, template) {
    n++;

    assert.equal(error, undefined);
    assert.isDefined(template.run);
    assert.isDefined(template.finish);
    assert.isDefined(template.down);
    assert.isDefined(template.log.run);
    assert.isDefined(template.log.config);
    assert.isDefined(template.log.main);
  });
};

exports.setup = function(done) {
  async.series([
    async.apply(ps.ensure, "config"),
    async.apply(exec, "mkdir .tests/services"),
    async.apply(exec, "mkdir .tests/services/available"),
    async.apply(exec, "mkdir .tests/services/enabled"),
    function(callback) {
      runit_templates = require('runit/templates/base');
      BASE_TEMPLATE = runit_templates.BASE_TEMPLATE;
      runit = require('runit/services');
      require('services/runit').load();
      ps.emit(ps.AGENT_STATE_START);
      callback();
    },
    async.apply(ps.ensure, "cast.agent.services.runit.started")
  ],
  done);
};
<|endoftext|>