<commit_before>const { get } = require('lodash')

const metadata = require('../../../lib/metadata')
const { isValidGuid } = require('../../../lib/controller-utils')
const { getDitCompany } = require('../../companies/repos')
const { getAdviser } = require('../../adviser/repos')
const { getInvestment } = require('../repos')

function getNextStage (currentStage, projectStages) {
  const projectStageIndex = projectStages.findIndex((projectStage) => {
    return projectStage.name.toLowerCase() === currentStage.toLowerCase()
  })
  return projectStages[projectStageIndex + 1]
}

function getCompanyDetails (req, res, next) {
  getDitCompany(req.session.token, req.params.companyId)
    .then((company) => {
      res.locals.company = company
      return next()
    })
    .catch(next)
}

async function getInvestmentDetails (req, res, next, investmentId = req.params.investmentId) {
  if (!isValidGuid(investmentId)) {
    return next()
  }
  try {
    const investmentProjectStages = metadata.investmentProjectStage
    const investmentData = await getInvestment(req.session.token, investmentId)
    const investorCompany = await getDitCompany(req.session.token, get(investmentData, 'investor_company.id'))
    const ukCompanyId = get(investmentData, 'uk_company.id')

    investmentData.investor_company = Object.assign({}, investmentData.investor_company, investorCompany)

    if (ukCompanyId) {
      const companyDetails = await getDitCompany(req.session.token, ukCompanyId)
      investmentData.uk_company = Object.assign({}, investmentData.uk_company, companyDetails)
    }

    const clientRelationshipManager = await getAdviser(req.session.token, investmentData.client_relationship_manager.id)
    investmentData.client_relationship_manager = clientRelationshipManager

    res.locals.investmentData = investmentData
    res.locals.equityCompany = investmentData.investor_company
    res.locals.investmentProjectStages = investmentProjectStages.map((stage) => stage.name)

    res.locals.investmentStatus = {
      id: investmentData.id,
      meta: [
        {
          label: 'Project code',
          value: investmentData.project_code,
        },
        {
          label: 'Valuation',
          value: investmentData.value_complete ? 'Project valued' : 'Not yet valued',
        },
      ],
      company: {
        name: investmentData.investor_company.name,
        url: `/companies/${investmentData.investor_company.id}`,
      },
      currentStage: {
        name: investmentData.stage.name,
        isComplete: investmentData.team_complete && investmentData.requirements_complete && investmentData.value_complete,
      },
      nextStage: getNextStage(investmentData.stage.name, investmentProjectStages),
    }

    res.breadcrumb({
      name: investmentData.name,
      url: `/investment-projects/${investmentData.id}`,
    })

    next()
  } catch (error) {
    next(error)
  }
}

module.exports = {
  getCompanyDetails,
  getInvestmentDetails,
}
<commit_msg>fixup! Use investmentId as parameter name instead of id<commit_after>const { get } = require('lodash')

const metadata = require('../../../lib/metadata')
const { isValidGuid } = require('../../../lib/controller-utils')
const { getDitCompany } = require('../../companies/repos')
const { getAdviser } = require('../../adviser/repos')
const { getInvestment } = require('../repos')

function getNextStage (currentStage, projectStages) {
  const projectStageIndex = projectStages.findIndex((projectStage) => {
    return projectStage.name.toLowerCase() === currentStage.toLowerCase()
  })
  return projectStages[projectStageIndex + 1]
}

function getCompanyDetails (req, res, next) {
  getDitCompany(req.session.token, req.params.companyId)
    .then((company) => {
      res.locals.company = company
      return next()
    })
    .catch(next)
}

async function getInvestmentDetails (req, res, next) {
  const investmentId = req.params.investmentId

  if (!isValidGuid(investmentId)) {
    return next()
  }
  try {
    const investmentProjectStages = metadata.investmentProjectStage
    const investmentData = await getInvestment(req.session.token, investmentId)
    const investorCompany = await getDitCompany(req.session.token, get(investmentData, 'investor_company.id'))
    const ukCompanyId = get(investmentData, 'uk_company.id')

    investmentData.investor_company = Object.assign({}, investmentData.investor_company, investorCompany)

    if (ukCompanyId) {
      const companyDetails = await getDitCompany(req.session.token, ukCompanyId)
      investmentData.uk_company = Object.assign({}, investmentData.uk_company, companyDetails)
    }

    const clientRelationshipManager = await getAdviser(req.session.token, investmentData.client_relationship_manager.id)
    investmentData.client_relationship_manager = clientRelationshipManager

    res.locals.investmentData = investmentData
    res.locals.equityCompany = investmentData.investor_company
    res.locals.investmentProjectStages = investmentProjectStages.map((stage) => stage.name)

    res.locals.investmentStatus = {
      id: investmentData.id,
      meta: [
        {
          label: 'Project code',
          value: investmentData.project_code,
        },
        {
          label: 'Valuation',
          value: investmentData.value_complete ? 'Project valued' : 'Not yet valued',
        },
      ],
      company: {
        name: investmentData.investor_company.name,
        url: `/companies/${investmentData.investor_company.id}`,
      },
      currentStage: {
        name: investmentData.stage.name,
        isComplete: investmentData.team_complete && investmentData.requirements_complete && investmentData.value_complete,
      },
      nextStage: getNextStage(investmentData.stage.name, investmentProjectStages),
    }

    res.breadcrumb({
      name: investmentData.name,
      url: `/investment-projects/${investmentData.id}`,
    })

    next()
  } catch (error) {
    next(error)
  }
}

module.exports = {
  getCompanyDetails,
  getInvestmentDetails,
}
<|endoftext|>


<commit_before>'use strict';

var inherits = require('util').inherits,
	Steppy = require('twostep').Steppy,
	_ = require('underscore'),
	https = require('https');

exports.register = function(app) {
	var ParentTransport = app.lib.notifier.BaseNotifierTransport,
		logger = app.lib.logger('telegram notifier'),
		emojiHash = {
			done: '\u2705',
			error: '\ufe0f\u26d4\ufe0f',
			canceled: '\u26a0'
		};

	function Transport() {
		ParentTransport.call(this);
	}

	inherits(Transport, ParentTransport);

	Transport.prototype.init = function(params, callback) {
		this.token = params.token;
		callback();
	};

	Transport.prototype._sendMessage = function(params, callback) {
		callback = _.once(callback);

		var req = https.request({
			host: 'api.telegram.org',
			path: '/bot' + this.token + '/sendMessage',
			headers: {'Content-Type': 'application/json'},
			method: 'POST'
		}, function(res) {
			logger.log('response status code %d', res.statusCode);

			var chunks = [];
			res.on('data', function(chunk) {
				chunks.push(chunk);
			});
			res.on('end', function() {
				logger.log('response %s', Buffer.concat(chunks).toString());
				callback();
			});
		});

		req.on('error', callback);

		req.end(JSON.stringify({
			chat_id: params.recipient,
			text: params.message,
			parse_mode: 'Markdown',
			disable_web_page_preview: true
		}));
	};

	Transport.prototype._messageTemplate = _(
		'<%= build.project.name %> build [#<%= build.number %>](<%= baseUrl %>/builds/<%= build.id %>) ' +
		'initiated by <%= build.initiator.type %> is *<%= build.status %>* ' +
		'<%= emoji %>\n\n' +
		'<% if (changes.length) { %>' +
			'scm changes:\n' +
			'<% _(changes).chain().first(20).each(function(change, index) { %>' +
				'<%= change.author %>: `<%= change.comment %>`\n' +
			'<% }); %>' +
			'<% if (changes.length > 20) { %>' +
				'...\n' +
			'<% } %>' +
		'<% } else { %>' +
			'no scm changes\n' +
		'<% } %>' +
		'\n' +
		'<% if (build.status === \'error\') { %>' +
			'failed at *<%= build.currentStep%>*' +
		'<% } %>'
	).template();

	Transport.prototype.send = function(params, callback) {
		var self = this,
			build = params.build,
			changes = build.scm.changes,
			recipients = build.project.notify.to.telegram;

		if (_(recipients).isEmpty()) {
			logger.log('no recipients, quit');
			return callback();
		}

		Steppy(
			function() {
				logger.log('send message to %s', recipients);

				var message = self._messageTemplate({
					build: build,
					baseUrl: app.config.http.url,
					changes: changes,
					emoji: emojiHash[build.status] || ''
				});

				var group = this.makeGroup();
				_(recipients).each(function(recipient) {
					self._sendMessage({
						recipient: recipient,
						message: message
					}, group.slot());
				});
			},
			callback
		);
	};

	app.lib.notifier.register('telegram', Transport);
};
<commit_msg>use HTML parse_mode to prevent telegram parsing error<commit_after>'use strict';

var inherits = require('util').inherits,
	Steppy = require('twostep').Steppy,
	_ = require('underscore'),
	https = require('https');

exports.register = function(app) {
	var ParentTransport = app.lib.notifier.BaseNotifierTransport,
		logger = app.lib.logger('telegram notifier'),
		emojiHash = {
			done: '\u2705',
			error: '\ufe0f\u26d4\ufe0f',
			canceled: '\u26a0'
		};

	function Transport() {
		ParentTransport.call(this);
	}

	inherits(Transport, ParentTransport);

	Transport.prototype.init = function(params, callback) {
		this.token = params.token;
		callback();
	};

	Transport.prototype._sendMessage = function(params, callback) {
		callback = _.once(callback);

		var req = https.request({
			host: 'api.telegram.org',
			path: '/bot' + this.token + '/sendMessage',
			headers: {'Content-Type': 'application/json'},
			method: 'POST'
		}, function(res) {
			logger.log('response status code %d', res.statusCode);

			var chunks = [];
			res.on('data', function(chunk) {
				chunks.push(chunk);
			});
			res.on('end', function() {
				logger.log('response %s', Buffer.concat(chunks).toString());
				callback();
			});
		});

		req.on('error', callback);

		req.end(JSON.stringify({
			chat_id: params.recipient,
			text: params.message,
			parse_mode: 'HTML',
			disable_web_page_preview: true
		}));
	};

	Transport.prototype._messageTemplate = _(
		'<%- build.project.name %> build ' +
		'<a href="<%- baseUrl %>/builds/<%- build.id %>">[#<%- build.number %>] ' +
		'initiated by <%- build.initiator.type %> is <%- build.status %> ' +
		'<%- emoji %>\n\n' +
		'<% if (changes.length) { %>' +
			'scm changes:\n' +
			'<% _(changes).chain().first(20).each(function(change, index) { %>' +
				'\u2219 <%- change.author %>: <%- change.comment %>\n' +
			'<% }); %>' +
			'<% if (changes.length > 20) { %>' +
				'...\n' +
			'<% } %>' +
		'<% } else { %>' +
			'no scm changes\n' +
		'<% } %>' +
		'\n' +
		'<% if (build.status === \'error\') { %>' +
			'failed at <%- build.currentStep %>' +
		'<% } %>'
	).template();

	Transport.prototype.send = function(params, callback) {
		var self = this,
			build = params.build,
			changes = build.scm.changes,
			recipients = build.project.notify.to.telegram;

		if (_(recipients).isEmpty()) {
			logger.log('no recipients, quit');
			return callback();
		}

		Steppy(
			function() {
				logger.log('send message to %s', recipients);

				var message = self._messageTemplate({
					build: build,
					baseUrl: app.config.http.url,
					changes: changes,
					emoji: emojiHash[build.status] || ''
				});

				var group = this.makeGroup();
				_(recipients).each(function(recipient) {
					self._sendMessage({
						recipient: recipient,
						message: message
					}, group.slot());
				});
			},
			callback
		);
	};

	app.lib.notifier.register('telegram', Transport);
};
<|endoftext|>


<commit_before>/*
 *  Guacamole - Clientless Remote Desktop
 *  Copyright (C) 2010  Michael Jumper
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * Main Guacamole web service namespace.
 * @namespace
 */
var GuacamoleService = GuacamoleService || {};

/**
 * An arbitrary Guacamole connection, consisting of an ID/protocol pair.
 *
 * @constructor
 * @param {String} protocol The protocol used by this connection.
 * @param {String} id The ID associated with this connection.
 */
GuacamoleService.Connection = function(protocol, id) {

    /**
     * The protocol associated with this connection.
     */
    this.protocol = protocol;

    /**
     * The ID associated with this connection.
     */
    this.id = id;

};

/**
 * A basic set of permissions that can be assigned to a user, describing
 * whether they can create other users/connections and describing which
 * users/connections they have permission to read or modify.
 */
GuacamoleService.PermissionSet = function() {

    /**
     * Whether permission to create users is granted.
     */
    this.create_user = false;

    /**
     * Whether permission to create connections is granted.
     */
    this.create_connection = false;

    /**
     * Object with a property entry for each readable user.
     */
    this.read_user = {};

    /**
     * Object with a property entry for each updatable user.
     */
    this.update_user = {};

    /**
     * Object with a property entry for each removable user.
     */
    this.remove_user = {};

    /**
     * Object with a property entry for each administerable user.
     */
    this.administer_user = {};

    /**
     * Object with a property entry for each readable connection.
     */
    this.read_connection = {};

    /**
     * Object with a property entry for each updatable connection.
     */
    this.update_connection = {};

    /**
     * Object with a property entry for each removable connection.
     */
    this.remove_connection = {};

    /**
     * Object with a property entry for each administerable connection.
     */
    this.administer_connection = {};

};

/**
 * Collection of service functions which deal with connections. Each function
 * makes an explicit HTTP query to the server, and parses the response.
 */
GuacamoleService.Connections = {

     /**
      * Returns an array of Connections for which the current user has access.
      *
      * @param {String} parameters Any parameters which should be passed to the
      *                            server for the sake of authentication
      *                            (optional).
      * @return {GuacamoleService.Connection[]} An array of Connections for
      *                                         which the current user has
      *                                         access.
      */
    "list" : function(parameters) {

        // Construct request URL
        var list_url = "connections";
        if (parameters) list_url += "?" + parameters;

        // Get connection list
        var xhr = new XMLHttpRequest();
        xhr.open("GET", list_url, false);
        xhr.send(null);

        // If fail, throw error
        if (xhr.status != 200)
            throw new Error(xhr.statusText);

        // Otherwise, get list
        var connections = new Array();

        var connectionElements = xhr.responseXML.getElementsByTagName("connection");
        for (var i=0; i<connectionElements.length; i++) {
            connections.push(new GuacamoleService.Connection(
                connectionElements[i].getAttribute("protocol"),
                connectionElements[i].getAttribute("id")
            ));
        }

        return connections;

    }

};

/**
 * Collection of service functions which deal with users. Each function
 * makes an explicit HTTP query to the server, and parses the response.
 */
GuacamoleService.Users = {

    /**
     * Returns an array of usernames for which the current user has access.
     *
     * @param {String} parameters Any parameters which should be passed to the
     *                            server for the sake of authentication
     *                            (optional).
     * @return {String[]} An array of usernames for which the current user has
     *                    access.
     */
    "list" : function(parameters) {

        // Construct request URL
        var users_url = "users";
        if (parameters) users_url += "?" + parameters;

        // Get user list
        var xhr = new XMLHttpRequest();
        xhr.open("GET", users_url, false);
        xhr.send(null);

        // If fail, throw error
        if (xhr.status != 200)
            throw new Error(xhr.statusText);

        // Otherwise, get list
        var users = new Array();

        var userElements = xhr.responseXML.getElementsByTagName("user");
        for (var i=0; i<userElements.length; i++)
            users.push(userElements[i].getAttribute("name"));

        return users;

    },

    /**
     * Updates the user having the given username.
     *
     * @param {String} username The username of the user to create.
     * @param {String} password The password to assign to the user.
     * @param {GuacamoleService.PermissionSet} permissions The permissions to
     *                                                     assign.
     * @param {String} parameters Any parameters which should be passed to the
     *                            server for the sake of authentication
     *                            (optional).
     */
    "update" : function(username, password, permissions, parameters) {

        // Construct request URL
        var users_url = "users/update?name=" + encodeURIComponent(username);
        if (parameters) users_url += "&" + parameters;

        // Init POST data
        var data = "password=" + encodeURIComponent(password);

        // Creation permissions
        if (permissions.create_user)       data += "&user=create";
        if (permissions.create_connection) data += "&connection=create";

        var name;

        // User permissions
        for (name in permissions.read_user)
            data += "&user=read:"  + encodeURIComponent(name);
        for (name in permissions.administer_user)
            data += "&user=admin:" + encodeURIComponent(name);
        for (name in permissions.update_user)
            data += "&user=update:" + encodeURIComponent(name);
        for (name in permissions.remove_user)
            data += "&user=delete:" + encodeURIComponent(name);

        // Connection permissions
        for (name in permissions.read_connection)
            data += "&connection=read:" + encodeURIComponent(name);
        for (name in permissions.administer_connection)
            data += "&connection=admin:" + encodeURIComponent(name);
        for (name in permissions.update_connection)
            data += "&connection=update:" + encodeURIComponent(name);
        for (name in permissions.remove_connection)
            data += "&connection=delete:" + encodeURIComponent(name);

        // Update user
        var xhr = new XMLHttpRequest();
        xhr.open("POST", users_url, false);
        xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xhr.send(data);

        // If fail, throw error
        if (xhr.status != 200)
            throw new Error(xhr.statusText);

    },

    /**
     * Creates a new user having the given username.
     *
     * @param {String} username The username of the user to create.
     * @param {String} parameters Any parameters which should be passed to the
     *                            server for the sake of authentication
     *                            (optional).
     */
    "create" : function(username, parameters) {

        // Construct request URL
        var users_url = "users/create?name=" + encodeURIComponent(username);
        if (parameters) users_url += "&" + parameters;

        // Add user
        var xhr = new XMLHttpRequest();
        xhr.open("GET", users_url, false);
        xhr.send(null);

        // If fail, throw error
        if (xhr.status != 200)
            throw new Error(xhr.statusText);

    },
    /**
     * Deletes the user having the given username.
     *
     * @param {String} username The username of the user to delete.
     * @param {String} parameters Any parameters which should be passed to the
     *                            server for the sake of authentication
     *                            (optional).
     */
    "remove" : function(username, parameters) {

        // Construct request URL
        var users_url = "users/delete?name=" + encodeURIComponent(username);
        if (parameters) users_url += "&" + parameters;

        // Add user
        var xhr = new XMLHttpRequest();
        xhr.open("GET", users_url, false);
        xhr.send(null);

        // If fail, throw error
        if (xhr.status != 200)
            throw new Error(xhr.statusText);

    }

};

/**
 * Collection of service functions which deal with permissions. Each function
 * makes an explicit HTTP query to the server, and parses the response.
 */
GuacamoleService.Permissions = {

     /**
      * Returns a PermissionSet describing the permissions given to a
      * specified user.
      *
      * @param {String} username The username of the user to list permissions
      *                          of.
      * @param {String} parameters Any parameters which should be passed to the
      *                            server for the sake of authentication
      *                            (optional).
      * @return {GuacamoleService.PermissionSet} A PermissionSet describing the
      *                                          permissions given to the
      *                                          specified user.
      */
    "list" : function(username, parameters) {

        // Construct request URL
        var list_url = "permissions?user=" + encodeURIComponent(username);
        if (parameters) list_url += "&" + parameters;

        // Get permission list
        var xhr = new XMLHttpRequest();
        xhr.open("GET", list_url, false);
        xhr.send(null);

        // If fail, throw error
        if (xhr.status != 200)
            throw new Error(xhr.statusText);

        // Otherwise, build PermissionSet
        var i, type, name;
        var permissions = new GuacamoleService.PermissionSet();

        // Read connections permissions
        var connectionsElements = xhr.responseXML.getElementsByTagName("connections");
        for (i=0; i<connectionsElements.length; i++) {

            // Get type
            type = connectionsElements[i].getAttribute("type");
            switch (type) {

                // Create permission
                case "create":
                    permissions.create_connection = true;
                    break;

            }

        }

        // Read connection permissions
        var connectionElements = xhr.responseXML.getElementsByTagName("connection");
        for (i=0; i<connectionElements.length; i++) {

            // Get name and type
            type = connectionElements[i].getAttribute("type");
            name = connectionElements[i].getAttribute("name");

            switch (type) {

                // Read permission
                case "read":
                    permissions.read_connection[name] = true;
                    break;

                // Update permission
                case "update":
                    permissions.update_connection[name] = true;
                    break;

                // Admin permission
                case "admin":
                    permissions.administer_connection[name] = true;
                    break;

                // Delete permission
                case "delete":
                    permissions.remove_connection[name] = true;
                    break;

            }

        }

        // Read users permissions
        var usersElements = xhr.responseXML.getElementsByTagName("users");
        for (i=0; i<usersElements.length; i++) {

            // Get type
            type = usersElements[i].getAttribute("type");
            switch (type) {

                // Create permission
                case "create":
                    permissions.create_user = true;
                    break;

            }

        }

        // Read user permissions
        var userElements = xhr.responseXML.getElementsByTagName("user");
        for (i=0; i<userElements.length; i++) {

            // Get name and type
            type = userElements[i].getAttribute("type");
            name = userElements[i].getAttribute("name");

            switch (type) {

                // Read permission
                case "read":
                    permissions.read_user[name] = true;
                    break;

                // Update permission
                case "update":
                    permissions.update_user[name] = true;
                    break;

                // Admin permission
                case "admin":
                    permissions.administer_user[name] = true;
                    break;

                // Delete permission
                case "delete":
                    permissions.remove_user[name] = true;
                    break;

            }

        }

        return permissions;

    }

};

<commit_msg>#268: Implement remaining user service calls.<commit_after>/*
 *  Guacamole - Clientless Remote Desktop
 *  Copyright (C) 2010  Michael Jumper
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/**
 * Main Guacamole web service namespace.
 * @namespace
 */
var GuacamoleService = GuacamoleService || {};

/**
 * An arbitrary Guacamole connection, consisting of an ID/protocol pair.
 *
 * @constructor
 * @param {String} protocol The protocol used by this connection.
 * @param {String} id The ID associated with this connection.
 */
GuacamoleService.Connection = function(protocol, id) {

    /**
     * The protocol associated with this connection.
     */
    this.protocol = protocol;

    /**
     * The ID associated with this connection.
     */
    this.id = id;

    /**
     * All parameters associated with this connection, if available.
     */
    this.parameters = {};

};

/**
 * A basic set of permissions that can be assigned to a user, describing
 * whether they can create other users/connections and describing which
 * users/connections they have permission to read or modify.
 */
GuacamoleService.PermissionSet = function() {

    /**
     * Whether permission to create users is granted.
     */
    this.create_user = false;

    /**
     * Whether permission to create connections is granted.
     */
    this.create_connection = false;

    /**
     * Object with a property entry for each readable user.
     */
    this.read_user = {};

    /**
     * Object with a property entry for each updatable user.
     */
    this.update_user = {};

    /**
     * Object with a property entry for each removable user.
     */
    this.remove_user = {};

    /**
     * Object with a property entry for each administerable user.
     */
    this.administer_user = {};

    /**
     * Object with a property entry for each readable connection.
     */
    this.read_connection = {};

    /**
     * Object with a property entry for each updatable connection.
     */
    this.update_connection = {};

    /**
     * Object with a property entry for each removable connection.
     */
    this.remove_connection = {};

    /**
     * Object with a property entry for each administerable connection.
     */
    this.administer_connection = {};

};

/**
 * Collection of service functions which deal with connections. Each function
 * makes an explicit HTTP query to the server, and parses the response.
 */
GuacamoleService.Connections = {

     /**
      * Returns an array of Connections for which the current user has access.
      *
      * @param {String} parameters Any parameters which should be passed to the
      *                            server for the sake of authentication
      *                            (optional).
      * @return {GuacamoleService.Connection[]} An array of Connections for
      *                                         which the current user has
      *                                         access.
      */
    "list" : function(parameters) {

        // Construct request URL
        var list_url = "connections";
        if (parameters) list_url += "?" + parameters;

        // Get connection list
        var xhr = new XMLHttpRequest();
        xhr.open("GET", list_url, false);
        xhr.send(null);

        // If fail, throw error
        if (xhr.status != 200)
            throw new Error(xhr.statusText);

        // Otherwise, get list
        var connections = new Array();

        var connectionElements = xhr.responseXML.getElementsByTagName("connection");
        for (var i=0; i<connectionElements.length; i++) {
            connections.push(new GuacamoleService.Connection(
                connectionElements[i].getAttribute("protocol"),
                connectionElements[i].getAttribute("id")
            ));
        }

        return connections;

    },

    /**
     * Creates a new connection.
     *
     * @param {GuacamoleService.Connection} connection The connection to create.
     * @param {String} parameters Any parameters which should be passed to the
     *                            server for the sake of authentication
     *                            (optional).
     */
    "create" : function(connection, parameters) {

        // Construct request URL
        var users_url = "connections/create?id=" + encodeURIComponent(connection.id);
        if (parameters) users_url += "&" + parameters;

        // Init POST data
        var data = "protocol=" + encodeURIComponent(connection.protocol);

        // Add parameters
        for (var name in connection.parameters)
            data += "&_" + encodeURIComponent(name)
                 +  "="  + encodeURIComponent(connection.parameters[name]);

        // Add user
        var xhr = new XMLHttpRequest();
        xhr.open("POST", users_url, false);
        xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xhr.send(data);

        // If fail, throw error
        if (xhr.status != 200)
            throw new Error(xhr.statusText);

    },

    /**
     * Updates an existing connection.
     *
     * @param {GuacamoleService.Connection} connection The connection to create.
     * @param {String} parameters Any parameters which should be passed to the
     *                            server for the sake of authentication
     *                            (optional).
     */
    "update" : function(connection, parameters) {

        // Construct request URL
        var users_url = "connections/update?id=" + encodeURIComponent(connection.id);
        if (parameters) users_url += "&" + parameters;

        // Init POST data
        var data = "protocol=" + encodeURIComponent(connection.protocol);

        // Add parameters
        for (var name in connection.parameters)
            data += "&_" + encodeURIComponent(name)
                 +  "="  + encodeURIComponent(connection.parameters[name]);

        // Add user
        var xhr = new XMLHttpRequest();
        xhr.open("POST", users_url, false);
        xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xhr.send(data);

        // If fail, throw error
        if (xhr.status != 200)
            throw new Error(xhr.statusText);

    },

    /**
     * Deletes the connection having the given identifier.
     *
     * @param {String} id The identifier of the connection to delete.
     * @param {String} parameters Any parameters which should be passed to the
     *                            server for the sake of authentication
     *                            (optional).
     */
    "remove" : function(id, parameters) {

        // Construct request URL
        var connections_url = "connections/delete?id=" + encodeURIComponent(id);
        if (parameters) connections_url += "&" + parameters;

        // Add user
        var xhr = new XMLHttpRequest();
        xhr.open("GET", connections_url, false);
        xhr.send(null);

        // If fail, throw error
        if (xhr.status != 200)
            throw new Error(xhr.statusText);

    }

};

/**
 * Collection of service functions which deal with users. Each function
 * makes an explicit HTTP query to the server, and parses the response.
 */
GuacamoleService.Users = {

    /**
     * Returns an array of usernames for which the current user has access.
     *
     * @param {String} parameters Any parameters which should be passed to the
     *                            server for the sake of authentication
     *                            (optional).
     * @return {String[]} An array of usernames for which the current user has
     *                    access.
     */
    "list" : function(parameters) {

        // Construct request URL
        var users_url = "users";
        if (parameters) users_url += "?" + parameters;

        // Get user list
        var xhr = new XMLHttpRequest();
        xhr.open("GET", users_url, false);
        xhr.send(null);

        // If fail, throw error
        if (xhr.status != 200)
            throw new Error(xhr.statusText);

        // Otherwise, get list
        var users = new Array();

        var userElements = xhr.responseXML.getElementsByTagName("user");
        for (var i=0; i<userElements.length; i++)
            users.push(userElements[i].getAttribute("name"));

        return users;

    },

    /**
     * Updates the user having the given username.
     *
     * @param {String} username The username of the user to create.
     * @param {String} password The password to assign to the user.
     * @param {GuacamoleService.PermissionSet} permissions The permissions to
     *                                                     assign.
     * @param {String} parameters Any parameters which should be passed to the
     *                            server for the sake of authentication
     *                            (optional).
     */
    "update" : function(username, password, permissions, parameters) {

        // Construct request URL
        var users_url = "users/update?name=" + encodeURIComponent(username);
        if (parameters) users_url += "&" + parameters;

        // Init POST data
        var data = "password=" + encodeURIComponent(password);

        // Creation permissions
        if (permissions.create_user)       data += "&user=create";
        if (permissions.create_connection) data += "&connection=create";

        var name;

        // User permissions
        for (name in permissions.read_user)
            data += "&user=read:"  + encodeURIComponent(name);
        for (name in permissions.administer_user)
            data += "&user=admin:" + encodeURIComponent(name);
        for (name in permissions.update_user)
            data += "&user=update:" + encodeURIComponent(name);
        for (name in permissions.remove_user)
            data += "&user=delete:" + encodeURIComponent(name);

        // Connection permissions
        for (name in permissions.read_connection)
            data += "&connection=read:" + encodeURIComponent(name);
        for (name in permissions.administer_connection)
            data += "&connection=admin:" + encodeURIComponent(name);
        for (name in permissions.update_connection)
            data += "&connection=update:" + encodeURIComponent(name);
        for (name in permissions.remove_connection)
            data += "&connection=delete:" + encodeURIComponent(name);

        // Update user
        var xhr = new XMLHttpRequest();
        xhr.open("POST", users_url, false);
        xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
        xhr.send(data);

        // If fail, throw error
        if (xhr.status != 200)
            throw new Error(xhr.statusText);

    },

    /**
     * Creates a new user having the given username.
     *
     * @param {String} username The username of the user to create.
     * @param {String} parameters Any parameters which should be passed to the
     *                            server for the sake of authentication
     *                            (optional).
     */
    "create" : function(username, parameters) {

        // Construct request URL
        var users_url = "users/create?name=" + encodeURIComponent(username);
        if (parameters) users_url += "&" + parameters;

        // Add user
        var xhr = new XMLHttpRequest();
        xhr.open("GET", users_url, false);
        xhr.send(null);

        // If fail, throw error
        if (xhr.status != 200)
            throw new Error(xhr.statusText);

    },

    /**
     * Deletes the user having the given username.
     *
     * @param {String} username The username of the user to delete.
     * @param {String} parameters Any parameters which should be passed to the
     *                            server for the sake of authentication
     *                            (optional).
     */
    "remove" : function(username, parameters) {

        // Construct request URL
        var users_url = "users/delete?name=" + encodeURIComponent(username);
        if (parameters) users_url += "&" + parameters;

        // Add user
        var xhr = new XMLHttpRequest();
        xhr.open("GET", users_url, false);
        xhr.send(null);

        // If fail, throw error
        if (xhr.status != 200)
            throw new Error(xhr.statusText);

    }

};

/**
 * Collection of service functions which deal with permissions. Each function
 * makes an explicit HTTP query to the server, and parses the response.
 */
GuacamoleService.Permissions = {

     /**
      * Returns a PermissionSet describing the permissions given to a
      * specified user.
      *
      * @param {String} username The username of the user to list permissions
      *                          of.
      * @param {String} parameters Any parameters which should be passed to the
      *                            server for the sake of authentication
      *                            (optional).
      * @return {GuacamoleService.PermissionSet} A PermissionSet describing the
      *                                          permissions given to the
      *                                          specified user.
      */
    "list" : function(username, parameters) {

        // Construct request URL
        var list_url = "permissions?user=" + encodeURIComponent(username);
        if (parameters) list_url += "&" + parameters;

        // Get permission list
        var xhr = new XMLHttpRequest();
        xhr.open("GET", list_url, false);
        xhr.send(null);

        // If fail, throw error
        if (xhr.status != 200)
            throw new Error(xhr.statusText);

        // Otherwise, build PermissionSet
        var i, type, name;
        var permissions = new GuacamoleService.PermissionSet();

        // Read connections permissions
        var connectionsElements = xhr.responseXML.getElementsByTagName("connections");
        for (i=0; i<connectionsElements.length; i++) {

            // Get type
            type = connectionsElements[i].getAttribute("type");
            switch (type) {

                // Create permission
                case "create":
                    permissions.create_connection = true;
                    break;

            }

        }

        // Read connection permissions
        var connectionElements = xhr.responseXML.getElementsByTagName("connection");
        for (i=0; i<connectionElements.length; i++) {

            // Get name and type
            type = connectionElements[i].getAttribute("type");
            name = connectionElements[i].getAttribute("name");

            switch (type) {

                // Read permission
                case "read":
                    permissions.read_connection[name] = true;
                    break;

                // Update permission
                case "update":
                    permissions.update_connection[name] = true;
                    break;

                // Admin permission
                case "admin":
                    permissions.administer_connection[name] = true;
                    break;

                // Delete permission
                case "delete":
                    permissions.remove_connection[name] = true;
                    break;

            }

        }

        // Read users permissions
        var usersElements = xhr.responseXML.getElementsByTagName("users");
        for (i=0; i<usersElements.length; i++) {

            // Get type
            type = usersElements[i].getAttribute("type");
            switch (type) {

                // Create permission
                case "create":
                    permissions.create_user = true;
                    break;

            }

        }

        // Read user permissions
        var userElements = xhr.responseXML.getElementsByTagName("user");
        for (i=0; i<userElements.length; i++) {

            // Get name and type
            type = userElements[i].getAttribute("type");
            name = userElements[i].getAttribute("name");

            switch (type) {

                // Read permission
                case "read":
                    permissions.read_user[name] = true;
                    break;

                // Update permission
                case "update":
                    permissions.update_user[name] = true;
                    break;

                // Admin permission
                case "admin":
                    permissions.administer_user[name] = true;
                    break;

                // Delete permission
                case "delete":
                    permissions.remove_user[name] = true;
                    break;

            }

        }

        return permissions;

    }

};

<|endoftext|>


<commit_before>(function() {
  'use strict';

  var sass = require('node-sass'),
      each = require('async').each,
      path = require('path'),

      isSassFile = function isSassFile(filename) {
        return (/^[^_.].*\.scss/).test(path.basename(filename));
      },

      isPartial = function isPartial(filename) {
        return (/^_.*\.scss/).test(path.basename(filename));
      },

      compile = function(basePath, files, filename, done) {
        var file = files[filename],
            includes = this.includePaths || [],
            outputStyle = this.outputStyle || 'compressed',
            imagePath = this.imagePath || '/',
            outputDir = this.outputDir || path.dirname(filename),
            fileDir = path.dirname(path.join(basePath, filename));

        if (isSassFile(filename) === true) {
          // Append the file's base path to the available include paths.
          includes.push(fileDir);

          // Compile the file using SASS.
          sass.render({
            // Use the file's content stream buffer rather than the file path.
            data: file.contents.toString(),
            includePaths: includes,
            imagePath: imagePath,
            outputStyle: outputStyle,
            success: function(css) {
              // replace contents
              file.contents = new Buffer(css);
              // rename file extension
              files[path.join(outputDir, path.basename(filename).replace('.scss', '.css'))] = file;
              delete files[filename];
              done();
            },
            error: function(err) {
              console.log(err);
              done(err);
            }
          });
        } else if (isPartial(filename) === true) {
          delete files[filename];
          done();
        } else {
          done();
        }
      },

      compileSass = function compileSass(files, metalsmith, done) {
        /**
         * Looks up different key names on `metalsmith` to support
         * old versions (< v1) of Metalsmith. At some point, I will remove
         * support for < v1 and remove the key lookups
         */
        var directory = metalsmith.dir || metalsmith._directory,
            source = metalsmith._src || metalsmith._source,
            basePath = path.join(directory, source);
        each(Object.keys(files), compile.bind(this, basePath, files), done);
      },

      plugin = function plugin(options) {
        var config = options || {};
        return compileSass.bind(config);
      };

  module.exports = plugin;
}());
<commit_msg>remove error log statement<commit_after>(function() {
  'use strict';

  var sass = require('node-sass'),
      each = require('async').each,
      path = require('path'),

      isSassFile = function isSassFile(filename) {
        return (/^[^_.].*\.scss/).test(path.basename(filename));
      },

      isPartial = function isPartial(filename) {
        return (/^_.*\.scss/).test(path.basename(filename));
      },

      compile = function(basePath, files, filename, done) {
        var file = files[filename],
            includes = this.includePaths || [],
            outputStyle = this.outputStyle || 'compressed',
            imagePath = this.imagePath || '/',
            outputDir = this.outputDir || path.dirname(filename),
            fileDir = path.dirname(path.join(basePath, filename));

        if (isSassFile(filename) === true) {
          // Append the file's base path to the available include paths.
          includes.push(fileDir);

          // Compile the file using SASS.
          sass.render({
            // Use the file's content stream buffer rather than the file path.
            data: file.contents.toString(),
            includePaths: includes,
            imagePath: imagePath,
            outputStyle: outputStyle,
            success: function(css) {
              // replace contents
              file.contents = new Buffer(css);
              // rename file extension
              files[path.join(outputDir, path.basename(filename).replace('.scss', '.css'))] = file;
              delete files[filename];
              done();
            },
            error: function(err) {
              done(err);
            }
          });
        } else if (isPartial(filename) === true) {
          delete files[filename];
          done();
        } else {
          done();
        }
      },

      compileSass = function compileSass(files, metalsmith, done) {
        /**
         * Looks up different key names on `metalsmith` to support
         * old versions (< v1) of Metalsmith. At some point, I will remove
         * support for < v1 and remove the key lookups
         */
        var directory = metalsmith.dir || metalsmith._directory,
            source = metalsmith._src || metalsmith._source,
            basePath = path.join(directory, source);
        each(Object.keys(files), compile.bind(this, basePath, files), done);
      },

      plugin = function plugin(options) {
        var config = options || {};
        return compileSass.bind(config);
      };

  module.exports = plugin;
}());
<|endoftext|>


<commit_before>/* global Firebase */
import Schema from 'orbit-common/schema';
import FirebaseSerializer from 'orbit-firebase/firebase-serializer';
import FirebaseListener from 'orbit-firebase/firebase-listener';
import FirebaseClient from 'orbit-firebase/firebase-client';
import { uuid } from 'orbit/lib/uuid';
import Orbit from 'orbit/main';
import { captureDidTransform, captureDidTransforms, op, prepareFirebaseClient } from 'tests/test-helper';
import { fop } from 'orbit-firebase/lib/operation-utils';
import { Promise, all, allSettled, resolve } from 'rsvp';
import { eq } from 'orbit/lib/eq';
import { any } from 'orbit-firebase/lib/array-utils';
import Operation from 'orbit/operation';

var schemaDefinition = {
  modelDefaults: {
    keys: {
      'id': {primaryKey: true, defaultValue: uuid}
    }
  },
  models: {
    planet: {
      attributes: {
        name: {type: 'string'},
        classification: {type: 'string'}
      },
      links: {
        moons: {type: 'hasMany', model: 'moon', inverse: 'planet'},
        races: {type: 'hasMany', model: 'race', inverse: 'planets'},
        next: {type: 'hasOne', model: 'planet', inverse: 'previous'},
        previous: {type: 'hasOne', model: 'planet', inverse: 'next'}
      }
    },
    moon: {
      attributes: {
        name: {type: 'string'}
      },
      links: {
        planet: {type: 'hasOne', model: 'planet', inverse: 'moons'}
      }
    },
    race: {
      attributes: {
        name: {type: 'string'},
      },
      links: {
        planets: {type: 'hasMany', model: 'planet', inverse: 'races'}
      }
    }
  }
};

var firebaseClient,
    firebaseListener,
    schema,
    cache;

function shouldIncludeOperation(operation, operations){
  var present = any(operations, function(candidate){
    return eq(candidate.serialize(), operation.serialize());
  });

  if(!present){
    console.group("operation", operation.toString(), "not found in...");
    operations.forEach(function(operation){
      console.log("*", operation.toString());
    });
    console.groupEnd();
  }

  ok(present, "operation was present: " + operation.path.join("/"));
}

module("OF - FirebaseListener", {
  setup: function() {
    Orbit.Promise = Promise;
    Orbit.all = all;
    Orbit.allSettled = allSettled;
    Orbit.resolve = resolve;

    schema = new Schema(schemaDefinition);
    var serializer = new FirebaseSerializer(schema);

    stop();
    prepareFirebaseClient().then(function(preparedFirebaseClient){
      firebaseClient = preparedFirebaseClient;
      firebaseListener = new FirebaseListener(firebaseClient.firebaseRef, schema, serializer);
      start();
    });
  },

  teardown: function() {
    firebaseListener.unsubscribeAll();
    firebaseListener = firebaseClient = null;
  }
});

test("receive add record operation", function(){
  stop();
  firebaseListener.subscribeToType('planet', "abc123");

  var planet = schema.normalize('planet', {id: "abc123", name: "Pluto"});
  var receiveOperation = captureDidTransform(firebaseListener, 3  );

  firebaseClient.set('planet/abc123', planet);

  receiveOperation.then(function(operation){
    start();
    equal(operation.op, 'add', "op matches");
    deepEqual(operation.path, ['planet', 'abc123'], "path matches");
    deepEqual(operation.value.id, planet.id, "record matches");
  });
});

test("receive remove record operation", function(){
  stop();
  firebaseListener.subscribeToType('planet', "abc123");

  var planet = schema.normalize('planet', {id: "abc123", name: "Pluto"});

  var receiveOperation = captureDidTransform(firebaseListener, 4);

  firebaseClient.set('planet/abc123', planet);
  firebaseClient.remove('planet/abc123');

  receiveOperation.then(function(receivedOperation){
    start();
    equal(receivedOperation.op, 'remove', "op matches");
    deepEqual(receivedOperation.path, ['planet', 'abc123'], "path matches");
  });
});

test("receive update attribute operation", function(){
  stop();
  firebaseListener.subscribeToType('planet');

  var planet = schema.normalize('planet', {id: "abc123", name: "Pluto"});

  var receiveOperation = captureDidTransform(firebaseListener, 3);
  firebaseClient.set('planet/abc123', planet);
  firebaseClient.set('planet/abc123/name', "Jupiter");

  receiveOperation.then(function(receivedOperation){
    start();
    equal(receivedOperation.op, 'replace', "op matches");
    deepEqual(receivedOperation.path, ['planet', 'abc123', 'name'], "path matches");
    equal(receivedOperation.value, "Jupiter", "attribute value matches");
  });
});

test("receive replace hasOne operation", function(){
  stop();
  firebaseListener.subscribeToType('moon', null, {include: ['planet']});
  var moon = schema.normalize('moon', {id: "moon123", name: "titan"});
  var planet = schema.normalize('planet', {id: "planet456", name: "jupiter"});

  var receiveOperation = captureDidTransform(firebaseListener, 8);

  firebaseClient.set('moon/moon123', moon);
  firebaseClient.set('planet/planet456', planet);
  firebaseClient.set('moon/moon123/planet', planet.id);

  receiveOperation.then(function(receivedOperation){
    start();
    equal(receivedOperation.op, 'replace', "op matches");
    deepEqual(receivedOperation.path, ['moon', 'moon123', '__rel', 'planet'], "path matches");
    equal(receivedOperation.value, "planet456", "link value matches");
  });
});

test("receive remove hasOne operation", function(){
  stop();
  firebaseListener.subscribeToType('moon', null, {include: ['planet']});
  var moon = schema.normalize('moon', {id: "moon123", name: "titan"});
  var planet = schema.normalize('planet', {id: "planet456", name: "jupiter"});

  var receiveOperations = captureDidTransforms(firebaseListener, 3);

  firebaseClient.set('moon/moon123', moon);
  firebaseClient.set('planet/planet456', planet);
  firebaseClient.remove('moon/moon123/planet');

  receiveOperations.then(function(receivedOperations){

    start();
    shouldIncludeOperation(op('add', 'moon/moon123/__rel/planet', null), receivedOperations);
  });
});

test("receive add to hasMany operation", function(){
  stop();
  firebaseListener.subscribeToType('planet', null, {include: ['moons']});

  var moon = schema.normalize('moon', {id: "moon123", name: "titan"});
  var planet = schema.normalize('planet', {id: "planet456", name: "jupiter"});

  var receiveOperations = captureDidTransforms(firebaseListener, 8);

  firebaseClient.set('moon/moon123', moon);
  firebaseClient.set('planet/planet456', planet);
  firebaseClient.set('planet/planet456/moons/moon123', true);

  receiveOperations.then(function(receivedOperations){
    start();
    shouldIncludeOperation(op('add', 'planet/planet456/__rel/moons/moon123', true), receivedOperations);
  });
});

test("receive remove from hasMany operation", function(){
  stop();
  firebaseListener.subscribeToType('planet', null, {include: ['moons']});

  var moon = schema.normalize('moon', {id: "moon123", name: "titan"});
  var planet = schema.normalize('planet', {id: "planet456", name: "jupiter"});

  var receiveOperations = captureDidTransforms(firebaseListener, 9);

  all([
    firebaseClient.set('moon/moon123', moon),
    firebaseClient.set('planet/planet456', planet),
    firebaseClient.set('planet/planet456/moons/moon123', true)
  ])
  .then(function(){
    return firebaseClient.remove('planet/planet456/moons/moon123');
  });

  receiveOperations.then(function(receivedOperations){
    start();
    var removeFromHasManyOperation = new Operation({op: 'remove', path: 'planet/planet456/__rel/moons/moon123'});
    shouldIncludeOperation(removeFromHasManyOperation, receivedOperations);
  });
});

test("subscribe to hasMany link", function(){
  stop();

  var moon = schema.normalize('moon', {id: "moon123", name: "titan", planet: 'planet456'});
  var planet = schema.normalize('planet', {id: "planet456", name: "jupiter", moons: {'moon123': true}});

  all([
    firebaseClient.set('moon/moon123', moon),
    firebaseClient.set('planet/planet456', planet)
  ])
  .then(function(){
    var receiveOperation = captureDidTransforms(firebaseListener, 8);

    firebaseListener.subscribeToLink('planet', 'planet456', 'moons');

    receiveOperation.then(function(receivedOperations){
      start();

      shouldIncludeOperation(op('add', 'planet/planet456/__rel/moons', {'moon123': true}), receivedOperations);
      shouldIncludeOperation(op('replace', 'moon/moon123/__rel/planet', 'planet456'), receivedOperations);
      shouldIncludeOperation(op('add', 'planet/planet456/__rel/moons/moon123', true), receivedOperations);
    });

  });

});
<commit_msg>Add shouldNotIncludeOperation helper<commit_after>/* global Firebase */
import Schema from 'orbit-common/schema';
import FirebaseSerializer from 'orbit-firebase/firebase-serializer';
import FirebaseListener from 'orbit-firebase/firebase-listener';
import FirebaseClient from 'orbit-firebase/firebase-client';
import { uuid } from 'orbit/lib/uuid';
import Orbit from 'orbit/main';
import { captureDidTransform, captureDidTransforms, op, prepareFirebaseClient } from 'tests/test-helper';
import { fop } from 'orbit-firebase/lib/operation-utils';
import { Promise, all, allSettled, resolve } from 'rsvp';
import { eq } from 'orbit/lib/eq';
import { any } from 'orbit-firebase/lib/array-utils';
import Operation from 'orbit/operation';

var schemaDefinition = {
  modelDefaults: {
    keys: {
      'id': {primaryKey: true, defaultValue: uuid}
    }
  },
  models: {
    planet: {
      attributes: {
        name: {type: 'string'},
        classification: {type: 'string'}
      },
      links: {
        moons: {type: 'hasMany', model: 'moon', inverse: 'planet'},
        races: {type: 'hasMany', model: 'race', inverse: 'planets'},
        next: {type: 'hasOne', model: 'planet', inverse: 'previous'},
        previous: {type: 'hasOne', model: 'planet', inverse: 'next'}
      }
    },
    moon: {
      attributes: {
        name: {type: 'string'}
      },
      links: {
        planet: {type: 'hasOne', model: 'planet', inverse: 'moons'}
      }
    },
    race: {
      attributes: {
        name: {type: 'string'},
      },
      links: {
        planets: {type: 'hasMany', model: 'planet', inverse: 'races'}
      }
    }
  }
};

var firebaseClient,
    firebaseListener,
    schema,
    cache;

function shouldIncludeOperation(operation, operations){
  var present = any(operations, function(candidate){
    return eq(candidate.serialize(), operation.serialize());
  });

  if(!present){
    console.group("operation", operation.toString(), "not found in...");
    operations.forEach(function(operation){
      console.log("*", operation.toString());
    });
    console.groupEnd();
  }

  ok(present, "operation was present: " + operation.path.join("/"));
}

function shouldNotIncludeOperation(operation, operations){
  var present = any(operations, function(candidate){
    return eq(candidate.serialize(), operation.serialize());
  });

  if(present){
    console.group("operation", operation.toString(), "found in...");
    operations.forEach(function(operation){
      console.log("*", operation.toString());
    });
    console.groupEnd();
  }

  ok(!present, "operation wasn't present: " + operation.path.join("/"));
}

module("OF - FirebaseListener", {
  setup: function() {
    Orbit.Promise = Promise;
    Orbit.all = all;
    Orbit.allSettled = allSettled;
    Orbit.resolve = resolve;

    schema = new Schema(schemaDefinition);
    var serializer = new FirebaseSerializer(schema);

    stop();
    prepareFirebaseClient().then(function(preparedFirebaseClient){
      firebaseClient = preparedFirebaseClient;
      firebaseListener = new FirebaseListener(firebaseClient.firebaseRef, schema, serializer);
      start();
    });
  },

  teardown: function() {
    firebaseListener.unsubscribeAll();
    firebaseListener = firebaseClient = null;
  }
});

test("receive add record operation", function(){
  stop();
  firebaseListener.subscribeToType('planet', "abc123");

  var planet = schema.normalize('planet', {id: "abc123", name: "Pluto"});
  var receiveOperation = captureDidTransform(firebaseListener, 3  );

  firebaseClient.set('planet/abc123', planet);

  receiveOperation.then(function(operation){
    start();
    equal(operation.op, 'add', "op matches");
    deepEqual(operation.path, ['planet', 'abc123'], "path matches");
    deepEqual(operation.value.id, planet.id, "record matches");
  });
});

test("receive remove record operation", function(){
  stop();
  firebaseListener.subscribeToType('planet', "abc123");

  var planet = schema.normalize('planet', {id: "abc123", name: "Pluto"});

  var receiveOperation = captureDidTransform(firebaseListener, 4);

  firebaseClient.set('planet/abc123', planet);
  firebaseClient.remove('planet/abc123');

  receiveOperation.then(function(receivedOperation){
    start();
    equal(receivedOperation.op, 'remove', "op matches");
    deepEqual(receivedOperation.path, ['planet', 'abc123'], "path matches");
  });
});

test("receive update attribute operation", function(){
  stop();
  firebaseListener.subscribeToType('planet');

  var planet = schema.normalize('planet', {id: "abc123", name: "Pluto"});

  var receiveOperation = captureDidTransform(firebaseListener, 3);
  firebaseClient.set('planet/abc123', planet);
  firebaseClient.set('planet/abc123/name', "Jupiter");

  receiveOperation.then(function(receivedOperation){
    start();
    equal(receivedOperation.op, 'replace', "op matches");
    deepEqual(receivedOperation.path, ['planet', 'abc123', 'name'], "path matches");
    equal(receivedOperation.value, "Jupiter", "attribute value matches");
  });
});

test("receive replace hasOne operation", function(){
  stop();
  firebaseListener.subscribeToType('moon', null, {include: ['planet']});
  var moon = schema.normalize('moon', {id: "moon123", name: "titan"});
  var planet = schema.normalize('planet', {id: "planet456", name: "jupiter"});

  var receiveOperation = captureDidTransform(firebaseListener, 8);

  firebaseClient.set('moon/moon123', moon);
  firebaseClient.set('planet/planet456', planet);
  firebaseClient.set('moon/moon123/planet', planet.id);

  receiveOperation.then(function(receivedOperation){
    start();
    equal(receivedOperation.op, 'replace', "op matches");
    deepEqual(receivedOperation.path, ['moon', 'moon123', '__rel', 'planet'], "path matches");
    equal(receivedOperation.value, "planet456", "link value matches");
  });
});

test("receive remove hasOne operation", function(){
  stop();
  firebaseListener.subscribeToType('moon', null, {include: ['planet']});
  var moon = schema.normalize('moon', {id: "moon123", name: "titan"});
  var planet = schema.normalize('planet', {id: "planet456", name: "jupiter"});

  var receiveOperations = captureDidTransforms(firebaseListener, 3);

  firebaseClient.set('moon/moon123', moon);
  firebaseClient.set('planet/planet456', planet);
  firebaseClient.remove('moon/moon123/planet');

  receiveOperations.then(function(receivedOperations){

    start();
    shouldIncludeOperation(op('add', 'moon/moon123/__rel/planet', null), receivedOperations);
  });
});

test("receive add to hasMany operation", function(){
  stop();
  firebaseListener.subscribeToType('planet', null, {include: ['moons']});

  var moon = schema.normalize('moon', {id: "moon123", name: "titan"});
  var planet = schema.normalize('planet', {id: "planet456", name: "jupiter"});

  var receiveOperations = captureDidTransforms(firebaseListener, 8);

  firebaseClient.set('moon/moon123', moon);
  firebaseClient.set('planet/planet456', planet);
  firebaseClient.set('planet/planet456/moons/moon123', true);

  receiveOperations.then(function(receivedOperations){
    start();
    shouldIncludeOperation(op('add', 'planet/planet456/__rel/moons/moon123', true), receivedOperations);
  });
});

test("receive remove from hasMany operation", function(){
  stop();
  firebaseListener.subscribeToType('planet', null, {include: ['moons']});

  var moon = schema.normalize('moon', {id: "moon123", name: "titan"});
  var planet = schema.normalize('planet', {id: "planet456", name: "jupiter"});

  var receiveOperations = captureDidTransforms(firebaseListener, 9);

  all([
    firebaseClient.set('moon/moon123', moon),
    firebaseClient.set('planet/planet456', planet),
    firebaseClient.set('planet/planet456/moons/moon123', true)
  ])
  .then(function(){
    return firebaseClient.remove('planet/planet456/moons/moon123');
  });

  receiveOperations.then(function(receivedOperations){
    start();
    var removeFromHasManyOperation = new Operation({op: 'remove', path: 'planet/planet456/__rel/moons/moon123'});
    shouldIncludeOperation(removeFromHasManyOperation, receivedOperations);
  });
});

test("subscribe to hasMany link", function(){
  stop();

  var moon = schema.normalize('moon', {id: "moon123", name: "titan", planet: 'planet456'});
  var planet = schema.normalize('planet', {id: "planet456", name: "jupiter", moons: {'moon123': true}});

  all([
    firebaseClient.set('moon/moon123', moon),
    firebaseClient.set('planet/planet456', planet)
  ])
  .then(function(){
    var receiveOperation = captureDidTransforms(firebaseListener, 8);

    firebaseListener.subscribeToLink('planet', 'planet456', 'moons');

    receiveOperation.then(function(receivedOperations){
      start();

      shouldIncludeOperation(op('add', 'planet/planet456/__rel/moons', {'moon123': true}), receivedOperations);
      shouldIncludeOperation(op('replace', 'moon/moon123/__rel/planet', 'planet456'), receivedOperations);
      shouldIncludeOperation(op('add', 'planet/planet456/__rel/moons/moon123', true), receivedOperations);
    });

  });

});
<|endoftext|>


<commit_before>var $ = require('jquery');
var deck = require('./deck');
var Hand = require('./hand');
var Game = require('./game');

var playerHand = new Hand();
var dealerHand = new Hand();
var game = new Game();
var dealerWins = 0;
var playerWins = 0;

function addClickListenerToStayButton () {
  $("#stay-button").on("click", dealerTurn)
}

function playerTakesAHit () {
  dealOneCard(playerHand, $("#player-hand"));
  scorePlayerHand();
}

function addClickListenerToHitButton () {
  $("#hit-me-button").on("click", playerTakesAHit)
}

function scorePlayerHand () {
  playerHand.score();
  playerHand.renderTo($("#player-hand"));
  playerHand.renderScore($("#player-score"));

  if (playerHand.score() > 21) {
    ++dealerWins;
    playerHand.renderMessage($("#player-message"), "
BUSTED!
 Sorry! Try Again!
");
    dealerHand.renderMessage($(".win-counter"), '
Dealer Score: ' + dealerWins + ' –– Player Score: ' + playerWins + '
');
    game.buttonsAfterGame();

    game.newGame(playerHand, dealerHand);

  } else if (playerHand.score() === 21) {
    ++playerWins;
    playerHand.renderMessage($("#player-message"), "
Congratulations! You Won!
");
    dealerHand.renderMessage($(".win-counter"), '
Dealer Score: ' + dealerWins + ' –– Player Score: ' + playerWins + '
');
    game.buttonsAfterGame();
    game.newGame(playerHand, dealerHand);
  }
}

function scoreDealerHand () {
  dealerHand.score();
  dealerHand.renderTo($("#dealer-hand"));
  dealerHand.renderScore($("#dealer-score"));
}

function playerStays() {
  game.buttonsDuringStay();

  while (dealerHand.score() < 17) {
    dealOneCard(dealerHand, $("#dealer-hand"));
    scoreDealerHand();
  }

  if (dealerHand.score() > 21) {
    ++playerWins;
    dealerHand.renderMessage($("#dealer-message"), "
Dealer Busted - PLAYER WINS!
");
    dealerHand.renderMessage($(".win-counter"), '
Dealer Score: ' + dealerWins + ' –– Player Score: ' + playerWins + '
');
    game.buttonsAfterGame();
    game.newGame(playerHand, dealerHand);
  } else if (dealerHand.score() === 21) {
    ++dealerWins;
    dealerHand.renderMessage($("#dealer-message"), "
Oh well – the dealer won!
");
    dealerHand.renderMessage($(".win-counter"), '
Dealer Score: ' + dealerWins + ' –– Player Score: ' + playerWins + '
');
    game.buttonsAfterGame();
    game.newGame(playerHand, dealerHand);
  } else if (dealerHand.score() >= 17) {
    // game.evaluateFinalScores();
    dealerHand.renderMessage($("#dealer-message"), "
evaluate like crazy!
");
  }
}

function dealOneCard (whoseHand, jQueryDestination) {
  var card = deck.pickCard();
  whoseHand.receiveCard(card);
  whoseHand.renderTo(jQueryDestination);
}

function dealDealerHand(dealerHand) {
  dealOneCard(dealerHand, $("#dealer-hand"));
  dealOneCard(dealerHand, $("#dealer-hand"));
}

function dealPlayerHand (playerHand){
  dealOneCard(playerHand, $("#player-hand"));
  dealOneCard(playerHand, $("#player-hand"));
}

function dealHands () {
  dealPlayerHand(playerHand);
  scorePlayerHand();
  dealDealerHand(dealerHand);
  scoreDealerHand();
  game.buttonsDuringGame();
}

function addClickListenerToDealButton() {
  $("#deal-cards-button").on("click", dealHands)
}

function addClickListenerToStayButton() {
  $("#stay-button").on("click", playerStays)
}

function addClickListenerNewGameButton() {
  $("#new-game-button").on("click", dealHands);
  $("#new-game-button").on("click", removeMessage)
}

function removeMessage () {
  $('h2')[0].remove();
}

game.initialize();
addClickListenerToDealButton();
addClickListenerToHitButton();
addClickListenerToStayButton();
addClickListenerNewGameButton();
<commit_msg>Update 'playerStays' with 'evaluateFinaleScores'. WIP.<commit_after>var $ = require('jquery');
var deck = require('./deck');
var Hand = require('./hand');
var Game = require('./game');

var playerHand = new Hand();
var dealerHand = new Hand();
var game = new Game();
var dealerWins = 0;
var playerWins = 0;

function addClickListenerToStayButton () {
  $("#stay-button").on("click", dealerTurn)
}

function playerTakesAHit () {
  dealOneCard(playerHand, $("#player-hand"));
  scorePlayerHand();
}

function addClickListenerToHitButton () {
  $("#hit-me-button").on("click", playerTakesAHit)
}

function scorePlayerHand () {
  playerHand.score();
  playerHand.renderTo($("#player-hand"));
  playerHand.renderScore($("#player-score"));

  if (playerHand.score() > 21) {
    ++dealerWins;
    playerHand.renderMessage($("#player-message"), "
BUSTED!
 Sorry! Try Again!
");
    dealerHand.renderMessage($(".win-counter"), '
Dealer Score: ' + dealerWins + ' –– Player Score: ' + playerWins + '
');
    game.buttonsAfterGame();

    game.newGame(playerHand, dealerHand);

  } else if (playerHand.score() === 21) {
    ++playerWins;
    playerHand.renderMessage($("#player-message"), "
Congratulations! You Won!
");
    dealerHand.renderMessage($(".win-counter"), '
Dealer Score: ' + dealerWins + ' –– Player Score: ' + playerWins + '
');
    game.buttonsAfterGame();
    game.newGame(playerHand, dealerHand);
  }
}

function scoreDealerHand () {
  dealerHand.score();
  dealerHand.renderTo($("#dealer-hand"));
  dealerHand.renderScore($("#dealer-score"));
}

function playerStays() {
  game.buttonsDuringStay();

  while (dealerHand.score() < 17) {
    dealOneCard(dealerHand, $("#dealer-hand"));
    scoreDealerHand();
  }

  if (dealerHand.score() > 21) {
    ++playerWins;
    dealerHand.renderMessage($("#dealer-message"), "
Dealer Busted - PLAYER WINS!
");
    dealerHand.renderMessage($(".win-counter"), '
Dealer Score: ' + dealerWins + ' –– Player Score: ' + playerWins + '
');
    game.buttonsAfterGame();
    game.newGame(playerHand, dealerHand);
  } else if (dealerHand.score() === 21) {
    ++dealerWins;
    dealerHand.renderMessage($("#dealer-message"), "
Oh well – the dealer won!
");
    dealerHand.renderMessage($(".win-counter"), '
Dealer Score: ' + dealerWins + ' –– Player Score: ' + playerWins + '
');
    game.buttonsAfterGame();
    game.newGame(playerHand, dealerHand);
  } else if (dealerHand.score() >= 17) {
    dealerHand.renderMessage($("#dealer-message"), "
evaluate like crazy!
");
    evaluateFinalScores();
  }
}

function evaluateFinalScores() {

}

function dealOneCard (whoseHand, jQueryDestination) {
  var card = deck.pickCard();
  whoseHand.receiveCard(card);
  whoseHand.renderTo(jQueryDestination);
}

function dealDealerHand(dealerHand) {
  dealOneCard(dealerHand, $("#dealer-hand"));
  dealOneCard(dealerHand, $("#dealer-hand"));
}

function dealPlayerHand (playerHand){
  dealOneCard(playerHand, $("#player-hand"));
  dealOneCard(playerHand, $("#player-hand"));
}

function dealHands () {
  dealPlayerHand(playerHand);
  scorePlayerHand();
  dealDealerHand(dealerHand);
  scoreDealerHand();
  game.buttonsDuringGame();
}

function addClickListenerToDealButton() {
  $("#deal-cards-button").on("click", dealHands)
}

function addClickListenerToStayButton() {
  $("#stay-button").on("click", playerStays)
}

function addClickListenerNewGameButton() {
  $("#new-game-button").on("click", dealHands);
  $("#new-game-button").on("click", removeMessage)
}

function removeMessage () {
  $('h2')[0].remove();
}

game.initialize();
addClickListenerToDealButton();
addClickListenerToHitButton();
addClickListenerToStayButton();
addClickListenerNewGameButton();
<|endoftext|>


<commit_before>'use strict'

describe('Subscribe', function () {
  var perf = require('chai-performance')
  perf.log = true
  chai.use(perf)
  var Observable = require('../../../../lib/observable')
  // var Event = require('../../../lib/event')
  var amount = 1000
  var arr

  function observable () {
    arr = []
    for (var i = 0; i < amount; i++) {
      var a = new Observable({ //eslint-disable-line
        b: true
      })
      a.subscribe({
        b: true
      })
      arr.push(a)
    }
  }

  it('creating observables add listeners and fire on existing field (' + amount + ')', function (done) {
    this.timeout(50e3)
    expect(function () {
      arr = []
      for (var i = 0; i < amount; i++) {
        var a = new Observable({ //eslint-disable-line
          b: true,
          on: {
            data () {

            }
          }
        })
        a.val = i
        arr.push(a)
      }
    }).performance({
      loop: 10,
      time: 100
    }, done)
  })

  it('creating observables add listeners using context (' + amount + ')', function (done) {
    this.timeout(50e3)
    var thing = new Observable({
      b: true,
      on: { data () {} }
    })
    var Thing = thing.Constructor
    expect(function () {
      arr = []
      for (var i = 0; i < amount; i++) {
        var a = new Thing({
          val: i
        })
        arr.push(a)
      }
    }).performance({
      loop: 10,
      time: 100
    }, done)
  })

  it('creating observables and subscribing on existing field (' + amount + ')', function (done) {
    this.timeout(50e3)
    expect(observable).performance({
      loop: 10,
      time: 100
    }, done)
  })

  it('creating observables subscribing using context (' + amount + ')', function (done) {
    this.timeout(50e3)
    var thing = new Observable({
      b: true
    })
    thing.subscribe({
      b: true
    })
    var Thing = thing.Constructor
    expect(function () {
      arr = []
      for (var i = 0; i < amount; i++) {
        var a = new Thing({
          b: i
        })
        arr.push(a)
      }
    }).performance({
      loop: 10,
      time: 100
    }, done)
  })
})
<commit_msg>added more tests<commit_after>'use strict'

describe('Subscribe', function () {
  var perf = require('chai-performance')
  perf.log = true
  chai.use(perf)
  var Observable = require('../../../../lib/observable')
  // var Event = require('../../../lib/event')
  var amount = 1000
  var arr

  describe('Observable default emitters (baseline)', function () {
    function baseline () {
      arr = []
      for (var i = 0; i < amount; i++) {
        var a = new Observable({ //eslint-disable-line
          b: true,
          on: {
            data () {

            }
          }
        })
        a.val = i
        arr.push(a)
      }
    }

    it('creating observables add listeners and fire on existing field (' + amount + ')', function (done) {
      this.timeout(50e3)
      expect(baseline).performance({
        loop: 10,
        time: 100
      }, done)
    })

    it('firing listeners on observables (' + amount + ')', function (done) {
      this.timeout(50e3)
      expect(function () {
        var len = arr.length
        for (let i = 0; i < len; i++) {
          arr[i].b.val = i * 2
        }
      }).performance({
        loop: 10,
        time: 100,
        before: baseline
      }, done)
    })

    it('creating observables add listeners using context (' + amount + ')', function (done) {
      this.timeout(50e3)
      var thing = new Observable({
        b: true,
        on: { data () {} }
      })
      var Thing = thing.Constructor
      expect(function () {
        arr = []
        for (var i = 0; i < amount; i++) {
          var a = new Thing({
            val: i
          })
          arr.push(a)
        }
      }).performance({
        loop: 10,
        time: 100
      }, done)
    })
  })

  describe('Existing field', function () {
    function observable () {
      arr = []
      for (var i = 0; i < amount; i++) {
        var a = new Observable({ //eslint-disable-line
          b: true
        })
        a.subscribe({
          b: true
        }, function () {})
        arr.push(a)
      }
    }

    it('creating observables and subscribing on existing field (' + amount + ')', function (done) {
      this.timeout(50e3)
      expect(observable).performance({
        loop: 10,
        time: 100
      }, done)
    })

    it('firing listeners on observables and subscribing on existing field (' + amount + ')', function (done) {
      this.timeout(50e3)
      expect(function () {
        var len = arr.length
        for (let i = 0; i < len; i++) {
          arr[i].b.val = i * 2
        }
      }).performance({
        loop: 10,
        time: 100,
        before: observable
      }, done)
    })

    it('creating observables subscribing using context (' + amount + ')', function (done) {
      this.timeout(50e3)
      var thing = new Observable({
        b: true
      })
      thing.subscribe({
        b: true
      })
      var Thing = thing.Constructor
      expect(function () {
        arr = []
        for (var i = 0; i < amount; i++) {
          var a = new Thing({
            b: i
          })
          arr.push(a)
        }
      }).performance({
        loop: 10,
        time: 100
      }, done)
    })
  })
})
<|endoftext|>


<commit_before>/**
 * @name      ElkArte Forum
 * @copyright ElkArte Forum contributors
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause
 *
 * @version 1.0 Beta 2
 *
 * Ajaxifying likes - WIP
 */

/**
 * Simply invoke the constructor by calling likePosts
 */
(function() {
	function likePosts() {}

	/**
	 * This is bound to a click event on the page like/unlike buttons
	 * likePosts.prototype.likeUnlikePosts(event, messageID, topidID)
	 */
	likePosts.prototype = function() {
		var init = '',
			likeUnlikePosts = function(e, mId, tId) {
				var messageId = parseInt(mId, 10),
					topicId = parseInt(tId, 10),
					subAction = '',
					check = $(e.target).attr('class');

				// Set the subAction to what they are doing
				if (check.indexOf('unlike_button') >= 0)
					subAction = 'unlikepost';
				else
					subAction = 'likepost';

				// Need to know what we are liking of course
				var values = {
					'topic': topicId,
					'msg': messageId
				};

				// Make the ajax call to the likes system
				$.ajax({
					url: elk_scripturl + '?action=likes;sa=' + subAction + ';api;' + elk_session_var + '=' + elk_session_id,
					type: 'POST',
					dataType: 'json',
					data: values,
					cache: false
				})
				.done(function(resp) {
					// json response from the server says success?
					if (resp.result === true)
					{
						// Update the page with the new likes information
						updateUi({
							'elem': $(e.target),
							'count': resp.count,
							'text': resp.text,
							'title': resp.title,
							'action': subAction
						});
					}
					// Some failure trying to process the request
					else
						handleError(resp);
				})
				.fail(function(err, textStatus, errorThrown) {
					// Some failure sending the request
					console.log(textStatus);
					console.log(errorThrown);
					handleError(err);
				});
			},

			/**
			 * Does the actual update to the page the user is viewing
			 *
			 * @param {object} params object of new values from the ajax request
			 */
			updateUi = function(params)
			{
				var currentClass = (params.action === 'unlikepost') ? 'unlike_button' : 'like_button',
					nextClass = (params.action === 'unlikepost') ? 'like_button' : 'unlike_button';

				// Swap the button class as needed, update the text for the hover
				$(params.elem).removeClass(currentClass).addClass(nextClass);
				$(params.elem).html(' ' + params.text);
				$(params.elem).attr('title', params.title);

				// Changed the title text, update the tooltips
				$("." + nextClass).SiteTooltip({hoverIntent: {sensitivity: 10, interval: 150, timeout: 50}});
			},

			/**
			 * Show a non modal error box when something goes wrong with
			 * sending the request or processing it
			 *
			 * @param {type} params
			 */
			handleError = function(params)
			{
				var str = '

Error in Likes

' + params.data + '

OK

';
				$('body').append(str);

				var screenWidth = $(window).width(),
					screenHeight = $(window).height(),
					popupHeight = $('.floating_error').outerHeight(),
					popupWidth = $('.floating_error').outerWidth(),
					topPopUpOffset = (screenHeight - popupHeight) / 2,
					leftPopUpOffset = (screenWidth - popupWidth) / 2;

				$('.floating_error').css({
					top: topPopUpOffset + 'px',
					left: leftPopUpOffset + 'px'
				});

				$(document).one('click keyup', removeOverlay);
			},

			/**
			 * Clear the error box from the screen by click or escape key
			 *
			 * @param {type} e
			 */
			removeOverlay = function(e)
			{
				if (typeof(e) === 'undefined' && this.timeoutTimer === null)
					return false;
				else if ((e.type === 'keyup' && e.keyCode === 27) || e.type === 'click')
				{
					$('.floating_error').remove();
					$('.floating_error').unbind('click');
					$(document).unbind('click', removeOverlay);
					$(document).unbind('keyup', removeOverlay);
				}
			};

		return {
			likeUnlikePosts: likeUnlikePosts
		};
	}();

	// instead of this, we can use namespace too
	this.likePosts = likePosts;
}());<commit_msg>removed excessive check<commit_after>/**
 * @name      ElkArte Forum
 * @copyright ElkArte Forum contributors
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause
 *
 * @version 1.0 Beta 2
 *
 * Ajaxifying likes - WIP
 */

/**
 * Simply invoke the constructor by calling likePosts
 */
(function() {
	function likePosts() {}

	/**
	 * This is bound to a click event on the page like/unlike buttons
	 * likePosts.prototype.likeUnlikePosts(event, messageID, topidID)
	 */
	likePosts.prototype = function() {
		var init = '',
			likeUnlikePosts = function(e, mId, tId) {
				var messageId = parseInt(mId, 10),
					topicId = parseInt(tId, 10),
					subAction = '',
					check = $(e.target).attr('class');

				// Set the subAction to what they are doing
				if (check.indexOf('unlike_button') >= 0)
					subAction = 'unlikepost';
				else
					subAction = 'likepost';

				// Need to know what we are liking of course
				var values = {
					'topic': topicId,
					'msg': messageId
				};

				// Make the ajax call to the likes system
				$.ajax({
					url: elk_scripturl + '?action=likes;sa=' + subAction + ';api;' + elk_session_var + '=' + elk_session_id,
					type: 'POST',
					dataType: 'json',
					data: values,
					cache: false
				})
				.done(function(resp) {
					// json response from the server says success?
					if (resp.result === true)
					{
						// Update the page with the new likes information
						updateUi({
							'elem': $(e.target),
							'count': resp.count,
							'text': resp.text,
							'title': resp.title,
							'action': subAction
						});
					}
					// Some failure trying to process the request
					else
						handleError(resp);
				})
				.fail(function(err, textStatus, errorThrown) {
					// Some failure sending the request
					console.log(textStatus);
					console.log(errorThrown);
					handleError(err);
				});
			},

			/**
			 * Does the actual update to the page the user is viewing
			 *
			 * @param {object} params object of new values from the ajax request
			 */
			updateUi = function(params)
			{
				var currentClass = (params.action === 'unlikepost') ? 'unlike_button' : 'like_button',
					nextClass = (params.action === 'unlikepost') ? 'like_button' : 'unlike_button';

				// Swap the button class as needed, update the text for the hover
				$(params.elem).removeClass(currentClass).addClass(nextClass);
				$(params.elem).html(' ' + params.text);
				$(params.elem).attr('title', params.title);

				// Changed the title text, update the tooltips
				$("." + nextClass).SiteTooltip({hoverIntent: {sensitivity: 10, interval: 150, timeout: 50}});
			},

			/**
			 * Show a non modal error box when something goes wrong with
			 * sending the request or processing it
			 *
			 * @param {type} params
			 */
			handleError = function(params)
			{
				var str = '

Error in Likes

' + params.data + '

OK

';
				$('body').append(str);

				var screenWidth = $(window).width(),
					screenHeight = $(window).height(),
					popupHeight = $('.floating_error').outerHeight(),
					popupWidth = $('.floating_error').outerWidth(),
					topPopUpOffset = (screenHeight - popupHeight) / 2,
					leftPopUpOffset = (screenWidth - popupWidth) / 2;

				$('.floating_error').css({
					top: topPopUpOffset + 'px',
					left: leftPopUpOffset + 'px'
				});

				$(document).one('click keyup', removeOverlay);
			},

			/**
			 * Clear the error box from the screen by click or escape key
			 *
			 * @param {type} e
			 */
			removeOverlay = function(e)
			{
				if (typeof(e) === 'undefined')
					return false;
				else if ((e.type === 'keyup' && e.keyCode === 27) || e.type === 'click')
				{
					$('.floating_error').remove();
					$('.floating_error').unbind('click');
					$(document).unbind('click', removeOverlay);
					$(document).unbind('keyup', removeOverlay);
				}
			};

		return {
			likeUnlikePosts: likeUnlikePosts
		};
	}();

	// instead of this, we can use namespace too
	this.likePosts = likePosts;
}());
<|endoftext|>


<commit_before>var gulp   = require('gulp');
var jshint = require('gulp-jshint');
var jscs   = require('gulp-jscs');
var babel  = require('gulp-babel');
var rename = require('gulp-rename');
var uglify = require('gulp-uglify');
var header = require('gulp-header');
var pkg    = require('./package.json');

var banner = '/*! <%= pkg.name %> - v<%= pkg.version %> | <%= new Date().getFullYear() %> */\n';

gulp.task('build', function() {
    return gulp.src('./src/d3-funnel/d3-funnel.js')
        .pipe(jshint())
        .pipe(jshint.reporter('default'))
        .pipe(jshint.reporter('fail'))
        .pipe(jscs({
            esnext: true,
            verbose: true
        }))
        .pipe(babel())
        .pipe(gulp.dest('./dist/'))
        .pipe(rename({
            extname: '.min.js'}
        ))
        .pipe(uglify())
        .pipe(header(banner, {
            pkg: pkg
        }))
        .pipe(gulp.dest('./dist/'));
});

gulp.task('default', ['build']);
<commit_msg>Fix issue with gulp-jscs not using options in .jscsrc<commit_after>var gulp   = require('gulp');
var jshint = require('gulp-jshint');
var jscs   = require('gulp-jscs');
var babel  = require('gulp-babel');
var rename = require('gulp-rename');
var uglify = require('gulp-uglify');
var header = require('gulp-header');
var pkg    = require('./package.json');

var banner = '/*! <%= pkg.name %> - v<%= pkg.version %> | <%= new Date().getFullYear() %> */\n';

gulp.task('build', function() {
	return gulp.src('./src/d3-funnel/d3-funnel.js')
		.pipe(jshint())
		.pipe(jshint.reporter('default'))
		.pipe(jshint.reporter('fail'))
		.pipe(jscs({
			configPath: './.jscsrc'
		}))
		.pipe(babel())
		.pipe(gulp.dest('./dist/'))
		.pipe(rename({
				extname: '.min.js'}
		))
		.pipe(uglify())
		.pipe(header(banner, {
			pkg: pkg
		}))
		.pipe(gulp.dest('./dist/'));
});

gulp.task('default', ['build']);
<|endoftext|>


<commit_before>var canvas = document.getElementById('game');
var context = canvas.getContext('2d');
var dino_img_right = document.getElementById("dino_right");
var dino_img_left = document.getElementById("dino_left");
dino_img_right.style.visibility = 'hidden';
dino_img_left.style.visibility = 'hidden';

function Dinosaur() {
  this.height = 25;
  this.width = 25;
  this.x = canvas.width / 2;
  this.y = canvas.height - this.height;
  this.status = null;
  this.direction = "right";
}

Dinosaur.prototype.mouthX = function() {
  if (this.direction === "right"){
    return this.x+this.width;
  } else {
    return this.x;
  }
}

Dinosaur.prototype.mouthY = function() {
  return this.y+this.height/2;
}

function Bubble(x, y, direction){
  this.x = x;
  this.y = y;
  this.direction = direction;
  this.status = "new";
  this.height = 5;
  this.width = 5;
}

Bubble.prototype.draw = function(direction) {
  context.fillRect(this.x, this.y, this.width, this.height);
  var bubble = this;
  var count = 0;
  if (this.status === "new") {
    this.status = "done";
    if (direction === "right") {
      var floatRight = function(that) {
        if (count < 50 && that.x < canvas.width - 5) {
          count++;
          that.x++;
          setTimeout(floatRight, 25, that);
        } else if ((count >= 50 && that.y > 0) || (that.x === canvas.width - 5 && that.y > 0)){
          count++;
          that.y--;
          setTimeout(floatRight, 25, that);
        }
      };
      floatRight(bubble);
    } else if (direction === "left") {
      var floatLeft = function(that) {
        if (count < 50 && that.x > 0) {
          count++;
          that.x--;
          setTimeout(floatLeft, 25, that);
        } else if ((count >= 50 && that.y > 0) || (that.x === 0 && that.y > 0)){
          count++;
          that.y--;
          setTimeout(floatLeft, 25, that);
        }
      };
      floatLeft(bubble);
    }
  }
  return this;
};

var bubbles = [];

Dinosaur.prototype.draw = function() {
  // context.fillRect(this.x, this.y, this.width, this.height);
  var dino_img;
  if (this.direction === "right") {
    dino_img = dino_img_right;
  } else {
    dino_img = dino_img_left;
  }
  context.drawImage(dino_img, this.x, this.y, this.width, this.height);
  return this;
};

Dinosaur.prototype.left = function() {
  if (this.x > 0) {
    this.x -= 5;
    this.direction = "left";
  }
  return this;
};

Dinosaur.prototype.right = function() {
  if (this.x < canvas.width - 10) {
    this.x += 5;
    this.direction = "right";
  }
  return this;
};

Dinosaur.prototype.jump = function() {
  var count = 0;
  var dino = this;
  var increment = function(that){
    that.status = "jumping";
    if ( count < 5 ){
      count++;
      that.y -= 6;
      setTimeout(increment, 50, that);
    } else if (count >= 5 && count < 10) {
      count++;
      that.y += 6;
      setTimeout(increment, 50, that);
    } else if (count === 10) {
      that.status = null;
    }
  };
  increment(dino);
  return this;
};

var dino = new Dinosaur();

document.addEventListener('keydown', function(key) {
  if (key.keyCode === 65 ) {
    dino.left();
  } else if (key.keyCode === 68) {
    dino.right();
  } else if (key.keyCode === 87 || key.keyCode === 75) {
    if (!dino.status) {
      dino.jump();
    }
  } else if (key.keyCode === 32 || key.keyCode === 74) {
    var bubble = new Bubble(dino.mouthX(), dino.mouthY(), dino.direction);
    bubbles.push(bubble);
  }
});

requestAnimationFrame(function gameLoop(){
  context.clearRect(0, 0, canvas.width, canvas.height);
  dino.draw();
  bubbles.forEach(function(bubble){
    bubble.draw(dino.direction);
  });
  requestAnimationFrame(gameLoop);
});
<commit_msg>Refactor move methods to not use setTimeout<commit_after>var canvas = document.getElementById('game');
var context = canvas.getContext('2d');

// DINOSAUR stuff --------------------------------------------------------------
var dino_img_right = document.getElementById("dino_right");
var dino_img_left = document.getElementById("dino_left");
dino_img_right.style.visibility = 'hidden';
dino_img_left.style.visibility = 'hidden';

var jumpSteps = 15;
var jumpTotal = 30;
var jumpSize = jumpTotal/jumpSteps;

function Dinosaur() {
  this.height = 25;
  this.width = 25;
  this.x = canvas.width / 2;
  this.y = canvas.height - this.height;
  this.status = null;
  this.direction = "right";
  this.count = 0;
}

Dinosaur.prototype.mouthX = function() {
  if (this.direction === "right"){
    return this.x+this.width;
  } else {
    return this.x;
  }
};

Dinosaur.prototype.mouthY = function() {
  return this.y+this.height/2;
};

Dinosaur.prototype.dino_img = function() {
  if (this.direction === "right") {
    return dino_img_right;
  } else {
    return dino_img_left;
  }
};

Dinosaur.prototype.draw = function() {
  context.drawImage(this.dino_img(), this.x, this.y, this.width, this.height);
  return this;
};

Dinosaur.prototype.left = function() {
  if (this.x > 0) {
    this.x -= 5;
    this.direction = "left";
  }
  return this;
};

Dinosaur.prototype.right = function() {
  if (this.x < canvas.width - 10) {
    this.x += 5;
    this.direction = "right";
  }
  return this;
};

Dinosaur.prototype.move = function() {
  if (this.status === "jumping") {
    this.jump();
  }
  return this;
};

Dinosaur.prototype.jump = function() {
  if ( this.count < jumpSteps ){
    this.count++;
    this.y -= jumpSize;
  } else if (this.count >= jumpSteps && this.count < 2*jumpSteps) {
    this.count++;
    this.y += jumpSize;
  } else if (this.count === 2*jumpSteps) {
    this.status = null;
    this.count = 0;
  }
  return this;
};

// mMM BUBBLES  ----------------------------------------------------------------
function Bubble(x, y, direction){
  this.x = x;
  this.y = y;
  this.direction = direction;
  this.status = "new";
  this.height = 5;
  this.width = 5;
  if (direction === "right") {
    this.xInc = 1;
  } else {
    this.xInc = -1;
  }
  this.count = 0;
}

Bubble.prototype.draw = function() {
  context.fillRect(this.x, this.y, this.width, this.height);
  return this;
};

Bubble.prototype.move = function() {
  if (this.status === "new") {
    this.x+=this.xInc;
  } else if (this.status === "floating") {
    this.y--;
  }
  this.count++;

  if (this.x >= (canvas.width - 5) || this.x <= 0 || this.count === 50) {
    this.status = "floating";
  }

  if (this.y <= 0) {
    this.status = "done";
  }

  return this;
};

// THE GAME STUFF --------------------------------------------------------------

var dino = new Dinosaur();
var bubbles = [];

document.addEventListener('keydown', function(key) {
  if (key.keyCode === 65 ) {
    dino.left();
  } else if (key.keyCode === 68) {
    dino.right();
  } else if (key.keyCode === 87 || key.keyCode === 75) {
    if (!dino.status) { dino.status = "jumping"; }
  } else if (key.keyCode === 32 || key.keyCode === 74) {
    var bubble = new Bubble(dino.mouthX(), dino.mouthY(), dino.direction);
    bubbles.push(bubble);
  }
});

requestAnimationFrame(function gameLoop(){
  context.clearRect(0, 0, canvas.width, canvas.height);
  dino.move().draw();
  bubbles.forEach(function(bubble){
    bubble.move().draw();
  });
  requestAnimationFrame(gameLoop);
});
<|endoftext|>