<commit_before>/* eslint react/no-danger: 0 */

import React, { Component, PropTypes } from 'react';
import { Link } from 'react-router';
import moment from 'moment';
import currentUserProps from "../prop-types/current_user_props";

// Note, acceptable type strings are: response_set, question, form, survey
export default class SearchResult extends Component {
  render() {
    return (this.baseResult(this.props.type,
                            this.props.result.Source,
                            this.props.result.highlight,
                            this.props.handleSelectSearchResult,
                            this.props.extraActionName,
                            this.props.extraAction));
  }

  isRevisable(source) {
    // Needs concept of source.mostRecent === source.version
    // Currently no way to do this in ES schema
    return source.status === 'published' &&
      (source.createdById || source.createdBy.id) === this.props.currentUser.id;
  }

  isEditable(source) {
    // Needs concept of source.mostRecent === source.version
    return source.status === 'draft' &&
      (source.createdById || source.createdBy.id) === this.props.currentUser.id;
  }

  isExtendable(source) {
    return source.status === 'published';
  }

  resultDropdownMenu(result, type, extraActionName, extraAction) {
    type = type.replace('_s','S');
    return (

        {this.isRevisable(result) &&

          <Link to={`/${type}s/${result.id}/revise`}>Revise</Link>

}
        {this.isEditable(result) &&

          <Link to={`/${type}s/${result.id}/edit`}>Edit</Link>

}
        {this.isExtendable(result) &&

          <Link to={`/${type}s/${result.id}/extend`}>Extend</Link>

}

          <Link to={`/${type}s/${result.id}`}>Details</Link>

        {extraActionName && extraAction &&

      <a className="menu-action" id={`action_for_${result.id}`} onClick={() => extraAction()}>
        {extraActionName}

}

    );
  }

  resultStatus(status) {
    if(status === 'published') {
      return(

published

      );
    } else if (status === 'draft') {
      return(

draft

      );
    }
  }

  programsInfo(result) {
    return (

        {result.programsCount}

programs

    );
  }

  systemsInfo(result) {
    return (

        {result.systemsCount}

systems

    );
  }

  selectResultButton(result, handleSelectSearchResult) {
    return (
      <a title="Select Search Result" href="#" id={`select-${result.name}`} onClick={(e) => {
        e.preventDefault();
        handleSelectSearchResult(result);
      }}>
    );
  }

  linkedDetails(result, type){
    switch(type) {
      case 'question':
        return (

<a className="panel-toggle" data-toggle="collapse" href={`#collapse-${result.id}-question`}>Linked Response Sets: {result.responseSets && result.responseSets.length}

        );
      case 'responseSet':
        return (

<a className="panel-toggle" data-toggle="collapse" href={`#collapse-${result.id}-rs`}>Responses: {result.codes && result.codes.length}

        );
      case 'form':
        return (

<a className="panel-toggle" data-toggle="collapse" href={`#collapse-${result.id}-form`}>Questions: {result.questions && result.questions.length}

        );
      case 'survey':
        return (

<a className="panel-toggle" data-toggle="collapse" href={`#collapse-${result.id}-survey`}>Forms: {result.forms && result.forms.length}

        );
    }
  }

  detailsPanel(result, type){
    switch(type) {
      case 'question':
        return (
          <div className="panel-collapse panel-details collapse" id={`collapse-${result.id}-question`}>

              {result.responseSets && result.responseSets.length > 0 &&
                result.responseSets.map((rs, i) => {
                  return(
                    <div key={`response-set-${rs.id}-${i}`} className="result-details-content">
                      <Link to={`/responseSets/${rs.id}`}>{rs.name}</Link>

                  );
                })
              }

        );
      case 'responseSet':
        return (
          <div className="panel-collapse panel-details collapse" id={`collapse-${result.id}-rs`}>

              {result.codes && result.codes.length > 0 &&
                result.codes.map((c, i) => {
                  return(
                    <div key={`response-${c.id}-${i}`} className="result-details-content">
                      {`${i+1}. ${c.displayName ? c.displayName : c.code}`}

                  );
                })
              }

        );
      case 'form':
        return (
          <div className="panel-collapse panel-details collapse" id={`collapse-${result.id}-form`}>

              {result.questions && result.questions.length > 0 &&
                result.questions.map((q, i) => {
                  return(
                    <div key={`question-${q.id}-${i}`} className="result-details-content">
                      <text>
                        <Link to={`/questions/${q.id}`}> {q.name}</Link>
                      </text>

                  );
                })
              }

        );
      case 'survey':
        return (
          <div className="panel-collapse panel-details collapse" id={`collapse-${result.id}-survey`}>

              {result.forms && result.forms.length > 0 &&
                result.forms.map((f, i) => {
                  return(
                    <div key={`form-${f.id}-${i}`} className="result-details-content">
                      <Link to={`/forms/${f.id}`}>{f.name}</Link>

                  );
                })
              }

        );
    }
  }

  baseResult(type, result, highlight, handleSelectSearchResult, actionName, action) {
    const iconMap = {'response_set': 'fa-list', 'question': 'fa-tasks', 'form': 'fa-clipboard', 'survey': 'fa-clipboard'};
    return (

        <div className="u-result" id={`${type}_id_${result.id}`}>

                <div className={`u-result-details result__${type}`}>

<span className={`fa ${iconMap[type]} fa-2x`} aria-hidden="true">

                        <Link to={`/${type.replace('_s','S')}s/${result.id}`}>
                          {highlight && highlight.name ? <text dangerouslySetInnerHTML={{__html: highlight.name[0]}} /> : result.name}
                        </Link>

                    {highlight && highlight.description ? <text dangerouslySetInnerHTML={{__html: highlight.description[0]}} /> : result.description}

                      {result.programsCount && this.programsInfo(result)}
                      {result.systemsCount && this.systemsInfo(result)}
                      {result.status && this.resultStatus(result.status)}

{ moment(result.createdAt,'').format('MMMM Do, YYYY') }

version {result.version && result.version} | {type}

                  {this.linkedDetails(result, type)}

<Link to={`/${type.replace('_s','S')}s/${result.id}`}></Link>

                  {handleSelectSearchResult ? (
                    this.selectResultButton(result, handleSelectSearchResult)
                  ) : (

                      <a id={`${type}_${result.id}_menu`} className="dropdown-toggle" type="" data-toggle="dropdown">

                      {this.resultDropdownMenu(result, type, actionName, action)}

                  )}

          {this.detailsPanel(result, type)}

    );
  }

}

SearchResult.propTypes = {
  type: PropTypes.string,
  currentUser: currentUserProps,
  result: PropTypes.object.isRequired,
  handleSelectSearchResult: PropTypes.func,
  extraActionName: PropTypes.string,
  extraAction: PropTypes.func
};
<commit_msg>Fixing response set collapsible panel<commit_after>/* eslint react/no-danger: 0 */

import React, { Component, PropTypes } from 'react';
import { Link } from 'react-router';
import moment from 'moment';
import currentUserProps from "../prop-types/current_user_props";

// Note, acceptable type strings are: response_set, question, form, survey
export default class SearchResult extends Component {
  render() {
    return (this.baseResult(this.props.type,
                            this.props.result.Source,
                            this.props.result.highlight,
                            this.props.handleSelectSearchResult,
                            this.props.extraActionName,
                            this.props.extraAction));
  }

  isRevisable(source) {
    // Needs concept of source.mostRecent === source.version
    // Currently no way to do this in ES schema
    return source.status === 'published' &&
      (source.createdById || source.createdBy.id) === this.props.currentUser.id;
  }

  isEditable(source) {
    // Needs concept of source.mostRecent === source.version
    return source.status === 'draft' &&
      (source.createdById || source.createdBy.id) === this.props.currentUser.id;
  }

  isExtendable(source) {
    return source.status === 'published';
  }

  resultDropdownMenu(result, type, extraActionName, extraAction) {
    type = type.replace('_s','S');
    return (

        {this.isRevisable(result) &&

          <Link to={`/${type}s/${result.id}/revise`}>Revise</Link>

}
        {this.isEditable(result) &&

          <Link to={`/${type}s/${result.id}/edit`}>Edit</Link>

}
        {this.isExtendable(result) &&

          <Link to={`/${type}s/${result.id}/extend`}>Extend</Link>

}

          <Link to={`/${type}s/${result.id}`}>Details</Link>

        {extraActionName && extraAction &&

      <a className="menu-action" id={`action_for_${result.id}`} onClick={() => extraAction()}>
        {extraActionName}

}

    );
  }

  resultStatus(status) {
    if(status === 'published') {
      return(

published

      );
    } else if (status === 'draft') {
      return(

draft

      );
    }
  }

  programsInfo(result) {
    return (

        {result.programsCount}

programs

    );
  }

  systemsInfo(result) {
    return (

        {result.systemsCount}

systems

    );
  }

  selectResultButton(result, handleSelectSearchResult) {
    return (
      <a title="Select Search Result" href="#" id={`select-${result.name}`} onClick={(e) => {
        e.preventDefault();
        handleSelectSearchResult(result);
      }}>
    );
  }

  linkedDetails(result, type){
    switch(type) {
      case 'question':
        return (

<a className="panel-toggle" data-toggle="collapse" href={`#collapse-${result.id}-question`}>Linked Response Sets: {result.responseSets && result.responseSets.length}

        );
      case 'response_set':
        return (

<a className="panel-toggle" data-toggle="collapse" href={`#collapse-${result.id}-rs`}>Responses: {result.codes && result.codes.length}

        );
      case 'form':
        return (

<a className="panel-toggle" data-toggle="collapse" href={`#collapse-${result.id}-form`}>Questions: {result.questions && result.questions.length}

        );
      case 'survey':
        return (

<a className="panel-toggle" data-toggle="collapse" href={`#collapse-${result.id}-survey`}>Forms: {result.forms && result.forms.length}

        );
    }
  }

  detailsPanel(result, type){
    switch(type) {
      case 'question':
        return (
          <div className="panel-collapse panel-details collapse" id={`collapse-${result.id}-question`}>

              {result.responseSets && result.responseSets.length > 0 &&
                result.responseSets.map((rs, i) => {
                  return(
                    <div key={`response-set-${rs.id}-${i}`} className="result-details-content">
                      <Link to={`/responseSets/${rs.id}`}>{rs.name}</Link>

                  );
                })
              }

        );
      case 'response_set':
        return (
          <div className="panel-collapse panel-details collapse" id={`collapse-${result.id}-rs`}>

              {result.codes && result.codes.length > 0 &&
                result.codes.map((c, i) => {
                  return(
                    <div key={`response-${c.id}-${i}`} className="result-details-content">
                      {`${i+1}. ${c.displayName ? c.displayName : c.code}`}

                  );
                })
              }

        );
      case 'form':
        return (
          <div className="panel-collapse panel-details collapse" id={`collapse-${result.id}-form`}>

              {result.questions && result.questions.length > 0 &&
                result.questions.map((q, i) => {
                  return(
                    <div key={`question-${q.id}-${i}`} className="result-details-content">
                      <text>
                        <Link to={`/questions/${q.id}`}> {q.name}</Link>
                      </text>

                  );
                })
              }

        );
      case 'survey':
        return (
          <div className="panel-collapse panel-details collapse" id={`collapse-${result.id}-survey`}>

              {result.forms && result.forms.length > 0 &&
                result.forms.map((f, i) => {
                  return(
                    <div key={`form-${f.id}-${i}`} className="result-details-content">
                      <Link to={`/forms/${f.id}`}>{f.name}</Link>

                  );
                })
              }

        );
    }
  }

  baseResult(type, result, highlight, handleSelectSearchResult, actionName, action) {
    const iconMap = {'response_set': 'fa-list', 'question': 'fa-tasks', 'form': 'fa-clipboard', 'survey': 'fa-clipboard'};
    return (

        <div className="u-result" id={`${type}_id_${result.id}`}>

                <div className={`u-result-details result__${type}`}>

<span className={`fa ${iconMap[type]} fa-2x`} aria-hidden="true">

                        <Link to={`/${type.replace('_s','S')}s/${result.id}`}>
                          {highlight && highlight.name ? <text dangerouslySetInnerHTML={{__html: highlight.name[0]}} /> : result.name}
                        </Link>

                    {highlight && highlight.description ? <text dangerouslySetInnerHTML={{__html: highlight.description[0]}} /> : result.description}

                      {result.programsCount && this.programsInfo(result)}
                      {result.systemsCount && this.systemsInfo(result)}
                      {result.status && this.resultStatus(result.status)}

{ moment(result.createdAt,'').format('MMMM Do, YYYY') }

version {result.version && result.version} | {type}

                  {this.linkedDetails(result, type)}

<Link to={`/${type.replace('_s','S')}s/${result.id}`}></Link>

                  {handleSelectSearchResult ? (
                    this.selectResultButton(result, handleSelectSearchResult)
                  ) : (

                      <a id={`${type}_${result.id}_menu`} className="dropdown-toggle" type="" data-toggle="dropdown">

                      {this.resultDropdownMenu(result, type, actionName, action)}

                  )}

          {this.detailsPanel(result, type)}

    );
  }

}

SearchResult.propTypes = {
  type: PropTypes.string,
  currentUser: currentUserProps,
  result: PropTypes.object.isRequired,
  handleSelectSearchResult: PropTypes.func,
  extraActionName: PropTypes.string,
  extraAction: PropTypes.func
};
<|endoftext|>


<commit_before>#!/usr/bin/env node
'use strict';

var Q           = require('q'),
    fs          = require('fs'),
    http        = require('http'),
    https       = require('https'),
    prompt      = require('prompt'),
    checkUpdate = require('check-update'),
    pkg         = require('../package.json');

prompt.start();
prompt.message = '';
prompt.delimiter = '\"'.magenta;

var body = [];

var doRequest = function (protocol, url, partialBody, body, index, deferred) {
  protocol.get(url, function (res) {
    res.setEncoding('utf8');
    res.on('data', function (chunk) {
      partialBody += chunk;
    });
    res.on('end', function () {
      console.log(url + ' => √ Done'.green);
      body[index] += partialBody;
      deferred.resolve();
    });
  });
};

var getBody = function (url) {
  var deferred = Q.defer(),
      partialBody = '',
      index = body.length;

  body[index] = index === 0 ? 'Dump generated by chupa-cabra (version: ' + pkg.version +'): \n\n---- ' + url + ' ---- \n\n' : '\n\n---- ' + url + ' ---- \n\n';

  if (exports.isHttp(url)) {
    doRequest(http, url, partialBody, body, index, deferred);
  } else if (exports.isHttps(url)) {
    doRequest(https, url, partialBody, body, index, deferred);
  } else {
    url = exports.forceHttp(url);
    doRequest(http, url, partialBody, body, index, deferred);
  }

  return deferred.promise;
};

exports.generateLoop = function (from, to, by) {
  var result = [];
  for (var i = from; i <= to; i += by) {
    result.push(i);
  }

  return result;
};

var doLoop = function (from, to, by, url) {
  var originalUrl = url,
      promises = [],
      loop = exports.generateLoop(from, to, by);

  loop.forEach(function (n) {
    url = originalUrl.replace(/\[\d*,\d*,\d*\]/, n);
    promises.push(getBody(url));
  });

  return Q.allSettled(promises);
};

exports.validateURL = function (url) {
  try {
    return url.match(/(http(s)?:\/\/)?\w*(\.(\w)+)+(\W\d+)?(\/*\w*\W*)*/g)
      .toString().length == url.length;
  } catch (err) {
    return false;
  }
};

// TODO: Requests with intervals
// exports.timeout = function(seconds){

// };

exports.isHttp = function (url) {
  return url.match(/^http:\/\//) !== null;
};

exports.isHttps = function (url) {
  return url.match(/^https:\/\//) !== null;
};

exports.forceHttp = function (url) {
  return 'http://' + url;
};

var getExpression = function (url) {
  return url.match(/\[\d*,\d*,\d*\]/);
};

exports.expressionExists = function (url) {
  return getExpression(url) !== null;
};

var getLoop = function (url) {
  var result = getExpression(url).toString().replace(/\[|\]/g, '').split(',');
  result = [parseInt(result[0]), parseInt(result[1]), parseInt(result[2])];

  return result;
};

var questionsSequenceOne = [{
    name: 'url',
    description: 'Please, enter the URL endpoint you want to dump',
    required: true,
    message: 'Insert a valid URL.',
    conform: function(url){
      return exports.validateURL(url);
    }
  },
  // TODO: Requests with intervals
  // {
  //     name: 'interval',
  //     patterns: '[yYnN]',
  //     message: 'Choose Yes or No for the question.',
  //     description: 'Do you want the requisitions make intervals? (y/N)',
  //     default: 'N'
  // }
];

// TODO: Requests with intervals
// var questionsSequenceTwo = {
//   name: 'seconds',
//   description: 'Enter the interval in seconds',
//   default: 20
// };

var writeToFile = function (buffer) {
  fs.writeFile('dump_' + Date.parse(new Date()) + '.txt', buffer, function () {
    console.log('dump.txt generated succesfully!'.green);
  });
};

prompt.get(questionsSequenceOne, function (err, result) {
  if (result !== undefined) {
    var url = result.url,
        fullBody = '';

    checkUpdate({packageName: pkg.name, packageVersion: pkg.version, isCLI: true}, function (err, latestVersion, defaultMessage) {
        if (!err) {
          console.log(defaultMessage);
        }
    });

    if (exports.expressionExists(url)) {
      var loop = getLoop(url);

      // var loopArray = doLoop(loop[0], loop[1], loop[2], url).then(function () { --never used yet--
      doLoop(loop[0], loop[1], loop[2], url).then(function () {
        // var len = body.length; --never used yet--
        body.forEach(function (content) {
          fullBody += content;
        });

        writeToFile(fullBody);
        console.log('The loop was: '.green, loop);
      });
    } else {
      getBody(url).then(function () {
        writeToFile(body[0]);
      });
    }

    // TODO: Requests with intervals
    // if (result.interval.match(/[Yy]/))
    //   prompt.get(questionsSequenceTwo, function(err, result){
    //     var seconds = result.seconds;
    //   })
  }
});<commit_msg>fix: remove annoying characters #9<commit_after>#!/usr/bin/env node
'use strict';

var Q           = require('q'),
    fs          = require('fs'),
    http        = require('http'),
    https       = require('https'),
    prompt      = require('prompt'),
    checkUpdate = require('check-update'),
    pkg         = require('../package.json');

prompt.start();
prompt.message = '';
prompt.delimiter = '\"'.magenta;

var body = [];

var doRequest = function (protocol, url, partialBody, body, index, deferred) {
  protocol.get(url, function (res) {
    res.setEncoding('utf8');
    res.on('data', function (chunk) {
      partialBody += chunk;
    });
    res.on('end', function () {
      console.log(url + ' => √ Done'.green);
      body[index] += partialBody;
      deferred.resolve();
    });
  });
};

var getBody = function (url) {
  var deferred = Q.defer(),
      partialBody = '',
      index = body.length;

  body[index] = index === 0 ? 'Dump generated by chupa-cabra (version: ' + pkg.version +'): \n\n---- ' + url + ' ---- \n\n' : '\n\n---- ' + url + ' ---- \n\n';

  if (exports.isHttp(url)) {
    doRequest(http, url, partialBody, body, index, deferred);
  } else if (exports.isHttps(url)) {
    doRequest(https, url, partialBody, body, index, deferred);
  } else {
    url = exports.forceHttp(url);
    doRequest(http, url, partialBody, body, index, deferred);
  }

  return deferred.promise;
};

exports.generateLoop = function (from, to, by) {
  var result = [];
  for (var i = from; i <= to; i += by) {
    result.push(i);
  }

  return result;
};

var doLoop = function (from, to, by, url) {
  var originalUrl = url,
      promises = [],
      loop = exports.generateLoop(from, to, by);

  loop.forEach(function (n) {
    url = originalUrl.replace(/\[\d*,\d*,\d*\]/, n);
    promises.push(getBody(url));
  });

  return Q.allSettled(promises);
};

exports.validateURL = function (url) {
  try {
    return url.match(/(http(s)?:\/\/)?\w*(\.(\w)+)+(\W\d+)?(\/*\w*\W*)*/g)
      .toString().length == url.length;
  } catch (err) {
    return false;
  }
};

// TODO: Requests with intervals
// exports.timeout = function(seconds){

// };

exports.isHttp = function (url) {
  return url.match(/^http:\/\//) !== null;
};

exports.isHttps = function (url) {
  return url.match(/^https:\/\//) !== null;
};

exports.forceHttp = function (url) {
  return 'http://' + url;
};

var getExpression = function (url) {
  return url.match(/\[\d*,\d*,\d*\]/);
};

exports.expressionExists = function (url) {
  return getExpression(url) !== null;
};

var getLoop = function (url) {
  var result = getExpression(url).toString().replace(/\[|\]/g, '').split(',');
  result = [parseInt(result[0]), parseInt(result[1]), parseInt(result[2])];

  return result;
};

var questionsSequenceOne = [{
    name: 'url',
    description: 'Please, enter the URL endpoint you want to dump',
    required: true,
    message: 'Insert a valid URL.',
    conform: function(url){
      return exports.validateURL(url);
    }
  },
  // TODO: Requests with intervals
  // {
  //     name: 'interval',
  //     patterns: '[yYnN]',
  //     message: 'Choose Yes or No for the question.',
  //     description: 'Do you want the requisitions make intervals? (y/N)',
  //     default: 'N'
  // }
];

// TODO: Requests with intervals
// var questionsSequenceTwo = {
//   name: 'seconds',
//   description: 'Enter the interval in seconds',
//   default: 20
// };

var writeToFile = function (buffer) {
  fs.writeFile('dump_' + Date.parse(new Date()) + '.txt', buffer, function () {
    console.log('dump.txt generated succesfully!'.green);
  });
};

prompt.get(questionsSequenceOne, function (err, result) {
  if (result !== undefined) {
    var url = result.url,
        fullBody = '';

    checkUpdate({packageName: pkg.name, packageVersion: pkg.version, isCLI: true}, function (err, latestVersion, defaultMessage) {
        if (!err) {
          console.log(defaultMessage);
        }
    });

    if (exports.expressionExists(url)) {
      var loop = getLoop(url);

      // var loopArray = doLoop(loop[0], loop[1], loop[2], url).then(function () { --never used yet--
      doLoop(loop[0], loop[1], loop[2], url).then(function () {
        // var len = body.length; --never used yet--
        body.forEach(function (content) {
          fullBody += content;
        });

        writeToFile(fullBody);
        console.log('The loop was: '.green, loop);
      });
    } else {
      getBody(url).then(function () {
        writeToFile(body[0]);
      });
    }

    // TODO: Requests with intervals
    // if (result.interval.match(/[Yy]/))
    //   prompt.get(questionsSequenceTwo, function(err, result){
    //     var seconds = result.seconds;
    //   })
  }
});<|endoftext|>


<commit_before>import { test } from 'qunit';
import moduleForAcceptance from 'hospitalrun/tests/helpers/module-for-acceptance';
import runWithPouchDump from 'hospitalrun/tests/helpers/run-with-pouch-dump';
import select from 'hospitalrun/tests/helpers/select';
import { waitToAppear, waitToDisappear } from 'hospitalrun/tests/helpers/wait-to-appear';
import { authenticateUser } from 'hospitalrun/tests/helpers/authenticate-user';

function verifyPricingLists(path, includesPrices, excludesPrices, assert) {
  return runWithPouchDump('billing', async function() {
    await authenticateUser();
    await visit(path);
    assert.equal(currentURL(), path);
    includesPrices.forEach(function(priceName) {
      assert.equal(find(`.price-name:contains(${priceName})`).length, 1, `${priceName} displays`);
    });
    excludesPrices.forEach(function(priceName) {
      assert.equal(find(`.price-name:contains(${priceName})`).length, 0, `${priceName} is not present`);
    });
  });
}

moduleForAcceptance('Acceptance | pricing');

test('visiting /pricing', function(assert) {
  let includesPrices = [
    'Xray Hand',
    'Blood test',
    'Leg Casting',
    'Gauze pad'
  ];
  return verifyPricingLists('/pricing', includesPrices, [], assert);
});

test('visiting /pricing/imaging', function(assert) {
  let excludesPrices = [
    'Blood test',
    'Leg Casting',
    'Gauze pad'
  ];
  let includesPrices = [
    'Xray Hand'
  ];
  return verifyPricingLists('/pricing/imaging', includesPrices, excludesPrices, assert);

});

test('visiting /pricing/lab', function(assert) {
  let excludesPrices = [
    'Xray Hand',
    'Leg Casting',
    'Gauze pad'
  ];
  let includesPrices = [
    'Blood test'
  ];
  return verifyPricingLists('/pricing/lab', includesPrices, excludesPrices, assert);
});

test('visiting /pricing/procedure', function(assert) {
  let excludesPrices = [
    'Xray Hand',
    'Blood test',
    'Gauze pad'
  ];
  let includesPrices = [
    'Leg Casting'
  ];
  return verifyPricingLists('/pricing/procedure', includesPrices, excludesPrices, assert);
});

test('visiting /pricing/ward', function(assert) {
  let excludesPrices = [
    'Xray Hand',
    'Blood test',
    'Leg Casting'
  ];
  let includesPrices = [
    'Gauze pad'
  ];
  return verifyPricingLists('/pricing/ward', includesPrices, excludesPrices, assert);
});

test('create new price', function(assert) {
  return runWithPouchDump('billing', async function() {
    await authenticateUser();
    await visit('/pricing');
    await click('button:contains(+ new item)');
    assert.equal(currentURL(), '/pricing/edit/new');

    await fillIn('.price-name input', 'Xray Foot');
    await fillIn('.price-amount input', 100);
    await fillIn('.price-department input', 'Imaging');
    await select('.price-category', 'Imaging');
    await click('button:contains(Add):last');
    await waitToAppear('.modal-dialog');
    assert.dom('.modal-title').hasText('Pricing Item Saved', 'Pricing Item saved');

    await click('button:contains(Ok)');
    await click('button:contains(Add Override)');
    await waitToAppear('.modal-dialog');
    assert.dom('.modal-title').hasText('Add Override', 'Add Override Dialog displays');

    await select('.pricing-profile', 'Half off');
    await fillIn('.pricing-override-price input', 20);
    await click('button:contains(Add):last');
    await waitToAppear('.override-profile');
    assert.dom('.override-profile').hasText('Half off', 'Pricing override saved');

    await click('button:contains(Delete)');
    await waitToAppear('.modal-dialog');
    await click('button:contains(Ok)');
    assert.dom('.override-profile').doesNotExist('Pricing override deleted');
  });
});

test('verify behavior of Category control and Pricing Type field', function(assert) {
  return runWithPouchDump('default', async function() {

    // go to /pricing/lab, add item and confirm Pricing Type is 'Lab Procedure' (bug fixed in PR #1526)
    await authenticateUser();
    await visit('/pricing/lab');
    await click('button:contains(+ new item)');
    assert.equal(currentURL(), '/pricing/edit/newLab');
    await fillIn('.price-name input', 'Test Lab Item');
    await fillIn('.price-amount input', 10);
    await fillIn('.price-department input', 'Test Expense Acct');
    await click('button:contains(Add):last');

    await waitToAppear('.modal-dialog');
    assert.dom('.modal-title').hasText('Pricing Item Saved', 'Pricing Item saved');
    await click('button:contains(Return)');

    assert.dom('td:nth-child(4)').hasText('Lab Procedure');

    await click('button:contains(Delete)');
    await waitToAppear('.modal-dialog');
    await click('button:contains(Delete):last');

    // test that changing Category sets proper Pricing Type depending on which Category selected
    await visit('/pricing/ward');
    await click('button:contains(+ new item)');
    assert.equal(currentURL(), '/pricing/edit/newWard');

    await fillIn('.price-name input', 'Test Ward Item');
    await fillIn('.price-amount input', 10);
    await fillIn('.price-department input', 'Test Expense Acct');

    await fillIn('.price-type input', 'fake price type');
    await select('.price-category', 'Procedure');
    assert.dom('.price-type input').hasText('', 'Changing Category to "Procedure" sets Pricing Type to ""');

    await select('.price-category', 'Imaging');
    await click('button:contains(Add):last');

    await waitToAppear('.modal-dialog');
    assert.dom('.modal-title').hasText('Pricing Item Saved', 'Pricing Item saved');
    await click('button:contains(Return)');

    assert.dom('td:nth-child(4)').hasText('Imaging Procedure');
  });
});

test('delete price', function(assert) {
  return runWithPouchDump('billing', async function() {
    await authenticateUser();
    await visit('/pricing/lab');
    assert.equal(currentURL(), '/pricing/lab');
    assert.equal(find('.price-name:contains(Blood test)').length, 1, 'Price exists to delete');

    await click('button:contains(Delete)');
    await waitToAppear('.modal-dialog');
    assert.dom('.alert').hasText(
      'Are you sure you wish to delete Blood test?',
      'Pricing item is displayed for deletion'
    );

    await click('button:contains(Delete):last');
    await waitToDisappear('.price-name:contains(Blood test)');
    assert.equal(find('.price-name:contains(Blood test)').length, 0, 'Price disappears from price list');
  });
});

test('create new pricing profile', function(assert) {
  return runWithPouchDump('billing', async function() {
    await authenticateUser();
    await visit('/pricing/profiles');
    assert.equal(currentURL(), '/pricing/profiles');

    await click('button:contains(+ new item)');
    await waitToAppear('.modal-dialog');
    assert.dom('.modal-title').hasText('New Pricing Profile', 'New Pricing Profile modal appears');

    await fillIn('.pricing-profile-name input', 'Quarter Off');
    await fillIn('.pricing-profile-percentage input', 25);
    await fillIn('.pricing-profile-discount input', 10);
    await click('button:contains(Add)');
    await waitToAppear('.modal-title:contains(Pricing Profile Saved)');
    await click('button:contains(Ok)');
    await waitToAppear('.pricing-profile-name:contains(Quarter Off)');
    assert.equal(find('.pricing-profile-name:contains(Quarter Off)').text(), 'Quarter Off', 'New price profile displays');
  });
});

test('delete pricing profile', function(assert) {
  return runWithPouchDump('billing', async function() {
    await authenticateUser();
    await visit('/pricing/profiles');
    assert.equal(currentURL(), '/pricing/profiles');
    assert.equal(find('.pricing-profile-name:contains(Half off)').length, 1, 'Pricing profile exists to delete');

    await click('button:contains(Delete)');
    await waitToAppear('.modal-dialog');
    assert.dom('.modal-title').hasText('Delete Profile', 'Pricing Profile delete confirmation is displayed');

    await click('button:contains(Ok)');
    await waitToDisappear('.pricing-profile-name:contains(Half off)');
    assert.equal(find('.pricing-profile-name:contains(Half off)').length, 0, 'Pricing profile disappears from list');
  });
});

test('Searching pricing', function(assert) {
  return runWithPouchDump('billing', async function() {
    await authenticateUser();
    await visit('/pricing');

    await fillIn('[role="search"] div input', 'Xray Hand');
    await click('.glyphicon-search');
    assert.equal(currentURL(), '/pricing/search/Xray%20Hand', 'Searched for Name: Xray Hand');
    assert.equal(find('button:contains(Delete)').length, 1, 'There is one search item');

    await fillIn('[role="search"] div input', 'Blood');
    await click('.glyphicon-search');
    assert.equal(currentURL(), '/pricing/search/Blood', 'Searched for Name: Blood');
    assert.equal(find('button:contains(Delete)').length, 1, 'There is one search item');

    await fillIn('[role="search"] div input', 'Leg');
    await click('.glyphicon-search');
    assert.equal(currentURL(), '/pricing/search/Leg', 'Searched for Name: Leg');
    assert.equal(find('button:contains(Delete)').length, 1, 'There is one search item');

    await fillIn('[role="search"] div input', 'Gauze');
    await click('.glyphicon-search');
    assert.equal(currentURL(), '/pricing/search/Gauze', 'Searched for Name: Gauze');
    assert.equal(find('button:contains(Delete)').length, 1, 'There is one search item');

    await fillIn('[role="search"] div input', 'xray');
    await click('.glyphicon-search');
    assert.equal(currentURL(), '/pricing/search/xray', 'Searched for all lower case xray');
    assert.equal(find('button:contains(Delete)').length, 1, 'There is one search item');

    await fillIn('[role="search"] div input', 'd');
    await click('.glyphicon-search');
    assert.equal(currentURL(), '/pricing/search/d', 'Searched for the letter d');
    assert.equal(find('button:contains(Delete)').length, 3, 'There are three search items');

    await fillIn('[role="search"] div input', 'ItemNotFound');
    await click('.glyphicon-search');
    assert.equal(currentURL(), '/pricing/search/ItemNotFound', 'Searched for ItemNotFound');
    assert.dom('.clickable').doesNotExist('There is no search result');
  });
});
<commit_msg>Fix for ESLint.<commit_after>import { test } from 'qunit';
import moduleForAcceptance from 'hospitalrun/tests/helpers/module-for-acceptance';
import runWithPouchDump from 'hospitalrun/tests/helpers/run-with-pouch-dump';
import select from 'hospitalrun/tests/helpers/select';
import { waitToAppear, waitToDisappear } from 'hospitalrun/tests/helpers/wait-to-appear';
import { authenticateUser } from 'hospitalrun/tests/helpers/authenticate-user';

function verifyPricingLists(path, includesPrices, excludesPrices, assert) {
  return runWithPouchDump('billing', async function() {
    await authenticateUser();
    await visit(path);
    assert.equal(currentURL(), path);
    includesPrices.forEach(function(priceName) {
      assert.equal(find(`.price-name:contains(${priceName})`).length, 1, `${priceName} displays`);
    });
    excludesPrices.forEach(function(priceName) {
      assert.equal(find(`.price-name:contains(${priceName})`).length, 0, `${priceName} is not present`);
    });
  });
}

moduleForAcceptance('Acceptance | pricing');

test('visiting /pricing', function(assert) {
  let includesPrices = [
    'Xray Hand',
    'Blood test',
    'Leg Casting',
    'Gauze pad'
  ];
  return verifyPricingLists('/pricing', includesPrices, [], assert);
});

test('visiting /pricing/imaging', function(assert) {
  let excludesPrices = [
    'Blood test',
    'Leg Casting',
    'Gauze pad'
  ];
  let includesPrices = [
    'Xray Hand'
  ];
  return verifyPricingLists('/pricing/imaging', includesPrices, excludesPrices, assert);

});

test('visiting /pricing/lab', function(assert) {
  let excludesPrices = [
    'Xray Hand',
    'Leg Casting',
    'Gauze pad'
  ];
  let includesPrices = [
    'Blood test'
  ];
  return verifyPricingLists('/pricing/lab', includesPrices, excludesPrices, assert);
});

test('visiting /pricing/procedure', function(assert) {
  let excludesPrices = [
    'Xray Hand',
    'Blood test',
    'Gauze pad'
  ];
  let includesPrices = [
    'Leg Casting'
  ];
  return verifyPricingLists('/pricing/procedure', includesPrices, excludesPrices, assert);
});

test('visiting /pricing/ward', function(assert) {
  let excludesPrices = [
    'Xray Hand',
    'Blood test',
    'Leg Casting'
  ];
  let includesPrices = [
    'Gauze pad'
  ];
  return verifyPricingLists('/pricing/ward', includesPrices, excludesPrices, assert);
});

test('create new price', function(assert) {
  return runWithPouchDump('billing', async function() {
    await authenticateUser();
    await visit('/pricing');
    await click('button:contains(+ new item)');
    assert.equal(currentURL(), '/pricing/edit/new');

    await fillIn('.price-name input', 'Xray Foot');
    await fillIn('.price-amount input', 100);
    await fillIn('.price-department input', 'Imaging');
    await select('.price-category', 'Imaging');
    await click('button:contains(Add):last');
    await waitToAppear('.modal-dialog');
    assert.dom('.modal-title').hasText('Pricing Item Saved', 'Pricing Item saved');

    await click('button:contains(Ok)');
    await click('button:contains(Add Override)');
    await waitToAppear('.modal-dialog');
    assert.dom('.modal-title').hasText('Add Override', 'Add Override Dialog displays');

    await select('.pricing-profile', 'Half off');
    await fillIn('.pricing-override-price input', 20);
    await click('button:contains(Add):last');
    await waitToAppear('.override-profile');
    assert.dom('.override-profile').hasText('Half off', 'Pricing override saved');

    await click('button:contains(Delete)');
    await waitToAppear('.modal-dialog');
    await click('button:contains(Ok)');
    assert.dom('.override-profile').doesNotExist('Pricing override deleted');
  });
});

test('verify behavior of Category control and Pricing Type field', function(assert) {
  return runWithPouchDump('default', async function() {

    // go to /pricing/lab, add item and confirm Pricing Type is 'Lab Procedure' (bug fixed in PR #1526)
    await authenticateUser();
    await visit('/pricing/lab');
    await click('button:contains(+ new item)');
    assert.equal(currentURL(), '/pricing/edit/newLab');
    await fillIn('.price-name input', 'Test Lab Item');
    await fillIn('.price-amount input', 10);
    await fillIn('.price-department input', 'Test Expense Acct');
    await click('button:contains(Add):last');

    await waitToAppear('.modal-dialog');
    assert.dom('.modal-title').hasText('Pricing Item Saved', 'Pricing Item saved');
    await click('button:contains(Return)');

    assert.dom('td:nth-child(4)').hasText('Lab Procedure');

    await click('button:contains(Delete)');
    await waitToAppear('.modal-dialog');
    await click('button:contains(Delete):last');

    // test that changing Category sets proper Pricing Type depending on which Category selected
    await visit('/pricing/ward');
    await click('button:contains(+ new item)');
    assert.equal(currentURL(), '/pricing/edit/newWard');

    await fillIn('.price-name input', 'Test Ward Item');
    await fillIn('.price-amount input', 10);
    await fillIn('.price-department input', 'Test Expense Acct');

    await fillIn('.price-type input', 'fake price type');
    await select('.price-category', 'Procedure');
    assert.dom('.price-type input').hasText('', 'Changing Category to "Procedure" sets Pricing Type to ""');

    await select('.price-category', 'Imaging');
    await click('button:contains(Add):last');

    await waitToAppear('.modal-dialog');
    assert.dom('.modal-title').hasText('Pricing Item Saved', 'Pricing Item saved');
    await click('button:contains(Return)');

    assert.dom('td:nth-child(4)').hasText('Imaging Procedure');
  });
});

test('delete price', function(assert) {
  return runWithPouchDump('billing', async function() {
    await authenticateUser();
    await visit('/pricing/lab');
    assert.equal(currentURL(), '/pricing/lab');
    assert.equal(find('.price-name:contains(Blood test)').length, 1, 'Price exists to delete');

    await click('button:contains(Delete)');
    await waitToAppear('.modal-dialog');
    assert.dom('.alert').hasText(
      'Are you sure you wish to delete Blood test?',
      'Pricing item is displayed for deletion'
    );

    await click('button:contains(Delete):last');
    await waitToDisappear('.price-name:contains(Blood test)');
    assert.equal(find('.price-name:contains(Blood test)').length, 0, 'Price disappears from price list');
  });
});

test('create new pricing profile', function(assert) {
  return runWithPouchDump('billing', async function() {
    await authenticateUser();
    await visit('/pricing/profiles');
    assert.equal(currentURL(), '/pricing/profiles');

    await click('button:contains(+ new item)');
    await waitToAppear('.modal-dialog');
    assert.dom('.modal-title').hasText('New Pricing Profile', 'New Pricing Profile modal appears');

    await fillIn('.pricing-profile-name input', 'Quarter Off');
    await fillIn('.pricing-profile-percentage input', 25);
    await fillIn('.pricing-profile-discount input', 10);
    await click('button:contains(Add)');
    await waitToAppear('.modal-title:contains(Pricing Profile Saved)');
    await click('button:contains(Ok)');
    await waitToAppear('.pricing-profile-name:contains(Quarter Off)');
    assert.equal(find('.pricing-profile-name:contains(Quarter Off)').text(), 'Quarter Off', 'New price profile displays');
  });
});

test('delete pricing profile', function(assert) {
  return runWithPouchDump('billing', async function() {
    await authenticateUser();
    await visit('/pricing/profiles');
    assert.equal(currentURL(), '/pricing/profiles');
    assert.equal(find('.pricing-profile-name:contains(Half off)').length, 1, 'Pricing profile exists to delete');

    await click('button:contains(Delete)');
    await waitToAppear('.modal-dialog');
    assert.dom('.modal-title').hasText('Delete Profile', 'Pricing Profile delete confirmation is displayed');

    await click('button:contains(Ok)');
    await waitToDisappear('.pricing-profile-name:contains(Half off)');
    assert.equal(find('.pricing-profile-name:contains(Half off)').length, 0, 'Pricing profile disappears from list');
  });
});

test('Searching pricing', function(assert) {
  return runWithPouchDump('billing', async function() {
    await authenticateUser();
    await visit('/pricing');

    await fillIn('[role="search"] div input', 'Xray Hand');
    await click('.glyphicon-search');
    assert.equal(currentURL(), '/pricing/search/Xray%20Hand', 'Searched for Name: Xray Hand');
    assert.equal(find('button:contains(Delete)').length, 1, 'There is one search item');

    await fillIn('[role="search"] div input', 'Blood');
    await click('.glyphicon-search');
    assert.equal(currentURL(), '/pricing/search/Blood', 'Searched for Name: Blood');
    assert.equal(find('button:contains(Delete)').length, 1, 'There is one search item');

    await fillIn('[role="search"] div input', 'Leg');
    await click('.glyphicon-search');
    assert.equal(currentURL(), '/pricing/search/Leg', 'Searched for Name: Leg');
    assert.equal(find('button:contains(Delete)').length, 1, 'There is one search item');

    await fillIn('[role="search"] div input', 'Gauze');
    await click('.glyphicon-search');
    assert.equal(currentURL(), '/pricing/search/Gauze', 'Searched for Name: Gauze');
    assert.equal(find('button:contains(Delete)').length, 1, 'There is one search item');

    await fillIn('[role="search"] div input', 'xray');
    await click('.glyphicon-search');
    assert.equal(currentURL(), '/pricing/search/xray', 'Searched for all lower case xray');
    assert.equal(find('button:contains(Delete)').length, 1, 'There is one search item');

    await fillIn('[role="search"] div input', 'd');
    await click('.glyphicon-search');
    assert.equal(currentURL(), '/pricing/search/d', 'Searched for the letter d');
    assert.equal(find('button:contains(Delete)').length, 3, 'There are three search items');

    await fillIn('[role="search"] div input', 'ItemNotFound');
    await click('.glyphicon-search');
    assert.equal(currentURL(), '/pricing/search/ItemNotFound', 'Searched for ItemNotFound');
    assert.dom('.clickable').doesNotExist('There is no search result');
  });
});
<|endoftext|>


<commit_before><commit_msg>Do nothing if item is not in array or already in right place<commit_after><|endoftext|>


<commit_before>var debug = require('debug')('webtorrent-www:home')
var fs = require('fs')
var moment = require('moment')
var path = require('path')
var prettyBytes = require('pretty-bytes')
var TorrentGraph = require('../lib/torrent-graph')
var WebTorrent = require('webtorrent')
var xhr = require('xhr')

var TORRENT = fs.readFileSync(
  path.join(__dirname, '../../static/torrents/sintel.torrent')
)

module.exports = function () {
  var graph = window.graph = new TorrentGraph('#svgWrap')

  getRtcConfig('https://instant.io/rtcConfig', function (err, rtcConfig) {
    if (err) onError(err)
    createClient(rtcConfig)
  })

  var torrent
  function createClient (rtcConfig) {
    var client = window.client = new WebTorrent({ rtcConfig: rtcConfig })
    client.on('warning', onWarning)
    client.on('error', onError)

    torrent = client.add(TORRENT, onTorrent)
    graph.add({ id: 'You', me: true })
  }

  var $body = document.body
  var $progressBar = document.querySelector('#progressBar')
  var $numPeers = document.querySelector('#numPeers')
  var $downloaded = document.querySelector('#downloaded')
  var $total = document.querySelector('#total')
  var $remaining = document.querySelector('#remaining')

  function onTorrent () {
    torrent.files[0].appendTo('#videoWrap .video', onError)
    torrent.on('wire', onWire)
    torrent.on('done', onDone)
    onProgress()
  }

  function onWire (wire) {
    var id = wire.peerId.toString()
    graph.add({ id: id, ip: wire.remoteAddress || 'Unknown' })
    graph.connect('You', id)
    wire.once('close', function () {
      graph.disconnect('You', id)
      graph.remove(id)
      onProgress()
    })
    onProgress()
  }

  function onProgress () {
    var percent = Math.round(torrent.progress * 100 * 100) / 100
    $progressBar.style.width = percent + '%'
    $numPeers.innerHTML = torrent.numPeers + (torrent.numPeers === 1 ? ' peer' : ' peers')

    $downloaded.innerHTML = prettyBytes(torrent.downloaded)
    $total.innerHTML = prettyBytes(torrent.length)

    var remaining
    if (torrent.done) {
      remaining = 'Done.'
    } else {
      remaining = moment.duration(torrent.timeRemaining / 1000, 'seconds').humanize()
      remaining = remaining[0].toUpperCase() + remaining.substring(1) + ' remaining.'
    }
    $remaining.innerHTML = remaining
  }

  var interval = setInterval(onProgress, 500)

  function onDone () {
    $body.className += ' is-seed'
    onProgress()
    clearInterval(interval)
  }

  function onError (err) {
    if (err) {
      window.alert(err)
      console.error(err)
    }
  }

  function onWarning (err) {
    if (err) {
      console.error(err)
    }
  }

  function getRtcConfig (url, cb) {
    xhr(url, function (err, res) {
      if (err || res.statusCode !== 200) {
        cb(new Error('Could not get WebRTC config from server. Using default (without TURN).'))
      } else {
        var rtcConfig
        try {
          rtcConfig = JSON.parse(res.body)
        } catch (err) {
          return cb(new Error('Got invalid WebRTC config from server: ' + res.body))
        }
        debug('got rtc config: %o', rtcConfig)
        cb(null, rtcConfig)
      }
    })
  }
}
<commit_msg>Standard fix<commit_after>var debug = require('debug')('webtorrent-www:home')
var fs = require('fs')
var moment = require('moment')
var path = require('path')
var prettyBytes = require('pretty-bytes')
var TorrentGraph = require('../lib/torrent-graph')
var WebTorrent = require('webtorrent')
var xhr = require('xhr')

var TORRENT = fs.readFileSync(
  path.join(__dirname, '../../static/torrents/sintel.torrent')
)

module.exports = function () {
  var graph = window.graph = new TorrentGraph('#svgWrap')

  getRtcConfig('https://instant.io/rtcConfig', function (err, rtcConfig) {
    if (err) onError(err)
    createClient(rtcConfig)
  })

  var torrent
  function createClient (rtcConfig) {
    var client = window.client = new WebTorrent({ rtcConfig: rtcConfig })
    client.on('warning', onWarning)
    client.on('error', onError)

    torrent = client.add(TORRENT, onTorrent)
    graph.add({ id: 'You', me: true })
  }

  var $body = document.body
  var $progressBar = document.querySelector('#progressBar')
  var $numPeers = document.querySelector('#numPeers')
  var $downloaded = document.querySelector('#downloaded')
  var $total = document.querySelector('#total')
  var $remaining = document.querySelector('#remaining')

  function onTorrent () {
    torrent.files[0].appendTo('#videoWrap .video', onError)
    torrent.on('wire', onWire)
    torrent.on('done', onDone)
    onProgress()
  }

  function onWire (wire) {
    var id = wire.peerId.toString()
    graph.add({ id: id, ip: wire.remoteAddress || 'Unknown' })
    graph.connect('You', id)
    wire.once('close', function () {
      graph.disconnect('You', id)
      graph.remove(id)
      onProgress()
    })
    onProgress()
  }

  function onProgress () {
    var percent = Math.round(torrent.progress * 100 * 100) / 100
    $progressBar.style.width = percent + '%'
    $numPeers.innerHTML = torrent.numPeers + (torrent.numPeers === 1 ? ' peer' : ' peers')

    $downloaded.innerHTML = prettyBytes(torrent.downloaded)
    $total.innerHTML = prettyBytes(torrent.length)

    var remaining
    if (torrent.done) {
      remaining = 'Done.'
    } else {
      remaining = moment.duration(torrent.timeRemaining / 1000, 'seconds').humanize()
      remaining = remaining[0].toUpperCase() + remaining.substring(1) + ' remaining.'
    }
    $remaining.innerHTML = remaining
  }

  var interval = setInterval(onProgress, 500)

  function onDone () {
    $body.className += ' is-seed'
    onProgress()
    clearInterval(interval)
  }

  function onError (err) {
    if (err) {
      window.alert(err)
      console.error(err)
    }
  }

  function onWarning (err) {
    if (err) {
      console.error(err)
    }
  }

  function getRtcConfig (url, cb) {
    xhr(url, function (err, res) {
      if (err || res.statusCode !== 200) {
        cb(new Error('Could not get WebRTC config from server. Using default (without TURN).'))
      } else {
        var rtcConfig
        try {
          rtcConfig = JSON.parse(res.body)
        } catch (err) {
          return cb(new Error('Got invalid WebRTC config from server: ' + res.body))
        }
        debug('got rtc config: %o', rtcConfig)
        cb(null, rtcConfig)
      }
    })
  }
}
<|endoftext|>


<commit_before>import * as ActionCreators from 'ActionCreators';
import Constants from 'Constants';

describe('ActionCreators', function () {
    var request, dispatchMock;

    function sessionTest(testfunc, params) {
        describe(testfunc, function () {
            beforeEach(function () {
                dispatchMock = jasmine.createSpy();
                ActionCreators[testfunc].apply(this, params)(dispatchMock);
                request = jasmine.Ajax.requests.mostRecent();
            });

            it('dispatches SET_SESSION first', function () {
                expect(dispatchMock.calls.argsFor(0)).toEqual([{type: Constants.SET_SESSION}]);
            });

            describe('on fail', function () {
                beforeEach(function () {
                    request.respondWith({
                        status: 401
                    });
                });

                it('dispatches SET_SESSION_FAIL', function () {
                    expect(dispatchMock.calls.argsFor(1)).toEqual([{
                        type: Constants.SET_SESSION_FAIL,
                        error: jasmine.any(Error)
                    }]);
                });
            });

            describe('on success', function () {
                var dispatchSuccessMock, dispatchCapabilitiesMock, dispatchDocumentationMock,
                    dispatchMinionsMock, dispatchJobsMock, capabilityRequest, documentationRequest,
                    minionsRequest, jobsRequest;

                beforeEach(function () {
                    request.respondWith({
                        status: 200,
                        responseText: '{ "Hello": 42 }'
                    });
                    dispatchSuccessMock = jasmine.createSpy();
                    dispatchCapabilitiesMock = jasmine.createSpy();
                    dispatchDocumentationMock = jasmine.createSpy();
                    dispatchMinionsMock = jasmine.createSpy();
                    dispatchJobsMock = jasmine.createSpy();

                    dispatchMock.calls.argsFor(1)[0](dispatchSuccessMock); // Call returned function
                    dispatchSuccessMock.calls.argsFor(1)[0](dispatchCapabilitiesMock);
                    capabilityRequest = jasmine.Ajax.requests.mostRecent();

                    dispatchSuccessMock.calls.argsFor(2)[0](dispatchDocumentationMock);
                    documentationRequest = jasmine.Ajax.requests.mostRecent();

                    dispatchSuccessMock.calls.argsFor(3)[0](dispatchMinionsMock);
                    minionsRequest = jasmine.Ajax.requests.mostRecent();

                    dispatchSuccessMock.calls.argsFor(4)[0](dispatchJobsMock);
                    jobsRequest = jasmine.Ajax.requests.mostRecent();
                });

                it('dispatches SET_SESSION_SUCCESS', function () {
                    expect(dispatchSuccessMock.calls.argsFor(0)).toEqual([{
                        type: Constants.SET_SESSION_SUCCESS,
                        session: {Hello: 42}
                    }]);
                });

                describe('load capabilities', function () {
                    it('dispatches GET_CAPABILITIES', function () {
                        expect(dispatchCapabilitiesMock.calls.argsFor(0)).toEqual([{
                            type: Constants.GET_CAPABILITIES
                        }]);
                    });

                    describe('on success', function () {
                        beforeEach(function () {
                            capabilityRequest.respondWith({
                                status: 200,
                                responseText: '{ "Hello": 42 }'
                            });
                        });

                        it('dispatches GET_CAPABILITIES_SUCCESS', function () {
                            expect(dispatchCapabilitiesMock.calls.argsFor(1)).toEqual([{
                                type: Constants.GET_CAPABILITIES_SUCCESS,
                                capabilities: {Hello: 42}
                            }]);
                        });
                    });

                    describe('on fail', function () {
                        it('with status 400 dispatches only GET_CAPABILITIES_FAIL', function () {
                            capabilityRequest.respondWith({
                                status: 400
                            });

                            expect(dispatchCapabilitiesMock.calls.argsFor(1)).toEqual([{
                                type: Constants.GET_CAPABILITIES_FAIL,
                                error: jasmine.any(Error)
                            }]);
                            expect(dispatchCapabilitiesMock.calls.count()).toBe(2);
                        });

                        describe('with status 401', function () {
                            beforeEach(function () {
                                capabilityRequest.respondWith({
                                    status: 401
                                });
                            });

                            it('dispatch GET_CAPABILITIES_FAIL', function () {
                                expect(dispatchCapabilitiesMock.calls.argsFor(1)).toEqual([{
                                    type: Constants.GET_CAPABILITIES_FAIL,
                                    error: jasmine.any(Error)
                                }]);
                            });

                            it('dispatch SET_SESSION for resetting', function () {
                                expect(dispatchCapabilitiesMock.calls.argsFor(2)).toEqual([{
                                    type: Constants.SET_SESSION
                                }]);
                            });

                            it('dispatch pushState', function () {
                                expect(dispatchCapabilitiesMock.calls.argsFor(3)).toEqual([{
                                    type: '@@reduxReactRouter/historyAPI',
                                    payload: {
                                        method: 'pushState',
                                        args: [null, '/molten/login']
                                    }
                                }]);
                            });
                        });
                    });
                });

                describe('load minions', function () {
                    it('dispatches GET_MINIONS', function () {
                        expect(dispatchMinionsMock.calls.argsFor(0)).toEqual([{
                            type: Constants.GET_MINIONS
                        }]);
                    });

                    describe('on success', function () {
                        beforeEach(function () {
                            minionsRequest.respondWith({
                                status: 200,
                                responseText: '{ "Hello": 42 }'
                            });
                        });

                        it('dispatches GET_MINIONS_SUCCESS', function () {
                            expect(dispatchMinionsMock.calls.argsFor(1)).toEqual([{
                                type: Constants.GET_MINIONS_SUCCESS,
                                minionList: {Hello: 42}
                            }]);
                        });
                    });

                    describe('on fail', function () {
                        it('dispatches GET_MINIONS_FAIL', function () {
                            minionsRequest.respondWith({
                                status: 400
                            });

                            expect(dispatchMinionsMock.calls.argsFor(1)).toEqual([{
                                type: Constants.GET_MINIONS_FAIL,
                                error: jasmine.any(Error)
                            }]);
                            expect(dispatchMinionsMock.calls.count()).toBe(2);
                        });
                    });
                });

                describe('load jobs', function () {
                    it('dispatches GET_JOBS', function () {
                        expect(dispatchJobsMock.calls.argsFor(0)).toEqual([{
                            type: Constants.GET_JOBS
                        }]);
                    });

                    describe('on success', function () {
                        beforeEach(function () {
                            jobsRequest.respondWith({
                                status: 200,
                                responseText: '{ "Hello": 42 }'
                            });
                        });

                        it('dispatches GET_JOBS_SUCCESS', function () {
                            expect(dispatchJobsMock.calls.argsFor(1)).toEqual([{
                                type: Constants.GET_JOBS_SUCCESS,
                                jobList: {Hello: 42}
                            }]);
                        });
                    });

                    describe('on fail', function () {
                        it('dispatches GET_JOBS_FAIL', function () {
                            jobsRequest.respondWith({
                                status: 400
                            });

                            expect(dispatchJobsMock.calls.argsFor(1)).toEqual([{
                                type: Constants.GET_JOBS_FAIL,
                                error: jasmine.any(Error)
                            }]);
                            expect(dispatchJobsMock.calls.count()).toBe(2);
                        });
                    });
                });

                describe('load documentation', function () {
                    it('dispatches GET_DOCUMENTATION for execution', function () {
                        expect(dispatchDocumentationMock.calls.argsFor(0)).toEqual([{
                            type: Constants.GET_DOCUMENTATION,
                            docType: 'execution'
                        }]);
                    });

                    it('dispatches GET_DOCUMENTATION for runner', function () {
                        expect(dispatchDocumentationMock.calls.argsFor(1)).toEqual([{
                            type: Constants.GET_DOCUMENTATION,
                            docType: 'runner'
                        }]);
                    });

                    describe('on success', function () {
                        beforeEach(function () {
                            documentationRequest.respondWith({
                                status: 200,
                                responseText: '{ "Hello": 42 }'
                            });
                        });

                        it('dispatches GET_DOCUMENTATION_SUCCESS', function () {
                            expect(dispatchDocumentationMock.calls.argsFor(3)).toEqual([{
                                type: Constants.GET_DOCUMENTATION_SUCCESS,
                                docType: 'wheel',
                                documentation: {Hello: 42}
                            }]);
                        });
                    });

                    describe('on fail', function () {
                        it('dispatches GET_DOCUMENTATION_FAIL', function () {
                            documentationRequest.respondWith({
                                status: 400
                            });

                            expect(dispatchDocumentationMock.calls.argsFor(3)).toEqual([{
                                type: Constants.GET_DOCUMENTATION_FAIL,
                                error: jasmine.any(Error)
                            }]);
                        });
                    });
                });
            });
        });
    }

    sessionTest('testSessionStatus', []);
    sessionTest('createSession', ['someuser', 'somepass']);

    function testAsyncCreator(creator, args, basename, submit, successResponse, success, failResponse, fail) {
        describe(creator, function () {
            beforeEach(function () {
                dispatchMock = jasmine.createSpy();
                ActionCreators[creator].apply(this, args)(dispatchMock);
                request = jasmine.Ajax.requests.mostRecent();
            });

            it(`dispatches ${basename} first`, function () {
                expect(dispatchMock.calls.argsFor(0)).toEqual([submit]);
            });

            it(`on success dispatches ${basename}_SUCCESS`, function () {
                request.respondWith(successResponse);

                expect(dispatchMock.calls.argsFor(1)).toEqual([success]);
            });

            describe('on fail', function () {
                beforeEach(function () {
                    request.respondWith(failResponse);
                });

                it(`dispatch ${basename}_FAIL`, function () {
                    expect(dispatchMock.calls.argsFor(1)).toEqual([fail]);
                });

                it('dispatch SET_SESSION for resetting', function () {
                    expect(dispatchMock.calls.argsFor(2)).toEqual([{
                        type: Constants.SET_SESSION
                    }]);
                });

                it('dispatch pushState', function () {
                    expect(dispatchMock.calls.argsFor(3)).toEqual([{
                        type: '@@reduxReactRouter/historyAPI',
                        payload: {
                            method: 'pushState',
                            args: [null, '/molten/login']
                        }
                    }]);
                });
            });
        });
    }

    testAsyncCreator(
        'executeCommand',
        [{ Hello: 42 }],
        'SUBMIT_COMMAND',
        {
            type: Constants.SUBMIT_COMMAND,
            commandObj: { Hello: 42 }
        },
        {
            status: 200,
            responseText: '{ "Ahoi": 43 }'
        },
        {
            type: Constants.SUBMIT_COMMAND_SUCCESS,
            commandObj: { Hello: 42 },
            result: { Ahoi: 43 }
        },
        {
            status: 401
        },
        {
            type: Constants.SUBMIT_COMMAND_FAIL,
            commandObj: { Hello: 42 },
            error: jasmine.any(Error)
        }
    );

    testAsyncCreator(
        'loadJobResult',
        [1234],
        'GET_JOB',
        {
            type: Constants.GET_JOB,
            jid: 1234
        },
        {
            status: 200,
            responseText: '{ "Ahoi": 43 }'
        },
        {
            type: Constants.GET_JOB_SUCCESS,
            jid: 1234,
            job: { Ahoi: 43 }
        },
        {
            status: 401
        },
        {
            type: Constants.GET_JOB_FAIL,
            jid: 1234,
            error: jasmine.any(Error)
        }
    );

    testAsyncCreator(
        'logout',
        [],
        'UNSET_SESSION',
        {
            type: Constants.UNSET_SESSION
        },
        {
            status: 200,
            responseText: '{ "Ahoi": 43 }'
        },
        {
            type: Constants.UNSET_SESSION_SUCCESS,
            session: undefined
        },
        {
            status: 401
        },
        {
            type: Constants.UNSET_SESSION_FAIL,
            error: jasmine.any(Error)
        }
    );
});
<commit_msg>Linter fix<commit_after>import * as ActionCreators from 'ActionCreators';
import Constants from 'Constants';

describe('ActionCreators', function () {
    var request, dispatchMock;

    function sessionTest(testfunc, params) {
        describe(testfunc, function () {
            beforeEach(function () {
                dispatchMock = jasmine.createSpy();
                ActionCreators[testfunc].apply(this, params)(dispatchMock);
                request = jasmine.Ajax.requests.mostRecent();
            });

            it('dispatches SET_SESSION first', function () {
                expect(dispatchMock.calls.argsFor(0)).toEqual([{ type: Constants.SET_SESSION }]);
            });

            describe('on fail', function () {
                beforeEach(function () {
                    request.respondWith({
                        status: 401
                    });
                });

                it('dispatches SET_SESSION_FAIL', function () {
                    expect(dispatchMock.calls.argsFor(1)).toEqual([{
                        type: Constants.SET_SESSION_FAIL,
                        error: jasmine.any(Error)
                    }]);
                });
            });

            describe('on success', function () {
                var dispatchSuccessMock, dispatchCapabilitiesMock, dispatchDocumentationMock,
                    dispatchMinionsMock, dispatchJobsMock, capabilityRequest, documentationRequest,
                    minionsRequest, jobsRequest;

                beforeEach(function () {
                    request.respondWith({
                        status: 200,
                        responseText: '{ "Hello": 42 }'
                    });
                    dispatchSuccessMock = jasmine.createSpy();
                    dispatchCapabilitiesMock = jasmine.createSpy();
                    dispatchDocumentationMock = jasmine.createSpy();
                    dispatchMinionsMock = jasmine.createSpy();
                    dispatchJobsMock = jasmine.createSpy();

                    dispatchMock.calls.argsFor(1)[0](dispatchSuccessMock); // Call returned function
                    dispatchSuccessMock.calls.argsFor(1)[0](dispatchCapabilitiesMock);
                    capabilityRequest = jasmine.Ajax.requests.mostRecent();

                    dispatchSuccessMock.calls.argsFor(2)[0](dispatchDocumentationMock);
                    documentationRequest = jasmine.Ajax.requests.mostRecent();

                    dispatchSuccessMock.calls.argsFor(3)[0](dispatchMinionsMock);
                    minionsRequest = jasmine.Ajax.requests.mostRecent();

                    dispatchSuccessMock.calls.argsFor(4)[0](dispatchJobsMock);
                    jobsRequest = jasmine.Ajax.requests.mostRecent();
                });

                it('dispatches SET_SESSION_SUCCESS', function () {
                    expect(dispatchSuccessMock.calls.argsFor(0)).toEqual([{
                        type: Constants.SET_SESSION_SUCCESS,
                        session: { Hello: 42 }
                    }]);
                });

                describe('load capabilities', function () {
                    it('dispatches GET_CAPABILITIES', function () {
                        expect(dispatchCapabilitiesMock.calls.argsFor(0)).toEqual([{
                            type: Constants.GET_CAPABILITIES
                        }]);
                    });

                    describe('on success', function () {
                        beforeEach(function () {
                            capabilityRequest.respondWith({
                                status: 200,
                                responseText: '{ "Hello": 42 }'
                            });
                        });

                        it('dispatches GET_CAPABILITIES_SUCCESS', function () {
                            expect(dispatchCapabilitiesMock.calls.argsFor(1)).toEqual([{
                                type: Constants.GET_CAPABILITIES_SUCCESS,
                                capabilities: { Hello: 42 }
                            }]);
                        });
                    });

                    describe('on fail', function () {
                        it('with status 400 dispatches only GET_CAPABILITIES_FAIL', function () {
                            capabilityRequest.respondWith({
                                status: 400
                            });

                            expect(dispatchCapabilitiesMock.calls.argsFor(1)).toEqual([{
                                type: Constants.GET_CAPABILITIES_FAIL,
                                error: jasmine.any(Error)
                            }]);
                            expect(dispatchCapabilitiesMock.calls.count()).toBe(2);
                        });

                        describe('with status 401', function () {
                            beforeEach(function () {
                                capabilityRequest.respondWith({
                                    status: 401
                                });
                            });

                            it('dispatch GET_CAPABILITIES_FAIL', function () {
                                expect(dispatchCapabilitiesMock.calls.argsFor(1)).toEqual([{
                                    type: Constants.GET_CAPABILITIES_FAIL,
                                    error: jasmine.any(Error)
                                }]);
                            });

                            it('dispatch SET_SESSION for resetting', function () {
                                expect(dispatchCapabilitiesMock.calls.argsFor(2)).toEqual([{
                                    type: Constants.SET_SESSION
                                }]);
                            });

                            it('dispatch pushState', function () {
                                expect(dispatchCapabilitiesMock.calls.argsFor(3)).toEqual([{
                                    type: '@@reduxReactRouter/historyAPI',
                                    payload: {
                                        method: 'pushState',
                                        args: [null, '/molten/login']
                                    }
                                }]);
                            });
                        });
                    });
                });

                describe('load minions', function () {
                    it('dispatches GET_MINIONS', function () {
                        expect(dispatchMinionsMock.calls.argsFor(0)).toEqual([{
                            type: Constants.GET_MINIONS
                        }]);
                    });

                    describe('on success', function () {
                        beforeEach(function () {
                            minionsRequest.respondWith({
                                status: 200,
                                responseText: '{ "Hello": 42 }'
                            });
                        });

                        it('dispatches GET_MINIONS_SUCCESS', function () {
                            expect(dispatchMinionsMock.calls.argsFor(1)).toEqual([{
                                type: Constants.GET_MINIONS_SUCCESS,
                                minionList: { Hello: 42 }
                            }]);
                        });
                    });

                    describe('on fail', function () {
                        it('dispatches GET_MINIONS_FAIL', function () {
                            minionsRequest.respondWith({
                                status: 400
                            });

                            expect(dispatchMinionsMock.calls.argsFor(1)).toEqual([{
                                type: Constants.GET_MINIONS_FAIL,
                                error: jasmine.any(Error)
                            }]);
                            expect(dispatchMinionsMock.calls.count()).toBe(2);
                        });
                    });
                });

                describe('load jobs', function () {
                    it('dispatches GET_JOBS', function () {
                        expect(dispatchJobsMock.calls.argsFor(0)).toEqual([{
                            type: Constants.GET_JOBS
                        }]);
                    });

                    describe('on success', function () {
                        beforeEach(function () {
                            jobsRequest.respondWith({
                                status: 200,
                                responseText: '{ "Hello": 42 }'
                            });
                        });

                        it('dispatches GET_JOBS_SUCCESS', function () {
                            expect(dispatchJobsMock.calls.argsFor(1)).toEqual([{
                                type: Constants.GET_JOBS_SUCCESS,
                                jobList: { Hello: 42 }
                            }]);
                        });
                    });

                    describe('on fail', function () {
                        it('dispatches GET_JOBS_FAIL', function () {
                            jobsRequest.respondWith({
                                status: 400
                            });

                            expect(dispatchJobsMock.calls.argsFor(1)).toEqual([{
                                type: Constants.GET_JOBS_FAIL,
                                error: jasmine.any(Error)
                            }]);
                            expect(dispatchJobsMock.calls.count()).toBe(2);
                        });
                    });
                });

                describe('load documentation', function () {
                    it('dispatches GET_DOCUMENTATION for execution', function () {
                        expect(dispatchDocumentationMock.calls.argsFor(0)).toEqual([{
                            type: Constants.GET_DOCUMENTATION,
                            docType: 'execution'
                        }]);
                    });

                    it('dispatches GET_DOCUMENTATION for runner', function () {
                        expect(dispatchDocumentationMock.calls.argsFor(1)).toEqual([{
                            type: Constants.GET_DOCUMENTATION,
                            docType: 'runner'
                        }]);
                    });

                    describe('on success', function () {
                        beforeEach(function () {
                            documentationRequest.respondWith({
                                status: 200,
                                responseText: '{ "Hello": 42 }'
                            });
                        });

                        it('dispatches GET_DOCUMENTATION_SUCCESS', function () {
                            expect(dispatchDocumentationMock.calls.argsFor(3)).toEqual([{
                                type: Constants.GET_DOCUMENTATION_SUCCESS,
                                docType: 'wheel',
                                documentation: { Hello: 42 }
                            }]);
                        });
                    });

                    describe('on fail', function () {
                        it('dispatches GET_DOCUMENTATION_FAIL', function () {
                            documentationRequest.respondWith({
                                status: 400
                            });

                            expect(dispatchDocumentationMock.calls.argsFor(3)).toEqual([{
                                type: Constants.GET_DOCUMENTATION_FAIL,
                                error: jasmine.any(Error)
                            }]);
                        });
                    });
                });
            });
        });
    }

    sessionTest('testSessionStatus', []);
    sessionTest('createSession', ['someuser', 'somepass']);

    function testAsyncCreator(creator, args, basename, submit, successResponse, success, failResponse, fail) {
        describe(creator, function () {
            beforeEach(function () {
                dispatchMock = jasmine.createSpy();
                ActionCreators[creator].apply(this, args)(dispatchMock);
                request = jasmine.Ajax.requests.mostRecent();
            });

            it(`dispatches ${basename} first`, function () {
                expect(dispatchMock.calls.argsFor(0)).toEqual([submit]);
            });

            it(`on success dispatches ${basename}_SUCCESS`, function () {
                request.respondWith(successResponse);

                expect(dispatchMock.calls.argsFor(1)).toEqual([success]);
            });

            describe('on fail', function () {
                beforeEach(function () {
                    request.respondWith(failResponse);
                });

                it(`dispatch ${basename}_FAIL`, function () {
                    expect(dispatchMock.calls.argsFor(1)).toEqual([fail]);
                });

                it('dispatch SET_SESSION for resetting', function () {
                    expect(dispatchMock.calls.argsFor(2)).toEqual([{
                        type: Constants.SET_SESSION
                    }]);
                });

                it('dispatch pushState', function () {
                    expect(dispatchMock.calls.argsFor(3)).toEqual([{
                        type: '@@reduxReactRouter/historyAPI',
                        payload: {
                            method: 'pushState',
                            args: [null, '/molten/login']
                        }
                    }]);
                });
            });
        });
    }

    testAsyncCreator(
        'executeCommand',
        [{ Hello: 42 }],
        'SUBMIT_COMMAND',
        {
            type: Constants.SUBMIT_COMMAND,
            commandObj: { Hello: 42 }
        },
        {
            status: 200,
            responseText: '{ "Ahoi": 43 }'
        },
        {
            type: Constants.SUBMIT_COMMAND_SUCCESS,
            commandObj: { Hello: 42 },
            result: { Ahoi: 43 }
        },
        {
            status: 401
        },
        {
            type: Constants.SUBMIT_COMMAND_FAIL,
            commandObj: { Hello: 42 },
            error: jasmine.any(Error)
        }
    );

    testAsyncCreator(
        'loadJobResult',
        [1234],
        'GET_JOB',
        {
            type: Constants.GET_JOB,
            jid: 1234
        },
        {
            status: 200,
            responseText: '{ "Ahoi": 43 }'
        },
        {
            type: Constants.GET_JOB_SUCCESS,
            jid: 1234,
            job: { Ahoi: 43 }
        },
        {
            status: 401
        },
        {
            type: Constants.GET_JOB_FAIL,
            jid: 1234,
            error: jasmine.any(Error)
        }
    );

    testAsyncCreator(
        'logout',
        [],
        'UNSET_SESSION',
        {
            type: Constants.UNSET_SESSION
        },
        {
            status: 200,
            responseText: '{ "Ahoi": 43 }'
        },
        {
            type: Constants.UNSET_SESSION_SUCCESS,
            session: undefined
        },
        {
            status: 401
        },
        {
            type: Constants.UNSET_SESSION_FAIL,
            error: jasmine.any(Error)
        }
    );
});
<|endoftext|>


<commit_before>var lgs = {
	'ar': { lg: 'ar', name: 'العربية', short: 'العربية'},
	'de': { lg: 'de', name: 'Deutsch', short: 'de'},
	'en': { lg: 'en', name: 'English', short: 'en'},
	'es': { lg: 'es', name: 'Castellano', short: 'es'},
	'fr': { lg: 'fr', name: 'Français', short: 'fr'},
	'it': { lg: 'it', name: 'Italiano', short: 'it'},
	'da': { lg: 'da', name: 'Dansk', short: 'da'},
	'zh_TW': { lg: 'zh_TW', name: '國語', short: '國語'}
};

Template.lang_sel.helpers({
	lgs: function() {
		return _.values(lgs);
	},

	short: function() {
		return lgs[Session.get('locale')].short;
	}

});

Template.lang_sel.events({
	'click a.langselect': function(e){
		mfPkg.setLocale(this.lg);
		localStorage.setItem('locale', this.lg);
		Session.set('locale', this.lg);
		e.preventDefault();
		if (Meteor.user()){
			Meteor.call('updateUserLocale', this.lg);
		}
	}
});

// Always load english translation
// For dynamically constructed translation strings there is no default
// translation and meteor would show the translation key if there is no
// translation in the current locale
mfPkg.loadLangs('en');
<commit_msg>adding Japanese language selector and english string per language<commit_after>var lgs = {
	'ar': { lg: 'ar', name: 'العربية', short: 'العربية', english:'Arabic'},
	'da': { lg: 'da', name: 'Dansk', short: 'da', english:'Danish'},
	'de': { lg: 'de', name: 'Deutsch', short: 'de', english:'German'},
	'en': { lg: 'en', name: 'English', short: 'en', english:'English'},
	'es': { lg: 'es', name: 'Castellano', short: 'es', english:'Spanish'},
	'fr': { lg: 'fr', name: 'Français', short: 'fr', english:'French'},
	'it': { lg: 'it', name: 'Italiano', short: 'it', english:'Italian'},
	'ja': { lg: 'ja', name: '日本語', short: '日本語', english:'Japanese'},
	'zh_TW': { lg: 'zh_TW', name: '國語', short: '國語', english:'Guóyǔ, Taiwanese'}
};

Template.lang_sel.helpers({
	lgs: function() {
		return _.values(lgs);
	},

	short: function() {
		return lgs[Session.get('locale')].short;
	}

});

Template.lang_sel.events({
	'click a.langselect': function(e){
		mfPkg.setLocale(this.lg);
		localStorage.setItem('locale', this.lg);
		Session.set('locale', this.lg);
		e.preventDefault();
		if (Meteor.user()){
			Meteor.call('updateUserLocale', this.lg);
		}
	}
});

// Always load english translation
// For dynamically constructed translation strings there is no default
// translation and meteor would show the translation key if there is no
// translation in the current locale
mfPkg.loadLangs('en');
<|endoftext|>


<commit_before>ddescribe('refetchEvents', function() {
	describe('when agenda events are rerendered', function() {
		beforeEach(function() {
			affix('#cal');
		});

		it('keeps scroll after refetchEvents', function(done) {
			var renderCalls = 0;

			$('#cal').fullCalendar({
				now: '2015-08-07',
				scrollTime: '00:00',
				height: 400, // makes this test more consistent across viewports
				defaultView: 'agendaDay',
				events: function(start, end, timezone, callback) {
					setTimeout(function() {
						callback([
							{ id: '1', resourceId: 'b', start: '2015-08-07T02:00:00', end: '2015-08-07T07:00:00', title: 'event 1' },
							{ id: '2', resourceId: 'c', start: '2015-08-07T05:00:00', end: '2015-08-07T22:00:00', title: 'event 2' },
							{ id: '3', resourceId: 'd', start: '2015-08-06', end: '2015-08-08', title: 'event 3' },
							{ id: '4', resourceId: 'e', start: '2015-08-07T03:00:00', end: '2015-08-07T08:00:00', title: 'event 4' },
							{ id: '5', resourceId: 'f', start: '2015-08-07T00:30:00', end: '2015-08-07T02:30:00', title: 'event 5' }
						]);
					}, 100);
				},
				eventAfterAllRender: function() {
					var scrollEl = $('.fc-time-grid-container.fc-scroller');
					renderCalls++;
					if (renderCalls == 1) {
						setTimeout(function() {
							scrollEl.scrollTop(100);
							setTimeout(function() {
								$('#cal').fullCalendar('refetchEvents');
							}, 100);
						}, 100);
					}
					else if (renderCalls == 2) {
						expect(scrollEl.scrollTop()).toBe(100);
						done();
					}
				}
			});
		});
	});

	describe('when there are multiple event sources', function() {
		var options;
		var count;
		var currentCalendar;

		beforeEach(function() {
			affix('#cal');
			currentCalendar = $('#cal');
			options = {
				now: '2015-08-07',
				defaultView: 'agendaWeek',
				eventSources: [
					{
						events: createEvents(),
						color: 'green',
						id: 'source1'
					},
					{
						events: createEvents(),
						color: 'blue',
						id: 'source2'
					},
					{
						events: createEvents(),
						color: 'red',
						id: 'source3'
					}
				]
			};
		});

		describe('and all events are fetched synchronously', function() {
			it('all events are immediately updated', function(done) {
				count = 0;
				currentCalendar.fullCalendar(options);
				count++;
				currentCalendar.fullCalendar('refetchEvents');
				checkAllEvents();
				done();
			});
		});

		describe('and one event source is asynchronous', function() {
			it('original events remain on the calendar until all events have been refetched', function(done) {
				count = 0;
				// set a 100ms timeout on this event source
				options.eventSources[0].events = function(start, end, timezone, callback) {
					var events = [
						{ id: '1', start: '2015-08-07T02:00:00', end: '2015-08-07T03:00:00', title: 'event A', className: 'fetch' + count }
					];

					setTimeout(function() {
						callback(events);
					}, 100);
				};
				options.eventAfterAllRender = function() {
					count++;
					if (count === 1) {
						// after the initial rendering of events, call refetchEvents
						currentCalendar.fullCalendar('refetchEvents');

						expect($('.fetch0').length).toEqual(3); // original events still on the calendar
						expect($('.fetch1').length).toEqual(0); // new events not yet refetched

						setTimeout(function() {
							checkAllEvents();
							done();
						}, 100);
					}
				};

				currentCalendar.fullCalendar(options);
			});
		});

		function createEvents() {
			return function(start, end, timezone, callback) {
				var events = [
					{ id: 1, start: '2015-08-07T02:00:00', end: '2015-08-07T03:00:00', title: 'event A', className: 'fetch' + count }
				];

				callback(events);
			};
		}

		// Checks to make sure all refetched events have been rendered
		function checkAllEvents() {
			expect($('.fetch0').length).toEqual(0);
			expect($('.fetch1').length).toEqual(3);
		}
	});
});
<commit_msg>createEvents -> createEventGenerator. count -> fetchCount<commit_after>ddescribe('refetchEvents', function() {
	describe('when agenda events are rerendered', function() {
		beforeEach(function() {
			affix('#cal');
		});

		it('keeps scroll after refetchEvents', function(done) {
			var renderCalls = 0;

			$('#cal').fullCalendar({
				now: '2015-08-07',
				scrollTime: '00:00',
				height: 400, // makes this test more consistent across viewports
				defaultView: 'agendaDay',
				events: function(start, end, timezone, callback) {
					setTimeout(function() {
						callback([
							{ id: '1', resourceId: 'b', start: '2015-08-07T02:00:00', end: '2015-08-07T07:00:00', title: 'event 1' },
							{ id: '2', resourceId: 'c', start: '2015-08-07T05:00:00', end: '2015-08-07T22:00:00', title: 'event 2' },
							{ id: '3', resourceId: 'd', start: '2015-08-06', end: '2015-08-08', title: 'event 3' },
							{ id: '4', resourceId: 'e', start: '2015-08-07T03:00:00', end: '2015-08-07T08:00:00', title: 'event 4' },
							{ id: '5', resourceId: 'f', start: '2015-08-07T00:30:00', end: '2015-08-07T02:30:00', title: 'event 5' }
						]);
					}, 100);
				},
				eventAfterAllRender: function() {
					var scrollEl = $('.fc-time-grid-container.fc-scroller');
					renderCalls++;
					if (renderCalls == 1) {
						setTimeout(function() {
							scrollEl.scrollTop(100);
							setTimeout(function() {
								$('#cal').fullCalendar('refetchEvents');
							}, 100);
						}, 100);
					}
					else if (renderCalls == 2) {
						expect(scrollEl.scrollTop()).toBe(100);
						done();
					}
				}
			});
		});
	});

	describe('when there are multiple event sources', function() {
		var options;
		var fetchCount;
		var currentCalendar;

		beforeEach(function() {
			affix('#cal');
			currentCalendar = $('#cal');
			options = {
				now: '2015-08-07',
				defaultView: 'agendaWeek',
				eventSources: [
					{
						events: createEventGenerator(),
						color: 'green',
						id: 'source1'
					},
					{
						events: createEventGenerator(),
						color: 'blue',
						id: 'source2'
					},
					{
						events: createEventGenerator(),
						color: 'red',
						id: 'source3'
					}
				]
			};
		});

		describe('and all events are fetched synchronously', function() {
			it('all events are immediately updated', function(done) {
				fetchCount = 0;
				currentCalendar.fullCalendar(options);
				fetchCount++;
				currentCalendar.fullCalendar('refetchEvents');
				checkAllEvents();
				done();
			});
		});

		describe('and one event source is asynchronous', function() {
			it('original events remain on the calendar until all events have been refetched', function(done) {
				fetchCount = 0;
				// set a 100ms timeout on this event source
				options.eventSources[0].events = function(start, end, timezone, callback) {
					var events = [
						{ id: '1', start: '2015-08-07T02:00:00', end: '2015-08-07T03:00:00', title: 'event A', className: 'fetch' + fetchCount }
					];

					setTimeout(function() {
						callback(events);
					}, 100);
				};
				options.eventAfterAllRender = function() {
					fetchCount++;
					if (fetchCount === 1) {
						// after the initial rendering of events, call refetchEvents
						currentCalendar.fullCalendar('refetchEvents');

						expect($('.fetch0').length).toEqual(3); // original events still on the calendar
						expect($('.fetch1').length).toEqual(0); // new events not yet refetched

						setTimeout(function() {
							checkAllEvents();
							done();
						}, 100);
					}
				};

				currentCalendar.fullCalendar(options);
			});
		});

		function createEventGenerator() {
			return function(start, end, timezone, callback) {
				var events = [
					{ id: 1, start: '2015-08-07T02:00:00', end: '2015-08-07T03:00:00', title: 'event A', className: 'fetch' + fetchCount }
				];

				callback(events);
			};
		}

		// Checks to make sure all refetched events have been rendered
		function checkAllEvents() {
			expect($('.fetch0').length).toEqual(0);
			expect($('.fetch1').length).toEqual(3);
		}
	});
});
<|endoftext|>