<commit_before>import React, { Component } from 'react';
import cx from 'classnames';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import WindowEventHandler from 'utils/component/WindowEventHandler';
import getViewportSize from 'utils/dom/getViewportSize';
import throttle from 'lodash/throttle';

class Affix extends Component {
  static propTypes = {
    placeHoldClassName: PropTypes.string,
    className: PropTypes.string,
    prefix: PropTypes.string,
    zIndex: PropTypes.number,
    offsetTop: PropTypes.number,
    offsetBottom: PropTypes.number,
    onPin: PropTypes.func,
    onUnpin: PropTypes.func
  };

  static defaultProps = {
    offsetTop: 0,
    prefix: 'zent',
    zIndex: 10
  };

  constructor(props) {
    super(props);
    this.state = {
      position: 'static',
      width: null,
      placeHoldStyle: {}
    };
  }

  affix = false;

  setFixed = () => {
    const { onPin } = this.props;
    this.affix = true;
    this.setState({ position: 'fixed' });
    onPin && onPin();
  };

  setonUnpin = () => {
    const { onUnpin } = this.props;
    this.affix = false;
    this.setState({ position: 'static' });
    onUnpin && onUnpin();
  };

  setWidth = () => {
    const element = ReactDOM.findDOMNode(this);
    this.setState({
      width: element.offsetWidth,
      placeHoldStyle: {
        width: element.offsetWidth,
        height: element.offsetHeight
      }
    });
  };

  checkFixed = () => {
    const affix = this.affix;
    const props = this.props;
    const element = ReactDOM.findDOMNode(this);
    let reallyNum, propsNum;
    if (props.offsetBottom !== undefined) {
      reallyNum =
        getViewportSize().height - element.getBoundingClientRect().bottom;
      propsNum = props.offsetBottom;
    } else {
      reallyNum = element.getBoundingClientRect().top;
      propsNum = props.offsetTop;
    }

    if (affix && reallyNum > propsNum) {
      this.setonUnpin();
    }
    if (!affix && reallyNum <= propsNum) {
      this.setFixed();
    }
  };

  getStyleObj = () => {
    const { zIndex, offsetBottom, offsetTop } = this.props;
    const { position, width } = this.state;
    let styleObj = {};
    if (position === 'fixed') {
      styleObj = { position, zIndex, width };
      offsetBottom !== undefined
        ? (styleObj.bottom = offsetBottom)
        : (styleObj.top = offsetTop);
    } else {
      styleObj = { position };
    }
    return styleObj;
  };

  componentDidMount() {
    this.checkFixed();
    this.setWidth();
  }

  render() {
    const { prefix, className, placeHoldClassName } = this.props;
    const wrapClass = cx(`${prefix}-affix`, className);
    return (

          {this.props.children}

        <WindowEventHandler
          eventName="scroll"
          callback={throttle(this.checkFixed, 20)}
        />
        <WindowEventHandler
          eventName="resize"
          callback={throttle(this.setWidth, 20)}
        />

    );
  }
}

export default Affix;
<commit_msg>fix: add throttle<commit_after>import React, { Component } from 'react';
import cx from 'classnames';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import WindowEventHandler from 'utils/component/WindowEventHandler';
import getViewportSize from 'utils/dom/getViewportSize';
import throttle from 'lodash/throttle';

class Affix extends Component {
  static propTypes = {
    placeHoldClassName: PropTypes.string,
    className: PropTypes.string,
    prefix: PropTypes.string,
    zIndex: PropTypes.number,
    offsetTop: PropTypes.number,
    offsetBottom: PropTypes.number,
    onPin: PropTypes.func,
    onUnpin: PropTypes.func
  };

  static defaultProps = {
    offsetTop: 0,
    prefix: 'zent',
    zIndex: 10
  };

  constructor(props) {
    super(props);
    this.state = {
      position: 'static',
      width: null,
      placeHoldStyle: {}
    };
  }

  affix = false;

  setFixed = () => {
    const { onPin } = this.props;
    this.affix = true;
    this.setWidth();
    this.setState({ position: 'fixed' });
    onPin && onPin();
  };

  setonUnpin = () => {
    const { onUnpin } = this.props;
    this.affix = false;
    this.setState({ position: 'static', width: null, placeHoldStyle: null });
    onUnpin && onUnpin();
  };

  setWidth = throttle(() => {
    const element = ReactDOM.findDOMNode(this);
    this.setState({
      width: element.offsetWidth,
      placeHoldStyle: {
        width: '100%',
        height: element.offsetHeight
      }
    });
  }, 20);

  checkFixed = throttle(() => {
    const affix = this.affix;
    const props = this.props;
    const element = ReactDOM.findDOMNode(this);
    let reallyNum, propsNum;
    if (props.offsetBottom !== undefined) {
      reallyNum =
        getViewportSize().height - element.getBoundingClientRect().bottom;
      propsNum = props.offsetBottom;
    } else {
      reallyNum = element.getBoundingClientRect().top;
      propsNum = props.offsetTop;
    }

    if (affix && reallyNum > propsNum) {
      this.setonUnpin();
    }
    if (!affix && reallyNum <= propsNum) {
      this.setFixed();
    }
  }, 20);

  getStyleObj = () => {
    const { zIndex, offsetBottom, offsetTop } = this.props;
    const { position, width } = this.state;
    let styleObj = {};
    if (position === 'fixed') {
      styleObj = { position, zIndex, width };
      offsetBottom !== undefined
        ? (styleObj.bottom = offsetBottom)
        : (styleObj.top = offsetTop);
    } else {
      styleObj = { position };
    }
    return styleObj;
  };

  componentDidMount() {
    this.checkFixed();
    this.setWidth();
  }

  render() {
    const { prefix, className, placeHoldClassName } = this.props;
    const wrapClass = cx(`${prefix}-affix`, className);
    return (

          {this.props.children}

        <WindowEventHandler eventName="scroll" callback={this.checkFixed} />
        <WindowEventHandler eventName="resize" callback={this.setWidth} />

    );
  }
}

export default Affix;
<|endoftext|>


<commit_before>// auto-suggest docs:
// http://code.drewwilson.com/entry/autosuggest-jquery-plugin
// Changes to previous
// - prefill and ashtmlid in data-auto-suggest-config
define([
    'jquery',
    '../core/logging',
    '../core/parser',
    '../registry',
    '../utils',
    'jquery_autosuggest',
    'jquery_form'
], function($, logging, Parser, registry, utils) {
    var log = logging.getLogger('autosuggest');

    var parser = new Parser("autosuggest");
    parser.add_argument('words');
    parser.add_argument('pre-fill');
    parser.add_argument('as-html-id', false);
    parser.add_argument('selected-value-prop', "name");
    parser.add_argument('search-obj-prop', "name");
    parser.add_argument('start-text', "Enter text");

    var _ = {
        name: 'autosuggest',
        trigger: "input.pat-autosuggest",
        init: function($el, opts) {
            if ($el.length > 1) {
                return $el.map(function() {
                    return _.init($(this), opts);
                });
            }

            // fetch config from first parent found
            var cfg = _.parser.parse($el, opts);
            if ($el.attr('readonly')) {
                cfg.startText = "";
            }

            if (cfg.preFill && (cfg.preFill.slice(0,1) === ',')) {
                cfg.preFill = cfg.preFill.slice(1);
            }

            $el.data("patterns.autosuggest", cfg);

            $el.on('keydown.pat-autosuggest', _.onKeyDown);

            // are we autosubmit?
            var autosubmit = $el.is('.pat-autosubmit') ||
                    ($el.parents('.pat-autosubmit').length > 0) ||
                    $el.is('.pat-autosubmit2') ||
                    ($el.parents('.pat-autosubmit2').length > 0);
            log.debug('autosubmit', autosubmit, $el);

            // XXX: this feels hacky and is either needed for fast
            // typers in which case it should be in autosubmit or to
            // work around triggers in autoSuggest.
            var $form;
            if (autosubmit) {
                $form = $el.parents('form');

                $form.ajaxForm({
                    data: {
                        submit: "submit"
                    }
                });

                var submit_debounced = utils.debounce(function() {
                    $form.submit();
                }, 400);
                cfg.selectionAdded = function($item) {
                    log.debug('submit because selection was added', $item);
                    // trigger the form
                    submit_debounced();
                };
                cfg.selectionRemoved = function($item) {
                    // ignore removal request if readonly
                    if ($el.attr('readonly')) return;
                    log.debug('submit because selection was removed', $item);
                    // trigger the form
                    $item.remove();
                    submit_debounced();
                };
            }

            var data = cfg.words.split(/\s*,\s*/).map(function(word) {
                return {value: word, name: word};
            });

            $el.autoSuggest(data, cfg);

            return $el;
        },
        destroy: function($el) {
            $el.off('.pat-autosuggest');
            $el.data('patterns.autosuggest', null);

            // XXX: destroy the jqueryPlugin, unfortunately it doesn't
            // support this as of now
        },

        parser: parser,

        onKeyDown: function(ev) {
            var $this = $(this);
            if (ev.which === 13) {
                var $results = $this.parents('.as-selections').next();
                ev.preventDefault();
                // skip ENTER->comma translation, if selection is active
                if (($results.is(':visible')) &&
                    ($results.find('.active').length > 0)) return;
                var newev = $.Event("keydown");
                newev.ctrlKey = false;
                newev.which = 188;
                newev.keyCode = 188;
                $this.trigger(newev);
            }
        }
    };
    registry.register(_);
    return _;
});

// jshint indent: 4, browser: true, jquery: true, quotmark: double
// vim: sw=4 expandtab
<commit_msg>remove old autosuggest hacks<commit_after>// auto-suggest docs:
// http://code.drewwilson.com/entry/autosuggest-jquery-plugin
// Changes to previous
// - prefill and ashtmlid in data-auto-suggest-config
define([
    'jquery',
    '../core/logging',
    '../core/parser',
    '../registry',
    '../utils',
    'jquery_autosuggest',
    'jquery_form'
], function($, logging, Parser, registry, utils) {
    var log = logging.getLogger('autosuggest');

    var parser = new Parser("autosuggest");
    parser.add_argument('words');
    parser.add_argument('pre-fill');
    parser.add_argument('as-html-id', false);
    parser.add_argument('selected-value-prop', "name");
    parser.add_argument('search-obj-prop', "name");
    parser.add_argument('start-text', "Enter text");

    var _ = {
        name: 'autosuggest',
        trigger: "input.pat-autosuggest",
        init: function($el, opts) {
            if ($el.length > 1) {
                return $el.map(function() {
                    return _.init($(this), opts);
                });
            }

            // fetch config from first parent found
            var cfg = _.parser.parse($el, opts);
            if ($el.attr('readonly')) {
                cfg.startText = "";
            }

            if (cfg.preFill && (cfg.preFill.slice(0,1) === ',')) {
                cfg.preFill = cfg.preFill.slice(1);
            }

            $el.on('keydown.pat-autosuggest', _.onKeyDown);

            var data = cfg.words.split(/\s*,\s*/).map(function(word) {
                return {value: word, name: word};
            });

            $el.autoSuggest(data, cfg);

            return $el;
        },
        destroy: function($el) {
            $el.off('.pat-autosuggest');

            // XXX: destroy the jqueryPlugin, unfortunately it doesn't
            // support this as of now
        },

        parser: parser,

        onKeyDown: function(ev) {
            var $this = $(this);
            if (ev.which === 13) {
                var $results = $this.parents('.as-selections').next();
                ev.preventDefault();
                // skip ENTER->comma translation, if selection is active
                if (($results.is(':visible')) &&
                    ($results.find('.active').length > 0)) return;
                var newev = $.Event("keydown");
                newev.ctrlKey = false;
                newev.which = 188;
                newev.keyCode = 188;
                $this.trigger(newev);
            }
        }
    };
    registry.register(_);
    return _;
});

// jshint indent: 4, browser: true, jquery: true, quotmark: double
// vim: sw=4 expandtab
<|endoftext|>


<commit_before>var BlogPost = require('./models/posts');
var BlogPage = require('./models/pages');
var marked = require('marked');

// Adds a new post!
module.exports = function(app){
	marked.setOptions({
		renderer: new marked.Renderer(),
		gfm: true,
		tables: true,
		breaks: false,
		pedantic: false,
		sanitize: true,
		smartLists: true,
		smartypants: false
	});
	app.post('/api/addcontent', function(req, res){
		console.log("Adding Something Awesome!");
		console.log(req.body);
		if(req.body['content-type'] === "post"){
			console.log("content type post");
			BlogPost.create({
				postName: req.body['content-title'],
				postSlug: req.body['content-slug'],
				postDate : new Date(),
				postAuthor : "Brett Warner",
				postBody: marked(req.body['content-body'])
			}, function(err, success){
				if(err)
					res.send(err);
				BlogPost.find(function(err, posts){
					res.send(posts);
				})
			});
		}else if(req.body['content-type'] ==="page"){
			console.log("content type page");
			BlogPage.create({
				pageName: req.body['content-title'],
				pageSlug: req.body['content-slug'],
				pageDate : new Date(),
				pageAuthor : "Brett Warner",
				pageBody: marked(req.body['content-body'])
			}, function(err, success){
				if(err)
					res.send(err);
				BlogPage.find(function(err,pages){
					res.send(pages);
				})
			});
		}
	});

	//Edits a piece of content
	app.post("/api/editcontent", function(req, res){
		console.log("Editing a Piece of Content!")
	});

	//Deletes a post
	app.post("/api/editcontent", function(req, res){
		console.log("Deleting a Post!")
	})
	app.get('/rss', function(req, res){
		var feed = new Feed({
			title: 'Brett Warner',
			description: 'Stuff I break.',
			link: 'http://www.brettkwarner.com',
		//image: 'image'
		copyright: 'Copyright @ 2014 Brett Warner. All rights reserved',

		author: {
			name: 'Brett Warner',
			email: 'brett@brettkwarner.com',
			link: 'http://www.brettkwarner.com'
		}
	});

		BlogPost.find(function(err, thePosts){
			for(var blogPost in thePosts){
				feed.addItem({
					title: thePosts[blogPost].postName,
					link: 'http://www.brettkwarner.com' + thePosts[blogPost].postSlug,
					description: 'still testing',
					date: thePosts[blogPost].postDate
				});
			}
		//res.set('Content-Type', 'text/xml');
		res.set('Content-Type', 'application/rss+xml');
        // Sending the feed as a response
        res.send(feed.render('rss-2.0'));
    });
	});

	app.get('/:pageSlug', function(req, res){

		BlogPage.findOne({ pageSlug: req.params.pageSlug}, function(err, thePage){
			if(!thePage){
				console.log("the error" + err);
				res.send("Not found");
			}else{
				console.log(thePage);
				console.log(req.params.pageTitle);
				res.render("page", {title: thePage.pageName, body: thePage.pageBody});
			}
		});
	});

// This is what I'm currently working on. Will pull a post based on title.
app.get('/blog/:postSlug', function(req,res){
	BlogPost.findOne({ postSlug: req.params.postSlug }, function(err, thePost){
		if(!thePost){
			console.log("The error"+ err);
			res.send('Not found');
		}else{
			console.log(thePost);
			console.log(req.params.postTitle);
			res.render("post", {title: thePost.postName, body: thePost.postBody});
		}
	});
});
}
<commit_msg>moved some functions around, fixed some random indentation issues<commit_after>var BlogPost = require('./models/posts');
var BlogPage = require('./models/pages');
var marked = require('marked');

// Adds a new post!
module.exports = function(app){
	marked.setOptions({
		renderer: new marked.Renderer(),
		gfm: true,
		tables: true,
		breaks: false,
		pedantic: false,
		sanitize: true,
		smartLists: true,
		smartypants: false
	});
	app.post('/api/addcontent', function(req, res){
		console.log("Adding Something Awesome!");
		console.log(req.body);
		if(req.body['content-type'] === "post"){
			console.log("content type post");
			BlogPost.create({
				postName: req.body['content-title'],
				postSlug: req.body['content-slug'],
				postDate : new Date(),
				postAuthor : "Brett Warner",
				postBody: marked(req.body['content-body'])
			}, function(err, success){
				if(err)
					res.send(err);
				BlogPost.find(function(err, posts){
					res.send(posts);
				})
			});
		}else if(req.body['content-type'] ==="page"){
			console.log("content type page");
			BlogPage.create({
				pageName: req.body['content-title'],
				pageSlug: req.body['content-slug'],
				pageDate : new Date(),
				pageAuthor : "Brett Warner",
				pageBody: marked(req.body['content-body'])
			}, function(err, success){
				if(err)
					res.send(err);
				BlogPage.find(function(err,pages){
					res.send(pages);
				})
			});
		}
	});

	//Edits a piece of content needs to be done still
	app.post("/api/editcontent", function(req, res){
		console.log("Editing a Piece of Content!")
	});

	//Deletes a post needs to be done still
	app.post("/api/editcontent", function(req, res){
		console.log("Deleting a Post!")
	})

	app.get('/rss', function(req, res){
		var feed = new Feed({
			title: 'Brett Warner',
			description: 'Stuff I break.',
			link: 'http://www.brettkwarner.com',
		    //image: 'image'
		    copyright: 'Copyright @ 2014 Brett Warner. All rights reserved',

		    author: {
		    	name: 'Brett Warner',
		    	email: 'brett@brettkwarner.com',
		    	link: 'http://www.brettkwarner.com'
		    }
		});

		BlogPost.find(function(err, thePosts){
			for(var blogPost in thePosts){
				feed.addItem({
					title: thePosts[blogPost].postName,
					link: 'http://www.brettkwarner.com' + thePosts[blogPost].postSlug,
					description: thePosts[blogPost].postBody,
					date: thePosts[blogPost].postDate
				});
			}
	      	//res.set('Content-Type', 'text/xml');
	      	res.set('Content-Type', 'application/rss+xml');
            // Sending the feed as a response
            res.send(feed.render('rss-2.0'));
        });
	});

	// Pulls a page based on the slug
	app.get('/:pageSlug', function(req, res){

		BlogPage.findOne({ pageSlug: req.params.pageSlug}, function(err, thePage){
			if(!thePage){
				console.log("the error" + err);
				res.send("Not found");
			}else{
				console.log(thePage);
				console.log(req.params.pageTitle);
				res.render("page", {title: thePage.pageName, body: thePage.pageBody});
			}
		});
	});

	// Pulls a post based on the slug.
	app.get('/blog/:postSlug', function(req,res){
		BlogPost.findOne({ postSlug: req.params.postSlug }, function(err, thePost){
			if(!thePost){
				console.log("The error"+ err);
				res.send('Not found');
			}else{
				console.log(thePost);
				console.log(req.params.postTitle);
				res.render("post", {title: thePost.postName, body: thePost.postBody});
			}
		});
	});
}
<|endoftext|>


<commit_before>/**
 * Import(s)
 */

var Nightmare = require('nightmare')
var expect = require('expect.js')
var resolve = require('./helper').resolve

/**
 * Test(s)
 */

describe('registration', function () {

  var expectOK = function (ret) {
    expect(ret).to.be.ok
  }
  var expectTextError = function (text) {
    expect(text).to.be.eql('(error)')
  }
  var expectTextSuccess = function (text) {
    expect(text).to.be.eql('(success)')
  }
  var getUsernameStatus = function () {
    return document.querySelector('#inputUsernameStatus').innerText
  }
  var getEmailStatus = function () {
    return document.querySelector('#inputEmailStatus').innerText
  }
  var getConfirmEmailStatus = function () {
    return document.querySelector('#inputConfirmEmailStatus').innerText
  }
  var getPasswordStatus = function () {
    return document.querySelector('#inputPasswordStatus').innerText
  }

  describe('first loaded page', function () {
    this.timeout(20000)

    it('should be invalid', function (done) {
      new Nightmare()
        .goto(resolve('./registration.html'))
        .exists('#username .has-error', expectOK)
        .exists('#inputUsernameIcon .glyphicon-remove', expectOK)
        .evaluate(getUsernameStatus, expectTextError)
        .exists('#email .has-error', expectOK)
        .exists('#inputEmailIcon .glyphicon-remove', expectOK)
        .evaluate(getEmailStatus, expectTextError)
        .exists('#confirmEmail .has-error', expectOK)
        .exists('#inputConfirmEmailIcon .glyphicon-remove', expectOK)
        .evaluate(getConfirmEmailStatus, expectTextError)
        .exists('#password .has-error', expectOK)
        .exists('#inputPassword .glyphicon-remove', expectOK)
        .evaluate(getPasswordStatus, expectTextError)
        .exists('button[type="submit"] .disabled', expectOK)
        .run(done)
    })
  })

  describe('input valid username', function () {
    this.timeout(20000)

    it('should be valid', function (done) {
      new Nightmare()
        .goto(resolve('./registration.html'))
        .type('#inputUsername', 'kazupon')
        .wait('#inputUsername')
        .exists('#username .has-success', expectOK) // success
        .exists('#inputUsernameIcon .glyphicon-ok', expectOK) // ok
        .evaluate(getUsernameStatus, expectTextSuccess) // success
        .exists('#email .has-error', expectOK)
        .exists('#inputEmailIcon .glyphicon-remove', expectOK)
        .evaluate(getEmailStatus, expectTextError)
        .exists('#confirmEmail .has-error', expectOK)
        .exists('#inputConfirmEmailIcon .glyphicon-remove', expectOK)
        .evaluate(getConfirmEmailStatus, expectTextError)
        .exists('#password .has-error', expectOK)
        .exists('#inputPassword .glyphicon-remove', expectOK)
        .evaluate(getPasswordStatus, expectTextError)
        .exists('button[type="submit"] .disabled', expectOK)
        .run(done)
    })
  })

  describe('input valid email', function () {
    this.timeout(20000)

    it('should be valid', function (done) {
      new Nightmare()
        .goto(resolve('./registration.html'))
        .type('#inputEmail', 'foo@domain.com')
        .wait('#inputEmail')
        .exists('#username .has-error', expectOK)
        .exists('#inputUsernameIcon .glyphicon-remove', expectOK)
        .evaluate(getUsernameStatus, expectTextError)
        .exists('#email .has-success', expectOK) // success
        .exists('#inputEmailIcon .glyphicon-ok', expectOK) // ok
        .evaluate(getEmailStatus, expectTextSuccess) // success
        .exists('#confirmEmail .has-error', expectOK)
        .exists('#inputConfirmEmailIcon .glyphicon-remove', expectOK)
        .evaluate(getConfirmEmailStatus, expectTextError)
        .exists('#password .has-error', expectOK)
        .exists('#inputPassword .glyphicon-remove', expectOK)
        .evaluate(getPasswordStatus, expectTextError)
        .exists('button[type="submit"] .disabled', expectOK)
        .run(done)
    })
  })

  describe('input valid confirm email', function () {
    this.timeout(20000)

    it('should be valid', function (done) {
      new Nightmare()
        .goto(resolve('./registration.html'))
        .type('#inputEmail', 'foo@domain.com')
        .wait('#inputEmail')
        .type('#inputConfirmEmail', 'foo@domain.com')
        .wait('#inputConfirmEmail')
        .exists('#username .has-error', expectOK)
        .exists('#inputUsernameIcon .glyphicon-remove', expectOK)
        .evaluate(getUsernameStatus, expectTextError)
        .exists('#email .has-success', expectOK) // success
        .exists('#inputEmailIcon .glyphicon-ok', expectOK) // ok
        .evaluate(getEmailStatus, expectTextSuccess) // success
        .exists('#confirmEmail .has-success', expectOK) // success
        .exists('#inputConfirmEmailIcon .glyphicon-ok', expectOK) // ok
        .evaluate(getConfirmEmailStatus, expectTextSuccess) // success
        .exists('#password .has-error', expectOK)
        .exists('#inputPassword .glyphicon-remove', expectOK)
        .evaluate(getPasswordStatus, expectTextError)
        .exists('button[type="submit"] .disabled', expectOK)
        .run(done)
    })
  })

  describe('input valid password', function () {
    this.timeout(20000)

    it('should be valid', function (done) {
      new Nightmare()
        .goto(resolve('./registration.html'))
        .type('#inputPassword', 'xxxxxxxxx')
        .wait('#inputPassword')
        .exists('#username .has-error', expectOK)
        .exists('#inputUsernameIcon .glyphicon-remove', expectOK)
        .evaluate(getUsernameStatus, expectTextError)
        .exists('#email .has-error', expectOK)
        .exists('#inputEmailIcon .glyphicon-remove', expectOK)
        .evaluate(getEmailStatus, expectTextError)
        .exists('#confirmEmail .has-error', expectOK)
        .exists('#inputConfirmEmailIcon .glyphicon-remove', expectOK)
        .evaluate(getConfirmEmailStatus, expectTextError)
        .exists('#password .has-success', expectOK) // success
        .exists('#inputPassword .glyphicon-ok', expectOK) // ok
        .evaluate(getPasswordStatus, expectTextSuccess) // success
        .exists('button[type="submit"] .disabled', expectOK)
        .run(done)
    })
  })

  describe('input valid fileds', function () {
    this.timeout(20000)

    it('join button should be enabled', function (done) {
      new Nightmare()
        .goto(resolve('./registration.html'))
        .type('#inputUsername', 'kazupon')
        .wait('#inputUsername')
        .type('#inputEmail', 'foo@domain.com')
        .wait('#inputEmail')
        .type('#inputConfirmEmail', 'foo@domain.com')
        .wait('#inputConfirmEmail')
        .type('#inputPassword', 'xxxxxxxxx')
        .wait('#inputPassword')
        .exists('#username .has-success', expectOK)
        .exists('#inputUsernameIcon .glyphicon-ok', expectOK)
        .evaluate(getUsernameStatus, expectTextSuccess)
        .exists('#email .has-success', expectOK)
        .exists('#inputEmailIcon .glyphicon-ok', expectOK)
        .evaluate(getEmailStatus, expectTextSuccess)
        .exists('#confirmEmail .has-success', expectOK)
        .exists('#inputConfirmEmailIcon .glyphicon-ok', expectOK)
        .evaluate(getConfirmEmailStatus, expectTextSuccess)
        .exists('#password .has-success', expectOK)
        .exists('#inputPassword .glyphicon-ok', expectOK)
        .evaluate(getPasswordStatus, expectTextSuccess)
        .exists('button[type="submit"]', expectOK) // enabled
        .run(done)
    })
  })
})
<commit_msg>Change assertion at e2e<commit_after>/**
 * Import(s)
 */

var Nightmare = require('nightmare')
var assert = require('power-assert')
var resolve = require('./helper').resolve

/**
 * Test(s)
 */

describe('registration', function () {

  var expectOK = function (ret) {
    assert(ret)
  }
  var expectTextError = function (text) {
    assert(text === '(error)')
  }
  var expectTextSuccess = function (text) {
    assert(text === '(success)')
  }
  var getUsernameStatus = function () {
    return document.querySelector('#inputUsernameStatus').innerText
  }
  var getEmailStatus = function () {
    return document.querySelector('#inputEmailStatus').innerText
  }
  var getConfirmEmailStatus = function () {
    return document.querySelector('#inputConfirmEmailStatus').innerText
  }
  var getPasswordStatus = function () {
    return document.querySelector('#inputPasswordStatus').innerText
  }

  describe('first loaded page', function () {
    this.timeout(20000)

    it('should be invalid', function (done) {
      new Nightmare()
        .goto(resolve('./registration.html'))
        .exists('#username .has-error', expectOK)
        .exists('#inputUsernameIcon .glyphicon-remove', expectOK)
        .evaluate(getUsernameStatus, expectTextError)
        .exists('#email .has-error', expectOK)
        .exists('#inputEmailIcon .glyphicon-remove', expectOK)
        .evaluate(getEmailStatus, expectTextError)
        .exists('#confirmEmail .has-error', expectOK)
        .exists('#inputConfirmEmailIcon .glyphicon-remove', expectOK)
        .evaluate(getConfirmEmailStatus, expectTextError)
        .exists('#password .has-error', expectOK)
        .exists('#inputPassword .glyphicon-remove', expectOK)
        .evaluate(getPasswordStatus, expectTextError)
        .exists('button[type="submit"] .disabled', expectOK)
        .run(done)
    })
  })

  describe('input valid username', function () {
    this.timeout(20000)

    it('should be valid', function (done) {
      new Nightmare()
        .goto(resolve('./registration.html'))
        .type('#inputUsername', 'kazupon')
        .wait('#inputUsername')
        .exists('#username .has-success', expectOK) // success
        .exists('#inputUsernameIcon .glyphicon-ok', expectOK) // ok
        .evaluate(getUsernameStatus, expectTextSuccess) // success
        .exists('#email .has-error', expectOK)
        .exists('#inputEmailIcon .glyphicon-remove', expectOK)
        .evaluate(getEmailStatus, expectTextError)
        .exists('#confirmEmail .has-error', expectOK)
        .exists('#inputConfirmEmailIcon .glyphicon-remove', expectOK)
        .evaluate(getConfirmEmailStatus, expectTextError)
        .exists('#password .has-error', expectOK)
        .exists('#inputPassword .glyphicon-remove', expectOK)
        .evaluate(getPasswordStatus, expectTextError)
        .exists('button[type="submit"] .disabled', expectOK)
        .run(done)
    })
  })

  describe('input valid email', function () {
    this.timeout(20000)

    it('should be valid', function (done) {
      new Nightmare()
        .goto(resolve('./registration.html'))
        .type('#inputEmail', 'foo@domain.com')
        .wait('#inputEmail')
        .exists('#username .has-error', expectOK)
        .exists('#inputUsernameIcon .glyphicon-remove', expectOK)
        .evaluate(getUsernameStatus, expectTextError)
        .exists('#email .has-success', expectOK) // success
        .exists('#inputEmailIcon .glyphicon-ok', expectOK) // ok
        .evaluate(getEmailStatus, expectTextSuccess) // success
        .exists('#confirmEmail .has-error', expectOK)
        .exists('#inputConfirmEmailIcon .glyphicon-remove', expectOK)
        .evaluate(getConfirmEmailStatus, expectTextError)
        .exists('#password .has-error', expectOK)
        .exists('#inputPassword .glyphicon-remove', expectOK)
        .evaluate(getPasswordStatus, expectTextError)
        .exists('button[type="submit"] .disabled', expectOK)
        .run(done)
    })
  })

  describe('input valid confirm email', function () {
    this.timeout(20000)

    it('should be valid', function (done) {
      new Nightmare()
        .goto(resolve('./registration.html'))
        .type('#inputEmail', 'foo@domain.com')
        .wait('#inputEmail')
        .type('#inputConfirmEmail', 'foo@domain.com')
        .wait('#inputConfirmEmail')
        .exists('#username .has-error', expectOK)
        .exists('#inputUsernameIcon .glyphicon-remove', expectOK)
        .evaluate(getUsernameStatus, expectTextError)
        .exists('#email .has-success', expectOK) // success
        .exists('#inputEmailIcon .glyphicon-ok', expectOK) // ok
        .evaluate(getEmailStatus, expectTextSuccess) // success
        .exists('#confirmEmail .has-success', expectOK) // success
        .exists('#inputConfirmEmailIcon .glyphicon-ok', expectOK) // ok
        .evaluate(getConfirmEmailStatus, expectTextSuccess) // success
        .exists('#password .has-error', expectOK)
        .exists('#inputPassword .glyphicon-remove', expectOK)
        .evaluate(getPasswordStatus, expectTextError)
        .exists('button[type="submit"] .disabled', expectOK)
        .run(done)
    })
  })

  describe('input valid password', function () {
    this.timeout(20000)

    it('should be valid', function (done) {
      new Nightmare()
        .goto(resolve('./registration.html'))
        .type('#inputPassword', 'xxxxxxxxx')
        .wait('#inputPassword')
        .exists('#username .has-error', expectOK)
        .exists('#inputUsernameIcon .glyphicon-remove', expectOK)
        .evaluate(getUsernameStatus, expectTextError)
        .exists('#email .has-error', expectOK)
        .exists('#inputEmailIcon .glyphicon-remove', expectOK)
        .evaluate(getEmailStatus, expectTextError)
        .exists('#confirmEmail .has-error', expectOK)
        .exists('#inputConfirmEmailIcon .glyphicon-remove', expectOK)
        .evaluate(getConfirmEmailStatus, expectTextError)
        .exists('#password .has-success', expectOK) // success
        .exists('#inputPassword .glyphicon-ok', expectOK) // ok
        .evaluate(getPasswordStatus, expectTextSuccess) // success
        .exists('button[type="submit"] .disabled', expectOK)
        .run(done)
    })
  })

  describe('input valid fileds', function () {
    this.timeout(20000)

    it('join button should be enabled', function (done) {
      new Nightmare()
        .goto(resolve('./registration.html'))
        .type('#inputUsername', 'kazupon')
        .wait('#inputUsername')
        .type('#inputEmail', 'foo@domain.com')
        .wait('#inputEmail')
        .type('#inputConfirmEmail', 'foo@domain.com')
        .wait('#inputConfirmEmail')
        .type('#inputPassword', 'xxxxxxxxx')
        .wait('#inputPassword')
        .exists('#username .has-success', expectOK)
        .exists('#inputUsernameIcon .glyphicon-ok', expectOK)
        .evaluate(getUsernameStatus, expectTextSuccess)
        .exists('#email .has-success', expectOK)
        .exists('#inputEmailIcon .glyphicon-ok', expectOK)
        .evaluate(getEmailStatus, expectTextSuccess)
        .exists('#confirmEmail .has-success', expectOK)
        .exists('#inputConfirmEmailIcon .glyphicon-ok', expectOK)
        .evaluate(getConfirmEmailStatus, expectTextSuccess)
        .exists('#password .has-success', expectOK)
        .exists('#inputPassword .glyphicon-ok', expectOK)
        .evaluate(getPasswordStatus, expectTextSuccess)
        .exists('button[type="submit"]', expectOK) // enabled
        .run(done)
    })
  })
})
<|endoftext|>


<commit_before>'use strict';

/**
 * Class Constructor
 */
function NetworkInterface() {

    this.defaultRouter = {
        connectedTo: [], gateway: '0.0.0.0', ip: '0.0.0.0', name: 'Router', netmask: '0.0.0.0',
        type: 'Router', forwarding: true
    };
    this.defaultPC = {
        connectedTo: [], gateway: '0.0.0.0', ip: '0.0.0.0', name: 'Ordinateur', netmask: '0.0.0.0',
        type: 'PC'
    };
    this.defaultSwitch = {
        connectedTo: [], gateway: '0.0.0.0', ip: '0.0.0.0', name: 'Switch', netmask: '0.0.0.0',
        type: 'Switch'
    };

    this.dataset = { nodes: undefined, links: undefined };
    this.currentElement = undefined;
    this.hoverElement = undefined;

    var container = $('#mainCanvas');

    this.width = container.width();
    this.height = container.height();

    container.empty();
    var th = this;

    this.svg = d3.select('#mainCanvas').append('svg')
        .attr('id', 'mainSvg')
        .attr('width', this.width)
        .attr('height', this.height)
        .on('drop', function (d) {
            var name = d3.event.dataTransfer.getData('name');
            th.add(name, d3.mouse(this)[0], d3.mouse(this)[1]);
        })
        .on('dragover', function () {
            d3.event.preventDefault();
        })
        .append('g');

    $('#mainSvg').attr('xmlns:svg', 'http://www.w3.org/2000/svg');
    $('#mainSvg').attr('xmlns:xlink', 'http://www.w3.org/1999/xlink');

    d3.json('data/nodes.json', function (error, json) {
        if (error) return console.warn(error);
        var nodes = json;
        d3.json('data/links.json', function (error, json) {
            if (error) return console.warn(error);
            var links = json;
            th.dataset.nodes = nodes;
            th.dataset.links = links;
            th.update();
        });
    });

    $('#svgToPng').attr('height', this.height);
    $('#svgToPng').attr('width', this.width);
}

/**
 * Resizes and adapts the svg object to the parent element
 */
NetworkInterface.prototype.resize = function() {
    var container = $('#mainCanvas');

    this.height = container.height();
    this.width = container.width();

    d3.select('#mainSvg').attr('height', this.height).attr('width', this.width);
    if(this.dataset.node == undefined && this.dataset.links) {
        this.update();
    }
};

/**
 * Converts the svg to a canvas and generates a png file
 */
NetworkInterface.prototype.downloadImage = function() {
    var html = d3.select('svg')
        .attr('version', 1.1)
        .attr('xmlns', 'http://www.w3.org/2000/svg')
        .node().parentNode.innerHTML;

    var imgsrc = 'data:image/svg+xml;base64,'+ btoa(html);
    var img = '';
    d3.select('#svgdataurl').html(img);

    var canvas = document.querySelector('canvas'),
        context = canvas.getContext('2d');
    context.clearRect(0, 0, canvas.width, canvas.height);

    var image = new Image;
    image.src = imgsrc;
    image.onload = function() {
        context.drawImage(image, 0, 0);

        var canvasdata = canvas.toDataURL('image/png');

        var pngimg = '';
        d3.select('#pngdataurl').html(pngimg);

        var a = document.createElement('a');
        // TODO add name of TP
        a.download = 'topologie.png';
        a.href = canvasdata;
        a.click();
    };

};

/**
 * Edit Settings of the currentElement
 * @param name The name
 * @param type The type (router, switch, pc)
 * @param ip The ip address (192.168.1.23)
 * @param netmask The network mask (255.255.255.255)
 * @param gateway The gatewax (192.168.1.1)
 * @param forwarding Enables IPv4 Forwarding (true, false)
 */
NetworkInterface.prototype.editSettings = function(name, type, ip, netmask, gateway, forwarding) {

    var oldType = this.currentElement.type;
    var oldName = this.currentElement.name;

    this.currentElement.name = name;
    this.currentElement.type = type;
    this.currentElement.ip = ip;
    this.currentElement.netmask = netmask;
    this.currentElement.gateway = gateway;
    this.currentElement.forwarding = forwarding;

    this.dataset.nodes[this.currentElement.count] = this.currentElement;

    if(oldType !== this.currentElement.type || oldName !== this.currentElement.name) {
        this.update();
    }
};

/**
 * Creates a new object
 * @param type (router, switch, pc)
 * @param x X - Position
 * @param y Y - Position
 */
NetworkInterface.prototype.add = function(type, x, y) {
    var newNode;

    switch (type) {
        case 'switch':
            newNode = jQuery.extend({}, this.defaultSwitch);
            break;
        case 'router':
            newNode = jQuery.extend({}, this.defaultRouter);
            break;
        default:
            newNode = jQuery.extend({}, this.defaultPC);
            break;
    }

    var l = this.dataset.nodes.length;
    newNode.code =  'Objet-' + l;
    newNode.count = l;

    if(x !== undefined && y !== undefined) {
        newNode.x = x;
        newNode.y = y;
        newNode.fixed = true;
    }

    var newLinks = {
        'source': l,
        'target': l
    };

    this.dataset.nodes.push(newNode);
    this.dataset.links.push(newLinks);

    this.update();
};

/**
 * Updates / Draws the svg with objects from dataset
 */
NetworkInterface.prototype.update = function() {
    var th = this;

    var line;
    var toggle = false;
    var startElement;

    var nodes = this.dataset.nodes;
    var links = this.dataset.links;

    this.svg.selectAll('*').remove();

    var defs = this.svg.append('defs');
    var filter = defs.append('filter')
        .attr('id', 'dropshadow')
        .attr('height', '130%');
    filter.append('feGaussianBlur')
        .attr('in', 'SourceAlpha')
        .attr('stdDeviation', 3);
    filter.append('feOffset')
        .attr('dx', 2)
        .attr('dy', 2)
        .attr('result', 'offsetblur');
    var feMerge = filter.append('feMerge');
    feMerge.append('feMergeNode');
    feMerge.append('feMergeNode')
        .attr('in', 'SourceGraphic');

    // Establish the dynamic force behavor of the nodes
    var force = self.force = d3.layout.force()
        .nodes(nodes)
        .links(links)
        .size([this.width, this.height])
        .linkDistance([250])
        .charge([-1500])
        .gravity(0.3)
        .on('tick', tick)
        .start();

    var node_drag = d3.behavior.drag()
        .on('dragstart', function() { force.stop(); })
        .on('dragend', function(d) {
            d.fixed = true;
            tick();
        })
        .on('drag', function(d) {
            vis.on('mouseup', null);

            if (d3.event.x >= th.width) {
                d.px = th.width;
                d.x = th.width;
            } else if (d3.event.x <= 0) {
                d.px =  0;
                d.x = 0;
            } else {
                d.px += d3.event.dx;
                d.x += d3.event.dx;
            }

            if (d3.event.y >= th.height) {
                d.py = th.height;
                d.y = th.height;
            } else if (d3.event.y <= 0) {
                d.py =  0;
                d.y = 0;
            } else {
                d.py += d3.event.dy;
                d.y += d3.event.dy;
            }

            tick();
        });

    var edges = this.svg.selectAll('line')
        .data(links)
        .enter()
        .append('line')
        .style('stroke', '#ccc')
        .style('stroke-width', 1);

    var elem = this.svg.selectAll('g')
        .data(nodes);

    var elemEnter = elem.enter()
        .append('g');

    var node = elemEnter
        .append('image')
        .attr('width', 50)
        .attr('height', 50)
        .attr('xlink:href',function(d) { return (window.images[d.type.toLowerCase()]); })
        .on('mousedown', function(d) {
            th.currentElement = th.dataset['nodes'][d.count];
            th.svg.selectAll('image').style('filter', '');
            d3.select(this).style('filter', 'url(#dropshadow)');
        })
        .on('click', function(d) {
            th.currentElement = th.dataset['nodes'][d.count];
            vis.on('mouseup', mouseup);
        })
        .on('mouseenter', function(d) {
            th.hoverElement = d;
        })
        .on('mouseleave', function() {
            th.hoverElement = null;
        })
        .on('contextmenu',function (d) {
            angular.element($('#settingsForm')).scope().updateSettings(d);
            angular.element($('#settingsForm')).scope().$apply();
            d3.event.preventDefault();
            d3.event.stopPropagation();
            window.toggleSidebar(true, 'settings');
        })
        .call(node_drag);

    var labels = elemEnter.append('text')
        .attr('dy', '40')
        .attr('fill', 'black')
        .attr('font-family', 'sans-serif')
        .attr('font-size', '14px')
        .attr('text-anchor', 'middle')
        .text(function(d) { return d.name; });

    function tick() {
        edges.attr('x1', function(d) { return d.source.x; })
             .attr('y1', function(d) { return d.source.y; })
             .attr('x2', function(d) { return d.target.x; })
             .attr('y2', function(d) { return d.target.y; });

        node.attr('x', function(d) { return d.x - 25; })
              .attr('y', function(d) { return d.y - 25; });

        labels.attr('transform', function(d) { return 'translate(' + d.x + ',' + d.y + ')'; });
    }

    var vis = d3.select('body').select('svg');

    vis.on('mouseup', mouseup);
    vis.on('contextmenu', function() {
        th.hoverElement = null;
        d3.event.preventDefault();
        window.toggleSidebar(true, 'components');
    });

    function mouseup() {
        // Only create a new edge if left mousebutton is pressed
        if(d3.event.button === 0) {
            var m = d3.mouse(this);
            line = vis.select('g').append('line')
                .attr('class', 'tempLine')
                .attr('x1', m[0])
                .attr('y1', m[1])
                .attr('x2', m[0])
                .attr('y2', m[1])
                .style('stroke', '#ccc')
                .style('stroke-width', 1);

            if (toggle) {
                toggle = false;
                vis.on('mousemove', null);
                if (th.hoverElement !== null && th.hoverElement !== undefined) {
                    line.attr('class', 'line');
                    var newLink = {
                        'source': startElement.count,
                        'target': th.hoverElement.count
                    };
                    var found = false;

                    for (var i = 0; i < th.dataset['links'].length; i++) {
                        if ((th.dataset['links'][i].source.count == newLink.source &&
                            th.dataset['links'][i].target.count == newLink.target) ||
                            (th.dataset['links'][i].target.count == newLink.source &&
                            th.dataset['links'][i].source.count == newLink.target)) {
                            found = true;
                            break;
                        }
                    }
                    if (!found) {
                        th.dataset['links'].push(newLink);
                        th.update();
                    } else {
                        vis.select('g').selectAll('.tempLine').remove();
                        $('.tempLine').remove();
                    }
                } else {
                    vis.select('g').selectAll('.tempLine').remove();
                    $('.tempLine').remove();
                }
            } else {
                if (th.hoverElement !== null) {
                    toggle = true;
                    startElement = th.hoverElement;
                    vis.on('mousemove', mousemove);
                } else {
                    window.toggleSidebar(false);
                }

            }
        }

    }

    function mousemove() {
        var m = d3.mouse(this);
        line.attr('x2', m[0]-1)
            .attr('y2', m[1]-1);
    }

};<commit_msg>Fixed naming mistake<commit_after>'use strict';

/**
 * Class Constructor
 */
function NetworkInterface() {

    this.defaultRouter = {
        connectedTo: [], gateway: '0.0.0.0', ip: '0.0.0.0', name: 'Router', netmask: '0.0.0.0',
        type: 'Router', forwarding: true
    };
    this.defaultPC = {
        connectedTo: [], gateway: '0.0.0.0', ip: '0.0.0.0', name: 'Ordinateur', netmask: '0.0.0.0',
        type: 'PC'
    };
    this.defaultSwitch = {
        connectedTo: [], gateway: '0.0.0.0', ip: '0.0.0.0', name: 'Switch', netmask: '0.0.0.0',
        type: 'Switch'
    };

    this.dataset = { nodes: undefined, links: undefined };
    this.currentElement = undefined;
    this.hoverElement = undefined;

    var container = $('#mainCanvas');

    this.width = container.width();
    this.height = container.height();

    container.empty();
    var th = this;

    this.svg = d3.select('#mainCanvas').append('svg')
        .attr('id', 'mainSvg')
        .attr('width', this.width)
        .attr('height', this.height)
        .on('drop', function (d) {
            var name = d3.event.dataTransfer.getData('name');
            th.add(name, d3.mouse(this)[0], d3.mouse(this)[1]);
        })
        .on('dragover', function () {
            d3.event.preventDefault();
        });
    this.g = this.svg.append('g');

    $('#mainSvg').attr('xmlns:svg', 'http://www.w3.org/2000/svg');
    $('#mainSvg').attr('xmlns:xlink', 'http://www.w3.org/1999/xlink');

    d3.json('data/nodes.json', function (error, json) {
        if (error) return console.warn(error);
        var nodes = json;
        d3.json('data/links.json', function (error, json) {
            if (error) return console.warn(error);
            var links = json;
            th.dataset.nodes = nodes;
            th.dataset.links = links;
            th.update();
        });
    });

    $('#svgToPng').attr('height', this.height);
    $('#svgToPng').attr('width', this.width);
}

/**
 * Resizes and adapts the svg object to the parent element
 */
NetworkInterface.prototype.resize = function() {
    var container = $('#mainCanvas');

    this.height = container.height();
    this.width = container.width();

    d3.select('#mainSvg').attr('height', this.height).attr('width', this.width);
    if(this.dataset.node == undefined && this.dataset.links) {
        this.update();
    }
};

/**
 * Converts the svg to a canvas and generates a png file
 */
NetworkInterface.prototype.downloadImage = function() {
    var html = d3.select('svg')
        .attr('version', 1.1)
        .attr('xmlns', 'http://www.w3.org/2000/svg')
        .node().parentNode.innerHTML;

    var imgsrc = 'data:image/svg+xml;base64,'+ btoa(html);
    var img = '';
    d3.select('#svgdataurl').html(img);

    var canvas = document.querySelector('canvas'),
        context = canvas.getContext('2d');
    context.clearRect(0, 0, canvas.width, canvas.height);

    var image = new Image;
    image.src = imgsrc;
    image.onload = function() {
        context.drawImage(image, 0, 0);

        var canvasdata = canvas.toDataURL('image/png');

        var pngimg = '';
        d3.select('#pngdataurl').html(pngimg);

        var a = document.createElement('a');
        // TODO add name of TP
        a.download = 'topologie.png';
        a.href = canvasdata;
        a.click();
    };

};

/**
 * Edit Settings of the currentElement
 * @param name The name
 * @param type The type (router, switch, pc)
 * @param ip The ip address (192.168.1.23)
 * @param netmask The network mask (255.255.255.255)
 * @param gateway The gatewax (192.168.1.1)
 * @param forwarding Enables IPv4 Forwarding (true, false)
 */
NetworkInterface.prototype.editSettings = function(name, type, ip, netmask, gateway, forwarding) {

    var oldType = this.currentElement.type;
    var oldName = this.currentElement.name;

    this.currentElement.name = name;
    this.currentElement.type = type;
    this.currentElement.ip = ip;
    this.currentElement.netmask = netmask;
    this.currentElement.gateway = gateway;
    this.currentElement.forwarding = forwarding;

    this.dataset.nodes[this.currentElement.count] = this.currentElement;

    if(oldType !== this.currentElement.type || oldName !== this.currentElement.name) {
        this.update();
    }
};

/**
 * Creates a new object
 * @param type (router, switch, pc)
 * @param x X - Position
 * @param y Y - Position
 */
NetworkInterface.prototype.add = function(type, x, y) {
    var newNode;

    switch (type) {
        case 'switch':
            newNode = jQuery.extend({}, this.defaultSwitch);
            break;
        case 'router':
            newNode = jQuery.extend({}, this.defaultRouter);
            break;
        default:
            newNode = jQuery.extend({}, this.defaultPC);
            break;
    }

    var l = this.dataset.nodes.length;
    newNode.code =  'Objet-' + l;
    newNode.count = l;

    if(x !== undefined && y !== undefined) {
        newNode.x = x;
        newNode.y = y;
        newNode.fixed = true;
    }

    var newLinks = {
        'source': l,
        'target': l
    };

    this.dataset.nodes.push(newNode);
    this.dataset.links.push(newLinks);

    this.update();
};

/**
 * Updates / Draws the svg with objects from dataset
 */
NetworkInterface.prototype.update = function() {
    var th = this;

    var line;
    var toggle = false;
    var startElement;

    var nodes = this.dataset.nodes;
    var links = this.dataset.links;

    this.g.selectAll('*').remove();

    var defs = this.g.append('defs');
    var filter = defs.append('filter')
        .attr('id', 'dropshadow')
        .attr('height', '130%');
    filter.append('feGaussianBlur')
        .attr('in', 'SourceAlpha')
        .attr('stdDeviation', 3);
    filter.append('feOffset')
        .attr('dx', 2)
        .attr('dy', 2)
        .attr('result', 'offsetblur');
    var feMerge = filter.append('feMerge');
    feMerge.append('feMergeNode');
    feMerge.append('feMergeNode')
        .attr('in', 'SourceGraphic');

    // Establish the dynamic force behavor of the nodes
    var force = self.force = d3.layout.force()
        .nodes(nodes)
        .links(links)
        .size([this.width, this.height])
        .linkDistance([250])
        .charge([-1500])
        .gravity(0.3)
        .on('tick', tick)
        .start();

    var node_drag = d3.behavior.drag()
        .on('dragstart', function() { force.stop(); })
        .on('dragend', function(d) {
            d.fixed = true;
            tick();
        })
        .on('drag', function(d) {
            th.svg.on('mouseup', null);

            if (d3.event.x >= th.width) {
                d.px = th.width;
                d.x = th.width;
            } else if (d3.event.x <= 0) {
                d.px =  0;
                d.x = 0;
            } else {
                d.px += d3.event.dx;
                d.x += d3.event.dx;
            }

            if (d3.event.y >= th.height) {
                d.py = th.height;
                d.y = th.height;
            } else if (d3.event.y <= 0) {
                d.py =  0;
                d.y = 0;
            } else {
                d.py += d3.event.dy;
                d.y += d3.event.dy;
            }

            tick();
        });

    var edges = this.g.selectAll('line')
        .data(links)
        .enter()
        .append('line')
        .style('stroke', '#ccc')
        .style('stroke-width', 1);

    var elem = this.g.selectAll('g')
        .data(nodes);

    var elemEnter = elem.enter()
        .append('g');

    var node = elemEnter
        .append('image')
        .attr('width', 50)
        .attr('height', 50)
        .attr('xlink:href',function(d) { return (window.images[d.type.toLowerCase()]); })
        .on('mousedown', function(d) {
            th.currentElement = th.dataset['nodes'][d.count];
            th.g.selectAll('image').style('filter', '');
            d3.select(this).style('filter', 'url(#dropshadow)');
        })
        .on('click', function(d) {
            th.currentElement = th.dataset['nodes'][d.count];
            th.svg.on('mouseup', mouseup);
        })
        .on('mouseenter', function(d) {
            th.hoverElement = d;
        })
        .on('mouseleave', function() {
            th.hoverElement = null;
        })
        .on('contextmenu',function (d) {
            angular.element($('#settingsForm')).scope().updateSettings(d);
            angular.element($('#settingsForm')).scope().$apply();
            d3.event.preventDefault();
            d3.event.stopPropagation();
            window.toggleSidebar(true, 'settings');
        })
        .call(node_drag);

    var labels = elemEnter.append('text')
        .attr('dy', '40')
        .attr('fill', 'black')
        .attr('font-family', 'sans-serif')
        .attr('font-size', '14px')
        .attr('text-anchor', 'middle')
        .text(function(d) { return d.name; });

    function tick() {
        edges.attr('x1', function(d) { return d.source.x; })
             .attr('y1', function(d) { return d.source.y; })
             .attr('x2', function(d) { return d.target.x; })
             .attr('y2', function(d) { return d.target.y; });

        node.attr('x', function(d) { return d.x - 25; })
              .attr('y', function(d) { return d.y - 25; });

        labels.attr('transform', function(d) { return 'translate(' + d.x + ',' + d.y + ')'; });
    }

    th.svg.on('mouseup', mouseup);
    th.svg.on('contextmenu', function() {
        th.hoverElement = null;
        d3.event.preventDefault();
        window.toggleSidebar(true, 'components');
    });

    function mouseup() {
        // Only create a new edge if left mousebutton is pressed
        if(d3.event.button === 0) {
            var m = d3.mouse(this);
            line = th.g.append('line')
                .attr('class', 'tempLine')
                .attr('x1', m[0])
                .attr('y1', m[1])
                .attr('x2', m[0])
                .attr('y2', m[1])
                .style('stroke', '#ccc')
                .style('stroke-width', 1);

            if (toggle) {
                toggle = false;
                th.svg.on('mousemove', null);
                if (th.hoverElement !== null && th.hoverElement !== undefined) {
                    line.attr('class', 'line');
                    var newLink = {
                        'source': startElement.count,
                        'target': th.hoverElement.count
                    };
                    var found = false;

                    for (var i = 0; i < th.dataset['links'].length; i++) {
                        if ((th.dataset['links'][i].source.count == newLink.source &&
                            th.dataset['links'][i].target.count == newLink.target) ||
                            (th.dataset['links'][i].target.count == newLink.source &&
                            th.dataset['links'][i].source.count == newLink.target)) {
                            found = true;
                            break;
                        }
                    }
                    if (!found) {
                        th.dataset['links'].push(newLink);
                        th.update();
                    } else {
                        th.g.selectAll('.tempLine').remove();
                        $('.tempLine').remove();
                    }
                } else {
                    th.g.selectAll('.tempLine').remove();
                    $('.tempLine').remove();
                }
            } else {
                if (th.hoverElement !== null) {
                    toggle = true;
                    startElement = th.hoverElement;
                    th.svg.on('mousemove', mousemove);
                } else {
                    window.toggleSidebar(false);
                }

            }
        }

    }

    function mousemove() {
        var m = d3.mouse(this);
        line.attr('x2', m[0]-1)
            .attr('y2', m[1]-1);
    }

};<|endoftext|>


<commit_before>"use strict";

var snippetUtils = require("./../snippet").utils;
var _            = require("lodash");
var utils        = require("./utils");
var foxy         = require("foxy");

/**
 * @param {BrowserSync} bs
 * @param {String} scripts
 * @returns {*}
 */
module.exports = function createProxyServer (bs, scripts) {

    var options = bs.options;

    checkProxyTarget(options, function (err) {
        if (err) {
            bs.events.emit("config:warn", {msg: err});
        }
    });

    var opts = getOptions(bs, scripts);

    var app = foxy(options.getIn(["proxy", "target"]), opts);

    return utils.getServer(app, bs.options);
};

/**
 * @param bs
 * @param scripts
 */
function getOptions (bs, scripts) {

    var options  = bs.options;

    var snippetOptions = options.get("snippetOptions").toJS();

    var out = {
        rules:       snippetUtils.getRegex(options.get("snippet"), options.get("snippetOptions")),
        whitelist:   snippetOptions.whitelist,
        blacklist:   snippetOptions.blacklist,
        middleware:  options.get("middleware").push(getPluginMiddleware(bs, scripts)),
        errHandler:  function (err) {
            bs.logger.debug("{red:[proxy error]} %s", err.message);
        }
    };

    if (options.getIn(["proxy", "reqHeaders"])) {
        out.reqHeaders = options.getIn(["proxy", "reqHeaders"]);
    }

    return out;
}

/**
 * Get proxy specific middleware
 * @param bs
 * @param scripts
 * @returns {*}
 */
function getPluginMiddleware (bs, scripts) {
    return bs.pluginManager.hook("server:middleware", snippetUtils.getProxyMiddleware(scripts, bs.options.getIn(["scriptPaths", "versioned"])));
}

/**
 * @param {Object} opts
 * @param {Function} cb
 */
function checkProxyTarget (opts, cb) {

    var chunks  = [];
    var errored = false;
    var target  = opts.getIn(["proxy", "target"]);
    var scheme  = opts.get("scheme");

    function logError() {
        if (!errored) {
            cb("Proxy address not reachable - is your server running?");
            errored = true;
        }
    }

    require(scheme).get(target, function (res) {
        res.on("data", function (data) {
            chunks.push(data);
        });
    }).on("error", function (err) {
        if (_.contains(["ENOTFOUND", "ECONNREFUSED"], err.code)) {
            logError();
        }
    }).on("close", function () {
        if (!chunks.length) {
            logError();
        }
    });
}
<commit_msg>Foxy cookies.stripDomain option configurable<commit_after>"use strict";

var snippetUtils = require("./../snippet").utils;
var _            = require("lodash");
var utils        = require("./utils");
var foxy         = require("foxy");

/**
 * @param {BrowserSync} bs
 * @param {String} scripts
 * @returns {*}
 */
module.exports = function createProxyServer (bs, scripts) {

    var options = bs.options;

    checkProxyTarget(options, function (err) {
        if (err) {
            bs.events.emit("config:warn", {msg: err});
        }
    });

    var opts = getOptions(bs, scripts);

    var app = foxy(options.getIn(["proxy", "target"]), opts);

    return utils.getServer(app, bs.options);
};

/**
 * @param bs
 * @param scripts
 */
function getOptions (bs, scripts) {

    var options  = bs.options;

    var snippetOptions = options.get("snippetOptions").toJS();

    var out = {
        rules:       snippetUtils.getRegex(options.get("snippet"), options.get("snippetOptions")),
        whitelist:   snippetOptions.whitelist,
        blacklist:   snippetOptions.blacklist,
        middleware:  options.get("middleware").push(getPluginMiddleware(bs, scripts)),
        errHandler:  function (err) {
            bs.logger.debug("{red:[proxy error]} %s", err.message);
        }
    };

    if (options.getIn(["proxy", "reqHeaders"])) {
        out.reqHeaders = options.getIn(["proxy", "reqHeaders"]);
    }

    if (options.getIn(["proxy", "cookies"])) {
        out.cookies = options.getIn(["proxy", "cookies"]);
    }

    return out;
}

/**
 * Get proxy specific middleware
 * @param bs
 * @param scripts
 * @returns {*}
 */
function getPluginMiddleware (bs, scripts) {
    return bs.pluginManager.hook("server:middleware", snippetUtils.getProxyMiddleware(scripts, bs.options.getIn(["scriptPaths", "versioned"])));
}

/**
 * @param {Object} opts
 * @param {Function} cb
 */
function checkProxyTarget (opts, cb) {

    var chunks  = [];
    var errored = false;
    var target  = opts.getIn(["proxy", "target"]);
    var scheme  = opts.get("scheme");

    function logError() {
        if (!errored) {
            cb("Proxy address not reachable - is your server running?");
            errored = true;
        }
    }

    require(scheme).get(target, function (res) {
        res.on("data", function (data) {
            chunks.push(data);
        });
    }).on("error", function (err) {
        if (_.contains(["ENOTFOUND", "ECONNREFUSED"], err.code)) {
            logError();
        }
    }).on("close", function () {
        if (!chunks.length) {
            logError();
        }
    });
}
<|endoftext|>


<commit_before>export const createApp = (state) => {
  let callingView = false
  let willCallView = false
  let view

  const callView = () => {
    if (willCallView) return

    willCallView = true

    Promise.resolve().then(() => {
      willCallView = false

      if (!callingView && view) {
        callingView = true

        view(get())

        callingView = false
      }
    })
  }

  const proxy = new Proxy(
    {},
    {
      set(_, key, val) {
        if (callingView) return false

        state[key] = val

        callView()

        return true
      },
      get(_, key) {
        return state[key]
      }
    }
  )

  const get = () => (typeof state === 'object' ? proxy : state)

  return {
    render(v) {
      view = v

      callView()
    },
    set state(val) {
      if (val !== proxy) {
        state = val
      }

      callView()
    },
    get state() {
      return get()
    }
  }
}
<commit_msg>Remove untested proxy support<commit_after>export const createApp = (state) => {
  let willCallView = false
  let view

  const callView = () => {
    if (willCallView) return

    willCallView = true

    Promise.resolve().then(() => {
      willCallView = false

      if (view) {
        view(state)
      }
    })
  }

  return {
    render(v) {
      view = v

      callView()
    },
    set state(val) {
      state = val

      callView()
    },
    get state() {
      return state
    }
  }
}
<|endoftext|>


<commit_before>var onDocumentLoad = function ( event ) {

	var name = /[A-z0-9]+.html/.exec( window.location.pathname ).toString().split( '.html' )[ 0 ];
	var path = /\/api\/[A-z0-9\/]+/.exec( window.location.pathname ).toString().substr( 5 );

	var text = document.body.innerHTML;

	text = text.replace(/\[name\]/gi, name);
	text = text.replace(/\[path\]/gi, path);
	text = text.replace(/\[page:(\w+)\]/gi, "[page:$1 $1]" ); // [page:name] to [page:name title]
	text = text.replace(/\[page:(\w+) ([\w|\.]+)\]/gi, "$2" ); // [page:name title]
	text = text.replace(/\[link:([\w|\:|\/|\.|\-|\_]+)\]/gi, "[link:$1 $1]" ); // [link:url] to [link:url title]
	text = text.replace(/\[link:([\w|\:|\/|\.|\-|\_]+) ([\w|\:|\/|\.|\-|\_]+)\]/gi, "$2" ); // [link:url title]
	text = text.replace(/\*([\w|\ |\-|\/|\+|\-|\(|\)|\=|\,|\.\"]+)\*/gi, "$1" ); // *

	document.body.innerHTML = text;

	// Edit button

	var button = document.createElement( 'div' );
	button.id = 'button';
	button.textContent = 'Edit this page';

	button.addEventListener( 'click', function ( event ) {

		window.open( 'https://github.com/mrdoob/three.js/blob/dev/docs/api/' + path + '.html' );

	}, false );

	document.body.appendChild( button );

};

document.addEventListener( 'DOMContentLoaded', onDocumentLoad, false );
<commit_msg>Fixed bug in docs regular expression.<commit_after>var onDocumentLoad = function ( event ) {

	var name = /[A-z0-9]+\.html/.exec( window.location.pathname ).toString().split( '.html' )[ 0 ];
	var path = /\/api\/[A-z0-9\/]+/.exec( window.location.pathname ).toString().substr( 5 );

	var text = document.body.innerHTML;

	text = text.replace(/\[name\]/gi, name);
	text = text.replace(/\[path\]/gi, path);
	text = text.replace(/\[page:(\w+)\]/gi, "[page:$1 $1]" ); // [page:name] to [page:name title]
	text = text.replace(/\[page:(\w+) ([\w|\.]+)\]/gi, "$2" ); // [page:name title]
	text = text.replace(/\[link:([\w|\:|\/|\.|\-|\_]+)\]/gi, "[link:$1 $1]" ); // [link:url] to [link:url title]
	text = text.replace(/\[link:([\w|\:|\/|\.|\-|\_]+) ([\w|\:|\/|\.|\-|\_]+)\]/gi, "$2" ); // [link:url title]
	text = text.replace(/\*([\w|\ |\-|\/|\+|\-|\(|\)|\=|\,|\.\"]+)\*/gi, "$1" ); // *

	document.body.innerHTML = text;

	// Edit button

	var button = document.createElement( 'div' );
	button.id = 'button';
	button.textContent = 'Edit this page';

	button.addEventListener( 'click', function ( event ) {

		window.open( 'https://github.com/mrdoob/three.js/blob/dev/docs/api/' + path + '.html' );

	}, false );

	document.body.appendChild( button );

};

document.addEventListener( 'DOMContentLoaded', onDocumentLoad, false );
<|endoftext|>


<commit_before>var Filer = require('../..');
var util = require('../lib/test-utils.js');
var expect = require('chai').expect;
var constants = require('../../src/constants.js');

describe('fs.open', function() {
  beforeEach(util.setup);
  afterEach(util.cleanup);

  it('should be a function', function() {
    var fs = util.fs();
    expect(fs.open).to.be.a('function');
  });

  it('should return an error if the parent path does not exist', function(done) {
    var fs = util.fs();

    fs.open('/tmp/myfile', 'w+', function(error, result) {
      expect(error).to.exist;
      expect(error.code).to.equal("ENOENT");
      expect(result).not.to.exist;
      done();
    });
  });

  it('should return an error when flagged for read and the path does not exist', function(done) {
    var fs = util.fs();

    fs.open('/myfile', 'r+', function(error, result) {
      expect(error).to.exist;
      expect(error.code).to.equal("ENOENT");
      expect(result).not.to.exist;
      done();
    });
  });

  it('should return an error when flagged for write and the path is a directory', function(done) {
    var fs = util.fs();

    fs.mkdir('/tmp', function(error) {
      if(error) throw error;
      fs.open('/tmp', 'w', function(error, result) {
        expect(error).to.exist;
        expect(error.code).to.equal("EISDIR");
        expect(result).not.to.exist;
        done();
      });
    });
  });

  it('should return an error when flagged for append and the path is a directory', function(done) {
    var fs = util.fs();

    fs.mkdir('/tmp', function(error) {
      if(error) throw error;
      fs.open('/tmp', 'a', function(error, result) {
        expect(error).to.exist;
        expect(error.code).to.equal("EISDIR");
        expect(result).not.to.exist;
        done();
      });
    });
  });

  it('should return a unique file descriptor', function(done) {
    var fs = util.fs();
    var fd1;

    fs.open('/file1', 'w+', function(error, fd) {
      if(error) throw error;
      expect(error).not.to.exist;
      expect(fd).to.be.a('number');

      fs.open('/file2', 'w+', function(error, fd) {
        if(error) throw error;
        expect(error).not.to.exist;
        expect(fd).to.be.a('number');
        expect(fd).not.to.equal(fd1);
        done();
      });
    });
  });

  it('should return the argument value of the file descriptor index matching the value set by the first useable file descriptor constant', function(done) {
    var fs = util.fs();
    var firstFD = constants.FIRST_DESCRIPTOR;
    var fd1;

    fs.open('/file1', 'w+', function(error, fd) {
      if(error) throw error;
      expect(fd).to.equal(firstFD);
      done();
    });
  });

  it('should create a new file when flagged for write', function(done) {
    var fs = util.fs();

    fs.open('/myfile', 'w', function(error, result) {
      if(error) throw error;
      fs.stat('/myfile', function(error, result) {
        expect(error).not.to.exist;
        expect(result).to.exist;
        expect(result.type).to.equal('FILE');
        done();
      });
    });
  });

  it('should error if an ofd\'s node goes away while open', function(done) {
    var fs = util.fs();

    fs.writeFile('/myfile', 'data', function(error) {
      if(error) throw error;

      fs.open('/myfile', 'r', function(error, fd) {
        if(error) throw error;

        // Delete the file while it's still open
        fs.unlink('/myfile', function(error) {
          if(error) throw error;

          // This should fail now, since fd points to a bad node
          fs.fstat(fd, function(error, result) {
            expect(error).to.exist;
            expect(error.code).to.equal('EBADF');
            expect(result).not.to.exist;

            fs.close(fd);
            done();
          });
        });
      });
    });
  });
});
<commit_msg>Add note about https://github.com/filerjs/filer/issues/314<commit_after>var Filer = require('../..');
var util = require('../lib/test-utils.js');
var expect = require('chai').expect;
var constants = require('../../src/constants.js');

describe('fs.open', function() {
  beforeEach(util.setup);
  afterEach(util.cleanup);

  it('should be a function', function() {
    var fs = util.fs();
    expect(fs.open).to.be.a('function');
  });

  it('should return an error if the parent path does not exist', function(done) {
    var fs = util.fs();

    fs.open('/tmp/myfile', 'w+', function(error, result) {
      expect(error).to.exist;
      expect(error.code).to.equal("ENOENT");
      expect(result).not.to.exist;
      done();
    });
  });

  it('should return an error when flagged for read and the path does not exist', function(done) {
    var fs = util.fs();

    fs.open('/myfile', 'r+', function(error, result) {
      expect(error).to.exist;
      expect(error.code).to.equal("ENOENT");
      expect(result).not.to.exist;
      done();
    });
  });

  it('should return an error when flagged for write and the path is a directory', function(done) {
    var fs = util.fs();

    fs.mkdir('/tmp', function(error) {
      if(error) throw error;
      fs.open('/tmp', 'w', function(error, result) {
        expect(error).to.exist;
        expect(error.code).to.equal("EISDIR");
        expect(result).not.to.exist;
        done();
      });
    });
  });

  it('should return an error when flagged for append and the path is a directory', function(done) {
    var fs = util.fs();

    fs.mkdir('/tmp', function(error) {
      if(error) throw error;
      fs.open('/tmp', 'a', function(error, result) {
        expect(error).to.exist;
        expect(error.code).to.equal("EISDIR");
        expect(result).not.to.exist;
        done();
      });
    });
  });

  it('should return a unique file descriptor', function(done) {
    var fs = util.fs();
    var fd1;

    fs.open('/file1', 'w+', function(error, fd) {
      if(error) throw error;
      expect(error).not.to.exist;
      expect(fd).to.be.a('number');

      fs.open('/file2', 'w+', function(error, fd) {
        if(error) throw error;
        expect(error).not.to.exist;
        expect(fd).to.be.a('number');
        expect(fd).not.to.equal(fd1);
        done();
      });
    });
  });

  it('should return the argument value of the file descriptor index matching the value set by the first useable file descriptor constant', function(done) {
    var fs = util.fs();
    var firstFD = constants.FIRST_DESCRIPTOR;
    var fd1;

    fs.open('/file1', 'w+', function(error, fd) {
      if(error) throw error;
      expect(fd).to.equal(firstFD);
      done();
    });
  });

  it('should create a new file when flagged for write', function(done) {
    var fs = util.fs();

    fs.open('/myfile', 'w', function(error, result) {
      if(error) throw error;
      fs.stat('/myfile', function(error, result) {
        expect(error).not.to.exist;
        expect(result).to.exist;
        expect(result.type).to.equal('FILE');
        done();
      });
    });
  });

  /**
   * This test is currently correct per our code, but incorrect according to the spec.
   * When we fix https://github.com/filerjs/filer/issues/314 we'll have to update this.
   */
  it('should error if an ofd\'s node goes away while open', function(done) {
    var fs = util.fs();

    fs.writeFile('/myfile', 'data', function(error) {
      if(error) throw error;

      fs.open('/myfile', 'r', function(error, fd) {
        if(error) throw error;

        // Delete the file while it's still open
        fs.unlink('/myfile', function(error) {
          if(error) throw error;

          // This should fail now, since fd points to a bad node
          fs.fstat(fd, function(error, result) {
            expect(error).to.exist;
            expect(error.code).to.equal('EBADF');
            expect(result).not.to.exist;

            fs.close(fd);
            done();
          });
        });
      });
    });
  });
});
<|endoftext|>


<commit_before>const env = require('./test-environment')
const db = require('../../../server/db/db')

let testDb = null

beforeEach(() => {
  testDb = env.getTestDb()
  return env.initialise(testDb)
})

afterEach(() => env.cleanup(testDb))

test('getUser gets users id', () => {
  return db.getUserById(2, testDb)
    .then(user => {
      expect(user.id).toBe(2)
    })
})

test('getSprint gets sprint number', () => {
  return db.getSprintById(1, testDb)
    .then(sprint => {
      expect(sprint.number).toBe(0)
    })
})

test('getAssignmentsBySprintId returns correct assignment', () => {
  return db.getAssignmentsBySprintId(1, testDb)
    .then(assignment => {
      expect(assignment[0].title).toBe('kimmis cookies')
    })
})

test('getTasksByAssignmentId returns correct task', () => {
  return db.getTasksByAssignmentId(3, testDb)
    .then(task => {
      expect(task[0].description).toBe('smiles')
    })
})

test('getAssignedTasks returns a boolean for complete', () => {
  return db.getAssignedTasks(1, 1, testDb)
    .then(assignedtask => {
      expect(assignedtask[0].user_id).toBe(1)
    })
})
<commit_msg>edited test file<commit_after>const env = require('./test-environment')
const db = require('../../../server/db/db')

let testDb = null

beforeEach(() => {
  testDb = env.getTestDb()
  return env.initialise(testDb)
})

afterEach(() => env.cleanup(testDb))

test('getUser gets users id', () => {
  return db.getUserById(2, testDb)
    .then(user => {
      expect(user.id).toBe(2)
    })
})

test('getSprint gets sprint number', () => {
  return db.getSprintById(1, testDb)
    .then(sprint => {
      expect(sprint.number).toBe(0)
    })
})

test('getAssignmentsBySprintId returns correct assignment', () => {
  return db.getAssignmentsBySprintId(1, testDb)
    .then(assignment => {
      expect(assignment[0].title).toBe('Assignment 1')
    })
})

test('getTasksByAssignmentId returns correct task', () => {
  return db.getTasksByAssignmentId(3, testDb)
    .then(task => {
      expect(task[0].description).toBe('Start Toggle')
    })
})

test('getAssignedTasks returns a boolean for complete', () => {
  return db.getAssignedTasks(1, 1, testDb)
    .then(assignedtask => {
      expect(assignedtask[0].user_id).toBe(1)
    })
})
<|endoftext|>


<commit_before>import React, { Component } from 'react'
import t from 't-component'
import shuffle from 'lodash.shuffle'
import { SortableContainer, SortableElement, arrayMove } from 'react-sortable-hoc'
import userConnector from 'lib/site/connectors/user'
import topicStore from 'lib/stores/topic-store/topic-store'
import ChangeVote from '../change-vote-button/component'
import CantComment from '../cant-comment/component'
import Required from '../required/component'

class Hierarchy extends Component {
  constructor (props) {
    super(props)
    this.prepareState(this.props)
    this.handleVote = this.handleVote.bind(this)
  }

  componentWillReceiveProps (props) {
    this.prepareState(props)
  }

  prepareState (props) {
    const items = props.topic.action.results.map((item) => item.value)
    this.state = {
      value: props.topic.voted,
      voted: props.topic.voted,
      changingVote: false,
      items: props.topic.voted ? items : shuffle(items)
    }
  }

  handleVote (e) {
    if (!this.props.user.state.fulfilled) return
    const { items } = this.state
    topicStore
      .vote(this.props.topic.id, items.toString())
      .then(() => {
        this.setState({
          voted: true,
          changingVote: false
        })
      })
      .catch((err) => {
        console.warn('Error on vote setState', err)
        this.setState({
          voted: false
        })
      })
  }

  changeVote = () => {
    this.setState({
      changingVote: true
    })
  }

  onSortEnd = ({ oldIndex, newIndex }) => {
    if (oldIndex !== newIndex) {
      const { items } = this.state

      this.setState({
        items: arrayMove(items, oldIndex, newIndex)
      })
    }
  }

  render () {
    const { value, changingVote, items } = this.state
    const { topic, user } = this.props

    const votesTotal = topic.action.count

    const showResults = topic.closed
    const showVoteBox = (user.state.fulfilled && (!showResults && !topic.voted)) || changingVote
    const showChangeVote = (!topic.closed && topic.voted) && !changingVote
    const cantComment = user.state.fulfilled && !topic.privileges.canVote
    const isRequired = !user.state.fulfilled && !showResults

    return (

        {showVoteBox &&

          {t('proposal-behavior.hierarchy')}

        }
        {
          showResults &&

            {t('proposal-behavior.hierarchy.result')}

        }

        { showVoteBox &&

              <SortableList
                helperClass='sortable-li-focus'
                items={items}
                onSortEnd={this.onSortEnd} />

          <VoteBox onVote={this.handleVote} />

        }
        {
          showChangeVote &&

                <VotedBox votes={value.split(',')} />
                <ChangeVote handleClick={this.changeVote} />

        }
        {
          showResults &&
            <ResultBox
              votesTotals={votesTotal}
              results={topic.action.results}
              voted={topic.voted} />

        }
        {
          isRequired &&
            <Required />
        }
        {
          cantComment &&
          <CantComment />
        }

    )
  }
}

const SortableList = SortableContainer(({ items }) => {
  return (

      {items.map((value, index) => (
        <SortableItem key={`item-${index}`} index={index} value={value} />
      ))}

  )
})

const SortableItem = SortableElement(({ value }) =>

    {value}

)

function VotedBox ({ votes }) {
  return (

        {t('topics.actions.thanks')}
        {t('topics.actions.feedback')}

{t('topics.actions.answer')}

        {votes.map((vote, index) => {
          return (
            <li key={`voted-${index}`} className='voted-li'>
              { vote }

          )
        })}

  )
}

function VoteBox ({ onVote }) {
  return (

          <button
            className='btn btn-primary'
            onClick={onVote}>
            {t('topics.actions.poll.do')}
          </button>

  )
}

class ResultBox extends Component {
  state = {
    showAnswer: false
  }

  updateShowAnswer = () => {
    this.setState((prevState) => {
      return {
        showAnswer: !prevState.showAnswer
      }
    })
  }

  render () {
    const { votesTotals, results, voted } = this.props
    const noVoted = votesTotals === 0
    if (noVoted) {
      return (

            {t('proposal-options.no-votes-cast')}

      )
    }

    if (!noVoted && !this.state.showAnswer) {
      return (

          { voted &&
            <button
              className='btn btn-link btn-answer'
              onClick={this.updateShowAnswer}>{t('proposal-behavior.hierarchy.show.answer')}</button>
          }

            {results.map((vote, index) => {
              return (
                <li key={`item-${index}`} className='result-voted-li'>
                  { vote.value }
                  { vote.porcentage }

              )
            })}

      )
    }

    if (!noVoted && this.state.showAnswer) {
      return (

          <button
            className='btn btn-link btn-answer'
            onClick={this.updateShowAnswer}>{t('proposal-behavior.hierarchy.show.results')}</button>

{t('topics.actions.answer')}

            {voted && voted.split(',').map((vote, i) => (
              <li key={`voted-${i}`} className='answer-li'>
                { vote }

            ))}

      )
    }
  }
}

export default userConnector(Hierarchy)
<commit_msg>Fix conditional rendering in hierarchy component<commit_after>import React, { Component } from 'react'
import t from 't-component'
import shuffle from 'lodash.shuffle'
import { SortableContainer, SortableElement, arrayMove } from 'react-sortable-hoc'
import userConnector from 'lib/site/connectors/user'
import topicStore from 'lib/stores/topic-store/topic-store'
import ChangeVote from '../change-vote-button/component'
import CantComment from '../cant-comment/component'
import Required from '../required/component'

class Hierarchy extends Component {
  constructor (props) {
    super(props)
    this.prepareState(this.props)
    this.handleVote = this.handleVote.bind(this)
  }

  componentWillReceiveProps (props) {
    this.prepareState(props)
  }

  prepareState (props) {
    const items = props.topic.action.results.map((item) => item.value)
    this.state = {
      value: props.topic.voted,
      voted: props.topic.voted,
      changingVote: false,
      items: props.topic.voted ? items : shuffle(items)
    }
  }

  handleVote (e) {
    if (!this.props.user.state.fulfilled) return
    const { items } = this.state
    topicStore
      .vote(this.props.topic.id, items.toString())
      .then(() => {
        this.setState({
          voted: true,
          changingVote: false
        })
      })
      .catch((err) => {
        console.warn('Error on vote setState', err)
        this.setState({
          voted: false
        })
      })
  }

  changeVote = () => {
    this.setState({
      changingVote: true
    })
  }

  onSortEnd = ({ oldIndex, newIndex }) => {
    if (oldIndex !== newIndex) {
      const { items } = this.state

      this.setState({
        items: arrayMove(items, oldIndex, newIndex)
      })
    }
  }

  render () {
    const { value, changingVote, items } = this.state
    const { topic, user } = this.props

    const votesTotal = topic.action.count

    const showResults = topic.closed
    const showVoteBox = (user.state.fulfilled && (!showResults && !topic.voted)) || changingVote
    const showChangeVote = (!topic.closed && topic.voted) && !changingVote
    const cantComment = user.state.fulfilled && !topic.privileges.canVote
    const isRequired = !user.state.fulfilled && !showResults

    return (

        {showVoteBox &&

          {t('proposal-behavior.hierarchy')}

        }
        {
          showResults &&

            {t('proposal-behavior.hierarchy.result')}

        }

        { showVoteBox &&

              <SortableList
                helperClass='sortable-li-focus'
                items={items}
                onSortEnd={this.onSortEnd} />

          <VoteBox onVote={this.handleVote} />

        }
        {
          showChangeVote &&

                <VotedBox votes={value.split(',')} />
                <ChangeVote handleClick={this.changeVote} />

        }
        {
          showResults &&
            <ResultBox
              votesTotals={votesTotal}
              results={topic.action.results}
              voted={topic.voted} />

        }
        {
          isRequired &&
            <Required />
        }
        {
          cantComment &&
          <CantComment />
        }

    )
  }
}

const SortableList = SortableContainer(({ items }) => {
  return (

      {items.map((value, index) => (
        <SortableItem key={`item-${index}`} index={index} value={value} />
      ))}

  )
})

const SortableItem = SortableElement(({ value }) =>

    {value}

)

function VotedBox ({ votes }) {
  return (

        {t('topics.actions.thanks')}
        {t('topics.actions.feedback')}

{t('topics.actions.answer')}

        {votes.map((vote, index) => {
          return (
            <li key={`voted-${index}`} className='voted-li'>
              { vote }

          )
        })}

  )
}

function VoteBox ({ onVote }) {
  return (

          <button
            className='btn btn-primary'
            onClick={onVote}>
            {t('topics.actions.poll.do')}
          </button>

  )
}

class ResultBox extends Component {
  state = {
    showAnswer: false
  }

  updateShowAnswer = () => {
    this.setState((prevState) => {
      return {
        showAnswer: !prevState.showAnswer
      }
    })
  }

  render () {
    const { votesTotals, results, voted } = this.props
    const noVoted = votesTotals === 0
    if (noVoted) {
      return (

            {t('proposal-options.no-votes-cast')}

      )
    } else {
      if (this.state.showAnswer) {
        return (

            <button
              className='btn btn-link btn-answer'
              onClick={this.updateShowAnswer}>{t('proposal-behavior.hierarchy.show.results')}</button>

{t('topics.actions.answer')}

              {voted && voted.split(',').map((vote, i) => (
                <li key={`voted-${i}`} className='answer-li'>
                  { vote }

              ))}

        )
      } else {
        return (

            { voted &&
              <button
                className='btn btn-link btn-answer'
                onClick={this.updateShowAnswer}>{t('proposal-behavior.hierarchy.show.answer')}</button>
            }

              {results.map((vote, index) => {
                return (
                  <li key={`item-${index}`} className='result-voted-li'>
                    { vote.value }
                    { vote.porcentage }

                )
              })}

        )
      }
    }
  }
}

export default userConnector(Hierarchy)
<|endoftext|>