<commit_before>function resize_main_div() {
    // Resize main_div to exactly take up remaining vertical space.
    var div = $('#main_div');
    div.height(Math.max(200, div.height() + $(window).height() - $('body').height()));
}
$(function () {
    resize_main_div();
    $(window).resize(resize_main_div);
    $('#zephyr-type-tabs a').on('shown', function (e) { resize_main_div(); });
});

$(function() {
    $('#zephyr-type-tabs a[href="#class-message"]').on('shown', function (e) {
        $('#class-message input:not(:hidden):first').focus().select();
    });
    $('#zephyr-type-tabs a[href="#personal-message"]').on('shown', function (e) {
        $('#personal-message input:not(:hidden):first').focus().select();
    });
});

$.ajaxSetup({
     beforeSend: function(xhr, settings) {
         function getCookie(name) {
             var cookieValue = null;
             if (document.cookie && document.cookie != '') {
                 var cookies = document.cookie.split(';');
                 for (var i = 0; i < cookies.length; i++) {
                     var cookie = jQuery.trim(cookies[i]);
                     // Does this cookie string begin with the name we want?
                 if (cookie.substring(0, name.length + 1) == (name + '=')) {
                     cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                     break;
                 }
             }
         }
         return cookieValue;
         }
         if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
             // Only send the token to relative URLs i.e. locally.
             xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
         }
     }
});

$(function() {
    var status_classes = 'alert-error alert-success alert-info';
    var send_status = $('#send-status');
    var buttons = $('#class-message, #personal-message').find('input[type="submit"]');

    var options = {
        beforeSubmit: function (form, _options) {
            send_status.removeClass(status_classes)
                       .addClass('alert-info')
                       .text('Sending')
                       .stop(true).fadeTo(0,1);
            buttons.attr('disabled', 'disabled');
            buttons.blur()
        },
        success: function (resp, statusText, xhr, form) {
            form.find('textarea').val('');
            send_status.removeClass(status_classes)
                       .addClass('alert-success')
                       .text('Sent message')
                       .stop(true).fadeTo(0,1).delay(1000).fadeOut(1000);
            buttons.removeAttr('disabled');
        },
        error: function() {
            send_status.removeClass(status_classes)
                       .addClass('alert-error')
                       .text('Error sending message ')
                       .append($('')
                           .addClass('send-status-close').html('×')
                           .click(function () { send_status.stop(true).fadeOut(500); }))
                       .stop(true).fadeTo(0,1);

            buttons.removeAttr('disabled');
        }
    };

    send_status.hide();
    $("#class-message form").ajaxForm(options);
    $("#personal-message form").ajaxForm(options);
});

selected_tag = '
▶
'

var allow_hotkeys = true;

function select_zephyr(next_zephyr) {
    p = $("#selected");
    td = $(p).closest("td");
    if (next_zephyr.length != 0) { // We are not at the bottom or top of the zephyrs.
        td.empty(); // Clear the previous arrow.
        next_zephyr.children("td:first").html(selected_tag);
        $.post("update", {pointer: next_zephyr.attr("id")});

        if (($(next_zephyr).offset().top < $("#main_div").offset().top) ||
            ($(next_zephyr).offset().top + $(next_zephyr).height() > $("#main_div").offset().top + $("#main_div").height())) {
            scroll_to_selected();
        }
    }
}

// NB: This just binds to current elements, and won't bind to elements
// created after ready() is called.

$(document).ready(function() {
    $('input, textarea, button').focus(function() {
          allow_hotkeys = false;
    });

    $('input, textarea, button').blur(function() {
          allow_hotkeys = true;
    });
    $("body").delegate("p", "click", function(){
        select_zephyr($(this).parent().parent());
    });
});

var goto_pressed = false;

$(document).keydown(function(event) {
    if (allow_hotkeys) {

        if (event.keyCode == 38 || event.keyCode == 40) { // down or up arrow

            p = $("#selected");
            tr = $(p).closest("tr");
            if (event.keyCode == 40) { // down arrow
                // There are probably more verbose but more efficient ways to do this.
                next_zephyr = tr.nextAll(":not(:hidden):first");
            } else { // up arrow
                next_zephyr = tr.prevAll(":not(:hidden):first");
            }
            select_zephyr(next_zephyr);
            event.preventDefault();
        } else if (event.keyCode == 82) { // 'r' keypress, for responding to a zephyr
            var parent = $("#selected").parents("tr");
            var zephyr_class = parent.find("span.zephyr_class").text();
            var instance = parent.find("span.zephyr_instance").text();
            if (zephyr_class != '') {
                $('#zephyr-type-tabs a[href="#class-message"]').tab('show');
                $("#class").val(zephyr_class);
                $("#instance").val(instance);
                $("#new_zephyr").focus();
                $("#new_zephyr").select();
            } else { // No instance, must be a personal

                var recipient = parent.find("span.zephyr_sender").text();
                if (recipient == username) { // that is, we sent the original message
                    recipient = parent.find("span.zephyr_personal_recipient").text();
                }
                prepare_personal(recipient);
                $("#new_personal_zephyr").focus();
                $("#new_personal_zephyr").select();
            }
            event.preventDefault();
        } else if (event.keyCode == 71) { // 'g' keypress, set trigger for "go to"
            goto_pressed = true;
            event.preventDefault();
        } else if (goto_pressed && event.keyCode == 67) { // 'c' keypress, for narrow-by-recipient
            var parent = $("#selected").parents("tr");
            var zephyr_class = parent.find("span.zephyr_class").text();
            narrow(zephyr_class, parent.attr("id"));
            event.preventDefault()
        } else if (goto_pressed && event.keyCode == 73) { // 'i' keypress, for narrow-by-instance
            var parent = $("#selected").parents("tr");
            var zephyr_class = parent.find("span.zephyr_class").text();
            var zephyr_instance = parent.find("span.zephyr_instance").text();
            narrow_instance(zephyr_class, zephyr_instance, parent.attr("id"));
            event.preventDefault()
        } else if (goto_pressed && event.keyCode == 80) { // 'p' keypress, for narrow-to-personals
            narrow_personals($("#selected").parents("tr").attr("id"));
            event.preventDefault();
        } else if (goto_pressed && event.keyCode == 65) { // 'a' keypress, for unnarrow
            unhide();
            event.preventDefault();
        }

        if (event.keyCode != 71) { // not 'g'
            goto_pressed = false;
        }

    } else if (event.keyCode == 27) { // Esc pressed
        $('input, textarea, button').blur();
        event.preventDefault();
    }
});

function scroll_to_selected() {
    $('#main_div').scrollTop(0);
    $('#main_div').scrollTop($("#selected").offset().top - $('#main_div').height()/1.5);

}

function hide_personals() {
    $("span.zephyr_personal_recipient").each(
        function() {
            $(this).parents("tr").hide();
        }
    );
}

function narrow_personals(target_zephyr) {
    var old_top = $("#main_div").offset().top - $("#" + target_zephyr).offset().top;

    $("span.zephyr_personal_recipient").each(
        function() {
            $(this).parents("tr").show();
        }
    );
            event.preventDefault();
    $("span.zephyr_class").each(
        function() {
            $(this).parents("tr").hide();
        }
    );

    $("#selected").closest("td").empty();
    $("#" + target_zephyr).children("td:first").html(selected_tag);
    $.post("update", {pointer: target_zephyr});
    scroll_to_zephyr(target_zephyr, old_top);

    $("#unhide").removeAttr("disabled");
    $("#narrow_indicator").html("Showing personals");
}

function narrow(class_name, target_zephyr) {
    // We want the zephyr on which the narrow happened to stay in the same place if possible.
    var old_top = $("#main_div").offset().top - $("#" + target_zephyr).offset().top;
    $("span.zephyr_class").each(
        function() {
            if ($(this).text() != class_name) {
                $(this).parents("tr").hide();
            } else {
                // If you've narrowed on an instance and then click on the class, that should unhide the other instances on that class.
                $(this).parents("tr").show();
            }
        }
    );
    hide_personals();
    $("#selected").closest("td").empty();
    $("#" + target_zephyr).children("td:first").html(selected_tag);
    $.post("update", {pointer: target_zephyr});

    scroll_to_selected();

    $("#unhide").removeAttr("disabled");
    $("#narrow_indicator").html("Showing " + class_name + "");
}

function narrow_instance(class_name, instance, target_zephyr) {
    var old_top = $("#main_div").offset().top - $("#" + target_zephyr).offset().top;
    $("tr").each(
        function() {
            if (($(this).find("span.zephyr_class").text() != class_name) ||
                ($(this).find("span.zephyr_instance").text() != instance)) {
                $(this).hide();
            }
        }
    );
    hide_personals();
    $("#selected").closest("td").empty();
    $("#" + target_zephyr).children("td:first").html(selected_tag);
    $.post("update", {pointer: target_zephyr});

    scroll_to_selected();

    $("#unhide").removeAttr("disabled");
    $("#narrow_indicator").html("Showing " + class_name
      + " " + instance + "");
}

function prepare_personal(username) {
    $('#zephyr-type-tabs a[href="#personal-message"]').tab('show');
    $("#recipient").val(username);
    $("#new_personal_zephyr").focus();
}

function unhide() {
    $("tr").show();

    scroll_to_selected();

    $("#unhide").attr("disabled", "disabled");
    $("#narrow_indicator").html("");
}

function newline2br(content) {
    return content.replace(/\n/g, '
');
}

function add_message(index, zephyr) {
    var zephyr_para = $('
');
    var new_label = function (text, classes, on_click) {
        zephyr_para.append($('')
            .text(text)
            .addClass('label zephyr_label_clickable ' + classes)
            .click(on_click));
        zephyr_para.append(' ');
    };

    if (zephyr.type == 'class') {
        new_label(zephyr.display_recipient, 'zephyr_class',
            function (e) { narrow(zephyr.display_recipient, zephyr.id); });
        new_label(zephyr.instance, 'zephyr_instance',
            function (e) { narrow_instance(zephyr.display_recipient,
                                           zephyr.instance, zephyr.id); });
    } else {
        new_label(zephyr.display_recipient, 'zephyr_personal_recipient',
            function (e) { narrow_personals(zephyr.id); });
        zephyr_para.append('← ');
    }

    new_label(zephyr.sender, 'zephyr_sender',
             function (e) { prepare_personal(zephyr.sender); });

    zephyr_para.append('
' + newline2br(zephyr.content));

    $('#table tr:last').after($('
')
        .attr('id', zephyr.id)
        .append('

	')
        .append($('').append(zephyr_para)));
}

$(function() {
  $(initial_zephyr_json).each(add_message);
});

var longpoll_failures = 0;

function get_updates_longpoll(data) {
    if (data && data.zephyrs) {
        $.each(data.zephyrs, add_message);
    }
    var last_received = $("tr:last").attr("id");
    $.ajax({
        type:     'POST',
        url:      'get_updates_longpoll',
        data:     { last_received: last_received },
        dataType: 'json',
        success: function (data) {
            longpoll_failures = 0;
            get_updates_longpoll(data);
        },
        error: function () {
            longpoll_failures += 1;
            if (longpoll_failures >= 6) {
                $('#connection-error').show();
                resize_main_div();
            } else {
                setTimeout(get_updates_longpoll, 5*1000);
            }
        }
    });
}

$(function () {
    get_updates_longpoll();
});

<commit_msg>Rename narrow to narrow_class.<commit_after>function resize_main_div() {
    // Resize main_div to exactly take up remaining vertical space.
    var div = $('#main_div');
    div.height(Math.max(200, div.height() + $(window).height() - $('body').height()));
}
$(function () {
    resize_main_div();
    $(window).resize(resize_main_div);
    $('#zephyr-type-tabs a').on('shown', function (e) { resize_main_div(); });
});

$(function() {
    $('#zephyr-type-tabs a[href="#class-message"]').on('shown', function (e) {
        $('#class-message input:not(:hidden):first').focus().select();
    });
    $('#zephyr-type-tabs a[href="#personal-message"]').on('shown', function (e) {
        $('#personal-message input:not(:hidden):first').focus().select();
    });
});

$.ajaxSetup({
     beforeSend: function(xhr, settings) {
         function getCookie(name) {
             var cookieValue = null;
             if (document.cookie && document.cookie != '') {
                 var cookies = document.cookie.split(';');
                 for (var i = 0; i < cookies.length; i++) {
                     var cookie = jQuery.trim(cookies[i]);
                     // Does this cookie string begin with the name we want?
                 if (cookie.substring(0, name.length + 1) == (name + '=')) {
                     cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                     break;
                 }
             }
         }
         return cookieValue;
         }
         if (!(/^http:.*/.test(settings.url) || /^https:.*/.test(settings.url))) {
             // Only send the token to relative URLs i.e. locally.
             xhr.setRequestHeader("X-CSRFToken", getCookie('csrftoken'));
         }
     }
});

$(function() {
    var status_classes = 'alert-error alert-success alert-info';
    var send_status = $('#send-status');
    var buttons = $('#class-message, #personal-message').find('input[type="submit"]');

    var options = {
        beforeSubmit: function (form, _options) {
            send_status.removeClass(status_classes)
                       .addClass('alert-info')
                       .text('Sending')
                       .stop(true).fadeTo(0,1);
            buttons.attr('disabled', 'disabled');
            buttons.blur()
        },
        success: function (resp, statusText, xhr, form) {
            form.find('textarea').val('');
            send_status.removeClass(status_classes)
                       .addClass('alert-success')
                       .text('Sent message')
                       .stop(true).fadeTo(0,1).delay(1000).fadeOut(1000);
            buttons.removeAttr('disabled');
        },
        error: function() {
            send_status.removeClass(status_classes)
                       .addClass('alert-error')
                       .text('Error sending message ')
                       .append($('')
                           .addClass('send-status-close').html('×')
                           .click(function () { send_status.stop(true).fadeOut(500); }))
                       .stop(true).fadeTo(0,1);

            buttons.removeAttr('disabled');
        }
    };

    send_status.hide();
    $("#class-message form").ajaxForm(options);
    $("#personal-message form").ajaxForm(options);
});

selected_tag = '
▶
'

var allow_hotkeys = true;

function select_zephyr(next_zephyr) {
    p = $("#selected");
    td = $(p).closest("td");
    if (next_zephyr.length != 0) { // We are not at the bottom or top of the zephyrs.
        td.empty(); // Clear the previous arrow.
        next_zephyr.children("td:first").html(selected_tag);
        $.post("update", {pointer: next_zephyr.attr("id")});

        if (($(next_zephyr).offset().top < $("#main_div").offset().top) ||
            ($(next_zephyr).offset().top + $(next_zephyr).height() > $("#main_div").offset().top + $("#main_div").height())) {
            scroll_to_selected();
        }
    }
}

// NB: This just binds to current elements, and won't bind to elements
// created after ready() is called.

$(document).ready(function() {
    $('input, textarea, button').focus(function() {
          allow_hotkeys = false;
    });

    $('input, textarea, button').blur(function() {
          allow_hotkeys = true;
    });
    $("body").delegate("p", "click", function(){
        select_zephyr($(this).parent().parent());
    });
});

var goto_pressed = false;

$(document).keydown(function(event) {
    if (allow_hotkeys) {

        if (event.keyCode == 38 || event.keyCode == 40) { // down or up arrow

            p = $("#selected");
            tr = $(p).closest("tr");
            if (event.keyCode == 40) { // down arrow
                // There are probably more verbose but more efficient ways to do this.
                next_zephyr = tr.nextAll(":not(:hidden):first");
            } else { // up arrow
                next_zephyr = tr.prevAll(":not(:hidden):first");
            }
            select_zephyr(next_zephyr);
            event.preventDefault();
        } else if (event.keyCode == 82) { // 'r' keypress, for responding to a zephyr
            var parent = $("#selected").parents("tr");
            var zephyr_class = parent.find("span.zephyr_class").text();
            var instance = parent.find("span.zephyr_instance").text();
            if (zephyr_class != '') {
                $('#zephyr-type-tabs a[href="#class-message"]').tab('show');
                $("#class").val(zephyr_class);
                $("#instance").val(instance);
                $("#new_zephyr").focus();
                $("#new_zephyr").select();
            } else { // No instance, must be a personal

                var recipient = parent.find("span.zephyr_sender").text();
                if (recipient == username) { // that is, we sent the original message
                    recipient = parent.find("span.zephyr_personal_recipient").text();
                }
                prepare_personal(recipient);
                $("#new_personal_zephyr").focus();
                $("#new_personal_zephyr").select();
            }
            event.preventDefault();
        } else if (event.keyCode == 71) { // 'g' keypress, set trigger for "go to"
            goto_pressed = true;
            event.preventDefault();
        } else if (goto_pressed && event.keyCode == 67) { // 'c' keypress, for narrow-by-recipient
            var parent = $("#selected").parents("tr");
            var zephyr_class = parent.find("span.zephyr_class").text();
            narrow(zephyr_class, parent.attr("id"));
            event.preventDefault()
        } else if (goto_pressed && event.keyCode == 73) { // 'i' keypress, for narrow-by-instance
            var parent = $("#selected").parents("tr");
            var zephyr_class = parent.find("span.zephyr_class").text();
            var zephyr_instance = parent.find("span.zephyr_instance").text();
            narrow_instance(zephyr_class, zephyr_instance, parent.attr("id"));
            event.preventDefault()
        } else if (goto_pressed && event.keyCode == 80) { // 'p' keypress, for narrow-to-personals
            narrow_personals($("#selected").parents("tr").attr("id"));
            event.preventDefault();
        } else if (goto_pressed && event.keyCode == 65) { // 'a' keypress, for unnarrow
            unhide();
            event.preventDefault();
        }

        if (event.keyCode != 71) { // not 'g'
            goto_pressed = false;
        }

    } else if (event.keyCode == 27) { // Esc pressed
        $('input, textarea, button').blur();
        event.preventDefault();
    }
});

function scroll_to_selected() {
    $('#main_div').scrollTop(0);
    $('#main_div').scrollTop($("#selected").offset().top - $('#main_div').height()/1.5);

}

function hide_personals() {
    $("span.zephyr_personal_recipient").each(
        function() {
            $(this).parents("tr").hide();
        }
    );
}

function narrow_personals(target_zephyr) {
    var old_top = $("#main_div").offset().top - $("#" + target_zephyr).offset().top;

    $("span.zephyr_personal_recipient").each(
        function() {
            $(this).parents("tr").show();
        }
    );
            event.preventDefault();
    $("span.zephyr_class").each(
        function() {
            $(this).parents("tr").hide();
        }
    );

    $("#selected").closest("td").empty();
    $("#" + target_zephyr).children("td:first").html(selected_tag);
    $.post("update", {pointer: target_zephyr});
    scroll_to_zephyr(target_zephyr, old_top);

    $("#unhide").removeAttr("disabled");
    $("#narrow_indicator").html("Showing personals");
}

function narrow_class(class_name, target_zephyr) {
    // We want the zephyr on which the narrow happened to stay in the same place if possible.
    var old_top = $("#main_div").offset().top - $("#" + target_zephyr).offset().top;
    $("span.zephyr_class").each(
        function() {
            if ($(this).text() != class_name) {
                $(this).parents("tr").hide();
            } else {
                // If you've narrowed on an instance and then click on the class, that should unhide the other instances on that class.
                $(this).parents("tr").show();
            }
        }
    );
    hide_personals();
    $("#selected").closest("td").empty();
    $("#" + target_zephyr).children("td:first").html(selected_tag);
    $.post("update", {pointer: target_zephyr});

    scroll_to_selected();

    $("#unhide").removeAttr("disabled");
    $("#narrow_indicator").html("Showing " + class_name + "");
}

function narrow_instance(class_name, instance, target_zephyr) {
    var old_top = $("#main_div").offset().top - $("#" + target_zephyr).offset().top;
    $("tr").each(
        function() {
            if (($(this).find("span.zephyr_class").text() != class_name) ||
                ($(this).find("span.zephyr_instance").text() != instance)) {
                $(this).hide();
            }
        }
    );
    hide_personals();
    $("#selected").closest("td").empty();
    $("#" + target_zephyr).children("td:first").html(selected_tag);
    $.post("update", {pointer: target_zephyr});

    scroll_to_selected();

    $("#unhide").removeAttr("disabled");
    $("#narrow_indicator").html("Showing " + class_name
      + " " + instance + "");
}

function prepare_personal(username) {
    $('#zephyr-type-tabs a[href="#personal-message"]').tab('show');
    $("#recipient").val(username);
    $("#new_personal_zephyr").focus();
}

function unhide() {
    $("tr").show();

    scroll_to_selected();

    $("#unhide").attr("disabled", "disabled");
    $("#narrow_indicator").html("");
}

function newline2br(content) {
    return content.replace(/\n/g, '
');
}

function add_message(index, zephyr) {
    var zephyr_para = $('
');
    var new_label = function (text, classes, on_click) {
        zephyr_para.append($('')
            .text(text)
            .addClass('label zephyr_label_clickable ' + classes)
            .click(on_click));
        zephyr_para.append(' ');
    };

    if (zephyr.type == 'class') {
        new_label(zephyr.display_recipient, 'zephyr_class',
            function (e) { narrow_class(zephyr.display_recipient, zephyr.id); });
        new_label(zephyr.instance, 'zephyr_instance',
            function (e) { narrow_instance(zephyr.display_recipient,
                                           zephyr.instance, zephyr.id); });
    } else {
        new_label(zephyr.display_recipient, 'zephyr_personal_recipient',
            function (e) { narrow_personals(zephyr.id); });
        zephyr_para.append('← ');
    }

    new_label(zephyr.sender, 'zephyr_sender',
             function (e) { prepare_personal(zephyr.sender); });

    zephyr_para.append('
' + newline2br(zephyr.content));

    $('#table tr:last').after($('
')
        .attr('id', zephyr.id)
        .append('

	')
        .append($('').append(zephyr_para)));
}

$(function() {
  $(initial_zephyr_json).each(add_message);
});

var longpoll_failures = 0;

function get_updates_longpoll(data) {
    if (data && data.zephyrs) {
        $.each(data.zephyrs, add_message);
    }
    var last_received = $("tr:last").attr("id");
    $.ajax({
        type:     'POST',
        url:      'get_updates_longpoll',
        data:     { last_received: last_received },
        dataType: 'json',
        success: function (data) {
            longpoll_failures = 0;
            get_updates_longpoll(data);
        },
        error: function () {
            longpoll_failures += 1;
            if (longpoll_failures >= 6) {
                $('#connection-error').show();
                resize_main_div();
            } else {
                setTimeout(get_updates_longpoll, 5*1000);
            }
        }
    });
}

$(function () {
    get_updates_longpoll();
});

<|endoftext|>


<commit_before>var mongoose = require('mongoose');
var Wallet = require('../../models/wallet.js').Wallet;
exports.getWalletByID = function(req, res) {
	return Wallet.findById(req.params.id, function(err, wallet) {
		if (!err) {
			res.send(wallet);
		}
		else {
			console.log(err);
		}
	});
}

exports.getWalletByUser = function(req, res) {
	Wallet.find({ 'userID' : req.session.userId},
		function(err, wallet) {
			if (!err) {
				res.send({"wallet":wallet});
			}
			else {
				console.log(err);
			}
		});
}

exports.updateWallet = function(req, res) {
	Wallet.findByIdAndUpdate(req.params.id,
			{
				green: req.body.wallet.green,
				purple: req.body.wallet.purple,
				red: req.body.wallet.red,
				blue: req.body.wallet.blue
			},
			function(err, wallet) {
				if (!err) {
					res.send(200);
				}
				else {
					console.log(err);
					res.send(500);
				}
			});
}<commit_msg>Updated wallet PUT method to conform to Ember Data expectation<commit_after>var mongoose = require('mongoose');
var Wallet = require('../../models/wallet.js').Wallet;
exports.getWalletByID = function(req, res) {
	return Wallet.findById(req.params.id, function(err, wallet) {
		if (!err) {
			res.send(wallet);
		}
		else {
			console.log(err);
		}
	});
}

exports.getWalletByUser = function(req, res) {
	Wallet.find({ 'userID' : req.session.userId},
		function(err, wallet) {
			if (!err) {
				res.send({"wallet":wallet});
			}
			else {
				console.log(err);
			}
		});
}

exports.updateWallet = function(req, res) {
	Wallet.findByIdAndUpdate(req.params.id,
			{
				green: req.body.wallet.green,
				purple: req.body.wallet.purple,
				red: req.body.wallet.red,
				blue: req.body.wallet.blue
			},
			function(err, wallet) {
				if (!err) {
					res.send(200, { wallet: wallet });
				}
				else {
					console.log(err);
					res.send(500);
				}
			});
}<|endoftext|>


<commit_before>//////////////////////////////////////////////////
//
//  grouple - devil.game.js
//
//  Purpose: Game logic for devil
//  Created: 2014.02.11
//
//////////////////////////////////////////////////

// Module dependencies
var async = require('async');

// Model
var Hero = require('../lib/model').Hero;
var Devil = require('../lib/model').Devil;
var City = require('../lib/model').City;
var Player = require('../lib/model').Player;
var Monster = require('../lib/model').Monster;

// Model Prototype
var ProtoHero = require('../lib/model').ProtoHero;
var ProtoSoldier = require('../lib/model').ProtoSoldier;
var ProtoMonster = require('../lib/model').ProtoMonster;

// Library
var errorHandler = require('../lib/errorHandler');
var common = require('../lib/common');

var getBattleResult = common.getBattleResult;
var getIntrudeResult = common.getIntrudeResult;
var getPointToUpdate = common.getPointToUpdate;
var getDamage = common.getDamage;

exports.purchase = function (req, res) {
  async.waterfall([
    function getPlayer (callback) {
      Player.findById(req.session.current_player_id, function (err, player) {
        if (err) throw err;

        if ( !player ) {
          callback('NO_PLAYER_FOUND');
          return;
        }

        callback(null, player);
        return;
      });
    },

    function getDevil (player, callback) {
      Devil.findById(player.devil_id, function (err, devil) {
        if (err) throw err;

        if ( !devil ) {
          callback('NO_DEVIL_FOUND');
          return;
        }

        callback(null, player, devil);
        return;
      });
    },

    function checkMonsterLimit (player, devil, callback) {
      Monster.find({ 'player_id': player._id }, function (err, monsters) {
        if (err) throw err;

        if ( devil.monster_limit <= monsters.length - 1 ) {
          callback('MONSTER_LIMIT_EXCEEDED');
          return;
        }

        callback(null, player, devil);
        return;
      });
    },

    function getProtoMonster (player, devil, callback) {
      ProtoMonster.findById(req.body.monster_id, function (err, protomonster) {
        if (err) throw err;

        if ( !protomonster ) {
          callback('NO_MONSTER_PROTOTYPE_FOUND');
          return;
        }

        callback(null, player, devil, protomonster);
        return;
      });
    },

    function payActionPoint (player, devil, protomonster, callback) {
      Devil.findByIdAndUpdate(devil._id, { $inc: { 'current_action_point': -1 } }, function (err, devil) {
        if (err) throw err;

        if ( !devil ) {
          callback('NO_DEVIL_FOUND');
          return;
        }

        callback(null, player, devil, protomonster);
        return;
      });
    },

    function payMonsterTraining (player, devil, protomonster, callback) {
      var update = {
        $inc: {
          'money': -protomonster.price
        }
      };

      if ( player.money < protomonster.price ) {
        callback('NOT_ENOUGH_MONEY');
        return;
      }

      Player.findByIdAndUpdate(player._id, update, function (err, player) {
        if (err) throw err;

        if ( !player ) {
          callback('NO_PLAYER_FOUND');
          return;
        }

        callback(null, player, devil, protomonster);
        return;
      });
    },

    function addToMonster (player, devil, protomonster, callback) {
      var monster = JSON.parse(JSON.stringify(protomonster));

      monster.player_id = player._id;
      monster.current_health_point = monster.health_point;

      delete monster.created_at;
      delete monster.updated_at;
      delete monster._id;

      Monster(monster).save(function (err, monster) {
        if (err) throw err;

        var result = {
          'result': 'success',
          'player': player,
          'monster': monster
        };

        callback(null, result);
        return;
      });
    },
  ], function (err, result) {
    if (err) {
      errorHandler.sendErrorMessage(err, res);
      return;
    }

    res.send(result);
    return;
  });
};

exports.delete = function (req, res) {
  async.waterfall([
    function getPlayer (callback) {
      Player.findById(req.session.current_player_id, function (err, player) {
        if (err) throw err;

        if ( !player ) {
          callback('NO_PLAYER_FOUND');
          return;
        }

        callback(null, player);
        return;
      });
    },

    function getDevil (player, callback) {
      Devil.findById(player.devil_id, function (err, devil) {
        if (err) throw err;

        if ( !devil ) {
          callback('NO_DEVIL_FOUND');
          return;
        }

        callback(null, player, devil);
        return;
      });
    },

    function removeMonster (player, devil, callback) {
      Monster.findOneAndRemove({ '_id': req.body.monster_id, 'player_id': player._id }, function (err, monster) {
        if (err) throw err;

        var result = {
          'result': 'success',
          'monster': monster
        };

        callback(null, result);
        return;
      });
    }
  ], function (err, result) {
    if (err) {
      errorHandler.sendErrorMessage(err, res);
      return;
    }

    res.send(result);
    return;
  });
};

exports.buildup = function (req, res) {
  async.waterfall([
    function getPlayer (callback) {
      Player.findById(req.session.current_player_id, function (err, player) {
        if (err) throw err;

        if ( !player ) {
          callback('NO_PLAYER_FOUND');
          return;
        }

        callback(null, player);
        return;
      });
    },

    function getDevil (player, callback) {
      Devil.findById(player.devil_id, function (err, devil) {
        if (err) throw err;

        if ( !devil ) {
          callback('NO_DEVIL_FOUND');
          return;
        }

        callback(null, player, devil);
        return;
      });
    },

    function getMonster (player, devil, callback) {
      Monster.findOne({ '_id': req.body.monster_id, 'player_id': player._id }, function (err, monster) {
        if (err) throw err;

        var result = {
          'result': 'success',
          'monster': monster
        };

        callback(null, result);
        return;
      });
    }
  ], function (err, result) {
    if (err) {
      errorHandler.sendErrorMessage(err, res);
      return;
    }

    res.send(result);
    return;
  });
};

exports.position = function (req, res) {
  Monster.findByIdAndUpdate(req.body.monster_id, { 'floor': req.body.floor }, function (err, monster) {
    if (err) throw err;

    if ( !monster ) {
      errorHandler.sendErrorMessage('NO_MONSTER_FOUND', res);
      return;
    }

    var result = {
      'result': 'success',
      'monster': monster
    };

    res.send(result);
    return;
  });
};

exports.intrude = function (req, res) {
  async.waterfall([
    function getPlayer (callback) {
      Player.findById(req.session.current_player_id, function (err, player) {
        if (err) throw err;

        if ( !player ) {
          callback('NO_PLAYER_FOUND');
          return;
        }

        callback(null, player);
        return;
      });
    },

    function getDevil (player, callback) {
      Devil.findById(player.devil_id, function (err, devil) {
        if (err) throw err;

        if ( !devil ) {
          callback('NO_DEVIL_FOUND');
          return;
        }

        callback(null, player, devil);
        return;
      });
    },

    function getMonsters (player, devil, callback) {
      Monster.find({ 'player_id': player._id }, function (err, monsters) {
        if (err) throw err;

        callback(null, player, devil, monsters);
        return;
      });
    },

    function getProtoHero (player, devil, monsters, callback) {
      // THIS IS ONLY FOR THE TEST PURPOSE
      ProtoHero.find({ 'published': true }, function summonDefenders (err, protoheroes) {
        if (err) throw err;

        if ( protoheroes.length === 0 ) {
          callback('NO_PROTOHEROES_EXIST');
          return;
        }

        var random = Math.floor(Math.random()*protoheroes.length);
        var intruder = JSON.parse(JSON.stringify(protoheroes[random]));
        intruder.current_health_point = intruder.health_point;

        if ( !intruder ) {
          callback('FAILED_TO_MAKE_INTRUDER');
          return;
        }

        callback(null, player, devil, monsters, intruder);
        return;
      });
      // THIS IS ONLY FOR THE TEST PURPOSE
    },

    function battle (player, devil, monsters, intruder, callback) {
      var logs = [];

      var defenders = {
        '1f': [],
        '2f': [],
        '3f': [],
        '4f': [],
        '5f': [],
        '6f': []
      };

      for ( var i in monsters ) {
        var monster = monsters[i];

        if ( monster.floor !== 'waiting' && monster.floor !== undefined ) {
          defenders[monster.floor].push(monster);
        }
      }

      getIntrudeResult([ intruder ], defenders, devil, logs);

      callback(null, player, devil, defenders, intruder, logs);
      return;
    },

    function saveDevil (player, devil, defenders, intruder, logs, callback) {
      var healthPointToUpdate = ( devil.current_health_point > 0 ) ? devil.current_health_point : 0;
      var update = {
        $set: {
          'updated_at': new Date(),
          'current_health_point': healthPointToUpdate
        }
      };

      Devil.findByIdAndUpdate(devil._id, update, function (err, devil) {
        if (err) throw err;

        callback(null, player, devil, defenders, intruder, logs);
        return;
      });
    },

    function testResult (player, devil, defenders, intruder, logs, callback) {
      console.log('defenders:', defenders);

      var result = {
        'result': 'success',
        'player': player,
        'devil': devil,
        'defenders': defenders,
        'intruder': intruder,
        'logs': logs
      };

      callback(null, result);
      return;
    }
  ], function (err, result) {
    if (err) {
      errorHandler.sendErrorMessage(err, res);
      return;
    }

    res.send(result);
    return;
  });
};<commit_msg>Money and action point check routine added.<commit_after>//////////////////////////////////////////////////
//
//  grouple - devil.game.js
//
//  Purpose: Game logic for devil
//  Created: 2014.02.11
//
//////////////////////////////////////////////////

// Module dependencies
var async = require('async');

// Model
var Hero = require('../lib/model').Hero;
var Devil = require('../lib/model').Devil;
var City = require('../lib/model').City;
var Player = require('../lib/model').Player;
var Monster = require('../lib/model').Monster;

// Model Prototype
var ProtoHero = require('../lib/model').ProtoHero;
var ProtoSoldier = require('../lib/model').ProtoSoldier;
var ProtoMonster = require('../lib/model').ProtoMonster;

// Library
var errorHandler = require('../lib/errorHandler');
var common = require('../lib/common');

var getBattleResult = common.getBattleResult;
var getIntrudeResult = common.getIntrudeResult;
var getPointToUpdate = common.getPointToUpdate;
var getDamage = common.getDamage;

exports.purchase = function (req, res) {
  async.waterfall([
    function getPlayer (callback) {
      Player.findById(req.session.current_player_id, function (err, player) {
        if (err) throw err;

        if ( !player ) {
          callback('NO_PLAYER_FOUND');
          return;
        }

        callback(null, player);
        return;
      });
    },

    function getDevil (player, callback) {
      Devil.findById(player.devil_id, function (err, devil) {
        if (err) throw err;

        if ( !devil ) {
          callback('NO_DEVIL_FOUND');
          return;
        }

        callback(null, player, devil);
        return;
      });
    },

    function checkMonsterLimit (player, devil, callback) {
      Monster.find({ 'player_id': player._id }, function (err, monsters) {
        if (err) throw err;

        if ( devil.monster_limit <= monsters.length - 1 ) {
          callback('MONSTER_LIMIT_EXCEEDED');
          return;
        }

        callback(null, player, devil);
        return;
      });
    },

    function getProtoMonster (player, devil, callback) {
      ProtoMonster.findById(req.body.monster_id, function (err, protomonster) {
        if (err) throw err;

        if ( !protomonster ) {
          callback('NO_MONSTER_PROTOTYPE_FOUND');
          return;
        }

        callback(null, player, devil, protomonster);
        return;
      });
    },

    function payMonsterTraining (player, devil, protomonster, callback) {
      if ( player.money < protomonster.price ) {
        callback('NOT_ENOUGH_MONEY');
        return;
      }

      if ( devil.current_action_point < 1 ) {
        callback('NOT_ENOUGH_ACTION_POINT');
        return;
      }

      async.parallel([
        function payActionPoint (done) {
          Devil.findByIdAndUpdate(devil._id, { $inc: { 'current_action_point': -1 } }, function (err, devil) {
            if (err) throw err;

            if ( !devil ) {
              done('NO_DEVIL_FOUND');
              return;
            }

            done(null);
            return;
          });
        },

        function payMoney (done) {
          var update = {
            $inc: {
              'money': -protomonster.price
            }
          };

          Player.findByIdAndUpdate(player._id, update, function (err, player) {
            if (err) throw err;

            if ( !player ) {
              done('NO_PLAYER_FOUND');
              return;
            }

            done(null);
            return;
          });
        }
      ], function (err, result) {
        if (err) {
          callback(err);
          return;
        }

        callback(null, player, devil, protomonster);
        return;
      });
    },

    function addToMonster (player, devil, protomonster, callback) {
      var monster = JSON.parse(JSON.stringify(protomonster));

      monster.player_id = player._id;
      monster.current_health_point = monster.health_point;

      delete monster.created_at;
      delete monster.updated_at;
      delete monster._id;

      Monster(monster).save(function (err, monster) {
        if (err) throw err;

        var result = {
          'result': 'success',
          'player': player,
          'monster': monster
        };

        callback(null, result);
        return;
      });
    },
  ], function (err, result) {
    if (err) {
      errorHandler.sendErrorMessage(err, res);
      return;
    }

    res.send(result);
    return;
  });
};

exports.delete = function (req, res) {
  async.waterfall([
    function getPlayer (callback) {
      Player.findById(req.session.current_player_id, function (err, player) {
        if (err) throw err;

        if ( !player ) {
          callback('NO_PLAYER_FOUND');
          return;
        }

        callback(null, player);
        return;
      });
    },

    function getDevil (player, callback) {
      Devil.findById(player.devil_id, function (err, devil) {
        if (err) throw err;

        if ( !devil ) {
          callback('NO_DEVIL_FOUND');
          return;
        }

        callback(null, player, devil);
        return;
      });
    },

    function removeMonster (player, devil, callback) {
      Monster.findOneAndRemove({ '_id': req.body.monster_id, 'player_id': player._id }, function (err, monster) {
        if (err) throw err;

        var result = {
          'result': 'success',
          'monster': monster
        };

        callback(null, result);
        return;
      });
    }
  ], function (err, result) {
    if (err) {
      errorHandler.sendErrorMessage(err, res);
      return;
    }

    res.send(result);
    return;
  });
};

exports.buildup = function (req, res) {
  async.waterfall([
    function getPlayer (callback) {
      Player.findById(req.session.current_player_id, function (err, player) {
        if (err) throw err;

        if ( !player ) {
          callback('NO_PLAYER_FOUND');
          return;
        }

        callback(null, player);
        return;
      });
    },

    function getDevil (player, callback) {
      Devil.findById(player.devil_id, function (err, devil) {
        if (err) throw err;

        if ( !devil ) {
          callback('NO_DEVIL_FOUND');
          return;
        }

        callback(null, player, devil);
        return;
      });
    },

    function getMonster (player, devil, callback) {
      Monster.findOne({ '_id': req.body.monster_id, 'player_id': player._id }, function (err, monster) {
        if (err) throw err;

        var result = {
          'result': 'success',
          'monster': monster
        };

        callback(null, result);
        return;
      });
    }
  ], function (err, result) {
    if (err) {
      errorHandler.sendErrorMessage(err, res);
      return;
    }

    res.send(result);
    return;
  });
};

exports.position = function (req, res) {
  Monster.findByIdAndUpdate(req.body.monster_id, { 'floor': req.body.floor }, function (err, monster) {
    if (err) throw err;

    if ( !monster ) {
      errorHandler.sendErrorMessage('NO_MONSTER_FOUND', res);
      return;
    }

    var result = {
      'result': 'success',
      'monster': monster
    };

    res.send(result);
    return;
  });
};

exports.intrude = function (req, res) {
  async.waterfall([
    function getPlayer (callback) {
      Player.findById(req.session.current_player_id, function (err, player) {
        if (err) throw err;

        if ( !player ) {
          callback('NO_PLAYER_FOUND');
          return;
        }

        callback(null, player);
        return;
      });
    },

    function getDevil (player, callback) {
      Devil.findById(player.devil_id, function (err, devil) {
        if (err) throw err;

        if ( !devil ) {
          callback('NO_DEVIL_FOUND');
          return;
        }

        callback(null, player, devil);
        return;
      });
    },

    function getMonsters (player, devil, callback) {
      Monster.find({ 'player_id': player._id }, function (err, monsters) {
        if (err) throw err;

        callback(null, player, devil, monsters);
        return;
      });
    },

    function getProtoHero (player, devil, monsters, callback) {
      // THIS IS ONLY FOR THE TEST PURPOSE
      ProtoHero.find({ 'published': true }, function summonDefenders (err, protoheroes) {
        if (err) throw err;

        if ( protoheroes.length === 0 ) {
          callback('NO_PROTOHEROES_EXIST');
          return;
        }

        var random = Math.floor(Math.random()*protoheroes.length);
        var intruder = JSON.parse(JSON.stringify(protoheroes[random]));
        intruder.current_health_point = intruder.health_point;

        if ( !intruder ) {
          callback('FAILED_TO_MAKE_INTRUDER');
          return;
        }

        callback(null, player, devil, monsters, intruder);
        return;
      });
      // THIS IS ONLY FOR THE TEST PURPOSE
    },

    function battle (player, devil, monsters, intruder, callback) {
      var logs = [];

      var defenders = {
        '1f': [],
        '2f': [],
        '3f': [],
        '4f': [],
        '5f': [],
        '6f': []
      };

      for ( var i in monsters ) {
        var monster = monsters[i];

        if ( monster.floor !== 'waiting' && monster.floor !== undefined ) {
          defenders[monster.floor].push(monster);
        }
      }

      getIntrudeResult([ intruder ], defenders, devil, logs);

      callback(null, player, devil, defenders, intruder, logs);
      return;
    },

    function saveDevil (player, devil, defenders, intruder, logs, callback) {
      var healthPointToUpdate = ( devil.current_health_point > 0 ) ? devil.current_health_point : 0;
      var update = {
        $set: {
          'updated_at': new Date(),
          'current_health_point': healthPointToUpdate
        }
      };

      Devil.findByIdAndUpdate(devil._id, update, function (err, devil) {
        if (err) throw err;

        callback(null, player, devil, defenders, intruder, logs);
        return;
      });
    },

    function testResult (player, devil, defenders, intruder, logs, callback) {
      console.log('defenders:', defenders);

      var result = {
        'result': 'success',
        'player': player,
        'devil': devil,
        'defenders': defenders,
        'intruder': intruder,
        'logs': logs
      };

      callback(null, result);
      return;
    }
  ], function (err, result) {
    if (err) {
      errorHandler.sendErrorMessage(err, res);
      return;
    }

    res.send(result);
    return;
  });
};<|endoftext|>


<commit_before>'use scrict';

const { mapSeries, waterfall } = require('async');
const { get } = require('lodash');
const logger = require('../../lib/logger');

module.exports = (
  deploysController,
  getConfig,
  getBranchStatus,
  createDeployTemporaryBranch,
  getReleasePreview,
  deploy,
  cleanUpDeploy,
  notify
) => {
  return ({ repos, showPreview, verbose = false }, cb) => {
    try {
      deploysController.start();
    } catch (deployError) {
      logger.error('Already deploying error', repos, deployError);
      notify(repos, 'deployInProgress', verbose, slackError => {
        if (slackError) logger.error(`Error notifying slack: ${err.message}`, repos, slackError);
      });
      return cb(deployError);
    }

    waterfall([
      (next)            => getConfigForEachRepo(repos, next),
      (reposInfo, next) => getBranchStatusForEachRepo(reposInfo, next),
      (reposInfo, next) => createTemporaryBranchesForEachRepo(reposInfo, next),
      (reposInfo, next) => getReleasePreview(reposInfo, next),
      (reposInfo, next) => notifyPreviewSlackIfEnabled(showPreview, reposInfo, verbose, next),
      (reposInfo, next) => deployEachRepo(reposInfo, next),
      (reposInfo, next) => notifyRelease(reposInfo, next),
    ], (err, reposInfo) => {
      deploysController.finish();
      if (err) {
        logger.error('Error deploying all repos', reposInfo, err);
        mapSeries(reposInfo, cleanUpDeploy, cb);
        return;
      }
      cb();
    });

    function getConfigForEachRepo(repos, cb) {
      logger.debug('getConfigForEachRepo', { repos });
      mapSeries(repos, (repo, nextRepo) => {
        getConfig(repo, (err, config) => {
          if (err) {
            logger.error('Error getting repo config', repo, err);
            return nextRepo(null, { repo, failReason: 'INVALID_REPO_CONFIG' });
          }
          nextRepo(err, { repo, config });
        });
      }, cb);
    }

    function getBranchStatusForEachRepo(reposInfo, cb) {
      logger.debug('getBranchStatusForEachRepo', { reposInfo });
      mapSeries(reposInfo, (repoInfo, nextRepo) => {
        const devBranch = get(repoInfo, 'config.github.devBranch');
        getBranchStatus(repoInfo.repo, devBranch, (err, sha, _success) => {
          if (err) {
            logger.error('Error getting repo branch status', repoInfo.repo, devBranch, err);
            return nextRepo(null, { repo: repoInfo.repo, failReason: 'INVALID_REPO_STATUS' });
          }
          nextRepo(null, Object.assign({}, repoInfo, { sha }));
        });
      }, cb);
    }

    function createTemporaryBranchesForEachRepo(reposInfo, cb) {
      logger.debug('createTemporaryBranchesForEachRepo', reposInfo);
      mapSeries(reposInfo, (repoInfo, nextRepo) => {
        if (repoInfo.failReason) return nextRepo(null, repoInfo);
        const devBranch = get(repoInfo, 'config.github.devBranch');
        createDeployTemporaryBranch(repoInfo.repo, devBranch, (err, branch) => {
          if (err) {
            logger.error('Error creating temporary branch', repoInfo.repo, err);
            return nextRepo(null, Object.assign({}, repoInfo, { failReason: 'BRANCH_CREATION_FAILED' }));
          }
          nextRepo(null, Object.assign({}, repoInfo, { branch }));
        });
      }, cb);
    }

    function notifyPreviewSlackIfEnabled(showPreview, reposInfo, verbose, cb) {
      logger.debug('notifyPreviewSlackIfEnabled', { showPreview, reposInfo, verbose });
      if (!showPreview) return cb(null, reposInfo);
      notify(reposInfo, 'preview', verbose, err => cb(err, reposInfo));
    }

    function deployEachRepo(reposInfo, cb) {
      logger.debug('deployEachRepo', reposInfo);
      mapSeries(reposInfo, (repoInfo, nextRepo) => {
        if (repoInfo.failReason) {
          cleanUpDeploy(repoInfo, err => {
            if (err) logger.error('Error cleaning up deploy', repoInfo.repo, err);
            nextRepo(null, repoInfo);
          });
        }
        else deploy(repoInfo, (err, tag) => {
          // TODO: deserves a refactor
          if (err) {
            logger.error('Error deploying', repoInfo.repo, err);
            return nextRepo(null, Object.assign({}, repoInfo, { failReason: 'REPO_DEPLOY_FAILED' }));
          }
          nextRepo(null, Object.assign({}, repoInfo, { tag }));
        });
      }, cb);
    }

    function notifyRelease(reposInfo, cb) {
      logger.debug('notifyRelease', reposInfo);
      notify(reposInfo, 'release', verbose, err => cb(err, reposInfo));
    }

  };
};
<commit_msg>Fix tmp branch creation based on sha hash<commit_after>'use scrict';

const { mapSeries, waterfall } = require('async');
const { get } = require('lodash');
const logger = require('../../lib/logger');

module.exports = (
  deploysController,
  getConfig,
  getBranchStatus,
  createDeployTemporaryBranch,
  getReleasePreview,
  deploy,
  cleanUpDeploy,
  notify
) => {
  return ({ repos, showPreview, verbose = false }, cb) => {
    try {
      deploysController.start();
    } catch (deployError) {
      logger.error('Already deploying error', repos, deployError);
      notify(repos, 'deployInProgress', verbose, slackError => {
        if (slackError) logger.error(`Error notifying slack: ${err.message}`, repos, slackError);
      });
      return cb(deployError);
    }

    waterfall([
      (next)            => getConfigForEachRepo(repos, next),
      (reposInfo, next) => getBranchStatusForEachRepo(reposInfo, next),
      (reposInfo, next) => createTemporaryBranchesForEachRepo(reposInfo, next),
      (reposInfo, next) => getReleasePreview(reposInfo, next),
      (reposInfo, next) => notifyPreviewSlackIfEnabled(showPreview, reposInfo, verbose, next),
      (reposInfo, next) => deployEachRepo(reposInfo, next),
      (reposInfo, next) => notifyRelease(reposInfo, next),
    ], (err, reposInfo) => {
      deploysController.finish();
      if (err) {
        logger.error('Error deploying all repos', reposInfo, err);
        mapSeries(reposInfo, cleanUpDeploy, cb);
        return;
      }
      cb();
    });

    function getConfigForEachRepo(repos, cb) {
      logger.debug('getConfigForEachRepo', { repos });
      mapSeries(repos, (repo, nextRepo) => {
        getConfig(repo, (err, config) => {
          if (err) {
            logger.error('Error getting repo config', repo, err);
            return nextRepo(null, { repo, failReason: 'INVALID_REPO_CONFIG' });
          }
          nextRepo(err, { repo, config });
        });
      }, cb);
    }

    function getBranchStatusForEachRepo(reposInfo, cb) {
      logger.debug('getBranchStatusForEachRepo', { reposInfo });
      mapSeries(reposInfo, (repoInfo, nextRepo) => {
        const devBranch = get(repoInfo, 'config.github.devBranch');
        getBranchStatus(repoInfo.repo, devBranch, (err, sha, _success) => {
          if (err) {
            logger.error('Error getting repo branch status', repoInfo.repo, devBranch, err);
            return nextRepo(null, { repo: repoInfo.repo, failReason: 'INVALID_REPO_STATUS' });
          }
          nextRepo(null, Object.assign({}, repoInfo, { sha }));
        });
      }, cb);
    }

    function createTemporaryBranchesForEachRepo(reposInfo, cb) {
      logger.debug('createTemporaryBranchesForEachRepo', reposInfo);
      mapSeries(reposInfo, (repoInfo, nextRepo) => {
        if (repoInfo.failReason) return nextRepo(null, repoInfo);
        createDeployTemporaryBranch(repoInfo.repo, repoInfo.sha, (err, branch) => {
          if (err) {
            logger.error('Error creating temporary branch', repoInfo.repo, err);
            return nextRepo(null, Object.assign({}, repoInfo, { failReason: 'BRANCH_CREATION_FAILED' }));
          }
          nextRepo(null, Object.assign({}, repoInfo, { branch }));
        });
      }, cb);
    }

    function notifyPreviewSlackIfEnabled(showPreview, reposInfo, verbose, cb) {
      logger.debug('notifyPreviewSlackIfEnabled', { showPreview, reposInfo, verbose });
      if (!showPreview) return cb(null, reposInfo);
      notify(reposInfo, 'preview', verbose, err => cb(err, reposInfo));
    }

    function deployEachRepo(reposInfo, cb) {
      logger.debug('deployEachRepo', reposInfo);
      mapSeries(reposInfo, (repoInfo, nextRepo) => {
        if (repoInfo.failReason) {
          cleanUpDeploy(repoInfo, err => {
            if (err) logger.error('Error cleaning up deploy', repoInfo.repo, err);
            nextRepo(null, repoInfo);
          });
        }
        else deploy(repoInfo, (err, tag) => {
          // TODO: deserves a refactor
          if (err) {
            logger.error('Error deploying', repoInfo.repo, err);
            return nextRepo(null, Object.assign({}, repoInfo, { failReason: 'REPO_DEPLOY_FAILED' }));
          }
          nextRepo(null, Object.assign({}, repoInfo, { tag }));
        });
      }, cb);
    }

    function notifyRelease(reposInfo, cb) {
      logger.debug('notifyRelease', reposInfo);
      notify(reposInfo, 'release', verbose, err => cb(err, reposInfo));
    }

  };
};
<|endoftext|>


<commit_before>describe('Controller: DistrictMessage', function() {
  var subject,
      scopeget,
      httpBackend,
      timeout,
      DistrictMessage;

  var message = {"name": "some name",
    "address": "123 Main st",
    "sender_name": "educator",
    "sender_email": "something@something.com"}
  beforeEach(module('PDRClient'));

  beforeEach(inject(function($injector, $controller) {
      q                  = $injector.get('$q');
      scope              = $injector.get('$rootScope').$new();
      httpBackend        = $injector.get('$httpBackend');
      DistrictMessage  = $injector.get('DistrictMessage');

      subject  = $controller('DistrictMessageCtrl', {
        $scope: scope
      });
  }));

  it('can create a DistrictMessage', function() {
      spyOn(DistrictMessage, 'save').and.callFake(function(message) {
        var deferred = q.defer();
          deferred.resolve({});
        return {$promise: deferred.promise};
      });

      scope.sendMessage(message);
      scope.$apply();
      expect(scope.success).toEqual("Thank you!");
  });

  it('fails gracefully', function() {
      spyOn(DistrictMessage, 'save').and.callFake(function(message) {
        var deferred = q.defer();
        deferred.reject({"data": {"errors": {"some error"});
        return {$promise: deferred.promise};
      });

      scope.sendMessage(message);
      scope.$apply();
      expect(scope.errors).toEqual("some error");
  });
});
<commit_msg>Fixed struct<commit_after>describe('Controller: DistrictMessage', function() {
  var subject,
      scopeget,
      httpBackend,
      timeout,
      DistrictMessage;

  var message = {"name": "some name",
    "address": "123 Main st",
    "sender_name": "educator",
    "sender_email": "something@something.com"}
  beforeEach(module('PDRClient'));

  beforeEach(inject(function($injector, $controller) {
      q                  = $injector.get('$q');
      scope              = $injector.get('$rootScope').$new();
      httpBackend        = $injector.get('$httpBackend');
      DistrictMessage  = $injector.get('DistrictMessage');

      subject  = $controller('DistrictMessageCtrl', {
        $scope: scope
      });
  }));

  it('can create a DistrictMessage', function() {
      spyOn(DistrictMessage, 'save').and.callFake(function(message) {
        var deferred = q.defer();
          deferred.resolve({});
        return {$promise: deferred.promise};
      });

      scope.sendMessage(message);
      scope.$apply();
      expect(scope.success).toEqual("Thank you!");
  });

  it('fails gracefully', function() {
      spyOn(DistrictMessage, 'save').and.callFake(function(message) {
        var deferred = q.defer();
        deferred.reject({
          "data": {
            "errors": ["some error"]
          }
        });

        return {$promise: deferred.promise};
      });

      scope.sendMessage(message);
      scope.$apply();
      expect(scope.errors).toEqual(["some error"]);
  });
});
<|endoftext|>


<commit_before>import { moduleForComponent, test } from 'ember-qunit';

moduleForComponent('smart-banner', 'Unit | Component | smart banner', {
  // Specify the other units that are required for this test
  needs: ['config:environment'],
  unit: true
});

test('it renders', function(assert) {

  // Creates the component instance
  /*let component =*/ this.subject();
  // Renders the component to the page
  this.render();
  assert.equal(this.$().text().trim(), '');
});
<commit_msg>remove boilerplate unused unit test<commit_after><|endoftext|>


<commit_before>/*
Simple OpenID Plugin
http://code.google.com/p/openid-selector/

This code is licenced under the New BSD License.
*/

var providers_large = {
    stackexchange: {
        name: 'StackExchange',
        url: 'https://openid.stackexchange.com/',
        x: -1,
        y: -518
    },
    google: {
        name: 'Google',
        url: 'https://www.google.com/accounts/o8/id',
        x: -1,
        y: -1
    },
    yahoo: {
        name: 'Yahoo',
        url: 'http://yahoo.com/',
        x: -1,
        y: -63
    },
    myopenid: {
        name: 'MyOpenID',
        url: 'http://myopenid.com/',
        x: -1,
        y: -187
    },
    aol: {
        name: 'AOL',
        label: 'Enter your AOL screenname',
        url: 'http://openid.aol.com/{username}',
        x: -1,
        y: -125
    }
};

var providers_small = {
    livejournal: {
        name: 'LiveJournal',
        label: 'Enter your Livejournal username',
        url: 'http://{username}.livejournal.com/',
        x: -1,
        y: -352
    },
    wordpress: {
        name: 'Wordpress',
        label: 'Enter your Wordpress.com username',
        url: 'http://{username}.wordpress.com/',
        x: -1,
        y: -404
    },
    blogger: {
        name: 'Blogger',
        label: 'Enter your Blogger account',
        url: 'http://{username}.blogspot.com/',
        x: -1,
        y: -249
    },
    verisign: {
        name: 'Verisign',
        label: 'Enter your Verisign username',
        url: 'http://{username}.pip.verisignlabs.com/',
        x: -1,
        y: -378
    },
    claimid: {
        name: 'ClaimID',
        label: 'Enter your ClaimID username',
        url: 'http://openid.claimid.com/{username}',
        x: -1,
        y: -326
    },
    clickpass: {
        name: 'ClickPass',
        label: 'Enter your ClickPass username',
        url: 'http://clickpass.com/public/{username}',
        x: -1,
        y: -274
    },
    google_profile: {
        name: 'Google_Profile',
        label: 'Enter your Google Profile username',
        url: 'http://www.google.com/profiles/{username}',
        x: -1,
        y: -300
    }
};

var providers = $.extend({}, providers_large, providers_small);

var openid = {

    cookie_expires: 6 * 30, // 6 months.
    cookie_name: 'openid_provider',
    cookie_path: '/',

    img_path: '/Content/Img/openid/openid-logos.png?v=3',

    input_id: null,
    provider_url: null,

    init: function (input_id) {

        // turn off hourglass
        $('body').css('cursor', 'default');
        $('#openid_submit').css('cursor', 'default');

        // enable submit button on form
        $('input[type=submit]').removeAttr('disabled');

        var openid_btns = $('#openid_btns');

        this.input_id = input_id;

        $('#openid_choice').show();
        $('#openid_input_area').empty();

        // add box for each provider
        for (id in providers_large) {
            openid_btns.append(this.getBoxHTML(providers_large[id], 'large'));
        }
        if (providers_small) {
            openid_btns.append('
');
            for (id in providers_small) {
                openid_btns.append(this.getBoxHTML(providers_small[id], 'small'));
            }
        }

        $('#openid_form').submit(this.submitx);

    },

    getBoxHTML: function (provider, box_size) {

        var box_id = provider["name"].toLowerCase();
        return '';
    },

    /* provider image click */
    signin: function (box_id, onload) {

        var provider = providers[box_id];
        if (!provider) { return; }

        this.highlight(box_id);

        if (box_id == 'openid') {
            $('#openid_input_area').empty();
            this.setOpenIdUrl("");
            $("#openid_identifier").focus();
            return;
        }

        // prompt user for input?
        if (provider['label']) {
            this.useInputBox(provider);
            this.provider_url = provider['url'];
        } else {
            $('.' + box_id).css('cursor', 'wait');

            if (provider['oauth_version']) {
                this.setOAuthInfo(provider['oauth_version'], provider['oauth_server']);
            } else {
                this.setOpenIdUrl(provider['url']);
            }
            this.provider_url = null;
            if (!onload) {
                $('#openid_form').submit();
            }
        }
    },

    /* Sign-in button click */
    submitx: function () {
        if ($('#openid_username').val() == "") return true;

        // set up hourglass on body
        $('body').css('cursor', 'wait');
        $('#openid_submit').css('cursor', 'wait');
        // disable submit button on form
        $('input[type=submit]', this).attr('disabled', 'disabled');

        var url = openid.provider_url;
        if (url) {
            url = url.replace('{username}', $('#openid_username').val());
            openid.setOpenIdUrl(url);
        }
        return true;
    },

    setOpenIdUrl: function (url) {
        var hidden = $('#' + this.input_id);
        hidden.val(url);

        // Clear OAuth credentials
        $('#oauth_version').val('');
        $('#oauth_server').val('');
    },

    setOAuthInfo: function (version, server) {
        var ver = $('#oauth_version');
        ver.val(version);

        var serv = $('#oauth_server');
        serv.val(server);

        // Clear OpenId credentials
        $('#' + this.input_id).val('');
    },

    highlight: function (box_id) {
        // remove previous highlight.
        var highlight = $('#openid_highlight');
        if (highlight) {
            highlight.replaceWith($('#openid_highlight a')[0]);
        }
        // add new highlight.
        $('.' + box_id).wrap('

');
    },

    useInputBox: function (provider) {

        var input_area = $('#openid_input_area');

        var html = '';
        var id = 'openid_username';
        var value = '';
        var label = provider['label'];
        var style = '';

        if (label) {
            html = '
' + label + '
';
        }
        html += '<input id="' + id + '" type="text" style="' + style + '" name="' + id + '" value="' + value + '" />' +
					'<input id="openid_submit" type="submit" value="Sign In"/>';

        input_area.empty();
        input_area.append(html);

        $('#' + id).focus();
    }
};<commit_msg>Update Yahoo openId end point<commit_after>/*
Simple OpenID Plugin
http://code.google.com/p/openid-selector/

This code is licenced under the New BSD License.
*/

var providers_large = {
    stackexchange: {
        name: 'StackExchange',
        url: 'https://openid.stackexchange.com/',
        x: -1,
        y: -518
    },
    google: {
        name: 'Google',
        url: 'https://www.google.com/accounts/o8/id',
        x: -1,
        y: -1
    },
    yahoo: {
        name: 'Yahoo',
        url: 'https://me.yahoo.com/',
        x: -1,
        y: -63
    },
    myopenid: {
        name: 'MyOpenID',
        url: 'http://myopenid.com/',
        x: -1,
        y: -187
    },
    aol: {
        name: 'AOL',
        label: 'Enter your AOL screenname',
        url: 'http://openid.aol.com/{username}',
        x: -1,
        y: -125
    }
};

var providers_small = {
    livejournal: {
        name: 'LiveJournal',
        label: 'Enter your Livejournal username',
        url: 'http://{username}.livejournal.com/',
        x: -1,
        y: -352
    },
    wordpress: {
        name: 'Wordpress',
        label: 'Enter your Wordpress.com username',
        url: 'http://{username}.wordpress.com/',
        x: -1,
        y: -404
    },
    blogger: {
        name: 'Blogger',
        label: 'Enter your Blogger account',
        url: 'http://{username}.blogspot.com/',
        x: -1,
        y: -249
    },
    verisign: {
        name: 'Verisign',
        label: 'Enter your Verisign username',
        url: 'http://{username}.pip.verisignlabs.com/',
        x: -1,
        y: -378
    },
    claimid: {
        name: 'ClaimID',
        label: 'Enter your ClaimID username',
        url: 'http://openid.claimid.com/{username}',
        x: -1,
        y: -326
    },
    clickpass: {
        name: 'ClickPass',
        label: 'Enter your ClickPass username',
        url: 'http://clickpass.com/public/{username}',
        x: -1,
        y: -274
    },
    google_profile: {
        name: 'Google_Profile',
        label: 'Enter your Google Profile username',
        url: 'http://www.google.com/profiles/{username}',
        x: -1,
        y: -300
    }
};

var providers = $.extend({}, providers_large, providers_small);

var openid = {

    cookie_expires: 6 * 30, // 6 months.
    cookie_name: 'openid_provider',
    cookie_path: '/',

    img_path: '/Content/Img/openid/openid-logos.png?v=3',

    input_id: null,
    provider_url: null,

    init: function (input_id) {

        // turn off hourglass
        $('body').css('cursor', 'default');
        $('#openid_submit').css('cursor', 'default');

        // enable submit button on form
        $('input[type=submit]').removeAttr('disabled');

        var openid_btns = $('#openid_btns');

        this.input_id = input_id;

        $('#openid_choice').show();
        $('#openid_input_area').empty();

        // add box for each provider
        for (id in providers_large) {
            openid_btns.append(this.getBoxHTML(providers_large[id], 'large'));
        }
        if (providers_small) {
            openid_btns.append('
');
            for (id in providers_small) {
                openid_btns.append(this.getBoxHTML(providers_small[id], 'small'));
            }
        }

        $('#openid_form').submit(this.submitx);

    },

    getBoxHTML: function (provider, box_size) {

        var box_id = provider["name"].toLowerCase();
        return '';
    },

    /* provider image click */
    signin: function (box_id, onload) {

        var provider = providers[box_id];
        if (!provider) { return; }

        this.highlight(box_id);

        if (box_id == 'openid') {
            $('#openid_input_area').empty();
            this.setOpenIdUrl("");
            $("#openid_identifier").focus();
            return;
        }

        // prompt user for input?
        if (provider['label']) {
            this.useInputBox(provider);
            this.provider_url = provider['url'];
        } else {
            $('.' + box_id).css('cursor', 'wait');

            if (provider['oauth_version']) {
                this.setOAuthInfo(provider['oauth_version'], provider['oauth_server']);
            } else {
                this.setOpenIdUrl(provider['url']);
            }
            this.provider_url = null;
            if (!onload) {
                $('#openid_form').submit();
            }
        }
    },

    /* Sign-in button click */
    submitx: function () {
        if ($('#openid_username').val() == "") return true;

        // set up hourglass on body
        $('body').css('cursor', 'wait');
        $('#openid_submit').css('cursor', 'wait');
        // disable submit button on form
        $('input[type=submit]', this).attr('disabled', 'disabled');

        var url = openid.provider_url;
        if (url) {
            url = url.replace('{username}', $('#openid_username').val());
            openid.setOpenIdUrl(url);
        }
        return true;
    },

    setOpenIdUrl: function (url) {
        var hidden = $('#' + this.input_id);
        hidden.val(url);

        // Clear OAuth credentials
        $('#oauth_version').val('');
        $('#oauth_server').val('');
    },

    setOAuthInfo: function (version, server) {
        var ver = $('#oauth_version');
        ver.val(version);

        var serv = $('#oauth_server');
        serv.val(server);

        // Clear OpenId credentials
        $('#' + this.input_id).val('');
    },

    highlight: function (box_id) {
        // remove previous highlight.
        var highlight = $('#openid_highlight');
        if (highlight) {
            highlight.replaceWith($('#openid_highlight a')[0]);
        }
        // add new highlight.
        $('.' + box_id).wrap('

');
    },

    useInputBox: function (provider) {

        var input_area = $('#openid_input_area');

        var html = '';
        var id = 'openid_username';
        var value = '';
        var label = provider['label'];
        var style = '';

        if (label) {
            html = '
' + label + '
';
        }
        html += '<input id="' + id + '" type="text" style="' + style + '" name="' + id + '" value="' + value + '" />' +
					'<input id="openid_submit" type="submit" value="Sign In"/>';

        input_area.empty();
        input_area.append(html);

        $('#' + id).focus();
    }
};<|endoftext|>


<commit_before>import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import { blocklyWorkspaceMock } from '../../helpers/mocks';

module('Unit | Service | blocks-gallery', function (hooks) {
  setupTest(hooks);

  hooks.beforeEach(function () {
    this.blocksGallery = this.owner.lookup('service:blocksGallery');
    this.blockly = this.owner.lookup('service:blockly');
    blocklyWorkspaceMock();
    this.blocksGallery.start();
  });

///////////// REQUIRED INPUTS /////////////

function createBlock(type) {
  return Blockly.mainWorkspace.newBlock(type)
}

function testHasRequiredInputs(blockType) {
  test(`${blockType} has required inputs`, function(assert) {
    let block = createBlock(blockType)
    block.inputList
      .filter(input => input.type == Blockly.INPUT_VALUE)
      .forEach(input => {
        let inputBlock = input.connection.targetBlock()
        assert.ok(inputBlock, `${input.name} is required`)
        assert.equal(inputBlock.type, "required_value")
      })

    block.inputList
      .filter(input => input.type == Blockly.NEXT_STATEMENT)
      .forEach(input => {
        let inputBlock = input.connection.targetBlock()
        assert.ok(inputBlock, `${input.name} is required`)
        assert.equal(inputBlock.type, "required_statement")
      })
  });
}

// Repeticiones
testHasRequiredInputs('RepetirVacio')
testHasRequiredInputs('Repetir')
testHasRequiredInputs('Hasta')

// Alternativas
testHasRequiredInputs('Si')
testHasRequiredInputs('SiNo')

// Primitivas
testHasRequiredInputs('GirarGrados')

let toolbox = `
<block type="GirarGrados">
  <value name="grados">
    <block type="math_number"><field name="NUM">90</field></block>
  </value>
</block>
`

test('When required input exists should be ok', function(assert) {
  let block = Blockly.textToBlock(toolbox)
  assert.notOk(findChildren(block, "required_value"))
  assert.ok(block.allInputsFilled(false))
});

test('When required input exists and it is disposed should be required again', function(assert) {
  let block = Blockly.textToBlock(toolbox)
  findChildren(block, "math_number").dispose()
  assert.ok(findChildren(block, "required_value"))
  assert.notOk(block.allInputsFilled(false))
});

///////////// PARAMS /////////////

let procedure = `
<block type="procedures_defnoreturn" id="whpKBVIV.;:t%=8XN+E_" x="778" y="185">
<mutation>
  <arg name="param"></arg>
</mutation>
<field name="NAME">Hacer algo</field>
<field name="ARG0">param</field>
<statement name="STACK">
  <block type="GirarGrados" id=";qf!gXUI;'/BUa0nx#y]">
    <value name="grados">
      <block type="variables_get" id="wAE7-:@m*P0G[x'Uf$Hv">
        <mutation var="param" parent="whpKBVIV.;:t%=8XN+E_"></mutation>
      </block>
    </value>
  </block>
</statement>
</block>
`

test('Parameter in parent procedure should be ok', function(assert) {
    let param = findParam(Blockly.textToBlock(procedure))
    assert.notOk(param.disabled)
    assert.notOk(param.warning)
});

let procedureWithDeletedParam = `
<block type="procedures_defnoreturn" id="whpKBVIV.;:t%=8XN+E_" x="778" y="185">
<field name="NAME">Hacer algo</field>
<statement name="STACK">
  <block type="GirarGrados" id=";qf!gXUI;'/BUa0nx#y]">
    <value name="grados">
      <block type="variables_get" id="wAE7-:@m*P0G[x'Uf$Hv">
        <mutation var="param" parent="whpKBVIV.;:t%=8XN+E_"></mutation>
      </block>
    </value>
  </block>
</statement>
</block>
`

test('Parameter in parent procedure without param should be disabled', function(assert) {
  let param = findParam(Blockly.textToBlock(procedureWithDeletedParam))
  assert.ok(param.disabled)
  assert.equal(param.warning.getText(), "Este bloque ya no puede usarse, el parámetro ha sido eliminado.")
});

let emptyProcedure = `
<block type="procedures_defnoreturn" id="whpKBVIV.;:t%=8XN+E_" x="41" y="112">
<mutation>
  <arg name="param"></arg>
</mutation>
<field name="NAME">Hacer algo</field>
<field name="ARG0">param</field>
</block>
`

let main = `
<block type="al_empezar_a_ejecutar" id="~7u[uK:$SQa$}1uY9,h6" deletable="false" movable="false" editable="false" x="15" y="15">
<statement name="program">
  <block type="GirarGrados" id="jvQK2Fm?8Sh72]]8qk$Z">
    <value name="grados">
      <block type="variables_get" id="wAE7-:@m*P0G[x'Uf$Hv">
        <mutation var="param" parent="whpKBVIV.;:t%=8XN+E_"></mutation>
      </block>
    </value>
  </block>
</statement>
</block>
`

test('Parameter in non parent procedure should be disabled and with warning', function(assert) {
    Blockly.textToBlock(emptyProcedure)
    let param = findParam(Blockly.textToBlock(main))
    assert.ok(param.disabled)
    assert.equal(param.warning.getText(), "Este bloque no puede usarse aquí. Es un parámetro que sólo puede usarse en Hacer algo.")
});

let flying = `
<block type="variables_get" id="wAE7-:@m*P0G[x'Uf$Hv" disabled="true" x="399" y="294">
<mutation var="param" parent="whpKBVIV.;:t%=8XN+E_"></mutation>
</block>
`

test('Parameter in non parent procedure should only be disabled', function(assert) {
    Blockly.textToBlock(emptyProcedure)
    let param = findParam(Blockly.textToBlock(flying))
    assert.ok(param.disabled)
    assert.notOk(param.warning)
});

test('Parameter should dispose when procedure is disposed', function(assert) {
    let procedure = Blockly.textToBlock(emptyProcedure)
    let param = findParam(Blockly.textToBlock(flying))
    assert.ok(param.workspace)
    procedure.dispose()
    assertAsync(assert, function() {
        assert.notOk(param.workspace)
    })
});

let mainWithoutParent = `
<block type="al_empezar_a_ejecutar" id="~7u[uK:$SQa$}1uY9,h6" deletable="false" movable="false" editable="false" x="15" y="15">
<statement name="program">
  <block type="GirarGrados" id="jvQK2Fm?8Sh72]]8qk$Z">
    <value name="grados">
      <block type="variables_get" id="wAE7-:@m*P0G[x'Uf$Hv">
        <mutation var="param"></mutation>
      </block>
    </value>
  </block>
</statement>
</block>
`

test('Parameter without parent procedure should be always ok', function(assert) {
    let param = findParam(Blockly.textToBlock(mainWithoutParent))
    assert.notOk(param.disabled)
    assert.notOk(param.warning)
});

function findParam(rootBlock) {
    let param = findChildren(rootBlock, "variables_get")
    param.onchange() // Force initialize
    return param
}

function findChildren(rootBlock, type) {
  if (!rootBlock) return null
  if (rootBlock.type == type) return rootBlock
  return rootBlock.getChildren().map(b => findChildren(b, type)).find(b => b != undefined)
}

function assertAsync(assert, fn) {
  let done = assert.async(1)
  setTimeout(function() {
      fn(); done()
  })
}

///////////// ALIAS /////////////

let testAlias = function (alias, type) {
    test(`check if ${alias} block definition exist and is equal to ${type} block definition`, function (assert) {
      assert.ok(this.blocksGallery.areAliases(alias, type));
    });
  }

  testAlias('si', 'Si');
  testAlias('sino', 'SiNo');
  testAlias('Sino', 'SiNo');
  testAlias('hasta', 'Hasta');
  testAlias('prenderCompuConColision', 'PrenderComputadora');
  testAlias('PrenderCompu', 'PrenderComputadora');
  testAlias('ApagarCompu', 'ApagarComputadora');
  testAlias('SiguienteCompu', 'PasarASiguienteComputadora');
  testAlias('Descubralculpable', 'EsCulpable');
  testAlias('repetir', 'Repetir');
  testAlias('tocandoBanana', 'TocandoBanana');
  testAlias('tocandoManzana', 'TocandoManzana');
  testAlias('PrenderFogata', 'PrenderFogata');
  testAlias('Dejarregalo', 'DejarRegalo');
  testAlias('Contarbanana', 'ContarBanana');
  testAlias('Contarmanzana', 'ContarManzana');
  testAlias('AvanzarKm', 'Avanzar1km');
  testAlias('cambiarColor', 'CambiarColor');
  testAlias('siguienteFoco', 'siguienteFoco');
  testAlias('empezarFiesta', 'EmpezarFiesta');
  testAlias('Volveralbordeizquierdo', 'VolverAlBordeIzquierdo');
  testAlias('Primersospechoso', 'IrAlPrimerSospechoso');
  testAlias('PrimerSospechoso', 'IrAlPrimerSospechoso');
  testAlias('Siguientesospechoso', 'IrAlSiguienteSospechoso');
  testAlias('SiguienteSospechoso', 'IrAlSiguienteSospechoso');
  testAlias('Sacardisfraz', 'InterrogarSospechoso');
  testAlias('SacarDisfraz', 'InterrogarSospechoso');
  testAlias('Estoyenunaesquina', 'EstoyEnEsquina');
  testAlias('tocandoFogata', 'TocandoFogata');
  testAlias('tocandoInicio', 'TocandoInicio');
  testAlias('tocandoFinal', 'TocandoFinal');
  testAlias('tocandoPelota', 'TocandoPelota');
  testAlias('tocandoQueso', 'TocandoQueso');
  testAlias('tocandoLuz', 'TocandoLuz');
  testAlias('Abrirojos', 'AbrirOjos');
  testAlias('Cerrarojos', 'CerrarOjos');
  testAlias('Soar', 'Soniar');
  testAlias('Agarrarllave', 'AgarrarLlave');
  testAlias('Abrircofre', 'AbrirCofre');
  testAlias('Darsombrero', 'DarSombrero');
  testAlias('Atacarconespada', 'AtacarConEspada');
  testAlias('Escaparenunicornio', 'EscaparEnUnicornio');
  testAlias('estoyInicio', 'EstoySobreElInicio');
  testAlias('estoyAlInicio', 'EstoySobreElInicio');
  testAlias('estoyFinColumna', 'EstoySobreElFinal');
  testAlias('EstoyAlFin', 'EstoySobreElFinal');
  testAlias('ComerBananaNano', 'ComerBanana');
  testAlias('saltar1', 'SaltarHablando');
});<commit_msg>Refactor tests<commit_after>import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import { blocklyWorkspaceMock } from '../../helpers/mocks';

module('Unit | Service | blocks-gallery', function (hooks) {
  setupTest(hooks);

  hooks.beforeEach(function () {
    this.blocksGallery = this.owner.lookup('service:blocksGallery');
    this.blockly = this.owner.lookup('service:blockly');
    blocklyWorkspaceMock();
    this.blocksGallery.start();
  });

///////////// REQUIRED INPUTS /////////////

function createBlock(type) {
  return Blockly.mainWorkspace.newBlock(type)
}

function assertRequiredInputs(assert, block, inputType, blockType) {
  block.inputList
    .filter(input => input.type == inputType)
    .forEach(input => {
      let inputBlock = input.connection.targetBlock()
      assert.ok(inputBlock, `${input.name} is required`)
      assert.equal(inputBlock.type, blockType)
    })
}

function testHasRequiredInputs(blockType) {
  test(`${blockType} has required inputs`, function(assert) {
    let block = createBlock(blockType)
    assertRequiredInputs(assert, block, Blockly.INPUT_VALUE, 'required_value')
    assertRequiredInputs(assert, block, Blockly.NEXT_STATEMENT, 'required_statement')
  });
}

// Repeticiones
testHasRequiredInputs('RepetirVacio')
testHasRequiredInputs('Repetir')
testHasRequiredInputs('Hasta')

// Alternativas
testHasRequiredInputs('Si')
testHasRequiredInputs('SiNo')

// Primitivas
testHasRequiredInputs('GirarGrados')

// Toolbox
let toolbox = `
<block type="GirarGrados">
  <value name="grados">
    <block type="math_number"><field name="NUM">90</field></block>
  </value>
</block>
`

test('When required input exists should be ok', function(assert) {
  let block = Blockly.textToBlock(toolbox)
  assert.notOk(findChildren(block, "required_value"))
  assert.ok(block.allInputsFilled(false))
});

test('When required input exists and it is disposed should be required again', function(assert) {
  let block = Blockly.textToBlock(toolbox)
  findChildren(block, "math_number").dispose()
  assert.ok(findChildren(block, "required_value"))
  assert.notOk(block.allInputsFilled(false))
});

///////////// PARAMS /////////////

let procedure = `
<block type="procedures_defnoreturn" id="whpKBVIV.;:t%=8XN+E_" x="778" y="185">
<mutation>
  <arg name="param"></arg>
</mutation>
<field name="NAME">Hacer algo</field>
<field name="ARG0">param</field>
<statement name="STACK">
  <block type="GirarGrados" id=";qf!gXUI;'/BUa0nx#y]">
    <value name="grados">
      <block type="variables_get" id="wAE7-:@m*P0G[x'Uf$Hv">
        <mutation var="param" parent="whpKBVIV.;:t%=8XN+E_"></mutation>
      </block>
    </value>
  </block>
</statement>
</block>
`

test('Parameter in parent procedure should be ok', function(assert) {
    let param = findParam(Blockly.textToBlock(procedure))
    assert.notOk(param.disabled)
    assert.notOk(param.warning)
});

let procedureWithDeletedParam = `
<block type="procedures_defnoreturn" id="whpKBVIV.;:t%=8XN+E_" x="778" y="185">
<field name="NAME">Hacer algo</field>
<statement name="STACK">
  <block type="GirarGrados" id=";qf!gXUI;'/BUa0nx#y]">
    <value name="grados">
      <block type="variables_get" id="wAE7-:@m*P0G[x'Uf$Hv">
        <mutation var="param" parent="whpKBVIV.;:t%=8XN+E_"></mutation>
      </block>
    </value>
  </block>
</statement>
</block>
`

test('Parameter in parent procedure without param should be disabled', function(assert) {
  let param = findParam(Blockly.textToBlock(procedureWithDeletedParam))
  assert.ok(param.disabled)
  assert.equal(param.warning.getText(), "Este bloque ya no puede usarse, el parámetro ha sido eliminado.")
});

let emptyProcedure = `
<block type="procedures_defnoreturn" id="whpKBVIV.;:t%=8XN+E_" x="41" y="112">
<mutation>
  <arg name="param"></arg>
</mutation>
<field name="NAME">Hacer algo</field>
<field name="ARG0">param</field>
</block>
`

let main = `
<block type="al_empezar_a_ejecutar" id="~7u[uK:$SQa$}1uY9,h6" deletable="false" movable="false" editable="false" x="15" y="15">
<statement name="program">
  <block type="GirarGrados" id="jvQK2Fm?8Sh72]]8qk$Z">
    <value name="grados">
      <block type="variables_get" id="wAE7-:@m*P0G[x'Uf$Hv">
        <mutation var="param" parent="whpKBVIV.;:t%=8XN+E_"></mutation>
      </block>
    </value>
  </block>
</statement>
</block>
`

test('Parameter in non parent procedure should be disabled and with warning', function(assert) {
    Blockly.textToBlock(emptyProcedure)
    let param = findParam(Blockly.textToBlock(main))
    assert.ok(param.disabled)
    assert.equal(param.warning.getText(), "Este bloque no puede usarse aquí. Es un parámetro que sólo puede usarse en Hacer algo.")
});

let flying = `
<block type="variables_get" id="wAE7-:@m*P0G[x'Uf$Hv" disabled="true" x="399" y="294">
<mutation var="param" parent="whpKBVIV.;:t%=8XN+E_"></mutation>
</block>
`

test('Parameter in non parent procedure should only be disabled', function(assert) {
    Blockly.textToBlock(emptyProcedure)
    let param = findParam(Blockly.textToBlock(flying))
    assert.ok(param.disabled)
    assert.notOk(param.warning)
});

test('Parameter should dispose when procedure is disposed', function(assert) {
    let procedure = Blockly.textToBlock(emptyProcedure)
    let param = findParam(Blockly.textToBlock(flying))
    assert.ok(param.workspace)
    procedure.dispose()
    assertAsync(assert, function() {
        assert.notOk(param.workspace)
    })
});

let mainWithoutParent = `
<block type="al_empezar_a_ejecutar" id="~7u[uK:$SQa$}1uY9,h6" deletable="false" movable="false" editable="false" x="15" y="15">
<statement name="program">
  <block type="GirarGrados" id="jvQK2Fm?8Sh72]]8qk$Z">
    <value name="grados">
      <block type="variables_get" id="wAE7-:@m*P0G[x'Uf$Hv">
        <mutation var="param"></mutation>
      </block>
    </value>
  </block>
</statement>
</block>
`

test('Parameter without parent procedure should be always ok', function(assert) {
    let param = findParam(Blockly.textToBlock(mainWithoutParent))
    assert.notOk(param.disabled)
    assert.notOk(param.warning)
});

function findParam(rootBlock) {
    let param = findChildren(rootBlock, "variables_get")
    param.onchange() // Force initialize
    return param
}

function findChildren(rootBlock, type) {
  if (!rootBlock) return null
  if (rootBlock.type == type) return rootBlock
  return rootBlock.getChildren().map(b => findChildren(b, type)).find(b => b != undefined)
}

function assertAsync(assert, fn) {
  let done = assert.async(1)
  setTimeout(function() {
      fn(); done()
  })
}

///////////// ALIAS /////////////

let testAlias = function (alias, type) {
    test(`check if ${alias} block definition exist and is equal to ${type} block definition`, function (assert) {
      assert.ok(this.blocksGallery.areAliases(alias, type));
    });
  }

  testAlias('si', 'Si');
  testAlias('sino', 'SiNo');
  testAlias('Sino', 'SiNo');
  testAlias('hasta', 'Hasta');
  testAlias('prenderCompuConColision', 'PrenderComputadora');
  testAlias('PrenderCompu', 'PrenderComputadora');
  testAlias('ApagarCompu', 'ApagarComputadora');
  testAlias('SiguienteCompu', 'PasarASiguienteComputadora');
  testAlias('Descubralculpable', 'EsCulpable');
  testAlias('repetir', 'Repetir');
  testAlias('tocandoBanana', 'TocandoBanana');
  testAlias('tocandoManzana', 'TocandoManzana');
  testAlias('PrenderFogata', 'PrenderFogata');
  testAlias('Dejarregalo', 'DejarRegalo');
  testAlias('Contarbanana', 'ContarBanana');
  testAlias('Contarmanzana', 'ContarManzana');
  testAlias('AvanzarKm', 'Avanzar1km');
  testAlias('cambiarColor', 'CambiarColor');
  testAlias('siguienteFoco', 'siguienteFoco');
  testAlias('empezarFiesta', 'EmpezarFiesta');
  testAlias('Volveralbordeizquierdo', 'VolverAlBordeIzquierdo');
  testAlias('Primersospechoso', 'IrAlPrimerSospechoso');
  testAlias('PrimerSospechoso', 'IrAlPrimerSospechoso');
  testAlias('Siguientesospechoso', 'IrAlSiguienteSospechoso');
  testAlias('SiguienteSospechoso', 'IrAlSiguienteSospechoso');
  testAlias('Sacardisfraz', 'InterrogarSospechoso');
  testAlias('SacarDisfraz', 'InterrogarSospechoso');
  testAlias('Estoyenunaesquina', 'EstoyEnEsquina');
  testAlias('tocandoFogata', 'TocandoFogata');
  testAlias('tocandoInicio', 'TocandoInicio');
  testAlias('tocandoFinal', 'TocandoFinal');
  testAlias('tocandoPelota', 'TocandoPelota');
  testAlias('tocandoQueso', 'TocandoQueso');
  testAlias('tocandoLuz', 'TocandoLuz');
  testAlias('Abrirojos', 'AbrirOjos');
  testAlias('Cerrarojos', 'CerrarOjos');
  testAlias('Soar', 'Soniar');
  testAlias('Agarrarllave', 'AgarrarLlave');
  testAlias('Abrircofre', 'AbrirCofre');
  testAlias('Darsombrero', 'DarSombrero');
  testAlias('Atacarconespada', 'AtacarConEspada');
  testAlias('Escaparenunicornio', 'EscaparEnUnicornio');
  testAlias('estoyInicio', 'EstoySobreElInicio');
  testAlias('estoyAlInicio', 'EstoySobreElInicio');
  testAlias('estoyFinColumna', 'EstoySobreElFinal');
  testAlias('EstoyAlFin', 'EstoySobreElFinal');
  testAlias('ComerBananaNano', 'ComerBanana');
  testAlias('saltar1', 'SaltarHablando');
});<|endoftext|>