<commit_before>var chalk = require('chalk');
var readline = require('readline');
var _ = require('underscore');
var path = require('path');
var sliceAnsi = require('slice-ansi');
var stripAnsi = require('strip-ansi');

var spinners = [
    '⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏',
    '┤┘┴└├┌┬┐'
];
var selectedSpinner = 1;
var index;
var currentPending;
var currentErrors = [];
var log = {
    info: chalk.bgWhite.black,
    pending: chalk.bgCyan.white,
    error: chalk.bgRed.white,
    success: chalk.bgGreen.white,
    warn: chalk.bgYellow.white
};
var writeStream = process.stdout;

function write (st) {
    var maxLength = writeStream.columns - 10;

    // TODO Make something that works. Right now it's removing the capped line with the next one.
    // Cap the complete string length based on the output width
    if (stripAnsi(st).length > maxLength) {
        // st = sliceAnsi(st, 0, maxLength - 4) + '... ';
    }

    writeStream.write(st);
}

function pending (text, tab) {
    var spinner = spinners[selectedSpinner];
    tab = tab || '';
    index = 0;
    clearInterval(currentPending);
    currentPending = setInterval(function () {
        clear();
        write(
            tab +
            log.pending(
                chalk.bold(' [ ' + spinner.charAt(index) + ' ] ') + text
            )
        );
        index += 1;
        if (index >= spinner.length) {
            index = 0;
        }
    }, 80);
}

function clear () {
    readline.clearLine(writeStream);
    readline.cursorTo(writeStream, 0);
}

function finishTask () {
    currentErrors = [];
}

function buildString (task) {
    var st = ' ';
    var duration = '';
    // The longest a param can be.
    var maxLength = 20;
    var param;

    if (task.duration) {
        duration = chalk.bold.magenta(' [' + (task.duration / 1000).toFixed(2) +
            's] ');
    }

    if (task.it) {
        st += chalk.black(task.it) + ' ';
        return chalk.bgWhite(st) + ' ' + chalk.bold.bgWhite(duration);
    } else {
        for (var i in task.params) {
            if (task.params.hasOwnProperty(i)) {
                param = task.params[i];

                if (typeof param === 'object') {
                    param = JSON.stringify(param);
                }

                // Cap param string length.
                if (param.length > maxLength) {
                    param = param.substring(0, maxLength - 4) + '...';
                }

                st += chalk.blue.bold(i) + chalk.bold(' : ');
                st += chalk.black(param) + ' ';
            }
        }
        return chalk.bold(task.type) + ' ' +
            chalk.bgWhite(st) + ' ' +
            chalk.bold.bgWhite(duration);
    }
}

module.exports = function (runner) {
    runner.on('begin', function (taskFiles) {
        var st = '\n begin';
        var last;

        taskFiles = _.map(taskFiles, function (taskFile) {
            return taskFile.name;
        });

        st += ' ' + taskFiles.length + ' suite';
        if (taskFiles.length > 1) {
            st += 's';
            last = taskFiles.pop();
        }
        st += ' : ';
        st += chalk.blue(taskFiles.join(', '));

        if (last) {
            st += chalk.blue(' and ' + last);
        }

        st += ' ';

        write(log.info(st) + '\n');
    });

    runner.on('start', function (taskFile) {
        var tasks, nbTasks, config;

        try {
            tasks = require(taskFile);
        } catch (e) {
            // Can't get the file.
        }

        var st = '\n   ';
        st += ' ' + chalk.blue(path.basename(taskFile, '.json'));

        if (tasks) {
            if (tasks.config.describe) {
                st += chalk.blue.bold(': ');
                st += chalk.black(tasks.config.describe);
            }

            // Adding 1 for the navigation.
            nbTasks = tasks.tasks.length + 1;
            st += chalk.bold.red(' (' + nbTasks + ' task');
            if (nbTasks > 1) {
                st += chalk.bold.red('s');
            }
            st += chalk.bold.red(') ');

            config = {
                type: '   - configuration',
                // Omit the url because we have it in the first task.
                // Omit the describe because we have already wrote it.
                params: _.omit(tasks.config, ['url', 'describe'])
            };

            st += '\n ' + buildString(config);
        }

        st += ' ';

        // Write.
        clearInterval(currentPending);
        clear();
        write(log.info(st) + '\n');
    });

    runner.on('pending', function (task) {
        pending(buildString(task), '    ');
    });

    runner.on('error', function (error) {
        currentErrors.push(error);
    });

    runner.on('pass', function (task) {
        clearInterval(currentPending);
        clear();

        if (currentErrors.length) {
            write(
                '    ' +
                log.warn(chalk.bold(' [ ! ] ') + buildString(task)) +
                    chalk.bgYellow.red(' ' + currentErrors.length +
                        ' error(s) ') +
                    '\n'
            );
        } else {
            write(
                '    ' +
                log.success(chalk.bold(' [ √ ] ') + buildString(task)) + '\n'
            );
        }

        finishTask();
    });

    runner.on('fail', function (task, err) {
        clearInterval(currentPending);
        clear();

        var st = chalk.bold(' [ x ] ');
        st += buildString(task);
        st += ' ';

        if (err) {
            st += chalk.bgYellow.red(' ' + err + ' ') + ' ';
        }

        write('    ' + log.error(st) + '\n');
        finishTask();
    });

    runner.on('finish', function (report) {
        var t = report.timing;
        var e = report.errors;
        var i, max, j;

        clearInterval(currentPending);
        write(log.info(chalk.bold('\n Report ')) + '\n');
        write(log.info('- Ran for : ' +
            chalk.bold((t.total / 1000).toFixed(2) + 's ')) + '\n');

        if (t.slowest) {
            console.log(JSON.stringify(t.slowest));
            write(
                log.info('- Slowest : ' +
                chalk.bold((t.slowest.test.it + ' ') +
                chalk.red(
                    (t.slowest.test.duration / 1000).toFixed(2) + 's '))
                ) + '\n'
            );
        }

        if (t.above.length) {
            write(log.info('- Above median : ') + '\n');
            for (i = 0, max = t.above.length; i < max; i += 1) {
                write(log.info('    - ' + t.above[i].test.it + ' ') + '\n');
            }
        }

        if (_.isEmpty(e.byError)) {
            return;
        }

        write('\n' + log.error('- Errors : ') + '\n');
        for (i in e.byError) {
            write(
                log.warn(chalk.red(
                    '    - [' +
                    chalk.bold(e.byError[i].error.type) +
                    '] ' + i + ' : '
                )) + '\n'
            );
            for (j = 0, max = e.byError[i].length; j < max; j += 1) {
                write(
                    log.info('        - ' + e.byError[i][j].test.it + ' ') +
                    '\n'
                );
            }
            write(chalk.grey(
                JSON.stringify(e.byError[i].error.details, null, '\t')
            ) + '\n\n');
        }
    });
};
<commit_msg>chore: update log<commit_after>var chalk = require('chalk');
var readline = require('readline');
var _ = require('underscore');
var path = require('path');
var sliceAnsi = require('slice-ansi');
var stripAnsi = require('strip-ansi');

var spinners = [
    '⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏',
    '┤┘┴└├┌┬┐'
];
var selectedSpinner = 1;
var index;
var currentPending;
var currentErrors = [];
var log = {
    info: chalk.bgWhite.black,
    pending: chalk.bgCyan.white,
    error: chalk.bgRed.white,
    success: chalk.bgGreen.white,
    warn: chalk.bgYellow.white
};
var writeStream = process.stdout;

function write (st) {
    var maxLength = writeStream.columns - 10;

    // TODO Make something that works. Right now it's removing the capped line with the next one.
    // Cap the complete string length based on the output width
    if (stripAnsi(st).length > maxLength) {
        // st = sliceAnsi(st, 0, maxLength - 4) + '... ';
    }

    writeStream.write(st);
}

function pending (text, tab) {
    var spinner = spinners[selectedSpinner];
    tab = tab || '';
    index = 0;
    clearInterval(currentPending);
    currentPending = setInterval(function () {
        clear();
        write(
            tab +
            log.pending(
                chalk.bold(' [ ' + spinner.charAt(index) + ' ] ') + text
            )
        );
        index += 1;
        if (index >= spinner.length) {
            index = 0;
        }
    }, 80);
}

function clear () {
    readline.clearLine(writeStream);
    readline.cursorTo(writeStream, 0);
}

function finishTask () {
    currentErrors = [];
}

function buildString (task) {
    var st = ' ';
    var duration = '';
    // The longest a param can be.
    var maxLength = 20;
    var param;

    if (task.duration) {
        duration = chalk.bold.magenta(' [' + (task.duration / 1000).toFixed(2) +
            's] ');
    }

    if (task.it) {
        st += chalk.black(task.it) + ' ';
        return chalk.bgWhite(st) + ' ' + chalk.bold.bgWhite(duration);
    } else {
        for (var i in task.params) {
            if (task.params.hasOwnProperty(i)) {
                param = task.params[i];

                if (typeof param === 'object') {
                    param = JSON.stringify(param);
                }

                // Cap param string length.
                if (param.length > maxLength) {
                    param = param.substring(0, maxLength - 4) + '...';
                }

                st += chalk.blue.bold(i) + chalk.bold(' : ');
                st += chalk.black(param) + ' ';
            }
        }
        return chalk.bold(task.type) + ' ' +
            chalk.bgWhite(st) + ' ' +
            chalk.bold.bgWhite(duration);
    }
}

module.exports = function (runner) {
    runner.on('begin', function (taskFiles) {
        var st = '\n begin';
        var last;

        taskFiles = _.map(taskFiles, function (taskFile) {
            return taskFile.name;
        });

        st += ' ' + taskFiles.length + ' suite';
        if (taskFiles.length > 1) {
            st += 's';
            last = taskFiles.pop();
        }
        st += ' : ';
        st += chalk.blue(taskFiles.join(', '));

        if (last) {
            st += chalk.blue(' and ' + last);
        }

        st += ' ';

        write(log.info(st) + '\n');
    });

    runner.on('start', function (taskFile) {
        var tasks, nbTasks, config;

        try {
            tasks = require(taskFile);
        } catch (e) {
            // Can't get the file.
        }

        var st = '\n   ';
        st += ' ' + chalk.blue(path.basename(taskFile, '.json'));

        if (tasks) {
            if (tasks.config.describe) {
                st += chalk.blue.bold(': ');
                st += chalk.black(tasks.config.describe);
            }

            // Adding 1 for the navigation.
            nbTasks = tasks.tasks.length + 1;
            st += chalk.bold.red(' (' + nbTasks + ' task');
            if (nbTasks > 1) {
                st += chalk.bold.red('s');
            }
            st += chalk.bold.red(') ');

            config = {
                type: '   - configuration',
                // Omit the url because we have it in the first task.
                // Omit the describe because we have already wrote it.
                params: _.omit(tasks.config, ['url', 'describe'])
            };

            st += '\n ' + buildString(config);
        }

        st += ' ';

        // Write.
        clearInterval(currentPending);
        clear();
        write(log.info(st) + '\n');
    });

    runner.on('pending', function (task) {
        pending(buildString(task), '    ');
    });

    runner.on('error', function (error) {
        currentErrors.push(error);
    });

    runner.on('pass', function (task) {
        clearInterval(currentPending);
        clear();

        if (currentErrors.length) {
            write(
                '    ' +
                log.warn(chalk.bold(' [ ! ] ') + buildString(task)) +
                    chalk.bgYellow.red(' ' + currentErrors.length +
                        ' error(s) ') +
                    '\n'
            );
        } else {
            write(
                '    ' +
                log.success(chalk.bold(' [ √ ] ') + buildString(task)) + '\n'
            );
        }

        finishTask();
    });

    runner.on('fail', function (task, err) {
        clearInterval(currentPending);
        clear();

        var st = chalk.bold(' [ x ] ');
        st += buildString(task);
        st += ' ';

        if (err) {
            st += chalk.bgYellow.red(' ' + err + ' ') + ' ';
        }

        write('    ' + log.error(st) + '\n');
        finishTask();
    });

    runner.on('finish', function (report) {
        var t = report.timing;
        var e = report.errors;
        var i, max, j;

        clearInterval(currentPending);
        write(log.info(chalk.bold('\n Report ')) + '\n');
        write(log.info('- Ran for : ' +
            chalk.bold((t.total / 1000).toFixed(2) + 's ')) + '\n');

        if (t.slowest) {
            console.log(t, typeof t.slowest);
            write(
                log.info('- Slowest : ' +
                chalk.bold((t.slowest.test.it + ' ') +
                chalk.red(
                    (t.slowest.test.duration / 1000).toFixed(2) + 's '))
                ) + '\n'
            );
        }

        if (t.above.length) {
            write(log.info('- Above median : ') + '\n');
            for (i = 0, max = t.above.length; i < max; i += 1) {
                write(log.info('    - ' + t.above[i].test.it + ' ') + '\n');
            }
        }

        if (_.isEmpty(e.byError)) {
            return;
        }

        write('\n' + log.error('- Errors : ') + '\n');
        for (i in e.byError) {
            write(
                log.warn(chalk.red(
                    '    - [' +
                    chalk.bold(e.byError[i].error.type) +
                    '] ' + i + ' : '
                )) + '\n'
            );
            for (j = 0, max = e.byError[i].length; j < max; j += 1) {
                write(
                    log.info('        - ' + e.byError[i][j].test.it + ' ') +
                    '\n'
                );
            }
            write(chalk.grey(
                JSON.stringify(e.byError[i].error.details, null, '\t')
            ) + '\n\n');
        }
    });
};
<|endoftext|>


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

  // Config options
  App.ui.config.std.ajax = {
    'options': {},
    'version': null,
    'url': '/api',
    'skipAuthenticityToken': false
  };

  function url() {
    if (App.ui.config.std.ajax.version === null) {
      return App.ui.config.std.ajax.url;
    } else {
      return App.ui.config.std.ajax.url + '/v' + App.ui.config.std.ajax.version;
    }
  }

  function queryStringFromOptions(options_arg, defaultOptions_arg) {
    var queries = [];

    var options = options_arg || {};
    var defaultOptions = defaultOptions_arg || {};

    // Add options to default options (overwrites any default)
    Object.keys(options).forEach(function(key) {
      defaultOptions[key] = options[key];
    });

    Object.keys(defaultOptions).forEach(function(key) {
      queries.push(App.ui.interfaces.std.string.methods._underscore(key) + "=" + defaultOptions[key]);
    });

    if (queries.length > 0) {
      return '?' + queries.join('&');
    } else {
      return '';
    }
  }

  App.ui.interfaces.std.ajax = {
    methods: {
      _sendRequest: function(endpoint, method, data) {
        var path = url() + '/' + endpoint;

        // TODO: Implement all requests as form data.  Make file uploading much better
//         function jsonToFormData (inJSON, inTestJSON, inFormData, parentKey) {
//             // http://stackoverflow.com/a/22783314/260665
//             // Raj: Converts any nested JSON to formData.
//             var form_data = inFormData || new FormData();
//             var testJSON = inTestJSON || {};
//             for ( var key in inJSON ) {
//                 // 1. If it is a recursion, then key has to be constructed like "parent.child" where parent JSON contains a child JSON
//                 // 2. Perform append data only if the value for key is not a JSON, recurse otherwise!
//                 var constructedKey = key;
//                 if (parentKey) {
//                     constructedKey = parentKey + "." + key;
//                 }

//                 var value = inJSON[key];
//                 if (value && value.constructor === {}.constructor) {
//                     // This is a JSON, we now need to recurse!
//                     jsonToFormData (value, testJSON, form_data, constructedKey);
//                 } else {
//                     form_data.append(constructedKey, inJSON[key]);
//                     testJSON[constructedKey] = inJSON[key];
//                 }
//             }
//             return form_data;
//         }

        if (data instanceof(FormData)) {
          if (!App.ui.config.std.ajax.skipAuthenticityToken) {
            data.append('authenticity_token', App.ui.config.csrf_token);
          }

          return $.ajax({
              url: path,
              data: data || new FormData(),
              type: method || 'POST',
              processData: false,
              contentType: false,
              dataType: 'json'
          });
        }else{
          if (!App.ui.config.std.ajax.skipAuthenticityToken && data) {
            data['authenticity_token'] = App.ui.config.csrf_token;
          }

          return $.ajax({
            url: path,
            type: method || 'GET',
            data: data || {}
          });
        }
      },
      _getRequest: function(endpoint, options) {
        var requestUrl = endpoint + queryStringFromOptions(options, App.ui.config.std.ajax.options);
        return App.ui.interfaces.std.ajax.methods._sendRequest(requestUrl, 'GET');
      },
      _postRequest: function(endpoint, data, options) {
        var requestUrl = endpoint + queryStringFromOptions(options, App.ui.config.std.ajax.options);
        return App.ui.interfaces.std.ajax.methods._sendRequest(requestUrl, 'POST', data);
      },
      _deleteRequest: function(endpoint, data, options) {
        var requestUrl = endpoint + queryStringFromOptions(options, App.ui.config.std.ajax.options);
        return App.ui.interfaces.std.ajax.methods._sendRequest(requestUrl, 'DELETE', data);
      },
      _patchRequest: function(endpoint, data, options) {
        var requestUrl = endpoint + queryStringFromOptions(options, App.ui.config.std.ajax.options);
        return App.ui.interfaces.std.ajax.methods._sendRequest(requestUrl, 'PATCH', data);
      }
    }
  };
})();
<commit_msg>Update ajax.js<commit_after>(function() {
  "use strict";

  // Config options
  App.ui.config.std.ajax = {
    'options': {},
    'version': null,
    'url': '/api',
    'skipAuthenticityToken': false
  };

  function url() {
    if (App.ui.config.std.ajax.version === null) {
      return App.ui.config.std.ajax.url;
    } else {
      return App.ui.config.std.ajax.url + '/v' + App.ui.config.std.ajax.version;
    }
  }

  function queryStringFromOptions(options_arg, defaultOptions_arg) {
    var queries = [];

    var options = JSON.parse(JSON.stringify(options_arg)) || {};
    var defaultOptions = JSON.parse(JSON.stringify(defaultOptions_arg)) || {};

    // Add options to default options (overwrites any default)
    Object.keys(options).forEach(function(key) {
      defaultOptions[key] = options[key];
    });

    Object.keys(defaultOptions).forEach(function(key) {
      queries.push(App.ui.interfaces.std.string.methods._underscore(key) + "=" + defaultOptions[key]);
    });

    if (queries.length > 0) {
      return '?' + queries.join('&');
    } else {
      return '';
    }
  }

  App.ui.interfaces.std.ajax = {
    methods: {
      _sendRequest: function(endpoint, method, data) {
        var path = url() + '/' + endpoint;

        // TODO: Implement all requests as form data.  Make file uploading much better
//         function jsonToFormData (inJSON, inTestJSON, inFormData, parentKey) {
//             // http://stackoverflow.com/a/22783314/260665
//             // Raj: Converts any nested JSON to formData.
//             var form_data = inFormData || new FormData();
//             var testJSON = inTestJSON || {};
//             for ( var key in inJSON ) {
//                 // 1. If it is a recursion, then key has to be constructed like "parent.child" where parent JSON contains a child JSON
//                 // 2. Perform append data only if the value for key is not a JSON, recurse otherwise!
//                 var constructedKey = key;
//                 if (parentKey) {
//                     constructedKey = parentKey + "." + key;
//                 }

//                 var value = inJSON[key];
//                 if (value && value.constructor === {}.constructor) {
//                     // This is a JSON, we now need to recurse!
//                     jsonToFormData (value, testJSON, form_data, constructedKey);
//                 } else {
//                     form_data.append(constructedKey, inJSON[key]);
//                     testJSON[constructedKey] = inJSON[key];
//                 }
//             }
//             return form_data;
//         }

        if (data instanceof(FormData)) {
          if (!App.ui.config.std.ajax.skipAuthenticityToken) {
            data.append('authenticity_token', App.ui.config.csrf_token);
          }

          return $.ajax({
              url: path,
              data: data || new FormData(),
              type: method || 'POST',
              processData: false,
              contentType: false,
              dataType: 'json'
          });
        }else{
          if (!App.ui.config.std.ajax.skipAuthenticityToken && data) {
            data['authenticity_token'] = App.ui.config.csrf_token;
          }

          return $.ajax({
            url: path,
            type: method || 'GET',
            data: data || {}
          });
        }
      },
      _getRequest: function(endpoint, options) {
        var requestUrl = endpoint + queryStringFromOptions(options, App.ui.config.std.ajax.options);
        return App.ui.interfaces.std.ajax.methods._sendRequest(requestUrl, 'GET');
      },
      _postRequest: function(endpoint, data, options) {
        var requestUrl = endpoint + queryStringFromOptions(options, App.ui.config.std.ajax.options);
        return App.ui.interfaces.std.ajax.methods._sendRequest(requestUrl, 'POST', data);
      },
      _deleteRequest: function(endpoint, data, options) {
        var requestUrl = endpoint + queryStringFromOptions(options, App.ui.config.std.ajax.options);
        return App.ui.interfaces.std.ajax.methods._sendRequest(requestUrl, 'DELETE', data);
      },
      _patchRequest: function(endpoint, data, options) {
        var requestUrl = endpoint + queryStringFromOptions(options, App.ui.config.std.ajax.options);
        return App.ui.interfaces.std.ajax.methods._sendRequest(requestUrl, 'PATCH', data);
      }
    }
  };
})();
<|endoftext|>


<commit_before>'use strict';

var wrapInline = require('./formatting/wrapInline')

var formattingPlugins = [
  require('./commands/bold'),
  require('./commands/italic'),
  require('./commands/underline'),
  require('./commands/heading'),
  require('./commands/link'),
  require('./commands/blockquote'),
  require('./plugins/list'),
  require('./plugins/hr')
]

/**
 * appendParagraph(elem) appends an empty paragraph to elem. If no
 * element is given, returns the paragraph.
 *
 * @param {Element} elem
 * @return Element
 */
function appendParagraph (elem) {
  var p = document.createElement('p')

  p.appendChild(document.createElement('br'))

  if (elem)
    elem.appendChild(p)
  else return p
}

/**
 * fixSelection() fixes Firefox's select all behaviour by placing
 * the caret within block elements, not outside. Although this does
 * not prevent escaping of paragraph mode, it does allow for the
 * formatting of multiple blocks (e.g. <p> -> <h2>).
 */
function fixSelection () {
  /* jshint validthis:true */
  var sel = window.getSelection(),
      marker,
      last

  // Dont place markers and whatnot if we dont have to; otherwise,
  // it can cause issues (https://github.com/lucthev/quill/issues/12)
  if (!sel.rangeCount || this.selection.getContaining()) return

  this.selection.save()

  marker = this.elem.firstChild
  if (marker.classList.contains('Quill-marker')) {
    this.elem.removeChild(marker)

    this.elem.firstChild
      .insertBefore(marker, this.elem.firstChild.firstChild)
  }

  marker = this.elem.lastChild
  if (marker.classList.contains('Quill-marker')) {
    this.elem.removeChild(marker)

    last = this.elem.lastChild
    if (last.lastChild && last.lastChild.nodeName === 'BR')
      last.insertBefore(marker, last.lastChild)
    else last.appendChild(marker)
  }

  this.selection.restore()
}

/**
 * onFocus() fixes an issue where the caret is placed outside all
 * block element in Firefox when focusing the element.
 */
function onFocus () {
  /* jshint validthis:true */
  var sel = window.getSelection(),
      outside,
      node

  if (!sel.rangeCount) return

  this.selection.save()
  outside = this.elem.firstChild.classList.contains('Quill-marker')
  this.selection.removeMarkers()

  if (!outside) return

  node = this.elem.firstChild
  if (this.elem.textContent.trim()) {
    while (node.firstChild)
      node = node.firstChild
  }

  this.selection.placeCaret(node)
}

function onKeydown (e) {
  /* jshint validthis:true */
  var container = this.selection.getContaining(),
      newLine = this.selection.isNewLine(),
      sel = window.getSelection(),
      paragraph

  // Prevent newline creation when already on a new line.
  if (e.keyCode === 13 && newLine)
    return e.preventDefault()

  // Pressing enter after an <h[1-6]> or <blockquote> creates divs or
  // blockquotes, not paragraphs. We override this behaviour.
  // TODO: Ideally, this would be in the plugins themselves.
  if (e.keyCode === 13 && sel.isCollapsed &&
      /^H[1-6]|BLOCKQUOTE$/i.test(container.nodeName)) {

    if (this.selection.at('end', container)) {
      e.preventDefault()

      paragraph = appendParagraph()
      container.parentNode
        .insertBefore(paragraph, container.nextElementSibling)

      this.selection.placeCaret(paragraph)

      this.emit('input')
    }
  }
}

function onInput () {
  /* jshint validthis:true */

  this.selection.save()

  this.sanitizer.clean(this.elem)

  this.selection.restore()
}

function mergeSimilar (elem) {
  /* jshint validthis:true */
  var prev = elem.previousSibling

  // If they are similar and inline, we merge them.
  if (this.isInline(elem) && this.isInline(prev) &&
      this.areSimilar(prev, elem)) {

    while (prev.firstChild) {
      elem.insertBefore(
        prev.removeChild(prev.firstChild),
        elem.firstChild
      )
    }

    elem.parentNode.removeChild(prev)
  }
}

function afterClean (elem) {
  /* jshint validthis:true */

  if (elem === this.elem)
    wrapInline.call(this.node, elem)
}

/**
 * The Rich mode constructor.
 *
 * @param {Quill} Quill
 */
function RichMode (Quill) {

  formattingPlugins.forEach(function (Plugin) {
    Quill.use(Plugin)
  })

  this.elem = Quill.elem
  this.Quill = Quill

  // Store bound handlers for later removal.
  this.onFocus = onFocus.bind(Quill)
  this.onKeydown = onKeydown.bind(Quill)
  this.onKeyup = fixSelection.bind(Quill)
  this.mergeSimilar = mergeSimilar.bind(Quill.node)

  this.elem.addEventListener('keydown', this.onKeydown)
  this.elem.addEventListener('keyup', this.onKeyup)
  this.elem.addEventListener('focus', this.onFocus)

  if (!this.elem.firstElementChild)
    appendParagraph(this.elem)

  Quill.sanitizer
    .addElements(['p', 'br'])
    .addFilter(this.mergeSimilar)

  this.onInput = onInput.bind(Quill)
  this.afterClean = afterClean.bind(Quill)
  Quill.on('input', this.onInput)
  Quill.on('afterclean', this.afterClean)
}

/**
 * RichMode.destroy() removes event listeners, deletes references
 * to elements, etc.
 *
 * @return null
 */
RichMode.prototype.destroy = function () {
  this.elem.removeEventListener('keydown', this.onKeydown)
  this.elem.removeEventListener('keyup', this.onKeyup)
  this.elem.removeEventListener('focus', this.onFocus)

  this.Quill.sanitizer
    .removeElements(['p', 'br'])
    .removeFilter(this.mergeSimilar)

  this.Quill.off('input', this.onInput)
  this.Quill.off('afterclean', this.afterclean)

  delete this.Quill
  delete this.elem

  return null
}

// Plugin name.
RichMode.plugin = 'rich'

module.exports = RichMode
<commit_msg>Defer sanitization.<commit_after>'use strict';

var wrapInline = require('./formatting/wrapInline')

var formattingPlugins = [
  require('./commands/bold'),
  require('./commands/italic'),
  require('./commands/underline'),
  require('./commands/heading'),
  require('./commands/link'),
  require('./commands/blockquote'),
  require('./plugins/list'),
  require('./plugins/hr')
]

/**
 * appendParagraph(elem) appends an empty paragraph to elem. If no
 * element is given, returns the paragraph.
 *
 * @param {Element} elem
 * @return Element
 */
function appendParagraph (elem) {
  var p = document.createElement('p')

  p.appendChild(document.createElement('br'))

  if (elem)
    elem.appendChild(p)
  else return p
}

/**
 * fixSelection() fixes Firefox's select all behaviour by placing
 * the caret within block elements, not outside. Although this does
 * not prevent escaping of paragraph mode, it does allow for the
 * formatting of multiple blocks (e.g. <p> -> <h2>).
 */
function fixSelection () {
  /* jshint validthis:true */
  var sel = window.getSelection(),
      marker,
      last

  // Dont place markers and whatnot if we dont have to; otherwise,
  // it can cause issues (https://github.com/lucthev/quill/issues/12)
  if (!sel.rangeCount || this.selection.getContaining()) return

  this.selection.save()

  marker = this.elem.firstChild
  if (marker.classList.contains('Quill-marker')) {
    this.elem.removeChild(marker)

    this.elem.firstChild
      .insertBefore(marker, this.elem.firstChild.firstChild)
  }

  marker = this.elem.lastChild
  if (marker.classList.contains('Quill-marker')) {
    this.elem.removeChild(marker)

    last = this.elem.lastChild
    if (last.lastChild && last.lastChild.nodeName === 'BR')
      last.insertBefore(marker, last.lastChild)
    else last.appendChild(marker)
  }

  this.selection.restore()
}

/**
 * onFocus() fixes an issue where the caret is placed outside all
 * block element in Firefox when focusing the element.
 */
function onFocus () {
  /* jshint validthis:true */
  var sel = window.getSelection(),
      outside,
      node

  if (!sel.rangeCount) return

  this.selection.save()
  outside = this.elem.firstChild.classList.contains('Quill-marker')
  this.selection.removeMarkers()

  if (!outside) return

  node = this.elem.firstChild
  if (this.elem.textContent.trim()) {
    while (node.firstChild)
      node = node.firstChild
  }

  this.selection.placeCaret(node)
}

function onKeydown (e) {
  /* jshint validthis:true */
  var container = this.selection.getContaining(),
      newLine = this.selection.isNewLine(),
      sel = window.getSelection(),
      paragraph

  // Prevent newline creation when already on a new line.
  if (e.keyCode === 13 && newLine)
    return e.preventDefault()

  // Pressing enter after an <h[1-6]> or <blockquote> creates divs or
  // blockquotes, not paragraphs. We override this behaviour.
  // TODO: Ideally, this would be in the plugins themselves.
  if (e.keyCode === 13 && sel.isCollapsed &&
      /^H[1-6]|BLOCKQUOTE$/i.test(container.nodeName)) {

    if (this.selection.at('end', container)) {
      e.preventDefault()

      paragraph = appendParagraph()
      container.parentNode
        .insertBefore(paragraph, container.nextElementSibling)

      this.selection.placeCaret(paragraph)

      this.emit('input')
    }
  }
}

function onInput () {
  /* jshint validthis:true */

  // Give other event listeners a chance to finish before sanitizing.
  setTimeout(function () {
    this.selection.save()

    this.sanitizer.clean(this.elem)

    this.selection.restore()
  }.bind(this), 0)
}

function mergeSimilar (elem) {
  /* jshint validthis:true */
  var prev = elem.previousSibling

  // If they are similar and inline, we merge them.
  if (this.isInline(elem) && this.isInline(prev) &&
      this.areSimilar(prev, elem)) {

    while (prev.firstChild) {
      elem.insertBefore(
        prev.removeChild(prev.firstChild),
        elem.firstChild
      )
    }

    elem.parentNode.removeChild(prev)
  }
}

function afterClean (elem) {
  /* jshint validthis:true */

  if (elem === this.elem)
    wrapInline.call(this.node, elem)
}

/**
 * The Rich mode constructor.
 *
 * @param {Quill} Quill
 */
function RichMode (Quill) {

  formattingPlugins.forEach(function (Plugin) {
    Quill.use(Plugin)
  })

  this.elem = Quill.elem
  this.Quill = Quill

  // Store bound handlers for later removal.
  this.onFocus = onFocus.bind(Quill)
  this.onKeydown = onKeydown.bind(Quill)
  this.onKeyup = fixSelection.bind(Quill)
  this.mergeSimilar = mergeSimilar.bind(Quill.node)

  this.elem.addEventListener('keydown', this.onKeydown)
  this.elem.addEventListener('keyup', this.onKeyup)
  this.elem.addEventListener('focus', this.onFocus)

  if (!this.elem.firstElementChild)
    appendParagraph(this.elem)

  Quill.sanitizer
    .addElements(['p', 'br'])
    .addFilter(this.mergeSimilar)

  this.onInput = onInput.bind(Quill)
  this.afterClean = afterClean.bind(Quill)
  Quill.on('input', this.onInput)
  Quill.on('afterclean', this.afterClean)
}

/**
 * RichMode.destroy() removes event listeners, deletes references
 * to elements, etc.
 *
 * @return null
 */
RichMode.prototype.destroy = function () {
  this.elem.removeEventListener('keydown', this.onKeydown)
  this.elem.removeEventListener('keyup', this.onKeyup)
  this.elem.removeEventListener('focus', this.onFocus)

  this.Quill.sanitizer
    .removeElements(['p', 'br'])
    .removeFilter(this.mergeSimilar)

  this.Quill.off('input', this.onInput)
  this.Quill.off('afterclean', this.afterclean)

  delete this.Quill
  delete this.elem

  return null
}

// Plugin name.
RichMode.plugin = 'rich'

module.exports = RichMode
<|endoftext|>


<commit_before>// @flow

import { isSameRole } from './role';
import { getRole } from './get';
import { compose, composeAll, applyAll, identity, selectLast } from '../utils';

import type { Set, Map } from 'immutable';
import type { Role } from './role';
import type { Store } from '../store';
import type { Grant } from '../grant';

export const setRoleToRoles = (roles: Map<string, Role>) =>
  (role: Role) => roles.set(role.name, role);

export const deleteRoleOnGrantMembers = (role: Role) => (members: Set<any>) =>
  composeAll(
    members.delete.bind(members),
    members.find.bind(members, isSameRole(role)),
  )(members);

export const setRoleToStore = (store: Store) => compose(
  store.set.bind(store, 'roles'),
  setRoleToRoles(store.roles),
);

export const updateRoleOnGrant = (role: Role) => (grant: Grant) =>
  composeAll(
    grant.set.bind(grant, 'members'),
    (members: Set<any>) => members.add(role),
    deleteRoleOnGrantMembers(role),
  )(grant.members);

export const updateRolesOnGrants = (store: Store) =>
  composeAll(
    store.set.bind(store, 'grants'),
    store.grants.map.bind(store.grants),
    updateRoleOnGrant,
    getRole(store.roles),
  );

export const addMemberToRole = (roles: Map<string, Role>) =>
  (member: any, role: Role | string) => composeAll(
    ([role, members]) => role.set('members', members),
      applyAll(
        identity,
        (role: Role) => role.members.add(member),
      ),
      getRole(roles),
  )(role);

export const setRole = (stateSetter: Function, store: Store) =>
  composeAll(
    selectLast,
    applyAll(
      compose(stateSetter, ([state, role]) => updateRolesOnGrants(state)(role)),
      compose(identity, selectLast),
    ),
    applyAll(
      setRoleToStore(store),
      identity,
    ),
    addMemberToRole(store.roles),
  );<commit_msg>Fixed issue with updating roles on existing grants<commit_after>// @flow

import { isSameRole } from './role';
import { getRole } from './get';
import { compose, composeAll, applyAll, applyIf, identity, selectLast } from '../utils';

import type { Set, Map } from 'immutable';
import type { Role } from './role';
import type { Store } from '../store';
import type { Grant } from '../grant';

export const grantHaveRole = (role: Role) => (grant: Grant) =>
  !!grant.members.find(isSameRole(role));

export const deleteRoleOnGrantMembers = (role: Role) => (members: Set<any>) =>
  composeAll(
    members.delete.bind(members),
    members.find.bind(members, isSameRole(role)),
  )(members);

export const updateRoleOnGrant = (role: Role) => (grant: Grant) =>
  composeAll(
    grant.set.bind(grant, 'members'),
    (members: Set<any>) => members.add(role),
    deleteRoleOnGrantMembers(role),
  )(grant.members);

export const updateRolesOnGrants = (store: Store) =>
  composeAll(
    store.set.bind(store, 'grants'),
    store.grants.map.bind(store.grants),
    ([haveRole, updateRole]) => applyIf(updateRole)(haveRole),
    applyAll(
      grantHaveRole,
      updateRoleOnGrant,
    ),
  );

export const setRoleToRoles = (roles: Map<string, Role>) =>
  (role: Role) => roles.set(role.name, role);

export const setRoleToStore = (store: Store) => compose(
  store.set.bind(store, 'roles'),
  setRoleToRoles(store.roles),
);

export const addMemberToRole = (roles: Map<string, Role>) =>
  (member: any, role: Role | string) => composeAll(
    ([role, members]) => role.set('members', members),
    applyAll(
      identity,
      (role: Role) => role.members.add(member),
    ),
    getRole(roles),
  )(role);

export const setRole = (stateSetter: Function, store: Store) =>
  composeAll(
    selectLast,
    applyAll(
      compose(stateSetter, ([state, role]) => updateRolesOnGrants(state)(role)),
      compose(identity, selectLast),
    ),
    applyAll(
      setRoleToStore(store),
      identity,
    ),
    addMemberToRole(store.roles),
  );<|endoftext|>


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

moduleForModel('collaboration', 'Unit | Model | collaboration', {
  needs: ['model:project', 'model:user', 'model:team']
});

test('it exists', function(assert) {
  const collaboration = this.subject();
  assert.equal(collaboration.get('hasRole'), true);
});

test('it exists', function(assert) {
  const collaboration = this.subject();
  assert.equal(collaboration.get('roleHumanized'), "noPreference");
});
<commit_msg>chore: test case for switch<commit_after>import { moduleForModel, test} from 'ember-qunit';

moduleForModel('collaboration', 'Unit | Model | collaboration', {
  needs: ['model:project', 'model:user', 'model:team']
});

test('it exists', function(assert) {
  const collaboration = this.subject();
  assert.equal(collaboration.get('hasRole'), true, "Has Role");
});

test('it exists', function(assert) {
  const collaboration = this.subject();
  assert.equal(collaboration.get('roleHumanized'), "noPreference", "No Preference");
  collaboration.set('roleHumanized', "admin");
  assert.equal(collaboration.get('roleHumanized'), "admin", "Admin");
});
<|endoftext|>


<commit_before>import Ember from 'ember';
import BehaviorService from 'sl-ember-behavior/services/sl-behavior';
import { moduleFor, test } from 'ember-qunit';

let BS;

moduleFor( 'service:sl-behavior', 'Unit | Service | sl behavior', {
    unit: true,

    beforeEach() {
        BS = BehaviorService.create();
    }
});

test( '"behaviors" property defaults to null', function( assert ) {
    assert.equal(
        BS.get( 'behaviors' ),
        null
    );
});

test( 'setBehaviors() requires an Object to be provided', function( assert ) {

    // Empty parameter

    let assertionThrown = false;

    try {
        BS.setBehaviors();
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was empty'
    );

    // Number parameter

    assertionThrown = false;

    try {
        BS.setBehaviors( 4 );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was a Number'
    );

    // Boolean parameter

    assertionThrown = false;

    try {
        BS.setBehaviors( false );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was a Boolean'
    );

    // Array Parameter

    assertionThrown = false;

    try {
        BS.setBehaviors( [] );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was an Array'
    );

    // Function

    assertionThrown = false;

    try {
        BS.getBehaviorGroup( function(){} );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was a Function'
    );

    // String Parameter

    assertionThrown = false;

    try {
        BS.setBehaviors( 'test' );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was a String'
    );

    // Object Parameter

    assertionThrown = false;

    try {
        BS.setBehaviors( {} );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        !assertionThrown,
        'Parameter was an Object'
    );
});

test( 'setBehaviors() sets data on the behaviors property', function( assert ) {
    let testBehaviors = {
        'the_key': 'my value'
    };

    BS.setBehaviors( testBehaviors );

    assert.deepEqual(
        BS.get( 'behaviors' ),
        testBehaviors
    );
});

test( 'isAble() requires at least two parameters to be provided', function( assert ) {

    // No arguments

    let assertionThrown = false;

    try {
        BS.isAble();
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'No parameters were provided'
    );

    // One argument

    assertionThrown = false;

    try {
        BS.isAble( 'one' );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'One parameter was provided'
    );

    // Two arguments

    assertionThrown = false;

    try {
        BS.isAble( 'one', 'two' );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        !assertionThrown,
        'Two parameters were provided'
    );

    // Three arguments

    assertionThrown = false;

    try {
        BS.isAble( 'one', 'two', false );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        !assertionThrown,
        'Three parameters were provided'
    );
});

test( 'isAble() requires first parameter to be a String', function( assert ) {
    // Empty parameter

    let assertionThrown = false;

    try {
        BS.isAble();
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was empty'
    );

    // Number parameter

    assertionThrown = false;

    try {
        BS.isAble( 4, 'notUnderTest' );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was a Number'
    );

    // Boolean parameter

    assertionThrown = false;

    try {
        BS.isAble( false, 'notUnderTest' );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was a Boolean'
    );

    // Array Parameter

    assertionThrown = false;

    try {
        BS.isAble( [], 'notUnderTest' );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was an Array'
    );

    // Function

    assertionThrown = false;

    try {
        BS.getBehaviorGroup( function(){} );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was a Function'
    );

    // String Parameter

    assertionThrown = false;

    try {
        BS.isAble( {}, 'notUnderTest' );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was an Object'
    );

    // Object Parameter

    assertionThrown = false;

    try {
        BS.isAble( 'test', 'notUnderTest' );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        !assertionThrown,
        'Parameter was a String'
    );
});

test( 'isAble() requires second argument to be a String', function( assert ) {
    // Number parameter

    let assertionThrown = false;

    try {
        BS.isAble( 'notUnderTest', 4 );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was a Number'
    );

    // Boolean parameter

    assertionThrown = false;

    try {
        BS.isAble( 'notUnderTest', false );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was a Boolean'
    );

    // Array Parameter

    assertionThrown = false;

    try {
        BS.isAble( 'notUnderTest', [] );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was an Array'
    );

    // Function

    assertionThrown = false;

    try {
        BS.getBehaviorGroup( function(){} );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was a Function'
    );

    // String Parameter

    assertionThrown = false;

    try {
        BS.isAble( 'notUnderTest', 'test' );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        !assertionThrown,
        'Parameter was a String'
    );

    // Object Parameter

    assertionThrown = false;

    BS.getBehaviorGroup = function() {
        return true;
    };

    try {
        BS.isAble( 'notUnderTest', {});
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was an Object'
    );
});

test( 'isAble() requires third argument to be a boolean or undefined', function( assert ) {
    // Number parameter

    let assertionThrown = false;

    try {
        BS.isAble( 'notUnderTest', 'notUnderTest', 4 );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was a Number'
    );

    // Boolean parameter

    assertionThrown = false;

    try {
        BS.isAble( 'notUnderTest', 'notUnderTest', false );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        !assertionThrown,
        'Parameter was a Boolean'
    );

    // Array Parameter

    assertionThrown = false;

    try {
        BS.isAble( 'notUnderTest', 'notUnderTest', [] );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was an Array'
    );

    // Function

    assertionThrown = false;

    try {
        BS.isAble( 'notUnderTest', 'notUnderTest', function(){} );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was a Function'
    );

    // String Parameter

    assertionThrown = false;

    try {
        BS.isAble( 'notUnderTest', 'notUnderTest', 'test' );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was a String'
    );

    // Object Parameter

    assertionThrown = false;

    BS.getBehaviorGroup = function() {
        return true;
    };

    try {
        BS.isAble( 'notUnderTest', {});
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was an Object'
    );

    // No Parameter

    assertionThrown = false;

    BS.getBehaviorGroup = function() {
        return true;
    };

    try {
        BS.isAble( 'notUnderTest', 'notUnderTest');
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        !assertionThrown,
        'Parameter was undefined'
    );
});

test( 'isAble() 3rd parameter is provided - value is used in addition to Behavior data to make a determination', function( assert ) {
    BS.setBehaviors({
        device: {
            reboot: true
        }
    });

    assert.ok(
        !BS.isAble( 'reboot', 'device', false ),
        'Was not able'
    );

    assert.ok(
        BS.isAble( 'reboot', 'device', true ),
        'Was able'
    );

    BS.setBehaviors({
        device: {
            reboot: false
        }
    });

    assert.ok(
        !BS.isAble( 'reboot', 'device', true ),
        'Was not able'
    );

    assert.ok(
        !BS.isAble( 'reboot', 'device', false ),
        'Was not able'
    );
});

test( 'isAble() returns false if no Behavior data has been set', function( assert ) {
    assert.ok(
        !BS.isAble( 'reboot', 'device' ),
        'Returned false'
    );

    assert.ok(
        !BS.isAble( 'reboot', 'device', true ),
        'Returned false'
    );
});

test( 'isAble() returns false if specified Behavior Group has not been configured', function( assert ) {
    BS.setBehaviors({
        device: {
            reboot: false
        }
    });

    assert.ok(
        !BS.isAble( 'reboot', 'product' ),
        'Returned false'
    );

    assert.ok(
        !BS.isAble( 'reboot', 'product', true ),
        'Returned false'
    );
});

test( 'isAble() returns false if specified Behavior has not been configured', function( assert ) {
    BS.setBehaviors({
        device: {
            reboot: false
        }
    });

    assert.ok(
        !BS.isAble( 'restart', 'device' ),
        'Returned false'
    );

    assert.ok(
        !BS.isAble( 'restart', 'device', true ),
        'Returned false'
    );
});

test( 'isUnable() is the negated result of a call to isAble()', function( assert ) {
    BS.setBehaviors({
        device: {
            reboot: false
        }
    });

    assert.ok(
        BS.isUnable( 'reboot', 'device', true ),
        'Was unable'
    );

    BS.setBehaviors({
        device: {
            reboot: true
        }
    });

    assert.ok(
        !BS.isUnable( 'reboot', 'device', true ),
        'Was not unable'
    );

    assert.ok(
        BS.isUnable( 'reboot', 'device', false ),
        'Was unable'
    );
});
<commit_msg>Closes softlayer/sl-ember-behavior#63<commit_after>import Ember from 'ember';
import BehaviorService from 'sl-ember-behavior/services/sl-behavior';
import { moduleFor, test } from 'ember-qunit';

let BS;

moduleFor( 'service:sl-behavior', 'Unit | Service | sl behavior', {
    unit: true,

    beforeEach() {
        BS = BehaviorService.create();
    }
});

test( '"behaviors" property defaults to null', function( assert ) {
    assert.equal(
        BS.get( 'behaviors' ),
        null
    );
});

test( 'setBehaviors() requires an Object to be provided', function( assert ) {

    // Empty parameter

    let assertionThrown = false;

    try {
        BS.setBehaviors();
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was empty'
    );

    // null parameter

    assertionThrown = false;

    try {
        BS.setBehaviors( null );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was null'
    );

    // Number parameter

    assertionThrown = false;

    try {
        BS.setBehaviors( 4 );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was a Number'
    );

    // Boolean parameter

    assertionThrown = false;

    try {
        BS.setBehaviors( false );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was a Boolean'
    );

    // Array Parameter

    assertionThrown = false;

    try {
        BS.setBehaviors( [] );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was an Array'
    );

    // Function

    assertionThrown = false;

    try {
        BS.getBehaviorGroup( function(){} );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was a Function'
    );

    // String Parameter

    assertionThrown = false;

    try {
        BS.setBehaviors( 'test' );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was a String'
    );

    // Object Parameter

    assertionThrown = false;

    try {
        BS.setBehaviors( {} );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        !assertionThrown,
        'Parameter was an Object'
    );
});

test( 'setBehaviors() sets data on the behaviors property', function( assert ) {
    let testBehaviors = {
        'the_key': 'my value'
    };

    BS.setBehaviors( testBehaviors );

    assert.deepEqual(
        BS.get( 'behaviors' ),
        testBehaviors
    );
});

test( 'isAble() requires at least two parameters to be provided', function( assert ) {

    // No arguments

    let assertionThrown = false;

    try {
        BS.isAble();
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'No parameters were provided'
    );

    // One argument

    assertionThrown = false;

    try {
        BS.isAble( 'one' );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'One parameter was provided'
    );

    // Two arguments

    assertionThrown = false;

    try {
        BS.isAble( 'one', 'two' );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        !assertionThrown,
        'Two parameters were provided'
    );

    // Three arguments

    assertionThrown = false;

    try {
        BS.isAble( 'one', 'two', false );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        !assertionThrown,
        'Three parameters were provided'
    );
});

test( 'isAble() requires first parameter to be a String', function( assert ) {
    // Empty parameter

    let assertionThrown = false;

    try {
        BS.isAble();
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was empty'
    );

    // null parameter

    assertionThrown = false;

    try {
        BS.isAble( null, 'notUnderTest' );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was null'
    );

    // Number parameter

    assertionThrown = false;

    try {
        BS.isAble( 4, 'notUnderTest' );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was a Number'
    );

    // Boolean parameter

    assertionThrown = false;

    try {
        BS.isAble( false, 'notUnderTest' );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was a Boolean'
    );

    // Array Parameter

    assertionThrown = false;

    try {
        BS.isAble( [], 'notUnderTest' );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was an Array'
    );

    // Function

    assertionThrown = false;

    try {
        BS.getBehaviorGroup( function(){} );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was a Function'
    );

    // String Parameter

    assertionThrown = false;

    try {
        BS.isAble( {}, 'notUnderTest' );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was an Object'
    );

    // Object Parameter

    assertionThrown = false;

    try {
        BS.isAble( 'test', 'notUnderTest' );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        !assertionThrown,
        'Parameter was a String'
    );
});

test( 'isAble() requires second argument to be a String', function( assert ) {
    // Number parameter

    let assertionThrown = false;

    try {
        BS.isAble( 'notUnderTest', 4 );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was a Number'
    );

    // null parameter

    assertionThrown = false;

    try {
        BS.isAble( 'notUnderTest', null );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was null'
    );

    // Boolean parameter

    assertionThrown = false;

    try {
        BS.isAble( 'notUnderTest', false );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was a Boolean'
    );

    // Array Parameter

    assertionThrown = false;

    try {
        BS.isAble( 'notUnderTest', [] );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was an Array'
    );

    // Function

    assertionThrown = false;

    try {
        BS.getBehaviorGroup( function(){} );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was a Function'
    );

    // String Parameter

    assertionThrown = false;

    try {
        BS.isAble( 'notUnderTest', 'test' );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        !assertionThrown,
        'Parameter was a String'
    );

    // Object Parameter

    assertionThrown = false;

    BS.getBehaviorGroup = function() {
        return true;
    };

    try {
        BS.isAble( 'notUnderTest', {} );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was an Object'
    );
});

test( 'isAble() requires third argument to be a boolean or undefined', function( assert ) {
    // Number parameter

    let assertionThrown = false;

    try {
        BS.isAble( 'notUnderTest', 'notUnderTest', 4 );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was a Number'
    );

    // Boolean parameter

    assertionThrown = false;

    try {
        BS.isAble( 'notUnderTest', 'notUnderTest', false );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        !assertionThrown,
        'Parameter was a Boolean'
    );

    // Array Parameter

    assertionThrown = false;

    try {
        BS.isAble( 'notUnderTest', 'notUnderTest', [] );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was an Array'
    );

    // Function

    assertionThrown = false;

    try {
        BS.isAble( 'notUnderTest', 'notUnderTest', function(){} );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was a Function'
    );

    // String Parameter

    assertionThrown = false;

    try {
        BS.isAble( 'notUnderTest', 'notUnderTest', 'test' );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was a String'
    );

    // Object Parameter

    assertionThrown = false;

    BS.getBehaviorGroup = function() {
        return true;
    };

    try {
        BS.isAble( 'notUnderTest', 'notUnderTest', {} );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        assertionThrown,
        'Parameter was an Object'
    );

    // No Parameter

    assertionThrown = false;

    BS.getBehaviorGroup = function() {
        return true;
    };

    try {
        BS.isAble( 'notUnderTest', 'notUnderTest' );
    } catch( error ) {
        assertionThrown = true;
    }

    assert.ok(
        !assertionThrown,
        'Parameter was undefined'
    );
});

test( 'isAble() 3rd parameter is provided - value is used in addition to Behavior data to make a determination', function( assert ) {
    BS.setBehaviors({
        device: {
            reboot: true
        }
    });

    assert.ok(
        !BS.isAble( 'reboot', 'device', false ),
        'Was not able'
    );

    assert.ok(
        BS.isAble( 'reboot', 'device', true ),
        'Was able'
    );

    BS.setBehaviors({
        device: {
            reboot: false
        }
    });

    assert.ok(
        !BS.isAble( 'reboot', 'device', true ),
        'Was not able'
    );

    assert.ok(
        !BS.isAble( 'reboot', 'device', false ),
        'Was not able'
    );
});

test( 'isAble() returns false if no Behavior data has been set', function( assert ) {
    assert.ok(
        !BS.isAble( 'reboot', 'device' ),
        'Returned false'
    );

    assert.ok(
        !BS.isAble( 'reboot', 'device', true ),
        'Returned false'
    );
});

test( 'isAble() returns false if specified Behavior Group has not been configured', function( assert ) {
    BS.setBehaviors({
        device: {
            reboot: false
        }
    });

    assert.ok(
        !BS.isAble( 'reboot', 'product' ),
        'Returned false'
    );

    assert.ok(
        !BS.isAble( 'reboot', 'product', true ),
        'Returned false'
    );
});

test( 'isAble() returns false if specified Behavior has not been configured', function( assert ) {
    BS.setBehaviors({
        device: {
            reboot: false
        }
    });

    assert.ok(
        !BS.isAble( 'restart', 'device' ),
        'Returned false'
    );

    assert.ok(
        !BS.isAble( 'restart', 'device', true ),
        'Returned false'
    );
});

test( 'isUnable() is the negated result of a call to isAble()', function( assert ) {
    BS.setBehaviors({
        device: {
            reboot: false
        }
    });

    assert.ok(
        BS.isUnable( 'reboot', 'device', true ),
        'Was unable'
    );

    BS.setBehaviors({
        device: {
            reboot: true
        }
    });

    assert.ok(
        !BS.isUnable( 'reboot', 'device', true ),
        'Was not unable'
    );

    assert.ok(
        BS.isUnable( 'reboot', 'device', false ),
        'Was unable'
    );
});
<|endoftext|>


<commit_before>import { componentTypes, validatorTypes } from '@@ddf';
import { API } from '../../http_api';

const emsUrl = '/api/providers?expand=resources&attributes=id,name,supports_cloud_subnet_create&filter[]=supports_cloud_subnet_create=true';
const networkManagers = API.get(emsUrl).then(({ resources }) => {
  let networkManagersOptions = [];
  networkManagersOptions = resources.map(({ id, name }) => ({ label: name, value: id }));
  networkManagersOptions.unshift({ label: `<${__('Choose')}>`, value: '-1' });
  return networkManagersOptions;
});

let empty = true;
let showError = false;

const createSchema = (edit, fields = [], loadSchema, emptySchema) => ({
  fields: [
    {
      component: componentTypes.SELECT,
      name: 'ems_id',
      id: 'ems_id',
      label: __('Network Manager'),
      onChange: (value) => {
        if (value !== '-1') {
          API.options(`/api/cloud_subnets?ems_id=${value}`).then(loadSchema());
          empty = false;
          showError = false;
        } else {
          emptySchema();
          empty = true;
          showError = true;
        }
      },
      loadOptions: () => networkManagers,
      isDisabled: edit,
      isRequired: true,
      validate: [{ type: validatorTypes.REQUIRED }],
    },
    ...(!empty ? [
      {
        component: componentTypes.TEXT_FIELD,
        name: 'name',
        id: 'name',
        label: __('Name'),
        isRequired: true,
        validate: [{ type: validatorTypes.REQUIRED }],
        condition: {
          when: 'ems_id',
          isNotEmpty: true,
        },
      },
      {
        component: componentTypes.TEXT_FIELD,
        name: 'cidr',
        id: 'cidr',
        label: __('CIDR'),
        isRequired: true,
        isDisabled: edit,
        validate: [{ type: validatorTypes.REQUIRED }], // TODO: pattern for validating IPv4/mask or IPv6/mask
        condition: {
          when: 'ems_id',
          isNotEmpty: true,
        },
      },
      {
        component: componentTypes.FIELD_ARRAY,
        name: 'dns_nameservers',
        id: 'dns_nameservers',
        label: __('DNS Servers'),
        noItemsMessage: __('None'),
        buttonLabels: {
          add: __('Add'),
          remove: __('Remove'),
        },
        AddButtonProps: {
          size: 'small',
        },
        RemoveButtonProps: {
          size: 'small',
        },
        fields: [{ // TODO: pattern for validating IPv4 or IPv6
          component: componentTypes.TEXT_FIELD,
        }],
        condition: {
          when: 'ems_id',
          isNotEmpty: true,
        },
      },
    ] : []),
    ...(showError ? [
      {
        id: 'networkWarning',
        component: componentTypes.PLAIN_TEXT,
        name: 'networkWarning',
        label: __('Please select a network manager.'),
      },
    ] : []),
    ...fields,
  ],
});

export default createSchema;
<commit_msg>Fixed subnet form issue<commit_after>import { componentTypes, validatorTypes } from '@@ddf';
import { API } from '../../http_api';

const emsUrl = '/api/providers?expand=resources&attributes=id,name,supports_cloud_subnet_create&filter[]=supports_cloud_subnet_create=true';
const networkManagers = () => API.get(emsUrl).then(({ resources }) => {
  let networkManagersOptions = [];
  networkManagersOptions = resources.map(({ id, name }) => ({ label: name, value: id }));
  networkManagersOptions.unshift({ label: `<${__('Choose')}>`, value: '-1' });
  return networkManagersOptions;
});

let empty = true;
let showError = false;

const createSchema = (edit, fields = [], loadSchema, emptySchema) => ({
  fields: [
    {
      component: componentTypes.SELECT,
      name: 'ems_id',
      id: 'ems_id',
      label: __('Network Manager'),
      onChange: (value) => {
        if (value !== '-1') {
          API.options(`/api/cloud_subnets?ems_id=${value}`).then(loadSchema());
          empty = false;
          showError = false;
        } else {
          emptySchema();
          empty = true;
          showError = true;
        }
      },
      loadOptions: networkManagers,
      isDisabled: edit,
      isRequired: true,
      validate: [{ type: validatorTypes.REQUIRED }],
    },
    ...(!empty ? [
      {
        component: componentTypes.TEXT_FIELD,
        name: 'name',
        id: 'name',
        label: __('Name'),
        isRequired: true,
        validate: [{ type: validatorTypes.REQUIRED }],
        condition: {
          when: 'ems_id',
          isNotEmpty: true,
        },
      },
      {
        component: componentTypes.TEXT_FIELD,
        name: 'cidr',
        id: 'cidr',
        label: __('CIDR'),
        isRequired: true,
        isDisabled: edit,
        validate: [{ type: validatorTypes.REQUIRED }], // TODO: pattern for validating IPv4/mask or IPv6/mask
        condition: {
          when: 'ems_id',
          isNotEmpty: true,
        },
      },
      {
        component: componentTypes.FIELD_ARRAY,
        name: 'dns_nameservers',
        id: 'dns_nameservers',
        label: __('DNS Servers'),
        noItemsMessage: __('None'),
        buttonLabels: {
          add: __('Add'),
          remove: __('Remove'),
        },
        AddButtonProps: {
          size: 'small',
        },
        RemoveButtonProps: {
          size: 'small',
        },
        fields: [{ // TODO: pattern for validating IPv4 or IPv6
          component: componentTypes.TEXT_FIELD,
        }],
        condition: {
          when: 'ems_id',
          isNotEmpty: true,
        },
      },
    ] : []),
    ...(showError ? [
      {
        id: 'networkWarning',
        component: componentTypes.PLAIN_TEXT,
        name: 'networkWarning',
        label: __('Please select a network manager.'),
      },
    ] : []),
    ...fields,
  ],
});

export default createSchema;
<|endoftext|>


<commit_before>'use strict'

module.exports = function (mongoose, config, db) {
    const utils = require('../lib/utils')();

    function commentResponse(comment, _user) {
        const user = _user || comment.user;
        return {
            id: comment.id,
            created_at: comment.created_at,
            user_id: comment.user_id,
            user: {
                id: user.id,
                name: user.name,
                email: user.email
            },
            target_article_id: comment.target_article_id,
            target_id: comment.target_id,
            content: comment.content
        }
    }

    function createComment(res, content, user, article, target) {
        db.Sequence.getNextSequence('comment', (err, nextCommentId) => {
            const comment = db.Comment({
                nextCommentId,
                user_id: user.id,
                user,
                target_article_id: article.id,
                article,
                target_id: target ? target.id : 0,
                target,
                content
            });
            comment.save(err => err ?
                utils.error(res, 422, err.message) :
                utils.success(res, "update success!", commentResponse(comment, user))
                )
        });
    }

    return {
        create(req, res) {
            db.Article.findOne({ id: req.body.article }, (err, article) => {
                if (err) return utils.error(res, 422, err);
                if (!article) return utils.error(res, 404);
                if (req.body.target) {
                    db.Comment.findOne({ id: req.body.target }, (err, target) =>
                        createComment(res, req.body.content, req.user, article, target));
                } else {
                    createComment(res, req.body.content, req.user, article);
                }
            });
        },

        delete(req, res) {
            db.Comment.findOne({ id: req.params.commentId }).populate('target_article').populate('target').exec((err, comment) => {
                if (err) return utils.error(res, 422, err);
                if (comment.user_id != req.user.id
                    || comment.target_article.user_id != req.user.id
                    || comment.target.user_id != req.user.id) return utils.error(res, 403, "Forbidden");
                if (!comment) return utils.error(res, 404);
                comment.remove(err => err ? utils.error(res, 422) : utils.success(res));
            })
        },

        get(req, res) {
            const id = req.params.commentId;
            let query = {};
            let sortBy = null;

            if (id) {
                query = { id };
            } else {
                sortBy = {};
                sortBy["order_by"] = "created_at";
                sortBy["order_type"] = "desc";
                if (req.query.user_id) query["user_id"] = req.query.user_id;
                if (req.query.target_article_id) query["target_article_id"] = req.query.target_article_id;
                if (req.query.target_id) query["target_id"] = req.query.target_id;
            }

            const queryRequest = db.Comment.find(query);
            if (sortBy) {
                var sort = {};
                sort[sortBy["order_by"]] = sortBy["order_type"] === "asc" ? "ascending" : "descending";
                queryRequest.sort(sort);
            }

            queryRequest.populate('user').populate('target_article').populate('target').exec((err, dbResponse) => {
                if (err) return utils.error(res, 422, err.message);
                if (!dbResponse) return utils.error(res, 404);
                utils.responseData(res, dbResponse.count, dbResponse.map(article => commentResponse(article)));
            })
        }
    }
}<commit_msg>debug<commit_after>'use strict'

module.exports = function (mongoose, config, db) {
    const utils = require('../lib/utils')();

    function commentResponse(comment, _user) {
        const user = _user || comment.user;
        return {
            id: comment.id,
            created_at: comment.created_at,
            user_id: comment.user_id,
            user: {
                id: user.id,
                name: user.name,
                email: user.email
            },
            target_article_id: comment.target_article_id,
            target_id: comment.target_id,
            content: comment.content
        }
    }

    function createComment(res, content, user, article, target) {
        db.Sequence.getNextSequence('comment', (err, nextCommentId) => {
            const comment = db.Comment({
                nextCommentId,
                user_id: user.id,
                user,
                target_article_id: article.id,
                article,
                target_id: target ? target.id : 0,
                target,
                content
            });
            comment.save(err => err ?
                utils.error(res, 422, err.message) :
                utils.success(res, "update success!", commentResponse(comment, user))
                )
        });
    }

    return {
        create(req, res) {
            db.Article.findOne({ id: req.body.article }, (err, article) => {
                if (err) return utils.error(res, 422, err);
                if (!article) return utils.error(res, 404);
                if (req.body.target) {
                    db.Comment.findOne({ id: req.body.target }, (err, target) =>
                        createComment(res, req.body.content, req.user, article, target));
                } else {
                    createComment(res, req.body.content, req.user, article);
                }
            });
        },

        delete(req, res) {
            db.Comment.findOne({ id: req.params.commentId }).populate('target_article').populate('target').exec((err, comment) => {
                if (err) return utils.error(res, 422, err);
                if (comment.user_id != req.user.id
                    || comment.target_article.user_id != req.user.id
                    || comment.target.user_id != req.user.id) return utils.error(res, 403, "Forbidden");
                if (!comment) return utils.error(res, 404);
                comment.remove(err => err ? utils.error(res, 422) : utils.success(res));
            })
        },

        get(req, res) {
            const id = req.params.commentId;
            let query = {};
            let sortBy = null;

            if (id) {
                query = { id };
            } else {
                sortBy = {};
                sortBy["order_by"] = "created_at";
                sortBy["order_type"] = "desc";
                if (req.query.user_id) query["user_id"] = req.query.user_id;
                if (req.query.target_article_id) query["target_article_id"] = req.query.target_article_id;
                if (req.query.target_id) query["target_id"] = req.query.target_id;
            }

            const queryRequest = db.Comment.find(query);
            if (sortBy) {
                var sort = {};
                sort[sortBy["order_by"]] = sortBy["order_type"] === "asc" ? "ascending" : "descending";
                queryRequest.sort(sort);
            }

            queryRequest.populate('user').populate('target_article').populate('target').exec((err, dbResponse) => {
                if (err) return utils.error(res, 422, err.message);
                if (!dbResponse) return utils.error(res, 404);
                console.log('response', dbResponse);
                utils.responseData(res, dbResponse.count, dbResponse.map(article => commentResponse(article)));
            })
        }
    }
}<|endoftext|>


<commit_before>var nodemailer = require('nodemailer'),
    debug = require('debug')('freecc:cntr:contact'),
    secrets = require('../config/secrets');

var transporter = nodemailer.createTransport({
  service: 'Mandrill',
  auth: {
    user: secrets.mandrill.user,
    pass: secrets.mandrill.password
  }
});

/**
 * GET /contact
 * Contact form page.
 */

exports.getContact = function(req, res) {
  res.render('contact', {
    title: 'Free Code Work for Nonprofits Project Submission Page'
  });
};

/**
 * POST /contact
 * Send a contact form via Nodemailer.
 */

exports.postContact = function(req, res) {
  req.assert('name', 'Name cannot be blank').notEmpty();
  req.assert('email', 'Email is not valid').isEmail();
  req.assert('message', 'Message cannot be blank').notEmpty();

  if (req.validationErrors()) {
    req.flash('errors', errors);
    return res.redirect('/nonprofits');
  }

  var mailOptions = {
    to: 'team@freecodecamp.com',
    name: req.body.name,
    from: req.body.email,
    subject: 'CodeNonprofit Project Idea from ' + name,
    text: req.body.message
  };

  transporter.sendMail(mailOptions, function(err) {
    if (err) {
      req.flash('errors', { msg: err.message });
      return res.redirect('/nonprofits');
    }
    req.flash('success', { msg: 'Email has been sent successfully!' });
    res.redirect('/nonprofits');
  });
};
<commit_msg>fix an error introduced when the contact.js controller was refactored<commit_after>var nodemailer = require('nodemailer'),
    debug = require('debug')('freecc:cntr:contact'),
    secrets = require('../config/secrets');

var transporter = nodemailer.createTransport({
  service: 'Mandrill',
  auth: {
    user: secrets.mandrill.user,
    pass: secrets.mandrill.password
  }
});

/**
 * GET /contact
 * Contact form page.
 */

exports.getContact = function(req, res) {
  res.render('contact', {
    title: 'Free Code Work for Nonprofits Project Submission Page'
  });
};

/**
 * POST /contact
 * Send a contact form via Nodemailer.
 */

exports.postContact = function(req, res) {
  req.assert('name', 'Name cannot be blank').notEmpty();
  req.assert('email', 'Email is not valid').isEmail();
  req.assert('message', 'Message cannot be blank').notEmpty();

  if (req.validationErrors()) {
    req.flash('errors', errors);
    return res.redirect('/nonprofits');
  }

  var mailOptions = {
    to: 'team@freecodecamp.com',
    name: req.body.name,
    from: req.body.email,
    subject: 'CodeNonprofit Project Idea from ' + req.body.name,
    text: req.body.message
  };

  transporter.sendMail(mailOptions, function(err) {
    if (err) {
      req.flash('errors', { msg: err.message });
      return res.redirect('/nonprofits');
    }
    req.flash('success', { msg: 'Email has been sent successfully!' });
    res.redirect('/nonprofits');
  });
};
<|endoftext|>


<commit_before>var secrets = require('../config/secrets');
var sendgrid  = require('sendgrid')(secrets.sendgrid.user, secrets.sendgrid.password);

/**
 * GET /contact
 * Contact form page.
 */

exports.getContact = function(req, res) {
  res.render('contact', {
    title: 'Contact',
    success: req.flash('success'),
    errors: req.flash('errors')
  });
};

/**
 * POST /contact
 * Send a contact form via SendGrid.
 * @param {string} email
 * @param {string} name
 * @param {string} message
 */

exports.postContact = function(req, res) {
  req.assert('name', 'Name cannot be blank').notEmpty();
  req.assert('email', 'Email cannot be blank').notEmpty();
  req.assert('email', 'Email is not valid').isEmail();
  req.assert('message', 'Message cannot be blank').notEmpty();

  var errors = req.validationErrors();

  if (errors) {
    req.flash('errors', errors);
    return res.redirect('/contact');
  }

  var from = req.body.email;
  var name = req.body.name;
  var body = req.body.message;
  var to = 'you@email.com';
  var subject = 'API Example | Contact Form';

  var email = new sendgrid.Email({
    to: to,
    from: from,
    subject: subject,
    text: body + '\n\n' + name
  });

  sendgrid.send(email, function(err) {
    if (err) {
      req.flash('errors', err.message);
      return res.redirect('/contact');
    }
    req.flash('success', 'Email has been sent successfully!');
    res.redirect('/contact');
  });
};
<commit_msg>Mapped sengrid error message to msg property so it matches express-validator<commit_after>var secrets = require('../config/secrets');
var sendgrid  = require('sendgrid')(secrets.sendgrid.user, secrets.sendgrid.password);

/**
 * GET /contact
 * Contact form page.
 */

exports.getContact = function(req, res) {
  res.render('contact', {
    title: 'Contact',
    success: req.flash('success'),
    errors: req.flash('errors')
  });
};

/**
 * POST /contact
 * Send a contact form via SendGrid.
 * @param {string} email
 * @param {string} name
 * @param {string} message
 */

exports.postContact = function(req, res) {
  req.assert('name', 'Name cannot be blank').notEmpty();
  req.assert('email', 'Email cannot be blank').notEmpty();
  req.assert('email', 'Email is not valid').isEmail();
  req.assert('message', 'Message cannot be blank').notEmpty();

  var errors = req.validationErrors();

  if (errors) {
    req.flash('errors', errors);
    return res.redirect('/contact');
  }

  var from = req.body.email;
  var name = req.body.name;
  var body = req.body.message;
  var to = 'you@email.com';
  var subject = 'API Example | Contact Form';

  var email = new sendgrid.Email({
    to: to,
    from: from,
    subject: subject,
    text: body + '\n\n' + name
  });

  sendgrid.send(email, function(err) {
    if (err) {
      req.flash('errors', { msg: err.message });
      return res.redirect('/contact');
    }
    req.flash('success', 'Email has been sent successfully!');
    res.redirect('/contact');
  });
};
<|endoftext|>


<commit_before>const nodemailer = require('nodemailer');

const transporter = nodemailer.createTransport({
  service: 'SendGrid',
  auth: {
    user: process.env.SENDGRID_USER,
    pass: process.env.SENDGRID_PASSWORD
  }
});

/**
 * GET /contact
 * Contact form page.
 */
let fs = require('fs');
let notice = '';

exports.getContact = (req, res) => {
  fs.readFile('notice.data', 'utf8', function (err, data) {
    if (err) throw err;
    // if (!fs.isEmptySync('./data/currPrdt.data'))
    notice = data;
    // if(!isJSON(data)) {
    //   console.log('data: ' + data);
    //   products = [];
    //   nextSale = data.toString();
    // } else
    //   products = Array.from(JSON.parse(data).items);
      res.render('contact', {
      title: 'contact',
      notice,
    });
  });
};

/**
 * POST /contact
 * Send a contact form via Nodemailer.
 */
exports.postContact = (req, res) => {

  // console.log(req.body.message);
  fs.writeFile('notice.data', req.body.message, (err) => {
    if (err) throw err;
    console.log('The file has been saved!');
    req.flash('success', { msg:'Submitted successfully. | 您已经成功提交!' });
    res.redirect('/contact');
  });

//   req.assert('name', 'Name cannot be blank').notEmpty();
//   req.assert('email', 'Email is not valid').isEmail();
//   req.assert('message', 'Message cannot be blank').notEmpty();

//   const errors = req.validationErrors();

//   if (errors) {
//     req.flash('errors', errors);
//     return res.redirect('/contact');
//   }

//   const mailOptions = {
//     to: 'your@email.com',
//     from: `${req.body.name} <${req.body.email}>`,
//     subject: 'Contact Form | Hackathon Starter',
//     text: req.body.message
//   };

//   transporter.sendMail(mailOptions, (err) => {
//     if (err) {
//       req.flash('errors', { msg: err.message });
//       return res.redirect('/contact');
//     }
//     req.flash('success', { msg: 'Email has been sent successfully!' });
//     res.redirect('/contact');
//   });
//
 };
<commit_msg>./notice.data updated<commit_after>const nodemailer = require('nodemailer');

const transporter = nodemailer.createTransport({
  service: 'SendGrid',
  auth: {
    user: process.env.SENDGRID_USER,
    pass: process.env.SENDGRID_PASSWORD
  }
});

/**
 * GET /contact
 * Contact form page.
 */
let fs = require('fs');
let notice = '';

exports.getContact = (req, res) => {
  fs.readFile('/notice.data', 'utf8', function (err, data) {
    if (err) throw err;
    // if (!fs.isEmptySync('./data/currPrdt.data'))
    notice = data;
    // if(!isJSON(data)) {
    //   console.log('data: ' + data);
    //   products = [];
    //   nextSale = data.toString();
    // } else
    //   products = Array.from(JSON.parse(data).items);
      res.render('contact', {
      title: 'contact',
      notice,
    });
  });
};

/**
 * POST /contact
 * Send a contact form via Nodemailer.
 */
exports.postContact = (req, res) => {

  // console.log(req.body.message);
  fs.writeFile('/notice.data', req.body.message, (err) => {
    if (err) throw err;
    console.log('The file has been saved!');
    req.flash('success', { msg:'Submitted successfully. | 您已经成功提交!' });
    res.redirect('/contact');
  });

//   req.assert('name', 'Name cannot be blank').notEmpty();
//   req.assert('email', 'Email is not valid').isEmail();
//   req.assert('message', 'Message cannot be blank').notEmpty();

//   const errors = req.validationErrors();

//   if (errors) {
//     req.flash('errors', errors);
//     return res.redirect('/contact');
//   }

//   const mailOptions = {
//     to: 'your@email.com',
//     from: `${req.body.name} <${req.body.email}>`,
//     subject: 'Contact Form | Hackathon Starter',
//     text: req.body.message
//   };

//   transporter.sendMail(mailOptions, (err) => {
//     if (err) {
//       req.flash('errors', { msg: err.message });
//       return res.redirect('/contact');
//     }
//     req.flash('success', { msg: 'Email has been sent successfully!' });
//     res.redirect('/contact');
//   });
//
 };
<|endoftext|>