<commit_before>jQuery.fn.toc = function () {
  if(this.length === 0)
    return;

  var listStack = [ $("
")];
  listStack[0].appendTo(this);

  Array.prototype.last = function() { return this[this.length - 1]};

  var level = 2;
  $(document).ready(function() {
    $(":header").each(function(index, el) {

      if(parseInt(el.tagName[1]) === 1)
        return;

      var text = $(el).text();

      var anchor = text.replace(/[^a-zA-Z 0-9]+/g,'').replace(/\s/g, "_").toLowerCase();
      $(el).attr('id', anchor);

      var currentLevel = parseInt(el.tagName[1]);

      if(currentLevel > level) {
        var nextLevelList = $("
");
        nextLevelList.appendTo(listStack.last().children("li").last());
        listStack.push(nextLevelList);
      } else if(currentLevel < level) {
        listStack.pop();
      }

      level = currentLevel;
      var li = $("
");

      $("").text(text).attr('href', "#" + anchor).appendTo(li);
      li.appendTo(listStack.last());
    });
  });
};
// $($(".highlight")[2]).text().match(/(.*)\.(.*)/)
// "AMQP::Channel.direct".match(/(.*)\.(.*)/)
// "AMQP::Channel#direct".match(/(.*)#(.*)/)
jQuery.fn.yardLink = function () {
  var class_method = /(.*)\.(.*)/;
  var instance_method = /(.*)#(.*)/;
};

$(document).ready(function() {
  $(".well.sidebar-nav").toc();
});<commit_msg>Backport a JavaScript TOC fix from CDS<commit_after>jQuery.fn.toc = function () {
  if(this.length === 0)
    return;

  var listStack = [ $("
")];
  listStack[0].appendTo(this);

  Array.prototype.last = function() { return this[this.length - 1]};

  var level = 2;
  $(document).ready(function() {
    $(":header").filter(function(idx, el) {
      // filter out H1
      return !(parseInt(el.tagName[1]) === 1);
    }).
    each(function(index, el) {
      var currentLevel = parseInt(el.tagName[1]);

      var text = $(el).text();
      var anchor = text.replace(/[^a-zA-Z 0-9]+/g,'').replace(/\s/g, "_").toLowerCase();

      $(el).attr('id', anchor);

      if(currentLevel > level) {
        var nextLevelList = $("
");
        nextLevelList.appendTo(listStack.last().children("li").last());
        listStack.push(nextLevelList);
      } else if(currentLevel < level) {
	var delta = level - currentLevel;
        for(var i = 0; i < delta; i ++) {
	  listStack.pop();
	}
      }

      level = currentLevel;
      var li = $("
");

      $("").text(text).attr('href', "#" + anchor).appendTo(li);
      li.appendTo(listStack.last());
    });
  });
};

$(document).ready(function() {
  $(".well.sidebar-nav").toc();
});
<|endoftext|>


<commit_before>function Assert( testContext ) {
	this.test = testContext;
}

// Assert helpers
QUnit.assert = Assert.prototype = {

	// Specify the number of expected assertions to guarantee that failed test
	// (no assertions are run at all) don't slip through.
	expect: function( asserts ) {
		if ( arguments.length === 1 ) {
			this.test.expected = asserts;
		} else {
			return this.test.expected;
		}
	},

	// Increment this Test's semaphore counter, then return a single-use function that
	// decrements that counter a maximum of once.
	async: function() {
		var test = this.test,
			popped = false;

		test.semaphore += 1;
		test.usedAsync = true;
		pauseProcessing();

		return function done() {
			if ( !popped ) {
				test.semaphore -= 1;
				popped = true;
				resumeProcessing();
			} else {
				test.pushFailure( "Called the callback returned from `assert.async` more than once",
					sourceFromStacktrace( 2 ) );
			}
		};
	},

	// Exports test.push() to the user API
	push: function( /* result, actual, expected, message */ ) {
		var assert = this,
			currentTest = ( assert instanceof Assert && assert.test ) || QUnit.config.current;

		// Backwards compatibility fix.
		// Allows the direct use of global exported assertions and QUnit.assert.*
		// Although, it's use is not recommended as it can leak assertions
		// to other tests from async tests, because we only get a reference to the current test,
		// not exactly the test where assertion were intended to be called.
		if ( !currentTest ) {
			throw new Error( "assertion outside test context, in " + sourceFromStacktrace( 2 ) );
		}

		if ( currentTest.usedAsync === true && currentTest.semaphore === 0 ) {
			currentTest.pushFailure( "Assertion after the final `assert.async` was resolved",
				sourceFromStacktrace( 2 ) );

			// Allow this assertion to continue running anyway...
		}

		if ( !( assert instanceof Assert ) ) {
			assert = currentTest.assert;
		}
		return assert.test.push.apply( assert.test, arguments );
	},

	/**
	 * Asserts rough true-ish result.
	 * @name ok
	 * @function
	 * @example ok( "asdfasdf".length > 5, "There must be at least 5 chars" );
	 */
	ok: function( result, message ) {
		message = message || ( result ? "okay" : "failed, expected argument to be truthy, was: " +
			QUnit.dump.parse( result ) );
		this.push( !!result, result, true, message );
	},

	/**
	 * Assert that the first two arguments are equal, with an optional message.
	 * Prints out both actual and expected values.
	 * @name equal
	 * @function
	 * @example equal( format( "{0} bytes.", 2), "2 bytes.", "replaces {0} with next argument" );
	 */
	equal: function( actual, expected, message ) {
		/*jshint eqeqeq:false */
		this.push( expected == actual, actual, expected, message );
	},

	/**
	 * @name notEqual
	 * @function
	 */
	notEqual: function( actual, expected, message ) {
		/*jshint eqeqeq:false */
		this.push( expected != actual, actual, expected, message );
	},

	/**
	 * @name propEqual
	 * @function
	 */
	propEqual: function( actual, expected, message ) {
		actual = objectValues( actual );
		expected = objectValues( expected );
		this.push( QUnit.equiv( actual, expected ), actual, expected, message );
	},

	/**
	 * @name notPropEqual
	 * @function
	 */
	notPropEqual: function( actual, expected, message ) {
		actual = objectValues( actual );
		expected = objectValues( expected );
		this.push( !QUnit.equiv( actual, expected ), actual, expected, message );
	},

	/**
	 * @name deepEqual
	 * @function
	 */
	deepEqual: function( actual, expected, message ) {
		this.push( QUnit.equiv( actual, expected ), actual, expected, message );
	},

	/**
	 * @name notDeepEqual
	 * @function
	 */
	notDeepEqual: function( actual, expected, message ) {
		this.push( !QUnit.equiv( actual, expected ), actual, expected, message );
	},

	/**
	 * @name strictEqual
	 * @function
	 */
	strictEqual: function( actual, expected, message ) {
		this.push( expected === actual, actual, expected, message );
	},

	/**
	 * @name notStrictEqual
	 * @function
	 */
	notStrictEqual: function( actual, expected, message ) {
		this.push( expected !== actual, actual, expected, message );
	},

	"throws": function( block, expected, message ) {
		var actual, expectedType,
			expectedOutput = expected,
			ok = false;

		// 'expected' is optional unless doing string comparison
		if ( message == null && typeof expected === "string" ) {
			message = expected;
			expected = null;
		}

		this.test.ignoreGlobalErrors = true;
		try {
			block.call( this.test.testEnvironment );
		} catch (e) {
			actual = e;
		}
		this.test.ignoreGlobalErrors = false;

		if ( actual ) {
			expectedType = QUnit.objectType( expected );

			// we don't want to validate thrown error
			if ( !expected ) {
				ok = true;
				expectedOutput = null;

			// expected is a regexp
			} else if ( expectedType === "regexp" ) {
				ok = expected.test( errorString( actual ) );

			// expected is a string
			} else if ( expectedType === "string" ) {
				ok = expected === errorString( actual );

			// expected is a constructor, maybe an Error constructor
			} else if ( expectedType === "function" && actual instanceof expected ) {
				ok = true;

			// expected is an Error object
			} else if ( expectedType === "object" ) {
				ok = actual instanceof expected.constructor &&
					actual.name === expected.name &&
					actual.message === expected.message;

			// expected is a validation function which returns true if validation passed
			} else if ( expectedType === "function" && expected.call( {}, actual ) === true ) {
				expectedOutput = null;
				ok = true;
			}

			this.push( ok, actual, expectedOutput, message );
		} else {
			this.test.pushFailure( message, null, "No exception was thrown." );
		}
	}
};

// Provide an alternative to assert.throws(), for enviroments that consider throws a reserved word
// Known to us are: Closure Compiler, Narwhal
(function() {
	/*jshint sub:true */
	Assert.prototype.raises = Assert.prototype[ "throws" ];
}());
<commit_msg>Core: Remove JSDoc comments at the assertion methods<commit_after>function Assert( testContext ) {
	this.test = testContext;
}

// Assert helpers
QUnit.assert = Assert.prototype = {

	// Specify the number of expected assertions to guarantee that failed test
	// (no assertions are run at all) don't slip through.
	expect: function( asserts ) {
		if ( arguments.length === 1 ) {
			this.test.expected = asserts;
		} else {
			return this.test.expected;
		}
	},

	// Increment this Test's semaphore counter, then return a single-use function that
	// decrements that counter a maximum of once.
	async: function() {
		var test = this.test,
			popped = false;

		test.semaphore += 1;
		test.usedAsync = true;
		pauseProcessing();

		return function done() {
			if ( !popped ) {
				test.semaphore -= 1;
				popped = true;
				resumeProcessing();
			} else {
				test.pushFailure( "Called the callback returned from `assert.async` more than once",
					sourceFromStacktrace( 2 ) );
			}
		};
	},

	// Exports test.push() to the user API
	push: function( /* result, actual, expected, message */ ) {
		var assert = this,
			currentTest = ( assert instanceof Assert && assert.test ) || QUnit.config.current;

		// Backwards compatibility fix.
		// Allows the direct use of global exported assertions and QUnit.assert.*
		// Although, it's use is not recommended as it can leak assertions
		// to other tests from async tests, because we only get a reference to the current test,
		// not exactly the test where assertion were intended to be called.
		if ( !currentTest ) {
			throw new Error( "assertion outside test context, in " + sourceFromStacktrace( 2 ) );
		}

		if ( currentTest.usedAsync === true && currentTest.semaphore === 0 ) {
			currentTest.pushFailure( "Assertion after the final `assert.async` was resolved",
				sourceFromStacktrace( 2 ) );

			// Allow this assertion to continue running anyway...
		}

		if ( !( assert instanceof Assert ) ) {
			assert = currentTest.assert;
		}
		return assert.test.push.apply( assert.test, arguments );
	},

	ok: function( result, message ) {
		message = message || ( result ? "okay" : "failed, expected argument to be truthy, was: " +
			QUnit.dump.parse( result ) );
		this.push( !!result, result, true, message );
	},

	equal: function( actual, expected, message ) {
		/*jshint eqeqeq:false */
		this.push( expected == actual, actual, expected, message );
	},

	notEqual: function( actual, expected, message ) {
		/*jshint eqeqeq:false */
		this.push( expected != actual, actual, expected, message );
	},

	propEqual: function( actual, expected, message ) {
		actual = objectValues( actual );
		expected = objectValues( expected );
		this.push( QUnit.equiv( actual, expected ), actual, expected, message );
	},

	notPropEqual: function( actual, expected, message ) {
		actual = objectValues( actual );
		expected = objectValues( expected );
		this.push( !QUnit.equiv( actual, expected ), actual, expected, message );
	},

	deepEqual: function( actual, expected, message ) {
		this.push( QUnit.equiv( actual, expected ), actual, expected, message );
	},

	notDeepEqual: function( actual, expected, message ) {
		this.push( !QUnit.equiv( actual, expected ), actual, expected, message );
	},

	strictEqual: function( actual, expected, message ) {
		this.push( expected === actual, actual, expected, message );
	},

	notStrictEqual: function( actual, expected, message ) {
		this.push( expected !== actual, actual, expected, message );
	},

	"throws": function( block, expected, message ) {
		var actual, expectedType,
			expectedOutput = expected,
			ok = false;

		// 'expected' is optional unless doing string comparison
		if ( message == null && typeof expected === "string" ) {
			message = expected;
			expected = null;
		}

		this.test.ignoreGlobalErrors = true;
		try {
			block.call( this.test.testEnvironment );
		} catch (e) {
			actual = e;
		}
		this.test.ignoreGlobalErrors = false;

		if ( actual ) {
			expectedType = QUnit.objectType( expected );

			// we don't want to validate thrown error
			if ( !expected ) {
				ok = true;
				expectedOutput = null;

			// expected is a regexp
			} else if ( expectedType === "regexp" ) {
				ok = expected.test( errorString( actual ) );

			// expected is a string
			} else if ( expectedType === "string" ) {
				ok = expected === errorString( actual );

			// expected is a constructor, maybe an Error constructor
			} else if ( expectedType === "function" && actual instanceof expected ) {
				ok = true;

			// expected is an Error object
			} else if ( expectedType === "object" ) {
				ok = actual instanceof expected.constructor &&
					actual.name === expected.name &&
					actual.message === expected.message;

			// expected is a validation function which returns true if validation passed
			} else if ( expectedType === "function" && expected.call( {}, actual ) === true ) {
				expectedOutput = null;
				ok = true;
			}

			this.push( ok, actual, expectedOutput, message );
		} else {
			this.test.pushFailure( message, null, "No exception was thrown." );
		}
	}
};

// Provide an alternative to assert.throws(), for enviroments that consider throws a reserved word
// Known to us are: Closure Compiler, Narwhal
(function() {
	/*jshint sub:true */
	Assert.prototype.raises = Assert.prototype[ "throws" ];
}());
<|endoftext|>


<commit_before>'use strict'

module.exports = function (inject, type) {
  var sb
  var manual = !inject

  it('require status-bar', function () {
    sb = require('../lib')
  })

  if (inject) {
    it('create instance with mock properties', function () {
      sb = new sb.Constructor(inject)
    })
  }

  it('should set properties on init', function (done) {
    sb.val = true
    sb.ready.is(true, function () {
      expect(sb.display.val).to.not.be.false
      expect(sb.background.color.val).to.not.be.false
      expect(sb.background.opacity.val).to.not.be.false
      expect(sb.text.color.val).to.not.be.false
      expect(sb.text.opacity.val).to.not.be.false
      done()
    })
  })

  it('should be able to change just color for background', function (done) {
    this.timeout(5000)
    sb.background.color.on('data', (data) => {
      expect(sb.background.color.val).to.equal('FF0000')
      if (!manual) {
        done()
      }
    })

    sb.background.color.val = 'FF0000'

    if (manual) {
      alert('check if the color of status bar changed')
      setTimeout(function () {
        done()
      }, 1000)
    }
  })

  it('should be able to change just the opacity for background', function (done) {
    this.timeout(5000)
    sb.background.opacity.on('data', (data) => {
      expect(sb.background.opacity.val).to.equal(0.9)
      if (!manual) {
        done()
      }
    })
    sb.background.opacity.val = 0.9

    if (manual) {
      alert('check if the opacity of status bar changed')
      setTimeout(function () {
        done()
      }, 1000)
    }
  })

  it('should be able to change just the color for text', function (done) {
    this.timeout(5000)
    sb.text.color.on('data', (data) => {
      expect(sb.text.color.val).to.equal('00ff00')
      if (!manual) {
        done()
      }
    })
    sb.text.color.val = '00ff00'

    if (manual) {
      alert('check if the color of text changed')
      setTimeout(function () {
        done()
      }, 1000)
    }
  })

  it('should be able to change just the opacity for text', function (done) {
    this.timeout(5000)
    sb.text.opacity.on('data', (data) => {
      expect(sb.text.opacity.val).to.equal(0.9)
      if (!manual) {
        done()
      }
    })
    sb.text.opacity.val = 0.9

    if (manual) {
      alert('check if the opacity of text changed')
      setTimeout(function () {
        done()
      }, 2000)
    }
  })

  it('should be able to control the display of status bar', function (done) {
    this.timeout(5000)
    var displayShould
    var times = 0
    sb.display.on('data', () => {
      expect(sb.display.val).to.equal(displayShould)
      if (!manual && times === 3) done()
    })
    setTimeout(() => {
      times++
      sb.display.val = displayShould = 'hidden'
      setTimeout(() => {
        times++
        sb.display.val = displayShould = 'overlay'
        setTimeout(() => {
          times++
          sb.display.val = displayShould = 'top'
        }, 1000)
      }, 1000)
    }, 1000)
    if (manual) {
      alert('did the statusbar changed 3 times (hidden, overlay, top)?')
      setTimeout(function () {
        done()
      }, 1000)
    }
  })
}
<commit_msg>added more tests for double check functionalities in iOS<commit_after>'use strict'

module.exports = function (inject, type) {
  var sb
  var manual = !inject

  it('require status-bar', function () {
    sb = require('../lib')
  })

  if (inject) {
    it('create instance with mock properties', function () {
      sb = new sb.Constructor(inject)
    })
  }

  it('should set properties on init', function (done) {
    sb.val = true
    sb.ready.is(true, function () {
      expect(sb.display.val).to.not.be.false
      expect(sb.background.color.val).to.not.be.false
      expect(sb.background.opacity.val).to.not.be.false
      expect(sb.text.color.val).to.not.be.false
      expect(sb.text.opacity.val).to.not.be.false
      done()
    })
  })

  it('should be able to set color for background to 000000', function (done) {
    this.timeout(5000)
    sb.background.color.on('data', (data) => {
      expect(sb.background.color.val).to.equal('000000')
      if (!manual) {
        done()
      }
    })

    sb.background.color.val = '000000'

    if (manual) {
      alert('check if the color of status bar changed')
      setTimeout(function () {
        done()
      }, 1000)
    }
  })

  it('should be able to set color for background to ffffff', function (done) {
    this.timeout(5000)
    sb.background.color.on('data', (data) => {
      expect(sb.background.color.val).to.equal('ffffff')
      if (!manual) {
        done()
      }
    })

    sb.background.color.val = 'ffffff'

    if (manual) {
      alert('check if the color of status bar changed')
      setTimeout(function () {
        done()
      }, 1000)
    }
  })

  it('should be able to set the opacity for background to 0', function (done) {
    this.timeout(5000)
    sb.background.opacity.on('data', (data) => {
      expect(sb.background.opacity.val).to.equal(0)
      if (!manual) {
        done()
      }
    })
    sb.background.opacity.val = 0

    if (manual) {
      alert('check if the opacity of status bar changed')
      setTimeout(function () {
        done()
      }, 1000)
    }
  })

  it('should be able to set the opacity for background to 1', function (done) {
    this.timeout(5000)
    sb.background.opacity.on('data', (data) => {
      expect(sb.background.opacity.val).to.equal(1)
      if (!manual) {
        done()
      }
    })
    sb.background.opacity.val = 1

    if (manual) {
      alert('check if the opacity of status bar changed')
      setTimeout(function () {
        done()
      }, 1000)
    }
  })

  it('should be able to set the color for text to 000000', function (done) {
    this.timeout(5000)
    sb.text.color.on('data', (data) => {
      expect(sb.text.color.val).to.equal('000000')
      if (!manual) {
        done()
      }
    })
    sb.text.color.val = '000000'

    if (manual) {
      alert('check if the color of text changed')
      setTimeout(function () {
        done()
      }, 1000)
    }
  })

  it('should be able to set the color for text to ffffff', function (done) {
    this.timeout(5000)
    sb.text.color.on('data', (data) => {
      expect(sb.text.color.val).to.equal('ffffff')
      if (!manual) {
        done()
      }
    })
    sb.text.color.val = 'ffffff'

    if (manual) {
      alert('check if the color of text changed')
      setTimeout(function () {
        done()
      }, 1000)
    }
  })

  it('should be able to set the opacity for text to 1', function (done) {
    this.timeout(5000)
    sb.text.opacity.on('data', (data) => {
      expect(sb.text.opacity.val).to.equal(1)
      if (!manual) {
        done()
      }
    })
    sb.text.opacity.val = 1

    if (manual) {
      alert('check if the opacity of text changed')
      setTimeout(function () {
        done()
      }, 2000)
    }
  })

  it('should be able to set the opacity for text to 0', function (done) {
    this.timeout(5000)
    sb.text.opacity.on('data', (data) => {
      expect(sb.text.opacity.val).to.equal(0)
      if (!manual) {
        done()
      }
    })
    sb.text.opacity.val = 0

    if (manual) {
      alert('check if the opacity of text changed')
      setTimeout(function () {
        done()
      }, 2000)
    }
  })

  it('should be able to control the display of status bar', function (done) {
    this.timeout(10000)
    var displayShould
    var times = 0
    sb.display.on('data', () => {
      expect(sb.display.val).to.equal(displayShould)
      if (!manual && times === 3) done()
    })
    setTimeout(() => {
      times++
      sb.display.val = displayShould = 'hidden'
      setTimeout(() => {
        times++
        sb.display.val = displayShould = 'overlay'
        setTimeout(() => {
          times++
          sb.display.val = displayShould = 'top'
        }, 1000)
      }, 1000)
    }, 1000)
    if (manual) {
      alert('the statusbar changed 3 times (hidden, overlay, top)?')
      setTimeout(function () {
        done()
      }, 5000)
    }
  })
}
<|endoftext|>


<commit_before>// vendored from https://github.com/amasad/sane/blob/64ff3a870c42e84f744086884bf55a4f9c22d376/src/utils/recrawl-warning-dedupe.js

'use strict';

class RecrawlWarning {
  constructor(root, count) {
    this.root = root;
    this.count = count;
  }

  static findByRoot(root) {
    for (let i = 0; i < this.RECRAWL_WARNINGS.length; i++) {
      const warning = this.RECRAWL_WARNINGS[i];
      if (warning.root === root) {
        return warning;
      }
    }
  }

  static isRecrawlWarningDupe(warningMessage) {
    if (typeof warningMessage !== 'string') {
      return false;
    }
    const match = warningMessage.match(this.REGEXP);
    if (!match) {
      return false;
    }
    const count = Number(match[1]);
    const root = match[2];

    const warning = this.findByRoot(root);

    if (warning) {
      // only keep the highest count, assume count to either stay the same or
      // increase.
      if (warning.count >= count) {
        return true;
      } else {
        // update the existing warning to the latest (highest) count
        warning.count = count;
        return false;
      }
    } else {
      this.RECRAWL_WARNINGS.push(new RecrawlWarning(root, count));
      return false;
    }
  }
}

RecrawlWarning.RECRAWL_WARNINGS = [];
RecrawlWarning.REGEXP = /Recrawled this watch (\d+) times, most recently because:\n([^:]+)/;

module.exports = RecrawlWarning;
<commit_msg>chore: fix lint warning<commit_after>// vendored from https://github.com/amasad/sane/blob/64ff3a870c42e84f744086884bf55a4f9c22d376/src/utils/recrawl-warning-dedupe.js

'use strict';

class RecrawlWarning {
  constructor(root, count) {
    this.root = root;
    this.count = count;
  }

  static findByRoot(root) {
    for (let i = 0; i < this.RECRAWL_WARNINGS.length; i++) {
      const warning = this.RECRAWL_WARNINGS[i];
      if (warning.root === root) {
        return warning;
      }
    }

    return undefined;
  }

  static isRecrawlWarningDupe(warningMessage) {
    if (typeof warningMessage !== 'string') {
      return false;
    }
    const match = warningMessage.match(this.REGEXP);
    if (!match) {
      return false;
    }
    const count = Number(match[1]);
    const root = match[2];

    const warning = this.findByRoot(root);

    if (warning) {
      // only keep the highest count, assume count to either stay the same or
      // increase.
      if (warning.count >= count) {
        return true;
      } else {
        // update the existing warning to the latest (highest) count
        warning.count = count;
        return false;
      }
    } else {
      this.RECRAWL_WARNINGS.push(new RecrawlWarning(root, count));
      return false;
    }
  }
}

RecrawlWarning.RECRAWL_WARNINGS = [];
RecrawlWarning.REGEXP = /Recrawled this watch (\d+) times, most recently because:\n([^:]+)/;

module.exports = RecrawlWarning;
<|endoftext|>


<commit_before>import React, { Component } from 'react'
import { Link } from 'react-router-dom'
import ReactFireMixin from 'reactfire'
import reactMixin from 'react-mixin'
import { Button, ButtonGroup, ControlLabel, Form, FormControl, ListGroupItem } from 'react-bootstrap'
import { SortableContainer, SortableElement, SortableHandle, arrayMove } from 'react-sortable-hoc'
import { firebaseRef } from '../api/firebase'
import { withAppContext } from '../providers'

class Playlist extends Component {
  firebaseSequenceRef = firebaseRef.child('playlist/sequence')

  state = {
    sequence: null,
  }

  componentDidMount() {
    this.bindAsArray(this.firebaseSequenceRef, 'sequence')
  }

  createItem = (data) =>
    this.firebaseSequenceRef.push({'.priority': this.state.sequence.length, ...data})

  removeItem = (item) =>
    this.firebaseSequenceRef.child(item['.key']).remove()

  onSortEnd = ({ oldIndex, newIndex }) => {
    arrayMove(this.state.sequence, oldIndex, newIndex).forEach((item, position) =>
      this.firebaseSequenceRef.child(item['.key']).setPriority(position)
    )
  }

  render = () => {
    if (!this.props.appsLoaded || !this.state.sequence)
      return
Loading…

    return (

        <ButtonGroup>
          <Button title="Run in wireframe mode">
            <Link to="/preview">

            </Link>
          </Button>
          <Button title="Run the playlist">
            <Link to="/display">

            </Link>
          </Button>
        </ButtonGroup>
        <PlayListSequence
          apps={this.props.apps}
          items={this.state.sequence}
          editable={this.props.editable}
          remove={this.removeItem.bind(this)}
          onSortEnd={this.onSortEnd}
          useDragHandle={true} axis={'y'} />
        {this.props.editable &&
          <ListGroupItem>
            <AddPlayListItem apps={this.props.apps} create={this.createItem} />
          </ListGroupItem>}

    )
  }
}
reactMixin(Playlist.prototype, ReactFireMixin)
export default withAppContext(Playlist)

const Handle = SortableHandle(() =>
)

let PlayListItem = ({ item, app, editable, remove }) =>
  <ListGroupItem key={item['.key']}>
    {editable && <Handle />}

      {app.name}
      {item.duration &&  ({item.duration} seconds)}
      {' '}
      {editable &&
         remove(item)} />}

  </ListGroupItem>
PlayListItem = SortableElement(PlayListItem)

let PlayListSequence = ({ apps, items, editable, remove }) =>

    {items.map((item, index) =>
      <PlayListItem item={item} key={item['.key']} index={index}
        app={apps[item.app]} editable={editable} remove={remove} />)}

PlayListSequence = SortableContainer(PlayListSequence)

class AddPlayListItem extends Component {
  state = { app: 0 }

  handleSubmit(event) {
    event.preventDefault()
    this.props.create(this.state)
  }

  render() {
    const keys = Object.keys(this.props.apps).filter((k) => k[0] !== '.')
    return <Form inline onSubmit={this.handleSubmit.bind(this)}>
      <ControlLabel>Application: </ControlLabel>
      <FormControl componentClass="select"
          defaultValue={this.props.apps[0]['.key']}
          onChange={(e) => this.setState({app: e.target.value})}>
        {keys.map((key) =>
          <option key={key} value={key}>
            {this.props.apps[key].name}
          </option>)}
      </FormControl>
      <Button type="submit" bsSize="small" className="pull-right">Add</Button>
    </Form>
  }
}
<commit_msg>move playlist edit operations outside of component<commit_after>import React, { Component } from 'react'
import { Link } from 'react-router-dom'
import ReactFireMixin from 'reactfire'
import reactMixin from 'react-mixin'
import { Button, ButtonGroup, ControlLabel, Form, FormControl, ListGroupItem } from 'react-bootstrap'
import { SortableContainer, SortableElement, SortableHandle, arrayMove } from 'react-sortable-hoc'
import { firebaseRef } from '../api/firebase'
import { withAppContext } from '../providers'

const playlistItemsRef = firebaseRef.child('playlist/sequence')

const addPlaylistItem = (playlist, data) =>
  playlistItemsRef.push({'.priority': playlist.sequence.length, ...data})

const removePlaylistItem = (playlist, item) =>
  playlistItemsRef.child(item['.key']).remove()

const movePlaylistItem = (playlist, oldIndex, newIndex) =>
  arrayMove(playlist.sequence, oldIndex, newIndex).forEach((item, position) =>
    playlistItemsRef.child(item['.key']).setPriority(position)
  )

class Playlist extends Component {
  sequenceRef = firebaseRef.child('playlist/sequence')

  state = {
    sequence: null,
  }

  componentDidMount() {
    this.bindAsArray(this.sequenceRef, 'sequence')
  }

  render = () => {
    if (!this.props.appsLoaded || !this.state.sequence)
      return
Loading…

    return (

        <ButtonGroup>
          <Button title="Run in wireframe mode">
            <Link to="/preview">

            </Link>
          </Button>
          <Button title="Run the playlist">
            <Link to="/display">

            </Link>
          </Button>
        </ButtonGroup>

        <PlayListSequence
          apps={this.props.apps}
          items={this.state.sequence}
          editable={this.props.editable}
          remove={removePlaylistItem.bind(null, this.state)}
          onSortEnd={({oldIndex, newIndex}) => movePlaylistItem(this.state, oldIndex, newIndex)}
          useDragHandle={true} axis={'y'} />

        {this.props.editable &&
          <ListGroupItem>
            <AddPlayListItem apps={this.props.apps} create={addPlaylistItem.bind(null, this.state)} />
          </ListGroupItem>}

    )
  }
}
reactMixin(Playlist.prototype, ReactFireMixin)
export default withAppContext(Playlist)

const DragHandle = SortableHandle(() =>
)

let PlayListItem = ({ item, key, app, editable, remove }) =>
  <ListGroupItem key={key}>
    {editable && <DragHandle />}

      {app.name}
      {item.duration &&  ({item.duration} seconds)}
      {' '}
      {editable &&
         remove(item)} />}

  </ListGroupItem>
PlayListItem = SortableElement(PlayListItem)

let PlayListSequence = ({ apps, items, editable, remove }) =>

    {items.map((item, index) =>
      <PlayListItem item={item} key={item['.key']} index={index}
        app={apps[item.app]} editable={editable} remove={remove} />)}

PlayListSequence = SortableContainer(PlayListSequence)

class AddPlayListItem extends Component {
  state = { app: 0 }

  handleSubmit(event) {
    event.preventDefault()
    this.props.create(this.state)
  }

  render() {
    const keys = Object.keys(this.props.apps).filter((k) => k[0] !== '.')
    return <Form inline onSubmit={this.handleSubmit.bind(this)}>
      <ControlLabel>Application: </ControlLabel>
      <FormControl componentClass="select"
          defaultValue={this.props.apps[0]['.key']}
          onChange={(e) => this.setState({app: e.target.value})}>
        {keys.map((key) =>
          <option key={key} value={key}>
            {this.props.apps[key].name}
          </option>)}
      </FormControl>
      <Button type="submit" bsSize="small" className="pull-right">Add</Button>
    </Form>
  }
}
<|endoftext|>


<commit_before>athens.ajax_section = (function () {

    /**
     * The set of get variables which shall be included when requesting a section
     *
     * @type {{}}
     */
    var getVarRegistry = {};

    /**
     * A dictionary of sections, by name or handle
     *
     * @type []
     */
    var sectionRegistry = [];

    /**
     * An array of functions to call following every section load
     *
     * @type {Array}
     */
    var postSectionActions = [];

    /**
     * Represents a "get variable" to be encoded into a url string
     *
     * @param sectionName
     * @param filterName
     * @param argName
     * @param value
     * @returns {{sectionName: *, filterName: *, argName: *, value: *}}
     */
    var getVar = function (sectionName, filterName, argName, value) {
        return {
            sectionName: sectionName,
            filterName: filterName,
            argName: argName,
            value: value
        };
    };

    /**
     * Register a get var for inclusion in section requests
     *
     * @param getVar
     */
    var registerGetVar = function (getVar) {
        if (!(getVar.sectionName in getVarRegistry)) {
            getVarRegistry[getVar.sectionName] = {};
        }

        if (!(getVar.filterName in getVarRegistry[getVar.sectionName])) {
            getVarRegistry[getVar.sectionName][getVar.filterName] = {};
        }

        getVarRegistry[getVar.sectionName][getVar.filterName][getVar.argName] = getVar.value;
    };

    /**
     * De-register a getVar
     *
     * @param getVar
     */
    var unsetGetVar = function (getVar) {
        if (getVar.sectionName in getVarRegistry &&
            getVar.filterName in getVarRegistry[getVar.sectionName] &&
            getVar.argName in getVarRegistry[getVar.sectionName][getVar.filterName]
        ) {
            delete getVarRegistry[getVar.sectionName][getVar.filterName][getVar.argName];
        }
    };

    /**
     *
     * @param sectionName
     * @param filterName
     * @param argName
     * @returns {*}
     */
    var getGetVarValue = function (sectionName, filterName, argName) {

        if (sectionName in getVarRegistry &&
            filterName in getVarRegistry[sectionName] &&
            argName in getVarRegistry[sectionName][filterName]
        ) {
            return getVarRegistry[sectionName][filterName][argName];
        }
        return null;
    };

    /**
     * Render the registered get variables for a given AJAXSection into a URL-encoded string
     *
     * @param {string} name The name or handle of the AJAXSection for which we are encoding the get variables
     * @returns {string} The URL-encoded string of get variables
     */
    var renderGetVars = function (name) {
        if (!(name in getVarRegistry)) {
            return "";
        }

        var ret = "";
        for (var filterName in getVarRegistry[name]) {
            if (getVarRegistry[name].hasOwnProperty(filterName)) {
                for (var argName in getVarRegistry[name][filterName]) {
                    if (getVarRegistry[name][filterName].hasOwnProperty(argName)) {
                        ret += filterName + "-" + argName + "=" + getVarRegistry[name][filterName][argName] + "&";
                    }
                }
            }
        }

        return ret;
    };

    function getQueryParams(qs)
    {
        qs = qs.split('+').join(' ');

        var params = {},
            tokens,
            re = /[?&]?([^=]+)=([^&]*)/g;

        while (tokens = re.exec(qs)) {
            params[decodeURIComponent(tokens[1])] = decodeURIComponent(tokens[2]);
        }

        return params;
    }

    function cleanQueryParams(url)
    {
        var qs = url.substr(url.indexOf("?") + 1);
        params = getQueryParams(qs);

        qs = '';
        for (var param in params) {
            if (params.hasOwnProperty(param)) {
                qs += encodeURIComponent(param) + '=' + encodeURIComponent(params[param]) + '&';
            }
        }

        return url.split('?')[0] + '?' + qs;
    }

    /**
     * Load a registered section by name, ignoring the query variables in its indicated path.
     *
     * @param {string} id The name or handle of the section, as registered in sectionRegistry by registerAJAXSection
     */
    var bareLoadSection = function (id) {
        var targetDiv, targetUrl;

        targetDiv = $("#" + id);
        if (sectionRegistry.hasOwnProperty(id) && !targetDiv.data("request-uri")) {
            targetUrl = sectionRegistry[id];
        } else {
            targetUrl = targetDiv.data("request-uri");
            sectionRegistry[id] = targetUrl;
        }

        doLoadSection(id, targetDiv[0], targetUrl.split("?")[0]);
    };

    /**
     * Load a registered section by name
     *
     * @param {string} id The name or handle of the section, as registered in sectionRegistry by registerAJAXSection
     */
    var loadSection = function (id) {
        var targetDiv, targetUrl;

        targetDiv = $("#" + id);
        if (sectionRegistry.hasOwnProperty(id) && !targetDiv.data("request-uri")) {
            targetUrl = sectionRegistry[id];
        } else {
            targetUrl = targetDiv.data("request-uri");
            sectionRegistry[id] = targetUrl;
        }

        doLoadSection(id, targetDiv[0], targetUrl);

    };

    /**
     * Load a registered section by name
     *
     * @param {string} id The name or handle of the section, as registered in sectionRegistry by registerAJAXSection
     * @param {element} targetDiv
     * @param {string} targetUrl
     */
    var doLoadSection = function (id, targetDiv, targetUrl) {
        targetDiv = $(targetDiv);
        targetDiv.css("opacity", 0.7).append("

");

        if (targetUrl.indexOf("?") === -1) {
            targetUrl += "?";
        }

        targetUrl = targetUrl + renderGetVars(id);

        targetUrl = cleanQueryParams(targetUrl);

        $.get(
            targetUrl,
            function (data) {
                var targetResponse = $(data).find("#" + id);
                targetDiv.replaceWith(targetResponse);
                doPostSectionActions(targetDiv);
            }
        );
    };

    /**
     * Add a function to the array of callables to perform after every section load.
     *
     * @param f
     */
    var registerPostSectionAction = function (f) {
        postSectionActions.push(f);
    };

    /**
     * Execute those callables which should be called after every section load
     * @param target
     */
    var doPostSectionActions = function (target) {
        for (var i = 0; i < postSectionActions.length; i++) {
            postSectionActions[i](target);
        }
    };

    return {
        doPostSectionActions: doPostSectionActions,
        registerPostSectionAction: registerPostSectionAction,
        bareLoadSection: bareLoadSection,
        loadSection: loadSection,
        registerGetVar: registerGetVar,
        unsetGetVar: unsetGetVar,
        getVar: getVar,
        getGetVarValue: getGetVarValue
    };

}());
<commit_msg>Return an AJAX promise from section loading.<commit_after>athens.ajax_section = (function () {

    /**
     * The set of get variables which shall be included when requesting a section
     *
     * @type {{}}
     */
    var getVarRegistry = {};

    /**
     * A dictionary of sections, by name or handle
     *
     * @type []
     */
    var sectionRegistry = [];

    /**
     * An array of functions to call following every section load
     *
     * @type {Array}
     */
    var postSectionActions = [];

    /**
     * Represents a "get variable" to be encoded into a url string
     *
     * @param sectionName
     * @param filterName
     * @param argName
     * @param value
     * @returns {{sectionName: *, filterName: *, argName: *, value: *}}
     */
    var getVar = function (sectionName, filterName, argName, value) {
        return {
            sectionName: sectionName,
            filterName: filterName,
            argName: argName,
            value: value
        };
    };

    /**
     * Register a get var for inclusion in section requests
     *
     * @param getVar
     */
    var registerGetVar = function (getVar) {
        if (!(getVar.sectionName in getVarRegistry)) {
            getVarRegistry[getVar.sectionName] = {};
        }

        if (!(getVar.filterName in getVarRegistry[getVar.sectionName])) {
            getVarRegistry[getVar.sectionName][getVar.filterName] = {};
        }

        getVarRegistry[getVar.sectionName][getVar.filterName][getVar.argName] = getVar.value;
    };

    /**
     * De-register a getVar
     *
     * @param getVar
     */
    var unsetGetVar = function (getVar) {
        if (getVar.sectionName in getVarRegistry &&
            getVar.filterName in getVarRegistry[getVar.sectionName] &&
            getVar.argName in getVarRegistry[getVar.sectionName][getVar.filterName]
        ) {
            delete getVarRegistry[getVar.sectionName][getVar.filterName][getVar.argName];
        }
    };

    /**
     *
     * @param sectionName
     * @param filterName
     * @param argName
     * @returns {*}
     */
    var getGetVarValue = function (sectionName, filterName, argName) {

        if (sectionName in getVarRegistry &&
            filterName in getVarRegistry[sectionName] &&
            argName in getVarRegistry[sectionName][filterName]
        ) {
            return getVarRegistry[sectionName][filterName][argName];
        }
        return null;
    };

    /**
     * Render the registered get variables for a given AJAXSection into a URL-encoded string
     *
     * @param {string} name The name or handle of the AJAXSection for which we are encoding the get variables
     * @returns {string} The URL-encoded string of get variables
     */
    var renderGetVars = function (name) {
        if (!(name in getVarRegistry)) {
            return "";
        }

        var ret = "";
        for (var filterName in getVarRegistry[name]) {
            if (getVarRegistry[name].hasOwnProperty(filterName)) {
                for (var argName in getVarRegistry[name][filterName]) {
                    if (getVarRegistry[name][filterName].hasOwnProperty(argName)) {
                        ret += filterName + "-" + argName + "=" + getVarRegistry[name][filterName][argName] + "&";
                    }
                }
            }
        }

        return ret;
    };

    function getQueryParams(qs)
    {
        qs = qs.split('+').join(' ');

        var params = {},
            tokens,
            re = /[?&]?([^=]+)=([^&]*)/g;

        while (tokens = re.exec(qs)) {
            params[decodeURIComponent(tokens[1])] = decodeURIComponent(tokens[2]);
        }

        return params;
    }

    function cleanQueryParams(url)
    {
        var qs = url.substr(url.indexOf("?") + 1);
        params = getQueryParams(qs);

        qs = '';
        for (var param in params) {
            if (params.hasOwnProperty(param)) {
                qs += encodeURIComponent(param) + '=' + encodeURIComponent(params[param]) + '&';
            }
        }

        return url.split('?')[0] + '?' + qs;
    }

    /**
     * Load a registered section by name, ignoring the query variables in its indicated path.
     *
     * @param {string} id The name or handle of the section, as registered in sectionRegistry by registerAJAXSection
     * @returns {*}
     */
    var bareLoadSection = function (id) {
        var targetDiv, targetUrl;

        targetDiv = $("#" + id);
        if (sectionRegistry.hasOwnProperty(id) && !targetDiv.data("request-uri")) {
            targetUrl = sectionRegistry[id];
        } else {
            targetUrl = targetDiv.data("request-uri");
            sectionRegistry[id] = targetUrl;
        }

        return doLoadSection(id, targetDiv[0], targetUrl.split("?")[0]);
    };

    /**
     * Load a registered section by name
     *
     * @param {string} id The name or handle of the section, as registered in sectionRegistry by registerAJAXSection
     * @returns {*}
     */
    var loadSection = function (id) {
        var targetDiv, targetUrl;

        targetDiv = $("#" + id);
        if (sectionRegistry.hasOwnProperty(id) && !targetDiv.data("request-uri")) {
            targetUrl = sectionRegistry[id];
        } else {
            targetUrl = targetDiv.data("request-uri");
            sectionRegistry[id] = targetUrl;
        }

        return doLoadSection(id, targetDiv[0], targetUrl);

    };

    /**
     * Load a registered section by name
     *
     * @param {string} id The name or handle of the section, as registered in sectionRegistry by registerAJAXSection
     * @param {element} targetDiv
     * @param {string} targetUrl
     * @returns {*}
     */
    var doLoadSection = function (id, targetDiv, targetUrl) {
        targetDiv = $(targetDiv);
        targetDiv.css("opacity", 0.7).append("

");

        if (targetUrl.indexOf("?") === -1) {
            targetUrl += "?";
        }

        targetUrl = targetUrl + renderGetVars(id);

        targetUrl = cleanQueryParams(targetUrl);

        return $.get(
            targetUrl,
            function (data) {
                var targetResponse = $(data).find("#" + id);
                targetDiv.replaceWith(targetResponse);
                doPostSectionActions(targetDiv);
            }
        );
    };

    /**
     * Add a function to the array of callables to perform after every section load.
     *
     * @param f
     */
    var registerPostSectionAction = function (f) {
        postSectionActions.push(f);
    };

    /**
     * Execute those callables which should be called after every section load
     * @param target
     */
    var doPostSectionActions = function (target) {
        for (var i = 0; i < postSectionActions.length; i++) {
            postSectionActions[i](target);
        }
    };

    return {
        doPostSectionActions: doPostSectionActions,
        registerPostSectionAction: registerPostSectionAction,
        bareLoadSection: bareLoadSection,
        loadSection: loadSection,
        registerGetVar: registerGetVar,
        unsetGetVar: unsetGetVar,
        getVar: getVar,
        getGetVarValue: getGetVarValue
    };

}());
<|endoftext|>


<commit_before>
var expect = require('expect');
var lsys = require('../lindenmayer')

describe('Correct behavior of L-Systems', function() {

  it('should handle UTF8', function() {
    var test = new lsys.LSystem({
      word:'⚣⚤●',
      productions: [['⚣', '♂♂'], ['⚤', '♀♂'], ['●', '○◐◑']]
    })
    expect(test.next().value).toBe('♂♂♀♁○◐◑')
  })

  it('should generate the Koch-curve', function() {
    var koch = new lsys.LSystem({
      word:'F',
      productions: [['F', 'F+F--F+F']]
    })

    expect(koch.next().value).toBe('F+F--F+F')
    expect(koch.next().value).toBe('F+F--F+F+F+F--F+F--F+F--F+F+F+F--F+F')
    expect(koch.next().value).toBe('F+F--F+F+F+F--F+F--F+F--F+F+F+F--F+F+F+F--F+F+F+F--F+F--F+F--F+F+F+F--F+F--F+F--F+F+F+F--F+F--F+F--F+F+F+F--F+F+F+F--F+F+F+F--F+F--F+F--F+F+F+F--F+F')
  })

});
<commit_msg>Update tests.js<commit_after>
var expect = require('expect');
var lsys = require('../lindenmayer')

describe('Correct behavior of L-Systems', function() {

  it('should handle UTF8', function() {
    var test = new lsys.LSystem({
      word:'⚣⚤●',
      productions: [['⚣', '♂♂'], ['⚤', '♀♂'], ['●', '○◐◑']]
    })
    expect(test.next().value).toBe('♂♂♀♂○◐◑')
  })

  it('should generate the Koch-curve', function() {
    var koch = new lsys.LSystem({
      word:'F',
      productions: [['F', 'F+F--F+F']]
    })

    expect(koch.next().value).toBe('F+F--F+F')
    expect(koch.next().value).toBe('F+F--F+F+F+F--F+F--F+F--F+F+F+F--F+F')
    expect(koch.next().value).toBe('F+F--F+F+F+F--F+F--F+F--F+F+F+F--F+F+F+F--F+F+F+F--F+F--F+F--F+F+F+F--F+F--F+F--F+F+F+F--F+F--F+F--F+F+F+F--F+F+F+F--F+F+F+F--F+F--F+F--F+F+F+F--F+F')
  })

});
<|endoftext|>


<commit_before>// Handler functions for the /assets endpoint.

var async = require('async');
var fs = require('fs');
var path = require('path');
var crypto = require('crypto');
var storage = require('./storage');
var log = require('./logging').getLogger();

/**
 * @description Calculate a checksum of an uploaded file's contents to generate
 *   the fingerprinted asset name.
 */
function fingerprintAsset (asset, callback) {
  var sha256sum = crypto.createHash('sha256');
  var assetFile = fs.createReadStream(asset.path);
  var chunks = [];

  assetFile.on('data', function (chunk) {
    sha256sum.update(chunk);
    chunks.push(chunk);
  });

  assetFile.on('error', callback);

  assetFile.on('end', function () {
    var digest = sha256sum.digest('hex');
    var ext = path.extname(asset.name);
    var basename = path.basename(asset.name, ext);
    var fingerprinted = basename + '-' + digest + ext;

    log.debug({
      action: 'assetstore',
      originalAssetName: asset.name,
      assetFilename: fingerprinted,
      assetContentType: asset.type,
      message: 'Asset fingerprinted successfully.'
    });

    callback(null, {
      key: asset.key,
      original: asset.name,
      chunks: chunks,
      filename: fingerprinted,
      type: asset.type
    });
  });
}

/**
 * @description Upload an asset's contents to the asset container.
 */
function publishAsset (asset, callback) {
  storage.storeAsset(asset, function (err, asset) {
    if (err) {
      return callback(err);
    }

    log.debug({
      action: 'assetstore',
      assetFilename: asset.filename,
      assetContentType: asset.type,
      message: 'Asset uploaded successfully.'
    });

    callback(null, asset);
  });
}

/**
 * @description Give this asset a name. The final name and CDL URI of this
 *   asset will be included in all outgoing metadata envelopes, for use by
 *   layouts.
 */
function nameAsset (asset, callback) {
  storage.nameAsset(asset, function (err, asset) {
    if (err) {
      return callback(err);
    }

    log.debug({
      action: 'assetstore',
      originalAssetFilename: asset.original,
      assetName: asset.key,
      message: 'Asset named successfully.'
    });

    callback(null, asset);
  });
}

/**
 * @description Create and return a function that processes a single asset.
 */
function makeAssetHandler (shouldName) {
  return function (asset, callback) {
    log.debug({
      action: 'assetstore',
      originalAssetName: asset.name,
      message: 'Asset upload request received.'
    });

    var steps = [
      async.apply(fingerprintAsset, asset),
      publishAsset
    ];

    if (shouldName) {
      steps.push(nameAsset);
    }

    async.waterfall(steps, callback);
  };
}

/**
 * @description Enumerate all named assets.
 */
var enumerateNamed = exports.enumerateNamed = function (callback) {
  storage.findNamedAssets(function (err, assetVars) {
    if (err) {
      return callback(err);
    }

    var assets = {};

    for (var i = 0; i < assetVars.length; i++) {
      var assetVar = assetVars[i];
      assets[assetVar.key] = assetVar.publicURL;
    }

    callback(null, assets);
  });
};

/**
 * @description Append a list of asset names to a message before it's logged.
 */
function withAssetList (message, originalAssetNames) {
  var subset = originalAssetNames.slice(0, 3);

  if (originalAssetNames.length > 3) {
    subset.push('..');
  }

  var joined = subset.join(', ');

  return message + ': ' + joined + '.';
}

/**
 * @description Fingerprint and upload static, binary assets to the
 *   CDN-enabled ASSET_CONTAINER. Return a JSON object containing a
 *   map of the provided filenames to their final, public URLs.
 */
exports.accept = function (req, res, next) {
  var originalAssetNames = [];
  var assetData = Object.getOwnPropertyNames(req.files).map(function (key) {
    var asset = req.files[key];
    asset.key = key;
    originalAssetNames.push(key);
    return asset;
  });

  log.debug({
    action: 'assetstore',
    apikeyName: req.apikeyName,
    assetCount: assetData.length,
    originalAssetNames: originalAssetNames,
    message: withAssetList('Asset upload request received', originalAssetNames)
  });

  var reqStart = Date.now();

  async.map(assetData, makeAssetHandler(req.query.named), function (err, results) {
    if (err) {
      var statusCode = err.statusCode || 500;

      log.error({
        action: 'assetstore',
        statusCode: statusCode,
        apikeyName: req.apikeyName,
        error: err.message,
        stack: err.stack,
        message: withAssetList('Unable to upload one or more assets', originalAssetNames)
      });

      res.send(statusCode, {
        apikeyName: req.apikeyName,
        error: 'Unable to upload one or more assets.'
      });

      return next(err);
    }

    var summary = {};
    results.forEach(function (result) {
      summary[result.original] = result.publicURL;
    });
    log.info({
      action: 'assetstore',
      statusCode: 200,
      apikeyName: req.apikeyName,
      totalReqDuration: Date.now() - reqStart,
      message: withAssetList('All assets have been uploaded successfully', originalAssetNames)
    });

    res.send(summary);
    next();
  });
};

exports.list = function (req, res, next) {
  log.debug('Asset list requested.');

  enumerateNamed(function (err, assets) {
    if (err) {
      log.error({
        action: 'assetlist',
        statusCode: err.statusCode || 500,
        message: 'Unable to list assets.',
        error: err.message,
        stack: err.stack
      });
      return next(err);
    }

    res.send(assets);
    next();
  });
};

exports.retrieve = function (req, res, next) {
  log.debug({
    action: 'assetretrieve',
    message: 'Asset requested directly.'
  });

  var reqStart = Date.now();

  storage.getAsset(req.params.id, function (err, asset) {
    if (err) {
      log.error({
        action: 'assetretrieve',
        statusCode: err.statusCode || 500,
        message: 'Unable to retrieve asset',
        error: err.message,
        stack: err.stack
      });
      return next(err);
    }

    res.header('Content-Type', asset.contentType);
    res.send(asset.body);

    log.info({
      action: 'contentretrieve',
      statusCode: 200,
      assetFilename: req.params.id,
      assetContentType: asset.contentType,
      totalReqDuration: Date.now() - reqStart,
      message: 'Asset request successful.'
    });

    next();
  });
};
<commit_msg>Maybe this will work?<commit_after>// Handler functions for the /assets endpoint.

var async = require('async');
var fs = require('fs');
var path = require('path');
var crypto = require('crypto');
var storage = require('./storage');
var log = require('./logging').getLogger();

/**
 * @description Calculate a checksum of an uploaded file's contents to generate
 *   the fingerprinted asset name.
 */
function fingerprintAsset (asset, callback) {
  var sha256sum = crypto.createHash('sha256');
  var assetFile = fs.createReadStream(asset.path);
  var chunks = [];

  assetFile.on('data', function (chunk) {
    sha256sum.update(chunk);
    chunks.push(chunk);
  });

  assetFile.on('error', callback);

  assetFile.on('end', function () {
    var digest = sha256sum.digest('hex');
    var ext = path.extname(asset.name);
    var basename = path.basename(asset.name, ext);
    var fingerprinted = basename + '-' + digest + ext;

    log.debug({
      action: 'assetstore',
      originalAssetName: asset.name,
      assetFilename: fingerprinted,
      assetContentType: asset.type,
      message: 'Asset fingerprinted successfully.'
    });

    callback(null, {
      key: asset.key,
      original: asset.name,
      chunks: chunks,
      filename: fingerprinted,
      type: asset.type
    });
  });
}

/**
 * @description Upload an asset's contents to the asset container.
 */
function publishAsset (asset, callback) {
  storage.storeAsset(asset, function (err, asset) {
    if (err) {
      return callback(err);
    }

    log.debug({
      action: 'assetstore',
      assetFilename: asset.filename,
      assetContentType: asset.type,
      message: 'Asset uploaded successfully.'
    });

    callback(null, asset);
  });
}

/**
 * @description Give this asset a name. The final name and CDL URI of this
 *   asset will be included in all outgoing metadata envelopes, for use by
 *   layouts.
 */
function nameAsset (asset, callback) {
  storage.nameAsset(asset, function (err, asset) {
    if (err) {
      return callback(err);
    }

    log.debug({
      action: 'assetstore',
      originalAssetFilename: asset.original,
      assetName: asset.key,
      message: 'Asset named successfully.'
    });

    callback(null, asset);
  });
}

/**
 * @description Create and return a function that processes a single asset.
 */
function makeAssetHandler (shouldName) {
  return function (asset, callback) {
    log.debug({
      action: 'assetstore',
      originalAssetName: asset.name,
      message: 'Asset upload request received.'
    });

    var steps = [
      async.apply(fingerprintAsset, asset),
      publishAsset
    ];

    if (shouldName) {
      steps.push(nameAsset);
    }

    async.waterfall(steps, callback);
  };
}

/**
 * @description Enumerate all named assets.
 */
var enumerateNamed = exports.enumerateNamed = function (callback) {
  storage.findNamedAssets(function (err, assetVars) {
    if (err) {
      return callback(err);
    }

    var assets = {};

    for (var i = 0; i < assetVars.length; i++) {
      var assetVar = assetVars[i];
      assets[assetVar.key] = assetVar.publicURL;
    }

    callback(null, assets);
  });
};

/**
 * @description Append a list of asset names to a message before it's logged.
 */
function withAssetList (message, originalAssetNames) {
  var subset = originalAssetNames.slice(0, 3);

  if (originalAssetNames.length > 3) {
    subset.push('..');
  }

  var joined = subset.join(', ');

  return message + ': ' + joined + '.';
}

/**
 * @description Fingerprint and upload static, binary assets to the
 *   CDN-enabled ASSET_CONTAINER. Return a JSON object containing a
 *   map of the provided filenames to their final, public URLs.
 */
exports.accept = function (req, res, next) {
  var originalAssetNames = [];
  var assetData = Object.getOwnPropertyNames(req.files).map(function (key) {
    var asset = req.files[key];
    asset.key = key;
    originalAssetNames.push(key);
    return asset;
  });

  log.debug({
    action: 'assetstore',
    apikeyName: req.apikeyName,
    assetCount: assetData.length,
    originalAssetNames: originalAssetNames,
    message: withAssetList('Asset upload request received', originalAssetNames)
  });

  var reqStart = Date.now();

  async.map(assetData, makeAssetHandler(req.query.named), function (err, results) {
    if (err) {
      var statusCode = err.statusCode || 500;

      log.error({
        action: 'assetstore',
        statusCode: statusCode,
        apikeyName: req.apikeyName,
        error: err.message,
        stack: err.stack,
        message: withAssetList('Unable to upload one or more assets', originalAssetNames)
      });

      res.send(statusCode, {
        apikeyName: req.apikeyName,
        error: 'Unable to upload one or more assets.'
      });

      return next(err);
    }

    var summary = {};
    results.forEach(function (result) {
      summary[result.original] = result.publicURL;
    });
    log.info({
      action: 'assetstore',
      statusCode: 200,
      apikeyName: req.apikeyName,
      totalReqDuration: Date.now() - reqStart,
      message: withAssetList('All assets have been uploaded successfully', originalAssetNames)
    });

    res.send(summary);
    next();
  });
};

exports.list = function (req, res, next) {
  log.debug('Asset list requested.');

  enumerateNamed(function (err, assets) {
    if (err) {
      log.error({
        action: 'assetlist',
        statusCode: err.statusCode || 500,
        message: 'Unable to list assets.',
        error: err.message,
        stack: err.stack
      });
      return next(err);
    }

    res.send(assets);
    next();
  });
};

exports.retrieve = function (req, res, next) {
  log.debug({
    action: 'assetretrieve',
    message: 'Asset requested directly.'
  });

  var reqStart = Date.now();

  storage.getAsset(req.params.id, function (err, asset) {
    if (err) {
      log.error({
        action: 'assetretrieve',
        statusCode: err.statusCode || 500,
        message: 'Unable to retrieve asset',
        error: err.message,
        stack: err.stack
      });
      return next(err);
    }

    res.send(200, asset.body, {
      'Content-Type': asset.contentType
    });

    log.info({
      action: 'assetretrieve',
      statusCode: 200,
      assetFilename: req.params.id,
      assetContentType: asset.contentType,
      totalReqDuration: Date.now() - reqStart,
      message: 'Asset request successful.'
    });

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


<commit_before>/* global Vulcan */
/*

    # Vulcan.exportPostDetails({ selector, outputDir })

      Script to export a list of post details to a CSV file.

      selector (Object, optional):
        Mongo selector to choose posts. Default is all published pending and approved posts
      baseUrl (String, required):
        The website for which you are exporting posts, ie:
        https://lesswrong.com
      outputDir (String, required):
        Absolute path to the directory where you'd like the CSV output to be written
      outputFile (String, optional):
        Filename for your CSV file. Defaults to 'post_details'

    # Vulcan.exportPostDetailsByMonth({ month, outputDir, outputFile })

      Export details for a whole month

      month: (String, optional)
        Month to export posts for in

*/

import { wrapVulcanAsyncScript } from './utils'
import { Posts } from '../../lib/collections/posts'
import Users from 'meteor/vulcan:users'
import fs from 'mz/fs'
import path from 'path'
import moment from 'moment'
import Papa from 'papaparse'

function getPosts (selector) {
  const defaultSelector = {
    baseScore: {$gte: 0},
    draft: {$ne: true},
    status: { $in: [1, 2] }
  }

  const fields = {
    id: 1,
    userId: 1,
    title: 1,
    slug: 1,
    baseScore: 1,
    meta: 1,
    frontpageDate: 1,
    postedAt: 1,
    createdAt: 1
  }

  const finalSelector = Object.assign({}, defaultSelector, selector || {})

  return Posts
    .find(finalSelector, {fields, sort: { createdAt: 1 }})
}

Vulcan.exportPostDetails = wrapVulcanAsyncScript(
  'exportPostDetails',
  async ({selector, baseUrl, outputDir, outputFile = 'post_details.csv'}) => {
    if (!outputDir) throw new Error('you must specify an output directory (hint: {outputDir})')
    if (!baseUrl) throw new Error('you must specify a base url (hint: {baseUrl})')
    const documents = getPosts(selector)
    let c = 0
    const count = documents.count()
    const rows = []
    for (let post of documents) {
      // SD: this makes things horribly slow, but no idea how to do a more efficient join query in Mongo
      const user = Users.findOne(post.userId, { fields: { username: 1, email: 1 }})
      const row = {
        username: user.username + 'asdlfkjas;dlfkja',
        email: user.email,
        id: post._id,
        user_id: post.userId,
        title: post.title,
        slug: post.slug,
        karma: post.baseScore,
        community: !!post.meta,
        frontpage_date: post.frontpageDate,
        posted_at: post.postedAt,
        created_at: post.createdAt,
        url: `${baseUrl}/posts/${post._id}/${post.slug}`
      }
      rows.push(row)
      c++
      //eslint-disable-next-line no-console
      if (c % 20 === 0) console.log(`Post Details: Processed ${c}/${count} posts (${Math.round(c / count * 100)}%)`)
    }
    const csvFile = Papa.unparse(rows)
    const filePath = path.join(outputDir,`${path.basename(outputFile)}.csv`)
    await fs.writeFile(filePath, csvFile)
    //eslint-disable-next-line no-console
    console.log(`Wrote details for ${rows.length} posts to ${filePath}`)
  })

Vulcan.exportPostDetailsByMonth = ({month, baseUrl, outputDir, outputFile}) => {
  const lastMonth = moment.utc(month, 'YYYY-MM').startOf('month')
  outputFile = outputFile || `post_details_${lastMonth.format('YYYY-MM')}`
  //eslint-disable-next-line no-console
  console.log(`Exporting all posts from ${lastMonth.format('MMM YYYY')}`)
  return Vulcan.exportPostDetails({
    selector: {
      createdAt: {
        $gte: lastMonth.toDate(), // first of prev month
        $lte: moment.utc(lastMonth).endOf('month').toDate()
      }
    },
    baseUrl,
    outputFile,
    outputDir
  })
}
<commit_msg>url from site settings<commit_after>/* global Vulcan */
/*

    # Vulcan.exportPostDetails({ selector, outputDir })

      Script to export a list of post details to a CSV file.

      selector (Object, optional):
        Mongo selector to choose posts. Default is all published pending and approved posts
      outputDir (String, required):
        Absolute path to the directory where you'd like the CSV output to be written
      outputFile (String, optional):
        Filename for your CSV file. Defaults to 'post_details'

    # Vulcan.exportPostDetailsByMonth({ month, outputDir, outputFile })

      Export details for a whole month

      month: (String, optional)
        Month to export posts for in

*/

import { wrapVulcanAsyncScript } from './utils'
import { getSetting } from 'meteor/vulcan:core';
import { Posts } from '../../lib/collections/posts'
import Users from 'meteor/vulcan:users'
import fs from 'mz/fs'
import path from 'path'
import moment from 'moment'
import Papa from 'papaparse'

function getPosts (selector) {
  const defaultSelector = {
    baseScore: {$gte: 0},
    draft: {$ne: true},
    status: { $in: [1, 2] }
  }

  const fields = {
    id: 1,
    userId: 1,
    title: 1,
    slug: 1,
    baseScore: 1,
    meta: 1,
    frontpageDate: 1,
    postedAt: 1,
    createdAt: 1
  }

  const finalSelector = Object.assign({}, defaultSelector, selector || {})

  return Posts
    .find(finalSelector, {fields, sort: { createdAt: 1 }})
}

Vulcan.exportPostDetails = wrapVulcanAsyncScript(
  'exportPostDetails',
  async ({selector, outputDir, outputFile = 'post_details.csv'}) => {
    if (!outputDir) throw new Error('you must specify an output directory (hint: {outputDir})')
    const documents = getPosts(selector)
    let c = 0
    const count = documents.count()
    const rows = []
    for (let post of documents) {
      // SD: this makes things horribly slow, but no idea how to do a more efficient join query in Mongo
      const user = Users.findOne(post.userId, { fields: { username: 1, email: 1 }})
      const postUrl = getSetting('siteUrl')
      const row = {
        username: user.username,
        email: user.email,
        id: post._id,
        user_id: post.userId,
        title: post.title,
        slug: post.slug,
        karma: post.baseScore,
        community: !!post.meta,
        frontpage_date: post.frontpageDate,
        posted_at: post.postedAt,
        created_at: post.createdAt,
        url: `${postUrl}/posts/${post._id}/${post.slug}`
      }
      rows.push(row)
      c++
      //eslint-disable-next-line no-console
      if (c % 20 === 0) console.log(`Post Details: Processed ${c}/${count} posts (${Math.round(c / count * 100)}%)`)
    }
    const csvFile = Papa.unparse(rows)
    const filePath = path.join(outputDir,`${path.basename(outputFile)}.csv`)
    await fs.writeFile(filePath, csvFile)
    //eslint-disable-next-line no-console
    console.log(`Wrote details for ${rows.length} posts to ${filePath}`)
  })

Vulcan.exportPostDetailsByMonth = ({month, outputDir, outputFile}) => {
  const lastMonth = moment.utc(month, 'YYYY-MM').startOf('month')
  outputFile = outputFile || `post_details_${lastMonth.format('YYYY-MM')}`
  //eslint-disable-next-line no-console
  console.log(`Exporting all posts from ${lastMonth.format('MMM YYYY')}`)
  return Vulcan.exportPostDetails({
    selector: {
      createdAt: {
        $gte: lastMonth.toDate(), // first of prev month
        $lte: moment.utc(lastMonth).endOf('month').toDate()
      }
    },
    outputFile,
    outputDir
  })
}
<|endoftext|>


<commit_before>'use strict';

const passport = require('passport');
const cookie = require('cookie-signature');
const auth = require('./auth');
const userLib = require('./user')();
const db = require('./databaseConfig');
const logger = require('./logging').getLogger(__filename);
const expressWinston = require('express-winston');
const winstonCloudWatch = require('winston-cloudwatch');
const winston = require('winston');
const {URL} = require('url');

let cookieKey;
let cookieSecret;
const actualHost = new URL(process.env.DUMONDA_ME_DOMAIN).host;

const getLoggingTransport = function (jsonFormat) {
    let transports = [];
    if (process.env.NODE_ENV !== 'production') {
        transports.push(new winston.transports.Console({
            format: winston.format.combine(winston.format.colorize(), winston.format.simple())
        }));
    }
    if (process.env.CLOUD_WATCH_LOG_STREAM_NAME) {
        transports.push(new winstonCloudWatch({
            logGroupName: 'elyoosWebserver',
            logStreamName: process.env.CLOUD_WATCH_LOG_STREAM_NAME,
            level: 'info',
            jsonMessage: jsonFormat,
            awsRegion: process.env.AWS_REGION
        }));
    }
    return transports;
};

module.exports = function (app, nuxt) {

    app.get('/healthCheck', function (req, res) {
        res.type('text/plain');
        res.send("OK");
    });

    if (process.env.ROBOT_TEXT_ENABLE_CRAWLER === 'true') {
        app.get('/robots.txt', function (req, res) {
            res.type('text/plain');
            res.send("User-agent: *\nDisallow: *?answerId=* \nDisallow: *?eventId=*");
        });
    } else {
        app.get('/robots.txt', function (req, res) {
            res.type('text/plain');
            res.send("User-agent: *\nDisallow: /");
        });
    }

    app.on('middleware:before:session', function () {
        app.use(function (req, res, next) {
            let host = req.get('Host');
            if (host !== actualHost) {
                return res.redirect(301, process.env.DUMONDA_ME_DOMAIN + req.originalUrl);
            }
            return next();
        });
    });

    app.on('middleware:after:session', function () {
        app.use(passport.initialize());
        app.use(passport.session());
        //Tell passport to use our newly created local strategy for authentication
        passport.use(auth.localStrategy());
        //Give passport a way to serialize and deserialize a user. In this case, by the user's id.
        passport.serializeUser(userLib.serialize);
        passport.deserializeUser(userLib.deserialize);

        if ('testing' !== process.env.NODE_ENV) {
            app.use(function (req, res, next) {
                //Needed because rolling is some how not working
                req.session.touch();
                next();
            });
        }

        if (nuxt && nuxt.render) {
            app.use(function (req, res, next) {
                if (req.originalUrl.match(/^\/api\//) === null) {
                    req.headers.cookie = cookieKey + '=s:' + cookie.sign(req.sessionID, cookieSecret);
                }
                req.session.save(async function () {
                    if (req.originalUrl.match(/^\/api\//) === null) {
                        try {
                            await nuxt.render(req, res);
                        } catch (err) {
                            logger.error('Nuxt rendering has failed', {error: err});
                        }
                    } else {
                        next();
                    }
                });
            });
        }
    });

    app.on('middleware:before:router', function () {
        app.use(expressWinston.logger({
            transports: getLoggingTransport(false)
        }));
    });

    app.on('middleware:after:router', function () {
        app.use(expressWinston.errorLogger({
            transports: getLoggingTransport(true),
            meta: true,
            msg: "HTTP {{req.method}} {{req.url}}",
            expressFormat: true,
            dynamicMeta: function (req) {
                return {
                    user: req.user ? req.user : null,
                    body: req.body ? req.body : null,
                };
            }
        }));
    });

    return {
        onconfig: function (config, next) {

            let dbConfig = config.get('databaseConfig');
            db.config(dbConfig);
            let cookieConfig = config.get('middleware').session.module.arguments.find(arg => arg.cookie);
            cookieKey = cookieConfig.key;
            cookieSecret = cookieConfig.secret;

            next(null, config);
        }
    };

};
<commit_msg>Removed redirect.<commit_after>'use strict';

const passport = require('passport');
const cookie = require('cookie-signature');
const auth = require('./auth');
const userLib = require('./user')();
const db = require('./databaseConfig');
const logger = require('./logging').getLogger(__filename);
const expressWinston = require('express-winston');
const winstonCloudWatch = require('winston-cloudwatch');
const winston = require('winston');

let cookieKey;
let cookieSecret;

const getLoggingTransport = function (jsonFormat) {
    let transports = [];
    if (process.env.NODE_ENV !== 'production') {
        transports.push(new winston.transports.Console({
            format: winston.format.combine(winston.format.colorize(), winston.format.simple())
        }));
    }
    if (process.env.CLOUD_WATCH_LOG_STREAM_NAME) {
        transports.push(new winstonCloudWatch({
            logGroupName: 'elyoosWebserver',
            logStreamName: process.env.CLOUD_WATCH_LOG_STREAM_NAME,
            level: 'info',
            jsonMessage: jsonFormat,
            awsRegion: process.env.AWS_REGION
        }));
    }
    return transports;
};

module.exports = function (app, nuxt) {

    app.get('/healthCheck', function (req, res) {
        res.type('text/plain');
        res.send("OK");
    });

    if (process.env.ROBOT_TEXT_ENABLE_CRAWLER === 'true') {
        app.get('/robots.txt', function (req, res) {
            res.type('text/plain');
            res.send("User-agent: *\nDisallow: *?answerId=* \nDisallow: *?eventId=*");
        });
    } else {
        app.get('/robots.txt', function (req, res) {
            res.type('text/plain');
            res.send("User-agent: *\nDisallow: /");
        });
    }

    app.on('middleware:after:session', function () {
        app.use(passport.initialize());
        app.use(passport.session());
        //Tell passport to use our newly created local strategy for authentication
        passport.use(auth.localStrategy());
        //Give passport a way to serialize and deserialize a user. In this case, by the user's id.
        passport.serializeUser(userLib.serialize);
        passport.deserializeUser(userLib.deserialize);

        if ('testing' !== process.env.NODE_ENV) {
            app.use(function (req, res, next) {
                //Needed because rolling is some how not working
                req.session.touch();
                next();
            });
        }

        if (nuxt && nuxt.render) {
            app.use(function (req, res, next) {
                if (req.originalUrl.match(/^\/api\//) === null) {
                    req.headers.cookie = cookieKey + '=s:' + cookie.sign(req.sessionID, cookieSecret);
                }
                req.session.save(async function () {
                    if (req.originalUrl.match(/^\/api\//) === null) {
                        try {
                            await nuxt.render(req, res);
                        } catch (err) {
                            logger.error('Nuxt rendering has failed', {error: err});
                        }
                    } else {
                        next();
                    }
                });
            });
        }
    });

    app.on('middleware:before:router', function () {
        app.use(expressWinston.logger({
            transports: getLoggingTransport(false)
        }));
    });

    app.on('middleware:after:router', function () {
        app.use(expressWinston.errorLogger({
            transports: getLoggingTransport(true),
            meta: true,
            msg: "HTTP {{req.method}} {{req.url}}",
            expressFormat: true,
            dynamicMeta: function (req) {
                return {
                    user: req.user ? req.user : null,
                    body: req.body ? req.body : null,
                };
            }
        }));
    });

    return {
        onconfig: function (config, next) {

            let dbConfig = config.get('databaseConfig');
            db.config(dbConfig);
            let cookieConfig = config.get('middleware').session.module.arguments.find(arg => arg.cookie);
            cookieKey = cookieConfig.key;
            cookieSecret = cookieConfig.secret;

            next(null, config);
        }
    };

};
<|endoftext|>


<commit_before>"use strict"
//external
var assert = require('assert');
var path = require('path');
var fs = require('fs');
var _ = require('underscore');
var ValidationError = require("error/validation");
var OptionError = require("error/option");

//internal
var lib = path.join(path.dirname(fs.realpathSync(__filename)), '../src/lib');
var config = require(lib + '/config');
var recordTypes = config.recordTypes;
var recordTypeNames = config.recordTypeNames;
var utils = require(lib + '/utils');
var getEntry = utils.getEntry;
var getRecord = utils.getRecord;

function isValidationError(error) {
  if ( error.type === 'ValidationError' ) {
    return true;
  }
};

function testBadValues (fieldKey, badValues, recordOptions) {
  var badValues = badValues || [];
  var fieldKey = fieldKey || 'title not provided';
  _.each(badValues, function (badValue) {
    var i = {};
    i[fieldKey] = badValue;
    var badOptions = _.extend(_.clone(recordOptions), i);
    if (badValue === 'not provided') {
      delete badOptions[fieldKey];
    }
    it("should throw if " + fieldKey + " is [ " + badValue + " ]", function () {
      assert.throws(function () { getRecord('descriptive', badOptions) }, Error);
    });
  });
};

describe('# config', function () {

  describe('Descriptive Columns', function () {

    it('should get a total of 120 characters', function () {
      var totalCharsInColumns =_.reduce(recordTypes.descriptive.columns, function (total, column) {
        return total + column.size;
      }, 1);
      //initial value is 1 as we do not define the record type column
      assert.equal(120, totalCharsInColumns);
    });

    it('should validate each column against the column schema', function () {
      _.each(recordTypes.descriptive.columns, function(column) {
        //var errors = config.column.schema.validate(_.extend(_.clone(config.column.defaultOptions), column));
        var errors = config.column.schema.validate(_.defaults(column, config.column.defaultOptions));
        assert.equal(0, errors.length);
      });
    });

  });

});

describe('# utils', function () {
  var emptyOptions = {};

  describe('getRecord()', function () {
    var goodRecordOptions = {
      seq: 1,
      bankAbr: 'WBC',
      userSpec: 'LIFE CHURCH',
      userId: '252359',
      description: 'Payments',
      date: '311214',
    };

    it("should throw if type is not 'descriptive', 'detail' or 'file-total'", function () {
      assert.throws(function () {getRecord('foo', goodRecordOptions)}, Error);
      assert.throws(function () {getRecord('#', goodRecordOptions)}, Error);
    });

    describe('descriptive record', function () {
      var recordOutput = "0                 01WBC       LIFE CHURCH               252359Payments    290814                                        ";
      var recordOptions = {
        seq: 1,
        bankAbr: 'WBC',
        userSpec: 'LIFE CHURCH',
        userId: '252359',
        description: 'Payments',
        date: '290814',
      };

      it("should return a valid descriptive record", function () {
        assert.equal(recordOutput, getRecord('descriptive', recordOptions));
      });

      describe('seq', function () {
        testBadValues( this.title, ['not provided', null, undefined, '3', 'a'], recordOptions);
      });

      describe('bankAbr', function () {
        testBadValues( this.title, ['not provided', null, undefined, 'a', 'ab', 'abcd', '###', 123, '123'], recordOptions);
      });

      describe('userSpec', function () {
        testBadValues( this.title, ['not provided', null, undefined, '',], recordOptions);
      });

      describe('userId', function () {
        testBadValues( this.title, ['not provided', null, undefined, ''], recordOptions);
      });

      describe('description', function () {
        testBadValues( this.title, ['not provided', null, undefined, '', 'very long description', 1232344], recordOptions);
      });

      describe('date', function () {
        testBadValues( this.title, ['not provided', null, undefined, 'a', 'ab', 'abcd', '###', 123456], recordOptions);
      });

    });

  });

  describe('getEntry()', function () {

    it("should throw options do not validate", function () {
      assert.throws(
        function () {getEntry('foo', emptyOptions)},
        isValidationError
        );
    });

  });

});
<commit_msg>Add tests for detail record columns<commit_after>"use strict"
//external
var assert = require('assert');
var path = require('path');
var fs = require('fs');
var _ = require('underscore');
var ValidationError = require("error/validation");
var OptionError = require("error/option");

//internal
var lib = path.join(path.dirname(fs.realpathSync(__filename)), '../src/lib');
var config = require(lib + '/config');
var recordTypes = config.recordTypes;
var recordTypeNames = config.recordTypeNames;
var utils = require(lib + '/utils');
var getEntry = utils.getEntry;
var getRecord = utils.getRecord;

function isValidationError(error) {
  if ( error.type === 'ValidationError' ) {
    return true;
  }
};

function testBadValues (fieldKey, badValues, recordOptions) {
  var badValues = badValues || [];
  var fieldKey = fieldKey || 'title not provided';
  _.each(badValues, function (badValue) {
    var i = {};
    i[fieldKey] = badValue;
    var badOptions = _.extend(_.clone(recordOptions), i);
    if (badValue === 'not provided') {
      delete badOptions[fieldKey];
    }
    it("should throw if " + fieldKey + " is [ " + badValue + " ]", function () {
      assert.throws(function () { getRecord('descriptive', badOptions) }, Error);
    });
  });
};

describe('# config', function () {
  _.each(['descriptive', 'detail'], function (type) {
    describe('Config for ' + type + ' Columns', function () {

      it('should get a total of 120 characters', function () {
        var totalCharsInColumns =_.reduce(recordTypes[type].columns, function (total, column) {
          return total + column.size;
        }, 1);
        //initial value is 1 as we do not define the record type column
        assert.equal(120, totalCharsInColumns);
      });

      it('should validate each column against the column schema', function () {
        _.each(recordTypes[type].columns, function(column) {
          var errors = config.column.schema.validate(_.defaults(column, config.column.defaultOptions));
          assert.equal(0, errors.length);
        });
      });

    });
  });

});

describe('# utils', function () {
  var emptyOptions = {};

  describe('getRecord()', function () {
    var goodRecordOptions = {
      seq: 1,
      bankAbr: 'WBC',
      userSpec: 'LIFE CHURCH',
      userId: '252359',
      description: 'Payments',
      date: '311214',
    };

    it("should throw if type is not 'descriptive', 'detail' or 'file-total'", function () {
      assert.throws(function () {getRecord('foo', goodRecordOptions)}, Error);
      assert.throws(function () {getRecord('#', goodRecordOptions)}, Error);
    });

    describe('descriptive record', function () {
      var recordOutput = "0                 01WBC       LIFE CHURCH               252359Payments    290814                                        ";
      var recordOptions = {
        seq: 1,
        bankAbr: 'WBC',
        userSpec: 'LIFE CHURCH',
        userId: '252359',
        description: 'Payments',
        date: '290814',
      };

      it("should return a valid descriptive record", function () {
        assert.equal(recordOutput, getRecord('descriptive', recordOptions));
      });

      describe('seq', function () {
        testBadValues( this.title, ['not provided', null, undefined, '3', 'a'], recordOptions);
      });

      describe('bankAbr', function () {
        testBadValues( this.title, ['not provided', null, undefined, 'a', 'ab', 'abcd', '###', 123, '123'], recordOptions);
      });

      describe('userSpec', function () {
        testBadValues( this.title, ['not provided', null, undefined, '',], recordOptions);
      });

      describe('userId', function () {
        testBadValues( this.title, ['not provided', null, undefined, ''], recordOptions);
      });

      describe('description', function () {
        testBadValues( this.title, ['not provided', null, undefined, '', 'very long description', 1232344], recordOptions);
      });

      describe('date', function () {
        testBadValues( this.title, ['not provided', null, undefined, 'a', 'ab', 'abcd', '###', 123456], recordOptions);
      });

    });

  });

  describe('getEntry()', function () {

    it("should throw options do not validate", function () {
      assert.throws(
        function () {getEntry('foo', emptyOptions)},
        isValidationError
        );
    });

  });

});
<|endoftext|>


<commit_before>// LICENSE : MIT
"use strict";
import assert from "power-assert";
import {usageOfContent, usageOfFiles} from "../src/es-usage-rate";
import glob from "glob";
describe("usage", function () {
    describe("usageOfFiles", function () {
        it("should return string", ()=> {
            const filePathList = glob.sync(__dirname + "/../src/**.js");
            var output = usageOfFiles(filePathList);
            assert(typeof output === "string");
        });
    });
    describe("usageOfContent", function () {
        it("should return string", ()=> {
            var output = usageOfContent("var a = 1");
            assert(typeof output === "string");
            assert.equal(output, `Program
VariableDeclaration:var
VariableDeclarator
Identifier
NumericLiteral`)
        });
        it("should return Generator", ()=> {
            var output = usageOfContent("var a = function *(){}");
            assert(typeof output === "string");
            assert.equal(output, `Program
VariableDeclaration:var
VariableDeclarator
Identifier
GeneratorExpression
BlockStatement`)
        });
    });
});<commit_msg>fix test<commit_after>// LICENSE : MIT
"use strict";
import assert from "power-assert";
import {usageOfContent, usageOfFiles} from "../src/es-usage-rate";
import glob from "glob";
describe("usage", function () {
    describe("usageOfFiles", function () {
        it("should return string", ()=> {
            const filePathList = glob.sync(__dirname + "/../src/**.js");
            var output = usageOfFiles(filePathList);
            assert(typeof output === "string");
        });
    });
    describe("usageOfContent", function () {
        it("should return string", ()=> {
            var output = usageOfContent("var a = 1");
            assert(typeof output === "string");
            assert.equal(output, `Program
VariableDeclaration_var
VariableDeclarator
Identifier
NumericLiteral`)
        });
        it("should return Generator", ()=> {
            var output = usageOfContent("var a = function *(){}");
            assert(typeof output === "string");
            assert.equal(output, `Program
VariableDeclaration_var
VariableDeclarator
Identifier
GeneratorExpression
BlockStatement`)
        });
    });
});<|endoftext|>


<commit_before>'use strict';

let passport = require('passport');
let cookie = require('cookie-signature');
let auth = require('./auth');
let userLib = require('./user')();
let db = require('./databaseConfig');
let logger = require('./logging').getLogger(__filename);
let expressWinston = require('express-winston');
let winstonCloudWatch = require('winston-cloudwatch');
let winston = require('winston');

let cookieKey;
let cookieSecret;

const getLoggingTransport = function (jsonFormat) {
    let transports = [];
    if (process.env.NODE_ENV !== 'production') {
        transports.push(new winston.transports.Console({
            format: winston.format.combine(winston.format.colorize(), winston.format.simple())
        }));
    }
    if (process.env.CLOUD_WATCH_LOG_STREAM_NAME) {
        transports.push(new winstonCloudWatch({
            logGroupName: 'elyoosWebserver',
            logStreamName: process.env.CLOUD_WATCH_LOG_STREAM_NAME,
            level: 'info',
            jsonMessage: jsonFormat,
            awsRegion: process.env.AWS_REGION
        }));
    }
    return transports;
};

module.exports = function (app, nuxt) {

    app.get('/healthCheck', function (req, res) {
        res.type('text/plain');
        res.send("OK");
    });

    if (process.env.ROBOT_TEXT_ENABLE_CRAWLER === 'true') {
        app.get('/robots.txt', function (req, res) {
            res.type('text/plain');
            res.send("User-agent: *\nDisallow: ");
        });
    } else {
        app.get('/robots.txt', function (req, res) {
            res.type('text/plain');
            res.send("User-agent: *\nDisallow: /");
        });
    }

    app.on('middleware:after:session', function () {
        app.use(passport.initialize());
        app.use(passport.session());
        //Tell passport to use our newly created local strategy for authentication
        passport.use(auth.localStrategy());
        //Give passport a way to serialize and deserialize a user. In this case, by the user's id.
        passport.serializeUser(userLib.serialize);
        passport.deserializeUser(userLib.deserialize);

        if ('testing' !== process.env.NODE_ENV) {
            app.use(function (req, res, next) {
                //Needed because rolling is some how not working
                req.session.touch();
                next();
            });
        }

        if (nuxt && nuxt.render) {
            app.use(function (req, res, next) {
                if (req.originalUrl.match(/api/) === null) {
                    req.headers.cookie = cookieKey + '=s:' + cookie.sign(req.sessionID, cookieSecret);
                }
                req.session.save(async function () {
                    if (req.originalUrl.match(/api/) === null) {
                        try {
                            await nuxt.render(req, res);
                        } catch (err) {
                            logger.error('Nuxt rendering has failed', {error: err});
                        }
                    } else {
                        next();
                    }
                });
            });
        }
    });

    app.on('middleware:before:router', function () {
        app.use(expressWinston.logger({
            transports: getLoggingTransport(false)
        }));
    });

    app.on('middleware:after:router', function () {
        app.use(expressWinston.errorLogger({
            transports: getLoggingTransport(true),
            meta: true,
            msg: "HTTP {{req.method}} {{req.url}}",
            expressFormat: true
        }));
    });

    return {
        onconfig: function (config, next) {

            let dbConfig = config.get('databaseConfig');
            db.config(dbConfig);
            let cookieConfig = config.get('middleware').session.module.arguments.find(arg => arg.cookie);
            cookieKey = cookieConfig.key;
            cookieSecret = cookieConfig.secret;

            next(null, config);
        }
    };

};
<commit_msg>Body and user added to error message.<commit_after>'use strict';

let passport = require('passport');
let cookie = require('cookie-signature');
let auth = require('./auth');
let userLib = require('./user')();
let db = require('./databaseConfig');
let logger = require('./logging').getLogger(__filename);
let expressWinston = require('express-winston');
let winstonCloudWatch = require('winston-cloudwatch');
let winston = require('winston');

let cookieKey;
let cookieSecret;

const getLoggingTransport = function (jsonFormat) {
    let transports = [];
    if (process.env.NODE_ENV !== 'production') {
        transports.push(new winston.transports.Console({
            format: winston.format.combine(winston.format.colorize(), winston.format.simple())
        }));
    }
    if (process.env.CLOUD_WATCH_LOG_STREAM_NAME) {
        transports.push(new winstonCloudWatch({
            logGroupName: 'elyoosWebserver',
            logStreamName: process.env.CLOUD_WATCH_LOG_STREAM_NAME,
            level: 'info',
            jsonMessage: jsonFormat,
            awsRegion: process.env.AWS_REGION
        }));
    }
    return transports;
};

module.exports = function (app, nuxt) {

    app.get('/healthCheck', function (req, res) {
        res.type('text/plain');
        res.send("OK");
    });

    if (process.env.ROBOT_TEXT_ENABLE_CRAWLER === 'true') {
        app.get('/robots.txt', function (req, res) {
            res.type('text/plain');
            res.send("User-agent: *\nDisallow: ");
        });
    } else {
        app.get('/robots.txt', function (req, res) {
            res.type('text/plain');
            res.send("User-agent: *\nDisallow: /");
        });
    }

    app.on('middleware:after:session', function () {
        app.use(passport.initialize());
        app.use(passport.session());
        //Tell passport to use our newly created local strategy for authentication
        passport.use(auth.localStrategy());
        //Give passport a way to serialize and deserialize a user. In this case, by the user's id.
        passport.serializeUser(userLib.serialize);
        passport.deserializeUser(userLib.deserialize);

        if ('testing' !== process.env.NODE_ENV) {
            app.use(function (req, res, next) {
                //Needed because rolling is some how not working
                req.session.touch();
                next();
            });
        }

        if (nuxt && nuxt.render) {
            app.use(function (req, res, next) {
                if (req.originalUrl.match(/api/) === null) {
                    req.headers.cookie = cookieKey + '=s:' + cookie.sign(req.sessionID, cookieSecret);
                }
                req.session.save(async function () {
                    if (req.originalUrl.match(/api/) === null) {
                        try {
                            await nuxt.render(req, res);
                        } catch (err) {
                            logger.error('Nuxt rendering has failed', {error: err});
                        }
                    } else {
                        next();
                    }
                });
            });
        }
    });

    app.on('middleware:before:router', function () {
        app.use(expressWinston.logger({
            transports: getLoggingTransport(false)
        }));
    });

    app.on('middleware:after:router', function () {
        app.use(expressWinston.errorLogger({
            transports: getLoggingTransport(true),
            meta: true,
            msg: "HTTP {{req.method}} {{req.url}}",
            expressFormat: true,
            dynamicMeta: function(req) {
                return {
                    user: req.user ? req.user : null,
                    body: req.body ? req.body : null,
                };
            }
        }));
    });

    return {
        onconfig: function (config, next) {

            let dbConfig = config.get('databaseConfig');
            db.config(dbConfig);
            let cookieConfig = config.get('middleware').session.module.arguments.find(arg => arg.cookie);
            cookieKey = cookieConfig.key;
            cookieSecret = cookieConfig.secret;

            next(null, config);
        }
    };

};
<|endoftext|>