<commit_before>/**
* @license
*
* Regression.JS - Regression functions for javascript
* http://tom-alexander.github.com/regression-js/
*
* copyright(c) 2013 Tom Alexander
* Licensed under the MIT license.
*
**/

;(function() {
    'use strict';

    var gaussianElimination = function(a, o) {
           var i = 0, j = 0, k = 0, maxrow = 0, tmp = 0, n = a.length - 1, x = new Array(o);
           for (i = 0; i < n; i++) {
              maxrow = i;
              for (j = i + 1; j < n; j++) {
                 if (Math.abs(a[i][j]) > Math.abs(a[i][maxrow]))
                    maxrow = j;
              }
              for (k = i; k < n + 1; k++) {
                 tmp = a[k][i];
                 a[k][i] = a[k][maxrow];
                 a[k][maxrow] = tmp;
              }
              for (j = i + 1; j < n; j++) {
                 for (k = n; k >= i; k--) {
                    a[k][j] -= a[k][i] * a[i][j] / a[i][i];
                 }
              }
           }
           for (j = n - 1; j >= 0; j--) {
              tmp = 0;
              for (k = j + 1; k < n; k++)
                 tmp += a[k][j] * x[k];
              x[j] = (a[n][j] - tmp) / a[j][j];
           }
           return (x);
    };

        var methods = {
            linear: function(data) {
                var sum = [0, 0, 0, 0, 0], n = 0, results = [];

                for (; n < data.length; n++) {
                  if (data[n][1] != null) {
                    sum[0] += data[n][0];
                    sum[1] += data[n][1];
                    sum[2] += data[n][0] * data[n][0];
                    sum[3] += data[n][0] * data[n][1];
                    sum[4] += data[n][1] * data[n][1];
                  }
                }

                var gradient = (n * sum[3] - sum[0] * sum[1]) / (n * sum[2] - sum[0] * sum[0]);
                var intercept = (sum[1] / n) - (gradient * sum[0]) / n;
              //  var correlation = (n * sum[3] - sum[0] * sum[1]) / Math.sqrt((n * sum[2] - sum[0] * sum[0]) * (n * sum[4] - sum[1] * sum[1]));

                for (var i = 0, len = data.length; i < len; i++) {
                    var coordinate = [data[i][0], data[i][0] * gradient + intercept];
                    results.push(coordinate);
                }

                var string = 'y = ' + Math.round(gradient*100) / 100 + 'x + ' + Math.round(intercept*100) / 100;

                return {equation: [gradient, intercept], points: results, string: string};
            },

            exponential: function(data) {
                var sum = [0, 0, 0, 0, 0, 0], n = 0, results = [];

                for (len = data.length; n < len; n++) {
                  if (data[n][1] != null) {
                    sum[0] += data[n][0];
                    sum[1] += data[n][1];
                    sum[2] += data[n][0] * data[n][0] * data[n][1];
                    sum[3] += data[n][1] * Math.log(data[n][1]);
                    sum[4] += data[n][0] * data[n][1] * Math.log(data[n][1]);
                    sum[5] += data[n][0] * data[n][1];
                  }
                }

                var denominator = (sum[1] * sum[2] - sum[5] * sum[5]);
                var A = Math.pow(Math.E, (sum[2] * sum[3] - sum[5] * sum[4]) / denominator);
                var B = (sum[1] * sum[4] - sum[5] * sum[3]) / denominator;

                for (var i = 0, len = data.length; i < len; i++) {
                    var coordinate = [data[i][0], A * Math.pow(Math.E, B * data[i][0])];
                    results.push(coordinate);
                }

                var string = 'y = ' + Math.round(A*100) / 100 + 'e^(' + Math.round(B*100) / 100 + 'x)';

                return {equation: [A, B], points: results, string: string};
            },

            logarithmic: function(data) {
                var sum = [0, 0, 0, 0], n = 0, results = [];

                for (len = data.length; n < len; n++) {
                  if (data[n][1] != null) {
                    sum[0] += Math.log(data[n][0]);
                    sum[1] += data[n][1] * Math.log(data[n][0]);
                    sum[2] += data[n][1];
                    sum[3] += Math.pow(Math.log(data[n][0]), 2);
                  }
                }

                var B = (n * sum[1] - sum[2] * sum[0]) / (n * sum[3] - sum[0] * sum[0]);
                var A = (sum[2] - B * sum[0]) / n;

                for (var i = 0, len = data.length; i < len; i++) {
                    var coordinate = [data[i][0], A + B * Math.log(data[i][0])];
                    results.push(coordinate);
                }

                var string = 'y = ' + Math.round(A*100) / 100 + ' + ' + Math.round(B*100) / 100 + ' ln(x)';

                return {equation: [A, B], points: results, string: string};
            },

            power: function(data) {
                var sum = [0, 0, 0, 0], n = 0, results = [];

                for (len = data.length; n < len; n++) {
                  if (data[n][1] != null) {
                    sum[0] += Math.log(data[n][0]);
                    sum[1] += Math.log(data[n][1]) * Math.log(data[n][0]);
                    sum[2] += Math.log(data[n][1]);
                    sum[3] += Math.pow(Math.log(data[n][0]), 2);
                  }
                }

                var B = (n * sum[1] - sum[2] * sum[0]) / (n * sum[3] - sum[0] * sum[0]);
                var A = Math.pow(Math.E, (sum[2] - B * sum[0]) / n);

                for (var i = 0, len = data.length; i < len; i++) {
                    var coordinate = [data[i][0], A * Math.pow(data[i][0] , B)];
                    results.push(coordinate);
                }

                 var string = 'y = ' + Math.round(A*100) / 100 + 'x^' + Math.round(B*100) / 100;

                return {equation: [A, B], points: results, string: string};
            },

            polynomial: function(data, order) {
                if(typeof order == 'undefined'){
                    order = 2;
                }
                 var lhs = [], rhs = [], results = [], a = 0, b = 0, i = 0, k = order + 1;

                        for (; i < k; i++) {
                           for (var l = 0, len = data.length; l < len; l++) {
                              if (data[l][1] != null) {
                               a += Math.pow(data[l][0], i) * data[l][1];
                              }
                            }
                            lhs.push(a), a = 0;
                            var c = [];
                            for (var j = 0; j < k; j++) {
                               for (var l = 0, len = data.length; l < len; l++) {
                                  if (data[l][1] != null) {
                                   b += Math.pow(data[l][0], i + j);
                                  }
                                }
                                c.push(b), b = 0;
                            }
                            rhs.push(c);
                        }
                rhs.push(lhs);

               var equation = gaussianElimination(rhs, k);

                    for (var i = 0, len = data.length; i < len; i++) {
                        var answer = 0;
                        for (var w = 0; w < equation.length; w++) {
                            answer += equation[w] * Math.pow(data[i][0], w);
                        }
                        results.push([data[i][0], answer]);
                    }

                    var string = 'y = ';

                    for(var i = equation.length-1; i >= 0; i--){
                      if(i > 1) string += Math.round(equation[i]*100) / 100 + 'x^' + i + ' + ';
                      else if (i == 1) string += Math.round(equation[i]*100) / 100 + 'x' + ' + ';
                      else string += Math.round(equation[i]*100) / 100;
                    }

                return {equation: equation, points: results, string: string};
            },

            lastvalue: function(data) {
              var results = [];
              var lastvalue = null;
              for (var i = 0; i < data.length; i++) {
                if (data[i][1]) {
                  lastvalue = data[i][1];
                  results.push([data[i][0], data[i][1]]);
                }
                else {
                  results.push([data[i][0], lastvalue]);
                }
              }

              return {equation: [lastvalue], points: results, string: "" + lastvalue};
            }
        };

var regression = (function(method, data, order) {

       if (typeof method == 'string') {
           return methods[method](data, order);
       }
    });

if (typeof exports !== 'undefined') {
    module.exports = regression;
} else {
    window.regression = regression;
}

}());
<commit_msg>Update string of result for polynomial func.<commit_after>/**
* @license
*
* Regression.JS - Regression functions for javascript
* http://tom-alexander.github.com/regression-js/
*
* copyright(c) 2013 Tom Alexander
* Licensed under the MIT license.
*
**/

;(function() {
    'use strict';

    var gaussianElimination = function(a, o) {
           var i = 0, j = 0, k = 0, maxrow = 0, tmp = 0, n = a.length - 1, x = new Array(o);
           for (i = 0; i < n; i++) {
              maxrow = i;
              for (j = i + 1; j < n; j++) {
                 if (Math.abs(a[i][j]) > Math.abs(a[i][maxrow]))
                    maxrow = j;
              }
              for (k = i; k < n + 1; k++) {
                 tmp = a[k][i];
                 a[k][i] = a[k][maxrow];
                 a[k][maxrow] = tmp;
              }
              for (j = i + 1; j < n; j++) {
                 for (k = n; k >= i; k--) {
                    a[k][j] -= a[k][i] * a[i][j] / a[i][i];
                 }
              }
           }
           for (j = n - 1; j >= 0; j--) {
              tmp = 0;
              for (k = j + 1; k < n; k++)
                 tmp += a[k][j] * x[k];
              x[j] = (a[n][j] - tmp) / a[j][j];
           }
           return (x);
    };

        var methods = {
            linear: function(data) {
                var sum = [0, 0, 0, 0, 0], n = 0, results = [];

                for (; n < data.length; n++) {
                  if (data[n][1] != null) {
                    sum[0] += data[n][0];
                    sum[1] += data[n][1];
                    sum[2] += data[n][0] * data[n][0];
                    sum[3] += data[n][0] * data[n][1];
                    sum[4] += data[n][1] * data[n][1];
                  }
                }

                var gradient = (n * sum[3] - sum[0] * sum[1]) / (n * sum[2] - sum[0] * sum[0]);
                var intercept = (sum[1] / n) - (gradient * sum[0]) / n;
              //  var correlation = (n * sum[3] - sum[0] * sum[1]) / Math.sqrt((n * sum[2] - sum[0] * sum[0]) * (n * sum[4] - sum[1] * sum[1]));

                for (var i = 0, len = data.length; i < len; i++) {
                    var coordinate = [data[i][0], data[i][0] * gradient + intercept];
                    results.push(coordinate);
                }

                var string = 'y = ' + Math.round(gradient*100) / 100 + 'x + ' + Math.round(intercept*100) / 100;

                return {equation: [gradient, intercept], points: results, string: string};
            },

            exponential: function(data) {
                var sum = [0, 0, 0, 0, 0, 0], n = 0, results = [];

                for (len = data.length; n < len; n++) {
                  if (data[n][1] != null) {
                    sum[0] += data[n][0];
                    sum[1] += data[n][1];
                    sum[2] += data[n][0] * data[n][0] * data[n][1];
                    sum[3] += data[n][1] * Math.log(data[n][1]);
                    sum[4] += data[n][0] * data[n][1] * Math.log(data[n][1]);
                    sum[5] += data[n][0] * data[n][1];
                  }
                }

                var denominator = (sum[1] * sum[2] - sum[5] * sum[5]);
                var A = Math.pow(Math.E, (sum[2] * sum[3] - sum[5] * sum[4]) / denominator);
                var B = (sum[1] * sum[4] - sum[5] * sum[3]) / denominator;

                for (var i = 0, len = data.length; i < len; i++) {
                    var coordinate = [data[i][0], A * Math.pow(Math.E, B * data[i][0])];
                    results.push(coordinate);
                }

                var string = 'y = ' + Math.round(A*100) / 100 + 'e^(' + Math.round(B*100) / 100 + 'x)';

                return {equation: [A, B], points: results, string: string};
            },

            logarithmic: function(data) {
                var sum = [0, 0, 0, 0], n = 0, results = [];

                for (len = data.length; n < len; n++) {
                  if (data[n][1] != null) {
                    sum[0] += Math.log(data[n][0]);
                    sum[1] += data[n][1] * Math.log(data[n][0]);
                    sum[2] += data[n][1];
                    sum[3] += Math.pow(Math.log(data[n][0]), 2);
                  }
                }

                var B = (n * sum[1] - sum[2] * sum[0]) / (n * sum[3] - sum[0] * sum[0]);
                var A = (sum[2] - B * sum[0]) / n;

                for (var i = 0, len = data.length; i < len; i++) {
                    var coordinate = [data[i][0], A + B * Math.log(data[i][0])];
                    results.push(coordinate);
                }

                var string = 'y = ' + Math.round(A*100) / 100 + ' + ' + Math.round(B*100) / 100 + ' ln(x)';

                return {equation: [A, B], points: results, string: string};
            },

            power: function(data) {
                var sum = [0, 0, 0, 0], n = 0, results = [];

                for (len = data.length; n < len; n++) {
                  if (data[n][1] != null) {
                    sum[0] += Math.log(data[n][0]);
                    sum[1] += Math.log(data[n][1]) * Math.log(data[n][0]);
                    sum[2] += Math.log(data[n][1]);
                    sum[3] += Math.pow(Math.log(data[n][0]), 2);
                  }
                }

                var B = (n * sum[1] - sum[2] * sum[0]) / (n * sum[3] - sum[0] * sum[0]);
                var A = Math.pow(Math.E, (sum[2] - B * sum[0]) / n);

                for (var i = 0, len = data.length; i < len; i++) {
                    var coordinate = [data[i][0], A * Math.pow(data[i][0] , B)];
                    results.push(coordinate);
                }

                 var string = 'y = ' + Math.round(A*100) / 100 + 'x^' + Math.round(B*100) / 100;

                return {equation: [A, B], points: results, string: string};
            },

            polynomial: function(data, order) {
                if(typeof order == 'undefined'){
                    order = 2;
                }
                 var lhs = [], rhs = [], results = [], a = 0, b = 0, i = 0, k = order + 1;

                        for (; i < k; i++) {
                           for (var l = 0, len = data.length; l < len; l++) {
                              if (data[l][1] != null) {
                               a += Math.pow(data[l][0], i) * data[l][1];
                              }
                            }
                            lhs.push(a), a = 0;
                            var c = [];
                            for (var j = 0; j < k; j++) {
                               for (var l = 0, len = data.length; l < len; l++) {
                                  if (data[l][1] != null) {
                                   b += Math.pow(data[l][0], i + j);
                                  }
                                }
                                c.push(b), b = 0;
                            }
                            rhs.push(c);
                        }
                rhs.push(lhs);

               var equation = gaussianElimination(rhs, k);

                    for (var i = 0, len = data.length; i < len; i++) {
                        var answer = 0;
                        for (var w = 0; w < equation.length; w++) {
                            answer += equation[w] * Math.pow(data[i][0], w);
                        }
                        results.push([data[i][0], answer]);
                    }

                    var string = 'y = ';

                    for(var i = equation.length-1; i >= 0; i--){
                      if(i > 1) string += Math.round(equation[i] * Math.pow(10, i)) / Math.pow(10, i)  + 'x^' + i + ' + ';
                      else if (i == 1) string += Math.round(equation[i]*100) / 100 + 'x' + ' + ';
                      else string += Math.round(equation[i]*100) / 100;
                    }

                return {equation: equation, points: results, string: string};
            },

            lastvalue: function(data) {
              var results = [];
              var lastvalue = null;
              for (var i = 0; i < data.length; i++) {
                if (data[i][1]) {
                  lastvalue = data[i][1];
                  results.push([data[i][0], data[i][1]]);
                }
                else {
                  results.push([data[i][0], lastvalue]);
                }
              }

              return {equation: [lastvalue], points: results, string: "" + lastvalue};
            }
        };

var regression = (function(method, data, order) {

       if (typeof method == 'string') {
           return methods[method](data, order);
       }
    });

if (typeof exports !== 'undefined') {
    module.exports = regression;
} else {
    window.regression = regression;
}

}());
<|endoftext|>


<commit_before>// evilService.js
module.exports = function EvilService(dependencies) {
    this.dependencies = dependencies;

    this.random = dependencies.random;

    var data = [
        {
            count: 0,
            friendly_url: "instalar-baidu",
            title: "instalar o BAIDU!",
            img: "https://s3.amazonaws.com/elasticbeanstalk-us-east-1-141499087849/static/baidu.jpg",
            css: {
                background: "303030",
                accent: "F44336",
                accent_dark: "B71C1C"
            }
        },
        {
            count: 42,
            friendly_url: "chamar-taxi-e-uber-ao-mesmo-tempo",
            title: "chamar taxi e Uber ao mesmo tempo!",
            img: "https://s3.amazonaws.com/elasticbeanstalk-us-east-1-141499087849/static/uber.jpg",
            css: {
                background: "303030",
                accent: "F44336",
                accent_dark: "B71C1C"
            }
        },
        {
            count: 87,
            friendly_url: "fazer-while-true-no-codigo",
            title: "fazer WHILE true no código",
            img: "https://s3.amazonaws.com/elasticbeanstalk-us-east-1-141499087849/static/whiletrue.jpg",
            css: {
                background: "303030",
                accent: "F44336",
                accent_dark: "B71C1C"
            }
        },
        {
            count: 9,
            friendly_url: "abrir-o-ie",
            title: "abrir o IE",
            img: "https://s3.amazonaws.com/elasticbeanstalk-us-east-1-141499087849/static/ie8.jpg",
            css: {
                background: "303030",
                accent: "F44336",
                accent_dark: "B71C1C"
            }
        },
        {
            count: 52,
            friendly_url: "escutar-funk-proibidao-no-spotify-no-ultimo-volume",
            title: "escutar funk proibidão no spotify no ultimo volume",
            img: "https://s3.amazonaws.com/elasticbeanstalk-us-east-1-141499087849/static/bondetigrao.jpg",
            css: {
                background: "303030",
                accent: "F44336",
                accent_dark: "B71C1C"
            }
        },
        {
            count: 17,
            friendly_url: "passar-correndo-na-frente-dos-camelos-e-gritar-o-rapa",
            title: "passar correndo na frente dos camelos e gritar OOOh Rapaaaa!",
            img: "http://oglobo.globo.com/fotos/2011/09/15/15_MHG_RIO_camelo.jpg",
            css: {
                background: "303030",
                accent: "F44336",
                accent_dark: "B71C1C"
            }
        },
        {
            count: 0,
            friendly_url: "passar-sorvete-no-arroz",
            title: "passar sorvete no arroz",
            img: "https://i.ytimg.com/vi/H52kepS9tO4/hqdefault.jpg",
            css: {
                background: "303030",
                accent: "F44336",
                accent_dark: "B71C1C"
            }
        },
        {
            count: 12,
            friendly_url: "engordar-para-valer",
            title: "engordar para valer",
            img: "https://i.ytimg.com/vi/H52kepS9tO4/hqdefault.jpg",
            css: {
                background: "303030",
                accent: "F44336",
                accent_dark: "B71C1C"
            }
        },
        {
            count: 2,
            friendly_url: "peidar-na-fila-do-banco-e-sair-correndo",
            title: "peidar na fila do banco e sair correndo",
            img: "http://www.polemicaparaiba.com.br/wp-content/uploads/2015/09/fila-de-banco.jpg",
            css: {
                background: "303030",
                accent: "F44336",
                accent_dark: "B71C1C"
            }
        },
        {
            count: 3,
            friendly_url: "ir-no-mcdonalds-e-pedir-uma-salada",
            title: "ir no McDonalds e pedir uma salada",
            img: "https://venancios.files.wordpress.com/2013/04/gordo.jpg",
            css: {
                background: "303030",
                accent: "F44336",
                accent_dark: "B71C1C"
            }
        },
        {
            count: 1,
            friendly_url: "fazer-um-site-de-maldade",
            title: "fazer um site de maldade",
            img: "https://i.ytimg.com/vi/oR13iPNv9wI/hqdefault.jpg",
            css: {
                background: "303030",
                accent: "0288D1"
            }
        },
        {
            count: 0,
            friendly_url: "colocar-filtro-do-cachorro",
            title: "colocar o filtro do cachorro",
            img: "http://static1.purebreak.com.br/articles/1/30/98/1/@/154968-kendall-jenner-tambem-adora-usar-o-filtr-950x0-1.jpg",
            css: {
                background: "303030",
                accent: "0288D1"
            }
        },
        {
            count: 0,
            friendly_url: "pegar-homem-pegar-mulher",
            title: "pegar homem, pegar mulher! BORAA",
            img: "https://i.ytimg.com/vi/M81ke9svVXo/hqdefault.jpg",
            css: {
                background: "303030",
                accent: "0288D1"
            }
        },
        {
            count: 0,
            friendly_url: "pisar-na-grama",
            title: "pisar na grama",
            img: "http://redeemancipa.org.br/wp-content/uploads/2012/12/n%C3%A3o-pise.jpg",
            css: {
                background: "303030",
                accent: "0288D1"
            }
        }
    ];

    var newEvil = function() {
        var randomInt = random.randomInt(0,data.length);
        return data[randomInt];
    };

    var doEvil = function (friendlyUrl) {
        var evil = findByFriendlyURL(friendlyUrl);
        evil.count = evil.count+1;
    };

    var findByFriendlyURL = function(friendlyUrl) {
        for (var i = 0; i < data.length; i++) {
            var evil = data[i];
            if(evil.friendly_url === friendlyUrl){
                return evil;
            }
        }
        return {};
    };

    return {
        newEvil: newEvil,
        doEvil: doEvil,
        findByFriendlyURL: findByFriendlyURL
    }
};
<commit_msg>dia de maldade<commit_after>// evilService.js
module.exports = function EvilService(dependencies) {
    this.dependencies = dependencies;

    this.random = dependencies.random;

    var data = [
        {
            count: 0,
            friendly_url: "instalar-baidu",
            title: "instalar o BAIDU!",
            img: "https://s3.amazonaws.com/elasticbeanstalk-us-east-1-141499087849/static/baidu.jpg",
            css: {
                background: "303030",
                accent: "F44336",
                accent_dark: "B71C1C"
            }
        },
        {
            count: 42,
            friendly_url: "chamar-taxi-e-uber-ao-mesmo-tempo",
            title: "chamar taxi e Uber ao mesmo tempo!",
            img: "https://s3.amazonaws.com/elasticbeanstalk-us-east-1-141499087849/static/uber.jpg",
            css: {
                background: "303030",
                accent: "F44336",
                accent_dark: "B71C1C"
            }
        },
        {
            count: 87,
            friendly_url: "fazer-while-true-no-codigo",
            title: "fazer WHILE true no código",
            img: "https://s3.amazonaws.com/elasticbeanstalk-us-east-1-141499087849/static/whiletrue.jpg",
            css: {
                background: "303030",
                accent: "F44336",
                accent_dark: "B71C1C"
            }
        },
        {
            count: 9,
            friendly_url: "abrir-o-ie",
            title: "abrir o IE",
            img: "https://s3.amazonaws.com/elasticbeanstalk-us-east-1-141499087849/static/ie8.jpg",
            css: {
                background: "303030",
                accent: "F44336",
                accent_dark: "B71C1C"
            }
        },
        {
            count: 52,
            friendly_url: "escutar-funk-proibidao-no-spotify-no-ultimo-volume",
            title: "escutar funk proibidão no spotify no ultimo volume",
            img: "https://s3.amazonaws.com/elasticbeanstalk-us-east-1-141499087849/static/bondetigrao.jpg",
            css: {
                background: "303030",
                accent: "F44336",
                accent_dark: "B71C1C"
            }
        },
        {
            count: 17,
            friendly_url: "passar-correndo-na-frente-dos-camelos-e-gritar-o-rapa",
            title: "passar correndo na frente dos camelos e gritar OOOh Rapaaaa!",
            img: "http://oglobo.globo.com/fotos/2011/09/15/15_MHG_RIO_camelo.jpg",
            css: {
                background: "303030",
                accent: "F44336",
                accent_dark: "B71C1C"
            }
        },
        {
            count: 0,
            friendly_url: "passar-sorvete-no-arroz",
            title: "passar sorvete no arroz",
            img: "https://i.ytimg.com/vi/H52kepS9tO4/hqdefault.jpg",
            css: {
                background: "303030",
                accent: "F44336",
                accent_dark: "B71C1C"
            }
        },
        {
            count: 12,
            friendly_url: "engordar-para-valer",
            title: "engordar para valer",
            img: "https://i.ytimg.com/vi/H52kepS9tO4/hqdefault.jpg",
            css: {
                background: "303030",
                accent: "F44336",
                accent_dark: "B71C1C"
            }
        },
        {
            count: 2,
            friendly_url: "peidar-na-fila-do-banco-e-sair-correndo",
            title: "peidar na fila do banco e sair correndo",
            img: "http://www.polemicaparaiba.com.br/wp-content/uploads/2015/09/fila-de-banco.jpg",
            css: {
                background: "303030",
                accent: "F44336",
                accent_dark: "B71C1C"
            }
        },
        {
            count: 3,
            friendly_url: "ir-no-mcdonalds-e-pedir-uma-salada",
            title: "ir no McDonalds e pedir uma salada",
            img: "https://venancios.files.wordpress.com/2013/04/gordo.jpg",
            css: {
                background: "303030",
                accent: "F44336",
                accent_dark: "B71C1C"
            }
        },
        {
            count: 1,
            friendly_url: "fazer-um-site-de-maldade",
            title: "fazer um site de maldade",
            img: "https://i.ytimg.com/vi/oR13iPNv9wI/hqdefault.jpg",
            css: {
                background: "303030",
                accent: "0288D1"
            }
        },
        {
            count: 0,
            friendly_url: "colocar-filtro-do-cachorro",
            title: "colocar o filtro do cachorro",
            img: "http://static1.purebreak.com.br/articles/1/30/98/1/@/154968-kendall-jenner-tambem-adora-usar-o-filtr-950x0-1.jpg",
            css: {
                background: "303030",
                accent: "0288D1"
            }
        },
        {
            count: 0,
            friendly_url: "pegar-homem-pegar-mulher",
            title: "pegar homem, pegar mulher! BORAA",
            img: "https://i.ytimg.com/vi/M81ke9svVXo/hqdefault.jpg",
            css: {
                background: "303030",
                accent: "0288D1"
            }
        },
        {
            count: 0,
            friendly_url: "pisar-na-grama",
            title: "pisar na grama",
            img: "http://redeemancipa.org.br/wp-content/uploads/2012/12/n%C3%A3o-pise.jpg",
            css: {
                background: "303030",
                accent: "0288D1"
            }
        }

        {
            count: 0,
            friendly_url: "caps-log-ligado",
            title: "Dia de logar no notebook com o capslog ligado",
            img: "https://i.ytimg.com/vi/M81ke9svVXo/hqdefault.jpg",
            css: {
                background: "303030",
                accent: "0288D1"
            }
        },

        {
            count: 0,
            friendly_url: "visualizar-e-nao-responder",
            title: "Dia de visualizar e nao responder",
            img: "https://i.ytimg.com/vi/M81ke9svVXo/hqdefault.jpg",
            css: {
                background: "303030",
                accent: "0288D1"
            }
        },

        {
            count: 0,
            friendly_url: "link-proprio-video",
            title: "Dia de dar like no próprio video",
            img: "https://i.ytimg.com/vi/M81ke9svVXo/hqdefault.jpg",
            css: {
                background: "303030",
                accent: "0288D1"
            }
        },

        {
            count: 0,
            friendly_url: "curtir-proprio-comentario",
            title: "Dia de curtir o proprio comentário",
            img: "https://i.ytimg.com/vi/M81ke9svVXo/hqdefault.jpg",
            css: {
                background: "303030",
                accent: "0288D1"
            }
        },

        {
            count: 0,
            friendly_url: "nao-respoder-amem",
            title: "Dia de nao responder amém no grupo da famila",
            img: "https://i.ytimg.com/vi/M81ke9svVXo/hqdefault.jpg",
            css: {
                background: "303030",
                accent: "0288D1"
            }
        },

        {
            count: 0,
            friendly_url: "video-gemido",
            title: "Dia de mandar video de gemido para avó na fila do banco",
            img: "https://i.ytimg.com/vi/M81ke9svVXo/hqdefault.jpg",
            css: {
                background: "303030",
                accent: "0288D1"
            }
        },

        {
            count: 0,
            friendly_url: "whatsapap-pago",
            title: "Dia de espalhar que o whatsapp será pago",
            img: "https://i.ytimg.com/vi/M81ke9svVXo/hqdefault.jpg",
            css: {
                background: "303030",
                accent: "0288D1"
            }
        },

        {
            count: 0,
            friendly_url: "tinder-baranga",
            title: "Dia de dar superlike de baranga no Tinter",
            img: "https://i.ytimg.com/vi/M81ke9svVXo/hqdefault.jpg",
            css: {
                background: "303030",
                accent: "0288D1"
            }
        },

        {
            count: 0,
            friendly_url: "indireta-wifi",
            title: "Dia de mandar indireta para o vizinho com o nome da rede wifi",
            img: "https://i.ytimg.com/vi/M81ke9svVXo/hqdefault.jpg",
            css: {
                background: "303030",
                accent: "0288D1"
            }
        },

        {
            count: 0,
            friendly_url: "vida-candcrush",
            title: "Dia de pedir vida no candcrush",
            img: "https://i.ytimg.com/vi/M81ke9svVXo/hqdefault.jpg",
            css: {
                background: "303030",
                accent: "0288D1"
            }
        },

        {
            count: 0,
            friendly_url: "fonte-notepad",
            title: "Dia de alterar o fonte no notepad",
            img: "https://i.ytimg.com/vi/M81ke9svVXo/hqdefault.jpg",
            css: {
                background: "303030",
                accent: "0288D1"
            }
        },

        {
            count: 0,
            friendly_url: "debugar-producao",
            title: "Dia de debugar na produção",
            img: "https://i.ytimg.com/vi/M81ke9svVXo/hqdefault.jpg",
            css: {
                background: "303030",
                accent: "0288D1"
            }
        },

        {
            count: 0,
            friendly_url: "so-nao-homologado",
            title: "Dia de fechar o chamado no ultimo dia do SLA e falar que  o SO não é homologado",
            img: "https://i.ytimg.com/vi/M81ke9svVXo/hqdefault.jpg",
            css: {
                background: "303030",
                accent: "0288D1"
            }
        },

    ];

    var newEvil = function() {
        var randomInt = random.randomInt(0,data.length);
        return data[randomInt];
    };

    var doEvil = function (friendlyUrl) {
        var evil = findByFriendlyURL(friendlyUrl);
        evil.count = evil.count+1;
    };

    var findByFriendlyURL = function(friendlyUrl) {
        for (var i = 0; i < data.length; i++) {
            var evil = data[i];
            if(evil.friendly_url === friendlyUrl){
                return evil;
            }
        }
        return {};
    };

    return {
        newEvil: newEvil,
        doEvil: doEvil,
        findByFriendlyURL: findByFriendlyURL
    }
};
<|endoftext|>


<commit_before>import qs from 'qs'
import { superRequest, superfetch } from '../helpers/super'
import { convertFilters } from '../helpers/manageFilters'

export function fetchMetrics(catalogId) {
  if (!catalogId) return Promise.reject(new Error('catalogId is required'))
  return superfetch(`https://inspire.data.gouv.fr/api/geogw/catalogs/${catalogId}/metrics`)
}

export function fetchCatalog(catalogId) {
  if (!catalogId) return Promise.reject(new Error('catalogId is required'))
  return  superfetch(`https://inspire.data.gouv.fr/api/geogw/catalogs/${catalogId}`)
}

export function fetchCatalogs() {
  return superfetch('https://inspire.data.gouv.fr/api/geogw/catalogs')
}

export function fetchHarvest(catalogId, harvestId) {
  if (!catalogId) return Promise.reject(new Error('catalogId is required'))
  if (!harvestId) return Promise.reject(new Error('harvestId is required'))
  return superfetch(`https://inspire.data.gouv.fr/api/geogw/services/${catalogId}/synchronizations/${harvestId}`)
}

export function fetchHarvests(catalogId) {
  if (!catalogId) return Promise.reject(new Error('catalogId is required'))
  return superfetch(`https://inspire.data.gouv.fr/api/geogw/services/${catalogId}/synchronizations`)
}

export function fetchGlobalMetrics() {
  return superfetch('https://inspire.data.gouv.fr/dgv/api/datasets/metrics')
}

export function fetchDataset(datasetId) {
  if (!datasetId) return Promise.reject(new Error('datasetId is required'))
  return superfetch(`https://inspire.data.gouv.fr/api/geogw/records/${datasetId}`)
}

export function getProducers() {
  return superfetch('https://inspire.data.gouv.fr/dgv/api/producers')
}

export function fetchGeoJSON(link) {
  if (!link) return Promise.reject(new Error('link is required'))
  return superfetch(link + '?format=GeoJSON&projection=WGS84')
}

export function buildSearchQuery(q, filters, page) {
  const qsFilters = convertFilters(filters)
  const query = qs.stringify({q, page, ...qsFilters}, { indices: false })

  return query
}

export function search(q, filters, offset) {
  const qsFilters = convertFilters(filters)
  const query = qs.stringify({q, offset, ...qsFilters}, { indices: false })

  return superfetch('https://inspire.data.gouv.fr/api/geogw/records?' + query)
}

export function getUser() {
  return superfetch('https://inspire.data.gouv.fr/dgv/api/me', { credentials: 'include', mode: 'cors' })
}

export function getOrganization(organizationId) {
  if (!organizationId) return Promise.reject(new Error('organizationId is required'))
  return superfetch(`https://inspire.data.gouv.fr/dgv/api/organizations/${organizationId}`)
}

export function getOrganizationDetail(organizationId) {
  if (!organizationId) return Promise.reject(new Error('organizationId is required'))
  return superfetch(`https://www.data.gouv.fr/api/1/organizations/${organizationId}/`)
}

export function fetchOrganizationMetrics(organizationId) {
  if (!organizationId) return Promise.reject(new Error('organizationId is required'))
  return superfetch(`https://inspire.data.gouv.fr/dgv/api/organizations/${organizationId}/datasets/metrics`)
}

export function fetchOrganizationPublished(organizationId) {
  if (!organizationId) return Promise.reject(new Error('organizationId is required'))
  return superfetch(`https://inspire.data.gouv.fr/dgv/api/organizations/${organizationId}/datasets/published`)
}

export function fetchOrganizationNotPublishedYet(organizationId) {
  if (!organizationId) return Promise.reject(new Error('organizationId is required'))
  return superfetch(`https://inspire.data.gouv.fr/dgv/api/organizations/${organizationId}/datasets/not-published-yet`)
}

export function fetchOrganizationPublishedByOthers(organizationId) {
  if (!organizationId) return Promise.reject(new Error('organizationId is required'))
  return superfetch(`https://inspire.data.gouv.fr/dgv/api/organizations/${organizationId}/datasets/published-by-others`)
}

export function publishDataset(datasetId, organizationId) {
  if (!datasetId || !organizationId) return Promise.reject(new Error('datasetId and organizationId are required'))
  const url = `https://inspire.data.gouv.fr/dgv/api/datasets/${datasetId}/publication`

  return superRequest(url, 'PUT', { organization: organizationId })
}

export function updateCatalogSources(sourceCatalogs, organizationId) {
  if (!sourceCatalogs || !organizationId) return Promise.reject(new Error('sourceCatalogs and organizationId are required'))
  const url = `https://inspire.data.gouv.fr/dgv/api/organizations/${organizationId}`
  const params = {
    sourceCatalogs: sourceCatalogs,
    publishAll: true,
  }

  return superRequest(url, 'PUT', params)
}

export function syncCatalog(catalogId) {
  if (!catalogId) return Promise.reject(new Error('catalogId is required'))
  return superRequest(`https://inspire.data.gouv.fr/api/geogw/services/${catalogId}/sync`, 'POST')
}
<commit_msg>Add associate and dissociate producer fetch<commit_after>import qs from 'qs'
import { superRequest, superfetch } from '../helpers/super'
import { convertFilters } from '../helpers/manageFilters'

export function fetchMetrics(catalogId) {
  if (!catalogId) return Promise.reject(new Error('catalogId is required'))
  return superfetch(`https://inspire.data.gouv.fr/api/geogw/catalogs/${catalogId}/metrics`)
}

export function fetchCatalog(catalogId) {
  if (!catalogId) return Promise.reject(new Error('catalogId is required'))
  return  superfetch(`https://inspire.data.gouv.fr/api/geogw/catalogs/${catalogId}`)
}

export function fetchCatalogs() {
  return superfetch('https://inspire.data.gouv.fr/api/geogw/catalogs')
}

export function fetchHarvest(catalogId, harvestId) {
  if (!catalogId) return Promise.reject(new Error('catalogId is required'))
  if (!harvestId) return Promise.reject(new Error('harvestId is required'))
  return superfetch(`https://inspire.data.gouv.fr/api/geogw/services/${catalogId}/synchronizations/${harvestId}`)
}

export function fetchHarvests(catalogId) {
  if (!catalogId) return Promise.reject(new Error('catalogId is required'))
  return superfetch(`https://inspire.data.gouv.fr/api/geogw/services/${catalogId}/synchronizations`)
}

export function fetchGlobalMetrics() {
  return superfetch('https://inspire.data.gouv.fr/dgv/api/datasets/metrics')
}

export function fetchDataset(datasetId) {
  if (!datasetId) return Promise.reject(new Error('datasetId is required'))
  return superfetch(`https://inspire.data.gouv.fr/api/geogw/records/${datasetId}`)
}

export function getProducers() {
  return superfetch('https://inspire.data.gouv.fr/dgv/api/producers')
}

export function fetchGeoJSON(link) {
  if (!link) return Promise.reject(new Error('link is required'))
  return superfetch(link + '?format=GeoJSON&projection=WGS84')
}

export function buildSearchQuery(q, filters, page) {
  const qsFilters = convertFilters(filters)
  const query = qs.stringify({q, page, ...qsFilters}, { indices: false })

  return query
}

export function search(q, filters, offset) {
  const qsFilters = convertFilters(filters)
  const query = qs.stringify({q, offset, ...qsFilters}, { indices: false })

  return superfetch('https://inspire.data.gouv.fr/api/geogw/records?' + query)
}

export function getUser() {
  return superfetch('https://inspire.data.gouv.fr/dgv/api/me', { credentials: 'include', mode: 'cors' })
}

export function getOrganization(organizationId) {
  if (!organizationId) return Promise.reject(new Error('organizationId is required'))
  return superfetch(`https://inspire.data.gouv.fr/dgv/api/organizations/${organizationId}`)
}

export function getOrganizationDetail(organizationId) {
  if (!organizationId) return Promise.reject(new Error('organizationId is required'))
  return superfetch(`https://www.data.gouv.fr/api/1/organizations/${organizationId}/`)
}

export function fetchOrganizationMetrics(organizationId) {
  if (!organizationId) return Promise.reject(new Error('organizationId is required'))
  return superfetch(`https://inspire.data.gouv.fr/dgv/api/organizations/${organizationId}/datasets/metrics`)
}

export function fetchOrganizationPublished(organizationId) {
  if (!organizationId) return Promise.reject(new Error('organizationId is required'))
  return superfetch(`https://inspire.data.gouv.fr/dgv/api/organizations/${organizationId}/datasets/published`)
}

export function fetchOrganizationNotPublishedYet(organizationId) {
  if (!organizationId) return Promise.reject(new Error('organizationId is required'))
  return superfetch(`https://inspire.data.gouv.fr/dgv/api/organizations/${organizationId}/datasets/not-published-yet`)
}

export function fetchOrganizationPublishedByOthers(organizationId) {
  if (!organizationId) return Promise.reject(new Error('organizationId is required'))
  return superfetch(`https://inspire.data.gouv.fr/dgv/api/organizations/${organizationId}/datasets/published-by-others`)
}

export function publishDataset(datasetId, organizationId) {
  if (!datasetId || !organizationId) return Promise.reject(new Error('datasetId and organizationId are required'))
  const url = `https://inspire.data.gouv.fr/dgv/api/datasets/${datasetId}/publication`

  return superRequest(url, 'PUT', { organization: organizationId })
}

export function updateCatalogSources(sourceCatalogs, organizationId) {
  if (!sourceCatalogs || !organizationId) return Promise.reject(new Error('sourceCatalogs and organizationId are required'))
  const url = `https://inspire.data.gouv.fr/dgv/api/organizations/${organizationId}`
  const params = {
    sourceCatalogs: sourceCatalogs,
    publishAll: true,
  }

  return superRequest(url, 'PUT', params)
}

export function syncCatalog(catalogId) {
  if (!catalogId) return Promise.reject(new Error('catalogId is required'))
  return superRequest(`https://inspire.data.gouv.fr/api/geogw/services/${catalogId}/sync`, 'POST')
}

export function dissociateProducer(producerId, organizationId) {
  if (!producerId && organizationId) return Promise.reject(new Error('producerId and organizationId is required'))
  const url = `https://inspire.data.gouv.fr/dgv/api/organizations/${organizationId}/producers/${producerId}`

  return superRequest(url, 'DELETE')
}

export function associateProducer(producerId, organizationId) {
  if (!producerId && organizationId) return Promise.reject(new Error('producerId and organizationId is required'))
  const url = `https://inspire.data.gouv.fr/dgv/api/organizations/${organizationId}/producers`
  const params = { '_id': producerId, 'associatedTo': organizationId }

  return superRequest(url, 'POST', params)
}
<|endoftext|>


<commit_before>var Benchmark = require('benchmark');
var suite = new Benchmark.Suite();
var assert = require('assert');
var coalesceZooms = require('../lib/pure/coalescezooms'),
    args = require('./fixtures/coalesce.json'),
    result = require('./fixtures/coalesce-result.json');

suite.add('coalescezooms 1', function() {
    // @TODO worst case scenario this data
    coalesceZooms.one(args[0], args[1], args[2], args[3], args[4]);
}).add('coalescezooms 2', function() {
    // @TODO worst case scenario this data
    coalesceZooms.two(args[0], args[1], args[2], args[3], args[4]);
})
.on('cycle', function(event) {
  console.log(String(event.target));
})
.run();
<commit_msg>Fix coalescezooms bench.<commit_after>var Benchmark = require('benchmark');
var suite = new Benchmark.Suite();
var assert = require('assert');
var coalesceZooms = require('../lib/pure/coalescezooms'),
    args = require('./fixtures/coalesce.json'),
    result = require('./fixtures/coalesce-result.json');

suite.add('coalescezooms 1', function() {
    // @TODO worst case scenario this data
    coalesceZooms(args[0], args[1], args[2], args[3], args[4]);
}).add('coalescezooms 2', function() {
    // @TODO worst case scenario this data
    coalesceZooms(args[0], args[1], args[2], args[3], args[4]);
})
.on('cycle', function(event) {
  console.log(String(event.target));
})
.run();
<|endoftext|>


<commit_before>"use strict";

var path = require("path");
var fs = require("fs");
var _ = require("lodash");
var util = require("gulp-util");
var globule = require("globule");

var getTokens = function(string) {
    return _.compact(string.split(/[.-]/));
};

/**
 * Process a file base name to extract from it every tokens
 * matching one of the filtering tokens defined in the dimensions
 * @returns {Array of string} List of the tokens that hav been found within the dimensions
 */
var getFilteredTokens = function(string, dimensions, isFile) {
    var tokens = getTokens(string);

    // Remove the first token which corresponds to the root of the string (the first token can never be a token)
    tokens.shift();

    if (isFile) {
        // remove the last token which corresponds to the extension
        tokens.pop();
    }

    // remove unknown tokens from the list
    return _.intersection(tokens, _.flattenDeep(dimensions));
};

/**
 * Return the token of a file name that doesn't mathc any dimensional token
 * @param   {String} string   base name of the file
 * @param   {Array of Array of String dimensions   list of dimensions
 * @returns {Array of String} base name tokens
 */
var getBaseTokens = function(string, dimensions, isFile) {
    var allTokens = getTokens(string),
        filteredTokens = getFilteredTokens(string, dimensions, isFile);

    return _.difference(allTokens, filteredTokens);
};

/**
 * Determine if the given file is a root file or a derivation of a root file
 * which should be filtered according to the defined dimensions
 *
 * @param   {String} fileBaseName base name of a file
 * @param   {Array of Array of string}
 * @returns {Boolean} true if the file contains one more tokens defined within the dimensions
 */
var isFileDerivation = function(fileBaseName, dimensions) {
    var t = getFilteredTokens(fileBaseName, dimensions, true);
    return !!t.length;
};

var computeScore = function(tokens, dimensions) {
    var rst = 0;

    for (var t of tokens) {
        for (var i = 0, l = dimensions.length; i < l; i++) {
            if (dimensions[i].indexOf(t) >= 0) {
                rst = rst | 1 << l-i;
            }
        }
    }

    return rst;
};

/**
 * Check if the fileName is derived from the fileBaseName
 * according tot the dimensions that have been defined
 *
 * Examples :
 *
 * case 1
 * dimensions = [[android, ios]]
 * fileName = "test-android.js"    =>  true : fileName is derived from fileBaseName
 * fileBaseName = "test.js"
 *
 * case 2
 * dimensions = [[android, ios]]
 * fileName = "test-android-backup.js" => false : the two files have the same root but the fileName has an extra token,
 * fileBaseName = "test.js                not corresponding to any dimensions which means the 2 files have nothing in common.
 *
 * @param   {String} fileName          base name of the file to test
 * @param   {String} fileBaseName      base name of the file used as a reference
 * @param   {Array of Array of String} dimensions   list of the dimensions
 * @returns {Array of String} list of the dimensionals tokens found in the fileName if derived from fileBaseName, false otherwize
 */
var isDerivedFrom = function(string, baseString, dimensions, isFile) {
    var allTokens = getTokens(string),
        filteredTokens = getFilteredTokens(string, dimensions, isFile),
        diff = _.difference(allTokens, filteredTokens);

    var baseDiff = getBaseTokens(baseString, dimensions, isFile);

    return _.intersection(diff, baseDiff).length === baseDiff.length && filteredTokens || [];
};

/**
 * Get the real name without tokens for a file name.
 * @param {String}                     fileName   file name
 * @param {Array of array of string}   dimensions tokens defining every dimension
 */
var getFileNameBaseFrom = function(fileName, dimensions) {
    var baseTokens = getBaseTokens(fileName, dimensions, true);

    return baseTokens.join("-").replace(/-([^-]+)$/, ".$1"); // Replace the last "-" by "."
};

/**
 * Check if the intersection between tokens and filtering tokens is a perfect match
 * @param   {Array of String} tokens          tokens to analyze with the current filtering tokens
 * @param   {Array of String} filteringTokens tokens use to filter
 * @returns {Array of String} return the intersection if it's a perfect match
 */
var isPerfectMatch = function(tokens, filteringTokens) {
    var rst = _.intersection(tokens, filteringTokens);

    if (rst.length !== tokens.length || !rst.length) { // It's not a perfect match
        rst = null;
    }

    return rst;
};

/**
 * Check the given path is a derived path or not (according to the dimensions that have been defined)
 *
 * Example :
 * Let's say the dimensions are a simple array: [sony, ios]
 * /common/default/myFile.txt => true
 * /common/sony/myFiles.txt => false
 * /ios/myFiles.txt => false
 *
 * @returns true if the path is not a derived path (no dimensions tokens can be found in it)
 */
var isPlainPath = function(dir, baseDir, dimensions) {
    var derivedFolders = path.relative(baseDir, dir)
        .split("/")
        .filter(function(folderName) {
            var t = getFilteredTokens(folderName, dimensions);
            return t && t.length;
        });

    return !derivedFolders.length;
};

/**
 * For a given path, check if a derived path can match and return it if so.
 *
 * For example :
 * - dir = /home/user/myUser/myProject/myFolder/mySubFolder/myFile.txt
 * - baseDir = /home/user/myUser/myProject
 * - dimensions = [[dev, prod],[ios, android]]
 *
 * your project contains the following tree:
 * myProject
 *    |__myFolder
 *         |__ mySubFolder
 *                 |__ myFile.txt
 *         |__ mySubFolder-dev-android
 *                 |__ myFile.txt
 *    |__prod
 *         |__ mySubFolder
 *                 |__ myFile.txt
 *
 * If you run the following method with :
 *
 * - filteringTokens = [dev, android] => the return path will be /home/user/myUser/myProject/myFolder/mySubfolder-dev-android/myFile.txt
 * - filteringTokens = [prod] => the return path will be /home/user/myUser/myProject/prod/mySubFolder/myFile.txt
 *
 * @param   {String} dir             the directory for which to look for alternatives
 * @param   {String} baseDir         the base directory from which start to look for alternatives
 * @param   {String} fileBaseName    file base name of the path
 * @param   {Array of Array of String} dimensions      the dimensions of the project
 * @param   {Array of String} filteringTokens the dimensions token we're currently filtering with
 * @returns {String} The derived path if one has been found, the given dir otherwize
 */
var getBestDirPath = function(dir, baseDir, fileBaseName, dimensions, filteringTokens) {
    var relativePath = path.relative(baseDir, dir);
    var dirTokens = relativePath.split("/");

    for (var i = 0, l = dirTokens.length; i < l; i++) {
        var t = dirTokens[i];
        if (t && t !== "..") {

            // let's read each folder level and check if we can find a derivation

            var readPath = path.join.apply(path, [baseDir].concat(dirTokens.slice(0, i))); // first time : path.join(baseDir, dirTokens[0]),
                                                                                // then : path.join(baseDir, dirTokens[0], dirTokens[1]),...
                                                                                // => go through all the dir hierarchy

            var bestScore = 0,
                candidates = fs.readdirSync(readPath);

            // for each level, check if there are some matching derived paths and and if so, find the best one

            for (var item of candidates) {
                var p = path.join(readPath, item);
                if (fs.statSync(p).isDirectory()) { // process only directories

                    var baseTokens = getBaseTokens(item, dimensions),
                        filteredTokens = !baseTokens.length && getFilteredTokens(item, dimensions) || isDerivedFrom(item, t, dimensions);

                    var perfectMatchTokens = isPerfectMatch(filteredTokens, filteringTokens);
                    if (perfectMatchTokens) {
                        var score = computeScore(perfectMatchTokens, dimensions);
                        var doesFileExist = globule.find({
                            srcBase: path.join.apply(path, [p].concat(dirTokens.slice(i + 1, l))),
                            src: getFileNameBaseFrom(fileBaseName, dimensions)
                        }).length;

                        if (score > bestScore && doesFileExist) {
                            bestScore = score;
                            dirTokens[i] = item;
                        }
                    }
                }
            }
        }
    }

    var rst = path.join.apply(path, [baseDir].concat(dirTokens));

    if (path.relative(rst, dir)) {
        console.log(">>> Substituting dir path from ", relativePath, "to", path.relative(baseDir, rst));
    }

    return rst;
};

/**
 * Try to find the best matching candidate associated to a file in the same directory of that file
 * according to the given filtering tokens.
 * @param   {String} dir   Directory in which we should search for a derived file
 * @param   {String} baseDir base directory as defined by gulp.src (see https://github.com/gulpjs/gulp/blob/master/docs/API.md, options.base)
 * @param   {String} fileBaseName   file name we should use as a base to look for derived file
 * @param   {Array of array of string}   dimensions tokens defining every dimension
 * @param   {Array of strings}   tokens on which is processed the filtering
 * @returns {String or null} String if a candidate has been found, null
 */
var find = function(dir, baseDir, fileBaseName, dimensions, filteringTokens, filterDir) {
    var rst;

    // First, let's analyze the dir path and filter out derived path :
    // we only deal with non derived path, figuring out later on if we should replace them with some matching derived path

    if (isPlainPath(dir, baseDir, dimensions)) {

        // Let's check now if a derived dir path holding a file which has the same root name has the fileBaseName
        // can match the filtering tokens

        var dirPath = dir;
        if (filterDir) {
            dirPath = getBestDirPath(dir, baseDir, fileBaseName, dimensions, filteringTokens);
        }

        rst = path.join(dirPath, fileBaseName);

        // Retrieve potential candidates within the dir

        var candidates = fs.readdirSync(dirPath).filter(function(item) {
            return getFileNameBaseFrom(item, dimensions) === fileBaseName;
        });

        var bestScore = 0;
        for (var fileName of candidates) {

            var tokens = isDerivedFrom(fileName, fileBaseName, dimensions, true);

            // Check if the intersection is a perfect match and retrieve the matching tokens if so
            var perfectMatchTokens = isPerfectMatch(tokens, filteringTokens);
            if (perfectMatchTokens) {
                var score = computeScore(perfectMatchTokens, dimensions);
                if (score > bestScore) {
                    bestScore = score;
                    rst = path.join(dirPath, fileName);
                }
            }
        }

        if (bestScore) {
            console.log(">>> Substituting", fileBaseName, "with", path.basename(rst));
        }
    }

    return rst;
};

var getConf = function(dimensions) {
    var envOptions = _.compact(_.keys(util.env));
    return _.intersection(envOptions, _.flattenDeep(dimensions));
};

module.exports = {
    getTokens: getTokens,
    getFilteredTokens: getFilteredTokens,
    getBaseTokens: getBaseTokens,
    isFileDerivation: isFileDerivation,
    isDerivedFrom: isDerivedFrom,
    getFileNameBaseFrom: getFileNameBaseFrom,
    find: find,
    getConf: getConf
};
<commit_msg>[Filtering] - Removing filtering on directory containing only tokens<commit_after>"use strict";

var path = require("path");
var fs = require("fs");
var _ = require("lodash");
var util = require("gulp-util");
var globule = require("globule");

var getTokens = function(string) {
    return _.compact(string.split(/[.-]/));
};

/**
 * Process a file base name to extract from it every tokens
 * matching one of the filtering tokens defined in the dimensions
 * @returns {Array of string} List of the tokens that hav been found within the dimensions
 */
var getFilteredTokens = function(string, dimensions, isFile) {
    var tokens = getTokens(string);

    // Remove the first token which corresponds to the root of the string (the first token can never be a token)
    tokens.shift();

    if (isFile) {
        // remove the last token which corresponds to the extension
        tokens.pop();
    }

    // remove unknown tokens from the list
    return _.intersection(tokens, _.flattenDeep(dimensions));
};

/**
 * Return the token of a file name that doesn't mathc any dimensional token
 * @param   {String} string   base name of the file
 * @param   {Array of Array of String dimensions   list of dimensions
 * @returns {Array of String} base name tokens
 */
var getBaseTokens = function(string, dimensions, isFile) {
    var allTokens = getTokens(string),
        filteredTokens = getFilteredTokens(string, dimensions, isFile);

    return _.difference(allTokens, filteredTokens);
};

/**
 * Determine if the given file is a root file or a derivation of a root file
 * which should be filtered according to the defined dimensions
 *
 * @param   {String} fileBaseName base name of a file
 * @param   {Array of Array of string}
 * @returns {Boolean} true if the file contains one more tokens defined within the dimensions
 */
var isFileDerivation = function(fileBaseName, dimensions) {
    var t = getFilteredTokens(fileBaseName, dimensions, true);
    return !!t.length;
};

var computeScore = function(tokens, dimensions) {
    var rst = 0;

    for (var t of tokens) {
        for (var i = 0, l = dimensions.length; i < l; i++) {
            if (dimensions[i].indexOf(t) >= 0) {
                rst = rst | 1 << l-i;
            }
        }
    }

    return rst;
};

/**
 * Check if the fileName is derived from the fileBaseName
 * according tot the dimensions that have been defined
 *
 * Examples :
 *
 * case 1
 * dimensions = [[android, ios]]
 * fileName = "test-android.js"    =>  true : fileName is derived from fileBaseName
 * fileBaseName = "test.js"
 *
 * case 2
 * dimensions = [[android, ios]]
 * fileName = "test-android-backup.js" => false : the two files have the same root but the fileName has an extra token,
 * fileBaseName = "test.js                not corresponding to any dimensions which means the 2 files have nothing in common.
 *
 * @param   {String} fileName          base name of the file to test
 * @param   {String} fileBaseName      base name of the file used as a reference
 * @param   {Array of Array of String} dimensions   list of the dimensions
 * @returns {Array of String} list of the dimensionals tokens found in the fileName if derived from fileBaseName, false otherwize
 */
var isDerivedFrom = function(string, baseString, dimensions, isFile) {
    var allTokens = getTokens(string),
        filteredTokens = getFilteredTokens(string, dimensions, isFile),
        diff = _.difference(allTokens, filteredTokens);

    var baseDiff = getBaseTokens(baseString, dimensions, isFile);

    return _.intersection(diff, baseDiff).length === baseDiff.length && filteredTokens || [];
};

/**
 * Get the real name without tokens for a file name.
 * @param {String}                     fileName   file name
 * @param {Array of array of string}   dimensions tokens defining every dimension
 */
var getFileNameBaseFrom = function(fileName, dimensions) {
    var baseTokens = getBaseTokens(fileName, dimensions, true);

    return baseTokens.join("-").replace(/-([^-]+)$/, ".$1"); // Replace the last "-" by "."
};

/**
 * Check if the intersection between tokens and filtering tokens is a perfect match
 * @param   {Array of String} tokens          tokens to analyze with the current filtering tokens
 * @param   {Array of String} filteringTokens tokens use to filter
 * @returns {Array of String} return the intersection if it's a perfect match
 */
var isPerfectMatch = function(tokens, filteringTokens) {
    var rst = _.intersection(tokens, filteringTokens);

    if (rst.length !== tokens.length || !rst.length) { // It's not a perfect match
        rst = null;
    }

    return rst;
};

/**
 * Check the given path is a derived path or not (according to the dimensions that have been defined)
 *
 * Example :
 * Let's say the dimensions are a simple array: [sony, ios]
 * /common/default/myFile.txt => true
 * /common/sony/myFiles.txt => false
 * /ios/myFiles.txt => false
 *
 * @returns true if the path is not a derived path (no dimensions tokens can be found in it)
 */
var isPlainPath = function(dir, baseDir, dimensions) {
    var derivedFolders = path.relative(baseDir, dir)
        .split("/")
        .filter(function(folderName) {
            var t = getFilteredTokens(folderName, dimensions);
            return t && t.length;
        });

    return !derivedFolders.length;
};

/**
 * For a given path, check if a derived path can match and return it if so.
 *
 * For example :
 * - dir = /home/user/myUser/myProject/myFolder/mySubFolder/myFile.txt
 * - baseDir = /home/user/myUser/myProject
 * - dimensions = [[dev, prod],[ios, android]]
 *
 * your project contains the following tree:
 * myProject
 *    |__myFolder
 *         |__ mySubFolder
 *                 |__ myFile.txt
 *         |__ mySubFolder-dev-android
 *                 |__ myFile.txt
 *
 * If you run the following method with :
 *
 * - filteringTokens = [dev, android] => the return path will be /home/user/myUser/myProject/myFolder/mySubfolder-dev-android/myFile.txt
 *
 * @param   {String} dir             the directory for which to look for alternatives
 * @param   {String} baseDir         the base directory from which start to look for alternatives
 * @param   {String} fileBaseName    file base name of the path
 * @param   {Array of Array of String} dimensions      the dimensions of the project
 * @param   {Array of String} filteringTokens the dimensions token we're currently filtering with
 * @returns {String} The derived path if one has been found, the given dir otherwize
 */
var getBestDirPath = function(dir, baseDir, fileBaseName, dimensions, filteringTokens) {
    var relativePath = path.relative(baseDir, dir);
    var dirTokens = relativePath.split("/");

    for (var i = 0, l = dirTokens.length; i < l; i++) {
        var t = dirTokens[i];
        if (t && t !== "..") {

            // let's read each folder level and check if we can find a derivation

            var readPath = path.join.apply(path, [baseDir].concat(dirTokens.slice(0, i))); // first time : path.join(baseDir, dirTokens[0]),
                                                                                // then : path.join(baseDir, dirTokens[0], dirTokens[1]),...
                                                                                // => go through all the dir hierarchy

            var bestScore = 0,
                candidates = fs.readdirSync(readPath);

            // for each level, check if there are some matching derived paths and and if so, find the best one

            for (var item of candidates) {
                var p = path.join(readPath, item);
                if (fs.statSync(p).isDirectory()) { // process only directories

                    var filteredTokens = isDerivedFrom(item, t, dimensions);

                    var perfectMatchTokens = isPerfectMatch(filteredTokens, filteringTokens);
                    if (perfectMatchTokens) {
                        var score = computeScore(perfectMatchTokens, dimensions);
                        var doesFileExist = globule.find({
                            srcBase: path.join.apply(path, [p].concat(dirTokens.slice(i + 1, l))),
                            src: getFileNameBaseFrom(fileBaseName, dimensions)
                        }).length;

                        if (score > bestScore && doesFileExist) {
                            bestScore = score;
                            dirTokens[i] = item;
                        }
                    }
                }
            }
        }
    }

    var rst = path.join.apply(path, [baseDir].concat(dirTokens));

    if (path.relative(rst, dir)) {
        console.log(">>> Substituting dir path from ", relativePath, "to", path.relative(baseDir, rst));
    }

    return rst;
};

/**
 * Try to find the best matching candidate associated to a file in the same directory of that file
 * according to the given filtering tokens.
 * @param   {String} dir   Directory in which we should search for a derived file
 * @param   {String} baseDir base directory as defined by gulp.src (see https://github.com/gulpjs/gulp/blob/master/docs/API.md, options.base)
 * @param   {String} fileBaseName   file name we should use as a base to look for derived file
 * @param   {Array of array of string}   dimensions tokens defining every dimension
 * @param   {Array of strings}   tokens on which is processed the filtering
 * @returns {String or null} String if a candidate has been found, null
 */
var find = function(dir, baseDir, fileBaseName, dimensions, filteringTokens, filterDir) {
    var rst;

    // First, let's analyze the dir path and filter out derived path :
    // we only deal with non derived path, figuring out later on if we should replace them with some matching derived path

    if (isPlainPath(dir, baseDir, dimensions)) {

        // Let's check now if a derived dir path holding a file which has the same root name has the fileBaseName
        // can match the filtering tokens

        var dirPath = dir;
        if (filterDir) {
            dirPath = getBestDirPath(dir, baseDir, fileBaseName, dimensions, filteringTokens);
        }

        rst = path.join(dirPath, fileBaseName);

        // Retrieve potential candidates within the dir

        var candidates = fs.readdirSync(dirPath).filter(function(item) {
            return getFileNameBaseFrom(item, dimensions) === fileBaseName;
        });

        var bestScore = 0;
        for (var fileName of candidates) {

            var tokens = isDerivedFrom(fileName, fileBaseName, dimensions, true);

            // Check if the intersection is a perfect match and retrieve the matching tokens if so
            var perfectMatchTokens = isPerfectMatch(tokens, filteringTokens);
            if (perfectMatchTokens) {
                var score = computeScore(perfectMatchTokens, dimensions);
                if (score > bestScore) {
                    bestScore = score;
                    rst = path.join(dirPath, fileName);
                }
            }
        }

        if (bestScore) {
            console.log(">>> Substituting", fileBaseName, "with", path.basename(rst));
        }
    }

    return rst;
};

var getConf = function(dimensions) {
    var envOptions = _.compact(_.keys(util.env));
    return _.intersection(envOptions, _.flattenDeep(dimensions));
};

module.exports = {
    getTokens: getTokens,
    getFilteredTokens: getFilteredTokens,
    getBaseTokens: getBaseTokens,
    isFileDerivation: isFileDerivation,
    isDerivedFrom: isDerivedFrom,
    getFileNameBaseFrom: getFileNameBaseFrom,
    find: find,
    getConf: getConf
};
<|endoftext|>


<commit_before>import React, { useEffect } from 'react'
import PropTypes from 'prop-types'
import { connect, useSelector } from 'react-redux'

import { signIn, signUp } from './duck'
import { config } from '../../index'
import SignUpForm from './tabs/SignUpForm'
import SignInForm from './tabs/SignInForm'
import i18n from '../../i18n'
import { history, MAP } from '../../AppRouter'

const UserOnboarding = ({ signUp = false, onSignInSubmit, onSignUpSubmit }) => {
  const SignUp = () => <SignUpForm onSubmit={onSignUpSubmit} />
  const SignIn = () => <SignInForm onSubmit={onSignInSubmit} />

  const loggedIn = useSelector((state) => state.user.loggedIn)

  const fromLocation =
    history.location.state &&
    history.location.state.from &&
    history.location.state.from.pathname

  useEffect(() => {
    if (loggedIn) {
      history.push(fromLocation || MAP)
    }
  }, [loggedIn])

  return (

{i18n.t('user.onboarding.title')}

          {fromLocation ? (

{i18n.t('user.onboarding.protected_view_info')}

          ) : (
            <>

{i18n.t('user.onboarding.intro')}

{i18n.t('user.onboarding.protected_view_info')}

            </>
          )}

          {signUp ? <SignUp /> : <SignIn />}

  )
}

UserOnboarding.propTypes = {
  signUp: PropTypes.bool.isRequired,
  onSignInSubmit: PropTypes.func.isRequired,
  onSignUpSubmit: PropTypes.func.isRequired,
}

const mapStateToProps = ({ user }) => ({
  loggedIn: user.loggedIn,
})

const mapDispatchToProps = (dispatch) => ({
  onSignInSubmit: (payload) => dispatch(signIn(payload)),
  onSignUpSubmit: (payload) =>
    dispatch(signUp({ ...payload, baseurl: config.baseUrl })),
})

const UserOnboardingContainer = connect(
  mapStateToProps,
  mapDispatchToProps
)(UserOnboarding)

export default UserOnboardingContainer
<commit_msg>Show onbaording text only if no redirect.<commit_after>import React, { useEffect } from 'react'
import PropTypes from 'prop-types'
import { connect, useSelector } from 'react-redux'

import { signIn, signUp } from './duck'
import { config } from '../../index'
import SignUpForm from './tabs/SignUpForm'
import SignInForm from './tabs/SignInForm'
import i18n from '../../i18n'
import { history, MAP } from '../../AppRouter'

const UserOnboarding = ({ signUp = false, onSignInSubmit, onSignUpSubmit }) => {
  const SignUp = () => <SignUpForm onSubmit={onSignUpSubmit} />
  const SignIn = () => <SignInForm onSubmit={onSignInSubmit} />

  const loggedIn = useSelector((state) => state.user.loggedIn)

  const fromLocation =
    history.location.state &&
    history.location.state.from &&
    history.location.state.from.pathname

  useEffect(() => {
    if (loggedIn) {
      history.push(fromLocation || MAP)
    }
  }, [loggedIn])

  return (

{i18n.t('user.onboarding.title')}

          {fromLocation ? (

{i18n.t('user.onboarding.protected_view_info')}

          ) : (

{i18n.t('user.onboarding.intro')}

          )}

          {signUp ? <SignUp /> : <SignIn />}

  )
}

UserOnboarding.propTypes = {
  signUp: PropTypes.bool.isRequired,
  onSignInSubmit: PropTypes.func.isRequired,
  onSignUpSubmit: PropTypes.func.isRequired,
}

const mapStateToProps = ({ user }) => ({
  loggedIn: user.loggedIn,
})

const mapDispatchToProps = (dispatch) => ({
  onSignInSubmit: (payload) => dispatch(signIn(payload)),
  onSignUpSubmit: (payload) =>
    dispatch(signUp({ ...payload, baseurl: config.baseUrl })),
})

const UserOnboardingContainer = connect(
  mapStateToProps,
  mapDispatchToProps
)(UserOnboarding)

export default UserOnboardingContainer
<|endoftext|>


<commit_before>// http://stackoverflow.com/questions/15349733/setimmediate-vs-nexttick

const Benchmark = require('benchmark');
const suite = new Benchmark.Suite()

suite.add('process.nextTick', function () {
  var a = 0;
  for (var i = 0; i < 100; i++) {
    process.nextTick(function () {
      a++
    })
  }
})

suite.add('setTimeout(0)', function () {
  var a = 0
  for (var i = 0; i < 100; i++) {
    setTimeout(function () {
      a++
    }, 0)
  }
})

suite.on('cycle', function (event) {
  console.log(String(event.target));
})
  .on('complete', function () {
    console.log('Fastest is ' + this.filter('fastest').map('name'));
  })

suite.run()<commit_msg>remove next_tick.js<commit_after><|endoftext|>


<commit_before>/*
 * (C) Copyright 2016 o2r project
 *
 * 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.
 *
 */

/* eslint-env mocha */
const assert = require('chai').assert;
const request = require('request');
const fs = require('fs');
const config = require('../config/config');

require("./setup")
const cookie = 's:C0LIrsxGtHOGHld8Nv2jedjL4evGgEHo.GMsWD5Vveq0vBt7/4rGeoH5Xx7Dd2pgZR9DvhKCyDTY';
const requestLoadingTimeout = 2000;

describe('Direct upload of invalid files', function () {

    describe('POST /api/v1/compendium invalid.zip (not a zip file)', () => {
        it('should respond with HTTP 500 error', (done) => {
            let formData = {
                'content_type': 'compendium_v1',
                'compendium': {
                    value: fs.createReadStream('./test/erc/invalid.zip'),
                    options: {
                        contentType: 'application/zip'
                    }
                }
            };
            let j = request.jar();
            let ck = request.cookie('connect.sid=' + cookie);
            j.setCookie(ck, global.test_host);

            request({
                uri: global.test_host + '/api/v1/compendium',
                method: 'POST',
                jar: j,
                formData: formData,
                timeout: requestLoadingTimeout
            }, (err, res, body) => {
                assert.ifError(err);
                assert.equal(res.statusCode, 500);
                assert.isObject(JSON.parse(body), 'returned JSON');
                assert.isDefined(JSON.parse(body).error, 'returned error');
                assert.include(JSON.parse(body).error, 'extraction failed: ');
                done();
            });
        });

        it('should provide a useful error message', (done) => {
            let formData = {
                'content_type': 'compendium_v1',
                'compendium': {
                    value: fs.createReadStream('./test/erc/invalid.zip'),
                    options: {
                        contentType: 'application/zip'
                    }
                }
            };
            let j = request.jar();
            let ck = request.cookie('connect.sid=' + cookie);
            j.setCookie(ck, global.test_host);

            request({
                uri: global.test_host + '/api/v1/compendium',
                method: 'POST',
                jar: j,
                formData: formData,
                timeout: requestLoadingTimeout
            }, (err, res, body) => {
                assert.ifError(err);
                assert.isObject(JSON.parse(body), 'returned JSON');
                assert.isDefined(JSON.parse(body).error, 'returned error');
                assert.include(JSON.parse(body).error, 'extraction failed: ');
                done();
            });
        });

        it('should NOT respond with internal configuration of the server', (done) => {
            let formData = {
                'content_type': 'compendium_v1',
                'compendium': {
                    value: fs.createReadStream('./test/erc/invalid.zip'),
                    options: {
                        contentType: 'application/zip'
                    }
                }
            };
            let j = request.jar();
            let ck = request.cookie('connect.sid=' + cookie);
            j.setCookie(ck, global.test_host);

            request({
                uri: global.test_host + '/api/v1/compendium',
                method: 'POST',
                jar: j,
                formData: formData,
                timeout: requestLoadingTimeout
            }, (err, res, body) => {
                assert.ifError(err);
                assert.notInclude(JSON.parse(body).error, config.fs.base);
                done();
            });
        });
    });

    describe('POST /api/v1/compendium empty.zip (empty zip file)', () => {
        it('should respond with ERROR 500 and valid JSON document', (done) => {
            let formData = {
                'content_type': 'compendium_v1',
                'compendium': {
                    value: fs.createReadStream('./test/erc/empty.zip'),
                    options: {
                        contentType: 'application/zip'
                    }
                }
            };
            let j = request.jar();
            let ck = request.cookie('connect.sid=' + cookie);
            j.setCookie(ck, global.test_host);

            request({
                uri: global.test_host + '/api/v1/compendium',
                method: 'POST',
                jar: j,
                formData: formData,
                timeout: requestLoadingTimeout
            }, (err, res, body) => {
                assert.ifError(err);
                assert.equal(res.statusCode, 500);
                assert.isObject(JSON.parse(body), 'returned JSON');
                done();
            });
        }).timeout(1000 * 60);

        it('should respond provide a helpful error message', (done) => {
            let formData = {
                'content_type': 'compendium_v1',
                'compendium': {
                    value: fs.createReadStream('./test/erc/empty.zip'),
                    options: {
                        contentType: 'application/zip'
                    }
                }
            };
            let j = request.jar();
            let ck = request.cookie('connect.sid=' + cookie);
            j.setCookie(ck, global.test_host);

            request({
                uri: global.test_host + '/api/v1/compendium',
                method: 'POST',
                jar: j,
                formData: formData,
                timeout: requestLoadingTimeout
            }, (err, res, body) => {
                assert.ifError(err);
                assert.include(JSON.parse(body).error, 'zipfile is empty');
                done();
            });
        });

        it('should NOT respond with internal configuration of the server', (done) => {
            let formData = {
                'content_type': 'compendium_v1',
                'compendium': {
                    value: fs.createReadStream('./test/erc/empty.zip'),
                    options: {
                        contentType: 'application/zip'
                    }
                }
            };
            let j = request.jar();
            let ck = request.cookie('connect.sid=' + cookie);
            j.setCookie(ck, global.test_host);

            request({
                uri: global.test_host + '/api/v1/compendium',
                method: 'POST',
                jar: j,
                formData: formData,
                timeout: requestLoadingTimeout
            }, (err, res, body) => {
                assert.ifError(err);
                assert.notInclude(JSON.parse(body).error, config.fs.base);
                done();
            });
        });
    });
});
<commit_msg>add test for unsupported encoding<commit_after>/*
 * (C) Copyright 2016 o2r project
 *
 * 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.
 *
 */

/* eslint-env mocha */
const assert = require('chai').assert;
const request = require('request');
const fs = require('fs');
const config = require('../config/config');

require("./setup")
const cookie = 's:C0LIrsxGtHOGHld8Nv2jedjL4evGgEHo.GMsWD5Vveq0vBt7/4rGeoH5Xx7Dd2pgZR9DvhKCyDTY';
const requestLoadingTimeout = 2000;

describe('Direct upload of invalid files', function () {

    describe('POST /api/v1/compendium invalid.zip (not a zip file)', () => {
        it('should respond with HTTP 500 error', (done) => {
            let formData = {
                'content_type': 'compendium_v1',
                'compendium': {
                    value: fs.createReadStream('./test/erc/invalid.zip'),
                    options: {
                        contentType: 'application/zip'
                    }
                }
            };
            let j = request.jar();
            let ck = request.cookie('connect.sid=' + cookie);
            j.setCookie(ck, global.test_host);

            request({
                uri: global.test_host + '/api/v1/compendium',
                method: 'POST',
                jar: j,
                formData: formData,
                timeout: requestLoadingTimeout
            }, (err, res, body) => {
                assert.ifError(err);
                assert.equal(res.statusCode, 500);
                assert.isObject(JSON.parse(body), 'returned JSON');
                assert.isDefined(JSON.parse(body).error, 'returned error');
                assert.include(JSON.parse(body).error, 'extraction failed: ');
                done();
            });
        });

        it('should provide a useful error message', (done) => {
            let formData = {
                'content_type': 'compendium_v1',
                'compendium': {
                    value: fs.createReadStream('./test/erc/invalid.zip'),
                    options: {
                        contentType: 'application/zip'
                    }
                }
            };
            let j = request.jar();
            let ck = request.cookie('connect.sid=' + cookie);
            j.setCookie(ck, global.test_host);

            request({
                uri: global.test_host + '/api/v1/compendium',
                method: 'POST',
                jar: j,
                formData: formData,
                timeout: requestLoadingTimeout
            }, (err, res, body) => {
                assert.ifError(err);
                assert.isObject(JSON.parse(body), 'returned JSON');
                assert.isDefined(JSON.parse(body).error, 'returned error');
                assert.include(JSON.parse(body).error, 'extraction failed: ');
                done();
            });
        });

        it('should NOT respond with internal configuration of the server', (done) => {
            let formData = {
                'content_type': 'compendium_v1',
                'compendium': {
                    value: fs.createReadStream('./test/erc/invalid.zip'),
                    options: {
                        contentType: 'application/zip'
                    }
                }
            };
            let j = request.jar();
            let ck = request.cookie('connect.sid=' + cookie);
            j.setCookie(ck, global.test_host);

            request({
                uri: global.test_host + '/api/v1/compendium',
                method: 'POST',
                jar: j,
                formData: formData,
                timeout: requestLoadingTimeout
            }, (err, res, body) => {
                assert.ifError(err);
                assert.notInclude(JSON.parse(body).error, config.fs.base);
                done();
            });
        });
    });

    describe('POST /api/v1/compendium empty.zip (empty zip file)', () => {
        it('should respond with ERROR 500 and valid JSON document', (done) => {
            let formData = {
                'content_type': 'compendium_v1',
                'compendium': {
                    value: fs.createReadStream('./test/erc/empty.zip'),
                    options: {
                        contentType: 'application/zip'
                    }
                }
            };
            let j = request.jar();
            let ck = request.cookie('connect.sid=' + cookie);
            j.setCookie(ck, global.test_host);

            request({
                uri: global.test_host + '/api/v1/compendium',
                method: 'POST',
                jar: j,
                formData: formData,
                timeout: requestLoadingTimeout
            }, (err, res, body) => {
                assert.ifError(err);
                assert.equal(res.statusCode, 500);
                assert.isObject(JSON.parse(body), 'returned JSON');
                done();
            });
        }).timeout(1000 * 60);

        it('should respond provide a helpful error message', (done) => {
            let formData = {
                'content_type': 'compendium_v1',
                'compendium': {
                    value: fs.createReadStream('./test/erc/empty.zip'),
                    options: {
                        contentType: 'application/zip'
                    }
                }
            };
            let j = request.jar();
            let ck = request.cookie('connect.sid=' + cookie);
            j.setCookie(ck, global.test_host);

            request({
                uri: global.test_host + '/api/v1/compendium',
                method: 'POST',
                jar: j,
                formData: formData,
                timeout: requestLoadingTimeout
            }, (err, res, body) => {
                assert.ifError(err);
                assert.include(JSON.parse(body).error, 'zipfile is empty');
                done();
            });
        });

        it('should NOT respond with internal configuration of the server', (done) => {
            let formData = {
                'content_type': 'compendium_v1',
                'compendium': {
                    value: fs.createReadStream('./test/erc/empty.zip'),
                    options: {
                        contentType: 'application/zip'
                    }
                }
            };
            let j = request.jar();
            let ck = request.cookie('connect.sid=' + cookie);
            j.setCookie(ck, global.test_host);

            request({
                uri: global.test_host + '/api/v1/compendium',
                method: 'POST',
                jar: j,
                formData: formData,
                timeout: requestLoadingTimeout
            }, (err, res, body) => {
                assert.ifError(err);
                assert.notInclude(JSON.parse(body).error, config.fs.base);
                done();
            });
        });
    });

    describe('POST /api/v1/compendium unsupported_encoding.zip (encoding: SHIFT_JIS)', () => {
        it('should respond with HTTP 422 error', (done) => {
            let formData = {
                'content_type': 'compendium_v1',
                'compendium': {
                    value: fs.createReadStream('./test/erc/unsupported_encoding.zip'),
                    options: {
                        contentType: 'application/zip'
                    }
                }
            };
            let j = request.jar();
            let ck = request.cookie('connect.sid=' + cookie);
            j.setCookie(ck, global.test_host);

            request({
                uri: global.test_host + '/api/v1/compendium',
                method: 'POST',
                jar: j,
                formData: formData,
                timeout: requestLoadingTimeout
            }, (err, res, body) => {
                assert.ifError(err);
                assert.equal(res.statusCode, 422);
                assert.isObject(JSON.parse(body), 'returned JSON');
                assert.isDefined(JSON.parse(body).error, 'returned error');
                assert.propertyVal(JSON.parse(body), 'error', 'encoding not supported');
                done();
            });
        });
    });
});
<|endoftext|>