<commit_before>'use strict';

const util = require('util');
const fs = require('fs');
const path = require('path');

var cfg;
var configFileName = path.join(__dirname, '../config.json');

function init() {
  _loadConfig();
}

function setCount(n) {
  if (util.isNumber(n) && n > 0) {
    cfg.count = n;
    _saveConfig();
    return true;
  } else {
    return false;
  }
}

function getCount() {
  return cfg.count;
}

function _saveConfig() {
  fs.writeFileSync(configFileName, JSON.stringify(cfg, null, 2));
  _loadConfig();
}

function _loadConfig() {
  cfg = JSON.parse(fs.readFileSync(configFileName, 'utf8'));
}

module.exports = {
  init: init,
  setCount: setCount,
  getCount: getCount
};
<commit_msg>add rgb and hex<commit_after>'use strict';

const util = require('util');
const fs = require('fs');
const path = require('path');

var cfg;
var configFileName = path.join(__dirname, '../config.json');

function init() {
  _loadConfig();
}

function setCount(n) {
  n = parseInt(n) || 1;
  if (util.isNumber(n) && n > 0) {
    cfg.count = n;
    _saveConfig();
    return true;
  } else {
    return false;
  }
}

function getCount() {
  return cfg.count;
}

function _saveConfig() {
  fs.writeFileSync(configFileName, JSON.stringify(cfg, null, 2));
  _loadConfig();
}

function _loadConfig() {
  cfg = JSON.parse(fs.readFileSync(configFileName, 'utf8'));
}

module.exports = {
  init: init,
  setCount: setCount,
  getCount: getCount
};
<|endoftext|>


<commit_before>/**
 * --------------------------------------------------------------------------
 * Bootstrap (v4.3.1): dom/manipulator.js
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * --------------------------------------------------------------------------
 */

const regexDataKey = /[A-Z]/g

function normalizeData(val) {
  if (val === 'true') {
    return true
  } else if (val === 'false') {
    return false
  } else if (val === 'null') {
    return null
  } else if (val === Number(val).toString()) {
    return Number(val)
  } else if (val === '') {
    return null
  }

  return val
}

function normalizeDataKey(key) {
  return key.replace(regexDataKey, (chr) => chr.toLowerCase())
}

const Manipulator = {
  setDataAttribute(element, key, value) {
    element.setAttribute(`data-${normalizeDataKey(key)}`, value)
  },

  removeDataAttribute(element, key) {
    element.removeAttribute(`data-${normalizeDataKey(key)}`)
  },

  getDataAttributes(element) {
    if (typeof element === 'undefined' || element === null) {
      return {}
    }

    let attributes
    if (Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'dataset')) {
      attributes = {
        ...element.dataset
      }
    } else {
      attributes = {}
      for (let i = 0; i < element.attributes.length; i++) {
        const attribute = element.attributes[i]

        if (attribute.nodeName.indexOf('data-') !== -1) {
          // remove 'data-' part of the attribute name
          const attributeName = attribute
            .nodeName
            .substring('data-'.length)
            .replace(/-./g, (str) => str.charAt(1).toUpperCase())

          attributes[attributeName] = attribute.nodeValue
        }
      }
    }

    Object.keys(attributes)
      .forEach((key) => {
        attributes[key] = normalizeData(attributes[key])
      })

    return attributes
  },

  getDataAttribute(element, key) {
    return normalizeData(element
      .getAttribute(`data-${normalizeDataKey(key)}`)
    )
  },

  offset(element) {
    const rect = element.getBoundingClientRect()

    return {
      top: rect.top + document.body.scrollTop,
      left: rect.left + document.body.scrollLeft
    }
  },

  position(element) {
    return {
      top: element.offsetTop,
      left: element.offsetLeft
    }
  },

  toggleClass(element, className) {
    if (typeof element === 'undefined' || element === null) {
      return
    }

    if (element.classList.contains(className)) {
      element.classList.remove(className)
    } else {
      element.classList.add(className)
    }
  }
}

export default Manipulator
<commit_msg>use only dataset to get data attributes<commit_after>/**
 * --------------------------------------------------------------------------
 * Bootstrap (v4.3.1): dom/manipulator.js
 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
 * --------------------------------------------------------------------------
 */

const regexDataKey = /[A-Z]/g

function normalizeData(val) {
  if (val === 'true') {
    return true
  } else if (val === 'false') {
    return false
  } else if (val === 'null') {
    return null
  } else if (val === Number(val).toString()) {
    return Number(val)
  } else if (val === '') {
    return null
  }

  return val
}

function normalizeDataKey(key) {
  return key.replace(regexDataKey, (chr) => chr.toLowerCase())
}

const Manipulator = {
  setDataAttribute(element, key, value) {
    element.setAttribute(`data-${normalizeDataKey(key)}`, value)
  },

  removeDataAttribute(element, key) {
    element.removeAttribute(`data-${normalizeDataKey(key)}`)
  },

  getDataAttributes(element) {
    if (!element) {
      return {}
    }

    const attributes = {
      ...element.dataset
    }

    Object.keys(attributes)
      .forEach((key) => {
        attributes[key] = normalizeData(attributes[key])
      })

    return attributes
  },

  getDataAttribute(element, key) {
    return normalizeData(element
      .getAttribute(`data-${normalizeDataKey(key)}`)
    )
  },

  offset(element) {
    const rect = element.getBoundingClientRect()

    return {
      top: rect.top + document.body.scrollTop,
      left: rect.left + document.body.scrollLeft
    }
  },

  position(element) {
    return {
      top: element.offsetTop,
      left: element.offsetLeft
    }
  },

  toggleClass(element, className) {
    if (typeof element === 'undefined' || element === null) {
      return
    }

    if (element.classList.contains(className)) {
      element.classList.remove(className)
    } else {
      element.classList.add(className)
    }
  }
}

export default Manipulator
<|endoftext|>


<commit_before>/** @jsx React.DOM */
var React = require("react");
var _ = require("lodash");

// TableSorter React Component
var TableSorter = module.exports = React.createClass({displayName: 'exports',
  getInitialState: function() {
    return {
      items: this.props.initialItems || [],
      sort: this.props.config.sort || { column: "", order: "" },
      columns: this.props.config.columns
    };
  },
  componentWillReceiveProps: function(nextProps) {
    // Load new data when the dataSource property changes.
    if (nextProps.dataSource != this.props.dataSource) {
      this.loadData(nextProps.dataSource);
    }
  },
  componentWillMount: function() {
    this.loadData(this.props.dataSource, this.props.data);
  },
  loadData: function(dataSource, data) {
    if (!data){
      request = new XMLHttpRequest();
      request.open('GET', dataSource, true);

      request.onload = function() {
        if (request.status >= 200 && request.status < 400){
          // Success!
          data = JSON.parse(request.responseText);
          console.log(data);
          data.forEach(function(item){
          for (var key in item) {
              // allows text or react components
              if(typeof item[key] !== 'object' || item[key].props) {
                item[key] = {"text":item[key]}
              }
            }
          });
          console.log("Received data");
          this.setState({items: data});
        } else {
          // We reached our target server, but it returned an error
          console.log("Error loading JSON");
        }
      }.bind(this);

      request.onerror = function() {
        // There was a connection error of some sort
        console.log("Connection error. Could not retrieve JSON");
      };

      request.send();
    } else{
      console.log(data);
      data.forEach(function(item){
      for (var key in item) {
          if(typeof item[key] !== 'object') {
            item[key] = {"text":item[key]}
          }
        }
      });
      this.setState({items: data});
   }
  },
  handleFilterTextChange: function(column) {
    return function(newValue) {
      var obj = this.state.columns;
      obj[column].filterText = newValue;

      // Since we have already mutated the state, just call forceUpdate().
      // Ideally we'd copy and setState or use an immutable data structure.
      this.forceUpdate();
    }.bind(this);
  },
  columnNames: function() {
     return Object.keys(this.state.columns);
  },
  sortColumn: function(column) {
    return function(event) {
      var newSortOrder = (this.state.sort.order == "asc") ? "desc" : "asc";

      if (this.state.sort.column != column) {
          newSortOrder = this.state.columns[column].defaultSortOrder;
      }

      this.setState({sort: { column: column, order: newSortOrder }});
    }.bind(this);
  },
  sortClass: function(column) {
    var ascOrDesc = (this.state.sort.order == "asc") ? "headerSortAsc" : "headerSortDesc";
    return (this.state.sort.column == column) ? ascOrDesc : "";
  },
  render: function() {
    var rows = [];

    var columnNames = this.columnNames();
    var filters = {};

      // Inequality function map for the filtering
    var operators = {
      "<": function(x, y) { return x < y; },
      "<=": function(x, y) { return x <= y; },
      ">": function(x, y) { return x > y; },
      ">=": function(x, y) { return x >= y; },
      "==": function(x, y) { return x == y; }
    };

    var operandRegex = /^((?:(?:[<>]=?)|==))\s?([-]?\d+(?:\.\d+)?)$/;

    columnNames.forEach(function(column) {
      var filterText = this.state.columns[column].filterText;
      filters[column] = null;

      if (filterText.length > 0) {
        operandMatch = operandRegex.exec(filterText);
        if (operandMatch && operandMatch.length == 3) {
          filters[column] = function(match) { return function(x) { return operators[match[1]](x, match[2]); }; }(operandMatch);
        } else {
          filters[column] = function(x) {
            return (x.toString().toLowerCase().indexOf(filterText.toLowerCase()) > -1);
          };
        }
      }
    }, this);

    var filteredItems = _.filter(this.state.items, function(item) {
      return _.every(columnNames, function(c) {
        return (!filters[c] || filters[c](item[c].text));
      }, this);
    }, this);

    var sortedItems = _.sortBy(filteredItems, this.state.sort.column);

    if (this.state.sort.order === "desc") sortedItems.reverse();

    var headerExtra = function() {
      return columnNames.map(function(c) {
        return React.DOM.th( {className:"header-extra"}, this.state.columns[c].name);
      }, this);
    }.bind(this);

    var cell = function(x) {
      return columnNames.map(function(c) {
        //custom link defined in data
        if (x[c].link){
          return React.DOM.td(null, React.DOM.a( {href:x[c].link}, x[c].text));
        // link defined in config for entire column
        } else if (this.props.config.columns[c].link) {
         var link = this.props.config.columns[c].link.replace("{cell}", x[c].text);
          return React.DOM.td(null, React.DOM.a( {href:link}, x[c]));
        // simple cell
        } else {
          return React.DOM.td(null, x[c].text);
        }
      }, this);
    }.bind(this);

    var keyIndex = 0;
    sortedItems.forEach(function(item, idx) {
      var headerRepeat = parseInt(this.props.headerRepeat, 10);
      if ((this.props.headerRepeat > 0) &&
          (idx > 0) &&
          (idx % this.props.headerRepeat === 0)) {

          rows.push (
            React.DOM.tr( {key:"header-"+keyIndex},
               headerExtra()
            )
          )
      }

      rows.push(
        React.DOM.tr( {key:keyIndex},
           cell(item)
        )
      );
      keyIndex++;
    }.bind(this));

    var filterLink = function(column) {
      return {
        value: this.state.columns[column].filterText,
        requestChange: this.handleFilterTextChange(column)
      };
    }.bind(this);

    var header = columnNames.map(function(c) {
      return React.DOM.th( {onClick:this.sortColumn(c), className:"header " + this.sortClass(c)}, this.state.columns[c].name);
    }, this);

    var filterInputs = columnNames.map(function(c) {
      return React.DOM.td(null, React.DOM.input( {type:"text", valueLink:filterLink(c)} ));
    }, this);

    return (
      React.DOM.table( {cellSpacing:"0", className:"tablesorter"},
        React.DOM.thead(null,
          React.DOM.tr(null,
             header
          ),
          React.DOM.tr(null,
             filterInputs
          )
        ),
        React.DOM.tbody(null,
           rows
        )
      )
    );
  }
});
<commit_msg>allow for data prop to update as well as dataSource<commit_after>/** @jsx React.DOM */
var React = require("react");
var _ = require("lodash");

// TableSorter React Component
var TableSorter = module.exports = React.createClass({displayName: 'exports',
  getInitialState: function() {
    return {
      items: this.props.initialItems || [],
      sort: this.props.config.sort || { column: "", order: "" },
      columns: this.props.config.columns
    };
  },
  componentWillReceiveProps: function(nextProps) {
    // Load new data when the dataSource property changes.
    if (nextProps.dataSource != this.props.dataSource || nextProps.data != this.props.data) {
      this.loadData(nextProps.dataSource, nextProps.data);
    }
  },
  componentWillMount: function() {
    this.loadData(this.props.dataSource, this.props.data);
  },
  loadData: function(dataSource, data) {
    if (!data){
      request = new XMLHttpRequest();
      request.open('GET', dataSource, true);

      request.onload = function() {
        if (request.status >= 200 && request.status < 400){
          // Success!
          data = JSON.parse(request.responseText);
          console.log(data);
          data.forEach(function(item){
          for (var key in item) {
              // allows text or react components
              if(typeof item[key] !== 'object' || item[key].props) {
                item[key] = {"text":item[key]}
              }
            }
          });
          console.log("Received data");
          this.setState({items: data});
        } else {
          // We reached our target server, but it returned an error
          console.log("Error loading JSON");
        }
      }.bind(this);

      request.onerror = function() {
        // There was a connection error of some sort
        console.log("Connection error. Could not retrieve JSON");
      };

      request.send();
    } else{
      console.log(data);
      data.forEach(function(item){
      for (var key in item) {
          if(typeof item[key] !== 'object') {
            item[key] = {"text":item[key]}
          }
        }
      });
      this.setState({items: data});
   }
  },
  handleFilterTextChange: function(column) {
    return function(newValue) {
      var obj = this.state.columns;
      obj[column].filterText = newValue;

      // Since we have already mutated the state, just call forceUpdate().
      // Ideally we'd copy and setState or use an immutable data structure.
      this.forceUpdate();
    }.bind(this);
  },
  columnNames: function() {
     return Object.keys(this.state.columns);
  },
  sortColumn: function(column) {
    return function(event) {
      var newSortOrder = (this.state.sort.order == "asc") ? "desc" : "asc";

      if (this.state.sort.column != column) {
          newSortOrder = this.state.columns[column].defaultSortOrder;
      }

      this.setState({sort: { column: column, order: newSortOrder }});
    }.bind(this);
  },
  sortClass: function(column) {
    var ascOrDesc = (this.state.sort.order == "asc") ? "headerSortAsc" : "headerSortDesc";
    return (this.state.sort.column == column) ? ascOrDesc : "";
  },
  render: function() {
    var rows = [];

    var columnNames = this.columnNames();
    var filters = {};

      // Inequality function map for the filtering
    var operators = {
      "<": function(x, y) { return x < y; },
      "<=": function(x, y) { return x <= y; },
      ">": function(x, y) { return x > y; },
      ">=": function(x, y) { return x >= y; },
      "==": function(x, y) { return x == y; }
    };

    var operandRegex = /^((?:(?:[<>]=?)|==))\s?([-]?\d+(?:\.\d+)?)$/;

    columnNames.forEach(function(column) {
      var filterText = this.state.columns[column].filterText;
      filters[column] = null;

      if (filterText.length > 0) {
        operandMatch = operandRegex.exec(filterText);
        if (operandMatch && operandMatch.length == 3) {
          filters[column] = function(match) { return function(x) { return operators[match[1]](x, match[2]); }; }(operandMatch);
        } else {
          filters[column] = function(x) {
            return (x.toString().toLowerCase().indexOf(filterText.toLowerCase()) > -1);
          };
        }
      }
    }, this);

    var filteredItems = _.filter(this.state.items, function(item) {
      return _.every(columnNames, function(c) {
        return (!filters[c] || filters[c](item[c].text));
      }, this);
    }, this);

    var sortedItems = _.sortBy(filteredItems, this.state.sort.column);

    if (this.state.sort.order === "desc") sortedItems.reverse();

    var headerExtra = function() {
      return columnNames.map(function(c) {
        return React.DOM.th( {className:"header-extra"}, this.state.columns[c].name);
      }, this);
    }.bind(this);

    var cell = function(x) {
      return columnNames.map(function(c) {
        //custom link defined in data
        if (x[c].link){
          return React.DOM.td(null, React.DOM.a( {href:x[c].link}, x[c].text));
        // link defined in config for entire column
        } else if (this.props.config.columns[c].link) {
         var link = this.props.config.columns[c].link.replace("{cell}", x[c].text);
          return React.DOM.td(null, React.DOM.a( {href:link}, x[c]));
        // simple cell
        } else {
          return React.DOM.td(null, x[c].text);
        }
      }, this);
    }.bind(this);

    var keyIndex = 0;
    sortedItems.forEach(function(item, idx) {
      var headerRepeat = parseInt(this.props.headerRepeat, 10);
      if ((this.props.headerRepeat > 0) &&
          (idx > 0) &&
          (idx % this.props.headerRepeat === 0)) {

          rows.push (
            React.DOM.tr( {key:"header-"+keyIndex},
               headerExtra()
            )
          )
      }

      rows.push(
        React.DOM.tr( {key:keyIndex},
           cell(item)
        )
      );
      keyIndex++;
    }.bind(this));

    var filterLink = function(column) {
      return {
        value: this.state.columns[column].filterText,
        requestChange: this.handleFilterTextChange(column)
      };
    }.bind(this);

    var header = columnNames.map(function(c) {
      return React.DOM.th( {onClick:this.sortColumn(c), className:"header " + this.sortClass(c)}, this.state.columns[c].name);
    }, this);

    var filterInputs = columnNames.map(function(c) {
      return React.DOM.td(null, React.DOM.input( {type:"text", valueLink:filterLink(c)} ));
    }, this);

    return (
      React.DOM.table( {cellSpacing:"0", className:"tablesorter"},
        React.DOM.thead(null,
          React.DOM.tr(null,
             header
          ),
          React.DOM.tr(null,
             filterInputs
          )
        ),
        React.DOM.tbody(null,
           rows
        )
      )
    );
  }
});
<|endoftext|>


<commit_before>// This function makes it so that when the disclaimer is clicked, an active class is set.

$(function() {
    $(".disclaimer-button").click(function() {
       $(".disclaimer-button").addClass('disclaimer-button-active');
       active = true;
          if (active) {
            $(".disclaimer-button").click(function() {
                $(".disclaimer-button").removeClass('disclaimer-button-active');
                active = false;
          });
        }
    });
 });
<commit_msg>Updating disclaimer area<commit_after>// This function makes it so that when the disclaimer is clicked, an active class is set.

$(function() {
    $(".disclaimer-button").click(function() {
       $(".disclaimer-button").addClass('disclaimer-button-active');
       active = false;
          if (active) {
            $(".disclaimer-button").click(function() {
                $(".disclaimer-button").removeClass('disclaimer-button-active');
                active = true;
          });
        }
    });
 });
<|endoftext|>


<commit_before>/*global describe, it, expect*/
describe('Transport/Index', function () {
    'use strict';

    var path = require('path');
    var rootPath = path.resolve(__dirname, '../', '../', 'lib');
    var appMock = require('../mocks/appMock')();
    var baboon = appMock.baboon;
    var transport = require(path.resolve(rootPath, 'transport', 'index'));
    var sut;

    it('should throw an Error when not given params', function () {
        var func = function () {
            return transport();
        };
        expect(func).toThrow();
    });

    it('should throw an Error when not given param.config', function () {
        var func = function () {
            return transport({});
        };
        expect(func).toThrow();
    });

    it('should be initialzied correctly', function () {
        var sut = transport(baboon);

        expect(sut.getControllers).toBeDefined();
        expect(sut.addController).toBeDefined();
        expect(sut.processRequest).toBeDefined();
        expect(sut.registerSocketEvents).toBeDefined();
    });

    it('should be initialzied correctly with missing param "config.useRightSystem"', function () {
        var sut = transport({
            config: {
                path: {
                    modules: path.join(path.resolve('./test/mocks'), 'server', 'modules')
                }
            }
        });

        expect(sut.getControllers).toBeDefined();
        expect(sut.addController).toBeDefined();
        expect(sut.processRequest).toBeDefined();
        expect(sut.registerSocketEvents).toBeDefined();
    });

    describe('.getControllers()', function () {
        beforeEach(function () {
            sut = transport(baboon);
        });

        it('should return object of controllers and their actions', function () {
            var controllers = sut.getControllers();

            expect(Object.keys(controllers).length).toBe(2);

            var actions = controllers[Object.keys(controllers)[0]];
            expect(Object.keys(actions).length).toBe(3);
        });
    });

    describe('.addController()', function () {
        beforeEach(function () {
            sut = transport(baboon);
        });

        it('should add a controller with wrong action signatures', function () {
            var controllerNotOk = {
                foo1: function () {},
                foo2: function (data) {return data;},
                foo3: function (data, request) {return [data, request];},
                foo4: function (data, callback) {callback(data);},
                foo5: function (request, callback) {callback(request);},
                foo6: function (data, request, callback, bar) {callback([data, request, bar]);}
            };

            sut.addController(controllerNotOk, 'user/rights/', null);
            var controllers = sut.getControllers();
            expect(Object.keys(controllers).length).toBe(2);

            var actions = controllers[Object.keys(controllers)[0]];
            expect(Object.keys(actions).length).toBe(3);
        });

        it('should add a controller with actions', function () {
            var controllerOk = {
                read: function (data, request, callback) {callback([data, request]);},
                write: function (data, request, callback) {callback([data, request]);},
                remove: function (data, request, callback) {callback([data, request]);}
            };

            sut.addController(controllerOk, 'user/rights', null);

            var controllers = sut.getControllers();
            expect(Object.keys(controllers).length).toBe(3);

            var actions = controllers[Object.keys(controllers)[2]];
            expect(Object.keys(actions).length).toBe(3);
        });

        it('should do nothing when file does not exist', function () {
            var file = path.resolve(__dirname, '..', 'mocks', 'server', 'employees');

            sut.addController(file, 'user/rights', null);

            var controllers = sut.getControllers();
            expect(Object.keys(controllers).length).toBe(2);

            var actions = controllers[Object.keys(controllers)[0]];
            expect(Object.keys(actions).length).toBe(3);
        });

        it('should add a controller file with actions', function () {
            var file = path.resolve(__dirname, '..', 'mocks', 'server', 'employees.js');

            sut.addController(file, 'user/rights', null);

            var controllers = sut.getControllers();
            expect(Object.keys(controllers).length).toBe(3);

            var actions = controllers[Object.keys(controllers)[1]];
            expect(Object.keys(actions).length).toBe(1);
        });
    });

    describe('.processRequest()', function () {
        it('should process the request and call the corresponding action with rightsystem disabled', function (done) {
            var req = appMock.req;
            var res = {
                json: function(code, value){
                    expect(code).toBe(200);
                    expect(value).toBeDefined();
                    expect(value.length).toBe(5);

                    done();
                }
            };

            req.originalUrl = '/api/common/awesomeThings/index/getAll';

            sut = transport(baboon);
            sut.processRequest(req, res);
        });

//        it('should process the request and return access denied when right system is enabled and user has no access', function (done) {
//            var req = appMock.req;
//            var res = {
//                json: function(code, value){
//                    expect(code).toBe(403);
//                    expect(value).toBe('Access denied.');
//
//                    done();
//                }
//            };
//
//            req.originalUrl = '/api/common/awesomeThings/index/getAll';
//
//            baboon.config.useRightSystem = true;
//            sut = transport(baboon);
//            sut.processRequest(req, res);
//            baboon.config.useRightSystem = false;
//        });

        it('should process the request and return wrong url', function (done) {
            var req = appMock.req;
            var res = {
                json: function(code, value){
                    expect(code).toBe(403);
                    expect(value).toBe('Wrong url');

                    done();
                }
            };

            req.originalUrl = '/api/common/awesomeThings/index/foo';

            sut = transport(baboon);
            sut.processRequest(req, res);
        });

        it('should process the request and return raised error', function (done) {
            var req = appMock.req;
            var res = {
                json: function(code, value){
                    expect(code).toBe(401);
                    expect(value).toBe('Error raised');

                    done();
                }
            };

            req.originalUrl = '/api/common/awesomeThings/index/raiseError';

            sut = transport(baboon);
            sut.processRequest(req, res);
        });

        it('should process the request and process the session', function (done) {
            var req = appMock.req;
            var res = {
                json: function(code, value){
                    expect(code).toBe(200);
                    expect(value).toBeDefined();

                    done();
                }
            };

            req.originalUrl = '/api/common/awesomeThings/index/sessionTest';

            sut = transport(baboon);
            sut.processRequest(req, res);
        });
    });

    describe('.registerSocketEvents()', function () {
        it('should register events on socket', function (done) {
            var socket = appMock.socket;
            socket.events = {};

            sut = transport(baboon);
            sut.registerSocketEvents(socket);

            expect(Object.keys(socket.events).length).toBe(4);

            socket.events['api/common/awesomeThings/index/getAll']({}, function(error, result){
                expect(error).toBeNull();
                expect(result).toBeDefined();
                expect(result.length).toBe(5);

                done();
            });
        });

//        it('should not register events on socket if right system is enabled and user has no access', function () {
//            var socket = appMock.socket;
//            socket.events = {};
//
//            baboon.config.useRightSystem = true;
//            sut = transport(baboon);
//            sut.registerSocketEvents(socket);
//            baboon.config.useRightSystem = false;
//
//            expect(Object.keys(socket.events).length).toBe(0);
//        });
    });
});<commit_msg>chore(transport): tests angepasst<commit_after>/*global describe, it, expect*/
describe('Transport/Index', function () {
    'use strict';

    var path = require('path');
    var rootPath = path.resolve(__dirname, '../', '../', 'lib');
    var appMock = require('../mocks/appMock')();
    var baboon = appMock.baboon;
    var transport = require(path.resolve(rootPath, 'transport', 'index'));
    var sut;

    it('should throw an Error when not given params', function () {
        var func = function () {
            return transport();
        };
        expect(func).toThrow();
    });

    it('should throw an Error when not given param.config', function () {
        var func = function () {
            return transport({});
        };
        expect(func).toThrow();
    });

    it('should be initialzied correctly', function () {
        var sut = transport(baboon);

        expect(sut.getControllers).toBeDefined();
        expect(sut.addController).toBeDefined();
        expect(sut.processRequest).toBeDefined();
        expect(sut.registerSocketEvents).toBeDefined();
    });

    it('should be initialzied correctly with missing param "config.useRightSystem"', function () {
        var sut = transport({
            config: {
                path: {
                    modules: path.join(path.resolve('./test/mocks'), 'server', 'modules')
                }
            }
        });

        expect(sut.getControllers).toBeDefined();
        expect(sut.addController).toBeDefined();
        expect(sut.processRequest).toBeDefined();
        expect(sut.registerSocketEvents).toBeDefined();
    });

    describe('.getControllers()', function () {
        beforeEach(function () {
            sut = transport(baboon);
        });

        it('should return object of controllers and their actions', function () {
            var controllers = sut.getControllers();

            expect(Object.keys(controllers).length).toBe(2);

            var actions = controllers[Object.keys(controllers)[0]];
            expect(Object.keys(actions).length).toBe(3);
        });
    });

    describe('.addController()', function () {
        beforeEach(function () {
            sut = transport(baboon);
        });

        it('should add a controller with wrong action signatures', function () {
            var controllerNotOk = {
                foo1: function () {},
                foo2: function (data) {return data;},
                foo3: function (data, request) {return [data, request];},
                foo4: function (data, callback) {callback(data);},
                foo5: function (request, callback) {callback(request);},
                foo6: function (data, request, callback, bar) {callback([data, request, bar]);}
            };

            sut.addController(controllerNotOk, 'user/rights/', null);
            var controllers = sut.getControllers();
            expect(Object.keys(controllers).length).toBe(2);

            var actions = controllers[Object.keys(controllers)[0]];
            expect(Object.keys(actions).length).toBe(3);
        });

        it('should add a controller with actions', function () {
            var controllerOk = {
                read: function (data, request, callback) {callback([data, request]);},
                write: function (data, request, callback) {callback([data, request]);},
                remove: function (data, request, callback) {callback([data, request]);}
            };

            sut.addController(controllerOk, 'user/rights', null);

            var controllers = sut.getControllers();
            expect(Object.keys(controllers).length).toBe(3);

            var actions = controllers[Object.keys(controllers)[2]];
            expect(Object.keys(actions).length).toBe(3);
        });

        it('should do nothing when file does not exist', function () {
            var file = path.resolve(__dirname, '..', 'mocks', 'server', 'employees');

            sut.addController(file, 'user/rights', null);

            var controllers = sut.getControllers();
            expect(Object.keys(controllers).length).toBe(2);

            var actions = controllers[Object.keys(controllers)[0]];
            expect(Object.keys(actions).length).toBe(3);
        });

        it('should add a controller file with actions', function () {
            var file = path.resolve(__dirname, '..', 'mocks', 'server', 'employees.js');

            sut.addController(file, 'user/rights', null);

            var controllers = sut.getControllers();
            expect(Object.keys(controllers).length).toBe(3);

            var actions = controllers[Object.keys(controllers)[1]];
            expect(Object.keys(actions).length).toBe(1);
        });
    });

    describe('.processRequest()', function () {
        it('should process the request and call the corresponding action with rightsystem disabled', function (done) {
            var req = appMock.req;
            var res = {
                json: function(code, value){
                    expect(code).toBe(200);
                    expect(value).toBeDefined();
                    expect(value.length).toBe(5);

                    done();
                }
            };

            req.originalUrl = '/api/common/awesomeThings/index/getAll';

            sut = transport(baboon);
            sut.processRequest(req, res);
        });

        it('should process the request and return wrong url', function (done) {
            var req = appMock.req;
            var res = {
                json: function(code, value){
                    expect(code).toBe(403);
                    expect(value).toBe('Wrong url');

                    done();
                }
            };

            req.originalUrl = '/api/common/awesomeThings/index/foo';

            sut = transport(baboon);
            sut.processRequest(req, res);
        });

        it('should process the request and return raised error', function (done) {
            var req = appMock.req;
            var res = {
                json: function(code, value){
                    expect(code).toBe(401);
                    expect(value).toBe('Error raised');

                    done();
                }
            };

            req.originalUrl = '/api/common/awesomeThings/index/raiseError';

            sut = transport(baboon);
            sut.processRequest(req, res);
        });

        it('should process the request and process the session', function (done) {
            var req = appMock.req;
            var res = {
                json: function(code, value){
                    expect(code).toBe(200);
                    expect(value).toBeDefined();

                    done();
                }
            };

            req.originalUrl = '/api/common/awesomeThings/index/sessionTest';

            sut = transport(baboon);
            sut.processRequest(req, res);
        });
    });

    describe('.registerSocketEvents()', function () {
        it('should register events on socket', function (done) {
            var socket = appMock.socket;
            socket.events = {};

            sut = transport(baboon);
            sut.registerSocketEvents(socket);

            expect(Object.keys(socket.events).length).toBe(4);

            socket.events['api/common/awesomeThings/index/getAll']({}, function(error, result){
                expect(error).toBeNull();
                expect(result).toBeDefined();
                expect(result.length).toBe(5);

                done();
            });
        });
    });
});<|endoftext|>


<commit_before>var gulp = require('gulp')
var babel = require('gulp-babel')
var del = require('del')
var exec = require('child_process').exec
var eslint = require('gulp-eslint')
var run = require('run-sequence')

gulp.task('dbuild', function () {
  return gulp.src('./src/**/*.js')
    .pipe(babel({ presets: ['es2015'], plugins: ['lodash', 'transform-runtime'], env: { development: { sourceMaps: 'inline' } } }))
    .pipe(gulp.dest('./build'))
})

gulp.task('pbuild', function () {
  return gulp.src('./src/**/*.js')
    .pipe(babel({ presets: ['es2015'], plugins: ['lodash', 'transform-runtime'] }))
    .pipe(gulp.dest('./build'))
})

gulp.task('delete', function () {
  return del([
    'build/**/*',
    'build',
    'coverage/**/*',
    'coverage',
    '.nyc_output/*',
    '.nyc_output',
    'test/output/*',
    'test/output'
  ])
})

gulp.task('clean', function (cb) {
  return run('delete', 'dbuild', cb)
})

gulp.task('lint', function () {
  return gulp.src(['**/**/*.js', '!node_modules/**/*.*', '!build/**/*.js', '!bin/**/*.js'])
    .pipe(eslint.format())
})

gulp.task('coveralls', function () {
  return gulp.src('coverage/lcov.info')
    .pipe(coveralls())
})

gulp.task('test', function (cb) {
  exec('npm test', function (err, stdout, stderr) {
    console.log(stdout)
    console.log(stderr)
    cb(err)
  })
})

gulp.task('bin', function (cb) {
  return run('dbuild', cb)
})

gulp.task('default', function (cb) {
  return run('clean', 'test', cb)
})

gulp.task('all', function (cb) {
  return run('clean', 'lint', 'test', cb)
})
<commit_msg>chore(gulp): remove unnecessary tasks<commit_after>var gulp = require('gulp')
var babel = require('gulp-babel')
var del = require('del')
var eslint = require('gulp-eslint')
var run = require('run-sequence')

gulp.task('dbuild', function () {
  return gulp.src('./src/**/*.js')
    .pipe(babel({ presets: ['es2015'], plugins: ['lodash', 'transform-runtime'], env: { development: { sourceMaps: 'inline' } } }))
    .pipe(gulp.dest('./build'))
})

gulp.task('pbuild', function () {
  return gulp.src('./src/**/*.js')
    .pipe(babel({ presets: ['es2015'], plugins: ['lodash', 'transform-runtime'] }))
    .pipe(gulp.dest('./build'))
})

gulp.task('delete', function () {
  return del([
    'build/**/*',
    'build',
    'coverage/**/*',
    'coverage',
    '.nyc_output/*',
    '.nyc_output',
    'test/output/*',
    'test/output'
  ])
})

gulp.task('clean', function (cb) {
  return run('delete', 'dbuild', cb)
})

gulp.task('lint', function () {
  return gulp.src(['**/**/*.js', '!node_modules/**/*.*', '!build/**/*.js'])
    .pipe(eslint.format())
})

gulp.task('bin', function (cb) {
  return run('dbuild', cb)
})

gulp.task('default', function (cb) {
  return run('clean', 'test', cb)
})

gulp.task('all', function (cb) {
  return run('clean', 'lint', 'test', cb)
})
<|endoftext|>


<commit_before>/*
 * == BSD2 LICENSE ==
 * Copyright (c) 2014, Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 * == BSD2 LICENSE ==
 */

var _ = require('lodash');
var util = require('util');

/* global __TEST__ */

var schema = require('./validator/schematron');

var log;
if (typeof window !== 'undefined' && __TEST__ !== true) {
  log = console.log;
}
else {
  log = function() {};
}

var schemas = {
  basal: require('./basal'),
  bolus: require('./bolus'),
  cbg: require('./bg'),
  common: require('./common'),
  deviceEvent: schema(),
  message: require('./message'),
  pumpSettings: require('./pumpSettings'),
  smbg: require('./bg'),
  upload: require('./upload'),
  wizard: require('./wizard')
};

module.exports = {
  validateOne: function(datum, result) {
    result = result || {valid: [], invalid: []};
    var handler = schemas[datum.type];
    if (handler == null) {
      datum.errorMessage = util.format('No schema defined for data.type[%s]', datum.type);
      console.log(new Error(datum.errorMessage), datum);
      result.invalid.push(datum);
    }
    else {
      try {
        handler(datum);
        result.valid.push(datum);
      }
      catch(e) {
        log('Oh noes! This is wrong:\n', datum);
        log(util.format('Error Message: %s%s', datum.type, e.message));
        datum.errorMessage = e.message;
        result.invalid.push(datum);
      }
    }
  },
  validateAll: function(data) {
    var result = {valid: [], invalid: []};
    for (var i = 0; i < data.length; ++i) {
      this.validateOne(data[i], result);
    }
    return result;
  }
};
<commit_msg>fix conditional logging to stop throwing an Illegal Invocation<commit_after>/*
 * == BSD2 LICENSE ==
 * Copyright (c) 2014, Tidepool Project
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the associated License, which is identical to the BSD 2-Clause
 * License as published by the Open Source Initiative at opensource.org.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the License for more details.
 *
 * You should have received a copy of the License along with this program; if
 * not, you can obtain one from Tidepool Project at tidepool.org.
 * == BSD2 LICENSE ==
 */

var _ = require('lodash');
var util = require('util');

/* global __TEST__ */

var schema = require('./validator/schematron');

var log;
if (typeof window !== 'undefined' && __TEST__ !== true) {
  log = console.log.bind(console);
}
else {
  log = function() {};
}

var schemas = {
  basal: require('./basal'),
  bolus: require('./bolus'),
  cbg: require('./bg'),
  common: require('./common'),
  deviceEvent: schema(),
  message: require('./message'),
  pumpSettings: require('./pumpSettings'),
  smbg: require('./bg'),
  upload: require('./upload'),
  wizard: require('./wizard')
};

module.exports = {
  validateOne: function(datum, result) {
    result = result || {valid: [], invalid: []};
    var handler = schemas[datum.type];
    if (handler == null) {
      datum.errorMessage = util.format('No schema defined for data.type[%s]', datum.type);
      log(new Error(datum.errorMessage), datum);
      result.invalid.push(datum);
    }
    else {
      try {
        handler(datum);
        result.valid.push(datum);
      }
      catch(e) {
        log('Oh noes! This is wrong:\n', datum);
        log(util.format('Error Message: %s%s', datum.type, e.message));
        datum.errorMessage = e.message;
        result.invalid.push(datum);
      }
    }
  },
  validateAll: function(data) {
    var result = {valid: [], invalid: []};
    for (var i = 0; i < data.length; ++i) {
      this.validateOne(data[i], result);
    }
    return result;
  }
};
<|endoftext|>


<commit_before>'use strict';

var integration = require('@astronomerio/analytics.js-integration');

/*
 *Expose 'Netmining' integration.
 */

var Netmining = module.exports = integration('Netmining')
.option('src', '')
.option('aid', '')
.tag('<script type="text/javascript" async="" src="{{ src }}?aid={{ aid }}&siclientid=">')

/*
* Initialize Netmining
*/

Netmining.prototype.initialize = function() {
    this.load(this.ready);
};
<commit_msg>Added semicolon<commit_after>'use strict';

var integration = require('@astronomerio/analytics.js-integration');

/*
 *Expose 'Netmining' integration.
 */

var Netmining = module.exports = integration('Netmining')
.option('src', '')
.option('aid', '')
.tag('<script type="text/javascript" async="" src="{{ src }}?aid={{ aid }}&siclientid=">');

/*
* Initialize Netmining
*/

Netmining.prototype.initialize = function() {
    this.load(this.ready);
};
<|endoftext|>


<commit_before>var expect = require('expect.js')
var Treasure = require('../lib/treasure')

describe('Treasure Client', function () {
  var treasure
  var configuration

  function resetConfiguration () {
    configuration = {
      database: 'database',
      writeKey: 'writeKey',
      development: true,
      logging: false
    }
  }

  beforeEach(resetConfiguration)
  beforeEach(function () {
    var DEFAULT_CONFIG = Treasure.prototype._configurator._generateDefaultConfig()
    Treasure.prototype._configurator.DEFAULT_CONFIG = DEFAULT_CONFIG
    treasure = new Treasure(configuration)
  })

  describe('DEFAULT_CONFIG', function () {
    beforeEach(resetConfiguration)

    it('should allow you to set default values', function () {
      Treasure.prototype._configurator.DEFAULT_CONFIG.host = 'foo.bar'
      treasure = new Treasure(configuration)
      expect(treasure.client.host).to.equal('foo.bar')
    })

    it('should allow you to overwrite default config', function () {
      Treasure.prototype._configurator.DEFAULT_CONFIG.host = 'foo.bar'
      configuration.host = 'bar.baz'
      treasure = new Treasure(configuration)
      expect(treasure.client.host).to.equal('bar.baz')
    })

    it('should allow objectless instantiation if all required values are defaults', function () {
      Treasure.prototype._configurator.DEFAULT_CONFIG.database = 'database'
      Treasure.prototype._configurator.DEFAULT_CONFIG.writeKey = 'writeKey'
      treasure = new Treasure()
      expect(treasure.client.database).to.equal('database')
      expect(treasure.client.writeKey).to.equal('writeKey')
    })

    it('should throw if writeKey is missing', function () {
      Treasure.prototype._configurator.DEFAULT_CONFIG.database = 'database'
      expect(function () {
        return new Treasure()
      }).to.throwException()
    })

    it('should throw if database is missing', function () {
      Treasure.prototype._configurator.DEFAULT_CONFIG.writeKey = 'writeKey'
      expect(function () {
        return new Treasure()
      }).to.throwException()
    })
  })

  describe('constructor', function () {
    it('should create a new Treasure instance when called without new', function () {
      expect(Treasure(configuration)).to.be.a(Treasure)
    })

    it('should create a new Treasure instance', function () {
      expect(treasure).to.be.a(Treasure)
    })

    it('should error if no configuration object', function () {
      expect(function () {
        (treasure = new Treasure())
      }).to.throwException()
    })

    it('should create a new client object', function () {
      expect(treasure.client).to.be.an('object')
    })

    it('should create a globals object on client', function () {
      expect(treasure.client.globals).to.be.an('object')
    })

    it('should set defaults on client object', function () {
      var client = treasure.client
      expect(client.protocol).to.be.a('string')
      expect(client.host).to.be.a('string')
      expect(client.pathname).to.be.a('string')
      expect(client.requestType).to.be.a('string')
      expect(client.development).to.be.a('boolean')
      expect(client.logging).to.be.a('boolean')
      expect(client.endpoint).to.be.a('string')
    })

    it('should allow you to manually set values on client', function () {
      configuration.host = configuration.pathname = configuration.endpoint = 'foo'
      treasure = new Treasure(configuration)
      expect(treasure.client.host).to.equal('foo')
      expect(treasure.client.pathname).to.equal('foo')
      expect(treasure.client.endpoint).to.equal('foo')
    })

    describe('validates database', function () {
      var tryWithDatabaseValue = function (value) {
        configuration.database = value
        expect(function () {
          (treasure = new Treasure(configuration))
        }).to.throwException()
      }

      it('should error if database is absent', function () {
        tryWithDatabaseValue(undefined)
      })

      it('should error if database is of incorrect type', function () {
        // Number
        tryWithDatabaseValue(0)

        // Boolean
        tryWithDatabaseValue(false)

        // Array
        tryWithDatabaseValue(['array'])

        // Object
        tryWithDatabaseValue({})
      })

      it('should error if database is invalid', function () {
        // Empty string
        tryWithDatabaseValue('')

        // Under 3 characters
        tryWithDatabaseValue('12')

        // Over 255 characters
        tryWithDatabaseValue('1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111')

        // Uppercase chracters
        tryWithDatabaseValue('FOO_BAR')

        // Special characters
        tryWithDatabaseValue('!@#$%ˆ&*()-+=')
      })

      it('should set the database (string)', function () {
        expect(typeof treasure.client.database).to.be('string')
        expect(treasure.client.database).to.equal(configuration.database)
      })
    })

    describe('validates writeKey', function () {
      it('should error if writeKey is not set', function () {
        delete configuration.writeKey
        expect(function () {
          (treasure = new Treasure(configuration))
        }).to.throwException()
      })

      it('should set the writeKey (string)', function () {
        expect(typeof treasure.client.writeKey).to.be('string')
        expect(treasure.client.writeKey).to.equal(configuration.writeKey)
      })
    })

    describe('validates endpoint', function () {
      it('should set protocol to "https:" if designated as "https:"', function () {
        configuration.protocol = 'https:'
        treasure = new Treasure(configuration)
        expect(treasure.client.endpoint.indexOf('https://')).to.equal(0)
      })

      it('should set protocol to "http:" if designated as "http:"', function () {
        configuration.protocol = 'http:'
        treasure = new Treasure(configuration)
        expect(treasure.client.endpoint.indexOf('http://')).to.equal(0)
      })

      it('should set protocol to "https:" if designated as "https"', function () {
        configuration.protocol = 'https'
        treasure = new Treasure(configuration)
        expect(treasure.client.endpoint.indexOf('https://')).to.equal(0)
      })

      it('should set protocol to "http:" if designated as "http"', function () {
        configuration.protocol = 'http'
        treasure = new Treasure(configuration)
        expect(treasure.client.endpoint.indexOf('http://')).to.equal(0)
      })
    })

    describe('validates request type', function () {
      it('should set request type to "jsonp"', function () {
        expect(typeof treasure.client.requestType).to.be('string')
        expect(treasure.client.requestType).to.equal('jsonp')
      })

      it('should always set request type to "jsonp"', function () {
        configuration.requestType = 'xhr'
        treasure = new Treasure(configuration)
        expect(typeof treasure.client.requestType).to.be('string')
        expect(treasure.client.requestType).to.equal('jsonp')
      })
    })
  })
})
<commit_msg>Improve test handling of default configs<commit_after>var _ = require('lodash-compat')
var expect = require('expect.js')
var Treasure = require('../lib/treasure')

// Copy the default config because we change it later in tests
var DEFAULT_CONFIG = _.assign({}, Treasure.prototype._configurator.DEFAULT_CONFIG)

describe('Treasure Client', function () {
  var treasure
  var configuration

  function resetConfiguration () {
    configuration = {
      database: 'database',
      writeKey: 'writeKey',
      development: true,
      logging: false
    }
  }

  beforeEach(resetConfiguration)
  beforeEach(function () {
    treasure = new Treasure(configuration)
  })

  afterEach(function () {
    // Reset the config after each test to keep state cleaner
    Treasure.prototype._configurator.DEFAULT_CONFIG = _.assign({}, DEFAULT_CONFIG)
  })

  describe('DEFAULT_CONFIG', function () {
    beforeEach(resetConfiguration)

    it('should allow you to set default values', function () {
      Treasure.prototype._configurator.DEFAULT_CONFIG.host = 'foo.bar'
      treasure = new Treasure(configuration)
      expect(treasure.client.host).to.equal('foo.bar')
    })

    it('should allow you to overwrite default config', function () {
      Treasure.prototype._configurator.DEFAULT_CONFIG.host = 'foo.bar'
      configuration.host = 'bar.baz'
      treasure = new Treasure(configuration)
      expect(treasure.client.host).to.equal('bar.baz')
    })

    it('should allow objectless instantiation if all required values are defaults', function () {
      Treasure.prototype._configurator.DEFAULT_CONFIG.database = 'database'
      Treasure.prototype._configurator.DEFAULT_CONFIG.writeKey = 'writeKey'
      treasure = new Treasure()
      expect(treasure.client.database).to.equal('database')
      expect(treasure.client.writeKey).to.equal('writeKey')
    })

    it('should throw if writeKey is missing', function () {
      Treasure.prototype._configurator.DEFAULT_CONFIG.database = 'database'
      expect(function () {
        return new Treasure()
      }).to.throwException()
    })

    it('should throw if database is missing', function () {
      Treasure.prototype._configurator.DEFAULT_CONFIG.writeKey = 'writeKey'
      expect(function () {
        return new Treasure()
      }).to.throwException()
    })
  })

  describe('constructor', function () {
    it('should create a new Treasure instance when called without new', function () {
      expect(Treasure(configuration)).to.be.a(Treasure)
    })

    it('should create a new Treasure instance', function () {
      expect(treasure).to.be.a(Treasure)
    })

    it('should error if no configuration object', function () {
      expect(function () {
        (treasure = new Treasure())
      }).to.throwException()
    })

    it('should create a new client object', function () {
      expect(treasure.client).to.be.an('object')
    })

    it('should create a globals object on client', function () {
      expect(treasure.client.globals).to.be.an('object')
    })

    it('should set defaults on client object', function () {
      var client = treasure.client
      expect(client.protocol).to.be.a('string')
      expect(client.host).to.be.a('string')
      expect(client.pathname).to.be.a('string')
      expect(client.requestType).to.be.a('string')
      expect(client.development).to.be.a('boolean')
      expect(client.logging).to.be.a('boolean')
      expect(client.endpoint).to.be.a('string')
    })

    it('should allow you to manually set values on client', function () {
      configuration.host = configuration.pathname = configuration.endpoint = 'foo'
      treasure = new Treasure(configuration)
      expect(treasure.client.host).to.equal('foo')
      expect(treasure.client.pathname).to.equal('foo')
      expect(treasure.client.endpoint).to.equal('foo')
    })

    describe('validates database', function () {
      var tryWithDatabaseValue = function (value) {
        configuration.database = value
        expect(function () {
          (treasure = new Treasure(configuration))
        }).to.throwException()
      }

      it('should error if database is absent', function () {
        tryWithDatabaseValue(undefined)
      })

      it('should error if database is of incorrect type', function () {
        // Number
        tryWithDatabaseValue(0)

        // Boolean
        tryWithDatabaseValue(false)

        // Array
        tryWithDatabaseValue(['array'])

        // Object
        tryWithDatabaseValue({})
      })

      it('should error if database is invalid', function () {
        // Empty string
        tryWithDatabaseValue('')

        // Under 3 characters
        tryWithDatabaseValue('12')

        // Over 255 characters
        tryWithDatabaseValue('1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111')

        // Uppercase chracters
        tryWithDatabaseValue('FOO_BAR')

        // Special characters
        tryWithDatabaseValue('!@#$%ˆ&*()-+=')
      })

      it('should set the database (string)', function () {
        expect(typeof treasure.client.database).to.be('string')
        expect(treasure.client.database).to.equal(configuration.database)
      })
    })

    describe('validates writeKey', function () {
      it('should error if writeKey is not set', function () {
        delete configuration.writeKey
        expect(function () {
          (treasure = new Treasure(configuration))
        }).to.throwException()
      })

      it('should set the writeKey (string)', function () {
        expect(typeof treasure.client.writeKey).to.be('string')
        expect(treasure.client.writeKey).to.equal(configuration.writeKey)
      })
    })

    describe('validates endpoint', function () {
      it('should set protocol to "https:" if designated as "https:"', function () {
        configuration.protocol = 'https:'
        treasure = new Treasure(configuration)
        expect(treasure.client.endpoint.indexOf('https://')).to.equal(0)
      })

      it('should set protocol to "http:" if designated as "http:"', function () {
        configuration.protocol = 'http:'
        treasure = new Treasure(configuration)
        expect(treasure.client.endpoint.indexOf('http://')).to.equal(0)
      })

      it('should set protocol to "https:" if designated as "https"', function () {
        configuration.protocol = 'https'
        treasure = new Treasure(configuration)
        expect(treasure.client.endpoint.indexOf('https://')).to.equal(0)
      })

      it('should set protocol to "http:" if designated as "http"', function () {
        configuration.protocol = 'http'
        treasure = new Treasure(configuration)
        expect(treasure.client.endpoint.indexOf('http://')).to.equal(0)
      })
    })

    describe('validates request type', function () {
      it('should set request type to "jsonp"', function () {
        expect(typeof treasure.client.requestType).to.be('string')
        expect(treasure.client.requestType).to.equal('jsonp')
      })

      it('should always set request type to "jsonp"', function () {
        configuration.requestType = 'xhr'
        treasure = new Treasure(configuration)
        expect(typeof treasure.client.requestType).to.be('string')
        expect(treasure.client.requestType).to.equal('jsonp')
      })
    })
  })
})
<|endoftext|>


<commit_before>import BN from "bn.js"
import Fixture from "./helpers/Fixture"
import expectThrow from "../helpers/expectThrow"
import truffleAssert from "truffle-assertions"
import calcTxCost from "../helpers/calcTxCost"
import {createWinningTicket, getTicketHash} from "../helpers/ticket"
import {functionSig} from "../../utils/helpers"

const TicketBroker = artifacts.require("LivepeerETHTicketBroker")

contract("LivepeerETHTicketBroker", accounts => {
    let fixture
    let broker

    const sender = accounts[0]
    const recipient = accounts[1]

    const unlockPeriod = 20

    before(async () => {
        fixture = new Fixture(web3)
        await fixture.deploy()

        broker = await TicketBroker.new(fixture.controller.address, 0, unlockPeriod)
    })

    beforeEach(async () => {
        await fixture.setUp()
    })

    afterEach(async () => {
        await fixture.tearDown()
    })

    describe("fundDeposit", () => {
        it("grows the Minter ETH balance", async () => {
            await broker.fundDeposit({from: sender, value: 1000})

            const balance = await web3.eth.getBalance(fixture.minter.address)

            assert.equal(balance, "1000")
        })

        it("reduces the sender's ETH balance", async () => {
            const startBalance = new BN(await web3.eth.getBalance(sender))

            const txResult = await broker.fundDeposit({from: sender, value: 1000})

            const endBalance = new BN(await web3.eth.getBalance(sender))
            const txCost = await calcTxCost(txResult)

            assert.equal(startBalance.sub(endBalance).sub(txCost).toString(), "1000")
        })

        it("tracks the sender's ETH deposit amount", async () => {
            await broker.fundDeposit({from: sender, value: 1000})

            const deposit = (await broker.senders.call(sender)).deposit.toString()

            assert.equal(deposit, "1000")
        })

        it("tracks sender's multiple deposits", async () => {
            await broker.fundDeposit({from: sender, value: 1000})
            await broker.fundDeposit({from: sender, value: 500})

            const deposit = (await broker.senders.call(sender)).deposit.toString()

            assert.equal(deposit, "1500")
        })

        it("track multiple sender's deposits", async () => {
            const sender2 = accounts[2]
            await broker.fundDeposit({from: sender, value: 1000})
            await broker.fundDeposit({from: sender2, value: 500})

            const deposit = (await broker.senders.call(sender)).deposit.toString()
            const deposit2 = (await broker.senders.call(sender2)).deposit.toString()

            assert.equal(deposit, "1000")
            assert.equal(deposit2, "500")
        })

        it("emits a DepositFunded event", async () => {
            const txResult = await broker.fundDeposit({from: sender, value: 1000})

            truffleAssert.eventEmitted(txResult, "DepositFunded", ev => {
                return ev.sender === sender && ev.amount.toString() === "1000"
            })
        })

        it("emits a DepositFunded event with indexed sender", async () => {
            const sender2 = accounts[2]
            const fromBlock = (await web3.eth.getBlock("latest")).number
            await broker.fundDeposit({from: sender, value: 1000})
            await broker.fundDeposit({from: sender2, value: 1000})

            const events = await broker.getPastEvents("DepositFunded", {
                filter: {
                    sender
                },
                fromBlock,
                toBlock: "latest"
            })

            assert.equal(events.length, 1)
            assert.equal(events[0].returnValues.sender, sender)
            assert.equal(events[0].returnValues.amount.toString(), "1000")
        })
    })

    describe("fundPenaltyEscrow", () => {
        it("reverts when penalty escrow < minPenaltyEscrow", async () => {
            const brokerWithMinEscrow = await TicketBroker.new(fixture.controller.address, 1000, 0)

            await expectThrow(brokerWithMinEscrow.fundPenaltyEscrow({from: sender, value: 500}))
        })

        it("tracks sender's ETH penalty escrow", async () => {
            await broker.fundPenaltyEscrow({from: sender, value: 1000})

            const penaltyEscrow = (await broker.senders.call(sender)).penaltyEscrow.toString()

            assert.equal(penaltyEscrow, "1000")
        })

        it("tracks sender's multiple ETH penalty escrow fundings", async () => {
            await broker.fundPenaltyEscrow({from: sender, value: 1000})
            await broker.fundPenaltyEscrow({from: sender, value: 500})

            const penaltyEscrow = (await broker.senders.call(sender)).penaltyEscrow.toString()

            assert.equal(penaltyEscrow, "1500")
        })

        it("grows the Minter ETH balance", async () => {
            await broker.fundPenaltyEscrow({from: sender, value: 1000})

            const balance = await web3.eth.getBalance(fixture.minter.address)

            assert.equal(balance, "1000")
        })

        it("reduces the sender's ETH balance", async () => {
            const startBalance = new BN(await web3.eth.getBalance(sender))

            const txRes = await broker.fundPenaltyEscrow({from: sender, value: 1000})

            const endBalance = new BN(await web3.eth.getBalance(sender))
            const txCost = await calcTxCost(txRes)

            assert.equal(startBalance.sub(endBalance).sub(txCost).toString(), "1000")
        })

        it("emits a PenaltyEscrowFunded event", async () => {
            const txResult = await broker.fundPenaltyEscrow({from: sender, value: 1000})

            truffleAssert.eventEmitted(txResult, "PenaltyEscrowFunded", ev => {
                return ev.sender === sender && ev.amount.toString() === "1000"
            })
        })

        it("emits a PenaltyEscrowFunded event with indexed sender", async () => {
            const sender2 = accounts[2]
            const fromBlock = (await web3.eth.getBlock("latest")).number
            await broker.fundPenaltyEscrow({from: sender, value: 1000})
            await broker.fundPenaltyEscrow({from: sender2, value: 1000})

            const events = await broker.getPastEvents("PenaltyEscrowFunded", {
                filter: {
                    sender
                },
                fromBlock,
                toBlock: "latest"
            })

            assert.equal(events.length, 1)
            assert.equal(events[0].returnValues.sender, sender)
            assert.equal(events[0].returnValues.amount.toString(), "1000")
        })
    })

    describe("redeemWinningTicket", () => {
        describe("winningTicketTransfer", () => {
            it("updates transcoder with fees on bonding manager with deposit when deposit < faceValue", async () => {
                const currentRound = 17
                await fixture.roundsManager.setMockUint256(functionSig("currentRound()"), currentRound)
                const fromBlock = (await web3.eth.getBlock("latest")).number
                const deposit = 500
                await broker.fundDeposit({from: sender, value: deposit})

                const recipientRand = 5
                const faceValue = 1000
                const ticket = createWinningTicket(recipient, sender, recipientRand, faceValue)
                const senderSig = await web3.eth.sign(getTicketHash(ticket), sender)

                await broker.redeemWinningTicket(ticket, senderSig, recipientRand, {from: recipient})

                const events = await fixture.bondingManager.getPastEvents("UpdateTranscoderWithFees", {
                    fromBlock,
                    toBlock: "latest"
                })

                assert.equal(events.length, 1)
                const event = events[0]
                assert.equal(event.returnValues.transcoder, recipient)
                assert.equal(event.returnValues.fees, deposit.toString())
                assert.equal(event.returnValues.round, currentRound)
            })

            it("updates transcoder fees on bonding manager with faceValue when deposit > faceValue", async () => {
                const currentRound = 17
                await fixture.roundsManager.setMockUint256(functionSig("currentRound()"), currentRound)
                const fromBlock = (await web3.eth.getBlock("latest")).number
                const deposit = 1500
                await broker.fundDeposit({from: sender, value: deposit})

                const recipientRand = 5
                const faceValue = 1000
                const ticket = createWinningTicket(recipient, sender, recipientRand, faceValue)
                const senderSig = await web3.eth.sign(getTicketHash(ticket), sender)

                await broker.redeemWinningTicket(ticket, senderSig, recipientRand, {from: recipient})

                const events = await fixture.bondingManager.getPastEvents("UpdateTranscoderWithFees", {
                    fromBlock,
                    toBlock: "latest"
                })

                assert.equal(events.length, 1)
                const event = events[0]
                assert.equal(event.returnValues.transcoder, recipient)
                assert.equal(event.returnValues.fees, faceValue.toString())
                assert.equal(event.returnValues.round, currentRound)
            })

            it("updates transcoder fees on bonding manager with faceValue when deposit == faceValue", async () => {
                const currentRound = 17
                await fixture.roundsManager.setMockUint256(functionSig("currentRound()"), currentRound)
                const fromBlock = (await web3.eth.getBlock("latest")).number
                const deposit = 1500
                await broker.fundDeposit({from: sender, value: deposit})

                const recipientRand = 5
                const faceValue = 1500
                const ticket = createWinningTicket(recipient, sender, recipientRand, faceValue)
                const senderSig = await web3.eth.sign(getTicketHash(ticket), sender)

                await broker.redeemWinningTicket(ticket, senderSig, recipientRand, {from: recipient})

                const events = await fixture.bondingManager.getPastEvents("UpdateTranscoderWithFees", {
                    fromBlock,
                    toBlock: "latest"
                })

                assert.equal(events.length, 1)
                const event = events[0]
                assert.equal(event.returnValues.transcoder, recipient)
                assert.equal(event.returnValues.fees, faceValue.toString())
                assert.equal(event.returnValues.round, currentRound)
            })
        })

        describe("penaltyEscrowSlash", () => {
            it("burns sender.penaltyEscrow and sets penaltyEscrow to zero when deposit < faceValue", async () => {
                const fromBlock = (await web3.eth.getBlock("latest")).number
                const penaltyEscrow = 2000
                await broker.fundPenaltyEscrow({from: sender, value: penaltyEscrow})

                const recipientRand = 5
                const faceValue = 1000
                const ticket = createWinningTicket(recipient, sender, recipientRand, faceValue)
                const senderSig = await web3.eth.sign(getTicketHash(ticket), sender)

                await broker.redeemWinningTicket(ticket, senderSig, recipientRand, {from: recipient})

                const events = await fixture.minter.getPastEvents("TrustedBurnETH", {
                    fromBlock,
                    toBlock: "latest"
                })
                const endPenaltyEscrow = (await broker.senders.call(sender)).penaltyEscrow.toString()

                assert.equal(events.length, 1)
                const event = events[0]
                assert.equal(event.returnValues.amount, penaltyEscrow.toString())
                assert.equal(endPenaltyEscrow, 0)
            })

            it("does not burn sender.penaltyEscrow when deposit < faceValue and penaltyEscrow == 0", async () => {
                const fromBlock = (await web3.eth.getBlock("latest")).number
                const deposit = 500
                await broker.fundDeposit({from: sender, value: deposit})

                const recipientRand = 5
                const faceValue = 1000
                const ticket = createWinningTicket(recipient, sender, recipientRand, faceValue)
                const senderSig = await web3.eth.sign(getTicketHash(ticket), sender)

                await broker.redeemWinningTicket(ticket, senderSig, recipientRand, {from: recipient})

                const events = await fixture.minter.getPastEvents("TrustedBurnETH", {
                    fromBlock,
                    toBlock: "latest"
                })

                assert.equal(events.length, 0)
            })
        })
    })

    describe("withdraw", () => {
        describe("withdrawTransfer", () => {
            it("transfers the sum of deposit and penaltyEscrow to sender", async () => {
                const fromBlock = (await web3.eth.getBlock("latest")).number
                const deposit = 1000
                const penaltyEscrow = 2000
                await broker.fundDeposit({from: sender, value: deposit})
                await broker.fundPenaltyEscrow({from: sender, value: penaltyEscrow})
                await broker.unlock({from: sender})
                await fixture.rpc.wait(unlockPeriod)

                await broker.withdraw({from: sender})

                const events = await fixture.minter.getPastEvents("TrustedWithdrawETH", {
                    fromBlock,
                    toBlock: "latest"
                })

                assert.equal(events.length, 1)
                const event = events[0]
                assert.equal(event.returnValues.to, sender)
                assert.equal(event.returnValues.amount.toString(), (deposit + penaltyEscrow).toString())
            })
        })
    })
})
<commit_msg>PM: Add test for stubbed logic in LivepeerETHTicketBroker<commit_after>import BN from "bn.js"
import Fixture from "./helpers/Fixture"
import expectThrow from "../helpers/expectThrow"
import {expectRevertWithReason} from "../helpers/expectFail"
import truffleAssert from "truffle-assertions"
import calcTxCost from "../helpers/calcTxCost"
import {createTicket, createWinningTicket, getTicketHash} from "../helpers/ticket"
import {functionSig} from "../../utils/helpers"

const TicketBroker = artifacts.require("LivepeerETHTicketBroker")

contract("LivepeerETHTicketBroker", accounts => {
    let fixture
    let broker

    const sender = accounts[0]
    const recipient = accounts[1]

    const unlockPeriod = 20

    before(async () => {
        fixture = new Fixture(web3)
        await fixture.deploy()

        broker = await TicketBroker.new(fixture.controller.address, 0, unlockPeriod)
    })

    beforeEach(async () => {
        await fixture.setUp()
    })

    afterEach(async () => {
        await fixture.tearDown()
    })

    describe("fundDeposit", () => {
        it("grows the Minter ETH balance", async () => {
            await broker.fundDeposit({from: sender, value: 1000})

            const balance = await web3.eth.getBalance(fixture.minter.address)

            assert.equal(balance, "1000")
        })

        it("reduces the sender's ETH balance", async () => {
            const startBalance = new BN(await web3.eth.getBalance(sender))

            const txResult = await broker.fundDeposit({from: sender, value: 1000})

            const endBalance = new BN(await web3.eth.getBalance(sender))
            const txCost = await calcTxCost(txResult)

            assert.equal(startBalance.sub(endBalance).sub(txCost).toString(), "1000")
        })

        it("tracks the sender's ETH deposit amount", async () => {
            await broker.fundDeposit({from: sender, value: 1000})

            const deposit = (await broker.senders.call(sender)).deposit.toString()

            assert.equal(deposit, "1000")
        })

        it("tracks sender's multiple deposits", async () => {
            await broker.fundDeposit({from: sender, value: 1000})
            await broker.fundDeposit({from: sender, value: 500})

            const deposit = (await broker.senders.call(sender)).deposit.toString()

            assert.equal(deposit, "1500")
        })

        it("track multiple sender's deposits", async () => {
            const sender2 = accounts[2]
            await broker.fundDeposit({from: sender, value: 1000})
            await broker.fundDeposit({from: sender2, value: 500})

            const deposit = (await broker.senders.call(sender)).deposit.toString()
            const deposit2 = (await broker.senders.call(sender2)).deposit.toString()

            assert.equal(deposit, "1000")
            assert.equal(deposit2, "500")
        })

        it("emits a DepositFunded event", async () => {
            const txResult = await broker.fundDeposit({from: sender, value: 1000})

            truffleAssert.eventEmitted(txResult, "DepositFunded", ev => {
                return ev.sender === sender && ev.amount.toString() === "1000"
            })
        })

        it("emits a DepositFunded event with indexed sender", async () => {
            const sender2 = accounts[2]
            const fromBlock = (await web3.eth.getBlock("latest")).number
            await broker.fundDeposit({from: sender, value: 1000})
            await broker.fundDeposit({from: sender2, value: 1000})

            const events = await broker.getPastEvents("DepositFunded", {
                filter: {
                    sender
                },
                fromBlock,
                toBlock: "latest"
            })

            assert.equal(events.length, 1)
            assert.equal(events[0].returnValues.sender, sender)
            assert.equal(events[0].returnValues.amount.toString(), "1000")
        })
    })

    describe("fundPenaltyEscrow", () => {
        it("reverts when penalty escrow < minPenaltyEscrow", async () => {
            const brokerWithMinEscrow = await TicketBroker.new(fixture.controller.address, 1000, 0)

            await expectThrow(brokerWithMinEscrow.fundPenaltyEscrow({from: sender, value: 500}))
        })

        it("tracks sender's ETH penalty escrow", async () => {
            await broker.fundPenaltyEscrow({from: sender, value: 1000})

            const penaltyEscrow = (await broker.senders.call(sender)).penaltyEscrow.toString()

            assert.equal(penaltyEscrow, "1000")
        })

        it("tracks sender's multiple ETH penalty escrow fundings", async () => {
            await broker.fundPenaltyEscrow({from: sender, value: 1000})
            await broker.fundPenaltyEscrow({from: sender, value: 500})

            const penaltyEscrow = (await broker.senders.call(sender)).penaltyEscrow.toString()

            assert.equal(penaltyEscrow, "1500")
        })

        it("grows the Minter ETH balance", async () => {
            await broker.fundPenaltyEscrow({from: sender, value: 1000})

            const balance = await web3.eth.getBalance(fixture.minter.address)

            assert.equal(balance, "1000")
        })

        it("reduces the sender's ETH balance", async () => {
            const startBalance = new BN(await web3.eth.getBalance(sender))

            const txRes = await broker.fundPenaltyEscrow({from: sender, value: 1000})

            const endBalance = new BN(await web3.eth.getBalance(sender))
            const txCost = await calcTxCost(txRes)

            assert.equal(startBalance.sub(endBalance).sub(txCost).toString(), "1000")
        })

        it("emits a PenaltyEscrowFunded event", async () => {
            const txResult = await broker.fundPenaltyEscrow({from: sender, value: 1000})

            truffleAssert.eventEmitted(txResult, "PenaltyEscrowFunded", ev => {
                return ev.sender === sender && ev.amount.toString() === "1000"
            })
        })

        it("emits a PenaltyEscrowFunded event with indexed sender", async () => {
            const sender2 = accounts[2]
            const fromBlock = (await web3.eth.getBlock("latest")).number
            await broker.fundPenaltyEscrow({from: sender, value: 1000})
            await broker.fundPenaltyEscrow({from: sender2, value: 1000})

            const events = await broker.getPastEvents("PenaltyEscrowFunded", {
                filter: {
                    sender
                },
                fromBlock,
                toBlock: "latest"
            })

            assert.equal(events.length, 1)
            assert.equal(events[0].returnValues.sender, sender)
            assert.equal(events[0].returnValues.amount.toString(), "1000")
        })
    })

    describe("redeemWinningTicket", () => {
        // TODO: Test for stubbed logic. Reminder to update if necessary
        // when using Livepeer specific logic for ticket auxilary data
        // validation
        it("reverts if ticket is expired", async () => {
            await expectRevertWithReason(
                broker.redeemWinningTicket(
                    createTicket({
                        recipient,
                        sender,
                        auxData: web3.utils.numberToHex(0)
                    }),
                    web3.utils.asciiToHex("sig"),
                    5
                ),
                "ticket is expired"
            )
        })

        describe("winningTicketTransfer", () => {
            it("updates transcoder with fees on bonding manager with deposit when deposit < faceValue", async () => {
                const currentRound = 17
                await fixture.roundsManager.setMockUint256(functionSig("currentRound()"), currentRound)
                const fromBlock = (await web3.eth.getBlock("latest")).number
                const deposit = 500
                await broker.fundDeposit({from: sender, value: deposit})

                const recipientRand = 5
                const faceValue = 1000
                const ticket = createWinningTicket(recipient, sender, recipientRand, faceValue)
                const senderSig = await web3.eth.sign(getTicketHash(ticket), sender)

                await broker.redeemWinningTicket(ticket, senderSig, recipientRand, {from: recipient})

                const events = await fixture.bondingManager.getPastEvents("UpdateTranscoderWithFees", {
                    fromBlock,
                    toBlock: "latest"
                })

                assert.equal(events.length, 1)
                const event = events[0]
                assert.equal(event.returnValues.transcoder, recipient)
                assert.equal(event.returnValues.fees, deposit.toString())
                assert.equal(event.returnValues.round, currentRound)
            })

            it("updates transcoder fees on bonding manager with faceValue when deposit > faceValue", async () => {
                const currentRound = 17
                await fixture.roundsManager.setMockUint256(functionSig("currentRound()"), currentRound)
                const fromBlock = (await web3.eth.getBlock("latest")).number
                const deposit = 1500
                await broker.fundDeposit({from: sender, value: deposit})

                const recipientRand = 5
                const faceValue = 1000
                const ticket = createWinningTicket(recipient, sender, recipientRand, faceValue)
                const senderSig = await web3.eth.sign(getTicketHash(ticket), sender)

                await broker.redeemWinningTicket(ticket, senderSig, recipientRand, {from: recipient})

                const events = await fixture.bondingManager.getPastEvents("UpdateTranscoderWithFees", {
                    fromBlock,
                    toBlock: "latest"
                })

                assert.equal(events.length, 1)
                const event = events[0]
                assert.equal(event.returnValues.transcoder, recipient)
                assert.equal(event.returnValues.fees, faceValue.toString())
                assert.equal(event.returnValues.round, currentRound)
            })

            it("updates transcoder fees on bonding manager with faceValue when deposit == faceValue", async () => {
                const currentRound = 17
                await fixture.roundsManager.setMockUint256(functionSig("currentRound()"), currentRound)
                const fromBlock = (await web3.eth.getBlock("latest")).number
                const deposit = 1500
                await broker.fundDeposit({from: sender, value: deposit})

                const recipientRand = 5
                const faceValue = 1500
                const ticket = createWinningTicket(recipient, sender, recipientRand, faceValue)
                const senderSig = await web3.eth.sign(getTicketHash(ticket), sender)

                await broker.redeemWinningTicket(ticket, senderSig, recipientRand, {from: recipient})

                const events = await fixture.bondingManager.getPastEvents("UpdateTranscoderWithFees", {
                    fromBlock,
                    toBlock: "latest"
                })

                assert.equal(events.length, 1)
                const event = events[0]
                assert.equal(event.returnValues.transcoder, recipient)
                assert.equal(event.returnValues.fees, faceValue.toString())
                assert.equal(event.returnValues.round, currentRound)
            })
        })

        describe("penaltyEscrowSlash", () => {
            it("burns sender.penaltyEscrow and sets penaltyEscrow to zero when deposit < faceValue", async () => {
                const fromBlock = (await web3.eth.getBlock("latest")).number
                const penaltyEscrow = 2000
                await broker.fundPenaltyEscrow({from: sender, value: penaltyEscrow})

                const recipientRand = 5
                const faceValue = 1000
                const ticket = createWinningTicket(recipient, sender, recipientRand, faceValue)
                const senderSig = await web3.eth.sign(getTicketHash(ticket), sender)

                await broker.redeemWinningTicket(ticket, senderSig, recipientRand, {from: recipient})

                const events = await fixture.minter.getPastEvents("TrustedBurnETH", {
                    fromBlock,
                    toBlock: "latest"
                })
                const endPenaltyEscrow = (await broker.senders.call(sender)).penaltyEscrow.toString()

                assert.equal(events.length, 1)
                const event = events[0]
                assert.equal(event.returnValues.amount, penaltyEscrow.toString())
                assert.equal(endPenaltyEscrow, 0)
            })

            it("does not burn sender.penaltyEscrow when deposit < faceValue and penaltyEscrow == 0", async () => {
                const fromBlock = (await web3.eth.getBlock("latest")).number
                const deposit = 500
                await broker.fundDeposit({from: sender, value: deposit})

                const recipientRand = 5
                const faceValue = 1000
                const ticket = createWinningTicket(recipient, sender, recipientRand, faceValue)
                const senderSig = await web3.eth.sign(getTicketHash(ticket), sender)

                await broker.redeemWinningTicket(ticket, senderSig, recipientRand, {from: recipient})

                const events = await fixture.minter.getPastEvents("TrustedBurnETH", {
                    fromBlock,
                    toBlock: "latest"
                })

                assert.equal(events.length, 0)
            })
        })
    })

    describe("withdraw", () => {
        describe("withdrawTransfer", () => {
            it("transfers the sum of deposit and penaltyEscrow to sender", async () => {
                const fromBlock = (await web3.eth.getBlock("latest")).number
                const deposit = 1000
                const penaltyEscrow = 2000
                await broker.fundDeposit({from: sender, value: deposit})
                await broker.fundPenaltyEscrow({from: sender, value: penaltyEscrow})
                await broker.unlock({from: sender})
                await fixture.rpc.wait(unlockPeriod)

                await broker.withdraw({from: sender})

                const events = await fixture.minter.getPastEvents("TrustedWithdrawETH", {
                    fromBlock,
                    toBlock: "latest"
                })

                assert.equal(events.length, 1)
                const event = events[0]
                assert.equal(event.returnValues.to, sender)
                assert.equal(event.returnValues.amount.toString(), (deposit + penaltyEscrow).toString())
            })
        })
    })
})
<|endoftext|>


<commit_before>let pagination = require('./pagination');

/**
 * Retrieve the project name given its project ID and the associated url. After appending the appropriate suffix to
 * complete the request URL, pagination is called and returns the name of the project from the given arguments. If the
 * promise is resolved, the project name is returned. Else the rejected promise issues a message String used for error
 * logging.
 *
 * @param {Number} projectId
 * @param {String} url Should be in the following format: http://username:password@teamname.jamacloud.com/rest/latest/
 */
function getProjectName (projectId, url) {
  let newUrl = url + 'projects/' + projectId;
  let name = pagination(newUrl, 0, Number.MAX_SAFE_INTEGER);
  return name.then(function (item) {
    // pagination stores payload in an array
    return item[0].fields.name;
  }, () => Promise.reject('Promise for name has been rejected.'));
}

/**
 * Retrieve all items from some project given its project ID and the associated url. Prior to calling the pagination
 * function, `url` is appended with the appropriate suffix to complete the request URL for all project items. If the
 * promise is resolved, each iteration through the list of items pushes the ID, name, and item type into a temporary
 * node container, which ultimately becomes the value of the `nodes` data member. Else the rejected promise issues a
 * message String used for error logging.
 *
 * @param {Number} projectId
 * @param {String} url Should be in the following format: http://username:password@teamname.jamacloud.com/rest/latest/
 */
function getProjectItems (projectId, url) {
  let newUrl = url + 'items?project=' + projectId;
  let nodeItems = pagination(newUrl, 0, Number.MAX_SAFE_INTEGER);
  return nodeItems.then(function (items) {
    let tempNodeCont = [];
    items.forEach(function (i) {
      let node = {
        'id': i.id,
        'name': i.fields.name,
        'type': i.itemType
      };
      tempNodeCont.push(node);
    });
    return tempNodeCont;
  }, () => Promise.reject('Promise for nodes has been rejected.'));
}

/**
 * Retrieve all item relationships from some project given its project ID and the associated url. Prior to calling the
 * pagination function, `url` is appended with the appropriate suffix to complete the request URL for all project item
 * relationships. If the promise is resolved, each iteration through the list of item relationships pushes the ID, the
 * IDs of both items in the relationship, and relationship type into a temporary edge container, which ultimately
 * becomes the value of the `edges` data member. Else the rejected promise issues a message String used for error
 * logging.
 *
 * @param {Number} projectId
 * @param {String} url Should be in the following format: http://username:password@teamname.jamacloud.com/rest/latest/
 */
function getProjectRelationships (projectId, url) {
  let newUrl = url + 'relationships?project=' + projectId;
  let relationshipItems = pagination(newUrl, 0, Number.MAX_SAFE_INTEGER);
  return relationshipItems.then(function (item) {
    let tempEdgeCont = [];
    item.forEach(function (i) {
      let edge = {
        'id': i.id,
        'fromItem': i.fromItem,
        'toItem': i.toItem,
        'type': i.relationshipType
      };
      tempEdgeCont.push(edge);
    });
    return tempEdgeCont;
  }, () => Promise.reject('Promise for edges has been rejected.'));
}

let Graph = {
  name: '',
  nodes: [],
  edges: [],

  /**
   * Builds a graph object model given a project ID and a url that contains the username, password, and team name.
   *
   * @param {Number} projectId
   * @param {String} url Should be in the following format: http://username:password@teamname.jamacloud.com/rest/latest/
   * @constructor {Graph}
   */
  Graph: function (projectId, url) {
    getProjectName(projectId, url).then(name => this.name = name, error => console.error(error));
    getProjectItems(projectId, url).then(items => this.nodes = items, error => console.error(error));
    getProjectRelationships(projectId, url).then(
      relationships => this.edges = relationships,
      error => console.error(error)
    );
  },

  Reorganize: function (rootNode) {
    // TODO: dependent on story #60 (backlog)
  },

  /**
   * Iterates through all items in both the item and the item relationship lists and pushes to the `nodes` and `edges`
   * arrays, respectively.
   *
   * @param {Object} graphJson
   */
  fromJson: function (graphJson) {
    for (let i = 0; i < graphJson.items.length; ++i) {
      this.nodes.push(graphJson.items[i]);
    }
    for (let i = 0; i < graphJson.relationships.length; ++i) {
      this.edges.push(graphJson.relationships[i]);
    }
  },

  /**
   * Returns an object model abiding by the relationship graph JSON schema from the given nodes and edges.
   *
   * @returns {{items: Array, relationships: Array}}
   */
  toJson: function () {
    return { 'items': this.nodes, 'relationships': this.edges };
  }
};

module.exports = Graph;
<commit_msg>turn graph object into graph class<commit_after>let pagination = require('./pagination');

/**
 * Retrieve the project name given its project ID and the associated url. After appending the appropriate suffix to
 * complete the request URL, pagination is called and returns the name of the project from the given arguments. If the
 * promise is resolved, the project name is returned. Else the rejected promise issues a message String used for error
 * logging.
 *
 * @param {Number} projectId
 * @param {String} url Should be in the following format: http://username:password@teamname.jamacloud.com/rest/latest/
 */
function getProjectName (projectId, url) {
  let newUrl = url + 'projects/' + projectId;
  let name = pagination(newUrl, 0, Number.MAX_SAFE_INTEGER);
  return name.then(function (item) {
    // pagination stores payload in an array
    return item[0].fields.name;
  }, () => Promise.reject('Promise for name has been rejected.'));
}

/**
 * Retrieve all items from some project given its project ID and the associated url. Prior to calling the pagination
 * function, `url` is appended with the appropriate suffix to complete the request URL for all project items. If the
 * promise is resolved, each iteration through the list of items pushes the ID, name, and item type into a temporary
 * node container, which ultimately becomes the value of the `nodes` data member. Else the rejected promise issues a
 * message String used for error logging.
 *
 * @param {Number} projectId
 * @param {String} url Should be in the following format: http://username:password@teamname.jamacloud.com/rest/latest/
 */
function getProjectItems (projectId, url) {
  let newUrl = url + 'items?project=' + projectId;
  let nodeItems = pagination(newUrl, 0, Number.MAX_SAFE_INTEGER);
  return nodeItems.then(function (items) {
    let tempNodeCont = [];
    items.forEach(function (i) {
      let node = {
        'id': i.id,
        'name': i.fields.name,
        'type': i.itemType
      };
      tempNodeCont.push(node);
    });
    return tempNodeCont;
  }, () => Promise.reject('Promise for nodes has been rejected.'));
}

/**
 * Retrieve all item relationships from some project given its project ID and the associated url. Prior to calling the
 * pagination function, `url` is appended with the appropriate suffix to complete the request URL for all project item
 * relationships. If the promise is resolved, each iteration through the list of item relationships pushes the ID, the
 * IDs of both items in the relationship, and relationship type into a temporary edge container, which ultimately
 * becomes the value of the `edges` data member. Else the rejected promise issues a message String used for error
 * logging.
 *
 * @param {Number} projectId
 * @param {String} url Should be in the following format: http://username:password@teamname.jamacloud.com/rest/latest/
 */
function getProjectRelationships (projectId, url) {
  let newUrl = url + 'relationships?project=' + projectId;
  let relationshipItems = pagination(newUrl, 0, Number.MAX_SAFE_INTEGER);
  return relationshipItems.then(function (item) {
    let tempEdgeCont = [];
    item.forEach(function (i) {
      let edge = {
        'id': i.id,
        'fromItem': i.fromItem,
        'toItem': i.toItem,
        'type': i.relationshipType
      };
      tempEdgeCont.push(edge);
    });
    return tempEdgeCont;
  }, () => Promise.reject('Promise for edges has been rejected.'));
}

class Graph {
  name = '';
  nodes = [];
  edges = [];

  /**
   * Builds a graph object model given a project ID and a url that contains the username, password, and team name.
   *
   * @param {Number} projectId
   * @param {String} url Should be in the following format: http://username:password@teamname.jamacloud.com/rest/latest/
   * @constructor {Graph}
   */
  constructor(projectId, url) {
    getProjectName(projectId, url).then(name => this.name = name, error => console.error(error));
    getProjectItems(projectId, url).then(items => this.nodes = items, error => console.error(error));
    getProjectRelationships(projectId, url).then(
      relationships => this.edges = relationships,
      error => console.error(error)
    );
  }

  Reorganize(rootNode){
    // TODO: dependent on story #60 (backlog)
  }

  /**
   * Iterates through all items in both the item and the item relationship lists and pushes to the `nodes` and `edges`
   * arrays, respectively.
   *
   * @param {Object} graphJson
   */
  fromJson(graphJson) {
    for (let i = 0; i < graphJson.items.length; ++i) {
      this.nodes.push(graphJson.items[i]);
    }
    for (let i = 0; i < graphJson.relationships.length; ++i) {
      this.edges.push(graphJson.relationships[i]);
    }
  }

  /**
   * Returns an object model abiding by the relationship graph JSON schema from the given nodes and edges.
   *
   * @returns {{items: Array, relationships: Array}}
   */
  toJson() {
    return { 'items': this.nodes, 'relationships': this.edges };
  }
}

module.exports = Graph;
<|endoftext|>