<commit_before>/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
/*global require, exports, assertTrue, assertEqual, fail */

////////////////////////////////////////////////////////////////////////////////
/// @brief aql test helper functions
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2011-2012 triagens GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Copyright 2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

var internal = require("internal");
var arangodb = require("org/arangodb");
var _ = require("underscore");

// -----------------------------------------------------------------------------
// --SECTION--                                         AQL test helper functions
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief normalise a single row result
////////////////////////////////////////////////////////////////////////////////

function normalizeRow (row, recursive) {
  if (row !== null &&
      typeof row === 'object' &&
      ! Array.isArray(row)) {
    var keys = Object.keys(row);

    keys.sort();

    var i, n = keys.length, out = { };
    for (i = 0; i < n; ++i) {
      var key = keys[i];

      if (key[0] !== '_') {
        out[key] = row[key];
      }
    }

    return out;
  }

  if (recursive && Array.isArray(row)) {
    row = row.map(normalizeRow);
  }

  return row;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief return the parse results for a query
////////////////////////////////////////////////////////////////////////////////

function getParseResults (query) {
  return internal.AQL_PARSE(query);
}

////////////////////////////////////////////////////////////////////////////////
/// @brief assert a specific error code when parsing a query
////////////////////////////////////////////////////////////////////////////////

function assertParseError (errorCode, query) {
  try {
    getParseResults(query);
    fail();
  }
  catch (e) {
    assertTrue(e.errorNum !== undefined, "unexpected error format");
    assertEqual(errorCode, e.errorNum, "unexpected error code");
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief return the results of a query explanation
////////////////////////////////////////////////////////////////////////////////

function getQueryExplanation (query, bindVars) {
  var result = internal.AQL_EXPLAIN(query, bindVars);

  return result;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief return the results of a modify-query
////////////////////////////////////////////////////////////////////////////////

function getModifyQueryResults (query, bindVars) {
  var queryResult = internal.AQL_QUERY(query, bindVars);

  if (queryResult instanceof arangodb.ArangoCursor) {
    return queryResult.getExtra();
  }

  return queryResult.extra;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief return the results of a query
////////////////////////////////////////////////////////////////////////////////

function getRawQueryResults (query, bindVars) {
  var queryResult = internal.AQL_QUERY(query, bindVars, {
    count: true,
    batchSize : 3000
  });

  if (! (queryResult instanceof arangodb.ArangoCursor)) {
    if (typeof queryResult === 'object' && queryResult.hasOwnProperty('docs')) {
      return queryResult.docs;
    }

    return queryResult;
  }

  var rows = [ ];
  var func = function (row) {
    rows.push(row);
  };

  while (queryResult.hasNext()) {
    queryResult.toArray().forEach(func);
  }
  return rows;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief return the results of a query, version for AQL2
////////////////////////////////////////////////////////////////////////////////

function getRawQueryResultsAQL2 (query, bindVars) {
  var queryResult;
  if (typeof bindVars == "object") {
    queryResult = AQL_EXECUTE(query, bindVars, {
      count: true,
      batchSize : 3000
    });
  }
  else {
    queryResult = AQL_EXECUTE(query, {}, {
      count: true,
      batchSize : 3000
    });
  }
  return queryResult.json;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief return the results of a query in a normalised way
////////////////////////////////////////////////////////////////////////////////

function getQueryResults (query, bindVars, recursive) {
  var result = getRawQueryResults(query, bindVars);

  if (Array.isArray(result)) {
    result = result.map(function (row) {
      return normalizeRow(row, recursive);
    });
  }

  return result;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief return the results of a query in a normalised way, AQL2 version
////////////////////////////////////////////////////////////////////////////////

function getQueryResultsAQL2 (query, bindVars, recursive) {
  var result = getRawQueryResultsAQL2(query, bindVars);

  if (Array.isArray(result)) {
    result = result.map(function (row) {
      return normalizeRow(row, recursive);
    });
  }

  return result;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief return the results of a query in a normalised way, version to
/// run both the old and the new (AQL2) query
////////////////////////////////////////////////////////////////////////////////

function getQueryResults2 (query, bindVars, recursive) {
  var result = getQueryResults(query, bindVars, recursive);
  var result2 = getQueryResultsAQL2(query, bindVars, recursive);

  if (! _.isEqual(result, result2)) {
    require("internal").print("Old and new AQL return different results!");
    require("internal").print("Old result:\n", result);
    require("internal").print("New result:\n", result2);

    require("internal").print("Failed Query was:\n", query);

    throw "Results between AQL and AQL2 differ";
  }

  return result;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief assert a specific error code when running a query
////////////////////////////////////////////////////////////////////////////////

function assertQueryError (errorCode, query, bindVars) {
  try {
    getQueryResults(query, bindVars);
    fail();
  }
  catch (e) {
    assertTrue(e.errorNum !== undefined, "unexpected error format");
    assertEqual(errorCode, e.errorNum, "unexpected error code");
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief assert a specific error code when running a query, case of both
/// new and old AQL
////////////////////////////////////////////////////////////////////////////////

function assertQueryError2 (errorCode, query, bindVars) {
  try {
    getQueryResults(query, bindVars);
    fail();
  }
  catch (e) {
    assertTrue(e.errorNum !== undefined, "unexpected error format");
    assertEqual(errorCode, e.errorNum, "unexpected error code");
  }
  try {
    getQueryResultsAQL2(query, bindVars);
    fail();
  }
  catch (e2) {
    assertTrue(e2.errorNum !== undefined, "unexpected error format");
    assertEqual(errorCode, e2.errorNum, "unexpected error code");
  }
}

// -----------------------------------------------------------------------------
// --SECTION--                                                    module exports
// -----------------------------------------------------------------------------

exports.getParseResults       = getParseResults;
exports.assertParseError      = assertParseError;
exports.getQueryExplanation   = getQueryExplanation;
exports.getModifyQueryResults = getModifyQueryResults;
exports.getRawQueryResults    = getRawQueryResults;
exports.getQueryResults       = getQueryResults;
exports.getQueryResults2      = getQueryResults2;
exports.assertQueryError      = assertQueryError;
exports.assertQueryError2     = assertQueryError2;

// -----------------------------------------------------------------------------
// --SECTION--                                                       END-OF-FILE
// -----------------------------------------------------------------------------

// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}\\)"
// End:
<commit_msg>in case of we don't like the error number, output it plus the error message.<commit_after>/*jslint indent: 2, nomen: true, maxlen: 100, sloppy: true, vars: true, white: true, plusplus: true */
/*global require, exports, assertTrue, assertEqual, fail */

////////////////////////////////////////////////////////////////////////////////
/// @brief aql test helper functions
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2011-2012 triagens GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Copyright 2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

var internal = require("internal");
var arangodb = require("org/arangodb");
var _ = require("underscore");

// -----------------------------------------------------------------------------
// --SECTION--                                         AQL test helper functions
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @brief normalise a single row result
////////////////////////////////////////////////////////////////////////////////

function normalizeRow (row, recursive) {
  if (row !== null &&
      typeof row === 'object' &&
      ! Array.isArray(row)) {
    var keys = Object.keys(row);

    keys.sort();

    var i, n = keys.length, out = { };
    for (i = 0; i < n; ++i) {
      var key = keys[i];

      if (key[0] !== '_') {
        out[key] = row[key];
      }
    }

    return out;
  }

  if (recursive && Array.isArray(row)) {
    row = row.map(normalizeRow);
  }

  return row;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief return the parse results for a query
////////////////////////////////////////////////////////////////////////////////

function getParseResults (query) {
  return internal.AQL_PARSE(query);
}

////////////////////////////////////////////////////////////////////////////////
/// @brief assert a specific error code when parsing a query
////////////////////////////////////////////////////////////////////////////////

function assertParseError (errorCode, query) {
  try {
    getParseResults(query);
    fail();
  }
  catch (e) {
    assertTrue(e.errorNum !== undefined, "unexpected error format");
    assertEqual(errorCode, e.errorNum, "unexpected error code (" + e.errorMessage + "): ");
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief return the results of a query explanation
////////////////////////////////////////////////////////////////////////////////

function getQueryExplanation (query, bindVars) {
  var result = internal.AQL_EXPLAIN(query, bindVars);

  return result;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief return the results of a modify-query
////////////////////////////////////////////////////////////////////////////////

function getModifyQueryResults (query, bindVars) {
  var queryResult = internal.AQL_QUERY(query, bindVars);

  if (queryResult instanceof arangodb.ArangoCursor) {
    return queryResult.getExtra();
  }

  return queryResult.extra;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief return the results of a query
////////////////////////////////////////////////////////////////////////////////

function getRawQueryResults (query, bindVars) {
  var queryResult = internal.AQL_QUERY(query, bindVars, {
    count: true,
    batchSize : 3000
  });

  if (! (queryResult instanceof arangodb.ArangoCursor)) {
    if (typeof queryResult === 'object' && queryResult.hasOwnProperty('docs')) {
      return queryResult.docs;
    }

    return queryResult;
  }

  var rows = [ ];
  var func = function (row) {
    rows.push(row);
  };

  while (queryResult.hasNext()) {
    queryResult.toArray().forEach(func);
  }
  return rows;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief return the results of a query, version for AQL2
////////////////////////////////////////////////////////////////////////////////

function getRawQueryResultsAQL2 (query, bindVars) {
  var queryResult;
  if (typeof bindVars == "object") {
    queryResult = AQL_EXECUTE(query, bindVars, {
      count: true,
      batchSize : 3000
    });
  }
  else {
    queryResult = AQL_EXECUTE(query, {}, {
      count: true,
      batchSize : 3000
    });
  }
  return queryResult.json;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief return the results of a query in a normalised way
////////////////////////////////////////////////////////////////////////////////

function getQueryResults (query, bindVars, recursive) {
  var result = getRawQueryResults(query, bindVars);

  if (Array.isArray(result)) {
    result = result.map(function (row) {
      return normalizeRow(row, recursive);
    });
  }

  return result;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief return the results of a query in a normalised way, AQL2 version
////////////////////////////////////////////////////////////////////////////////

function getQueryResultsAQL2 (query, bindVars, recursive) {
  var result = getRawQueryResultsAQL2(query, bindVars);

  if (Array.isArray(result)) {
    result = result.map(function (row) {
      return normalizeRow(row, recursive);
    });
  }

  return result;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief return the results of a query in a normalised way, version to
/// run both the old and the new (AQL2) query
////////////////////////////////////////////////////////////////////////////////

function getQueryResults2 (query, bindVars, recursive) {
  var result = getQueryResults(query, bindVars, recursive);
  var result2 = getQueryResultsAQL2(query, bindVars, recursive);

  if (! _.isEqual(result, result2)) {
    require("internal").print("Old and new AQL return different results!");
    require("internal").print("Old result:\n", result);
    require("internal").print("New result:\n", result2);

    require("internal").print("Failed Query was:\n", query);

    throw "Results between AQL and AQL2 differ";
  }

  return result;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief assert a specific error code when running a query
////////////////////////////////////////////////////////////////////////////////

function assertQueryError (errorCode, query, bindVars) {
  try {
    getQueryResults(query, bindVars);
    fail();
  }
  catch (e) {
    assertTrue(e.errorNum !== undefined, "unexpected error format");
    assertEqual(errorCode, e.errorNum, "unexpected error code (" + e.errorMessage + "): ");
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief assert a specific error code when running a query, case of both
/// new and old AQL
////////////////////////////////////////////////////////////////////////////////

function assertQueryError2 (errorCode, query, bindVars) {
  try {
    getQueryResults(query, bindVars);
    fail();
  }
  catch (e) {
    assertTrue(e.errorNum !== undefined, "unexpected error format");
    assertEqual(errorCode, e.errorNum, "unexpected error code (" + e.errorMessage + "): ");
  }
  try {
    getQueryResultsAQL2(query, bindVars);
    fail();
  }
  catch (e2) {
    assertTrue(e2.errorNum !== undefined, "unexpected error format");
    assertEqual(errorCode, e2.errorNum, "unexpected error code (" + e2.errorMessage + "): ");
  }
}

// -----------------------------------------------------------------------------
// --SECTION--                                                    module exports
// -----------------------------------------------------------------------------

exports.getParseResults       = getParseResults;
exports.assertParseError      = assertParseError;
exports.getQueryExplanation   = getQueryExplanation;
exports.getModifyQueryResults = getModifyQueryResults;
exports.getRawQueryResults    = getRawQueryResults;
exports.getQueryResults       = getQueryResults;
exports.getQueryResults2      = getQueryResults2;
exports.assertQueryError      = assertQueryError;
exports.assertQueryError2     = assertQueryError2;

// -----------------------------------------------------------------------------
// --SECTION--                                                       END-OF-FILE
// -----------------------------------------------------------------------------

// Local Variables:
// mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}\\)"
// End:
<|endoftext|>


<commit_before>var creep_combat = {

	/** @param {Creep} creep **/
	run: function(creep) {
		//Defensive-focused attack
		//Only run this code if the room is being invaded, remain offline otherwise.
		//(Saves running excess finds in peacetime)
		if (creep.hits < creep.hitsMax) {
			creep.heal(creep);
		}

		if (Memory.roomsUnderAttack.indexOf(creep.room.name) != -1) {
			//Move towards Foe, stop at rampart
			var lookResult = creep.pos.lookFor(LOOK_STRUCTURES);
			var Foe = creep.pos.findInRange(FIND_HOSTILE_CREEPS, 50, {
				filter: (eCreep) => (!Memory.whiteList.includes(eCreep.owner.username))
			});
			var closeFoe = creep.pos.findClosestByRange(FIND_HOSTILE_CREEPS, {
				filter: (eCreep) => (!Memory.whiteList.includes(eCreep.owner.username))
			});

			var closestTower = creep.pos.findInRange(FIND_STRUCTURES, 20, {
				filter: (structure) => {
					return (structure.structureType == STRUCTURE_TOWER);
				}
			});

			if (Foe.length) {
				Foe.sort(targetOther);
			}
			if (closeFoe && closestTower.length) {
				creep.rangedAttack(closeFoe);
				var attackResult = creep.attack(closeFoe);
				if (lookResult.length) {
					if (Foe[0].getActiveBodyparts(ATTACK) == 0 && Foe[0].getActiveBodyparts(RANGED_ATTACK) == 0) {
						creep.moveTo(Foe[0], {
							maxRooms: 1
						});
					} else if (lookResult[0].structureType != STRUCTURE_RAMPART) {
						creep.moveTo(closeFoe, {
							maxRooms: 1
						});
					}
				} else if (attackResult == ERR_NOT_IN_RANGE) {
					creep.moveTo(closeFoe, {
						maxRooms: 1
					});
				}
			} else if (Foe.length) {
				creep.rangedAttack(closeFoe);
				var attackResult = creep.attack(closeFoe);
				creep.rangedAttack(Foe[0]);
				creep.attack(Foe[0]);
				var homeSpawn = Game.getObjectById(creep.memory.fromSpawn);
				if (homeSpawn) {
					if (Foe[0].getActiveBodyparts(ATTACK) == 0 && Foe[0].getActiveBodyparts(RANGED_ATTACK) == 0) {
						creep.moveTo(Foe[0], {
							maxRooms: 1
						});
					} else {
						if (creep.room.controller.level >= 5) {
							if (attackResult == OK && lookResult.length && lookResult[0].structureType == STRUCTURE_RAMPART) {

							} else {
								creep.moveTo(Foe[0], {
									maxRooms: 1
								});
							}
						} else {
							if (lookResult.length && lookResult[0].structureType == STRUCTURE_RAMPART) {

							} else if (homeSpawn) {
								creep.moveTo(homeSpawn, {
									maxRooms: 1
								});
							}
						}
					}
				}
			} else {
				var homeSpawn = Game.getObjectById(creep.memory.fromSpawn)
				if (lookResult.length && lookResult[0].structureType == STRUCTURE_RAMPART) {

				} else if (homeSpawn) {
					creep.moveTo(homeSpawn);
				}
			}
		} else {
			var lookResult = creep.pos.lookFor(LOOK_STRUCTURES);
			var homeSpawn = Game.getObjectById(creep.memory.fromSpawn)
			if (lookResult.length && lookResult[0].structureType == STRUCTURE_RAMPART) {

			} else if (homeSpawn) {
				creep.moveTo(homeSpawn);
			}
		}
	}
};

function targetOther(a, b) {
	if (a.getActiveBodyparts(HEAL) > b.getActiveBodyparts(HEAL))
		return 1;
	if (a.getActiveBodyparts(HEAL) < b.getActiveBodyparts(HEAL))
		return -1;
	return 0;
}

module.exports = creep_combat;<commit_msg>defender tweaks<commit_after>var creep_combat = {

	/** @param {Creep} creep **/
	run: function(creep) {
		//Defensive-focused attack
		//Only run this code if the room is being invaded, remain offline otherwise.
		//(Saves running excess finds in peacetime)
		if (creep.hits < creep.hitsMax) {
			creep.heal(creep);
		}

		if (Memory.roomsUnderAttack.indexOf(creep.room.name) != -1) {
			//Move towards Foe, stop at rampart
			var lookResult = creep.pos.lookFor(LOOK_STRUCTURES);
			var Foe = creep.pos.findInRange(FIND_HOSTILE_CREEPS, 50, {
				filter: (eCreep) => (!Memory.whiteList.includes(eCreep.owner.username))
			});
			var closeFoe = creep.pos.findClosestByRange(FIND_HOSTILE_CREEPS, {
				filter: (eCreep) => (!Memory.whiteList.includes(eCreep.owner.username))
			});

			if (Foe.length) {
				Foe.sort(targetOther);
			}
			if (closeFoe) {
				creep.rangedAttack(closeFoe);
				var attackResult = creep.attack(closeFoe);
				if (lookResult.length) {
					if (Foe[0].getActiveBodyparts(ATTACK) == 0 && Foe[0].getActiveBodyparts(RANGED_ATTACK) == 0) {
						creep.moveTo(Foe[0], {
							maxRooms: 1
						});
					} else if (lookResult[0].structureType != STRUCTURE_RAMPART) {
						creep.moveTo(closeFoe, {
							maxRooms: 1
						});
					}
				} else if (attackResult == ERR_NOT_IN_RANGE) {
					creep.moveTo(closeFoe, {
						maxRooms: 1
					});
				}
			}
		} else {
			var lookResult = creep.pos.lookFor(LOOK_STRUCTURES);
			var homeSpawn = Game.getObjectById(creep.memory.fromSpawn)
			if (lookResult.length && lookResult[0].structureType == STRUCTURE_RAMPART) {

			} else if (homeSpawn) {
				creep.moveTo(homeSpawn);
			}
		}
	}
};

function targetOther(a, b) {
	if (a.getActiveBodyparts(HEAL) > b.getActiveBodyparts(HEAL))
		return 1;
	if (a.getActiveBodyparts(HEAL) < b.getActiveBodyparts(HEAL))
		return -1;
	return 0;
}

module.exports = creep_combat;<|endoftext|>


<commit_before>// (c) Copyright 2016 Hewlett Packard Enterprise Development LP
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//  http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

var request = require('request');

function NGALMClient() {
  this.sourceProperties = [
    {
      name: "ngalm_url",
      optional: false
    },
    {
      name: "client_id",
      optional: false
    },
    {
      name: "client_secret",
      optional: false
    }
  ];
  this.paramProperties = [
    {
      name: "color",
      optional: true
    },
    {
      name: "from",
      optional: false
    },
    {
      name: "message",
      optional: false
    },
    {
      name: "message_format",
      optional: true
    },
    {
      name: "notify",
      optional: true
    }
  ];
  this.validInput = true;
  this.failOnError = true;
}

NGALMClient.prototype.checkArgument = function (argumentName, argumentValue) {
  if (!argumentValue || argumentValue.length === 0) {
    console.error("Please provide a value for", argumentName);
    this.validInput = false;
  }
};

// NGALMClient.prototype.connectALM = function (source, params, done) {
//   //First auth so that we can perform API calls
//   var requestUrl = '${source.ngalm_url}/authentication/sign_in',
//     authBody = {
//       client_id: source.client_id,
//       client_secret: source.client_secret,
//     },
//     requestOptions = {
//       url: requestUrl,
//       method: "POST",
//       json: authBody
//     };

//   request(requestOptions, (err, response) => {
//     if (err || response.statusCode > 200) {
//       return done(err || response.body)
//     }

//     //return done(err);
//   });

// };

// NGALMClient.prototype.pipelineVersion = function (source, params, done) {
// //Now let's create a CI server.  This is idempotent so we should be able to do it on every check
// var requestUrl = '${source.ngalm_url}/shared_spaces/1001/workspaces/1002/ci_servers',
//   postBody = {
//     instance_id: "0",
//     name: "Concourse_test_sam",
//     url: "http://192.168.1.100:3000",
//     server_type: "Concourse server"
//   },
//   requestOptions = {
//     url: requestUrl,
//     method: "POST",
//     json: {"data":[postBody]}//,
//     // headers: {
//     // "HPSSO-HEADER-CSRF": 'figure out how to generate CSFF, if needed'
//     // }
//   };

// request(requestOptions, (err, response) => {
//   if (err || response.statusCode > 200) {
//     return done(err || response.body)
//   }

//   return done(err);
// });

};

NGALMClient.prototype.checkProperties = function (values, properties) {
  for (property of properties) {
    if (!property.optional) {
      this.checkArgument(property.name, values[property.name]);
    }
  }
};

NGALMClient.prototype.sendMessage = function (source, params, done) {
  //First auth so that we can perform API calls
  var requestUrl = '${source.ngalm_url}/authentication/sign_in',
    authBody = {
      client_id: source.client_id,
      client_secret: source.client_secret,
    },
    requestOptions = {
      url: requestUrl,
      method: "POST",
      json: authBody
    };

  request(requestOptions, (err, response) => {
    if (err || response.statusCode > 200) {
      return done(err || response.body)
    }

    //return done(err);
  });

  //Now let's create a CI server.  This is idempotent so we should be able to do it on every check
  var requestUrl = '${source.ngalm_url}/shared_spaces/1001/workspaces/1002/ci_servers',
    postBody = {
      instance_id: "0",
      name: "Concourse_test_sam",
      url: "http://192.168.1.100:3000",
      server_type: "Concourse server"
    },
    requestOptions = {
      url: requestUrl,
      method: "POST",
      json: {"data":[postBody]}//,
      // headers: {
      // "HPSSO-HEADER-CSRF": 'figure out how to generate CSFF, if needed'
      // }
    };

  request(requestOptions, (err, response) => {
    if (err || response.statusCode > 200) {
      return done(err || response.body)
    }

    return done(err);
  });
};

NGALMClient.prototype.run = function (source, params) {
  var self = this;
  if (source.fail_on_error === undefined) {
    source.fail_on_error = true;
  }

  self.failOnError = source.fail_on_error;
  self.validInput = true;

  self.checkProperties(source, this.sourceProperties);
  self.checkProperties(params, this.paramProperties);

  if (!self.validInput) {
    console.error("Please provide valid input and try again");
    return process.exit(1);
  }

  self.sendMessage(source, params, (error, result) => {
    if (error) {
      console.error(`Error sending notification. Fail on error: ${self.failOnError}`);
      console.error(error);
      if (self.failOnError) {
        process.exit(1);
      }
    }

    // Concourse expects this output from stdout, do not use console.dir
    console.log(JSON.stringify({
      version: {
        ref: "none"
      }
    }));
    process.exit(0);
  });
};

// NGALMClient.prototype.connect = function (source, params) {
//   var self = this;
//   if (source.fail_on_error === undefined) {
//     source.fail_on_error = true;
//   }

//   self.failOnError = source.fail_on_error;
//   self.validInput = true;

//   self.checkProperties(source, this.sourceProperties);
//   self.checkProperties(params, this.paramProperties);

//   if (!self.validInput) {
//     console.error("Please provide valid input and try again");
//     return process.exit(1);
//   }

//   self.connectALM(source, params, (error, result) => {
//     if (error) {
//       console.error(`Error sending notification. Fail on error: ${self.failOnError}`);
//       console.error(error);
//       if (self.failOnError) {
//         process.exit(1);
//       }
//     }
//   });
//   self.pipelineVersion(source, params, (error, result) => {
//   if (error) {
//     console.error(`Error sending notification. Fail on error: ${self.failOnError}`);
//     console.error(error);
//     if (self.failOnError) {
//       process.exit(1);
//     }
//   }
//   // Concourse expects this output from stdout, do not use console.dir
//   console.log('this should work-printing out result');
//   console.log(result);
//   console.log(JSON.stringify({
//     version: {
//       ref: "test"
//     }
//   }));
//   process.exit(0);
// });
// };

module.exports = NGALMClient;<commit_msg>simplify back down to log in, so we can get the nested callbacks going<commit_after>// (c) Copyright 2016 Hewlett Packard Enterprise Development LP
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//  http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

var request = require('request');

function NGALMClient() {
  this.sourceProperties = [
    {
      name: "ngalm_url",
      optional: false
    },
    {
      name: "client_id",
      optional: false
    },
    {
      name: "client_secret",
      optional: false
    }
  ];
  this.paramProperties = [
    {
      name: "color",
      optional: true
    },
    {
      name: "from",
      optional: false
    },
    {
      name: "message",
      optional: false
    },
    {
      name: "message_format",
      optional: true
    },
    {
      name: "notify",
      optional: true
    }
  ];
  this.validInput = true;
  this.failOnError = true;
}

NGALMClient.prototype.checkArgument = function (argumentName, argumentValue) {
  if (!argumentValue || argumentValue.length === 0) {
    console.error("Please provide a value for", argumentName);
    this.validInput = false;
  }
};

// NGALMClient.prototype.connectALM = function (source, params, done) {
//   //First auth so that we can perform API calls
//   var requestUrl = '${source.ngalm_url}/authentication/sign_in',
//     authBody = {
//       client_id: source.client_id,
//       client_secret: source.client_secret,
//     },
//     requestOptions = {
//       url: requestUrl,
//       method: "POST",
//       json: authBody
//     };

//   request(requestOptions, (err, response) => {
//     if (err || response.statusCode > 200) {
//       return done(err || response.body)
//     }

//     //return done(err);
//   });

// };

// NGALMClient.prototype.pipelineVersion = function (source, params, done) {
// //Now let's create a CI server.  This is idempotent so we should be able to do it on every check
// var requestUrl = '${source.ngalm_url}/shared_spaces/1001/workspaces/1002/ci_servers',
//   postBody = {
//     instance_id: "0",
//     name: "Concourse_test_sam",
//     url: "http://192.168.1.100:3000",
//     server_type: "Concourse server"
//   },
//   requestOptions = {
//     url: requestUrl,
//     method: "POST",
//     json: {"data":[postBody]}//,
//     // headers: {
//     // "HPSSO-HEADER-CSRF": 'figure out how to generate CSFF, if needed'
//     // }
//   };

// request(requestOptions, (err, response) => {
//   if (err || response.statusCode > 200) {
//     return done(err || response.body)
//   }

//   return done(err);
// });

};

NGALMClient.prototype.checkProperties = function (values, properties) {
  for (property of properties) {
    if (!property.optional) {
      this.checkArgument(property.name, values[property.name]);
    }
  }
};

NGALMClient.prototype.sendMessage = function (source, params, done) {
  //First auth so that we can perform API calls
  var requestUrl = '${source.ngalm_url}/authentication/sign_in',
    authBody = {
      client_id: source.client_id,
      client_secret: source.client_secret,
    },
    requestOptions = {
      url: requestUrl,
      method: "POST",
      json: authBody
    };

  request(requestOptions, (err, response) => {
    if (err || response.statusCode > 200) {
      return done(err || response.body)
    }

    return done(err);
  });

  //Now let's create a CI server.  This is idempotent so we should be able to do it on every check
  // var requestUrl = '${source.ngalm_url}/shared_spaces/1001/workspaces/1002/ci_servers',
  //   postBody = {
  //     instance_id: "0",
  //     name: "Concourse_test_sam",
  //     url: "http://192.168.1.100:3000",
  //     server_type: "Concourse server"
  //   },
  //   requestOptions = {
  //     url: requestUrl,
  //     method: "POST",
  //     json: {"data":[postBody]}//,
  //     // headers: {
  //     // "HPSSO-HEADER-CSRF": 'figure out how to generate CSFF, if needed'
  //     // }
  //   };

  // request(requestOptions, (err, response) => {
  //   if (err || response.statusCode > 200) {
  //     return done(err || response.body)
  //   }

  //   return done(err);
  // });
};

NGALMClient.prototype.run = function (source, params) {
  var self = this;
  if (source.fail_on_error === undefined) {
    source.fail_on_error = true;
  }

  self.failOnError = source.fail_on_error;
  self.validInput = true;

  self.checkProperties(source, this.sourceProperties);
  self.checkProperties(params, this.paramProperties);

  if (!self.validInput) {
    console.error("Please provide valid input and try again");
    return process.exit(1);
  }

  self.sendMessage(source, params, (error, result) => {
    if (error) {
      console.error(`Error sending notification. Fail on error: ${self.failOnError}`);
      console.error(error);
      if (self.failOnError) {
        process.exit(1);
      }
    }

    // Concourse expects this output from stdout, do not use console.dir
    console.log(JSON.stringify({
      version: {
        ref: "none"
      }
    }));
    process.exit(0);
  });
};

// NGALMClient.prototype.connect = function (source, params) {
//   var self = this;
//   if (source.fail_on_error === undefined) {
//     source.fail_on_error = true;
//   }

//   self.failOnError = source.fail_on_error;
//   self.validInput = true;

//   self.checkProperties(source, this.sourceProperties);
//   self.checkProperties(params, this.paramProperties);

//   if (!self.validInput) {
//     console.error("Please provide valid input and try again");
//     return process.exit(1);
//   }

//   self.connectALM(source, params, (error, result) => {
//     if (error) {
//       console.error(`Error sending notification. Fail on error: ${self.failOnError}`);
//       console.error(error);
//       if (self.failOnError) {
//         process.exit(1);
//       }
//     }
//   });
//   self.pipelineVersion(source, params, (error, result) => {
//   if (error) {
//     console.error(`Error sending notification. Fail on error: ${self.failOnError}`);
//     console.error(error);
//     if (self.failOnError) {
//       process.exit(1);
//     }
//   }
//   // Concourse expects this output from stdout, do not use console.dir
//   console.log('this should work-printing out result');
//   console.log(result);
//   console.log(JSON.stringify({
//     version: {
//       ref: "test"
//     }
//   }));
//   process.exit(0);
// });
// };

module.exports = NGALMClient;<|endoftext|>


<commit_before>const raven = require('raven');
const request = require('request');
const https = require('https');
const { parseError } = require('raven/lib/parsers');
const { getModules, getCulprit } = require('raven/lib/utils');
const { https: ravenHTTPSTransport } = require('raven/lib/transports');
const config = require('../support/config');

const log = require('../support/log');

raven.config();
raven.disableConsoleAlerts();
const globalSentryDSNClient = new raven.Client();

ravenHTTPSTransport.agent = https.globalAgent;

function applyContext(frame, lines) {
  const linesOfContext = 7;
  const realLine = frame.lineno - 2;
  frame.pre_context = lines.slice(Math.max(0, realLine - (linesOfContext + 1)), realLine);
  frame.context_line = lines[realLine];
  frame.post_context = lines.slice(realLine + 1, realLine + linesOfContext);
}

function getSandboxModules() {
  const modules = {};
  const hostModules = getModules();

  for (const module of config.defaultGlobalModules) {
    modules[module] = hostModules[module];
  }
  return modules;
}

function notifySentryGlobal(ctx) {
  if (!raven.dsn) {
    log.info('Does not have global sentry');
    return;
  }
  ctx.event_id = raven.generateEventId();
  raven.send(ctx, (publishErr) => {
    if (publishErr) {
      log.error('Failed to publish error into global sentry: %s', publishErr.message);
      return;
    }

    log.info('Published in global sentry');
  });
}

function filterFrames(ctx, filename, code) {
  const lines = code.split('\n');

  for (const exception of ctx.exception) {
    const frames = exception.stacktrace.frames.filter((frame) => {
      if (frame.filename !== filename) {
        return false;
      }
      applyContext(frame, lines);

      if (!frame.context_line) {
        return false;
      }

      frame.in_app = true;
      return true;
    });

    if (frames.length > 0) {
      ctx.culprit = `${filename}: ${getCulprit(frames[frames.length - 1])}`;
    } else {
      ctx.culprit = filename;
    }

    exception.stacktrace.frames = frames;
  }

  ctx.message = `${filename}: ${ctx.message}`;
}

function filterStatusCode(statusCode) {
  return statusCode !== 408 && statusCode < 500;
}

class ErrorTracker {
  constructor({ sentryDSN, filename, extra, tags, code, breadcrumbs, sentryClient }) {
    this.sentryDSN = sentryDSN;
    this.filename = filename;
    this.extra = extra;
    this.code = code;

    this.tags = tags;
    this.breadcrumbs = breadcrumbs || [];
    this.sentryClient = sentryClient || globalSentryDSNClient;
  }

  notify(err) {
    if (err.statusCode && filterStatusCode(err.statusCode)) {
      return;
    }

    parseError(err, { extra: this.extra, tags: this.tags }, (ctx) => {
      filterFrames(ctx, this.filename, this.code);

      ctx.timestamp = new Date().toISOString().split('.')[0];
      ctx.breadcrumbs = { values: this.breadcrumbs };
      ctx.modules = getSandboxModules();

      if (this.sentryDSN) {
        this.sentryClient.config(this.sentryDSN);
        ctx.event_id = this.sentryClient.generateEventId();
        this.sentryClient.send(ctx, (publishErr) => {
          if (publishErr) {
            log.error('Failed to publish error into sentry: %s', publishErr.message);
          }
        });
      }

      notifySentryGlobal(ctx);
    });
  }

  static get name() {
    return 'Sentry';
  }

  static async ping() {
    const dsn = globalSentryDSNClient.dsn;

    if (!dsn) {
      return 'SENTRY_DSN is not setted yet';
    }

    const url = `${dsn.protocol}://${dsn.host}/api/0/`;

    return new Promise((resolve, reject) => {
      request({
        url,
        timeout: 3000,
      }, (err, response) => {
        if (err) {
          reject(err);
          return;
        }

        if (response.statusCode === 200) {
          resolve('OK');
          return;
        }

        reject(new Error(`HTTP status: ${response.statusCode} requesting sentry`));
      });
    });
  }
}

module.exports = ErrorTracker;
<commit_msg>Create DSN cache to avoid posible race conditions<commit_after>const raven = require('raven');
const request = require('request');
const https = require('https');
const { parseError } = require('raven/lib/parsers');
const { getModules, getCulprit } = require('raven/lib/utils');
const { https: ravenHTTPSTransport } = require('raven/lib/transports');
const config = require('../support/config');

const log = require('../support/log');

raven.config();
raven.disableConsoleAlerts();
const globalSentryDSNClient = new raven.Client();
const cache = {};

ravenHTTPSTransport.agent = https.globalAgent;

function getRavenClient(DSN) {
  if (!cache[DSN]) {
    cache[DSN] = new raven.Client(DSN);
  }

  return cache[DSN];
}

function applyContext(frame, lines) {
  const linesOfContext = 7;
  const realLine = frame.lineno - 2;
  frame.pre_context = lines.slice(Math.max(0, realLine - (linesOfContext + 1)), realLine);
  frame.context_line = lines[realLine];
  frame.post_context = lines.slice(realLine + 1, realLine + linesOfContext);
}

function getSandboxModules() {
  const modules = {};
  const hostModules = getModules();

  for (const module of config.defaultGlobalModules) {
    modules[module] = hostModules[module];
  }
  return modules;
}

function notifySentryGlobal(ctx) {
  if (!raven.dsn) {
    log.info('Does not have global sentry');
    return;
  }
  ctx.event_id = raven.generateEventId();
  raven.send(ctx, (publishErr) => {
    if (publishErr) {
      log.error('Failed to publish error into global sentry: %s', publishErr.message);
      return;
    }

    log.info('Published in global sentry');
  });
}

function filterFrames(ctx, filename, code) {
  const lines = code.split('\n');

  for (const exception of ctx.exception) {
    const frames = exception.stacktrace.frames.filter((frame) => {
      if (frame.filename !== filename) {
        return false;
      }
      applyContext(frame, lines);

      if (!frame.context_line) {
        return false;
      }

      frame.in_app = true;
      return true;
    });

    if (frames.length > 0) {
      ctx.culprit = `${filename}: ${getCulprit(frames[frames.length - 1])}`;
    } else {
      ctx.culprit = filename;
    }

    exception.stacktrace.frames = frames;
  }

  ctx.message = `${filename}: ${ctx.message}`;
}

function filterStatusCode(statusCode) {
  return statusCode !== 408 && statusCode < 500;
}

class ErrorTracker {
  constructor({ sentryDSN, filename, extra, tags, code, breadcrumbs, sentryClient }) {
    this.sentryDSN = sentryDSN;
    this.filename = filename;
    this.extra = extra;
    this.code = code;

    this.tags = tags;
    this.breadcrumbs = breadcrumbs || [];
    this.sentryClient = sentryClient || getRavenClient(sentryDSN);
  }

  notify(err) {
    if (err.statusCode && filterStatusCode(err.statusCode)) {
      return;
    }

    parseError(err, { extra: this.extra, tags: this.tags }, (ctx) => {
      filterFrames(ctx, this.filename, this.code);

      ctx.timestamp = new Date().toISOString().split('.')[0];
      ctx.breadcrumbs = { values: this.breadcrumbs };
      ctx.modules = getSandboxModules();

      if (this.sentryDSN) {
        ctx.event_id = this.sentryClient.generateEventId();
        this.sentryClient.send(ctx, (publishErr) => {
          if (publishErr) {
            log.error('Failed to publish error into sentry: %s', publishErr.message);
          }
        });
      }

      notifySentryGlobal(ctx);
    });
  }

  static get name() {
    return 'Sentry';
  }

  static async ping() {
    const dsn = globalSentryDSNClient.dsn;

    if (!dsn) {
      return 'SENTRY_DSN is not setted yet';
    }

    const url = `${dsn.protocol}://${dsn.host}/api/0/`;

    return new Promise((resolve, reject) => {
      request({
        url,
        timeout: 3000,
      }, (err, response) => {
        if (err) {
          reject(err);
          return;
        }

        if (response.statusCode === 200) {
          resolve('OK');
          return;
        }

        reject(new Error(`HTTP status: ${response.statusCode} requesting sentry`));
      });
    });
  }
}

module.exports = ErrorTracker;
<|endoftext|>


<commit_before>/*global require, exports */

////////////////////////////////////////////////////////////////////////////////
/// @brief Foxx Model
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2013 triagens GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Lucas Dohmen
/// @author Copyright 2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

var Model,
  _ = require('underscore'),
  joi = require('joi'),
  is = require('org/arangodb/is'),
  extend = require('org/arangodb/extend').extend,
  toJSONSchema = require('org/arangodb/foxx/schema').toJSONSchema,
  EventEmitter = require('events').EventEmitter,
  util = require('util'),
  excludeExtraAttributes,
  metadataSchema = {
    _id: joi.string().optional(),
    _key: joi.string().optional(),
    _rev: joi.string().optional()
  };

// -----------------------------------------------------------------------------
// --SECTION--                                                             Model
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_model_initializer
///
/// `new FoxxModel(data)`
///
/// If you initialize a model, you can give it initial *data* as an object.
///
/// @EXAMPLES
///
/// ```js
/// instance = new Model({
///   a: 1
/// });
/// ```
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////

excludeExtraAttributes = function (attributes, Model) {
  'use strict';
  var extraAttributeNames;
  if (Model.prototype.schema) {
    extraAttributeNames = _.difference(
      _.keys(metadataSchema),
      _.keys(Model.prototype.schema)
    );
  }
  return _.omit(attributes, extraAttributeNames);
};

Model = function (attributes) {
  'use strict';
////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_model_attributes
///
/// `model.attributes`
///
/// The *attributes* property is the internal hash containing the model's state.
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////

  this.attributes = {};

////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_model_isvalid
///
/// `model.isValid`
///
/// The *isValid* flag indicates whether the model's state is currently valid.
/// If the model does not have a schema, it will always be considered valid.
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////

  this.isValid = true;

////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_model_errors
///
/// `model.errors`
///
/// The *errors* property maps the names of any invalid attributes to their
/// corresponding validation error.
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////

  this.errors = {};

  var instance = this;
  if (instance.schema) {
    _.each(
      _.union(_.keys(instance.schema), _.keys(attributes)),
      function (attributeName) {
        instance.set(attributeName, attributes ? attributes[attributeName] : undefined);
      }
    );
  } else if (attributes) {
    instance.attributes = _.clone(attributes);
  }
  EventEmitter.call(instance);
};

util.inherits(Model, EventEmitter);

Model.fromClient = function (attributes) {
  'use strict';
  return new this(excludeExtraAttributes(attributes, this));
};

// "Class" Properties
_.extend(Model, {
  // TODO: Docs

  toJSONSchema: function (id) {
    'use strict';
    require('console').log('Model.toJSONSchema(id) is deprecated, use Foxx.toJSONSchema(id, Model) instead');
    return toJSONSchema(id, this);
  }
});

// Instance Properties
_.extend(Model.prototype, {
////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_model_get
///
/// `FoxxModel#get(name)`
///
/// Get the value of an attribute
///
/// @EXAMPLES
///
/// ```js
/// instance = new Model({
///   a: 1
/// });
///
/// instance.get("a");
/// ```
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////

  get: function (attributeName) {
    'use strict';
    return this.attributes[attributeName];
  },

////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_model_set
///
/// `FoxxModel#set(name, value)`
///
/// Set the value of an attribute or multiple attributes at once
///
/// @EXAMPLES
///
/// ```js
/// instance = new Model({
///   a: 1
/// });
///
/// instance.set("a", 2);
/// instance.set({
///   b: 2
/// });
/// ```
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////

  set: function (attributeName, value) {
    'use strict';

    if (is.object(attributeName)) {
      _.each(attributeName, function (value, key) {
        this.set(key, value);
      }, this);
      return;
    }

    if (this.schema) {
      var schema = (
          this.schema[attributeName] ||
          metadataSchema[attributeName] ||
          joi.forbidden()
        ),
        result = (
          schema.isJoi ? schema : joi.object().keys(schema)
        ).validate(value);

      if (result.error) {
        this.errors[attributeName] = result.error;
        this.isValid = false;
      } else {
        delete this.errors[attributeName];
        if (_.isEmpty(this.errors)) {
          this.isValid = true;
        }
      }
      if (result.value === undefined) {
        delete this.attributes[attributeName];
      } else {
        this.attributes[attributeName] = result.value;
      }
    } else {
      this.attributes[attributeName] = value;
    }
  },

////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_model_has
///
/// `FoxxModel#has(name)`
///
/// Returns true if the attribute is set to a non-null or non-undefined value.
///
/// @EXAMPLES
///
/// ```js
/// instance = new Model({
///   a: 1
/// });
///
/// instance.has("a"); //=> true
/// instance.has("b"); //=> false
/// ```
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////

  has: function (attributeName) {
    'use strict';
    return !(_.isUndefined(this.attributes[attributeName]) ||
             _.isNull(this.attributes[attributeName]));
  },

////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_model_forDB
///
/// `FoxxModel#forDB()`
///
/// Return a copy of the model which can be saved into ArangoDB
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////

  forDB: function () {
    'use strict';
    return this.attributes;
  },

////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_model_forClient
///
/// `FoxxModel#forClient()`
///
/// Return a copy of the model which you can send to the client.
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////

  forClient: function () {
    'use strict';
    return excludeExtraAttributes(this.attributes, this.constructor);
  }
});

////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_model_extend
///
/// `FoxxModel#extend(instanceProperties, classProperties)`
///
/// Extend the Model prototype to add or overwrite methods.
/// The first object contains the properties to be defined on the instance,
/// the second object those to be defined on the prototype.
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////

Model.extend = extend;

exports.Model = Model;

// -----------------------------------------------------------------------------
// --SECTION--                                                       END-OF-FILE
// -----------------------------------------------------------------------------

/// Local Variables:
/// mode: outline-minor
/// outline-regexp: "/// @brief\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}\\|/\\*jslint"
/// End:
<commit_msg>Removed deprecated toJSONSchema static method.<commit_after>/*global require, exports */

////////////////////////////////////////////////////////////////////////////////
/// @brief Foxx Model
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2013 triagens GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Lucas Dohmen
/// @author Copyright 2013, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

var Model,
  _ = require('underscore'),
  joi = require('joi'),
  is = require('org/arangodb/is'),
  extend = require('org/arangodb/extend').extend,
  toJSONSchema = require('org/arangodb/foxx/schema').toJSONSchema,
  EventEmitter = require('events').EventEmitter,
  util = require('util'),
  excludeExtraAttributes,
  metadataSchema = {
    _id: joi.string().optional(),
    _key: joi.string().optional(),
    _rev: joi.string().optional()
  };

// -----------------------------------------------------------------------------
// --SECTION--                                                             Model
// -----------------------------------------------------------------------------

////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_model_initializer
///
/// `new FoxxModel(data)`
///
/// If you initialize a model, you can give it initial *data* as an object.
///
/// @EXAMPLES
///
/// ```js
/// instance = new Model({
///   a: 1
/// });
/// ```
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////

excludeExtraAttributes = function (attributes, Model) {
  'use strict';
  var extraAttributeNames;
  if (Model.prototype.schema) {
    extraAttributeNames = _.difference(
      _.keys(metadataSchema),
      _.keys(Model.prototype.schema)
    );
  }
  return _.omit(attributes, extraAttributeNames);
};

Model = function (attributes) {
  'use strict';
////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_model_attributes
///
/// `model.attributes`
///
/// The *attributes* property is the internal hash containing the model's state.
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////

  this.attributes = {};

////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_model_isvalid
///
/// `model.isValid`
///
/// The *isValid* flag indicates whether the model's state is currently valid.
/// If the model does not have a schema, it will always be considered valid.
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////

  this.isValid = true;

////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_model_errors
///
/// `model.errors`
///
/// The *errors* property maps the names of any invalid attributes to their
/// corresponding validation error.
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////

  this.errors = {};

  var instance = this;
  if (instance.schema) {
    _.each(
      _.union(_.keys(instance.schema), _.keys(attributes)),
      function (attributeName) {
        instance.set(attributeName, attributes ? attributes[attributeName] : undefined);
      }
    );
  } else if (attributes) {
    instance.attributes = _.clone(attributes);
  }
  EventEmitter.call(instance);
};

util.inherits(Model, EventEmitter);

Model.fromClient = function (attributes) {
  'use strict';
  return new this(excludeExtraAttributes(attributes, this));
};

// Instance Properties
_.extend(Model.prototype, {
////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_model_get
///
/// `FoxxModel#get(name)`
///
/// Get the value of an attribute
///
/// @EXAMPLES
///
/// ```js
/// instance = new Model({
///   a: 1
/// });
///
/// instance.get("a");
/// ```
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////

  get: function (attributeName) {
    'use strict';
    return this.attributes[attributeName];
  },

////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_model_set
///
/// `FoxxModel#set(name, value)`
///
/// Set the value of an attribute or multiple attributes at once
///
/// @EXAMPLES
///
/// ```js
/// instance = new Model({
///   a: 1
/// });
///
/// instance.set("a", 2);
/// instance.set({
///   b: 2
/// });
/// ```
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////

  set: function (attributeName, value) {
    'use strict';

    if (is.object(attributeName)) {
      _.each(attributeName, function (value, key) {
        this.set(key, value);
      }, this);
      return;
    }

    if (this.schema) {
      var schema = (
          this.schema[attributeName] ||
          metadataSchema[attributeName] ||
          joi.forbidden()
        ),
        result = (
          schema.isJoi ? schema : joi.object().keys(schema)
        ).validate(value);

      if (result.error) {
        this.errors[attributeName] = result.error;
        this.isValid = false;
      } else {
        delete this.errors[attributeName];
        if (_.isEmpty(this.errors)) {
          this.isValid = true;
        }
      }
      if (result.value === undefined) {
        delete this.attributes[attributeName];
      } else {
        this.attributes[attributeName] = result.value;
      }
    } else {
      this.attributes[attributeName] = value;
    }
  },

////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_model_has
///
/// `FoxxModel#has(name)`
///
/// Returns true if the attribute is set to a non-null or non-undefined value.
///
/// @EXAMPLES
///
/// ```js
/// instance = new Model({
///   a: 1
/// });
///
/// instance.has("a"); //=> true
/// instance.has("b"); //=> false
/// ```
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////

  has: function (attributeName) {
    'use strict';
    return !(_.isUndefined(this.attributes[attributeName]) ||
             _.isNull(this.attributes[attributeName]));
  },

////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_model_forDB
///
/// `FoxxModel#forDB()`
///
/// Return a copy of the model which can be saved into ArangoDB
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////

  forDB: function () {
    'use strict';
    return this.attributes;
  },

////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_model_forClient
///
/// `FoxxModel#forClient()`
///
/// Return a copy of the model which you can send to the client.
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////

  forClient: function () {
    'use strict';
    return excludeExtraAttributes(this.attributes, this.constructor);
  }
});

////////////////////////////////////////////////////////////////////////////////
/// @startDocuBlock JSF_foxx_model_extend
///
/// `FoxxModel#extend(instanceProperties, classProperties)`
///
/// Extend the Model prototype to add or overwrite methods.
/// The first object contains the properties to be defined on the instance,
/// the second object those to be defined on the prototype.
/// @endDocuBlock
////////////////////////////////////////////////////////////////////////////////

Model.extend = extend;

exports.Model = Model;

// -----------------------------------------------------------------------------
// --SECTION--                                                       END-OF-FILE
// -----------------------------------------------------------------------------

/// Local Variables:
/// mode: outline-minor
/// outline-regexp: "/// @brief\\|/// @addtogroup\\|/// @page\\|// --SECTION--\\|/// @\\}\\|/\\*jslint"
/// End:
<|endoftext|>


<commit_before>/*
 * grunt-manifest
 * https://github.com/gunta/grunt-manifest
 *
 * Copyright (c) 2013 Gunther Brunner, contributors
 * Licensed under the MIT license.
 * https://github.com/gunta/grunt-manifest/blob/master/LICENSE-MIT
 */

'use strict';
module.exports = function (grunt) {

  grunt.registerMultiTask('manifest', 'Generate HTML5 cache manifest', function () {

    var options = this.options({verbose: true, timestamp: true});
    var done = this.async();

    grunt.verbose.writeflags(options, 'Options');

    var path = require('path');

    this.files.forEach(function (file) {

      var files;
      var cacheFiles = options.cache;
      var contents = 'CACHE MANIFEST\n';

      // if hash options is specified it will be used to calculate
      // a hash of local files that are included in the manifest
      var hasher;

      if (options.hash) {
        hasher = require('crypto').createHash('sha256');
      }

      // check to see if src has been set
      if (typeof file.src === "undefined") {
        grunt.fatal('Need to specify which files to include in the manifest.', 2);
      }

      // if a basePath is set, expand using the original file pattern
      if (options.basePath) {
        files = grunt.file.expand({cwd: options.basePath}, file.orig.src);
      } else {
        files = file.src;
      }

      // Exclude files
      if (options.exclude) {
        files = files.filter(function (item) {
          return options.exclude.indexOf(item) === -1;
        });
      }

      // Set default destination file
      if (!file.dest) {
        file.dest = 'manifest.appcache';
      }

      if (options.verbose) {
        contents += '# This manifest was generated by grunt-manifest HTML5 Cache Manifest Generator\n';
      }

      if (options.timestamp) {
        contents += '# Time: ' + new Date() + '\n';
      }

      if (options.revision) {
        contents += '# Revision: ' + options.revision + '\n';
      }

      // Cache section
      contents += '\nCACHE:\n';

      // add files to explicit cache manually
      if (cacheFiles) {
        cacheFiles.forEach(function (item) {
          contents += encodeURI(item) + '\n';
        });
      }

      // add files to explicit cache
      if (files) {
        files.forEach(function (item) {
          contents += encodeURI(item) + '\n';

          // hash file contents
          if (options.hash) {
            grunt.verbose.writeln('Hashing ' + path.join(options.basePath, item));
            hasher.update(grunt.file.read(path.join(options.basePath, item)), 'binary');
          }
        });
      }

      // Network section
      if (options.network) {
        contents += '\nNETWORK:\n';
        options.network.forEach(function (item) {
          contents += encodeURI(item) + '\n';
        });
      } else {
        // If there's no network section, add a default '*' wildcard
        contents += '\nNETWORK:\n';
        contents += '*\n';
      }

      // Fallback section
      if (options.fallback) {
        contents += '\nFALLBACK:\n';
        options.fallback.forEach(function (item) {
          contents += encodeURI(item) + '\n';
        });
      }

      // Settings section
      if (options.preferOnline) {
        contents += '\nSETTINGS:\n';
        contents += 'prefer-online\n';
      }

      // output hash to cache manifest
      if (options.hash) {

        // hash masters as well
        if (options.master) {

          // convert form string to array
          if (typeof options.master === 'string') {
            options.master = [options.master];
          }

          options.master.forEach(function (item) {
            grunt.log.writeln('Hashing ' + path.join(options.basePath, item));
            hasher.update(grunt.file.read(path.join(options.basePath, item)), 'binary');
          });
        }

        contents += '\n# hash: ' + hasher.digest("hex");
      }

      grunt.verbose.writeln('\n' + (contents).yellow);

      grunt.file.write(file.dest, contents);

      grunt.log.writeln('File "' + file.dest + '" created.');

      done();

    });

  });

};
<commit_msg>Added process option this is a function that processes file name before outputting them to the cache manifest.<commit_after>/*
 * grunt-manifest
 * https://github.com/gunta/grunt-manifest
 *
 * Copyright (c) 2013 Gunther Brunner, contributors
 * Licensed under the MIT license.
 * https://github.com/gunta/grunt-manifest/blob/master/LICENSE-MIT
 */

'use strict';
module.exports = function (grunt) {

  grunt.registerMultiTask('manifest', 'Generate HTML5 cache manifest', function () {

    var options = this.options({verbose: true, timestamp: true});
    var done = this.async();

    grunt.verbose.writeflags(options, 'Options');

    var path = require('path');

    this.files.forEach(function (file) {

      var files;
      var cacheFiles = options.cache;
      var contents = 'CACHE MANIFEST\n';

      // if hash options is specified it will be used to calculate
      // a hash of local files that are included in the manifest
      var hasher;

      if (options.hash) {
        hasher = require('crypto').createHash('sha256');
      }

      // check to see if src has been set
      if (typeof file.src === "undefined") {
        grunt.fatal('Need to specify which files to include in the manifest.', 2);
      }

      // if a basePath is set, expand using the original file pattern
      if (options.basePath) {
        files = grunt.file.expand({cwd: options.basePath}, file.orig.src);
      } else {
        files = file.src;
      }

      // Exclude files
      if (options.exclude) {
        files = files.filter(function (item) {
          return options.exclude.indexOf(item) === -1;
        });
      }

      // Set default destination file
      if (!file.dest) {
        file.dest = 'manifest.appcache';
      }

      if (options.verbose) {
        contents += '# This manifest was generated by grunt-manifest HTML5 Cache Manifest Generator\n';
      }

      if (options.timestamp) {
        contents += '# Time: ' + new Date() + '\n';
      }

      if (options.revision) {
        contents += '# Revision: ' + options.revision + '\n';
      }

      // Cache section
      contents += '\nCACHE:\n';

      // add files to explicit cache manually
      if (cacheFiles) {
        cacheFiles.forEach(function (item) {
          contents += encodeURI(item) + '\n';
        });
      }

      // add files to explicit cache
      if (files) {
        files.forEach(function (item) {
          if (options.process) {
            contents += encodeURI(options.process(item)) + '\n';
          } else {
            contents += encodeURI(item) + '\n';
          }

          // hash file contents
          if (options.hash) {
            grunt.verbose.writeln('Hashing ' + path.join(options.basePath, item));
            hasher.update(grunt.file.read(path.join(options.basePath, item)), 'binary');
          }
        });
      }

      // Network section
      if (options.network) {
        contents += '\nNETWORK:\n';
        options.network.forEach(function (item) {
          contents += encodeURI(item) + '\n';
        });
      } else {
        // If there's no network section, add a default '*' wildcard
        contents += '\nNETWORK:\n';
        contents += '*\n';
      }

      // Fallback section
      if (options.fallback) {
        contents += '\nFALLBACK:\n';
        options.fallback.forEach(function (item) {
          contents += encodeURI(item) + '\n';
        });
      }

      // Settings section
      if (options.preferOnline) {
        contents += '\nSETTINGS:\n';
        contents += 'prefer-online\n';
      }

      // output hash to cache manifest
      if (options.hash) {

        // hash masters as well
        if (options.master) {

          // convert form string to array
          if (typeof options.master === 'string') {
            options.master = [options.master];
          }

          options.master.forEach(function (item) {
            grunt.log.writeln('Hashing ' + path.join(options.basePath, item));
            hasher.update(grunt.file.read(path.join(options.basePath, item)), 'binary');
          });
        }

        contents += '\n# hash: ' + hasher.digest("hex");
      }

      grunt.verbose.writeln('\n' + (contents).yellow);

      grunt.file.write(file.dest, contents);

      grunt.log.writeln('File "' + file.dest + '" created.');

      done();

    });

  });

};
<|endoftext|>


<commit_before>/*jshint multistr: true, unused: false*/

'use strict';

var $ = require('jquery'),
    NavMainComponent = require('../../../js/NavMainComponent');

$.fx.off = !$.fx.off;

describe('NavMain component', function() {

    beforeEach(function() {
        this.$html = $('

').appendTo('html');
        this.$body = $('

').appendTo(this.$html);
        this.$markup = $('\
\

\
    Jadu\
\

\

\
          1\

\

\
          2\

\

\
          3\

\

\

\
\
    x\
\
    <form>\
      <input type="search" placeholder="search" />\
      <button>Go</button>\
    </form>\
\

\

\

\
            1.1\

\

\

\
\

\

\

\
            2.1\

\

\

\
\

\
\

\
').appendTo(this.$html);

        this.$navMain = this.$html.find('.nav-main');
        this.$closeLink = this.$html.find('[data-nav-action="close"]');
        this.$contentMain = this.$html.find('.content-main');

        this.$linkOne = this.$html.find('[href="#one"]');
        this.$linkTwo = this.$html.find('[href="#two"]');
        this.$linkThree = this.$html.find('[href="#three"]');
        this.$secondaryLinkOne = this.$html.find('[href="#one_one"]');
        this.$secondaryLinkTwo = this.$html.find('[href="#two_one"]');

        this.navMainComponent = new NavMainComponent(this.$html);

    });

    describe('clicking on the first primary nav link', function() {

        beforeEach(function() {
            this.navMainComponent.init();
            this.$linkOne.click();
        });

        it('should add the is-active class to the first link', function() {
            expect(this.$linkOne.hasClass('is-active')).to.be.true;
        });

        it('should open the secondary nav', function() {
            expect(this.$html.find('.nav-main').hasClass('is-open')).to.be.true;
        });

        it('should add the is-active class to the secondary sub navigation menu', function() {
            expect(this.$html.find('[data-nav="#one"]').hasClass('is-active')).to.be.true;
        });

        it('should not add the is-active class to the other sub navigation menus', function() {
            expect(this.$html.find('[data-nav="#two"]').hasClass('is-active')).to.be.false;
        });

    });

    describe('clicking the first, then the second primary nav link', function() {

        beforeEach(function() {
            this.navMainComponent.init();
            this.$linkOne.click();
            this.$linkTwo.click();
        });

        it('should add the is-active class to the second link', function() {
            expect(this.$linkTwo.hasClass('is-active')).to.be.true;
        });

        it('should remove the is-active class from the first link', function() {
            expect(this.$linkOne.hasClass('is-active')).to.be.false;
        });

        it('should add the is-active class to the second sub navigation menu', function() {
            expect(this.$html.find('[data-nav="#two"]').hasClass('is-active')).to.be.true;
        });

        it('should remove the is-active class from the first sub navigation menu', function() {
            expect(this.$html.find('[data-nav="#one"]').hasClass('is-active')).to.be.false;
        });

    });

    describe('clicking a secondary nav link', function() {

        beforeEach(function() {
            this.navMainComponent.init();
            this.$linkOne.click();
            this.$secondaryLinkOne.click();
        });

        it('should add the is-active class to the clicked link', function() {
            expect(this.$secondaryLinkOne.hasClass('is-active')).to.be.true;
        });

    });

    describe('clicking a second secondary nav link', function() {

        beforeEach(function() {
            this.navMainComponent.init();
            this.$linkOne.click();
            this.$secondaryLinkOne.click();
            this.$secondaryLinkTwo.click();
        });

        it('should add the is-active class to the clicked link', function() {
            expect(this.$secondaryLinkTwo.hasClass('is-active')).to.be.true;
        });

    });

    describe('clicking a primary nav link that has no sub navigation', function() {

        beforeEach(function() {
            this.navMainComponent.init();
            this.$linkThree.click();
        });

        it('should not open the secondary nav', function() {
            expect(this.$html.find('.nav-main').hasClass('is-open')).to.be.false;
        });
    });

    describe('clicking a primary nav link that has no sub navigation when the subnavigation is open', function() {

        beforeEach(function() {
            this.navMainComponent.init();
            this.$linkOne.click();
            this.$linkThree.click();
        });

        it('should close the secondary nav', function() {
            expect(this.$html.find('.nav-main').hasClass('nav-main--open')).to.be.false;
        });
    });

    describe('clicking the close icon, when the sub navigation is closed', function() {

        beforeEach(function() {
            this.navMainComponent.init();
            this.$closeLink.click();
        });

        it('should have no effect on the subnavigation', function() {
            expect(this.$html.find('.nav-main').hasClass('is-active')).to.be.false;
        });

    });

    describe('clicking the close icon, when the sub navigation is open', function() {

        beforeEach(function() {
            this.navMainComponent.init();
            this.$linkOne.click();
            this.$closeLink.click();
        });

        it('should close the sub navigation', function() {
            expect(this.$html.find('.nav-main').hasClass('is-open')).to.be.false;
        });

    });

    describe('clicking outside of the navigation, when the sub navigation is open', function() {

        beforeEach(function() {
            this.navMainComponent.init();
            this.$linkOne.click();
            this.$contentMain.click();
        });

        it('should close the sub navigation', function() {
            expect(this.$html.find('.nav-main').hasClass('is-open')).to.be.false;
        });

    });

});
<commit_msg>Related tests for fix<commit_after>/*jshint multistr: true, unused: false*/

'use strict';

var $ = require('jquery'),
    NavMainComponent = require('../../../js/NavMainComponent');

$.fx.off = !$.fx.off;

describe('NavMain component', function() {

    beforeEach(function() {
        this.$html = $('

').appendTo('html');
        this.$body = $('

').appendTo(this.$html);
        this.$markup = $('\
\

\
    Jadu\
\

\

\
          1\

\

\
          2\

\

\
          3\

\

\

\
\
    x\
\
    <form>\
      <input type="search" placeholder="search" />\
      <button>Go</button>\
    </form>\
\

\

\

\
            1.1\

\

\

\
\

\

\

\
            2.1\

\

\

\
\

\
\

\
').appendTo(this.$html);

        this.$navMain = this.$html.find('.nav-main');
        this.$closeLink = this.$html.find('[data-nav-action="close"]');
        this.$contentMain = this.$html.find('.content-main');

        this.$linkOne = this.$html.find('[href="#one"]');
        this.$linkTwo = this.$html.find('[href="#two"]');
        this.$linkThree = this.$html.find('[href="#three"]');
        this.$secondaryLinkOne = this.$html.find('[href="#one_one"]');
        this.$secondaryLinkTwo = this.$html.find('[href="#two_one"]');

        this.navMainComponent = new NavMainComponent(this.$html);

    });

    describe('clicking on the first primary nav link', function() {

        beforeEach(function() {
            this.navMainComponent.init();
            this.$linkOne.click();
        });

        it('should add the is-active class to the first link', function() {
            expect(this.$linkOne.hasClass('is-active')).to.be.true;
        });

        it('should open the secondary nav', function() {
            expect(this.$html.find('.nav-main').hasClass('is-open')).to.be.true;
        });

        it('should add the is-active class to the secondary sub navigation menu', function() {
            expect(this.$html.find('[data-nav="#one"]').hasClass('is-active')).to.be.true;
        });

        it('should not add the is-active class to the other sub navigation menus', function() {
            expect(this.$html.find('[data-nav="#two"]').hasClass('is-active')).to.be.false;
        });

    });

    describe('clicking the first, then the second primary nav link', function() {

        beforeEach(function() {
            this.navMainComponent.init();
            this.$linkOne.click();
            this.$linkTwo.click();
        });

        it('should add the is-active class to the second link', function() {
            expect(this.$linkTwo.hasClass('is-active')).to.be.true;
        });

        it('should remove the is-active class from the first link', function() {
            expect(this.$linkOne.hasClass('is-active')).to.be.false;
        });

        it('should add the is-active class to the second sub navigation menu', function() {
            expect(this.$html.find('[data-nav="#two"]').hasClass('is-active')).to.be.true;
        });

        it('should remove the is-active class from the first sub navigation menu', function() {
            expect(this.$html.find('[data-nav="#one"]').hasClass('is-active')).to.be.false;
        });

    });

    describe('clicking a secondary nav link', function() {

        beforeEach(function() {
            this.navMainComponent.init();
            this.$linkOne.click();
            this.$secondaryLinkOne.click();
        });

        it('should add the is-active class to the clicked link', function() {
            expect(this.$secondaryLinkOne.hasClass('is-active')).to.be.true;
        });

    });

    describe('clicking a second secondary nav link', function() {

        beforeEach(function() {
            this.navMainComponent.init();
            this.$linkOne.click();
            this.$secondaryLinkOne.click();
            this.$secondaryLinkTwo.click();
        });

        it('should add the is-active class to the clicked link', function() {
            expect(this.$secondaryLinkTwo.hasClass('is-active')).to.be.true;
        });

    });

    describe('clicking a primary nav link that has no sub navigation', function() {

        beforeEach(function() {
            this.navMainComponent.init();
            this.$linkThree.click();
        });

        it('should not open the secondary nav', function() {
            expect(this.$html.find('.nav-main').hasClass('is-open')).to.be.false;
        });
    });

    describe('clicking a primary nav link that has no sub navigation when the subnavigation is open', function() {

        beforeEach(function() {
            this.navMainComponent.init();
            this.$linkOne.click();
            this.$linkThree.click();
        });

        it('should close the secondary nav', function() {
            expect(this.$html.find('.nav-main').hasClass('nav-main--open')).to.be.false;
        });
    });

    describe('clicking the close icon, when the sub navigation is closed', function() {

        beforeEach(function() {
            this.navMainComponent.init();
            this.$closeLink.click();
        });

        it('should have no effect on the subnavigation', function() {
            expect(this.$html.find('.nav-main').hasClass('is-active')).to.be.false;
        });

    });

    describe('clicking the close icon, when the sub navigation is open', function() {

        beforeEach(function() {
            this.navMainComponent.init();
            this.$linkOne.click();
            this.$closeLink.click();
        });

        it('should close the sub navigation', function() {
            expect(this.$html.find('.nav-main').hasClass('is-open')).to.be.false;
        });

        it('should remove the highlight from that sections primary nav item', function() {
            expect(this.$html.find('.nav-primary .nav-link').hasClass('is-active')).to.be.false;
        });

    });

    describe('clicking outside of the navigation, when the sub navigation is open', function() {

        beforeEach(function() {
            this.navMainComponent.init();
            this.$linkOne.click();
            this.$contentMain.click();
        });

        it('should close the sub navigation', function() {
            expect(this.$html.find('.nav-main').hasClass('is-open')).to.be.false;
        });

    });

});
<|endoftext|>


<commit_before>import tumblrClient from '../tumblrClient';
import youtube from '../youtubeClient';
import range from 'lodash/range';
import without from 'lodash/without';
import map from 'lodash/map';
import toNumber from 'lodash/toNumber';
import { redisClient } from '../api';
import config from 'config';
const playlist = config.youtubePlaylistId;
// import redis from 'redis';

// function getBlogPostsPromise({ limit = 20, offset }) {
//   return new Promise((resolve, reject) => {
//     tumblrClient.blogPosts('vega-june.tumblr.com', {
//       limit,
//       offset: offset * 20,
//     }, (err, data) => {
//       if (err) reject(err);
//       resolve(data);
//     });
//   });
// }
//
// function getRedisMultiPromise(multi) {
//   return new Promise((resolve, reject) => {
//     multi.exec((err, data) => {
//       if (err) reject(err);
//       resolve(data);
//     });
//   });
// }
//
// function superagentGetPromise(superAgent) {
//   return new Promise((resolve, reject) => {
//     superAgent.end((err, data) => {
//       if (err) reject(err);
//       resolve(data);
//     });
//   });
// }
//
// function mapTumblrToIds(tumblrData) {
//   const multi = redisClient.multi();
//   const ids = map(tumblrData.posts, ({ id, type, photos, thumbnail_url }) => {
//     multi.get(id);
//     const url = type === 'video'
//       ? thumbnail_url
//       : photos[0].alt_sizes[5].url
//     return { id, url };
//   });
// }

export function loadInfo(req) {
  const offset = req && req.query && req.query.offset
    ? req.query.offset
    : 0;
  return new Promise((resolve, reject) => {
    tumblrClient.blogPosts('vega-june.tumblr.com', {
      limit: 20,
      offset: offset * 20,
    }, (err, data) => {
      if (err) return reject(err);
      return resolve(data);
    });
  });
}

export function loadAll(req) {
  console.log('loadingall!!!');
  return new Promise((masterResolve) => {
    const multi = redisClient.multi();
    multi.get('latestTumblr');
    multi.get('latestYoutube');

    multi.exec( (err, [data, youtube]) => {

      const tumblrPromise = new Promise((tumblrResolve, tumblrReject) => {
        if (data) {
          console.log('resolving data');
          return tumblrResolve(JSON.parse(data));
        } else {
          fetchAllPostsFromTumblr(req).then((tumblrData) => {
            redisClient.set('latestTumblr', JSON.stringify(tumblrData), (setErr, setData) => {
              console.log('setData', setData);
              tumblrResolve(tumblrData);
            });
          });
        }
      }).catch(console.log);
      const youtubePromise = new Promise((youtubeResolve, youtubeReject) => {
        if (youtube) {
          console.log('resolving data');
          return youtubeResolve(JSON.parse(youtube));
        } else {
          fetchAllYoutubeVideos().then((youtubeData) => {
            redisClient.set('latestYoutube', JSON.stringify(youtubeData), (setErr, setData) => {
              console.log('setData', setData);
              youtubeResolve(youtubeData);
            });
          });
        }
      }).catch(console.log);
      return Promise.all([tumblrPromise, youtubePromise]).then(([tumblr, youtube]) => {
        masterResolve({tumblr, youtube});
      }).catch(console.log);
    });
      // console.error('data, youtube', youtube);

    // }).catch(console.log);
  });
}

export function fetchAllPostsFromTumblr(req) {
  return new Promise((masterResolve, masterReject) => {
    const pages = req && req.query && req.query.pages
      ? map(req.query.pages.split(','), toNumber)
      : -1;
    const totalPosts = req && req.query && req.query.totalPosts
      ? req.query.totalPosts
      : null;
    const firstPromise = totalPosts
      ? Promise.resolve(totalPosts)
      : new Promise((resolve, reject) => {
        tumblrClient.blogPosts('vega-june.tumblr.com', {
          limit: 20,
        }, (err, data) => {
          if (err) return reject(err);
          return resolve(data.blog.posts);
        });
      });
    firstPromise.then((promiseResponse) => {
      const pagesNeeded = Math.floor(promiseResponse / 20 + 1);
      const allPagesNeededFetch = without(range(pagesNeeded), ...pages);
      return Promise.all(
        allPagesNeededFetch.reduce((out, page) => [
          ...out,
          new Promise((resolve, reject) => {
            console.log('getting page', page);
            tumblrClient.blogPosts('vega-june.tumblr.com', {
              limit: 20,
              offset: 20 * page
            }, (err, data) => {
              if (err) return reject(err);
              return resolve(data);
            });
          })
        ], [])
      ).then(resultArray => {
        redisClient.set('latestTumblr', JSON.stringify(resultArray), (setErr, setData) => {
          console.log('setData', setData);
          masterResolve(resultArray);
        });
      }).catch((err) => {
        masterReject(err);
      });
    });
  }).catch(err => console.error(err));
}

export function fetchAllYoutubeVideos() {
  return new Promise((resolve, reject) => {
    youtube.playlistItems.list({
      part: 'contentDetails',
      playlistId: 'PLDxchoMUm8NhAkt6c0pkdowAunWUaq_f8',
      mine: true,
    }, (err, res) => {
      if (err) {
        reject(err);
      }
      const ids = [];
      res.items.forEach((item) => ids.push(item.contentDetails.videoId));
      console.error('ids', ids);
      youtube.videos.list({
        part: 'contentDetails,snippet,player',
        id: ids.join(','),
      }, (err, res) => {
        if (err) {
          reject(err);
        }
        console.error('err', err);
        console.error('res', res);
        redisClient.set('latestYoutube', JSON.stringify(res), (setErr, setData) => {
          console.log('setData', setData);
          resolve(res);
        });

        res.items.forEach(item => {
          console.error('item.snippet', item.snippet);
          console.error('item.contentDetails', item.contentDetails);
          console.error('item.player', item.player);
        });
      });
    });
  }).catch(console.log);
}
<commit_msg>Removed logging.<commit_after>import tumblrClient from '../tumblrClient';
import youtube from '../youtubeClient';
import range from 'lodash/range';
import without from 'lodash/without';
import map from 'lodash/map';
import toNumber from 'lodash/toNumber';
import { redisClient } from '../api';
import config from 'config';
const playlist = config.youtubePlaylistId;
// import redis from 'redis';

// function getBlogPostsPromise({ limit = 20, offset }) {
//   return new Promise((resolve, reject) => {
//     tumblrClient.blogPosts('vega-june.tumblr.com', {
//       limit,
//       offset: offset * 20,
//     }, (err, data) => {
//       if (err) reject(err);
//       resolve(data);
//     });
//   });
// }
//
// function getRedisMultiPromise(multi) {
//   return new Promise((resolve, reject) => {
//     multi.exec((err, data) => {
//       if (err) reject(err);
//       resolve(data);
//     });
//   });
// }
//
// function superagentGetPromise(superAgent) {
//   return new Promise((resolve, reject) => {
//     superAgent.end((err, data) => {
//       if (err) reject(err);
//       resolve(data);
//     });
//   });
// }
//
// function mapTumblrToIds(tumblrData) {
//   const multi = redisClient.multi();
//   const ids = map(tumblrData.posts, ({ id, type, photos, thumbnail_url }) => {
//     multi.get(id);
//     const url = type === 'video'
//       ? thumbnail_url
//       : photos[0].alt_sizes[5].url
//     return { id, url };
//   });
// }

export function loadInfo(req) {
  const offset = req && req.query && req.query.offset
    ? req.query.offset
    : 0;
  return new Promise((resolve, reject) => {
    tumblrClient.blogPosts('vega-june.tumblr.com', {
      limit: 20,
      offset: offset * 20,
    }, (err, data) => {
      if (err) return reject(err);
      return resolve(data);
    });
  });
}

export function loadAll(req) {
  console.log('loadingall!!!');
  return new Promise((masterResolve) => {
    const multi = redisClient.multi();
    multi.get('latestTumblr');
    multi.get('latestYoutube');

    multi.exec( (err, [data, youtube]) => {

      const tumblrPromise = new Promise((tumblrResolve, tumblrReject) => {
        if (data) {
          console.log('resolving data');
          return tumblrResolve(JSON.parse(data));
        } else {
          fetchAllPostsFromTumblr(req).then((tumblrData) => {
            redisClient.set('latestTumblr', JSON.stringify(tumblrData), (setErr, setData) => {
              console.log('setData', setData);
              tumblrResolve(tumblrData);
            });
          });
        }
      }).catch(console.log);
      const youtubePromise = new Promise((youtubeResolve, youtubeReject) => {
        if (youtube) {
          console.log('resolving data');
          return youtubeResolve(JSON.parse(youtube));
        } else {
          fetchAllYoutubeVideos().then((youtubeData) => {
            redisClient.set('latestYoutube', JSON.stringify(youtubeData), (setErr, setData) => {
              console.log('setData', setData);
              youtubeResolve(youtubeData);
            });
          });
        }
      }).catch(console.log);
      return Promise.all([tumblrPromise, youtubePromise]).then(([tumblr, youtube]) => {
        masterResolve({tumblr, youtube});
      }).catch(console.log);
    });
      // console.error('data, youtube', youtube);

    // }).catch(console.log);
  });
}

export function fetchAllPostsFromTumblr(req) {
  return new Promise((masterResolve, masterReject) => {
    const pages = req && req.query && req.query.pages
      ? map(req.query.pages.split(','), toNumber)
      : -1;
    const totalPosts = req && req.query && req.query.totalPosts
      ? req.query.totalPosts
      : null;
    const firstPromise = totalPosts
      ? Promise.resolve(totalPosts)
      : new Promise((resolve, reject) => {
        tumblrClient.blogPosts('vega-june.tumblr.com', {
          limit: 20,
        }, (err, data) => {
          if (err) return reject(err);
          return resolve(data.blog.posts);
        });
      });
    firstPromise.then((promiseResponse) => {
      const pagesNeeded = Math.floor(promiseResponse / 20 + 1);
      const allPagesNeededFetch = without(range(pagesNeeded), ...pages);
      return Promise.all(
        allPagesNeededFetch.reduce((out, page) => [
          ...out,
          new Promise((resolve, reject) => {
            console.log('getting page', page);
            tumblrClient.blogPosts('vega-june.tumblr.com', {
              limit: 20,
              offset: 20 * page
            }, (err, data) => {
              if (err) return reject(err);
              return resolve(data);
            });
          })
        ], [])
      ).then(resultArray => {
        redisClient.set('latestTumblr', JSON.stringify(resultArray), (setErr, setData) => {
          console.log('setData', setData);
          masterResolve(resultArray);
        });
      }).catch((err) => {
        masterReject(err);
      });
    });
  }).catch(err => console.error(err));
}

export function fetchAllYoutubeVideos() {
  return new Promise((resolve, reject) => {
    youtube.playlistItems.list({
      part: 'contentDetails',
      playlistId: 'PLDxchoMUm8NhAkt6c0pkdowAunWUaq_f8',
      mine: true,
    }, (err, res) => {
      if (err) {
        reject(err);
      }
      const ids = [];
      res.items.forEach((item) => ids.push(item.contentDetails.videoId));
      console.error('ids', ids);
      youtube.videos.list({
        part: 'contentDetails,snippet,player',
        id: ids.join(','),
      }, (err, res) => {
        if (err || !res) {
          reject(err);
        }
        console.error('err', err);
        console.error('res', res);
        redisClient.set('latestYoutube', JSON.stringify(res), (setErr, setData) => {
          console.log('setData', setData);
          resolve(res);
        });
      });
    });
  }).catch(console.log);
}
<|endoftext|>