<commit_before>var express = require ('express');
var sequelize = require ('../sequelize');
var Sequelize = require ('sequelize');
var User = require ('./User');
var rest = require ('rest');
var app = require ('../../app');
var Rooms = require('./Rooms');

var tutorial = sequelize.define ('tutorial', {
	id: {
		type: Sequelize.UUID,
		defaultValue: Sequelize.UUIDV4,
		unique: true,
		primaryKey: true
	},
	grouptype: {
		type: Sequelize.STRING,
	},
	name: {
		type: Sequelize.STRING,
	},
	courseid: {
		type: Sequelize.STRING,
	},
	coursecode: {
		type: Sequelize.STRING
	},
	coursename: {
		type: Sequelize.STRING
	},
	week: {
		type: Sequelize.STRING
	},
	day: {
		type: Sequelize.STRING
	},
	time: {
		type: Sequelize.STRING
	}
}, {
	indexes: [
		{
			name: 'name',
			fields: ['name']
		},
		{
			name: 'courseid',
			fields: ['courseid']
		}
	]
});

var userTutorial = sequelize.define ('userTutorial', {
	role: {
		type: Sequelize.ENUM,
		values: ['student', 'tutor'],
		allowNull: false
	},
	tutorialId: {
		type: Sequelize.UUID,
		references: {
			model: tutorial,
			key: 'id'
		}
	},
	userId: {
		type: Sequelize.STRING,
		references: {
			model: User,
			key: 'id'
		}
	}
}, {
	indexes: [
		{
			name: 'tutorialId',
			fields: ['tutorialId']
		},
		{
			name: 'userId',
			fields: ['userId']
		}
	]
});

User.belongsToMany (tutorial, {
	foreignKey: 'userId',
	through: 'userTutorial',
});

tutorial.belongsToMany (User, {
	foreignKey: 'tutorialId',
	through: 'userTutorial',
});

sequelize.sync ();

var findTutorial = function (uid, tid) {
	return tutorial.findAndCountAll ({
		where: {
			id: tid
		},
		include: [{
			model: User,
			attributes: ['id'],
			where: {id: uid}
		}]
	})
};

var findTutorialTutorID = function (tid) {
	return userTutorial.find (
		{
			attributes: ['userId'],
			where: {
				tutorialId: tid,
				role: 'tutor'
			}
		}
	);
};

var checkIfInTutorialUserList = function (uid, tid) {
	return userTutorial.find (
		{
			where: {
				tutorialId: tid,
				userId: uid
			}
		}
	);
}

var findAndCountAllTutorials = function (uid) {
	return tutorial.findAndCountAll ({
		include: [{
			model: User,
			attributes: ['id'],
			where: {id: uid}
		}]
	});
};

var findAndCountAllUsersInTutorial = function(tid){
	return userTutorial.findAndCountAll({
		where:{
			tutorialId:tid
		}
	});
};

/**
 * Private function, fetch IVLE user modules, return promise
 * @param token
 * @returns {*}
 */
var fetchIVLEUserModules = function (token) {
	return rest ('https://ivle.nus.edu.sg/api/Lapi.svc/Modules?APIKey=' + app.get ('api-key') + '&AuthToken=' + token + '&Duration=0&IncludeAllInfo=false');
}

/**
 * Private function, fetch IVLE tutorial groups, return promise
 * @param token
 * @param course
 * @returns {*}
 */
var fetchIVLETutorialGroups = function (token, course) {
	return rest ('https://ivle.nus.edu.sg/API/Lapi.svc/GroupsByUserAndModule?APIKey=' + app.get ('api-key') + '&AuthToken=' + token + '&CourseID=' + course['ID'] + '&AcadYear=' + course['AcadYear'] + '&Semester=' + course['semester']).then (function (response) {
		return {tutorialGroup: JSON.parse (response.entity).Results, course: course};
	});
}

var forceSyncIVLE = function (uid) {
	return new Promise (function (fulfill, reject) {
		User.findOne ({
			where: {
				id: uid
			},
		}).then (function (user) {
			return fetchIVLEUserModules (user.token).then (function (response) {
				return [JSON.parse (response.entity).Results, user];
			});
		}).spread (function (courses, user) {
			if (courses.length == 0 && (response.status.code != 200)) {
				reject ('Sync Module Failed');
			}
			return Promise.all (courses.map (function (course) {
				return fetchIVLETutorialGroups (user.token, course)
			})).then (function (result) {
				if (result.length == 0) {
					return reject ('Sync Groups By User And Module Failed');
				}
				return [result, user];
			});
		}).spread (function (result, user) {
			//create tutorial in this block
			var groups = [];
			for (resultIndex in result) {
				for (groupIndex in result[resultIndex]['tutorialGroup']) {
					if (result[resultIndex]['tutorialGroup'][groupIndex]['GroupTypeCode'] === 'T') {
						var group = result[resultIndex]['tutorialGroup'][groupIndex];
						group['CourseName'] = result[resultIndex]['course']['CourseName'];
						group['Permission'] = result[resultIndex]['course']['Permission'];
						groups.push (group);
					}
				}
			}
			return Promise.all (groups.map (function (group) {
				return tutorial.findOrCreate ({
					where: {
						name: group['GroupName'],
						courseid: group['CourseID']
					},
					defaults: {
						grouptype: group['GroupType'],
						coursecode: group['ModuleCode'],
						coursename: group['CourseName'],
						week: group['Week'],
						day: group['Day'],
						time: group['Time']
					}
				}).spread (function (tutorial, created) {
					return tutorial;
				});
			})).then (function (tutorials) {
				return tutorials;
			}).then (function (tutorials) {
				return {tutorials: tutorials, user: user, groups: groups};
			})
		}).then (function (result) {
			//Add user tutorial relation in this block
			var tutorials = result.tutorials;
			var groups = result.groups;

			if (tutorials.length != groups.length) {
				return reject ('Database Error!');
			}
			var relations = [];
			for (groupIndex in groups) {
				var relation = {};
				relation['tutorial'] = tutorials[groupIndex];
				relation['permission'] = groups[groupIndex]['Permission'];
				relations.push (relation);
			}
			return Promise.all (relations.map (function (relation) {

				if (!Rooms.getLobby().get(relation['tutorial'].id)){
					//If room has not been created, create the room first
					var room = new Rooms.Room();
					Rooms.getLobby().addRoom(relation['tutorial'].id)
				}
				if (Rooms.getLobby().get(relation['tutorial'].id)){
					//If room has been created and user socket not exist in room, then add initialized user socket to the room storage
					if (!Rooms.getLobby().get(relation['tutorial'].id).get('default').get(result.user.id)){
						var socketClient = new Rooms.SocketClient(result.user.id,null);
						socketClient.joinRoom(relation['tutorial'].id);
					}
				}
				var role = 'student';
				if (relation['permission'] === 'M') {
					role = 'tutor';
					Rooms.getLobby().get(relation['tutorial'].id).tutors[result.user.id] = Rooms.getLobby().get(relation['tutorial'].id).get('default').get(result.user.id);
				}
				return relation['tutorial'].addUser (result.user, {role: role});
			}));
		}).then (function (result) {
			if (result) {
				fulfill (true);
			}
		}).catch (function (err) {
			reject ('Sync Failed: ' + err);
		})
	});
};

var findTutorialSession = function (uid) {
	return userTutorial.findAll ({
		where: {
			userId: uid
		}
	});
};

module.exports = tutorial;
module.exports.forceSyncIVLE = forceSyncIVLE;
module.exports.findTutorial = findTutorial;
module.exports.findAndCountAllTutorials = findAndCountAllTutorials;
module.exports.findTutorialSession = findTutorialSession;
module.exports.findTutorialTutorID = findTutorialTutorID;
module.exports.checkIfInTutorialUserList = checkIfInTutorialUserList;
module.exports.findAndCountAllUsersInTutorial = findAndCountAllUsersInTutorial;<commit_msg>fix room creation bug<commit_after>var express = require ('express');
var sequelize = require ('../sequelize');
var Sequelize = require ('sequelize');
var User = require ('./User');
var rest = require ('rest');
var app = require ('../../app');
var Rooms = require('./Rooms');

var tutorial = sequelize.define ('tutorial', {
	id: {
		type: Sequelize.UUID,
		defaultValue: Sequelize.UUIDV4,
		unique: true,
		primaryKey: true
	},
	grouptype: {
		type: Sequelize.STRING,
	},
	name: {
		type: Sequelize.STRING,
	},
	courseid: {
		type: Sequelize.STRING,
	},
	coursecode: {
		type: Sequelize.STRING
	},
	coursename: {
		type: Sequelize.STRING
	},
	week: {
		type: Sequelize.STRING
	},
	day: {
		type: Sequelize.STRING
	},
	time: {
		type: Sequelize.STRING
	}
}, {
	indexes: [
		{
			name: 'name',
			fields: ['name']
		},
		{
			name: 'courseid',
			fields: ['courseid']
		}
	]
});

var userTutorial = sequelize.define ('userTutorial', {
	role: {
		type: Sequelize.ENUM,
		values: ['student', 'tutor'],
		allowNull: false
	},
	tutorialId: {
		type: Sequelize.UUID,
		references: {
			model: tutorial,
			key: 'id'
		}
	},
	userId: {
		type: Sequelize.STRING,
		references: {
			model: User,
			key: 'id'
		}
	}
}, {
	indexes: [
		{
			name: 'tutorialId',
			fields: ['tutorialId']
		},
		{
			name: 'userId',
			fields: ['userId']
		}
	]
});

User.belongsToMany (tutorial, {
	foreignKey: 'userId',
	through: 'userTutorial',
});

tutorial.belongsToMany (User, {
	foreignKey: 'tutorialId',
	through: 'userTutorial',
});

sequelize.sync ();

var findTutorial = function (uid, tid) {
	return tutorial.findAndCountAll ({
		where: {
			id: tid
		},
		include: [{
			model: User,
			attributes: ['id'],
			where: {id: uid}
		}]
	})
};

var findTutorialTutorID = function (tid) {
	return userTutorial.find (
		{
			attributes: ['userId'],
			where: {
				tutorialId: tid,
				role: 'tutor'
			}
		}
	);
};

var checkIfInTutorialUserList = function (uid, tid) {
	return userTutorial.find (
		{
			where: {
				tutorialId: tid,
				userId: uid
			}
		}
	);
}

var findAndCountAllTutorials = function (uid) {
	return tutorial.findAndCountAll ({
		include: [{
			model: User,
			attributes: ['id'],
			where: {id: uid}
		}]
	});
};

var findAndCountAllUsersInTutorial = function(tid){
	return userTutorial.findAndCountAll({
		where:{
			tutorialId:tid
		}
	});
};

/**
 * Private function, fetch IVLE user modules, return promise
 * @param token
 * @returns {*}
 */
var fetchIVLEUserModules = function (token) {
	return rest ('https://ivle.nus.edu.sg/api/Lapi.svc/Modules?APIKey=' + app.get ('api-key') + '&AuthToken=' + token + '&Duration=0&IncludeAllInfo=false');
}

/**
 * Private function, fetch IVLE tutorial groups, return promise
 * @param token
 * @param course
 * @returns {*}
 */
var fetchIVLETutorialGroups = function (token, course) {
	return rest ('https://ivle.nus.edu.sg/API/Lapi.svc/GroupsByUserAndModule?APIKey=' + app.get ('api-key') + '&AuthToken=' + token + '&CourseID=' + course['ID'] + '&AcadYear=' + course['AcadYear'] + '&Semester=' + course['semester']).then (function (response) {
		return {tutorialGroup: JSON.parse (response.entity).Results, course: course};
	});
}

var forceSyncIVLE = function (uid) {
	return new Promise (function (fulfill, reject) {
		User.findOne ({
			where: {
				id: uid
			},
		}).then (function (user) {
			return fetchIVLEUserModules (user.token).then (function (response) {
				return [JSON.parse (response.entity).Results, user];
			});
		}).spread (function (courses, user) {
			if (courses.length == 0 && (response.status.code != 200)) {
				reject ('Sync Module Failed');
			}
			return Promise.all (courses.map (function (course) {
				return fetchIVLETutorialGroups (user.token, course)
			})).then (function (result) {
				if (result.length == 0) {
					return reject ('Sync Groups By User And Module Failed');
				}
				return [result, user];
			});
		}).spread (function (result, user) {
			//create tutorial in this block
			var groups = [];
			for (resultIndex in result) {
				for (groupIndex in result[resultIndex]['tutorialGroup']) {
					if (result[resultIndex]['tutorialGroup'][groupIndex]['GroupTypeCode'] === 'T') {
						var group = result[resultIndex]['tutorialGroup'][groupIndex];
						group['CourseName'] = result[resultIndex]['course']['CourseName'];
						group['Permission'] = result[resultIndex]['course']['Permission'];
						groups.push (group);
					}
				}
			}
			return Promise.all (groups.map (function (group) {
				return tutorial.findOrCreate ({
					where: {
						name: group['GroupName'],
						courseid: group['CourseID']
					},
					defaults: {
						grouptype: group['GroupType'],
						coursecode: group['ModuleCode'],
						coursename: group['CourseName'],
						week: group['Week'],
						day: group['Day'],
						time: group['Time']
					}
				}).spread (function (tutorial, created) {
					return tutorial;
				});
			})).then (function (tutorials) {
				return tutorials;
			}).then (function (tutorials) {
				return {tutorials: tutorials, user: user, groups: groups};
			})
		}).then (function (result) {
			//Add user tutorial relation in this block
			var tutorials = result.tutorials;
			var groups = result.groups;

			if (tutorials.length != groups.length) {
				return reject ('Database Error!');
			}
			var relations = [];
			for (groupIndex in groups) {
				var relation = {};
				relation['tutorial'] = tutorials[groupIndex];
				relation['permission'] = groups[groupIndex]['Permission'];
				relations.push (relation);
			}
			return Promise.all (relations.map (function (relation) {

				if (!Rooms.getLobby().get(relation['tutorial'].id)){
					//If room has not been created, create the room first
					var room = new Rooms.Room();
					Rooms.getLobby().addRoom(relation['tutorial'].id, room);
				}
				if (Rooms.getLobby().get(relation['tutorial'].id)){
					//If room has been created and user socket not exist in room, then add initialized user socket to the room storage
					if (!Rooms.getLobby().get(relation['tutorial'].id).get('default').get(result.user.id)){
						var socketClient = new Rooms.SocketClient(result.user.id,null);
						socketClient.joinRoom(relation['tutorial'].id);
					}
				}
				var role = 'student';
				if (relation['permission'] === 'M') {
					role = 'tutor';
					Rooms.getLobby().get(relation['tutorial'].id).tutors[result.user.id] = Rooms.getLobby().get(relation['tutorial'].id).get('default').get(result.user.id);
				}
				console.log("Room Id: "+relation['tutorial'].id);
				console.log("Room after creation: "+Rooms.getLobby().get(relation['tutorial'].id));
				return relation['tutorial'].addUser (result.user, {role: role});
			}));
		}).then (function (result) {
			if (result) {
				fulfill (true);
			}
		}).catch (function (err) {
			reject ('Sync Failed: ' + err);
		})
	});
};

var findTutorialSession = function (uid) {
	return userTutorial.findAll ({
		where: {
			userId: uid
		}
	});
};

module.exports = tutorial;
module.exports.forceSyncIVLE = forceSyncIVLE;
module.exports.findTutorial = findTutorial;
module.exports.findAndCountAllTutorials = findAndCountAllTutorials;
module.exports.findTutorialSession = findTutorialSession;
module.exports.findTutorialTutorID = findTutorialTutorID;
module.exports.checkIfInTutorialUserList = checkIfInTutorialUserList;
module.exports.findAndCountAllUsersInTutorial = findAndCountAllUsersInTutorial;<|endoftext|>


<commit_before>// ==UserScript==
// @name        Kurahen Premium
// @namespace   karachan.org
// @version     1.0
// @include     http://www.karachan.org/*
// @include     http://karachan.org/*
// @exclude     http://www.karachan.org/*/src/*
// @exclude     http://karachan.org/*/src/*
// ==/UserScript==

(function () {
	'use strict';

	var KurahenPremium = function () {
	};

	KurahenPremium.prototype.changeBoardTitle = function (newTitle) {
		document.title = newTitle;
		document.getElementsByClassName('boardTitle')[0].innerHTML = newTitle;
	};

	KurahenPremium.prototype.setCookie = function (name, value) {
		document.cookie = encodeURIComponent(name) + '=' + encodeURIComponent(value) + '; path=/; max-age=2592000';
	};

})();
<commit_msg>Add method for changing fonts<commit_after>// ==UserScript==
// @name        Kurahen Premium
// @namespace   karachan.org
// @version     1.0
// @include     http://www.karachan.org/*
// @include     http://karachan.org/*
// @exclude     http://www.karachan.org/*/src/*
// @exclude     http://karachan.org/*/src/*
// ==/UserScript==

(function () {
	'use strict';

	var KurahenPremium = function () {
	};

	KurahenPremium.prototype.changeBoardTitle = function (newTitle) {
		document.title = newTitle;
		document.getElementsByClassName('boardTitle')[0].innerHTML = newTitle;
	};

	KurahenPremium.prototype.setCookie = function (name, value) {
		document.cookie = encodeURIComponent(name) + '=' + encodeURIComponent(value) + '; path=/; max-age=2592000';
	};

	KurahenPremium.prototype.changeFonts = function () {
		var newLink = document.createElement('link');
		newLink.href = '//fonts.googleapis.com/css?family=Roboto:400,700&subset=latin,latin-ext';
		newLink.rel = 'stylesheet';
		var existingLink = document.getElementsByTagName('link')[0];
		existingLink.parentNode.insertBefore(newLink, existingLink);
		document.body.style.fontFamily = 'Roboto, "Helvetica Neue", Helvetica, Arial, sans-serif';
	};

})();
<|endoftext|>


<commit_before>/*
    This file customizes the CKEditor to the requirements of Kajona.

    $Id$
*/

CKEDITOR.editorConfig = function(config) {
    /*
        CKEditor offers a lot of toolbar buttons, here's a full list:

        config.toolbar_standard =
            [
                ['Source','-','Save','NewPage','Preview','-','Templates'],
                ['Cut','Copy','Paste','PasteText','PasteFromWord','-','Print', 'SpellChecker', 'Scayt'],
                ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'],
                ['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField'],
                '/',
                ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'],
                ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote'],
                ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'],
                ['Link','Unlink','Anchor'],
                ['Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak'],
                '/',
                ['Styles','Format','Font','FontSize'],
                ['TextColor','BGColor'],
                ['Maximize', 'ShowBlocks','-','About']
            ];
    */

    //default toolbar, e.g. used for the page paragraphs
    config.toolbar_standard =
        [
            ['Source','Save','-','Cut','Copy','Paste','PasteText','-'],
            ['Undo','Redo','-','RemoveFormat'],
            ['Link','Unlink','Anchor'],
            ['Image','Table','HorizontalRule','SpecialChar'],['Maximize'],
            '/',
            ['Font','FontSize'],
            ['Bold','Italic','Underline','Strike','Subscript','Superscript'],
            ['NumberedList','BulletedList','-','Outdent','Indent'],
            ['TextColor','BGColor']
        ];

    //limited toolbar, e.g. used for text-input only
    config.toolbar_minimaltext =
        [
            ['Undo','Redo','-','RemoveFormat'],
            ['Bold','Italic','Underline'],
            ['NumberedList','BulletedList','-','Outdent','Indent']
        ];

    //limited toolbar, e.g. used for the downloads and the gallery
    config.toolbar_minimal =
        [
            ['Source','Save','-'],
            ['Undo','Redo','-','RemoveFormat'],
            ['Link','Unlink'],
            ['Bold','Italic','Underline'],
            ['NumberedList','BulletedList','-','Outdent','Indent']
        ];

    //limited toolbar but with support for images
    config.toolbar_minimalimage =
        [
            ['Source','Save','-'],
            ['Undo','Redo','-','RemoveFormat'],
            ['Link','Unlink', 'Image'],
            ['Bold','Italic','Underline'],
            ['NumberedList','BulletedList','-','Outdent','Indent']
        ];

    config.toolbar_pe_full =
        [
            ['Undo','Redo','-','RemoveFormat'],
            ['Bold','Italic','Underline','Strike','Subscript','Superscript'],
            ['NumberedList','BulletedList','-','Outdent','Indent'],
            ['Link','Unlink'],
            ['Image','Table']
        ];

    config.toolbar_pe_lite =
        [
            ['Undo','Redo']
        ];

    //disable the conversion of special chars into html entities
    config.entities = false;
    config.entities_greek = false;
    config.entities_latin = false;
    config.autoParagraph = false;
    config.enterMode = CKEDITOR.ENTER_BR;
    config.width = 620;
    config.height = 250;
};<commit_msg>UPDATE: module_system | config_kajona_standard.js > remove image editor since the folderview.js depends on requirejs which is not available at the frontend<commit_after>/*
    This file customizes the CKEditor to the requirements of Kajona.

    $Id$
*/

CKEDITOR.editorConfig = function(config) {
    /*
        CKEditor offers a lot of toolbar buttons, here's a full list:

        config.toolbar_standard =
            [
                ['Source','-','Save','NewPage','Preview','-','Templates'],
                ['Cut','Copy','Paste','PasteText','PasteFromWord','-','Print', 'SpellChecker', 'Scayt'],
                ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'],
                ['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField'],
                '/',
                ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'],
                ['NumberedList','BulletedList','-','Outdent','Indent','Blockquote'],
                ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'],
                ['Link','Unlink','Anchor'],
                ['Image','Flash','Table','HorizontalRule','Smiley','SpecialChar','PageBreak'],
                '/',
                ['Styles','Format','Font','FontSize'],
                ['TextColor','BGColor'],
                ['Maximize', 'ShowBlocks','-','About']
            ];
    */

    //default toolbar, e.g. used for the page paragraphs
    config.toolbar_standard =
        [
            ['Source','Save','-','Cut','Copy','Paste','PasteText','-'],
            ['Undo','Redo','-','RemoveFormat'],
            ['Link','Unlink','Anchor'],
            ['Image','Table','HorizontalRule','SpecialChar'],['Maximize'],
            '/',
            ['Font','FontSize'],
            ['Bold','Italic','Underline','Strike','Subscript','Superscript'],
            ['NumberedList','BulletedList','-','Outdent','Indent'],
            ['TextColor','BGColor']
        ];

    //limited toolbar, e.g. used for text-input only
    config.toolbar_minimaltext =
        [
            ['Undo','Redo','-','RemoveFormat'],
            ['Bold','Italic','Underline'],
            ['NumberedList','BulletedList','-','Outdent','Indent']
        ];

    //limited toolbar, e.g. used for the downloads and the gallery
    config.toolbar_minimal =
        [
            ['Source','Save','-'],
            ['Undo','Redo','-','RemoveFormat'],
            ['Link','Unlink'],
            ['Bold','Italic','Underline'],
            ['NumberedList','BulletedList','-','Outdent','Indent']
        ];

    //limited toolbar but with support for images
    config.toolbar_minimalimage =
        [
            ['Source','Save','-'],
            ['Undo','Redo','-','RemoveFormat'],
            ['Link','Unlink', 'Image'],
            ['Bold','Italic','Underline'],
            ['NumberedList','BulletedList','-','Outdent','Indent']
        ];

    config.toolbar_pe_full =
        [
            ['Undo','Redo','-','RemoveFormat'],
            ['Bold','Italic','Underline','Strike','Subscript','Superscript'],
            ['NumberedList','BulletedList','-','Outdent','Indent'],
            ['Link','Unlink'],
            ['Table']
        ];

    config.toolbar_pe_lite =
        [
            ['Undo','Redo']
        ];

    //disable the conversion of special chars into html entities
    config.entities = false;
    config.entities_greek = false;
    config.entities_latin = false;
    config.autoParagraph = false;
    config.enterMode = CKEDITOR.ENTER_BR;
    config.width = 620;
    config.height = 250;
};<|endoftext|>


<commit_before>'use strict'; // eslint-disable-line strict

const proc = require('child_process');
const process = require('process');
const assert = require('assert');

const program = 's3cmd';
const upload = 'test1MB';
const emptyUpload = 'Utest0B';
const emptyDownload = 'Dtest0B';
const download = 'tmpfile';
const MPUpload = 'test16MB';
const MPDownload = 'MPtmpfile';
const bucket = 'universe';
const nonexist = 'nonexist';
const invalidName = 'VOID';
const emailAccount = 'sampleAccount1@sampling.com';
const lowerCaseEmail = emailAccount.toLowerCase();

const isIronman = process.env.CI ? ['-c', `${__dirname}/s3cfg`] : null;

function diff(putFile, receivedFile, done) {
    process.stdout.write(`diff ${putFile} ${receivedFile}\n`);
    proc.spawn('diff', [putFile, receivedFile]).on('exit', code => {
        assert.strictEqual(code, 0);
        done();
    });
}

function createFile(name, bytes, callback) {
    process.stdout.write(`dd if=/dev/urandom of=${name} bs=${bytes} count=1\n`);
    proc.spawn('dd', ['if=/dev/urandom', `of=${name}`,
        `bs=${bytes}`, 'count=1'], { stdio: 'inherit' }).on('exit', code => {
            assert.strictEqual(code, 0);
            callback();
        });
}

function createEmptyFile(name, callback) {
    process.stdout.write(`touch ${name}\n`);
    proc.spawn('touch', [name], { stdio: 'inherit' }).on('exit', code => {
        assert.strictEqual(code, 0);
        callback();
    });
}

function deleteFile(file, callback) {
    process.stdout.write(`rm ${file}\n`);
    proc.spawn('rm', [`${file}`]).on('exit', () => {
        callback();
    });
}

function exec(args, done, exitCode) {
    let exit = exitCode;
    if (exit === undefined) {
        exit = 0;
    }
    let av = args;
    if (isIronman) {
        av = args.concat(isIronman);
    }
    process.stdout.write(`${program} ${av}\n`);
    proc.spawn(program, av, { stdio: 'inherit' }).on('exit', code => {
        assert.strictEqual(code, exit,
                           's3cmd did not yield expected exit status.');
        done();
    });
}

// Test stdout against expected output
function checkRawOutput(args, lineFinder, testString, cb) {
    let av = args;
    if (isIronman) {
        av = args.concat(isIronman);
    }
    process.stdout.write(`${program} ${av}\n`);
    const allData = [];
    const child = proc.spawn(program, av);
    child.stdout.on('data', data => {
        allData.push(data.toString().trim());
        process.stdout.write(data.toString());
    });
    child.on('close', () => {
        const foundIt = allData.filter(item => item.indexOf(lineFinder) > -1)
                               .some(item => item.indexOf(testString) > -1);
        return cb(foundIt);
    });
}

// Pull line of interest from stderr (to get debug output)
function provideLineOfInterest(args, lineFinder, cb) {
    const av = isIronman ? args.concat(isIronman) : args;
    process.stdout.write(`${program} ${av}\n`);
    const allData = [];
    const child = proc.spawn(program, av);
    child.stderr.on('data', data => {
        allData.push(data.toString().trim());
        process.stdout.write(data.toString());
    });
    child.on('close', () => {
        const lineOfInterest = allData.find(item =>
                                            item.indexOf(lineFinder) > -1);
        const openingBracket = lineOfInterest.indexOf('{');
        const newLine = lineOfInterest.indexOf('\n');
        const endSlice = (newLine === -1) ? undefined : newLine;
        const resObject = lineOfInterest.slice(openingBracket, endSlice)
            .replace(/"/g, '\\"').replace(/'/g, '"');
        return cb(JSON.parse(resObject));
    });
}

describe('s3cmd putBucket', () => {
    it('should put a valid bucket', done => {
        exec(['mb', `s3://${bucket}`], done);
    });

    it('put the same bucket, should fail', done => {
        exec(['mb', `s3://${bucket}`], done, 13);
    });

    it('put an invalid bucket, should fail', done => {
        exec(['mb', `s3://${invalidName}`], done, 11);
    });
});

describe('s3cmd put and get bucket ACLs', function aclBuck() {
    this.timeout(60000);
    // Note that s3cmd first gets the current ACL and then
    // sets the new one so by running setacl you are running a
    // get and a put
    it('should set a canned ACL', done => {
        exec(['setacl', `s3://${bucket}`, '--acl-public'], done);
    });

    it('should get canned ACL that was set', done => {
        checkRawOutput(['info', `s3://${bucket}`], 'ACL', '*anon*: READ',
        (foundIt) => {
            assert(foundIt);
            done();
        });
    });

    it('should set a specific ACL', done => {
        exec(['setacl', `s3://${bucket}`,
        `--acl-grant=write:${emailAccount}`], done);
    });

    it('should get specific ACL that was set', done => {
        checkRawOutput(['info', `s3://${bucket}`], 'ACL',
        `${lowerCaseEmail}: WRITE`, (foundIt) => {
            assert(foundIt);
            done();
        });
    });
});

describe('s3cmd getBucket', () => {
    it('should list existing bucket', done => {
        exec(['ls', `s3://${bucket}`], done);
    });

    it('list non existing bucket, should fail', done => {
        exec(['ls', `s3://${nonexist}`], done, 12);
    });
});

describe('s3cmd getService', () => {
    it("should get a list of a user's buckets", done => {
        checkRawOutput(['ls'], 's3://', `${bucket}`, (foundIt) => {
            assert(foundIt);
            done();
        });
    });

    it("should have response headers matching AWS's response headers",
        done => {
            provideLineOfInterest(['ls', '--debug'], 'DEBUG: Response: {',
            parsedObject => {
                assert(parsedObject.headers['x-amz-id-2']);
                assert.strictEqual(parsedObject.headers.server, 'AmazonS3');
                assert(parsedObject.headers['transfer-encoding']);
                assert(parsedObject.headers['x-amz-request-id']);
                const gmtDate = new Date(parsedObject.headers.date)
                    .toUTCString();
                assert.strictEqual(parsedObject.headers.date, gmtDate);
                assert.strictEqual(parsedObject
                    .headers['content-type'], 'application/xml');
                assert.strictEqual(parsedObject
                    .headers['set-cookie'], undefined);
                done();
            });
        });
});

describe('s3cmd putObject', () => {
    before('create file to put', done => {
        createFile(upload, 1048576, done);
    });

    it('should put file in existing bucket', done => {
        exec(['put', upload, `s3://${bucket}`], done);
    });

    it('should put file with the same name in existing bucket', done => {
        exec(['put', upload, `s3://${bucket}`], done);
    });

    it('put file in non existing bucket, should fail', done => {
        exec(['put', upload, `s3://${nonexist}`], done, 12);
    });
});

describe('s3cmd getObject', function toto() {
    this.timeout(0);
    after('delete downloaded file', done => {
        deleteFile(download, done);
    });

    it('should get existing file in existing bucket', done => {
        exec(['get', `s3://${bucket}/${upload}`, download], done);
    });

    it('downloaded file should equal uploaded file', done => {
        diff(upload, download, done);
    });

    it('get non existing file in existing bucket, should fail', done => {
        exec(['get', `s3://${bucket}/${nonexist}`, 'fail'], done, 12);
    });

    it('get file in non existing bucket, should fail', done => {
        exec(['get', `s3://${nonexist}/${nonexist}`, 'fail2'], done, 12);
    });
});

describe('s3cmd put and get object ACLs', function aclObj() {
    this.timeout(60000);
    // Note that s3cmd first gets the current ACL and then
    // sets the new one so by running setacl you are running a
    // get and a put
    it('should set a canned ACL', done => {
        exec(['setacl', `s3://${bucket}/${upload}`, '--acl-public'], done);
    });

    it('should get canned ACL that was set', done => {
        checkRawOutput(['info', `s3://${bucket}/${upload}`], 'ACL',
        '*anon*: READ', (foundIt) => {
            assert(foundIt);
            done();
        });
    });

    it('should set a specific ACL', done => {
        exec(['setacl', `s3://${bucket}/${upload}`,
            `--acl-grant=read:${emailAccount}`], done);
    });

    it('should get specific ACL that was set', done => {
        checkRawOutput(['info', `s3://${bucket}/${upload}`], 'ACL',
        `${lowerCaseEmail}: READ`, (foundIt) => {
            assert(foundIt);
            done();
        });
    });

    it('should return error if set acl for ' +
        'nonexistent object', done => {
        exec(['setacl', `s3://${bucket}/${nonexist}`,
            '--acl-public'], done, 12);
    });
});

describe('s3cmd delObject', () => {
    it('should delete existing object', done => {
        exec(['rm', `s3://${bucket}/${upload}`], done);
    });

    it('delete an already deleted object, should return a 204', done => {
        provideLineOfInterest(['rm', `s3://${bucket}/${upload}`, '--debug'],
        'DEBUG: Response: {', parsedObject => {
            assert.strictEqual(parsedObject.status, 204);
            done();
        });
    });

    it('delete non-existing object, should return a 204', done => {
        provideLineOfInterest(['rm', `s3://${bucket}/${nonexist}`, '--debug'],
        'DEBUG: Response: {', parsedObject => {
            assert.strictEqual(parsedObject.status, 204);
            done();
        });
    });

    it('try to get the deleted object, should fail', done => {
        exec(['get', `s3://${bucket}/${upload}`, download], done, 12);
    });
});

describe('connector edge cases', function tata() {
    this.timeout(0);
    before('create file to put', done => {
        createEmptyFile(emptyUpload, done);
    });
    after('delete uploaded and downloaded file', done => {
        deleteFile(upload, () => {
            deleteFile(download, () => {
                deleteFile(emptyUpload, () => {
                    deleteFile(emptyDownload, done);
                });
            });
        });
    });

    it('should put previous file in existing bucket', done => {
        exec(['put', upload, `s3://${bucket}`], done);
    });

    it('should get existing file in existing bucket', done => {
        exec(['get', `s3://${bucket}/${upload}`, download], done);
    });

    it('should put a 0 Bytes file', done => {
        exec(['put', emptyUpload, `s3://${bucket}`], done);
    });

    it('should get a 0 Bytes file', done => {
        exec(['get', `s3://${bucket}/${emptyUpload}`, emptyDownload], done);
    });

    it('should delete a 0 Bytes file', done => {
        exec(['del', `s3://${bucket}/${emptyUpload}`], done);
    });
});

describe('s3cmd multipart upload', function titi() {
    this.timeout(0);
    before('create the multipart file', done => {
        this.timeout(60000);
        createFile(MPUpload, 16777216, done);
    });

    after('delete the multipart and the downloaded file', done => {
        deleteFile(MPUpload, () => {
            deleteFile(MPDownload, done);
        });
    });

    it('should put an object via a multipart upload', done => {
        exec(['put', MPUpload, `s3://${bucket}`], done);
    });

    it('should list multipart uploads', done => {
        exec(['multipart', `s3://${bucket}`], done);
    });

    it('should get an object that was put via multipart upload', done => {
        exec(['get', `s3://${bucket}/${MPUpload}`, MPDownload], done);
    });

    it('downloaded file should equal uploaded file', done => {
        diff(MPUpload, MPDownload, done);
    });

    it('should delete multipart uploaded object', done => {
        exec(['rm', `s3://${bucket}/${MPUpload}`], done);
    });

    it('should not be able to get deleted object', done => {
        exec(['get', `s3://${bucket}/${MPUpload}`, download], done, 12);
    });
});

describe('s3cmd put, get and delete object with spaces ' +
    'in object key names', function test() {
    this.timeout(0);
    const keyWithSpacesAndPluses = 'key with spaces and + pluses +';
    before('create file to put', done => {
        createFile(upload, 1000, done);
    });
    after('delete uploaded and downloaded file', done => {
        deleteFile(upload, () => {
            deleteFile(download, done);
        });
    });

    const bucket = 'freshbucket';

    it('should put a valid bucket', done => {
        exec(['mb', `s3://${bucket}`], done);
    });

    it('should put file with spaces in key in existing bucket', done => {
        exec(['put', upload, `s3://${bucket}/${keyWithSpacesAndPluses}`], done);
    });

    it('should get file with spaces', done => {
        exec(['get', `s3://${bucket}/${keyWithSpacesAndPluses}`, download],
             done);
    });

    it('should list bucket showing file with spaces', done => {
        checkRawOutput(['ls', `s3://${bucket}`], `s3://${bucket}`,
        keyWithSpacesAndPluses, foundIt => {
            assert(foundIt);
            done();
        });
    });

    it('downloaded file should equal uploaded file', done => {
        diff(upload, download, done);
    });

    it('should delete file with spaces', done => {
        exec(['del', `s3://${bucket}/${keyWithSpacesAndPluses}`], done);
    });

    it('should delete empty bucket', done => {
        exec(['rb', `s3://${bucket}`], done);
    });
});

describe('s3cmd info', () => {
// test that CORS and POLICY are returned as 'none'
    it('should find that policy has a value of none', done => {
        checkRawOutput(['info', `s3://${bucket}`], 'policy', 'none',
        foundIt => {
            assert(foundIt);
            done();
        });
    });

    it('should find that cors has a value of none', done => {
        checkRawOutput(['info', `s3://${bucket}`], 'cors', 'none', foundIt => {
            assert(foundIt);
            done();
        });
    });
});

describe('s3cmd delBucket', () => {
    it('delete non-empty bucket, should fail', done => {
        exec(['rb', `s3://${bucket}`], done, 13);
    });

    it('should delete remaining object', done => {
        exec(['rm', `s3://${bucket}/${upload}`], done);
    });

    it('should delete empty bucket', done => {
        exec(['rb', `s3://${bucket}`], done);
    });

    it('try to get the deleted bucket, should fail', done => {
        exec(['ls', `s3://${bucket}`], done, 12);
    });
});
<commit_msg>FIX: Random error on ci<commit_after>'use strict'; // eslint-disable-line strict

const proc = require('child_process');
const process = require('process');
const assert = require('assert');

const program = 's3cmd';
const upload = 'test1MB';
const emptyUpload = 'Utest0B';
const emptyDownload = 'Dtest0B';
const download = 'tmpfile';
const MPUpload = 'test16MB';
const MPDownload = 'MPtmpfile';
const bucket = 'universe';
const nonexist = 'nonexist';
const invalidName = 'VOID';
const emailAccount = 'sampleAccount1@sampling.com';
const lowerCaseEmail = emailAccount.toLowerCase();

const isIronman = process.env.CI ? ['-c', `${__dirname}/s3cfg`] : null;

function diff(putFile, receivedFile, done) {
    process.stdout.write(`diff ${putFile} ${receivedFile}\n`);
    proc.spawn('diff', [putFile, receivedFile]).on('exit', code => {
        assert.strictEqual(code, 0);
        done();
    });
}

function createFile(name, bytes, callback) {
    process.stdout.write(`dd if=/dev/urandom of=${name} bs=${bytes} count=1\n`);
    proc.spawn('dd', ['if=/dev/urandom', `of=${name}`,
        `bs=${bytes}`, 'count=1'], { stdio: 'inherit' }).on('exit', code => {
            assert.strictEqual(code, 0);
            callback();
        });
}

function createEmptyFile(name, callback) {
    process.stdout.write(`touch ${name}\n`);
    proc.spawn('touch', [name], { stdio: 'inherit' }).on('exit', code => {
        assert.strictEqual(code, 0);
        callback();
    });
}

function deleteFile(file, callback) {
    process.stdout.write(`rm ${file}\n`);
    proc.spawn('rm', [`${file}`]).on('exit', () => {
        callback();
    });
}

function exec(args, done, exitCode) {
    let exit = exitCode;
    if (exit === undefined) {
        exit = 0;
    }
    let av = args;
    if (isIronman) {
        av = args.concat(isIronman);
    }
    process.stdout.write(`${program} ${av}\n`);
    proc.spawn(program, av, { stdio: 'inherit' }).on('exit', code => {
        assert.strictEqual(code, exit,
                           's3cmd did not yield expected exit status.');
        done();
    });
}

// Test stdout against expected output
function checkRawOutput(args, lineFinder, testString, cb) {
    let av = args;
    if (isIronman) {
        av = args.concat(isIronman);
    }
    process.stdout.write(`${program} ${av}\n`);
    const allData = [];
    const child = proc.spawn(program, av);
    child.stdout.on('data', data => {
        allData.push(data.toString());
        process.stdout.write(data.toString());
    });
    child.on('close', () => {
        const foundIt = allData.join('').split('\n')
            .filter(item => item.indexOf(lineFinder) > -1)
            .some(item => item.indexOf(testString) > -1);
        return cb(foundIt);
    });
}

function findEndString(data, start) {
    const delimiter = data[start];
    const end = data.length;
    for (let i = start + 1; i < end; ++i) {
        if (data[i] === delimiter) {
            return (i);
        } else if (data[i] === '\\') {
            ++i;
        }
    }
    return (-1);
}

function findEndJson(data, start) {
    let count = 0;
    const end = data.length;
    for (let i = start; i < end; ++i) {
        if (data[i] === '{') {
            ++count;
        } else if (data[i] === '}') {
            --count;
        } else if (data[i] === '"' || data[i] === "'") {
            i = findEndString(data, i);
        }
        if (count === 0) {
            return (i);
        }
    }
    return (-1);
}

function readJsonFromChild(child, lineFinder, cb) {
    const allData = [];
    child.stderr.on('data', data => {
        allData.push(data.toString());
        process.stdout.write(data.toString());
    });
    child.on('close', () => {
        const data = allData.join('');
        const findLine = data.indexOf(lineFinder);
        const findBrace = data.indexOf('{', findLine);
        const findEnd = findEndJson(data, findBrace);
        const endJson = data.substring(findBrace, findEnd + 1)
            .replace(/"/g, '\\"').replace(/'/g, '"');
        return cb(JSON.parse(endJson));
    });
}

// Pull line of interest from stderr (to get debug output)
function provideLineOfInterest(args, lineFinder, cb) {
    const av = isIronman ? args.concat(isIronman) : args;
    process.stdout.write(`${program} ${av}\n`);
    const child = proc.spawn(program, av);
    readJsonFromChild(child, lineFinder, cb);
}

describe('s3cmd putBucket', () => {
    it('should put a valid bucket', done => {
        exec(['mb', `s3://${bucket}`], done);
    });

    it('put the same bucket, should fail', done => {
        exec(['mb', `s3://${bucket}`], done, 13);
    });

    it('put an invalid bucket, should fail', done => {
        exec(['mb', `s3://${invalidName}`], done, 11);
    });
});

describe('s3cmd put and get bucket ACLs', function aclBuck() {
    this.timeout(60000);
    // Note that s3cmd first gets the current ACL and then
    // sets the new one so by running setacl you are running a
    // get and a put
    it('should set a canned ACL', done => {
        exec(['setacl', `s3://${bucket}`, '--acl-public'], done);
    });

    it('should get canned ACL that was set', done => {
        checkRawOutput(['info', `s3://${bucket}`], 'ACL', '*anon*: READ',
        foundIt => {
            assert(foundIt);
            done();
        });
    });

    it('should set a specific ACL', done => {
        exec(['setacl', `s3://${bucket}`,
        `--acl-grant=write:${emailAccount}`], done);
    });

    it('should get specific ACL that was set', done => {
        checkRawOutput(['info', `s3://${bucket}`], 'ACL',
        `${lowerCaseEmail}: WRITE`, foundIt => {
            assert(foundIt);
            done();
        });
    });
});

describe('s3cmd getBucket', () => {
    it('should list existing bucket', done => {
        exec(['ls', `s3://${bucket}`], done);
    });

    it('list non existing bucket, should fail', done => {
        exec(['ls', `s3://${nonexist}`], done, 12);
    });
});

describe('s3cmd getService', () => {
    it("should get a list of a user's buckets", done => {
        checkRawOutput(['ls'], 's3://', `${bucket}`, foundIt => {
            assert(foundIt);
            done();
        });
    });

    it("should have response headers matching AWS's response headers",
        done => {
            provideLineOfInterest(['ls', '--debug'], 'DEBUG: Response: {',
            parsedObject => {
                assert(parsedObject.headers['x-amz-id-2']);
                assert.strictEqual(parsedObject.headers.server, 'AmazonS3');
                assert(parsedObject.headers['transfer-encoding']);
                assert(parsedObject.headers['x-amz-request-id']);
                const gmtDate = new Date(parsedObject.headers.date)
                    .toUTCString();
                assert.strictEqual(parsedObject.headers.date, gmtDate);
                assert.strictEqual(parsedObject
                    .headers['content-type'], 'application/xml');
                assert.strictEqual(parsedObject
                    .headers['set-cookie'], undefined);
                done();
            });
        });
});

describe('s3cmd putObject', () => {
    before('create file to put', done => {
        createFile(upload, 1048576, done);
    });

    it('should put file in existing bucket', done => {
        exec(['put', upload, `s3://${bucket}`], done);
    });

    it('should put file with the same name in existing bucket', done => {
        exec(['put', upload, `s3://${bucket}`], done);
    });

    it('put file in non existing bucket, should fail', done => {
        exec(['put', upload, `s3://${nonexist}`], done, 12);
    });
});

describe('s3cmd getObject', function toto() {
    this.timeout(0);
    after('delete downloaded file', done => {
        deleteFile(download, done);
    });

    it('should get existing file in existing bucket', done => {
        exec(['get', `s3://${bucket}/${upload}`, download], done);
    });

    it('downloaded file should equal uploaded file', done => {
        diff(upload, download, done);
    });

    it('get non existing file in existing bucket, should fail', done => {
        exec(['get', `s3://${bucket}/${nonexist}`, 'fail'], done, 12);
    });

    it('get file in non existing bucket, should fail', done => {
        exec(['get', `s3://${nonexist}/${nonexist}`, 'fail2'], done, 12);
    });
});

describe('s3cmd put and get object ACLs', function aclObj() {
    this.timeout(60000);
    // Note that s3cmd first gets the current ACL and then
    // sets the new one so by running setacl you are running a
    // get and a put
    it('should set a canned ACL', done => {
        exec(['setacl', `s3://${bucket}/${upload}`, '--acl-public'], done);
    });

    it('should get canned ACL that was set', done => {
        checkRawOutput(['info', `s3://${bucket}/${upload}`], 'ACL',
        '*anon*: READ', foundIt => {
            assert(foundIt);
            done();
        });
    });

    it('should set a specific ACL', done => {
        exec(['setacl', `s3://${bucket}/${upload}`,
            `--acl-grant=read:${emailAccount}`], done);
    });

    it('should get specific ACL that was set', done => {
        checkRawOutput(['info', `s3://${bucket}/${upload}`], 'ACL',
        `${lowerCaseEmail}: READ`, foundIt => {
            assert(foundIt);
            done();
        });
    });

    it('should return error if set acl for ' +
        'nonexistent object', done => {
        exec(['setacl', `s3://${bucket}/${nonexist}`,
            '--acl-public'], done, 12);
    });
});

describe('s3cmd delObject', () => {
    it('should delete existing object', done => {
        exec(['rm', `s3://${bucket}/${upload}`], done);
    });

    it('delete an already deleted object, should return a 204', done => {
        provideLineOfInterest(['rm', `s3://${bucket}/${upload}`, '--debug'],
        'DEBUG: Response: {', parsedObject => {
            assert.strictEqual(parsedObject.status, 204);
            done();
        });
    });

    it('delete non-existing object, should return a 204', done => {
        provideLineOfInterest(['rm', `s3://${bucket}/${nonexist}`, '--debug'],
        'DEBUG: Response: {', parsedObject => {
            assert.strictEqual(parsedObject.status, 204);
            done();
        });
    });

    it('try to get the deleted object, should fail', done => {
        exec(['get', `s3://${bucket}/${upload}`, download], done, 12);
    });
});

describe('connector edge cases', function tata() {
    this.timeout(0);
    before('create file to put', done => {
        createEmptyFile(emptyUpload, done);
    });
    after('delete uploaded and downloaded file', done => {
        deleteFile(upload, () => {
            deleteFile(download, () => {
                deleteFile(emptyUpload, () => {
                    deleteFile(emptyDownload, done);
                });
            });
        });
    });

    it('should put previous file in existing bucket', done => {
        exec(['put', upload, `s3://${bucket}`], done);
    });

    it('should get existing file in existing bucket', done => {
        exec(['get', `s3://${bucket}/${upload}`, download], done);
    });

    it('should put a 0 Bytes file', done => {
        exec(['put', emptyUpload, `s3://${bucket}`], done);
    });

    it('should get a 0 Bytes file', done => {
        exec(['get', `s3://${bucket}/${emptyUpload}`, emptyDownload], done);
    });

    it('should delete a 0 Bytes file', done => {
        exec(['del', `s3://${bucket}/${emptyUpload}`], done);
    });
});

describe('s3cmd multipart upload', function titi() {
    this.timeout(0);
    before('create the multipart file', done => {
        this.timeout(60000);
        createFile(MPUpload, 16777216, done);
    });

    after('delete the multipart and the downloaded file', done => {
        deleteFile(MPUpload, () => {
            deleteFile(MPDownload, done);
        });
    });

    it('should put an object via a multipart upload', done => {
        exec(['put', MPUpload, `s3://${bucket}`], done);
    });

    it('should list multipart uploads', done => {
        exec(['multipart', `s3://${bucket}`], done);
    });

    it('should get an object that was put via multipart upload', done => {
        exec(['get', `s3://${bucket}/${MPUpload}`, MPDownload], done);
    });

    it('downloaded file should equal uploaded file', done => {
        diff(MPUpload, MPDownload, done);
    });

    it('should delete multipart uploaded object', done => {
        exec(['rm', `s3://${bucket}/${MPUpload}`], done);
    });

    it('should not be able to get deleted object', done => {
        exec(['get', `s3://${bucket}/${MPUpload}`, download], done, 12);
    });
});

describe('s3cmd put, get and delete object with spaces ' +
    'in object key names', function test() {
    this.timeout(0);
    const keyWithSpacesAndPluses = 'key with spaces and + pluses +';
    before('create file to put', done => {
        createFile(upload, 1000, done);
    });
    after('delete uploaded and downloaded file', done => {
        deleteFile(upload, () => {
            deleteFile(download, done);
        });
    });

    const bucket = 'freshbucket';

    it('should put a valid bucket', done => {
        exec(['mb', `s3://${bucket}`], done);
    });

    it('should put file with spaces in key in existing bucket', done => {
        exec(['put', upload, `s3://${bucket}/${keyWithSpacesAndPluses}`], done);
    });

    it('should get file with spaces', done => {
        exec(['get', `s3://${bucket}/${keyWithSpacesAndPluses}`, download],
             done);
    });

    it('should list bucket showing file with spaces', done => {
        checkRawOutput(['ls', `s3://${bucket}`], `s3://${bucket}`,
        keyWithSpacesAndPluses, foundIt => {
            assert(foundIt);
            done();
        });
    });

    it('downloaded file should equal uploaded file', done => {
        diff(upload, download, done);
    });

    it('should delete file with spaces', done => {
        exec(['del', `s3://${bucket}/${keyWithSpacesAndPluses}`], done);
    });

    it('should delete empty bucket', done => {
        exec(['rb', `s3://${bucket}`], done);
    });
});

describe('s3cmd info', () => {
// test that CORS and POLICY are returned as 'none'
    it('should find that policy has a value of none', done => {
        checkRawOutput(['info', `s3://${bucket}`], 'policy', 'none',
        foundIt => {
            assert(foundIt);
            done();
        });
    });

    it('should find that cors has a value of none', done => {
        checkRawOutput(['info', `s3://${bucket}`], 'cors', 'none', foundIt => {
            assert(foundIt);
            done();
        });
    });
});

describe('s3cmd delBucket', () => {
    it('delete non-empty bucket, should fail', done => {
        exec(['rb', `s3://${bucket}`], done, 13);
    });

    it('should delete remaining object', done => {
        exec(['rm', `s3://${bucket}/${upload}`], done);
    });

    it('should delete empty bucket', done => {
        exec(['rb', `s3://${bucket}`], done);
    });

    it('try to get the deleted bucket, should fail', done => {
        exec(['ls', `s3://${bucket}`], done, 12);
    });
});
<|endoftext|>


<commit_before>const ogs = require('../../index');

describe('video', function () {
  it('Test Youtube Video - Should Return correct Open Graph Info', function () {
    return ogs({
      url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
    }, function (error, result, response) {
      console.log('error:', error);
      console.log('result:', result);
      expect(error).to.be.eql(false);
      expect(result.alAndroidAppName).to.be.eql('YouTube');
      expect(result.alAndroidPackage).to.be.eql('com.google.android.youtube');
      expect(result.alAndroidUrl).to.be.eql('vnd.youtube://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=applinks');
      expect(result.alIosAppName).to.be.eql('YouTube');
      expect(result.alIosAppStoreId).to.be.eql('544007664');
      expect(result.alIosUrl).to.be.eql('vnd.youtube://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=applinks');
      expect(result.alWebUrl).to.be.eql('https://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=applinks');
      expect(result.ogSiteName).to.be.eql('YouTube');
      expect(result.ogUrl).to.be.eql('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
      expect(result.ogTitle).to.be.eql('Rick Astley - Never Gonna Give You Up (Video)');
      expect(result.ogDescription).to.be.an('string').and.to.not.be.empty;
      expect(result.ogType).to.be.eql('video.other');
      expect(result.ogLocale).to.be.oneOf(['en', 'en-US', 'nl-NL']);
      expect(result.twitterCard).to.be.eql('player');
      expect(result.twitterSite).to.be.eql('@youtube');
      expect(result.twitterTitle).to.be.eql('Rick Astley - Never Gonna Give You Up (Video)');
      expect(result.twitterDescription).to.be.an('string').and.to.not.be.empty;
      expect(result.twitterAppNameiPhone).to.be.eql('YouTube');
      expect(result.twitterAppIdiPhone).to.be.eql('544007664');
      expect(result.twitterAppNameiPad).to.be.eql('YouTube');
      expect(result.twitterAppIdiPad).to.be.eql('544007664');
      expect(result.twitterUrl).to.be.eql('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
      expect(result.ogDate).to.be.oneOf(['2009-10-24', undefined]);
      expect(result.twitterAppUrliPhone).to.be.eql('vnd.youtube://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=applinks');
      expect(result.twitterAppUrliPad).to.be.eql('vnd.youtube://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=applinks');
      expect(result.twitterAppNameGooglePlay).to.be.eql('YouTube');
      expect(result.twitterAppIdGooglePlay).to.be.eql('com.google.android.youtube');
      expect(result.twitterAppUrlGooglePlay).to.be.eql('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
      expect(result.ogImage).to.be.eql({
        url: 'https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg',
        width: '1280',
        height: '720',
        type: 'jpg',
      });
      expect(result.ogVideo).to.be.eql({
        url: 'https://www.youtube.com/embed/dQw4w9WgXcQ',
        width: '1280',
        height: '720',
        type: 'text/html',
      });
      expect(result.twitterImage).to.be.eql({
        url: 'https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg',
        width: null,
        height: null,
        alt: null,
      });
      expect(result.twitterPlayer).to.be.eql({
        url: 'https://www.youtube.com/embed/dQw4w9WgXcQ',
        width: '1280',
        height: '720',
        stream: null,
      });
      expect(result.requestUrl).to.be.eql('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
      expect(result.charset).to.be.eql('utf8');
      expect(result.success).to.be.eql(true);
      if (result.ogDate === undefined) result.ogDate = 'hack because sometimes this does not come back for some reason';
      expect(result).to.have.all.keys(
        'alAndroidAppName',
        'alAndroidPackage',
        'alAndroidUrl',
        'alIosAppName',
        'alIosAppStoreId',
        'alIosUrl',
        'alWebUrl',
        'ogDate',
        'ogDescription',
        'ogImage',
        'ogLocale',
        'ogSiteName',
        'ogTitle',
        'ogType',
        'ogUrl',
        'ogVideo',
        'requestUrl',
        'success',
        'charset',
        'twitterAppIdGooglePlay',
        'twitterAppIdiPad',
        'twitterAppIdiPhone',
        'twitterAppNameGooglePlay',
        'twitterAppNameiPad',
        'twitterAppNameiPhone',
        'twitterAppUrlGooglePlay',
        'twitterAppUrliPad',
        'twitterAppUrliPhone',
        'twitterCard',
        'twitterDescription',
        'twitterImage',
        'twitterPlayer',
        'twitterSite',
        'twitterTitle',
        'twitterUrl',
      );
      expect(response).to.be.an('object').and.to.not.be.empty;
    });
  });
  it('Test Twitch.tv Video - Should Return correct Open Graph Info', function () {
    return ogs({
      url: 'https://jshemas.github.io/openGraphScraperPages/twitch.html',
    }, function (error, result, response) {
      console.log('error:', error);
      console.log('result:', result);
      expect(error).to.be.eql(false);
      expect(result.ogSiteName).to.be.eql('Twitch');
      expect(result.twitterSite).to.be.eql('@twitch');
      expect(result.ogLocale).to.be.eql('en-US');
      expect(result.ogTitle).to.be.oneOf(['Twitch', 'AI Soundscapes, Trials of Mana', 'AI Soundscapes, Trials of Mana - Vinesauce on Twitch']);
      expect(result.ogDescription).to.be.an('string').and.to.not.be.empty;
      expect(result.ogUrl).to.be.eql('https://www.twitch.tv/videos/632214184');
      expect(result.ogType).to.be.oneOf(['website', 'video.other']);
      expect(result.ogImage).to.be.to.be.an('object').and.to.not.be.empty;
      expect(result.requestUrl).to.be.eql('https://jshemas.github.io/openGraphScraperPages/twitch.html');
      expect(result.charset).to.be.eql('utf8');
      expect(result.success).to.be.eql(true);
      expect(result).to.have.all.keys(
        'ogDescription',
        'ogImage',
        'ogLocale',
        'ogSiteName',
        'ogTitle',
        'ogType',
        'ogUrl',
        'requestUrl',
        'success',
        'charset',
        'twitterSite',
      );
      expect(response).to.be.an('object').and.to.not.be.empty;
    });
  });
});
<commit_msg>fixing tests<commit_after>const ogs = require('../../index');

describe('video', function () {
  it('Test Youtube Video - Should Return correct Open Graph Info', function () {
    return ogs({
      url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
    }, function (error, result, response) {
      console.log('error:', error);
      console.log('result:', result);
      expect(error).to.be.eql(false);
      expect(result.alAndroidAppName).to.be.eql('YouTube');
      expect(result.alAndroidPackage).to.be.eql('com.google.android.youtube');
      expect(result.alAndroidUrl).to.be.eql('vnd.youtube://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=applinks');
      expect(result.alIosAppName).to.be.eql('YouTube');
      expect(result.alIosAppStoreId).to.be.eql('544007664');
      expect(result.alIosUrl).to.be.eql('vnd.youtube://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=applinks');
      expect(result.alWebUrl).to.be.oneOf(['https://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=applinks', 'http://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=applinks']);
      expect(result.ogSiteName).to.be.eql('YouTube');
      expect(result.ogUrl).to.be.eql('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
      expect(result.ogTitle).to.be.eql('Rick Astley - Never Gonna Give You Up (Video)');
      expect(result.ogDescription).to.be.an('string').and.to.not.be.empty;
      expect(result.ogType).to.be.eql('video.other');
      expect(result.ogLocale).to.be.oneOf(['en', 'en-US', 'nl-NL']);
      expect(result.twitterCard).to.be.eql('player');
      expect(result.twitterSite).to.be.eql('@youtube');
      expect(result.twitterTitle).to.be.eql('Rick Astley - Never Gonna Give You Up (Video)');
      expect(result.twitterDescription).to.be.an('string').and.to.not.be.empty;
      expect(result.twitterAppNameiPhone).to.be.eql('YouTube');
      expect(result.twitterAppIdiPhone).to.be.eql('544007664');
      expect(result.twitterAppNameiPad).to.be.eql('YouTube');
      expect(result.twitterAppIdiPad).to.be.eql('544007664');
      expect(result.twitterUrl).to.be.eql('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
      expect(result.ogDate).to.be.oneOf(['2009-10-24', undefined]);
      expect(result.twitterAppUrliPhone).to.be.eql('vnd.youtube://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=applinks');
      expect(result.twitterAppUrliPad).to.be.eql('vnd.youtube://www.youtube.com/watch?v=dQw4w9WgXcQ&feature=applinks');
      expect(result.twitterAppNameGooglePlay).to.be.eql('YouTube');
      expect(result.twitterAppIdGooglePlay).to.be.eql('com.google.android.youtube');
      expect(result.twitterAppUrlGooglePlay).to.be.eql('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
      expect(result.ogImage).to.be.eql({
        url: 'https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg',
        width: '1280',
        height: '720',
        type: 'jpg',
      });
      expect(result.ogVideo).to.be.eql({
        url: 'https://www.youtube.com/embed/dQw4w9WgXcQ',
        width: '1280',
        height: '720',
        type: 'text/html',
      });
      expect(result.twitterImage).to.be.eql({
        url: 'https://i.ytimg.com/vi/dQw4w9WgXcQ/maxresdefault.jpg',
        width: null,
        height: null,
        alt: null,
      });
      expect(result.twitterPlayer).to.be.eql({
        url: 'https://www.youtube.com/embed/dQw4w9WgXcQ',
        width: '1280',
        height: '720',
        stream: null,
      });
      expect(result.requestUrl).to.be.eql('https://www.youtube.com/watch?v=dQw4w9WgXcQ');
      expect(result.charset).to.be.eql('utf8');
      expect(result.success).to.be.eql(true);
      if (result.ogDate === undefined) result.ogDate = 'hack because sometimes this does not come back for some reason';
      expect(result).to.have.all.keys(
        'alAndroidAppName',
        'alAndroidPackage',
        'alAndroidUrl',
        'alIosAppName',
        'alIosAppStoreId',
        'alIosUrl',
        'alWebUrl',
        'ogDate',
        'ogDescription',
        'ogImage',
        'ogLocale',
        'ogSiteName',
        'ogTitle',
        'ogType',
        'ogUrl',
        'ogVideo',
        'requestUrl',
        'success',
        'charset',
        'twitterAppIdGooglePlay',
        'twitterAppIdiPad',
        'twitterAppIdiPhone',
        'twitterAppNameGooglePlay',
        'twitterAppNameiPad',
        'twitterAppNameiPhone',
        'twitterAppUrlGooglePlay',
        'twitterAppUrliPad',
        'twitterAppUrliPhone',
        'twitterCard',
        'twitterDescription',
        'twitterImage',
        'twitterPlayer',
        'twitterSite',
        'twitterTitle',
        'twitterUrl',
      );
      expect(response).to.be.an('object').and.to.not.be.empty;
    });
  });
  it('Test Twitch.tv Video - Should Return correct Open Graph Info', function () {
    return ogs({
      url: 'https://jshemas.github.io/openGraphScraperPages/twitch.html',
    }, function (error, result, response) {
      console.log('error:', error);
      console.log('result:', result);
      expect(error).to.be.eql(false);
      expect(result.ogSiteName).to.be.eql('Twitch');
      expect(result.twitterSite).to.be.eql('@twitch');
      expect(result.ogLocale).to.be.eql('en-US');
      expect(result.ogTitle).to.be.oneOf(['Twitch', 'AI Soundscapes, Trials of Mana', 'AI Soundscapes, Trials of Mana - Vinesauce on Twitch']);
      expect(result.ogDescription).to.be.an('string').and.to.not.be.empty;
      expect(result.ogUrl).to.be.eql('https://www.twitch.tv/videos/632214184');
      expect(result.ogType).to.be.oneOf(['website', 'video.other']);
      expect(result.ogImage).to.be.to.be.an('object').and.to.not.be.empty;
      expect(result.requestUrl).to.be.eql('https://jshemas.github.io/openGraphScraperPages/twitch.html');
      expect(result.charset).to.be.eql('utf8');
      expect(result.success).to.be.eql(true);
      expect(result).to.have.all.keys(
        'ogDescription',
        'ogImage',
        'ogLocale',
        'ogSiteName',
        'ogTitle',
        'ogType',
        'ogUrl',
        'requestUrl',
        'success',
        'charset',
        'twitterSite',
      );
      expect(response).to.be.an('object').and.to.not.be.empty;
    });
  });
});
<|endoftext|>


<commit_before>// Copyright 2015 Samsung Electronics Co., Ltd.
//
// 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.

assert ('abcd\
efgh' === 'abcdefgh');

assert ('\'' === "'");
assert ("\'" === "'");
assert ('\"' === '"');
assert ("\"" === '"');

//
// TODO
//   Extend the test by verifying character codes after String.charCodeAt would be implemented
//
assert ((new String ('\\')).length === 1);
assert ((new String ('\b')).length === 1);
assert ((new String ('\f')).length === 1);
assert ((new String ('\n')).length === 1);
assert ((new String ('\r')).length === 1);
assert ((new String ('\t')).length === 1);
assert ((new String ('\v')).length === 1);

// 'p' is not SingleEscapeCharacter
assert ('\p' === 'p');

var v\u0061riable = 'valu\u0065';
assert (variable === 'value');
<commit_msg>Extend the escape sequences test by verifying character codes. (#1428)<commit_after>// Copyright 2015 Samsung Electronics Co., Ltd.
//
// 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.

assert ('abcd\
efgh' === 'abcdefgh');

assert ('\'' === "'");
assert ("\'" === "'");
assert ('\"' === '"');
assert ("\"" === '"');

assert ((new String ('\\')).length === 1);
assert ((new String ('\b')).length === 1);
assert ((new String ('\f')).length === 1);
assert ((new String ('\n')).length === 1);
assert ((new String ('\r')).length === 1);
assert ((new String ('\t')).length === 1);
assert ((new String ('\v')).length === 1);

/* verifying character codes */
assert ((new String ('\\')).charCodeAt (0) === 92);
assert ((new String ('\b')).charCodeAt (0) === 8);
assert ((new String ('\f')).charCodeAt (0) === 12);
assert ((new String ('\n')).charCodeAt (0) === 10);
assert ((new String ('\r')).charCodeAt (0) === 13);
assert ((new String ('\t')).charCodeAt (0) === 9);
assert ((new String ('\v')).charCodeAt (0) === 11);

/* 'p' is not SingleEscapeCharacter */
assert ('\p' === 'p');

var v\u0061riable = 'valu\u0065';
assert (variable === 'value');
<|endoftext|>


<commit_before>var fs = require('fs'),
    path = require('path'),
    os = require('os'),
    win32 = os.platform() === 'win32',
    argv = nw.App.argv,
    bookmarkletOnly = argv.length > 0 && argv[0] === 'b',
    start_str = 'jni rpc: ',
    pdb_started = false,
    hide_backup = false,
    pdb,
    wnd,
    rpc_host

function println(str) {
    process.stdout.write(str + '\n')
}

function getChildArgs(initial_args, extra_args, child_cwd) {
    return initial_args.concat(extra_args, [
        '-Djava.class.path=' + path.join(child_cwd, 'bookmarks-all/target/bookmarks-all-jarjar.jar'),
        'bookmarks.all.Main',
        child_cwd
    ])
}

function isDir(dir) {
    return fs.statSync(dir).isDirectory()
}

function findSubDir(baseDir, subDirPrefix) {
    var dirs = fs.readdirSync(baseDir), dir, f
    for (var i = 0, len = dirs.length; i < len; i++) {
        if (isDir(dir=path.join(baseDir, f=dirs[i])) && 0 === f.indexOf(subDirPrefix))
            return dir
    }
    return null
}

function startProtostuffdb() {
    var spawn = require('child_process').spawn,
        child_cwd = path.join(__dirname, '..'),
        bin = path.join(child_cwd, 'target/protostuffdb'),
        port = fs.readFileSync(path.join(child_cwd, 'PORT.txt'), 'utf8').trim(),
        raw_args = fs.readFileSync(path.join(child_cwd, 'ARGS.txt'), 'utf8').trim(),
        extra_args = raw_args.split(' '),
        child_args = getChildArgs(['127.0.0.1:' + port, path.join(__dirname, 'g/user/UserServices.json')], extra_args, child_cwd),
        target_cwd,
        p

    hide_backup = raw_args.indexOf('-Dprotostuffdb.with_backup=true') === -1
    if (!win32) {
        target_cwd = child_cwd
    } else if (isDir(target_cwd = 'C:/Program Files/Java/jdk1.7.0_79/jre/bin/server')) {
        bin += '.exe'
    } else if (fs.existsSync(p = path.join(child_cwd, 'JDK_DIR.txt'))) {
        if (!isDir(target_cwd = path.join(fs.readFileSync(p, 'utf8').trim(), 'jre/bin/server'))) {
            println('JDK_DIR.txt did not contain a valid jdk path.')
            process.exit(1)
            return
        }
        bin += '.exe'
    } else if (!isDir('C:/Program Files/Java') ||
            !(p = findSubDir('C:/Program Files/Java', 'jdk1.7')) ||
            !isDir(target_cwd = path.join(p, 'jre/bin/server'))) {
        println('Please create JDK_DIR.txt in the root dir of the project that contains the full path to your jdk.')
        println('E.g.\nC:/path/to/jdk1.7.0_79')
        process.exit(1)
        return
    } else {
        bin += '.exe'
    }

    pdb = spawn(bin, child_args, { cwd: target_cwd })
    pdb.stdout.on('data', onChildOut)
    pdb.on('close', onChildClose)
    rpc_host = 'http://127.0.0.1:' + port
}

function isStart(data) {
    return data.length > start_str.length && start_str === String(data.slice(0, start_str.length))
}

function onChildOut(data) {
    if (pdb_started || !isStart(data))
        return
    pdb_started = true
    openWindow()
}

function onChildClose(code) {
    if (code)
        println('child process exited with code ' + code)
    if (wnd)
        wnd.close(true)
    pdb = undefined
}

function onClose() {
    this.hide()
    wnd = undefined
    if (pdb)
        pdb.kill()
    this.close(true)
}

function onOpen(w) {
    wnd = w
    if (bookmarkletOnly) {
        w.resizeTo(340, 100)
    } else {
        w.resizeTo(1005, 710)
    }

    w.moveTo(273, 0)
    if (pdb)
        w.on('close', onClose)
    w.show()
}

function openWindow() {
    global.rpc_host = rpc_host
    global.hide_backup = hide_backup
    nw.Window.open(bookmarkletOnly ? 'nw/bookmarklet.html' : 'index.html', { show: false }, onOpen)

    require('./dist/bookmarklet-nw')
}

startProtostuffdb()

<commit_msg>taskbar<commit_after>var fs = require('fs'),
    path = require('path'),
    os = require('os'),
    win32 = os.platform() === 'win32',
    argv = nw.App.argv,
    bookmarkletOnly = argv.length > 0 && argv[0] === 'b',
    start_str = 'jni rpc: ',
    pdb_started = false,
    hide_backup = false,
    pdb,
    wnd,
    rpc_host

function println(str) {
    process.stdout.write(str + '\n')
}

function getChildArgs(initial_args, extra_args, child_cwd) {
    return initial_args.concat(extra_args, [
        '-Djava.class.path=' + path.join(child_cwd, 'bookmarks-all/target/bookmarks-all-jarjar.jar'),
        'bookmarks.all.Main',
        child_cwd
    ])
}

function isDir(dir) {
    return fs.statSync(dir).isDirectory()
}

function findSubDir(baseDir, subDirPrefix) {
    var dirs = fs.readdirSync(baseDir), dir, f
    for (var i = 0, len = dirs.length; i < len; i++) {
        if (isDir(dir=path.join(baseDir, f=dirs[i])) && 0 === f.indexOf(subDirPrefix))
            return dir
    }
    return null
}

function startProtostuffdb() {
    var spawn = require('child_process').spawn,
        child_cwd = path.join(__dirname, '..'),
        bin = path.join(child_cwd, 'target/protostuffdb'),
        port = fs.readFileSync(path.join(child_cwd, 'PORT.txt'), 'utf8').trim(),
        raw_args = fs.readFileSync(path.join(child_cwd, 'ARGS.txt'), 'utf8').trim(),
        extra_args = raw_args.split(' '),
        child_args = getChildArgs(['127.0.0.1:' + port, path.join(__dirname, 'g/user/UserServices.json')], extra_args, child_cwd),
        target_cwd,
        p

    hide_backup = raw_args.indexOf('-Dprotostuffdb.with_backup=true') === -1
    if (!win32) {
        target_cwd = child_cwd
    } else if (isDir(target_cwd = 'C:/Program Files/Java/jdk1.7.0_79/jre/bin/server')) {
        bin += '.exe'
    } else if (fs.existsSync(p = path.join(child_cwd, 'JDK_DIR.txt'))) {
        if (!isDir(target_cwd = path.join(fs.readFileSync(p, 'utf8').trim(), 'jre/bin/server'))) {
            println('JDK_DIR.txt did not contain a valid jdk path.')
            process.exit(1)
            return
        }
        bin += '.exe'
    } else if (!isDir('C:/Program Files/Java') ||
            !(p = findSubDir('C:/Program Files/Java', 'jdk1.7')) ||
            !isDir(target_cwd = path.join(p, 'jre/bin/server'))) {
        println('Please create JDK_DIR.txt in the root dir of the project that contains the full path to your jdk.')
        println('E.g.\nC:/path/to/jdk1.7.0_79')
        process.exit(1)
        return
    } else {
        bin += '.exe'
    }

    pdb = spawn(bin, child_args, { cwd: target_cwd })
    pdb.stdout.on('data', onChildOut)
    pdb.on('close', onChildClose)
    rpc_host = 'http://127.0.0.1:' + port
}

function isStart(data) {
    return data.length > start_str.length && start_str === String(data.slice(0, start_str.length))
}

function onChildOut(data) {
    if (pdb_started || !isStart(data))
        return
    pdb_started = true
    openWindow()
}

function onChildClose(code) {
    if (code)
        println('child process exited with code ' + code)
    if (wnd)
        wnd.close(true)
    pdb = undefined
}

function onClose() {
    this.hide()
    wnd = undefined
    if (pdb)
        pdb.kill()
    this.close(true)
}

function onOpen(w) {
    wnd = w
    if (bookmarkletOnly) {
        w.resizeTo(340, 100)
    } else {
        w.resizeTo(1005, 710)
    }

    w.moveTo(273, 0)
    if (pdb)
        w.on('close', onClose)
    w.show()
}

function openWindow() {
    global.rpc_host = rpc_host
    global.hide_backup = hide_backup
    nw.Window.open(bookmarkletOnly ? 'nw/bookmarklet.html' : 'index.html', { show: false, show_in_taskbar: !win32 }, onOpen)

    require('./dist/bookmarklet-nw')
}

startProtostuffdb()

<|endoftext|>


<commit_before>// @flow

import React from 'react'
import {List, Map, Set} from 'immutable'
import {AreaOfStudyGroup} from './area-of-study-group'
import {FlatButton} from '../../components/button'
import {
	sortStudiesByType,
	areaTypeConstants,
	Student,
} from '@gob/object-student'

import './area-of-study-sidebar.scss'

type Props = {
	student: Student,
}

type State = {
	showAreaPickerFor: Map<string, boolean>,
}

export class AreaOfStudySidebar extends React.PureComponent<Props, State> {
	state = {
		showAreaPickerFor: Map(),
	}

	showAreaPicker = (type: string) => {
		this.setState(state => ({
			showAreaPickerFor: state.showAreaPickerFor.set(type, true),
		}))
	}

	hideAreaPicker = (type: string) => {
		this.setState(state => ({
			showAreaPickerFor: state.showAreaPickerFor.set(type, false),
		}))
	}

	render() {
		let props = this.props
		let {student} = props
		let {showAreaPickerFor} = this.state

		let sortedStudies = List(sortStudiesByType([...student.studies]))

		// group the studies by their type
		let groupedStudies = sortedStudies.groupBy(study =>
			study.type.toLowerCase(),
		)

		let allAreaTypes = Map(areaTypeConstants).toList()
		let usedAreaTypes = Set(student.studies.map(s => s.type))

		let unusedTypes = allAreaTypes.filter(
			type =>
				!usedAreaTypes.has(type) && !showAreaPickerFor.get(type, false),
		)

		let unusedTypesToShow = showAreaPickerFor.filter(
			(toShow, type) => toShow && !usedAreaTypes.has(type),
		)

		/////

		let activeAreas = groupedStudies.map((areas, areaType) => (
			<AreaOfStudyGroup
				key={areaType}
				areas={areas}
				onEndAddArea={this.hideAreaPicker}
				onInitiateAddArea={this.showAreaPicker}
				showAreaPicker={showAreaPickerFor.get(areaType, false)}
				student={student}
				type={areaType}
			/>
		))

		let openedAreas = unusedTypesToShow.map((shouldShow, type) => (
			<AreaOfStudyGroup
				key={type}
				onEndAddArea={this.hideAreaPicker}
				onInitiateAddArea={this.showAreaPicker}
				showAreaPicker={shouldShow || false}
				student={student}
				type={type}
			/>
		))

		return (
			<>
				{[...activeAreas.values()]}
				{[...openedAreas.values()]}
				{unusedTypes.size && (

						Add:

							{unusedTypes
								.map(type => (
									<FlatButton
										key={type}
										className="unused-areas--button"
										onClick={() =>
											this.showAreaPicker(type)
										}
									>
										{type}
									</FlatButton>
								))
								.toArray()}

				)}
			</>
		)
	}
}
<commit_msg>fix sidebar opening the area add/remove searchbar twice<commit_after>// @flow

import React from 'react'
import {List, Map} from 'immutable'
import {AreaOfStudyGroup} from './area-of-study-group'
import {FlatButton} from '../../components/button'
import {
	sortStudiesByType,
	areaTypeConstants,
	Student,
} from '@gob/object-student'

import './area-of-study-sidebar.scss'

type Props = {
	student: Student,
}

type State = {
	showAreaPickerFor: Map<string, boolean>,
}

export class AreaOfStudySidebar extends React.PureComponent<Props, State> {
	state = {
		showAreaPickerFor: Map(),
	}

	showAreaPicker = (type: string) => {
		this.setState(state => ({
			showAreaPickerFor: state.showAreaPickerFor.set(type, true),
		}))
	}

	hideAreaPicker = (type: string) => {
		this.setState(state => ({
			showAreaPickerFor: state.showAreaPickerFor.set(type, false),
		}))
	}

	render() {
		let props = this.props
		let {student} = props
		let {showAreaPickerFor} = this.state

		let sortedStudies = List(sortStudiesByType([...student.studies]))

		// group the studies by their type
		let groupedStudies = sortedStudies.groupBy(study =>
			study.type.toLowerCase(),
		)

		let allAreaTypes = Map(areaTypeConstants).toList()
		let usedAreaTypes = new Set(student.studies.map(s => s.type))

		let unusedTypes = allAreaTypes.filter(
			type =>
				!usedAreaTypes.has(type) && !showAreaPickerFor.get(type, false),
		)

		let unusedTypesToShow = showAreaPickerFor.filter(
			(toShow, type) => toShow && !usedAreaTypes.has(type),
		)

		/////

		let activeAreas = groupedStudies.map((areas, areaType) => (
			<AreaOfStudyGroup
				key={areaType}
				areas={areas}
				onEndAddArea={this.hideAreaPicker}
				onInitiateAddArea={this.showAreaPicker}
				showAreaPicker={showAreaPickerFor.get(areaType, false)}
				student={student}
				type={areaType}
			/>
		))

		let openedAreas = unusedTypesToShow.map((shouldShow, type) => (
			<AreaOfStudyGroup
				key={type}
				onEndAddArea={this.hideAreaPicker}
				onInitiateAddArea={this.showAreaPicker}
				showAreaPicker={shouldShow || false}
				student={student}
				type={type}
			/>
		))

		return (
			<>
				{[...activeAreas.values()]}
				{[...openedAreas.values()]}
				{unusedTypes.size && (

						Add:

							{unusedTypes
								.map(type => (
									<FlatButton
										key={type}
										className="unused-areas--button"
										onClick={() =>
											this.showAreaPicker(type)
										}
									>
										{type}
									</FlatButton>
								))
								.toArray()}

				)}
			</>
		)
	}
}
<|endoftext|>


<commit_before>var allTestFiles = [];
var TEST_REGEXP = /spec\.js$/;

var pathToModule = function(path) {
  return path.replace(/^\/base\/src\//, '').replace(/\.js$/, '');
};

Object.keys(window.__karma__.files).forEach(function(file) {
  if (TEST_REGEXP.test(file)) {
    allTestFiles.push(pathToModule(file));
  }
});

var run = function() {
  test(allTestFiles, function() {
    console.log('Starting Karma');
    window.__karma__.start();
  });
};

var test = require.config({
  baseUrl : '/base/src',
  paths : {
    'angular' : '../vendor/angular/angular',
    'angular-mocks' : '../vendor/angular-mocks/angular-mocks',
    'angularAMD' : '../vendor/angularAMD/angularAMD',
    'ngload' : '../vendor/angularAMD/ngload',
    'ui-bootstrap' : '../vendor/angular-bootstrap/ui-bootstrap-tpls.min',
    'domReady' : '../vendor/requirejs-domready/domReady',
    'Restangular' : '../vendor/restangular/dist/restangular.min',
    'underscore' : '../vendor/underscore/underscore',
    'angular-ui-router' : '../vendor/angular-ui-router/release/angular-ui-router',
    'angular-css-injector' : '../vendor/angular-css-injector/angular-css-injector',
    'angular-cookies' : '../vendor/angular-cookies/angular-cookies.min',
    'angular-translate' : '../vendor/angular-translate/angular-translate.min',
    'angular-translate-loader-static-files' : '../vendor/angular-translate-loader-static-files/angular-translate-loader-static-files.min',
    'jquery' : '../vendor/jquery/jquery',
    'footable' : '../vendor/footable/dist/footable.min',
    'pixi': '../vendor/pixi/bin/pixi',
    'd3' : '../vendor/d3/d3.min',
    'vis' : '../vendor/vis/dist/vis.min',
    'ocLazyLoad' : '../vendor/ocLazyLoad/dist/ocLazyLoad',
    'graphRenderer' : '../assets/js/graphRenderer'
  },

  shim : {
    'angular' : ['jquery'],
    'angular-mocks' : ['angular'],
    'angularAMD' : ['angular'],
    'ocLazyLoad' : ['angular'],
    'Restangular' : ['angular', 'underscore'],
    'ui-bootstrap' : ['angular'],
    'angular-css-injector' : ['angular'],
    'angular-ui-router' : ['angular'],
    'angular-cookies' : ['angular'],
    'angular-translate': ['angular'],
    'angular-translate-loader-static-files' : ['angular-translate'],
    'ngload' : ['angularAMD'],
    'pixi' : {
        exports: 'PIXI'
    },
    'graphRenderer' : ['pixi'],
    'jquery' : {
      exports : '$'
    },
    'footable' : ['jquery'],
    'undescore' : {
      exports : '_'
    }
  },

  deps : ['angular', 'angular-mocks'],

  callback: run
});
<commit_msg>[Bug 3288] Fix test runner dependencies<commit_after>var allTestFiles = [];
var TEST_REGEXP = /spec\.js$/;

var pathToModule = function(path) {
  return path.replace(/^\/base\/src\//, '').replace(/\.js$/, '');
};

Object.keys(window.__karma__.files).forEach(function(file) {
  if (TEST_REGEXP.test(file)) {
    allTestFiles.push(pathToModule(file));
  }
});

var run = function() {
  test(allTestFiles, function() {
    console.log('Starting Karma');
    window.__karma__.start();
  });
};

var test = require.config({
  baseUrl : '/base/src',
  paths : {
    'angular' : '../vendor/angular/angular',
    'angular-mocks' : '../vendor/angular-mocks/angular-mocks',
    'angularAMD' : '../vendor/angularAMD/angularAMD',
    'ngload' : '../vendor/angularAMD/ngload',
    'ui-bootstrap' : '../vendor/angular-bootstrap/ui-bootstrap-tpls.min',
    'domReady' : '../vendor/requirejs-domready/domReady',
    'Restangular' : '../vendor/restangular/dist/restangular.min',
    'underscore' : '../vendor/underscore/underscore',
    'angular-ui-router' : '../vendor/angular-ui-router/release/angular-ui-router',
    'angular-css-injector' : '../vendor/angular-css-injector/angular-css-injector',
    'angular-cookies' : '../vendor/angular-cookies/angular-cookies.min',
    'angular-translate' : '../vendor/angular-translate/angular-translate.min',
    'angular-translate-loader-static-files' : '../vendor/angular-translate-loader-static-files/angular-translate-loader-static-files.min',
    'jquery' : '../vendor/jquery/jquery',
    'jquery-ui' : '../vendor/jquery-ui/jquery-ui.min',
    'footable' : '../vendor/footable/dist/footable.min',
    'pixi': '../vendor/pixi/bin/pixi',
    'd3' : '../vendor/d3/d3.min',
    'vis' : '../vendor/vis/dist/vis.min',
    'ocLazyLoad' : '../vendor/ocLazyLoad/dist/ocLazyLoad',
    'sigma' : '../vendor/sigma/sigma.min',
    'sigma-parsers-gexf' : '../vendor/sigma/plugins/sigma.parsers.gexf.min',
    'sigma-forceAtlas2' : '../vendor/sigma/plugins/sigma.layout.forceAtlas2.min',
    'sigma-dragNodes' : '../vendor/sigma/plugins/sigma.plugins.dragNodes.min',
    'sigma-customShapes' : '../vendor/sigma/plugins/sigma.renderers.customShapes.min',
    'graphRenderer' : '../assets/js/graphRenderer',
    'ngSlider' : '../vendor/ng-slider/dist/ng-slider.min'
  },

  shim : {
    'angular' : ['jquery'],
    'angular-mocks' : ['angular'],
    'angularAMD' : ['angular'],
    'ocLazyLoad' : ['angular'],
    'Restangular' : ['angular', 'underscore'],
    'ui-bootstrap' : ['angular'],
    'angular-css-injector' : ['angular'],
    'angular-ui-router' : ['angular'],
    'angular-cookies' : ['angular'],
    'angular-translate': ['angular'],
    'angular-translate-loader-static-files' : ['angular-translate'],
    'ngload' : ['angularAMD'],
    'pixi' : {
        exports: 'PIXI'
    },
    'graphRenderer' : ['pixi'],
    'jquery' : {
      exports : '$'
    },
    'footable' : ['jquery'],
    'undescore' : {
      exports : '_'
    },
    'sticky' : ['jquery', 'angular'],
    'sigma-parsers-gexf' : ['sigma'],
    'sigma-forceAtlas2' : ['sigma'],
    'sigma-dragNodes' : ['sigma'],
    'sigma-customShapes' : ['sigma'],
    'ngSlider' : ['angular']
  },

  deps : ['angular', 'angular-mocks'],

  callback: run
});
<|endoftext|>


<commit_before>'use strict';

// Configuring the Projects module
angular.module('projects').run(['Menus',
	function(Menus) {
		// Add the Projects dropdown item
		Menus.addMenuItem('topbar', {
			title: 'Projects',
			state: 'projects',
			type: 'dropdown'
		});

		// Add the dropdown list item
		Menus.addSubMenuItem('topbar', 'projects', {
			title: 'List Projects',
			state: 'projects.list'
		});

		// Add the dropdown create item
		Menus.addSubMenuItem('topbar', 'projects', {
			title: 'Create Project',
			state: 'projects.create'
		});
	}
]);
<commit_msg>Changed name of search page on navbar<commit_after>'use strict';

// Configuring the Projects module
angular.module('projects').run(['Menus',
	function(Menus) {
		// Add the Projects dropdown item
		Menus.addMenuItem('topbar', {
			title: 'Projects',
			state: 'projects',
			type: 'dropdown'
		});

		// Add the dropdown list item
		Menus.addSubMenuItem('topbar', 'projects', {
			title: 'Search for Projects',
			state: 'projects.list'
		});

		// Add the dropdown create item
		Menus.addSubMenuItem('topbar', 'projects', {
			title: 'Create Project',
			state: 'projects.create'
		});
	}
]);
<|endoftext|>