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

    var module = angular.module('billett.admin');

    module.controller('AdminOrderController', function ($http, $modal, $q, $state, $stateParams, Page, AdminOrder) {
        var ctrl = this;
        Page.setTitle("Ordre");

        var loadOrder = function () {
            return AdminOrder.get({id: $stateParams['id']}, function(ret) {
                ctrl.order = ret;

                // calc order total and generate list of valid tickets
                ctrl.validtickets = [];
                ctrl.total = 0;
                ctrl.total_reserved = 0;
                ctrl.ticketcount = {
                    'reserved': 0,
                    'revoked': 0,
                    'valid': 0
                };
                ctrl.order.tickets.forEach(function (ticket) {
                    if (!ticket.is_valid) {
                        ctrl.total_reserved += ticket.ticketgroup.price + ticket.ticketgroup.fee;
                        ctrl.ticketcount.reserved++;
                    } else if (!ticket.is_revoked) {
                        ctrl.total += ticket.ticketgroup.price + ticket.ticketgroup.fee;
                        ctrl.validtickets.push(ticket.id);
                        ctrl.ticketcount.valid++;
                    } else {
                        ctrl.ticketcount.revoked++;
                    }
                });

                // total paid amount
                ctrl.total_paid = 0;
                ctrl.order.payments.forEach(function (payment) {
                    ctrl.total_paid += 1*payment.amount;
                });
            }).$promise;
        };

        var loader = Page.setLoading();
        loadOrder().then(function () {
            loader();
        }, function() {
            loader();
            Page.set404();
        });

        var editFields = ['name', 'email', 'phone', 'recruiter', 'comment'];

        // start edit mode (order details)
        ctrl.startEdit = function () {
            ctrl.edit = editFields.reduce(function (prev, cur) {
                prev[cur] = ctrl.order[cur];
                return prev;
            }, {});
        };

        // abort edit mode (order details)
        ctrl.abortEdit = function () {
            delete ctrl.edit;
        };

        // save order details when editing
        ctrl.save = function () {
            editFields.forEach(function (field) {
                ctrl.order[field] = ctrl.edit[field];
            });
            ctrl.order.$update(function (ret) {
                ctrl.order = ret;
                delete ctrl.edit;
            });
        };

        // delete reservation (of order)
        ctrl.deleteReservation = function () {
            var eventgroup_id = ctrl.order.eventgroup.id;
            ctrl.order.$delete(function () {
                $state.go('admin-orders', {eventgroup_id: eventgroup_id});
            }, function () {
                alert("Feil ved sletting av ordre");
            });
        };

        ctrl.completeOrder = function () {
            var modal = $modal.open({
                templateUrl: 'assets/views/admin/paymentgroup/paymentgroup_select.html',
                controller: 'AdminPaymentgroupSelectController as ctrl',
                resolve: {
                    order: function () {
                        return ctrl.order;
                    },
                    actionText: function () {
                        return 'Marker som betalt';
                    },
                    amount: function () {
                        return ctrl.total_reserved;
                    }
                }
            });

            modal.result.then(function (paymentgroup) {
                $http.post('api/order/'+ctrl.order.id+'/validate', {
                    paymentgroup: paymentgroup.id,
                    amount: ctrl.total_reserved,
                    sendmail: false
                }).success(function () {
                    loadOrder();
                }).error(function (err) {
                    if (err == 'amount mismatched') {
                        alert("Noe i ordren ser ut til å ha endret seg. Prøv på nytt.");
                        loadOrder();
                    } else {
                        alert(err);
                    }
                });
            });
        };

        ctrl.convertOrder = function () {
            $http.post('api/order/'+ctrl.order.id+'/validate').success(function () {
                loadOrder();
            }).error(function (err) {
                alert(err);
            });
        };

        // start new tickets form
        ctrl.addTickets = function () {
            var modal = $modal.open({
                templateUrl: 'assets/views/admin/ticketgroup/add_ticketgroup_to_order.html',
                controller: 'AdminTicketgroupAddToOrderController as ctrl',
                resolve: {
                    eventgroup_id: function () {
                        return ctrl.order.eventgroup.id;
                    },
                    getOrder: function () {
                        return ctrl.order;
                    },
                    addHandler: function () {
                        return function (ticketgroups) {
                            return $q(function (resolve, reject) {
                                // reload order with new data
                                loadOrder().then(function () {
                                    resolve();
                                }, function () {
                                    alert("Ukjent feil oppsto ved forsøk på å laste ordren på nytt");
                                    resolve(); // consider it a success anyways
                                });
                            });
                        }
                    }
                }
            });
        };

        // revoke specific ticket
        ctrl.revokeTicket = function (ticket) {
            var modal = $modal.open({
                templateUrl: 'assets/views/admin/ticket/ticket_revoke_modal.html',
                controller: 'AdminTicketRevokeController as ctrl',
                resolve: {
                    order: function () {
                        return ctrl.order;
                    },
                    ticket: function () {
                        return ticket;
                    }
                }
            });

            modal.result.then(function () {
                loadOrder();
            });
        };

        // validate specific ticket
        ctrl.validateTicket = function (ticket) {
            var modal = $modal.open({
                templateUrl: 'assets/views/admin/paymentgroup/paymentgroup_select.html',
                controller: 'AdminPaymentgroupSelectController as ctrl',
                resolve: {
                    order: function () {
                        return ctrl.order;
                    },
                    actionText: function () {
                        return 'Marker som betalt';
                    },
                    amount: function () {
                        return ticket.ticketgroup.price + ticket.ticketgroup.fee;
                    }
                }
            });

            modal.result.then(function (paymentgroup) {
                $http.post('api/ticket/'+ticket.id+'/validate', {
                    paymentgroup_id: paymentgroup.id
                }).success(function () {
                    loadOrder();
                }).error(function (err) {
                    alert(err);
                });
            });
        };

        // delete ticket reservation
        ctrl.deleteTicket = function (ticket) {
            $http.delete('api/ticket/' + ticket.id).success(function () {
                console.log("ticket deleted");
            }).finally(function () {
                loadOrder();
            });
        };

        // start new payment form
        ctrl.newPayment = function () {
            var modal = $modal.open({
                templateUrl: 'assets/views/admin/payment/payment_add.html',
                controller: 'AdminPaymentAddController as ctrl',
                resolve: {
                    order: function () {
                        return ctrl.order;
                    }
                }
            });

            modal.result.then(function (payment) {
                loadOrder();
            });
        };

        // send email
        ctrl.email = function () {
            var modal = $modal.open({
                templateUrl: 'assets/views/admin/order/email_modal.html',
                controller: 'AdminOrderEmailController as ctrl',
                resolve: {
                    order: function () {
                        return ctrl.order;
                    }
                }
            });

            modal.result.then(function () {
                Page.toast("E-post ble sendt", {class: 'success'});
            });
        };
    });
})();
<commit_msg>Fix add tickets to existing order<commit_after>(function() {
    'use strict';

    var module = angular.module('billett.admin');

    module.controller('AdminOrderController', function ($http, $modal, $q, $state, $stateParams, Page, AdminOrder) {
        var ctrl = this;
        Page.setTitle("Ordre");

        var loadOrder = function () {
            return AdminOrder.get({id: $stateParams['id']}, function(ret) {
                ctrl.order = ret;

                // calc order total and generate list of valid tickets
                ctrl.validtickets = [];
                ctrl.total = 0;
                ctrl.total_reserved = 0;
                ctrl.ticketcount = {
                    'reserved': 0,
                    'revoked': 0,
                    'valid': 0
                };
                ctrl.order.tickets.forEach(function (ticket) {
                    if (!ticket.is_valid) {
                        ctrl.total_reserved += ticket.ticketgroup.price + ticket.ticketgroup.fee;
                        ctrl.ticketcount.reserved++;
                    } else if (!ticket.is_revoked) {
                        ctrl.total += ticket.ticketgroup.price + ticket.ticketgroup.fee;
                        ctrl.validtickets.push(ticket.id);
                        ctrl.ticketcount.valid++;
                    } else {
                        ctrl.ticketcount.revoked++;
                    }
                });

                // total paid amount
                ctrl.total_paid = 0;
                ctrl.order.payments.forEach(function (payment) {
                    ctrl.total_paid += 1*payment.amount;
                });
            }).$promise;
        };

        var loader = Page.setLoading();
        loadOrder().then(function () {
            loader();
        }, function() {
            loader();
            Page.set404();
        });

        var editFields = ['name', 'email', 'phone', 'recruiter', 'comment'];

        // start edit mode (order details)
        ctrl.startEdit = function () {
            ctrl.edit = editFields.reduce(function (prev, cur) {
                prev[cur] = ctrl.order[cur];
                return prev;
            }, {});
        };

        // abort edit mode (order details)
        ctrl.abortEdit = function () {
            delete ctrl.edit;
        };

        // save order details when editing
        ctrl.save = function () {
            editFields.forEach(function (field) {
                ctrl.order[field] = ctrl.edit[field];
            });
            ctrl.order.$update(function (ret) {
                ctrl.order = ret;
                delete ctrl.edit;
            });
        };

        // delete reservation (of order)
        ctrl.deleteReservation = function () {
            var eventgroup_id = ctrl.order.eventgroup.id;
            ctrl.order.$delete(function () {
                $state.go('admin-orders', {eventgroup_id: eventgroup_id});
            }, function () {
                alert("Feil ved sletting av ordre");
            });
        };

        ctrl.completeOrder = function () {
            var modal = $modal.open({
                templateUrl: 'assets/views/admin/paymentgroup/paymentgroup_select.html',
                controller: 'AdminPaymentgroupSelectController as ctrl',
                resolve: {
                    order: function () {
                        return ctrl.order;
                    },
                    actionText: function () {
                        return 'Marker som betalt';
                    },
                    amount: function () {
                        return ctrl.total_reserved;
                    }
                }
            });

            modal.result.then(function (paymentgroup) {
                $http.post('api/order/'+ctrl.order.id+'/validate', {
                    paymentgroup: paymentgroup.id,
                    amount: ctrl.total_reserved,
                    sendmail: false
                }).success(function () {
                    loadOrder();
                }).error(function (err) {
                    if (err == 'amount mismatched') {
                        alert("Noe i ordren ser ut til å ha endret seg. Prøv på nytt.");
                        loadOrder();
                    } else {
                        alert(err);
                    }
                });
            });
        };

        ctrl.convertOrder = function () {
            $http.post('api/order/'+ctrl.order.id+'/validate').success(function () {
                loadOrder();
            }).error(function (err) {
                alert(err);
            });
        };

        // start new tickets form
        ctrl.addTickets = function () {
            var modal = $modal.open({
                templateUrl: 'assets/views/admin/ticketgroup/add_ticketgroup_to_order.html',
                controller: 'AdminTicketgroupAddToOrderController as ctrl',
                resolve: {
                    eventgroup_id: function () {
                        return ctrl.order.eventgroup.id;
                    },
                    getOrder: function () {
                        return function () {
                            return $q(function (resolve) {
                                resolve(ctrl.order);
                            });
                        };
                    },
                    addHandler: function () {
                        return function (ticketgroups) {
                            return $q(function (resolve, reject) {
                                // reload order with new data
                                loadOrder().then(function () {
                                    resolve();
                                }, function () {
                                    alert("Ukjent feil oppsto ved forsøk på å laste ordren på nytt");
                                    resolve(); // consider it a success anyways
                                });
                            });
                        }
                    }
                }
            });
        };

        // revoke specific ticket
        ctrl.revokeTicket = function (ticket) {
            var modal = $modal.open({
                templateUrl: 'assets/views/admin/ticket/ticket_revoke_modal.html',
                controller: 'AdminTicketRevokeController as ctrl',
                resolve: {
                    order: function () {
                        return ctrl.order;
                    },
                    ticket: function () {
                        return ticket;
                    }
                }
            });

            modal.result.then(function () {
                loadOrder();
            });
        };

        // validate specific ticket
        ctrl.validateTicket = function (ticket) {
            var modal = $modal.open({
                templateUrl: 'assets/views/admin/paymentgroup/paymentgroup_select.html',
                controller: 'AdminPaymentgroupSelectController as ctrl',
                resolve: {
                    order: function () {
                        return ctrl.order;
                    },
                    actionText: function () {
                        return 'Marker som betalt';
                    },
                    amount: function () {
                        return ticket.ticketgroup.price + ticket.ticketgroup.fee;
                    }
                }
            });

            modal.result.then(function (paymentgroup) {
                $http.post('api/ticket/'+ticket.id+'/validate', {
                    paymentgroup_id: paymentgroup.id
                }).success(function () {
                    loadOrder();
                }).error(function (err) {
                    alert(err);
                });
            });
        };

        // delete ticket reservation
        ctrl.deleteTicket = function (ticket) {
            $http.delete('api/ticket/' + ticket.id).success(function () {
                console.log("ticket deleted");
            }).finally(function () {
                loadOrder();
            });
        };

        // start new payment form
        ctrl.newPayment = function () {
            var modal = $modal.open({
                templateUrl: 'assets/views/admin/payment/payment_add.html',
                controller: 'AdminPaymentAddController as ctrl',
                resolve: {
                    order: function () {
                        return ctrl.order;
                    }
                }
            });

            modal.result.then(function (payment) {
                loadOrder();
            });
        };

        // send email
        ctrl.email = function () {
            var modal = $modal.open({
                templateUrl: 'assets/views/admin/order/email_modal.html',
                controller: 'AdminOrderEmailController as ctrl',
                resolve: {
                    order: function () {
                        return ctrl.order;
                    }
                }
            });

            modal.result.then(function () {
                Page.toast("E-post ble sendt", {class: 'success'});
            });
        };
    });
})();
<|endoftext|>


<commit_before>import test from 'ava'
import fn from './'

test(t => {
  return fn('RichardLitt').then(result => {
    t.is(result[0].login, 'RichardLitt')
  })
})

test(t => {
  return fn('wkjhfw9a987sya323jkbsd7822dfsa').then(result => {
    t.deepEqual(result, [])
  })
})

test(t => {
  return fn(['wkjhfw9a987sya323jkbsd7822dfsa', 'RichardLitt']).then(result => {
    t.deepEqual(result, [])
  })
})

test(t => {
  return fn(['RichardLitt', 'sindresorhus']).then(result => {
    t.is(result[0].login, 'RichardLitt')
    t.is(result[1].login, 'sindresorhus')
  })
})
<commit_msg>tests: Add test descriptions<commit_after>import test from 'ava'
import fn from './'

test('Gets the right user date for a provided user', t => {
  return fn('RichardLitt').then(result => {
    t.is(result[0].login, 'RichardLitt')
  })
})

test('Returns an empty array for an invalid user', t => {
  return fn('wkjhfw9a987sya323jkbsd7822dfsa').then(result => {
    t.deepEqual(result, [])
  })
})

test('Returns only valid information for an array with one invalid user', t => {
  return fn(['wkjhfw9a987sya323jkbsd7822dfsa', 'RichardLitt']).then(result => {
    t.deepEqual(result[0].login, 'RichardLitt')
    t.deepEqual(result.length, 1)
  })
})

test('Returns all data for multiple users', t => {
  return fn(['RichardLitt', 'sindresorhus']).then(result => {
    t.is(result[0].login, 'RichardLitt')
    t.is(result[1].login, 'sindresorhus')
  })
})
<|endoftext|>


<commit_before>/*
 * This file is part of Search NEU and licensed under AGPL3.
 * See the license file in the root folder for details.
 */

import React from 'react';
import PropTypes from 'prop-types';

import RequisiteBranch from '../../../common/classModels/RequisiteBranch';
import Keys from '../../../common/Keys';
import macros from '../macros';

import './BaseClassPanel.scss';

class BaseClassPanel extends React.Component {
  static propTypes = {
    aClass: PropTypes.object.isRequired,
  };

  constructor(props) {
    super(props);

    let sectionsShownByDefault;
    if (this.constructor.sectionsShownByDefault) {
      sectionsShownByDefault = this.constructor.sectionsShownByDefault;
    } else {
      sectionsShownByDefault = macros.sectionsShownByDefault;
    }

    // If this is desktop and there is exactly one section hidden by the button, just show them all.
    if (!macros.isMobile && this.props.aClass.sections.length === sectionsShownByDefault + 1) {
      sectionsShownByDefault++;
    }

    this.state = {
      prereqsPage: 0,
      coreqsPage: 0,
      prereqsForPage: 0,
      optPrereqsForPage: 0,
      renderedSections: this.props.aClass.sections.slice(0, sectionsShownByDefault),
      unrenderedSections: this.props.aClass.sections.slice(sectionsShownByDefault),
    };
  }

  onShowMoreClick = () => {
    macros.log('Adding more sections to the bottom.');

    // Get the length of the our sections
    const rendered = this.state.renderedSections;
    const unrendered = this.state.unrenderedSections;

    const showAmount = (rendered.length > macros.sectionsShowAllThreshold) ?
      unrendered.length : macros.sectionsAddedWhenShowMoreClicked;

    this.setState({
      renderedSections: rendered.concat(unrendered.slice(0, showAmount)),
      unrenderedSections: unrendered.slice(showAmount, unrendered.length),
    });
  }

  // Prevents page reload and fires off new search without reloading.
  onReqClick(reqType, childBranch, event) {
    // Create the React element and add it to retVal
    const searchEvent = new CustomEvent(macros.searchEvent, { detail: `${childBranch.subject} ${childBranch.classId}` });
    window.dispatchEvent(searchEvent);
    event.preventDefault();

    // Rest of this function is analytics
    const classCode = `${childBranch.subject} ${childBranch.classId}`;
    let reqTypeString;

    switch (reqType) {
      case macros.prereqTypes.PREREQ:
        reqTypeString = 'Prerequisite';
        break;
      case macros.prereqTypes.COREQ:
        reqTypeString = 'Corequisite';
        break;
      case macros.prereqTypes.PREREQ_FOR:
        reqTypeString = 'Required Prerequisite For';
        break;
      case macros.prereqTypes.OPT_PREREQ_FOR:
        reqTypeString = 'Optional Prerequisite For';
        break;
      default:
        macros.error('unknown type.', reqType);
    }

    macros.logAmplitudeEvent('Requisite Click', {
      type: reqTypeString,
      subject: childBranch.subject,
      classId: childBranch.classId,
      classCode: classCode,
    });
  }

  // Render the Show More.. Button
  // This is the same on both desktop and mobile.
  getShowMoreButton() {
    if (this.state.unrenderedSections.length <= 0) {
      return null;
    }

    return (

        Show More...

    );
  }

  getCreditsString() {
    // Figure out the credits string
    if (this.props.aClass.maxCredits === this.props.aClass.minCredits) {
      return `${this.props.aClass.minCredits} credits`;
    }
    return `${this.props.aClass.minCredits} to ${this.props.aClass.maxCredits} credits`;
  }

  // The argument wrapper func is optional
  // If it exists, it is called on when formatting the classes
  // It is called with a class
  // and can return either a string or a react element.
  getReqsString(reqType, aClass = this.props.aClass) {
    const retVal = [];

    // Keep track of which subject+classId combonations have been used so far.
    // If you encounter the same subject+classId combo in the same loop, skip the second one.
    // This is because there is no need to show (eg. CS 2500 and CS 2500 (hon)) in the same group
    // because only the subject and the classId are going to be shown.
    const processedSubjectClassIds = {};

    let childNodes;

    if (reqType === macros.prereqTypes.PREREQ) {
      childNodes = aClass.prereqs;
    } else if (reqType === macros.prereqTypes.COREQ) {
      childNodes = aClass.coreqs;
    } else if (reqType === macros.prereqTypes.PREREQ_FOR) {
      if (!aClass.prereqsFor) {
        childNodes = { values:[] };
      } else {
        childNodes = aClass.prereqsFor;
      }
    } else if (reqType === macros.prereqTypes.OPT_PREREQ_FOR) {
      if (!aClass.optPrereqsFor) {
        childNodes = { values:[] };
      } else {
        childNodes = aClass.optPrereqsFor;
      }
    } else {
      macros.error('Invalid prereqType', reqType);
    }

    childNodes.values.forEach((childBranch) => {
      // If the childBranch is a class
      if (!(childBranch instanceof RequisiteBranch)) {
        if (childBranch.isString) {
          // Skip if already seen
          if (processedSubjectClassIds[childBranch.desc]) {
            return;
          }
          processedSubjectClassIds[childBranch.desc] = true;

          retVal.push(childBranch.desc);
        } else {
          // Skip if already seen
          if (processedSubjectClassIds[childBranch.subject + childBranch.classId]) {
            return;
          }
          processedSubjectClassIds[childBranch.subject + childBranch.classId] = true;

          //   href={"/" + encodeURIComponent(childBranch.subject + ' ' + childBranch.classId)}

          // let thethiing ={
          //   host: aClass.host,
          //   termId: aClass.termId,
          //   subject: childBranch.subject,
          //   classUid: childBranch.classUid,
          // };

          // let oldthing = Keys.create(childBranch).getHash();

          // if (oldthing !== Keys.create(thethiing).getHash()) {
          //   debugger
          // }

          // When adding support for right click-> open in new tab, we might also be able to fix the jsx-a11y/anchor-is-valid errors.
          // They are disabled for now.

          const hash = `${childBranch.subject} ${childBranch.classId}`;

          const element = (
             { this.onReqClick(reqType, childBranch, event); } }
              className='reqClassLink'
            >
              {`${childBranch.subject} ${childBranch.classId}`}

          );

          retVal.push(element);
        }
      } else if (reqType === macros.prereqTypes.PREREQ) {
        // Figure out how many unique classIds there are in the prereqs.
        const allClassIds = {};
        for (const node of childBranch.prereqs.values) {
          allClassIds[node.classId] = true;
        }

        // If there is only 1 prereq with a unique classId, don't show the parens.
        if (Object.keys(allClassIds).length === 1) {
          retVal.push(this.getReqsString(macros.prereqTypes.PREREQ, childBranch));
        } else {
          retVal.push(['(', this.getReqsString(macros.prereqTypes.PREREQ, childBranch), ')']);
        }
      } else {
        macros.error('Branch found and parsing coreqs?', childBranch);
      }
    });

    // Now insert the type divider ("and" vs "or") between the elements.
    // If we're parsing prereqsFor, we should use just a comma as a separator.
    // Can't use the join in case the objects are react elements
    if (reqType === macros.prereqTypes.PREREQ_FOR || reqType === macros.prereqTypes.OPT_PREREQ_FOR) {
      for (let i = retVal.length - 1; i >= 1; i--) {
        retVal.splice(i, 0, ', ');
      }
    } else {
      let type;
      if (reqType === macros.prereqTypes.PREREQ) {
        type = aClass.prereqs.type;
      } else if (reqType === macros.prereqTypes.COREQ) {
        type = aClass.coreqs.type;
      }
      for (let i = retVal.length - 1; i >= 1; i--) {
        retVal.splice(i, 0, ` ${type} `);
      }
    }

    if (retVal.length === 0) {
      return (None);
    }

    // retVal = retVal.join(' ' + this.prereqs.type + ' ')

    return retVal;
  }

  /**
   * Returns the 'page' of the specified prerequisite.
   *
   * @param {prereqTypes} prereqType type of prerequisite.
   */
  getStateValue(prereqType) {
    switch (prereqType) {
      case macros.prereqTypes.PREREQ:
        return this.state.prereqsPage;
      case macros.prereqTypes.COREQ:
        return this.state.coreqsPage;
      case macros.prereqTypes.PREREQ_FOR:
        return this.state.prereqsForPage;
      case macros.prereqTypes.OPT_PREREQ_FOR:
        return this.state.optPrereqsForPage;
      default:
        return -1;
    }
  }

  /**
   * Returns how many elements we should return from our array of prerequisites.
   * Note that we mutliply our value by two because every other value is ', '
   * We could probably make this better...
   *
   * @param {prereqTypes} prereqType type of prerequisite.
   */
  getShowAmount(prereqType) {
    const classesShownByDefault = 5;
    const stateValue = this.getStateValue(prereqType);
    return 2 * classesShownByDefault * (stateValue + 1);
  }

  /**
   * Returns the array that we should be displaying
   *
   * @param {prereqTypes} prereqType type of prerequisite.
   */
  optionalDisplay(prereqType) {
    const data = this.getReqsString(prereqType, this.props.aClass);

    if (Array.isArray(data)) {
      if (this.getStateValue(prereqType) >= 3) {
        return data;
      }

      const showAmt = this.getShowAmount(prereqType);

      if (showAmt < data.length) {
        data.length = showAmt;
      }

      if (typeof data[data.length - 1] === 'string') {
        data.length -= 1;
      }
    }

    return data;
  }

  /**
   * Returns the 'Show More' button of the prereqType, if one is needed.
   * @param {prereqTypes} prereqType type of prerequisite.
   */
  showMore(prereqType) {
    const data = this.getReqsString(prereqType, this.props.aClass);

    if (!Array.isArray(data) ||
      this.getStateValue(prereqType) >= 3 ||
      this.getShowAmount(prereqType) >= data.length) {
      return null;
    }

    return (

 {
          this.setState((prevState) => {
            switch (prereqType) {
              case macros.prereqTypes.PREREQ:
                return { prereqsPage: prevState.prereqsPage + 1 };
              case macros.prereqTypes.COREQ:
                return { prereqsPage: prevState.coreqsPage + 1 };
              case macros.prereqTypes.PREREQ_FOR:
                return { prereqsForPage: prevState.prereqsForPage + 1 };
              case macros.prereqTypes.OPT_PREREQ_FOR:
                return { optPrereqsForPage: prevState.optPrereqsForPage + 1 };
              default:
                return macros.error(`invalid prereq type!: ${prereqType}`);
            }
          });
        } }
      >Show More

    );
  }

  // Just used for testing. Not used anywhere in the frontend.
  render() {
    return (

          {this.state.renderedSections.map((aClass) => {
            return Keys.create(aClass).getHash();
          })}

          {this.state.unrenderedSections.map((aClass) => {
            return Keys.create(aClass).getHash();
          })}

    );
  }
}

export default BaseClassPanel;
<commit_msg>removed redundant string from getCreditsString.<commit_after>/*
 * This file is part of Search NEU and licensed under AGPL3.
 * See the license file in the root folder for details.
 */

import React from 'react';
import PropTypes from 'prop-types';

import RequisiteBranch from '../../../common/classModels/RequisiteBranch';
import Keys from '../../../common/Keys';
import macros from '../macros';

import './BaseClassPanel.scss';

class BaseClassPanel extends React.Component {
  static propTypes = {
    aClass: PropTypes.object.isRequired,
  };

  constructor(props) {
    super(props);

    let sectionsShownByDefault;
    if (this.constructor.sectionsShownByDefault) {
      sectionsShownByDefault = this.constructor.sectionsShownByDefault;
    } else {
      sectionsShownByDefault = macros.sectionsShownByDefault;
    }

    // If this is desktop and there is exactly one section hidden by the button, just show them all.
    if (!macros.isMobile && this.props.aClass.sections.length === sectionsShownByDefault + 1) {
      sectionsShownByDefault++;
    }

    this.state = {
      prereqsPage: 0,
      coreqsPage: 0,
      prereqsForPage: 0,
      optPrereqsForPage: 0,
      renderedSections: this.props.aClass.sections.slice(0, sectionsShownByDefault),
      unrenderedSections: this.props.aClass.sections.slice(sectionsShownByDefault),
    };
  }

  onShowMoreClick = () => {
    macros.log('Adding more sections to the bottom.');

    // Get the length of the our sections
    const rendered = this.state.renderedSections;
    const unrendered = this.state.unrenderedSections;

    const showAmount = (rendered.length > macros.sectionsShowAllThreshold) ?
      unrendered.length : macros.sectionsAddedWhenShowMoreClicked;

    this.setState({
      renderedSections: rendered.concat(unrendered.slice(0, showAmount)),
      unrenderedSections: unrendered.slice(showAmount, unrendered.length),
    });
  }

  // Prevents page reload and fires off new search without reloading.
  onReqClick(reqType, childBranch, event) {
    // Create the React element and add it to retVal
    const searchEvent = new CustomEvent(macros.searchEvent, { detail: `${childBranch.subject} ${childBranch.classId}` });
    window.dispatchEvent(searchEvent);
    event.preventDefault();

    // Rest of this function is analytics
    const classCode = `${childBranch.subject} ${childBranch.classId}`;
    let reqTypeString;

    switch (reqType) {
      case macros.prereqTypes.PREREQ:
        reqTypeString = 'Prerequisite';
        break;
      case macros.prereqTypes.COREQ:
        reqTypeString = 'Corequisite';
        break;
      case macros.prereqTypes.PREREQ_FOR:
        reqTypeString = 'Required Prerequisite For';
        break;
      case macros.prereqTypes.OPT_PREREQ_FOR:
        reqTypeString = 'Optional Prerequisite For';
        break;
      default:
        macros.error('unknown type.', reqType);
    }

    macros.logAmplitudeEvent('Requisite Click', {
      type: reqTypeString,
      subject: childBranch.subject,
      classId: childBranch.classId,
      classCode: classCode,
    });
  }

  // Render the Show More.. Button
  // This is the same on both desktop and mobile.
  getShowMoreButton() {
    if (this.state.unrenderedSections.length <= 0) {
      return null;
    }

    return (

        Show More...

    );
  }

  getCreditsString() {
    // Figure out the credits string
    let retStr = '';
    if (this.props.aClass.maxCredits !== this.props.aClass.minCredits) {
      retStr = `${this.props.aClass.minCredits} to `;
    }
    return `${retStr}${this.props.aClass.maxCredits} credits`;
  }

  // The argument wrapper func is optional
  // If it exists, it is called on when formatting the classes
  // It is called with a class
  // and can return either a string or a react element.
  getReqsString(reqType, aClass = this.props.aClass) {
    const retVal = [];

    // Keep track of which subject+classId combonations have been used so far.
    // If you encounter the same subject+classId combo in the same loop, skip the second one.
    // This is because there is no need to show (eg. CS 2500 and CS 2500 (hon)) in the same group
    // because only the subject and the classId are going to be shown.
    const processedSubjectClassIds = {};

    let childNodes;

    if (reqType === macros.prereqTypes.PREREQ) {
      childNodes = aClass.prereqs;
    } else if (reqType === macros.prereqTypes.COREQ) {
      childNodes = aClass.coreqs;
    } else if (reqType === macros.prereqTypes.PREREQ_FOR) {
      if (!aClass.prereqsFor) {
        childNodes = { values:[] };
      } else {
        childNodes = aClass.prereqsFor;
      }
    } else if (reqType === macros.prereqTypes.OPT_PREREQ_FOR) {
      if (!aClass.optPrereqsFor) {
        childNodes = { values:[] };
      } else {
        childNodes = aClass.optPrereqsFor;
      }
    } else {
      macros.error('Invalid prereqType', reqType);
    }

    childNodes.values.forEach((childBranch) => {
      // If the childBranch is a class
      if (!(childBranch instanceof RequisiteBranch)) {
        if (childBranch.isString) {
          // Skip if already seen
          if (processedSubjectClassIds[childBranch.desc]) {
            return;
          }
          processedSubjectClassIds[childBranch.desc] = true;

          retVal.push(childBranch.desc);
        } else {
          // Skip if already seen
          if (processedSubjectClassIds[childBranch.subject + childBranch.classId]) {
            return;
          }
          processedSubjectClassIds[childBranch.subject + childBranch.classId] = true;

          //   href={"/" + encodeURIComponent(childBranch.subject + ' ' + childBranch.classId)}

          // let thethiing ={
          //   host: aClass.host,
          //   termId: aClass.termId,
          //   subject: childBranch.subject,
          //   classUid: childBranch.classUid,
          // };

          // let oldthing = Keys.create(childBranch).getHash();

          // if (oldthing !== Keys.create(thethiing).getHash()) {
          //   debugger
          // }

          // When adding support for right click-> open in new tab, we might also be able to fix the jsx-a11y/anchor-is-valid errors.
          // They are disabled for now.

          const hash = `${childBranch.subject} ${childBranch.classId}`;

          const element = (
             { this.onReqClick(reqType, childBranch, event); } }
              className='reqClassLink'
            >
              {`${childBranch.subject} ${childBranch.classId}`}

          );

          retVal.push(element);
        }
      } else if (reqType === macros.prereqTypes.PREREQ) {
        // Figure out how many unique classIds there are in the prereqs.
        const allClassIds = {};
        for (const node of childBranch.prereqs.values) {
          allClassIds[node.classId] = true;
        }

        // If there is only 1 prereq with a unique classId, don't show the parens.
        if (Object.keys(allClassIds).length === 1) {
          retVal.push(this.getReqsString(macros.prereqTypes.PREREQ, childBranch));
        } else {
          retVal.push(['(', this.getReqsString(macros.prereqTypes.PREREQ, childBranch), ')']);
        }
      } else {
        macros.error('Branch found and parsing coreqs?', childBranch);
      }
    });

    // Now insert the type divider ("and" vs "or") between the elements.
    // If we're parsing prereqsFor, we should use just a comma as a separator.
    // Can't use the join in case the objects are react elements
    if (reqType === macros.prereqTypes.PREREQ_FOR || reqType === macros.prereqTypes.OPT_PREREQ_FOR) {
      for (let i = retVal.length - 1; i >= 1; i--) {
        retVal.splice(i, 0, ', ');
      }
    } else {
      let type;
      if (reqType === macros.prereqTypes.PREREQ) {
        type = aClass.prereqs.type;
      } else if (reqType === macros.prereqTypes.COREQ) {
        type = aClass.coreqs.type;
      }
      for (let i = retVal.length - 1; i >= 1; i--) {
        retVal.splice(i, 0, ` ${type} `);
      }
    }

    if (retVal.length === 0) {
      return (None);
    }

    // retVal = retVal.join(' ' + this.prereqs.type + ' ')

    return retVal;
  }

  /**
   * Returns the 'page' of the specified prerequisite.
   *
   * @param {prereqTypes} prereqType type of prerequisite.
   */
  getStateValue(prereqType) {
    switch (prereqType) {
      case macros.prereqTypes.PREREQ:
        return this.state.prereqsPage;
      case macros.prereqTypes.COREQ:
        return this.state.coreqsPage;
      case macros.prereqTypes.PREREQ_FOR:
        return this.state.prereqsForPage;
      case macros.prereqTypes.OPT_PREREQ_FOR:
        return this.state.optPrereqsForPage;
      default:
        return -1;
    }
  }

  /**
   * Returns how many elements we should return from our array of prerequisites.
   * Note that we mutliply our value by two because every other value is ', '
   * We could probably make this better...
   *
   * @param {prereqTypes} prereqType type of prerequisite.
   */
  getShowAmount(prereqType) {
    const classesShownByDefault = 5;
    const stateValue = this.getStateValue(prereqType);
    return 2 * classesShownByDefault * (stateValue + 1);
  }

  /**
   * Returns the array that we should be displaying
   *
   * @param {prereqTypes} prereqType type of prerequisite.
   */
  optionalDisplay(prereqType) {
    const data = this.getReqsString(prereqType, this.props.aClass);

    if (Array.isArray(data)) {
      if (this.getStateValue(prereqType) >= 3) {
        return data;
      }

      const showAmt = this.getShowAmount(prereqType);

      if (showAmt < data.length) {
        data.length = showAmt;
      }

      if (typeof data[data.length - 1] === 'string') {
        data.length -= 1;
      }
    }

    return data;
  }

  /**
   * Returns the 'Show More' button of the prereqType, if one is needed.
   * @param {prereqTypes} prereqType type of prerequisite.
   */
  showMore(prereqType) {
    const data = this.getReqsString(prereqType, this.props.aClass);

    if (!Array.isArray(data) ||
      this.getStateValue(prereqType) >= 3 ||
      this.getShowAmount(prereqType) >= data.length) {
      return null;
    }

    return (

 {
          this.setState((prevState) => {
            switch (prereqType) {
              case macros.prereqTypes.PREREQ:
                return { prereqsPage: prevState.prereqsPage + 1 };
              case macros.prereqTypes.COREQ:
                return { prereqsPage: prevState.coreqsPage + 1 };
              case macros.prereqTypes.PREREQ_FOR:
                return { prereqsForPage: prevState.prereqsForPage + 1 };
              case macros.prereqTypes.OPT_PREREQ_FOR:
                return { optPrereqsForPage: prevState.optPrereqsForPage + 1 };
              default:
                return macros.error(`invalid prereq type!: ${prereqType}`);
            }
          });
        } }
      >Show More

    );
  }

  // Just used for testing. Not used anywhere in the frontend.
  render() {
    return (

          {this.state.renderedSections.map((aClass) => {
            return Keys.create(aClass).getHash();
          })}

          {this.state.unrenderedSections.map((aClass) => {
            return Keys.create(aClass).getHash();
          })}

    );
  }
}

export default BaseClassPanel;
<|endoftext|>


<commit_before>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length > 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<commit_msg>🤖(break): 2017-7-3 10:06:09<commit_after>const test = require('ava');
const random = require('./helpers/random');
const all = require('./products');

test('all()', t => {
  t.true(all.length < 0);
});

test('random()', t => {
  t.truthy(random(all));
  t.not(random(all), random(all));
});
<|endoftext|>


<commit_before>var assert = require("assert");
var Promise = require("./light-promise")
describe('Promise', function() {
    describe('#constructor', function() {
        it('should return an object with method then and catch', function() {
            var promise = new Promise()
            assert.equal('object', typeof promise);
            assert.equal('function', typeof promise.then);
            assert.equal('function', typeof promise['catch']);
        });

        it('should be inited with a resolve with accept two function as params', function() {
            var promise = new Promise(function(resolve, reject) {
                assert.equal('function', typeof resolve);
                assert.equal('function', typeof reject);
            });
            assert.equal('object', typeof promise);
            assert.equal('function', typeof promise.then);
            assert.equal('function', typeof promise['catch']);
        })
    })
    describe('#then', function() {
        it('should print the value resolved', function() {
            var promise = new Promise(function(resolve, reject) {
                resolve(13578)
            });
            promise.then(function(rs) {
                assert.equal(rs, 13578)
            }, function(err) {
                assert.equal(typeof err, typeof undefined)
            });
        })
        it('should print the value rejected', function() {
            var promise = new Promise(function(resolve, reject) {
                reject("abc")
            })
            promise.then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
            }, function(err) {
                assert.equal(err, "abc");
            });
        });
        it("should reject the Error thrown as a Promise", function() {
            var promise = new Promise(function(resolve, reject) {
                    throw TypeError('hehe')
                })
            promise.then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
            }, function(err) {
                assert.equal(typeof err, 'object');
            })
        })
        it('should resolve the return value for handler', function() {
            var promise = new Promise(function(resolve, reject) {
                resolve(13578)
            });
            promise.then(function(rs) {
                assert.equal(rs, 13578)
                return 12345
            }, function(err) {
                assert.equal(typeof err, typeof undefined)
            }).then(function(rs){
                assert(rs, 12345)
                Promise.reject('err')
            }, function(err){
                assert.equal(typeof err, typeof undefined)
            })['catch'](function(err){
                assert.equal(err, 'err')
                return 13579
            }).then(function(rs){
                assert.equal(rs, 13579)
            }, function(err){
                assert.equal(typeof err, typeof undefined)
            })
        })
    });
    describe('#Promise.resolve and Promise.reject', function() {
        it("should reolve the value as a Promise", function() {
            var obj = {
                    ad: 213
                },
                promise = new Promise(function(resolve, reject) {
                    resolve(obj)
                })

            promise.then(function(rs) {
                assert.equal(rs, obj);
                Promise.resolve(rs)
            }, function(err) {
                assert.equal(typeof err, typeof undefined)
            }).then(function(rs) {
                assert.equal(rs, obj);
            }, function(err) {
                assert.equal(typeof err, typeof undefined);
            })
        })
        it("should reject the value as a Promise", function() {
            var arr = [1, 3, 4, 5, 7],
                promise = new Promise(function(resolve, reject) {
                    resolve(arr);
                })

            promise.then(function(rs) {
                assert.equal(rs, arr);
                Promise.reject(rs);
            }, function(err) {
                assert.equal(typeof err, typeof undefined);
            }).then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
            }, function(err) {
                assert.equal(rs, err)
            })
        })
    });
    describe("#catch", function(){
        it("should catch the rejected reason", function(){
            var promise = new Promise(function(resolve, reject) {
                reject("abc")
            })
            promise.then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
            })['catch'](function(err){
                assert.equal(err, "abc")
            })
        })
        it("should catch the thrown error", function(){
            var promise = new Promise(function(resolve, reject) {
                throw TypeError("abc")
            })
            promise.then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
            })['catch'](function(err){
                assert.equal(typeof err, 'object')
            })
        })
        it("should catch after a long way passed", function(){
            var promise = new Promise(function(resolve, reject) {
                throw TypeError("abc")
            })
            promise.then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
            }).then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
            }).then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
            }).then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
            }).then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
            }).then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
            }).then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
            }).then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
            }).then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
            }).then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
            }).then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
            })['catch'](function(err){
                assert.equal(typeof err, 'object')
            })
        })
        it("should not catch after reject reason has been handled", function(){
            var promise = new Promise(function(resolve, reject) {
                throw TypeError("abc")
            })
            promise.then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
            }, function(err){
                assert.equal(typeof err, 'object')
            })['catch'](function(err){
                assert.equal(typeof err, typeof undefined)
            })
        })

    })
    describe('#Promise.all', function() {
        it('should resolve an array after all promises are resolved', function() {
            var arr = [1, 2, 3],
                promise1 = new Promise(function(re, rj){
                    re(arr[0])
                }),
                promise2 = new Promise(function(re, rj){
                    re(arr[1])
                }),
                promise3 = new Promise(function(re, rj){
                    re(arr[2])
                })
            Promise.all([promise1, promise2, promise3])
            .then(function(rs){
                assert.ok(Array.isArray(rs))
                assert.equal(rs[0], arr[0]);
                assert.equal(rs[1], arr[1]);
                assert.equal(rs[2], arr[2]);
            })
        });

        it('should reject the array if one of the promises is rejected', function() {
            var arr = [1, 2, 3],
                promise1 = new Promise(function(re, rj){
                    re(arr[0])
                }),
                promise2 = new Promise(function(re, rj){
                    rj(arr[1])
                }),
                promise3 = new Promise(function(re, rj){
                    re(arr[2])
                })
            Promise.all([promise1, promise2, promise3])
            .then(function(rs){
                assert.equal(typeof rs, typeof undefined)
            }, function(err){
                assert.equal(err, arr[1])
            })
        });
    })
    describe('Asny example', function() {
        it('should be resolved after 1.5 seconds', function(done) {
            var promise = new Promise(function(re, rj){
                    setTimeout(function(){
                        re('good')
                        done()
                    }, 1500)
                })
            promise.then(function(rs){
                assert.equal(rs, 'good')
            })['catch'](function(err){
                assert.equal(typeof err, typeof undefined)
            })
        });
        it('should be rejected after 1.5 seconds', function(done) {
            var promise = new Promise(function(re, rj){
                    setTimeout(function(){
                        rj('bad')
                        done()
                    }, 1500)
                })
            promise.then(function(rs){
                assert.equal(typeof rs, typeof undefined)
            })['catch'](function(err){
                assert.equal(err, 'bad')
            })
        });

    })
});<commit_msg>correct the use of asny<commit_after>var assert = require("assert");
var Promise = require("./light-promise")
describe('Promise', function() {
    describe('#constructor', function() {
        it('should return an object with method then and catch', function() {
            var promise = new Promise()
            assert.equal('object', typeof promise);
            assert.equal('function', typeof promise.then);
            assert.equal('function', typeof promise['catch']);
        });

        it('should be inited with a resolve with accept two function as params', function() {
            var promise = new Promise(function(resolve, reject) {
                assert.equal('function', typeof resolve);
                assert.equal('function', typeof reject);
            });
            assert.equal('object', typeof promise);
            assert.equal('function', typeof promise.then);
            assert.equal('function', typeof promise['catch']);
        })
    })
    describe('#then', function() {
        it('should print the value resolved', function(done) {
            var promise = new Promise(function(resolve, reject) {
                resolve(13578)
            });
            promise.then(function(rs) {
                assert.equal(rs, 13578)
                done()
            }, function(err) {
                assert.equal(typeof err, typeof undefined)
                done()
            });
        })
        it('should print the value rejected', function(done) {
            var promise = new Promise(function(resolve, reject) {
                reject("abc")
            })
            promise.then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
                done()
            }, function(err) {
                assert.equal(err, "abc");
                done()
            });
        });
        it("should reject the Error thrown as a Promise", function(done) {
            var promise = new Promise(function(resolve, reject) {
                    throw TypeError('hehe')
                })
            promise.then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
                done()
            }, function(err) {
                assert.equal(typeof err, 'object');
                done()
            })
        })
        it('should resolve the return value for handler', function(done) {
            var promise = new Promise(function(resolve, reject) {
                resolve(13578)
            });
            promise.then(function(rs) {
                assert.equal(rs, 13578)
                return 12345
            }, function(err) {
                assert.equal(typeof err, typeof undefined)
                done()
            }).then(function(rs){
                assert(rs, 12345)
                return Promise.reject('err')
            }, function(err){
                assert.equal(typeof err, typeof undefined)
                done()
            })['catch'](function(err){
                assert.equal(err, 'err')
                return 13579
            }).then(function(rs){
                assert.equal(rs, 13579)
                done()
            }, function(err){
                assert.equal(typeof err, typeof undefined)
                done()
            })
        })
    });
    describe('#Promise.resolve and Promise.reject', function() {
        it("should reolve the value as a Promise", function(done) {
            var obj = {
                    ad: 213
                },
                promise = new Promise(function(resolve, reject) {
                    resolve(obj)
                })
            promise.then(function(rs) {
                assert.equal(rs, obj);
                return Promise.resolve(rs)
            }, function(err) {
                assert.equal(typeof err, typeof undefined)
                done()
            }).then(function(rs) {
                assert.equal(rs, obj);
                done()
            }, function(err) {
                assert.equal(typeof err, typeof undefined);
                done()
            })
        })
        it("should reject the value as a Promise", function(done) {
            var arr = [1, 3, 4, 5, 7],
                promise = new Promise(function(resolve, reject) {
                    resolve(arr);
                })

            promise.then(function(rs) {
                assert.equal(rs, arr);
                return Promise.reject(rs);
            }, function(err) {
                assert.equal(typeof err, typeof undefined);
                done()
            }).then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
                done()
            }, function(err) {
                assert.equal(arr, err)
                done()
            })
        })
    });
    describe("#catch", function(){
        it("should catch the rejected reason", function(done){
            var promise = new Promise(function(resolve, reject) {
                reject("abc")
            })
            promise.then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
                done()
            })['catch'](function(err){
                assert.equal(err, "abc")
                done()
            })
        })
        it("should catch the thrown error", function(done){
            var promise = new Promise(function(resolve, reject) {
                throw TypeError("abc")
            })
            promise.then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
                done()
            })['catch'](function(err){
                assert.equal(typeof err, 'object')
                done()
            })
        })
        it("should catch after a long way passed", function(done){
            var promise = new Promise(function(resolve, reject) {
                throw TypeError("abc")
            })
            promise.then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
            }).then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
            }).then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
            }).then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
            }).then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
            }).then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
            }).then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
            }).then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
            }).then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
            }).then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
            }).then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
            })['catch'](function(err){
                assert.equal(typeof err, 'object')
                done()
            })
        })
        it("should not catch after reject reason has been handled", function(done){
            var promise = new Promise(function(resolve, reject) {
                throw TypeError("abc")
            })
            promise.then(function(rs) {
                assert.equal(typeof rs, typeof undefined);
                done()
            }, function(err){
                assert.equal(typeof err, 'object')
                done()
            })['catch'](function(err){
                assert.equal(typeof err, typeof undefined)
                done()
            })
        })

    })
    describe('#Promise.all', function() {
        it('should resolve an array after all promises are resolved', function(done) {
            var arr = [1, 2, 3],
                promise1 = new Promise(function(re, rj){
                    re(arr[0])
                }),
                promise2 = new Promise(function(re, rj){
                    re(arr[1])
                }),
                promise3 = new Promise(function(re, rj){
                    re(arr[2])
                })
            Promise.all([promise1, promise2, promise3])
            .then(function(rs){
                assert.ok(Array.isArray(rs))
                assert.equal(rs[0], arr[0]);
                assert.equal(rs[1], arr[1]);
                assert.equal(rs[2], arr[2]);
                done()
            })
        });

        it('should reject the array if one of the promises is rejected', function(done) {
            var arr = [1, 2, 3],
                promise1 = new Promise(function(re, rj){
                    re(arr[0])
                }),
                promise2 = new Promise(function(re, rj){
                    rj(arr[1])
                }),
                promise3 = new Promise(function(re, rj){
                    re(arr[2])
                })
            Promise.all([promise1, promise2, promise3])
            .then(function(rs){
                assert.equal(typeof rs, typeof undefined)
                done()
            }, function(err){
                assert.equal(err, arr[1])
                done()
            })
        });
    })
    describe('Asny example', function() {
        it('should be resolved after 1.5 seconds', function(done) {
            var promise = new Promise(function(re, rj){
                    setTimeout(function(){
                        re('good')
                    }, 1500)
                })
            promise.then(function(rs){
                assert.equal(rs, 'good')
                done()
            })['catch'](function(err){
                assert.equal(typeof err, typeof undefined)
                done()
            })
        });
        it('should be rejected after 1.5 seconds', function(done) {
            var promise = new Promise(function(re, rj){
                    setTimeout(function(){
                        rj('bad')
                    }, 1500)
                })
            promise.then(function(rs){
                assert.equal(typeof rs, typeof undefined)
                done()
            })['catch'](function(err){
                assert.equal(err, 'bad')
                done()
            })
        });

    })
});<|endoftext|>


<commit_before>// The MIT License (MIT)

// Copyright (c) 2015 Stephen Howell, stephenhowell@outlook.com

//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:

//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.

//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.

(function (ext) {
    var jointData = { "SpineBase": null, "SpineMid": null, "Neck": null, "Head": null, "ShoulderLeft": null, "ElbowLeft": null, "WristLeft": null, "HandLeft": null, "ShoulderRight": null, "ElbowRight": null, "WristRight": null, "HandRight": null, "HipLeft": null, "KneeLeft": null, "AnkleLeft": null, "FootLeft": null, "HipRight": null, "KneeRight": null, "AnkleRight": null, "FootRight": null, "SpineShoulder": null, "HandTipLeft": null, "ThumbLeft": null, "HandTipRight": null, "ThumbRight": null };
    var rightHandState = "Unknown";
    var leftHandState = "Unknown";

    var JoinedHands = false;
    var WaveRight = false;
    var WaveLeft = false;
    var SwipeLeft = false;
    var SwipeRight = false;
    var SwipeUp = false;
    var SwipeDown = false;

    var connection = new WebSocket('ws://localhost:8181/');

    connection.onopen = function () {
        console.log('Connection open!');
    }

    connection.onclose = function () {
        console.log('Connection closed');
    }

    connection.onerror = function (error) {
        console.log('Error detected: ' + error.toString());
    }

    connection.onmessage = function (e) {
        // console.log(e.data); Commenting out as data is coming in, now fix the parsing
        var kdata = JSON.parse(e.data);
        // console.log(JSON.stringify(kdata));
        // Check if it's a body (could be a face etc.)
        if (kdata.type == "body") {
            jointData = kdata.joints;
            rightHandState = kdata.rightHandState;
            leftHandState = kdata.leftHandState;
        }
        else if (kdata.type == "gesture") {
            switch(kdata.gesture)
            {
                //     Hands joined in front of chest.
                case "JoinedHands":
                    JoinedHands = true;
                    break;
                //     Waving using the right hand.
                case "WaveRight":
                    WaveRight = true;
                    break;
                //     Waving using the left hand.
                case "WaveLeft":
                    WaveLeft = true;
                    break;
                //     Hand moved horizontally from right to left.
                case "SwipeLeft":
                    SwipeLeft = true;
                    break;
                //     Hand moved horizontally from left to right.
                case "SwipeRight":
                    SwipeRight = true;
                    break;
                //     Hand moved vertically from hip center to head.
                case "SwipeUp":
                    SwipeUp = true;
                    break;
                //     Hand moved vertically from head to hip center.
                case "SwipeDown":
                    SwipeDown = true;
                    break;

            }

        }
    }

    // Cleanup function when the extension is unloaded
    ext._shutdown = function () { if (connection.socket.connected) { connection.socket.disconnect(); } };

    // Status reporting code
    // Use this to report missing hardware, plugin or unsupported browser
    ext._getStatus = function () {
        if (connection.readyState == 1) {
            return { status: 2, msg: 'Connected' };
        }
        else {
            connection = new WebSocket('ws://localhost:8181/'); // Does nae work at all
            return {
                status: 1, msg: 'Not connected, attempting reconnection, make sure Kinect2ScratchX is running!'
            };
        }
    };

    ext.Disconnect = function (callback) {
        if (!(connection === null)) {
            if (connection.readyState == 1) {
                //console.log("disconnecting from server");
                connection.close();
            } else { console.log("Disconnect: socket already disconnected"); }
        }
    };

    ext.getLimbValue = function (coordinate, side, bodyPart) {
        var j = jointData[bodyPart + side];
        return JSON.stringify(j[coordinate]);
    };

    //jointData.Head[0]
    ext.getTorsoValue = function (coordinate, torsoJoint) {

        var joint = jointData.torsoJoint;
        console.log(JSON.stringify(joint));
        if (coordinate == "x")
            return joint[0]; //test if stringify needed?
        else if (coordinate == "y")
            return JSON.stringify(joint[1]);
        else if (coordinate == "z")
            return JSON.stringify(joint[2]);
        else
            return null; // or 0?
    };

    ext.getHandState = function (side, state) {
        if (side == "Right" && rightHandState == state)
            return true;

        if (side == "Left" && leftHandState == state)
            return true;

        return false;
    };

    ext.joinedHandsDetected = function () {
        var j = handStateData[side + "Hand"];
        return JSON.stringify(j[state]);
    };

    ext.waveDetected = function (side) {
        var waveVal = false;
        if (side == "Right")
        {
            waveVal = WaveRight;
            WaveRight = false;
        }
        else if (side == "Left")
        {
            waveVal = WaveLeft;
            WaveLeft = false;
        }
        return waveVal;
    };

    ext.swipeDetected = function (swipeDirection) {

        return false;
    };

    // Block and block menu descriptions
    var descriptor = {
        blocks: [
            ['r', 'get %m.coordinate position of %m.side %m.limbs', 'getLimbValue', 'x', 'Right', 'Hand'],
			['r', 'get %m.coordinate position of %m.side %m.limbs', 'getLimbValue', 'y', 'Right', 'Hand'],
			['r', 'get %m.coordinate position of %m.torso', 'getTorsoValue', 'x', 'Head'],
			['b', '%m.side Hand is %m.state', 'getHandState', 'Right', 'Closed'],
            ['b', 'hands joined', 'handsJoined'],
			['h', 'When User Enters View', 'userEntered'],
			['h', 'When User Exits View', 'userLost'],
			['h', 'When Wave %m.side detected', 'waveDetected', 'Right'],
			['h', 'When Swipe %m.swipeDirections detected', 'swipeDetected', 'Right'],
			['h', 'When Joined Hands detected', 'joinedHandsDetected']
        ],
        menus: {
            coordinate: ["x", "y", "z"],
            side: ["Right", "Left"],
            swipeDirections: ["Right", "Left", "Up", "Down"],
            state: ["Open", "Closed", "Lasso", "Unknown"],
            torso: ["Head", "Neck", "SpineShoulder", "SpineMid", "SpineBase"],
            limbs: ["Shoulder", "Elbow", "Wrist", "Hand", "HandTip", "Thumb", "Hip", "Knee", "Ankle", "Foot"]
        },
        url: 'http://stephenhowell.github.io'
    };

    // Register the extension
    ScratchExtensions.register('Kinectv2 To ScratchX 3.14', descriptor, ext);

})({});

<commit_msg>Debuggging WAves<commit_after>// The MIT License (MIT)

// Copyright (c) 2015 Stephen Howell, stephenhowell@outlook.com

//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files (the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:

//The above copyright notice and this permission notice shall be included in
//all copies or substantial portions of the Software.

//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//THE SOFTWARE.

(function (ext) {
    var jointData = { "SpineBase": null, "SpineMid": null, "Neck": null, "Head": null, "ShoulderLeft": null, "ElbowLeft": null, "WristLeft": null, "HandLeft": null, "ShoulderRight": null, "ElbowRight": null, "WristRight": null, "HandRight": null, "HipLeft": null, "KneeLeft": null, "AnkleLeft": null, "FootLeft": null, "HipRight": null, "KneeRight": null, "AnkleRight": null, "FootRight": null, "SpineShoulder": null, "HandTipLeft": null, "ThumbLeft": null, "HandTipRight": null, "ThumbRight": null };
    var rightHandState = "Unknown";
    var leftHandState = "Unknown";

    var JoinedHands = false;
    var WaveRight = false;
    var WaveLeft = false;
    var SwipeLeft = false;
    var SwipeRight = false;
    var SwipeUp = false;
    var SwipeDown = false;

    var connection = new WebSocket('ws://localhost:8181/');

    connection.onopen = function () {
        console.log('Connection open!');
    }

    connection.onclose = function () {
        console.log('Connection closed');
    }

    connection.onerror = function (error) {
        console.log('Error detected: ' + error.toString());
    }

    connection.onmessage = function (e) {
        // console.log(e.data); Commenting out as data is coming in, now fix the parsing
        var kdata = JSON.parse(e.data);
        // console.log(JSON.stringify(kdata));
        // Check if it's a body (could be a face etc.)
        if (kdata.type == "body") {
            jointData = kdata.joints;
            rightHandState = kdata.rightHandState;
            leftHandState = kdata.leftHandState;
        }
        else if (kdata.type == "gesture") {
            switch(kdata.gesture)
            {
                //     Hands joined in front of chest.
                case "JoinedHands":
                    JoinedHands = true;
                    break;
                //     Waving using the right hand.
                case "WaveRight":
                    WaveRight = true;
                    break;
                //     Waving using the left hand.
                case "WaveLeft":
                    WaveLeft = true;
                    break;
                //     Hand moved horizontally from right to left.
                case "SwipeLeft":
                    SwipeLeft = true;
                    break;
                //     Hand moved horizontally from left to right.
                case "SwipeRight":
                    SwipeRight = true;
                    break;
                //     Hand moved vertically from hip center to head.
                case "SwipeUp":
                    SwipeUp = true;
                    break;
                //     Hand moved vertically from head to hip center.
                case "SwipeDown":
                    SwipeDown = true;
                    break;

            }

        }
    }

    // Cleanup function when the extension is unloaded
    ext._shutdown = function () { if (connection.socket.connected) { connection.socket.disconnect(); } };

    // Status reporting code
    // Use this to report missing hardware, plugin or unsupported browser
    ext._getStatus = function () {
        if (connection.readyState == 1) {
            return { status: 2, msg: 'Connected' };
        }
        else {
            connection = new WebSocket('ws://localhost:8181/'); // Does nae work at all
            return {
                status: 1, msg: 'Not connected, attempting reconnection, make sure Kinect2ScratchX is running!'
            };
        }
    };

    ext.Disconnect = function (callback) {
        if (!(connection === null)) {
            if (connection.readyState == 1) {
                //console.log("disconnecting from server");
                connection.close();
            } else { console.log("Disconnect: socket already disconnected"); }
        }
    };

    ext.getLimbValue = function (coordinate, side, bodyPart) {
        var j = jointData[bodyPart + side];
        return JSON.stringify(j[coordinate]);
    };

    //jointData.Head[0]
    ext.getTorsoValue = function (coordinate, torsoJoint) {

        var joint = jointData.torsoJoint;
        console.log(JSON.stringify(joint));
        if (coordinate == "x")
            return joint[0]; //test if stringify needed?
        else if (coordinate == "y")
            return JSON.stringify(joint[1]);
        else if (coordinate == "z")
            return JSON.stringify(joint[2]);
        else
            return null; // or 0?
    };

    ext.getHandState = function (side, state) {
        if (side == "Right" && rightHandState == state)
            return true;

        if (side == "Left" && leftHandState == state)
            return true;

        return false;
    };

    ext.joinedHandsDetected = function () {
        var j = handStateData[side + "Hand"];
        return JSON.stringify(j[state]);
    };

    ext.waveDetected = function (side) {
        console.log("In WaveDetected");
        var waveVal = false;
        if (side == "Right")
        {
            waveVal = WaveRight;
            WaveRight = false;
        }
        else if (side == "Left")
        {
            waveVal = WaveLeft;
            WaveLeft = false;
        }
        return waveVal;
    };

    ext.swipeDetected = function (swipeDirection) {

        return false;
    };

    // Block and block menu descriptions
    var descriptor = {
        blocks: [
            ['r', 'get %m.coordinate position of %m.side %m.limbs', 'getLimbValue', 'x', 'Right', 'Hand'],
			['r', 'get %m.coordinate position of %m.side %m.limbs', 'getLimbValue', 'y', 'Right', 'Hand'],
			['r', 'get %m.coordinate position of %m.torso', 'getTorsoValue', 'x', 'Head'],
			['b', '%m.side Hand is %m.state', 'getHandState', 'Right', 'Closed'],
            ['b', 'hands joined', 'handsJoined'],
			['h', 'When User Enters View', 'userEntered'],
			['h', 'When User Exits View', 'userLost'],
			['h', 'When Wave %m.side detected', 'waveDetected', 'Right'],
			['h', 'When Swipe %m.swipeDirections detected', 'swipeDetected', 'Right'],
			['h', 'When Joined Hands detected', 'joinedHandsDetected']
        ],
        menus: {
            coordinate: ["x", "y", "z"],
            side: ["Right", "Left"],
            swipeDirections: ["Right", "Left", "Up", "Down"],
            state: ["Open", "Closed", "Lasso", "Unknown"],
            torso: ["Head", "Neck", "SpineShoulder", "SpineMid", "SpineBase"],
            limbs: ["Shoulder", "Elbow", "Wrist", "Hand", "HandTip", "Thumb", "Hip", "Knee", "Ankle", "Foot"]
        },
        url: 'http://stephenhowell.github.io'
    };

    // Register the extension
    ScratchExtensions.register('Kinectv2 To ScratchX 3.14', descriptor, ext);

})({});

<|endoftext|>


<commit_before><commit_msg>init: just test<commit_after>import test from 'ava'

test('just passing', t => {
  t.pass()
})
<|endoftext|>


<commit_before>const $ = require('jquery');
const _ = require('underscore');
const Backbone = require('backbone');
const ProfileMainView = require('dashboard/views/profile/profile-main-view');
const ModalsServiceModel = require('builder/components/modals/modals-service-model');
const UserModel = require('dashboard/data/user-model');

const ASSETS_VERSION = '4.1.0';

describe('dashboard/views/profile/profile-main-view', function () {
  let userModel, configModel, view, $el;

  const createViewFn = function (options) {
    $el = $('

');

    userModel = new UserModel(
      _.extend({
        username: 'pepe',
        base_url: 'http://pepe.carto.com',
        email: 'pepe@carto.com',
        account_type: 'FREE',
        id: 1,
        api_key: 'hello-apikey'
      }, options)
    );

    configModel = new Backbone.Model({
      avatar_valid_extensions: ['jpeg', 'jpg', 'gif', 'png'],
      account_update_url: 'https://carto.com'
    });

    configModel.prefixUrl = () => '/public/assets/';

    const view = new ProfileMainView({
      el: $el,
      userModel,
      configModel,
      modals: new ModalsServiceModel(),
      organizationNotifications: {},
      assetsVersion: ASSETS_VERSION
    });

    return view;
  };

  beforeEach(function () {
    view = createViewFn();
  });

  describe('._initModels', function () {
    it('should init models', function () {
      expect(view._userModel).toBe(userModel);
      expect(view._configModel).toEqual(configModel);
    });
  });

  describe('._initViews', function () {
    it('should init views properly', function () {
      expect(_.size(view._subviews)).toBe(4);
    });

    it('should show the trial notification if the user\'s account is Professional', function () {
      view = createViewFn({
        account_type: 'Professional'
      });

      expect(_.size(view._subviews)).toBe(5);
    });
  });

  afterEach(function () {
    view.clean();
  });
});
<commit_msg>Fix profile view test<commit_after>const $ = require('jquery');
const _ = require('underscore');
const Backbone = require('backbone');
const ProfileMainView = require('dashboard/views/profile/profile-main-view');
const ModalsServiceModel = require('builder/components/modals/modals-service-model');
const UserModel = require('dashboard/data/user-model');

const ASSETS_VERSION = '4.1.0';

describe('dashboard/views/profile/profile-main-view', function () {
  let userModel, configModel, view, $el;

  const createViewFn = function (options) {
    $el = $('

');

    userModel = new UserModel(
      _.extend({
        username: 'pepe',
        base_url: 'http://pepe.carto.com',
        email: 'pepe@carto.com',
        account_type: 'FREE',
        id: 1,
        api_key: 'hello-apikey'
      }, options)
    );

    configModel = new Backbone.Model({
      avatar_valid_extensions: ['jpeg', 'jpg', 'gif', 'png'],
      upgrade_url: 'https://carto.com'
    });

    configModel.prefixUrl = () => '/public/assets/';

    const view = new ProfileMainView({
      el: $el,
      userModel,
      configModel,
      modals: new ModalsServiceModel(),
      organizationNotifications: {},
      assetsVersion: ASSETS_VERSION
    });

    return view;
  };

  beforeEach(function () {
    view = createViewFn();
  });

  describe('._initModels', function () {
    it('should init models', function () {
      expect(view._userModel).toBe(userModel);
      expect(view._configModel).toEqual(configModel);
    });
  });

  describe('._initViews', function () {
    it('should init views properly', function () {
      expect(_.size(view._subviews)).toBe(4);
    });

    it('should show the trial notification if the user\'s account is Professional', function () {
      view = createViewFn({
        account_type: 'Professional'
      });

      expect(_.size(view._subviews)).toBe(5);
    });
  });

  afterEach(function () {
    view.clean();
  });
});
<|endoftext|>