<commit_before>/**
 * The MIT License
 *
 * Copyright (c) 2010 Adam Abrons and Misko Hevery http://getangular.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.
 */

/*

 NUGGGGGH MUST TONGUE WANGS
                           \
                                .....
                               C C  /
                              /<   /
               ___ __________/_#__=o
              /(- /(\_\________   \
              \ ) \ )_      \o     \
              /|\ /|\       |'     |
                            |     _|
                            /o   __\
                           / '     |
                          / /      |
                         /_/\______|
                        (   _(    <
                         \    \    \
                          \    \    |
                           \____\____\
                           ____\_\__\_\
                         /`   /`     o\
                         |___ |_______|.. . b'ger

 IN THE FINAL BUILD THIS FILE DOESN'T HAVE DIRECT ACCESS TO GLOBAL FUNCTIONS
 DEFINED IN Angular.js YOU *MUST* REFER TO THEM VIA angular OBJECT
 (e.g. angular.forEach(...)) AND MAKE SURE THAT THE GIVEN FUNCTION IS EXPORTED
 TO THE angular NAMESPACE in AngularPublic.js

 */

/**
 * @ngdoc overview
 * @name angular.mock
 * @namespace Namespace for all built-in angular mocks.
 *
 * @description
 * `angular.mock` is a namespace for all built-in mocks that ship with angular and automatically
 * replace real services if `angular-mocks.js` file is loaded after `angular.js` and before any
 * tests.
 */
angular.mock = {};

/**
 * @workInProgress
 * @ngdoc service
 * @name angular.mock.service.$browser
 */
function MockBrowser() {
  var self = this,
      expectations = {},
      requests = [];

  this.isMock = true;
  self.url = "http://server";
  self.lastUrl = self.url; // used by url polling fn
  self.pollFns = [];

  // register url polling fn

  self.onHashChange = function(listener) {
    self.pollFns.push(
      function() {
        if (self.lastUrl != self.url) {
          listener();
          self.lastUrl == self.url
        }
      }
    );

    return listener;
  };

  self.xhr = function(method, url, data, callback) {
    if (angular.isFunction(data)) {
      callback = data;
      data = null;
    }
    if (data && angular.isObject(data)) data = angular.toJson(data);
    if (data && angular.isString(data)) url += "|" + data;
    var expect = expectations[method] || {};
    var response = expect[url];
    if (!response) {
      throw {
        message: "Unexpected request for method '" + method + "' and url '" + url + "'.",
        name: "Unexpected Request"
      };
    }
    requests.push(function(){
      callback(response.code, response.response);
    });
  };
  self.xhr.expectations = expectations;
  self.xhr.requests = requests;
  self.xhr.expect = function(method, url, data) {
    if (data && angular.isObject(data)) data = angular.toJson(data);
    if (data && angular.isString(data)) url += "|" + data;
    var expect = expectations[method] || (expectations[method] = {});
    return {
      respond: function(code, response) {
        if (!angular.isNumber(code)) {
          response = code;
          code = 200;
        }
        expect[url] = {code:code, response:response};
      }
    };
  };
  self.xhr.expectGET    = angular.bind(self, self.xhr.expect, 'GET');
  self.xhr.expectPOST   = angular.bind(self, self.xhr.expect, 'POST');
  self.xhr.expectDELETE = angular.bind(self, self.xhr.expect, 'DELETE');
  self.xhr.expectPUT    = angular.bind(self, self.xhr.expect, 'PUT');
  self.xhr.expectJSON   = angular.bind(self, self.xhr.expect, 'JSON');
  self.xhr.flush = function() {
    if (requests.length == 0) {
      throw new Error("No xhr requests to be flushed!");
    }

    while(requests.length) {
      requests.pop()();
    }
  };

  self.cookieHash = {};
  self.lastCookieHash = {};
  self.deferredFns = [];

  self.defer = function(fn) {
    self.deferredFns.push(fn);
  };

  self.defer.flush = function() {
    while (self.deferredFns.length) self.deferredFns.shift()();
  };
}
MockBrowser.prototype = {

  poll: function poll(){
    angular.forEach(this.pollFns, function(pollFn){
      pollFn();
    });
  },

  addPollFn: function(pollFn) {
    this.pollFns.push(pollFn);
    return pollFn;
  },

  hover: function(onHover) {
  },

  getUrl: function(){
    return this.url;
  },

  setUrl: function(url){
    this.url = url;
  },

  cookies:  function(name, value) {
    if (name) {
      if (value == undefined) {
        delete this.cookieHash[name];
      } else {
        if (angular.isString(value) &&       //strings only
            value.length <= 4096) {          //strict cookie storage limits
          this.cookieHash[name] = value;
        }
      }
    } else {
      if (!angular.equals(this.cookieHash, this.lastCookieHash)) {
        this.lastCookieHash = angular.copy(this.cookieHash);
        this.cookieHash = angular.copy(this.cookieHash);
      }
      return this.cookieHash;
    }
  }
};

angular.service('$browser', function(){
  return new MockBrowser();
});

/**
 * @workInProgress
 * @ngdoc service
 * @name angular.mock.service.$exceptionHandler
 *
 * @description
 * Mock implementation of {@link angular.service.$exceptionHandler} that rethrows any error passed
 * into `$exceptionHandler`. If any errors are are passed into the handler in tests, it typically
 * means that there is a bug in the application or test, so this mock will make these tests fail.
 *
 * See {@link angular.mock} for more info on angular mocks.
 */
angular.service('$exceptionHandler', function(e) {
  return function(e) {throw e;};
});

/**
 * @workInProgress
 * @ngdoc service
 * @name angular.mock.service.$log
 *
 * @description
 * Mock implementation of {@link angular.service.$log} that gathers all logged messages in arrays
 * (one array per logging level). These arrays are exposed as `logs` property of each of the
 * level-specific log function, e.g. for level `error` the array is exposed as `$log.error.logs`.
 *
 * See {@link angular.mock} for more info on angular mocks.
 */
angular.service('$log', MockLogFactory);

function MockLogFactory() {
  var $log = {
    log: function(){ $log.log.logs.push(arguments); },
    warn: function(){ $log.warn.logs.push(arguments); },
    info: function(){ $log.info.logs.push(arguments); },
    error: function(){ $log.error.logs.push(arguments); }
  };

  $log.log.logs = [];
  $log.warn.logs = [];
  $log.info.logs = [];
  $log.error.logs = [];

  return $log;
}

/**
 * Mock of the Date type which has its timezone specified via constroctor arg.
 *
 * The main purpose is to create Date-like instances with timezone fixed to the specified timezone
 * offset, so that we can test code that depends on local timezone settings without dependency on
 * the time zone settings of the machine where the code is running.
 *
 * @param {number} offset Offset of the *desired* timezone in hours (fractions will be honored)
 * @param {(number|string)} timestamp Timestamp representing the desired time in *UTC*
 *
 * @example
 * !!!! WARNING !!!!!
 * This is not a complete Date object so only methods that were implemented can be called safely.
 * To make matters worse, TzDate instances inherit stuff from Date via a prototype.
 *
 * We do our best to intercept calls to "unimplemented" methods, but since the list of methods is
 * incomplete we might be missing some non-standard methods. This can result in errors like:
 * "Date.prototype.foo called on incompatible Object".
 *
 * <pre>
 * var newYearInBratislava = new TzDate(-1, '2009-12-31T23:00:00Z');
 * newYearInBratislava.getTimezoneOffset() => -60;
 * newYearInBratislava.getFullYear() => 2010;
 * newYearInBratislava.getMonth() => 0;
 * newYearInBratislava.getDate() => 1;
 * newYearInBratislava.getHours() => 0;
 * newYearInBratislava.getMinutes() => 0;
 * </pre>
 *
 */
function TzDate(offset, timestamp) {
  if (angular.isString(timestamp)) {
    var tsStr = timestamp;

    this.origDate = angular.String.toDate(timestamp);

    timestamp = this.origDate.getTime();
    if (isNaN(timestamp))
      throw {
        name: "Illegal Argument",
        message: "Arg '" + tsStr + "' passed into TzDate constructor is not a valid date string"
      };
  } else {
    this.origDate = new Date(timestamp);
  }

  var localOffset = new Date(timestamp).getTimezoneOffset();
  this.offsetDiff = localOffset*60*1000 - offset*1000*60*60;
  this.date = new Date(timestamp + this.offsetDiff);

  this.getTime = function() {
    return this.date.getTime() - this.offsetDiff;
  };

  this.toLocaleDateString = function() {
    return this.date.toLocaleDateString();
  };

  this.getFullYear = function() {
    return this.date.getFullYear();
  };

  this.getMonth = function() {
    return this.date.getMonth();
  };

  this.getDate = function() {
    return this.date.getDate();
  };

  this.getHours = function() {
    return this.date.getHours();
  };

  this.getMinutes = function() {
    return this.date.getMinutes();
  };

  this.getSeconds = function() {
    return this.date.getSeconds();
  };

  this.getTimezoneOffset = function() {
    return offset * 60;
  };

  this.getUTCFullYear = function() {
    return this.origDate.getUTCFullYear();
  };

  this.getUTCMonth = function() {
    return this.origDate.getUTCMonth();
  };

  this.getUTCDate = function() {
    return this.origDate.getUTCDate();
  };

  this.getUTCHours = function() {
    return this.origDate.getUTCHours();
  };

  this.getUTCMinutes = function() {
    return this.origDate.getUTCMinutes();
  };

  this.getUTCSeconds = function() {
    return this.origDate.getUTCSeconds();
  };

  //hide all methods not implemented in this mock that the Date prototype exposes
  var unimplementedMethods = ['getDay', 'getMilliseconds', 'getTime', 'getUTCDay',
      'getUTCMilliseconds', 'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds',
      'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear',
      'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds',
      'setYear', 'toDateString', 'toJSON', 'toGMTString', 'toLocaleFormat', 'toLocaleString',
      'toLocaleTimeString', 'toSource', 'toString', 'toTimeString', 'toUTCString', 'valueOf'];

  angular.forEach(unimplementedMethods, function(methodName) {
    this[methodName] = function() {
      throw {
        name: "MethodNotImplemented",
        message: "Method '" + methodName + "' is not implemented in the TzDate mock"
      };
    };
  });
}

//make "tzDateInstance instanceof Date" return true
TzDate.prototype = Date.prototype;
<commit_msg>fix typo in $browser mock<commit_after>/**
 * The MIT License
 *
 * Copyright (c) 2010 Adam Abrons and Misko Hevery http://getangular.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.
 */

/*

 NUGGGGGH MUST TONGUE WANGS
                           \
                                .....
                               C C  /
                              /<   /
               ___ __________/_#__=o
              /(- /(\_\________   \
              \ ) \ )_      \o     \
              /|\ /|\       |'     |
                            |     _|
                            /o   __\
                           / '     |
                          / /      |
                         /_/\______|
                        (   _(    <
                         \    \    \
                          \    \    |
                           \____\____\
                           ____\_\__\_\
                         /`   /`     o\
                         |___ |_______|.. . b'ger

 IN THE FINAL BUILD THIS FILE DOESN'T HAVE DIRECT ACCESS TO GLOBAL FUNCTIONS
 DEFINED IN Angular.js YOU *MUST* REFER TO THEM VIA angular OBJECT
 (e.g. angular.forEach(...)) AND MAKE SURE THAT THE GIVEN FUNCTION IS EXPORTED
 TO THE angular NAMESPACE in AngularPublic.js

 */

/**
 * @ngdoc overview
 * @name angular.mock
 * @namespace Namespace for all built-in angular mocks.
 *
 * @description
 * `angular.mock` is a namespace for all built-in mocks that ship with angular and automatically
 * replace real services if `angular-mocks.js` file is loaded after `angular.js` and before any
 * tests.
 */
angular.mock = {};

/**
 * @workInProgress
 * @ngdoc service
 * @name angular.mock.service.$browser
 */
function MockBrowser() {
  var self = this,
      expectations = {},
      requests = [];

  this.isMock = true;
  self.url = "http://server";
  self.lastUrl = self.url; // used by url polling fn
  self.pollFns = [];

  // register url polling fn

  self.onHashChange = function(listener) {
    self.pollFns.push(
      function() {
        if (self.lastUrl != self.url) {
          listener();
          self.lastUrl = self.url;
        }
      }
    );

    return listener;
  };

  self.xhr = function(method, url, data, callback) {
    if (angular.isFunction(data)) {
      callback = data;
      data = null;
    }
    if (data && angular.isObject(data)) data = angular.toJson(data);
    if (data && angular.isString(data)) url += "|" + data;
    var expect = expectations[method] || {};
    var response = expect[url];
    if (!response) {
      throw {
        message: "Unexpected request for method '" + method + "' and url '" + url + "'.",
        name: "Unexpected Request"
      };
    }
    requests.push(function(){
      callback(response.code, response.response);
    });
  };
  self.xhr.expectations = expectations;
  self.xhr.requests = requests;
  self.xhr.expect = function(method, url, data) {
    if (data && angular.isObject(data)) data = angular.toJson(data);
    if (data && angular.isString(data)) url += "|" + data;
    var expect = expectations[method] || (expectations[method] = {});
    return {
      respond: function(code, response) {
        if (!angular.isNumber(code)) {
          response = code;
          code = 200;
        }
        expect[url] = {code:code, response:response};
      }
    };
  };
  self.xhr.expectGET    = angular.bind(self, self.xhr.expect, 'GET');
  self.xhr.expectPOST   = angular.bind(self, self.xhr.expect, 'POST');
  self.xhr.expectDELETE = angular.bind(self, self.xhr.expect, 'DELETE');
  self.xhr.expectPUT    = angular.bind(self, self.xhr.expect, 'PUT');
  self.xhr.expectJSON   = angular.bind(self, self.xhr.expect, 'JSON');
  self.xhr.flush = function() {
    if (requests.length == 0) {
      throw new Error("No xhr requests to be flushed!");
    }

    while(requests.length) {
      requests.pop()();
    }
  };

  self.cookieHash = {};
  self.lastCookieHash = {};
  self.deferredFns = [];

  self.defer = function(fn) {
    self.deferredFns.push(fn);
  };

  self.defer.flush = function() {
    while (self.deferredFns.length) self.deferredFns.shift()();
  };
}
MockBrowser.prototype = {

  poll: function poll(){
    angular.forEach(this.pollFns, function(pollFn){
      pollFn();
    });
  },

  addPollFn: function(pollFn) {
    this.pollFns.push(pollFn);
    return pollFn;
  },

  hover: function(onHover) {
  },

  getUrl: function(){
    return this.url;
  },

  setUrl: function(url){
    this.url = url;
  },

  cookies:  function(name, value) {
    if (name) {
      if (value == undefined) {
        delete this.cookieHash[name];
      } else {
        if (angular.isString(value) &&       //strings only
            value.length <= 4096) {          //strict cookie storage limits
          this.cookieHash[name] = value;
        }
      }
    } else {
      if (!angular.equals(this.cookieHash, this.lastCookieHash)) {
        this.lastCookieHash = angular.copy(this.cookieHash);
        this.cookieHash = angular.copy(this.cookieHash);
      }
      return this.cookieHash;
    }
  }
};

angular.service('$browser', function(){
  return new MockBrowser();
});

/**
 * @workInProgress
 * @ngdoc service
 * @name angular.mock.service.$exceptionHandler
 *
 * @description
 * Mock implementation of {@link angular.service.$exceptionHandler} that rethrows any error passed
 * into `$exceptionHandler`. If any errors are are passed into the handler in tests, it typically
 * means that there is a bug in the application or test, so this mock will make these tests fail.
 *
 * See {@link angular.mock} for more info on angular mocks.
 */
angular.service('$exceptionHandler', function(e) {
  return function(e) {throw e;};
});

/**
 * @workInProgress
 * @ngdoc service
 * @name angular.mock.service.$log
 *
 * @description
 * Mock implementation of {@link angular.service.$log} that gathers all logged messages in arrays
 * (one array per logging level). These arrays are exposed as `logs` property of each of the
 * level-specific log function, e.g. for level `error` the array is exposed as `$log.error.logs`.
 *
 * See {@link angular.mock} for more info on angular mocks.
 */
angular.service('$log', MockLogFactory);

function MockLogFactory() {
  var $log = {
    log: function(){ $log.log.logs.push(arguments); },
    warn: function(){ $log.warn.logs.push(arguments); },
    info: function(){ $log.info.logs.push(arguments); },
    error: function(){ $log.error.logs.push(arguments); }
  };

  $log.log.logs = [];
  $log.warn.logs = [];
  $log.info.logs = [];
  $log.error.logs = [];

  return $log;
}

/**
 * Mock of the Date type which has its timezone specified via constroctor arg.
 *
 * The main purpose is to create Date-like instances with timezone fixed to the specified timezone
 * offset, so that we can test code that depends on local timezone settings without dependency on
 * the time zone settings of the machine where the code is running.
 *
 * @param {number} offset Offset of the *desired* timezone in hours (fractions will be honored)
 * @param {(number|string)} timestamp Timestamp representing the desired time in *UTC*
 *
 * @example
 * !!!! WARNING !!!!!
 * This is not a complete Date object so only methods that were implemented can be called safely.
 * To make matters worse, TzDate instances inherit stuff from Date via a prototype.
 *
 * We do our best to intercept calls to "unimplemented" methods, but since the list of methods is
 * incomplete we might be missing some non-standard methods. This can result in errors like:
 * "Date.prototype.foo called on incompatible Object".
 *
 * <pre>
 * var newYearInBratislava = new TzDate(-1, '2009-12-31T23:00:00Z');
 * newYearInBratislava.getTimezoneOffset() => -60;
 * newYearInBratislava.getFullYear() => 2010;
 * newYearInBratislava.getMonth() => 0;
 * newYearInBratislava.getDate() => 1;
 * newYearInBratislava.getHours() => 0;
 * newYearInBratislava.getMinutes() => 0;
 * </pre>
 *
 */
function TzDate(offset, timestamp) {
  if (angular.isString(timestamp)) {
    var tsStr = timestamp;

    this.origDate = angular.String.toDate(timestamp);

    timestamp = this.origDate.getTime();
    if (isNaN(timestamp))
      throw {
        name: "Illegal Argument",
        message: "Arg '" + tsStr + "' passed into TzDate constructor is not a valid date string"
      };
  } else {
    this.origDate = new Date(timestamp);
  }

  var localOffset = new Date(timestamp).getTimezoneOffset();
  this.offsetDiff = localOffset*60*1000 - offset*1000*60*60;
  this.date = new Date(timestamp + this.offsetDiff);

  this.getTime = function() {
    return this.date.getTime() - this.offsetDiff;
  };

  this.toLocaleDateString = function() {
    return this.date.toLocaleDateString();
  };

  this.getFullYear = function() {
    return this.date.getFullYear();
  };

  this.getMonth = function() {
    return this.date.getMonth();
  };

  this.getDate = function() {
    return this.date.getDate();
  };

  this.getHours = function() {
    return this.date.getHours();
  };

  this.getMinutes = function() {
    return this.date.getMinutes();
  };

  this.getSeconds = function() {
    return this.date.getSeconds();
  };

  this.getTimezoneOffset = function() {
    return offset * 60;
  };

  this.getUTCFullYear = function() {
    return this.origDate.getUTCFullYear();
  };

  this.getUTCMonth = function() {
    return this.origDate.getUTCMonth();
  };

  this.getUTCDate = function() {
    return this.origDate.getUTCDate();
  };

  this.getUTCHours = function() {
    return this.origDate.getUTCHours();
  };

  this.getUTCMinutes = function() {
    return this.origDate.getUTCMinutes();
  };

  this.getUTCSeconds = function() {
    return this.origDate.getUTCSeconds();
  };

  //hide all methods not implemented in this mock that the Date prototype exposes
  var unimplementedMethods = ['getDay', 'getMilliseconds', 'getTime', 'getUTCDay',
      'getUTCMilliseconds', 'getYear', 'setDate', 'setFullYear', 'setHours', 'setMilliseconds',
      'setMinutes', 'setMonth', 'setSeconds', 'setTime', 'setUTCDate', 'setUTCFullYear',
      'setUTCHours', 'setUTCMilliseconds', 'setUTCMinutes', 'setUTCMonth', 'setUTCSeconds',
      'setYear', 'toDateString', 'toJSON', 'toGMTString', 'toLocaleFormat', 'toLocaleString',
      'toLocaleTimeString', 'toSource', 'toString', 'toTimeString', 'toUTCString', 'valueOf'];

  angular.forEach(unimplementedMethods, function(methodName) {
    this[methodName] = function() {
      throw {
        name: "MethodNotImplemented",
        message: "Method '" + methodName + "' is not implemented in the TzDate mock"
      };
    };
  });
}

//make "tzDateInstance instanceof Date" return true
TzDate.prototype = Date.prototype;
<|endoftext|>


<commit_before>import {GITHUB_USER_NAME,
  GITHUB_REPO_NAME} from '../utils/constants';
import * as Axis from '../../node_modules/axis.js';

let Octokat = require('octokat');

let octo = new Octokat({});

class GithubApi {

  /**
   * Creates new Octokat instance initialized with the oauth token passed to this method.
   *
   * https://github.com/philschatz/octokat.js#in-a-browser
   *
   * @param {String} token - The oauth token to store in new Octokat instance.
   * @returns {Promise} A promise which resolves after Octokat instance is created with oauth token.
   * @public
   */
  static addTokenToOcto(token){
    return new Promise(resolve => {
      octo = new Octokat({
        token: token
      });
      resolve();
    });
  }

  /**
   * Removes currently stored GitHub oauth token from Octokat instance by
   * overwriting current Octokat instance with a new, empty Ocktokat instance.
   *
   * https://github.com/philschatz/octokat.js#in-a-browser
   *
   * @returns {Promise} A promise which resolves after Octokat instance is overwritten.
   * @public
   */
  static removeTokenFromOcto(){
    return new Promise((resolve) => {
      octo = new Octokat({});
      resolve();
    });
  }

  /**
   * Gets the user object for the currently logged in user.
   *
   * https://developer.github.com/v3/users/#get-the-authenticated-user
   *
   * @returns {Promise} A promise which resolves to a user object, or rejects with a String error message.
   * @public
   */
  static getAuthenticatedUser(){
    return new Promise((resolve, reject) => {
      octo.user.fetch().then(result => {
        resolve(result);
      }).catch(error => {
        console.log(getErrorResponseMsg(error));
        reject("ERROR: GitHub responded with an error.");
      });
    });
  }

  /**
   * Gets a list of repositories owned and/or contributed to by the currently logged in user.
   *
   * https://developer.github.com/v3/repos/#list-your-repositories
   *
   * @returns {Promise} A promise which resolves to a list of repository objects, or rejects with a String error message.
   * @public
   */
  static getCurrentUserAllRepos(){
    return new Promise((resolve, reject) => {
      octo.fromUrl("/user/repos").fetch().then(result => {
        resolve(result);
      }).catch(error => {
        console.log(getErrorResponseMsg(error));
        reject("ERROR: GitHub responded with an error.");
      });
    });
  }

  /**
   * Gets a list of repositories owned by the specified user.
   *
   * https://developer.github.com/v3/repos/#list-user-repositories
   *
   * @param {String} userLogin - A string specifying the user login name for which to get owned repos.
   * @returns {Promise} A promise which resolves to a list of repository objects, or rejects with a String error message.
   * @public
   */
  static getUserOwnedRepos(userLogin){
    return new Promise((resolve, reject) => {
      octo.users(userLogin).repos.fetch().then(result => {
        resolve(result);
      }).catch(error => {
        console.log(getErrorResponseMsg(error));
        reject("ERROR: GitHub responded with an error.");
      });
    });
  }

  /**
   * Gets a list of branches in the specified repo.
   *
   * https://developer.github.com/v3/repos/branches/#list-branches
   *
   * @param {String} ownerLogin - The GitHub username/login ID of the owner of the repo.
   * @param {String} repoName - The name of the repo.
   * @returns {Promise} A promise which resolves to a list of branch objects, or rejects with a String error message.
   * @public
   */
  static getBranchesInRepo(ownerLogin, repoName){
    return new Promise((resolve, reject) => {
      octo.repos(ownerLogin, repoName).branches.fetch().then(result => {
        resolve(result);
      }).catch(error => {
        console.log(getErrorResponseMsg(error));
        reject("ERROR: GitHub responded with an error when fetching branches in repo '" + ownerLogin + "/" + repoName + "'");
      });
    });
  }

  /**
   * Gets a list of statuses for the specified commit reference in reverse chronological order.
   *
   * https://developer.github.com/v3/repos/statuses/#list-statuses-for-a-specific-ref
   *
   * @param {String} commitRef - A string specifying the commit reference (can be commit SHA ID, branch name, or tag name).
   * @returns {Promise} A promise which resolves to a list of commit status objects, or rejects with a String error message.
   * @public
   */
  static getStatusesForCommit(commitRef){
    return new Promise((resolve, reject) => {
      let isCommitRefParamValid = false;

      if(Axis.isString(commitRef) === true){
        if(commitRef.length > 0){
          isCommitRefParamValid = true;
        }
      }

      if(isCommitRefParamValid){
        octo.repos(GITHUB_USER_NAME, GITHUB_REPO_NAME).commits(commitRef).statuses.fetch().then(result => {
          resolve(result);
        }).catch(error => {
          console.log(getErrorResponseMsg(error));
          reject("ERROR: GitHub responded with an error.");
        });
      }else{
        reject("ERROR: Invalid commitRef parameter passed to GithubApi component.");
      }

    });
  }
}

/**
 * Parse 'error.message' from error JSON string to JavaScript object.
 *
 * @param {String} error - The error returned from GitHub as a JSON string.
 * @returns {Object} The 'error.message' JSON parsed to an object.
 * @private
 */
function parseErrorResponse(error){
  let errObj = JSON.parse(error.message);
  return errObj;
}

/**
 * Parse 'error.message.message' from error JSON string to JavaScript object.
 *
 * @param {String} error - The error returned from GitHub as a JSON string.
 * @returns {Object} The 'error.message.message' JSON parsed to an object.
 * @private
 */
function getErrorResponseMsg(error){
  let errObj = parseErrorResponse(error);
  let errMsg = errObj.message;

  return errMsg;
}

export default GithubApi;
<commit_msg>Add getCommitsOnBranch method to githubAPI.js<commit_after>import {GITHUB_USER_NAME,
  GITHUB_REPO_NAME} from '../utils/constants';
import * as Axis from '../../node_modules/axis.js';

let Octokat = require('octokat');

let octo = new Octokat({});

class GithubApi {

  /**
   * Creates new Octokat instance initialized with the oauth token passed to this method.
   *
   * https://github.com/philschatz/octokat.js#in-a-browser
   *
   * @param {String} token - The oauth token to store in new Octokat instance.
   * @returns {Promise} A promise which resolves after Octokat instance is created with oauth token.
   * @public
   */
  static addTokenToOcto(token){
    return new Promise(resolve => {
      octo = new Octokat({
        token: token
      });
      resolve();
    });
  }

  /**
   * Removes currently stored GitHub oauth token from Octokat instance by
   * overwriting current Octokat instance with a new, empty Ocktokat instance.
   *
   * https://github.com/philschatz/octokat.js#in-a-browser
   *
   * @returns {Promise} A promise which resolves after Octokat instance is overwritten.
   * @public
   */
  static removeTokenFromOcto(){
    return new Promise((resolve) => {
      octo = new Octokat({});
      resolve();
    });
  }

  /**
   * Gets the user object for the currently logged in user.
   *
   * https://developer.github.com/v3/users/#get-the-authenticated-user
   *
   * @returns {Promise} A promise which resolves to a user object, or rejects with a String error message.
   * @public
   */
  static getAuthenticatedUser(){
    return new Promise((resolve, reject) => {
      octo.user.fetch().then(result => {
        resolve(result);
      }).catch(error => {
        console.log(getErrorResponseMsg(error));
        reject("ERROR: GitHub responded with an error.");
      });
    });
  }

  /**
   * Gets a list of repositories owned and/or contributed to by the currently logged in user.
   *
   * https://developer.github.com/v3/repos/#list-your-repositories
   *
   * @returns {Promise} A promise which resolves to a list of repository objects, or rejects with a String error message.
   * @public
   */
  static getCurrentUserAllRepos(){
    return new Promise((resolve, reject) => {
      octo.fromUrl("/user/repos").fetch().then(result => {
        resolve(result);
      }).catch(error => {
        console.log(getErrorResponseMsg(error));
        reject("ERROR: GitHub responded with an error.");
      });
    });
  }

  /**
   * Gets a list of repositories owned by the specified user.
   *
   * https://developer.github.com/v3/repos/#list-user-repositories
   *
   * @param {String} userLogin - A string specifying the user login name for which to get owned repos.
   * @returns {Promise} A promise which resolves to a list of repository objects, or rejects with a String error message.
   * @public
   */
  static getUserOwnedRepos(userLogin){
    return new Promise((resolve, reject) => {
      octo.users(userLogin).repos.fetch().then(result => {
        resolve(result);
      }).catch(error => {
        console.log(getErrorResponseMsg(error));
        reject("ERROR: GitHub responded with an error.");
      });
    });
  }

  /**
   * Gets a list of branches in the specified repo.
   *
   * https://developer.github.com/v3/repos/branches/#list-branches
   *
   * @param {String} ownerLogin - The GitHub username/login ID of the owner of the repo.
   * @param {String} repoName - The name of the repo.
   * @returns {Promise} A promise which resolves to a list of branch objects, or rejects with a String error message.
   * @public
   */
  static getBranchesInRepo(ownerLogin, repoName){
    return new Promise((resolve, reject) => {
      octo.repos(ownerLogin, repoName).branches.fetch().then(result => {
        resolve(result);
      }).catch(error => {
        console.log(getErrorResponseMsg(error));
        reject("ERROR: GitHub responded with an error when fetching branches in repo '" + ownerLogin + "/" + repoName + "'");
      });
    });
  }

  /**
   * Gets a list of commits on the specified branch in the specified repo.
   *
   * https://developer.github.com/v3/repos/commits/#list-commits-on-a-repository
   *
   * @param {String} ownerLogin - The GitHub username/login ID of the owner of the repo.
   * @param {String} repoName - The name of the repo.
   * @param {String} branchName - The name of the branch.
   * @returns {Promise} A promise which resolves to a list of commit objects, or rejects with a String error message.
   * @public
   */
  static getCommitsOnBranch(ownerLogin, repoName, branchName){
    return new Promise((resolve, reject) => {
      octo.repos(ownerLogin, repoName).commits.fetch({sha: branchName}).then(result => {
        resolve(result);
      }).catch(error => {
        console.log(getErrorResponseMsg(error));
        reject("ERROR: GitHub responded with an error when fetching commits on branch '" + branchName + "' in repo '" + ownerLogin + "/" + repoName + "'");
      });
    });
  }

  /**
   * Gets a list of statuses for the specified commit reference in reverse chronological order.
   *
   * https://developer.github.com/v3/repos/statuses/#list-statuses-for-a-specific-ref
   *
   * @param {String} commitRef - A string specifying the commit reference (can be commit SHA ID, branch name, or tag name).
   * @returns {Promise} A promise which resolves to a list of commit status objects, or rejects with a String error message.
   * @public
   */
  static getStatusesForCommit(commitRef){
    return new Promise((resolve, reject) => {
      let isCommitRefParamValid = false;

      if(Axis.isString(commitRef) === true){
        if(commitRef.length > 0){
          isCommitRefParamValid = true;
        }
      }

      if(isCommitRefParamValid){
        octo.repos(GITHUB_USER_NAME, GITHUB_REPO_NAME).commits(commitRef).statuses.fetch().then(result => {
          resolve(result);
        }).catch(error => {
          console.log(getErrorResponseMsg(error));
          reject("ERROR: GitHub responded with an error.");
        });
      }else{
        reject("ERROR: Invalid commitRef parameter passed to GithubApi component.");
      }

    });
  }
}

/**
 * Parse 'error.message' from error JSON string to JavaScript object.
 *
 * @param {String} error - The error returned from GitHub as a JSON string.
 * @returns {Object} The 'error.message' JSON parsed to an object.
 * @private
 */
function parseErrorResponse(error){
  let errObj = JSON.parse(error.message);
  return errObj;
}

/**
 * Parse 'error.message.message' from error JSON string to JavaScript object.
 *
 * @param {String} error - The error returned from GitHub as a JSON string.
 * @returns {Object} The 'error.message.message' JSON parsed to an object.
 * @private
 */
function getErrorResponseMsg(error){
  let errObj = parseErrorResponse(error);
  let errMsg = errObj.message;

  return errMsg;
}

export default GithubApi;
<|endoftext|>


<commit_before>// to run:
//mongo MedBook < data_sets_to_studies.js

print("Starting data_sets_to_studies migration");

// Make a copy of the studies, data_sets, and sample_groups collections
// so that this script can be run many times.
// Then restore from the pre-migration data_sets collection
if (!db.pre_migration_studies.findOne()) {
  db.studies.renameCollection("pre_migration_studies");
  print("renamed old studies collection to pre_migration_studies");
}
if (!db.pre_migration_data_sets.findOne()) {
  db.data_sets.renameCollection("pre_migration_data_sets");
  print("renamed old data_sets collection to pre_migration_data_sets");
}
if (!db.pre_migration_sample_groups.findOne()) {
  db.sample_groups.renameCollection("pre_migration_sample_groups");
  print("renamed old sample_groups collection to pre_migration_sample_groups");
}

db.studies.remove({});
db.data_sets.remove({});
db.sample_groups.remove({});

db.pre_migration_data_sets.copyTo("data_sets");
db.pre_migration_sample_groups.copyTo("sample_groups");
print("restored data_sets, sample_groups from pre_migration collections");

// define the migration data (used below)
var idToMigrationData = {
  // WCDT (hg19)
  "54795e11b089fea9740779e4": {
    name: "West Coast Dream Team",
    study_label: "prad_wcdt",
    metadata: {
      normalization: "quan_norm_counts",
      value_scaling: "log2(x+1)",
      quantification_method: "rsem",
      genome_assembly: "hg19",
      read_strandedness: "unknown",
    }
  },
  "8j67EfaMQQB7zqQuC": {
    name: "TCGA prostate",
    study_label: "prad_tcga",
    metadata: {
      normalization: "quan_norm_counts",
      value_scaling: "log2(x+1)",
      quantification_method: "rsem",
      genome_assembly: "hg19",
      read_strandedness: "unknown",
    }
  },
  "hf32gGj3sezG9t9ME": {
    name: "Beltran prostate NE",
    study_label: "beltran_2011",
    metadata: {
      normalization: "quan_norm_counts",
      value_scaling: "log2(x+1)",
      quantification_method: "rsem",
      genome_assembly: "hg19",
      read_strandedness: "unknown",
    }
  },
  "nzsmSuNiHNnhvsxiw": {
    name: "OHSU JQ1 cell lines",
    study_label: "ohsu_jq1",
    metadata: {
      normalization: "quan_norm_counts",
      value_scaling: "log2(x+1)",
      quantification_method: "rsem",
      genome_assembly: "hg19",
      read_strandedness: "unknown",
    }
  },

  // CKCC (hg38)
  "L5df223T7NMK3Y986": {
    name: "California Kids Cancer Comparison",
    study_label: "ckcc",
    metadata: {
      normalization: "quan_norm_counts",
      value_scaling: "log2(x+1)",
      quantification_method: "rsem",
      genome_assembly: "hg38",
      read_strandedness: "unknown",
    }
  },
  "YDcb7YWfXTdjXbSKX": {
    name: "CKCC Reference Cohort",
    study_label: "ckcc_reference",
    metadata: {
      normalization: "quan_norm_counts",
      value_scaling: "log2(x+1)",
      quantification_method: "rsem",
      genome_assembly: "hg38",
      read_strandedness: "unknown",
    }
  },

  // Ellen's test data
  "Xmr3YCnvvkuBX2SCd": {
    name: "ETK Test Data set",
    study_label: "EKT_test",
    metadata: {
      normalization: "quan_norm_counts",
      value_scaling: "log2(x+1)",
      quantification_method: "rsem",
      genome_assembly: "hg38",
      read_strandedness: "unknown",
    }
  },
  "sH2WdCf9cYQAbWbNG": {
    name: "ETK Mini test set 1",
    study_label: "EKT_mini_test_1",
    metadata: {
      normalization: "quan_norm_counts",
      value_scaling: "log2(x+1)",
      quantification_method: "rsem",
      genome_assembly: "hg38",
      read_strandedness: "unknown",
    }
  },
};

db.data_sets.find().forEach(function (dataSet) {
  // loop through each
  // if there's no migration data, make a note to delete it
  // (delete the data sets that Ellen loaded when she
  // didn't have access to CKCC)
  var migrationData = idToMigrationData[dataSet._id];
  if (migrationData) {
    // make sure I didn't screw up somewhere
    if (dataSet.name !== migrationData.name) {
      print("DATA SET NAME NOT EQUAL TO MIGRATION NAME");
      print("dataSet.name:", dataSet.name);
      print("migrationData.name:", migrationData.name);
      quit(1);
    }

    // set the count for the sample group migration
    idToMigrationData[dataSet._id].sample_count =
        dataSet.gene_expression.length;

    // generate the sample_labels
    var sample_labels = dataSet.gene_expression.map(function(sample_label) {
      return migrationData.study_label + "/" + sample_label;
    });

    // generate the sample_label_index
    var sample_label_index = {};
    sample_labels.forEach(function(sample_label, index) {
      sample_label_index[sample_label] = index;
    });

    // create a study from every data set
    db.studies.insert({
      _id: dataSet._id,
      study_label: migrationData.study_label,
      name: dataSet.name,
      collaborations: dataSet.collaborations,
      description: dataSet.description,
      sample_labels: sample_labels
    });

    // update the data set
    db.data_sets.update({ _id: dataSet._id }, {
      $set: {
        value_type: "gene_expression",
        metadata: migrationData.metadata,
        sample_labels: sample_labels,
        sample_label_index: sample_label_index,
      },
      $unset: {
        gene_expression: 1,
        gene_expression_index: 1,
      },
      $rename: {
        gene_expression_genes: "feature_labels",
        gene_expression_wrangling: "currently_wrangling",
      }
    });

    print("migrated:", dataSet.name);
  } else {
    print("NOT MIGRATED:", dataSet.name,
        "\tdb.data_sets.remove({_id: " + dataSet._id + "});");
  }
});

// rename gene_expression to genomic_expression
if (!db.genomic_expression.findOne()) {
  print("starting move from gene_expression to genomic_expression");
  db.gene_expression.renameCollection("genomic_expression");

  db.genomic_expression.update({}, {
    $rename: {
      rsem_quan_log2: "values",
      gene_label: "feature_label",
    },
  }, { multi: true });
  print("done moving from gene_expression to genomic_expression");
}

// migrate sample groups
db.sample_groups.find().forEach(function (sampleGroup) {
  for (var i = 0; i < sampleGroup.data_sets.length; i++) {
    var dataSet = sampleGroup.data_sets[i];

    var migrationData = idToMigrationData[dataSet.data_set_id];

    // set the name
    dataSet.data_set_name = migrationData.name;

    // figure out the study_label and update all the sample_labels with it
    var study_label = migrationData.study_label;
    dataSet.sample_labels = dataSet.sample_labels.map(function (label) {
      return study_label + "/" + label;
    });

    // rename sample_labels_count ==> sample_count
    dataSet.sample_count = dataSet.sample_labels_count;
    delete dataSet.sample_labels_count;

    // put in the original sample count
    dataSet.unfiltered_sample_count = migrationData.sample_count;

    for (var j = 0; j < dataSet.filters.length; j++) {
      var filterType = dataSet.filters[j].type;

      if (filterType === "data_loaded") {
        // remove the filter
        dataSet.filters.splice(j, 1);
        j--;
        continue;
      } else if (filterType === "sample_label_list") {
        dataSet.filters[j] = {
          type: "include_sample_list",
          options: {
            sample_labels: dataSet.filters[j].options.sample_labels.map(
                  function (label) {
              return study_label + "/" + label;
            })
          },
        }
      } else if (filterType === "exclude_sample_label_list") {
        dataSet.filters[j] = {
          type: "exclude_sample_list",
          options: {
            sample_labels: dataSet.filters[j].options.sample_labels.map(
                  function (label) {
              return study_label + "/" + label;
            }),
          }
        }
      } else {
        print("WHAT");
      }

      dataSet.filters[j].options.sample_count =
          dataSet.filters[j].options.sample_labels.length;
    }
  }

  // put the mutated `data_sets` back into the database
  db.sample_groups.update({ _id: sampleGroup._id }, {
    $set: {
      data_sets: sampleGroup.data_sets,
      value_type: "gene_expression"
    }
  });
});

print("DONE");
<commit_msg>DataSet/Studies migration bugfix<commit_after>// to run:
//mongo MedBook < data_sets_to_studies.js

print("Starting data_sets_to_studies migration");

// Make a copy of the studies, data_sets, and sample_groups collections
// so that this script can be run many times.
// Then restore from the pre-migration data_sets collection
if (!db.pre_migration_studies.findOne()) {
  db.studies.renameCollection("pre_migration_studies");
  print("renamed old studies collection to pre_migration_studies");
}
if (!db.pre_migration_data_sets.findOne()) {
  db.data_sets.renameCollection("pre_migration_data_sets");
  print("renamed old data_sets collection to pre_migration_data_sets");
}
if (!db.pre_migration_sample_groups.findOne()) {
  db.sample_groups.renameCollection("pre_migration_sample_groups");
  print("renamed old sample_groups collection to pre_migration_sample_groups");
}

db.studies.remove({});
db.data_sets.remove({});
db.sample_groups.remove({});

db.pre_migration_data_sets.copyTo("data_sets");
db.pre_migration_sample_groups.copyTo("sample_groups");
print("restored data_sets, sample_groups from pre_migration collections");

// define the migration data (used below)
var idToMigrationData = {
  // WCDT (hg19)
  "54795e11b089fea9740779e4": {
    name: "West Coast Dream Team",
    study_label: "prad_wcdt",
    metadata: {
      normalization: "quan_norm_counts",
      value_scaling: "log2(x+1)",
      quantification_method: "rsem",
      genome_assembly: "hg19",
      read_strandedness: "unknown",
    }
  },
  "8j67EfaMQQB7zqQuC": {
    name: "TCGA prostate",
    study_label: "prad_tcga",
    metadata: {
      normalization: "quan_norm_counts",
      value_scaling: "log2(x+1)",
      quantification_method: "rsem",
      genome_assembly: "hg19",
      read_strandedness: "unknown",
    }
  },
  "hf32gGj3sezG9t9ME": {
    name: "Beltran prostate NE",
    study_label: "beltran_2011",
    metadata: {
      normalization: "quan_norm_counts",
      value_scaling: "log2(x+1)",
      quantification_method: "rsem",
      genome_assembly: "hg19",
      read_strandedness: "unknown",
    }
  },
  "nzsmSuNiHNnhvsxiw": {
    name: "OHSU JQ1 cell lines",
    study_label: "ohsu_jq1",
    metadata: {
      normalization: "quan_norm_counts",
      value_scaling: "log2(x+1)",
      quantification_method: "rsem",
      genome_assembly: "hg19",
      read_strandedness: "unknown",
    }
  },

  // CKCC (hg38)
  "L5df223T7NMK3Y986": {
    name: "California Kids Cancer Comparison",
    study_label: "ckcc",
    metadata: {
      normalization: "quan_norm_counts",
      value_scaling: "log2(x+1)",
      quantification_method: "rsem",
      genome_assembly: "hg38",
      read_strandedness: "unknown",
    }
  },
  "YDcb7YWfXTdjXbSKX": {
    name: "CKCC Reference Cohort",
    study_label: "ckcc_reference",
    metadata: {
      normalization: "quan_norm_counts",
      value_scaling: "log2(x+1)",
      quantification_method: "rsem",
      genome_assembly: "hg38",
      read_strandedness: "unknown",
    }
  },

  // Ellen's test data
  "Xmr3YCnvvkuBX2SCd": {
    name: "ETK Test Data set",
    study_label: "EKT_test",
    metadata: {
      normalization: "quan_norm_counts",
      value_scaling: "log2(x+1)",
      quantification_method: "rsem",
      genome_assembly: "hg38",
      read_strandedness: "unknown",
    }
  },
  "sH2WdCf9cYQAbWbNG": {
    name: "ETK Mini test set 1",
    study_label: "EKT_mini_test_1",
    metadata: {
      normalization: "quan_norm_counts",
      value_scaling: "log2(x+1)",
      quantification_method: "rsem",
      genome_assembly: "hg38",
      read_strandedness: "unknown",
    }
  },
};

db.data_sets.find().forEach(function (dataSet) {
  // loop through each
  // if there's no migration data, make a note to delete it
  // (delete the data sets that Ellen loaded when she
  // didn't have access to CKCC)
  var migrationData = idToMigrationData[dataSet._id];
  if (migrationData) {
    // make sure I didn't screw up somewhere
    if (dataSet.name !== migrationData.name) {
      print("DATA SET NAME NOT EQUAL TO MIGRATION NAME");
      print("dataSet.name:", dataSet.name);
      print("migrationData.name:", migrationData.name);
      quit(1);
    }

    // set the count for the sample group migration
    idToMigrationData[dataSet._id].sample_count =
        dataSet.gene_expression.length;

    // generate the sample_labels
    var sample_labels = dataSet.gene_expression.map(function(sample_label) {
      return migrationData.study_label + "/" + sample_label;
    });

    // generate the sample_label_index
    var sample_label_index = {};
    sample_labels.forEach(function(sample_label, index) {
      sample_label_index[sample_label] = index;
    });

    // create a study from every data set
    db.studies.insert({
      _id: dataSet._id,
      study_label: migrationData.study_label,
      name: dataSet.name,
      collaborations: dataSet.collaborations,
      description: dataSet.description,
      sample_labels: sample_labels
    });

    // update the data set
    db.data_sets.update({ _id: dataSet._id }, {
      $set: {
        value_type: "gene_expression",
        metadata: migrationData.metadata,
        sample_labels: sample_labels,
        sample_label_index: sample_label_index,
      },
      $unset: {
        gene_expression: 1,
        gene_expression_index: 1,
      },
      $rename: {
        gene_expression_genes: "feature_labels",
        gene_expression_wrangling: "currently_wrangling",
      }
    });

    print("migrated:", dataSet.name);
  } else {
    print("NOT MIGRATED:", dataSet.name,
        "\tdb.data_sets.remove({_id: " + dataSet._id + "});");
  }
});

// rename gene_expression to genomic_expression
if (!db.genomic_expression.findOne()) {
  print("starting move from gene_expression to genomic_expression");
  db.genomic_expression.drop()
  db.gene_expression.renameCollection("genomic_expression");

  db.genomic_expression.update({}, {
    $rename: {
      rsem_quan_log2: "values",
      gene_label: "feature_label",
    },
  }, { multi: true });
  print("done moving from gene_expression to genomic_expression");
}

// migrate sample groups
db.sample_groups.find().forEach(function (sampleGroup) {
  for (var i = 0; i < sampleGroup.data_sets.length; i++) {
    var dataSet = sampleGroup.data_sets[i];

    var migrationData = idToMigrationData[dataSet.data_set_id];

    // set the name
    dataSet.data_set_name = migrationData.name;

    // figure out the study_label and update all the sample_labels with it
    var study_label = migrationData.study_label;
    dataSet.sample_labels = dataSet.sample_labels.map(function (label) {
      return study_label + "/" + label;
    });

    // rename sample_labels_count ==> sample_count
    dataSet.sample_count = dataSet.sample_labels_count;
    delete dataSet.sample_labels_count;

    // put in the original sample count
    dataSet.unfiltered_sample_count = migrationData.sample_count;

    for (var j = 0; j < dataSet.filters.length; j++) {
      var filterType = dataSet.filters[j].type;

      if (filterType === "data_loaded") {
        // remove the filter
        dataSet.filters.splice(j, 1);
        j--;
        continue;
      } else if (filterType === "sample_label_list") {
        dataSet.filters[j] = {
          type: "include_sample_list",
          options: {
            sample_labels: dataSet.filters[j].options.sample_labels.map(
                  function (label) {
              return study_label + "/" + label;
            })
          },
        }
      } else if (filterType === "exclude_sample_label_list") {
        dataSet.filters[j] = {
          type: "exclude_sample_list",
          options: {
            sample_labels: dataSet.filters[j].options.sample_labels.map(
                  function (label) {
              return study_label + "/" + label;
            }),
          }
        }
      } else {
        print("WHAT");
      }

      dataSet.filters[j].options.sample_count =
          dataSet.filters[j].options.sample_labels.length;
    }
  }

  // put the mutated `data_sets` back into the database
  db.sample_groups.update({ _id: sampleGroup._id }, {
    $set: {
      data_sets: sampleGroup.data_sets,
      value_type: "gene_expression"
    }
  });
});

print("DONE");
<|endoftext|>


<commit_before>'use strict';

// NOTE: we only use the index on the primary key -- in future support indexes (NEED MORE NOTES ON
// THIS!!)
// TODO: because of indexing complexity need one store per DB?

var Promise = require('bluebird'),
  inherits = require('inherits'),
  CommonDB = require('../../common/db'),
  Collection = require('./collection'),
  utils = require('../../../../utils'),
  idbUtils = require('./utils'),
  clientUtils = require('../../../../client/utils');

if (global.window && !idbUtils.indexedDB()) { // in browser and no IndexedDB support?
  // Use a shim as phantomjs doesn't support indexedDB
  require('indexeddbshim'); // Automatically sets window.shimIndexedDB
}

/**
 * It appears that the IndexedDB spec takes some shortcuts. In order to create an object store, you
 * need to first close any open DB then re-open while triggering a DB upgrade. Therefore, you need
 * to worry about synchronizing transactions so that you are not executing a transaction while
 * opening/closing a DB or vise-versa. We'll handle this detail in this adapter so that the end user
 * doesn't have to.
 *
 * Synchronization:
 * - The initial open is triggered by the constructor and the 'open' event is fired when the open
 *   has completed
 * - All open/close operations are queued together as they need to be executed in sequence as the
 *   same IndexedDB cannot be opened/closed simulatenously
 * - All transactions are queued together as they can be executed simulatenously, but not during any
 *   open/closes
 * - Upon queuing a open/close or transaction the _processQueue() is triggered, which ensures that
 *   the above rules are followed
 * - After the first open has completed, _processQueue() is called in case any processes have been
 *   queued before the initial open
 */
var DB = function () {
  CommonDB.apply(this, arguments); // apply parent constructor
  this._cols = {};
  this._pendingObjectStores = [];

  // Promise that guarantees that DB is open
  this._opened = utils.once(this, 'open');

  this._opensCloses = []; // used to synchronize open/close transactions
  this._transactions = []; // used to synchronize transactions

  this._load();
};

inherits(DB, CommonDB);

DB.prototype._setDB = function (request) {
  this._db = request.result;
  this._version = parseInt(this._db.version);
};

// Package open as a promise so that we can consolidate code and provide a single place to test the
// error case
DB.prototype._open = function (onUpgradeNeeded, onSuccess) {
  var self = this;
  return new Promise(function (resolve, reject) {
    var request = null;
    if (self._version) {
      request = idbUtils.indexedDB().open(self._name, self._version);
    } else { // 1st time opening?
      request = idbUtils.indexedDB().open(self._name);
    }

    request.onupgradeneeded = function () {
      self._setDB(request);
      if (onUpgradeNeeded) {
        onUpgradeNeeded(request, resolve);
      }
    };

    request.onsuccess = function () {
      self._setDB(request);
      onSuccess(request, resolve);
      self.emit('open');

      // Process queue in case transactions have been waiting for this open
      self._processQueue();
    };

    // TODO: how to test onerror as FF doesn't call onerror for VersionError?
    /* istanbul ignore next */
    request.onerror = function () {
      reject(request.error);
    };
  });
};

DB.prototype._initStore = function () {
  var self = this;
  return self._open(null, function (request, resolve) {
    resolve();
  });
};

DB.prototype._openAndCreateObjectStore = function (name) {
  var self = this;

  var onUpgradeNeeded = function (request) {
    self._db.createObjectStore(name, {
      keyPath: self._idName
    });
  };

  var onSuccess = function (request, resolve) {
    resolve();
  };

  // Close any existing connection. We cannot reopen until we close first
  return self._close().then(function () {
    self._version++; // Increment the version that we can add the object store
    return self._open(onUpgradeNeeded, onSuccess);
  });
};

DB.prototype._getOrCreateObjectStore = function (name) {
  if (this._db.objectStoreNames.contains(name)) { // exists?
    return Promise.resolve();
  } else {
    return this._openAndCreateObjectStore(name);
  }
};

DB.prototype._createObjectStore = function (name) {
  var self = this;
  // Make sure cols have been loaded before trying to create cols so that we don't create a col that
  // already exists
  return self._loaded.then(function () {
    return self._openClose(function () {
      return self._getOrCreateObjectStore(name);
    });
  });
};

DB.prototype.col = function (name) {
  if (this._cols[name]) { // exists?
    return this._cols[name];
  } else {
    var col = new Collection(this, name);
    this._cols[name] = col;
    return col;
  }
};

DB.prototype._close = function () {
  var self = this;
  return new Promise(function (resolve) {
    if (self._db) { // db already opened?
      self._db.close(); // Close is synchronous
    }
    resolve();
  });
};

DB.prototype.close = function () {
  var self = this;
  return self._openClose(function () {
    return self._close();
  });
};

DB.prototype._queueOpenClose = function (promise) {
  this._opensCloses.push(promise);
};

DB.prototype._queueTransaction = function (promise) {
  this._transactions.push(promise);
};

DB.prototype._promiseFactory = function (promise) {
  return function () {
    return promise();
  };
};

DB.prototype._processOpensCloses = function () {
  // We need to process these sequentially as we can only open/close the DB in a synchronized way
  var chain = Promise.resolve();
  while (this._opensCloses.length > 0) { // more?
    var promise = this._opensCloses.shift();
    chain = chain.then(this._promiseFactory(promise));
  }
  return chain;
};

DB.prototype._processTransactions = function () {
  // We can process transactions simulatenously
  var promises = [];
  while (this._transactions.length > 0) { // more?
    var promise = this._transactions.shift();
    promises.push(promise()); // Need to execute the promise
  }
  return Promise.all(promises);
};

DB.prototype._moreToProcess = function () {
  return this._transactions.length > 0 || this._opensCloses.length > 0;
};

DB.prototype._processQueue = function () {
  var self = this;

  if (!self._processingQueue) { // not already processing?
    self._processingQueue = true; // allow others to know that we are processing the queue

    // Make sure the DB is open
    return self._opened.then(function () {
      // First process any opens/closes
      return self._processOpensCloses();
    }).then(function () {
      // Then process any executing transactions
      return self._processTransactions();
    }).then(function () {
      self._processingQueue = false; // allow others to know we are done

      // Has anything been queued since we started processing?
      if (self._moreToProcess()) {
        self._processQueue(); // process again
      }
    });
  }
};

DB.prototype._transaction = function (promise) {
  var self = this;
  return new Promise(function (resolve) {
    self._queueTransaction(function () {
      var resolvedPromise = promise();

      // Resolve after promise resolves so that processQueue() can wait for resolution
      resolve(resolvedPromise);

      // Return promise so caller can wait for resolution
      return resolvedPromise;
    });
    self._processQueue();
  });
};

DB.prototype._openClose = function (promise) {
  var self = this;
  return new Promise(function (resolve) {
    self._queueOpenClose(function () {
      var resolvedPromise = promise();

      // Resolve after promise resolves so that processQueue() can wait for resolution
      resolve(resolvedPromise);

      // Return promise so caller can wait for resolution
      return resolvedPromise;
    });
    self._processQueue();
  });
};

DB.prototype._destroy = function () {
  var self = this;
  return new Promise(function (resolve, reject) {
    var req = idbUtils.indexedDB().deleteDatabase(self._name);

    req.onsuccess = function () {
      resolve();
    };

    // TODO: how to trigger this for testing?
    /* istanbul ignore next */
    req.onerror = function () {
      reject(new Error("Couldn't destroy database: ") + req.err);
    };

    // TODO: how to trigger this for testing?
    /* istanbul ignore next */
    req.onblocked = function () {
      reject(new Error("Couldn't destroy database as blocked: " + req.err));
    };
  });
};

DB.prototype._closeDestroyUnregister = function () {
  var self = this;
  // The DB must be closed before we destroy it
  return self._close().then(function () {
    return self._destroy();
  }).then(function () {
    return self._adapter._unregister(self._name);
  });
};

DB.prototype.destroy = function () {
  var self = this;
  return self._openClose(function () {
    return self._closeDestroyUnregister();
  });
};

DB.prototype._closeDBAndDestroyCol = function (colName) {
  // Handle the destroying at the DB layer as we need to first close and then reopen the DB before
  // destroying the col. Oh the joys of IDB!
  var self = this;

  var onUpgradeNeeded = function (request) {
    self._db.deleteObjectStore(colName);
  };

  var onSuccess = function (request, resolve) {
    resolve();
  };

  // Close will coordinate with any existing DB transactions and by the time it resolves there will
  // be a clear path to reopen the DB
  return self._close().then(function () { // Close any existing connection
    self._version++; // Increment the version so that we can trigger an onupgradeneeded
    return self._open(onUpgradeNeeded, onSuccess);
  });
};

DB.prototype._destroyCol = function (colName) {
  var self = this;
  // We wait for the store to be loaded before closing the store as we wait for this same event when
  // creating a store and we don't want to try to close a store before we have opened it.
  return self._loaded.then(function () {
    return self._openClose(function () {
      return self._closeDBAndDestroyCol(colName);
    });
  });
};

DB.prototype.all = function (callback) {
  utils.each(this._cols, callback);
};

DB.prototype._load = function () {
  var self = this,
    promises = [];
  // Init DB store and then load object stores
  return self._initStore().then(function () {
    utils.each(self._db.objectStoreNames, function (name, i) {
      // indexeddbshim creates a 'length' attr that should be ignored
      if (i !== 'length') {
        promises.push(self.col(name));
      }
    });
    return Promise.all(promises).then(function () {
      self.emit('load');
    });
  });
};

module.exports = DB;
<commit_msg>fix(idb): wait for load when destorying db<commit_after>'use strict';

// NOTE: we only use the index on the primary key -- in future support indexes (NEED MORE NOTES ON
// THIS!!)
// TODO: because of indexing complexity need one store per DB?

var Promise = require('bluebird'),
  inherits = require('inherits'),
  CommonDB = require('../../common/db'),
  Collection = require('./collection'),
  utils = require('../../../../utils'),
  idbUtils = require('./utils'),
  clientUtils = require('../../../../client/utils');

if (global.window && !idbUtils.indexedDB()) { // in browser and no IndexedDB support?
  // Use a shim as phantomjs doesn't support indexedDB
  require('indexeddbshim'); // Automatically sets window.shimIndexedDB
}

/**
 * It appears that the IndexedDB spec takes some shortcuts. In order to create an object store, you
 * need to first close any open DB then re-open while triggering a DB upgrade. Therefore, you need
 * to worry about synchronizing transactions so that you are not executing a transaction while
 * opening/closing a DB or vise-versa. We'll handle this detail in this adapter so that the end user
 * doesn't have to.
 *
 * Synchronization:
 * - The initial open is triggered by the constructor and the 'open' event is fired when the open
 *   has completed
 * - All open/close operations are queued together as they need to be executed in sequence as the
 *   same IndexedDB cannot be opened/closed simulatenously
 * - All transactions are queued together as they can be executed simulatenously, but not during any
 *   open/closes
 * - Upon queuing a open/close or transaction the _processQueue() is triggered, which ensures that
 *   the above rules are followed
 * - After the first open has completed, _processQueue() is called in case any processes have been
 *   queued before the initial open
 */
var DB = function () {
  CommonDB.apply(this, arguments); // apply parent constructor
  this._cols = {};
  this._pendingObjectStores = [];

  // Promise that guarantees that DB is open
  this._opened = utils.once(this, 'open');

  this._opensCloses = []; // used to synchronize open/close transactions
  this._transactions = []; // used to synchronize transactions

  this._load();
};

inherits(DB, CommonDB);

DB.prototype._setDB = function (request) {
  this._db = request.result;
  this._version = parseInt(this._db.version);
};

// Package open as a promise so that we can consolidate code and provide a single place to test the
// error case
DB.prototype._open = function (onUpgradeNeeded, onSuccess) {
  var self = this;
  return new Promise(function (resolve, reject) {
    var request = null;
    if (self._version) {
      request = idbUtils.indexedDB().open(self._name, self._version);
    } else { // 1st time opening?
      request = idbUtils.indexedDB().open(self._name);
    }

    request.onupgradeneeded = function () {
      self._setDB(request);
      if (onUpgradeNeeded) {
        onUpgradeNeeded(request, resolve);
      }
    };

    request.onsuccess = function () {
      self._setDB(request);
      onSuccess(request, resolve);
      self.emit('open');

      // Process queue in case transactions have been waiting for this open
      self._processQueue();
    };

    // TODO: how to test onerror as FF doesn't call onerror for VersionError?
    /* istanbul ignore next */
    request.onerror = function () {
      reject(request.error);
    };
  });
};

DB.prototype._initStore = function () {
  var self = this;
  return self._open(null, function (request, resolve) {
    resolve();
  });
};

DB.prototype._openAndCreateObjectStore = function (name) {
  var self = this;

  var onUpgradeNeeded = function (request) {
    self._db.createObjectStore(name, {
      keyPath: self._idName
    });
  };

  var onSuccess = function (request, resolve) {
    resolve();
  };

  // Close any existing connection. We cannot reopen until we close first
  return self._close().then(function () {
    self._version++; // Increment the version that we can add the object store
    return self._open(onUpgradeNeeded, onSuccess);
  });
};

DB.prototype._getOrCreateObjectStore = function (name) {
  if (this._db.objectStoreNames.contains(name)) { // exists?
    return Promise.resolve();
  } else {
    return this._openAndCreateObjectStore(name);
  }
};

DB.prototype._createObjectStore = function (name) {
  var self = this;
  // Make sure cols have been loaded before trying to create cols so that we don't create a col that
  // already exists
  return self._loaded.then(function () {
    return self._openClose(function () {
      return self._getOrCreateObjectStore(name);
    });
  });
};

DB.prototype.col = function (name) {
  if (this._cols[name]) { // exists?
    return this._cols[name];
  } else {
    var col = new Collection(this, name);
    this._cols[name] = col;
    return col;
  }
};

DB.prototype._close = function () {
  var self = this;
  return new Promise(function (resolve) {
    if (self._db) { // db already opened?
      self._db.close(); // Close is synchronous
    }
    resolve();
  });
};

DB.prototype.close = function () {
  var self = this;
  return self._openClose(function () {
    return self._close();
  });
};

DB.prototype._queueOpenClose = function (promise) {
  this._opensCloses.push(promise);
};

DB.prototype._queueTransaction = function (promise) {
  this._transactions.push(promise);
};

DB.prototype._promiseFactory = function (promise) {
  return function () {
    return promise();
  };
};

DB.prototype._processOpensCloses = function () {
  // We need to process these sequentially as we can only open/close the DB in a synchronized way
  var chain = Promise.resolve();
  while (this._opensCloses.length > 0) { // more?
    var promise = this._opensCloses.shift();
    chain = chain.then(this._promiseFactory(promise));
  }
  return chain;
};

DB.prototype._processTransactions = function () {
  // We can process transactions simulatenously
  var promises = [];
  while (this._transactions.length > 0) { // more?
    var promise = this._transactions.shift();
    promises.push(promise()); // Need to execute the promise
  }
  return Promise.all(promises);
};

DB.prototype._moreToProcess = function () {
  return this._transactions.length > 0 || this._opensCloses.length > 0;
};

DB.prototype._processQueue = function () {
  var self = this;

  if (!self._processingQueue) { // not already processing?
    self._processingQueue = true; // allow others to know that we are processing the queue

    // Make sure the DB is open
    return self._opened.then(function () {
      // First process any opens/closes
      return self._processOpensCloses();
    }).then(function () {
      // Then process any executing transactions
      return self._processTransactions();
    }).then(function () {
      self._processingQueue = false; // allow others to know we are done

      // Has anything been queued since we started processing?
      if (self._moreToProcess()) {
        self._processQueue(); // process again
      }
    });
  }
};

DB.prototype._transaction = function (promise) {
  var self = this;
  return new Promise(function (resolve) {
    self._queueTransaction(function () {
      var resolvedPromise = promise();

      // Resolve after promise resolves so that processQueue() can wait for resolution
      resolve(resolvedPromise);

      // Return promise so caller can wait for resolution
      return resolvedPromise;
    });
    self._processQueue();
  });
};

DB.prototype._openClose = function (promise) {
  var self = this;
  return new Promise(function (resolve) {
    self._queueOpenClose(function () {
      var resolvedPromise = promise();

      // Resolve after promise resolves so that processQueue() can wait for resolution
      resolve(resolvedPromise);

      // Return promise so caller can wait for resolution
      return resolvedPromise;
    });
    self._processQueue();
  });
};

DB.prototype._destroy = function () {
  var self = this;
  return new Promise(function (resolve, reject) {
    var req = idbUtils.indexedDB().deleteDatabase(self._name);

    req.onsuccess = function () {
      resolve();
    };

    // TODO: how to trigger this for testing?
    /* istanbul ignore next */
    req.onerror = function () {
      reject(new Error("Couldn't destroy database: ") + req.err);
    };

    // TODO: how to trigger this for testing?
    /* istanbul ignore next */
    req.onblocked = function () {
      reject(new Error("Couldn't destroy database as blocked: " + req.err));
    };
  });
};

DB.prototype._closeDestroyUnregister = function () {
  var self = this;
  // The DB must be closed before we destroy it
  return self._close().then(function () {
    return self._destroy();
  }).then(function () {
    return self._adapter._unregister(self._name);
  });
};

DB.prototype.destroy = function () {
  var self = this;
  // We wait for the store to be loaded before closing the store as we wait for this same event when
  // creating a store and we don't want to try to close a store before we have opened it.
  return self._loaded.then(function () {
    return self._openClose(function () {
      return self._closeDestroyUnregister();
    });
  });
};

DB.prototype._closeDBAndDestroyCol = function (colName) {
  // Handle the destroying at the DB layer as we need to first close and then reopen the DB before
  // destroying the col. Oh the joys of IDB!
  var self = this;

  var onUpgradeNeeded = function (request) {
    self._db.deleteObjectStore(colName);
  };

  var onSuccess = function (request, resolve) {
    resolve();
  };

  // Close will coordinate with any existing DB transactions and by the time it resolves there will
  // be a clear path to reopen the DB
  return self._close().then(function () { // Close any existing connection
    self._version++; // Increment the version so that we can trigger an onupgradeneeded
    return self._open(onUpgradeNeeded, onSuccess);
  });
};

DB.prototype._destroyCol = function (colName) {
  var self = this;
  // We wait for the store to be loaded before closing the store as we wait for this same event when
  // creating a store and we don't want to try to close a store before we have opened it.
  return self._loaded.then(function () {
    return self._openClose(function () {
      return self._closeDBAndDestroyCol(colName);
    });
  });
};

DB.prototype.all = function (callback) {
  utils.each(this._cols, callback);
};

DB.prototype._load = function () {
  var self = this,
    promises = [];
  // Init DB store and then load object stores
  return self._initStore().then(function () {
    utils.each(self._db.objectStoreNames, function (name, i) {
      // indexeddbshim creates a 'length' attr that should be ignored
      if (i !== 'length') {
        promises.push(self.col(name));
      }
    });
    return Promise.all(promises).then(function () {
      self.emit('load');
    });
  });
};

module.exports = DB;
<|endoftext|>


<commit_before>import React from 'react';
import Formsy from 'formsy-react';
import { Checkbox, Select, Input, Textarea } from 'formsy-react-components';
import Separator from '../../../components/Separator';
import './SingleEvent.scss';

class EnrollForm extends React.Component {
  render() {
    const selectOptions = [
    { value: 'a', label: 'Option A' },
    { value: 'a', label: 'Option A (again)' },
    { value: 'b', label: 'Option B' },
    { value: 'c', label: 'Option C' },
    { value: 'd', label: 'Option D' },
    ];

    const singleSelectOptions = selectOptions.slice(0);
    singleSelectOptions.unshift({ value: '', label: 'Please select…' });

    return (

         this.props.closeForm()} />

Ilmoittaudu

Ilmoittautumistilanteesi on: [insert tilanne]

            <Formsy.Form
              onSubmit={this.submitForm}>
              <Input
                name="nimi"
                id="nimiId"
                value=""
                label="Nimi"
                type="text"
                placeholder="Nimesi"
                required />
              <Input
                name="email"
                value=""
                label="Sähköposti"
                type="email"
                placeholder="Sähköpostisi"
                validations="isEmail"
                validationErrors={{
                  isEmail: 'Anna sähköpostisi muodossa pekka@cto.fi',
                }}
                required
              />
              <Textarea className='open-question form-control'
                rows={3}
                cols={40}
                name="avoinKysymys"
                label="Avoin kysymys"
                placeholder="Tämä on avoimen kysymyksen ennakkoteksti."
              />
              <Checkbox
                name="checkbox1"
                value
                label="Valitse minut"
                rowLabel="Klikattava vaihtoehto"
              />
              <Select
                name="select1"
                label="Select"
                options={singleSelectOptions}
                required
              />
              <input className="btn btn-primary pull-right" formNoValidate type="submit" defaultValue="Submit" />
            </Formsy.Form>

    );
  }
}

class AttendButton extends React.Component {
  render() {
    return <button className='btn btn-success btn-block' onClick={() => this.props.openForm()} >
      {this.props.data.quotaName}</button>;
  }
}

class ViewProgress extends React.Component {
  render() {
    return (

        {this.props.data.quotaName}

          <div className="progress-bar" role="progressbar"
            style={{ minWidth: '4em', width: `${(this.props.data.going / this.props.data.max) * 100}%` }}>
            {this.props.data.going}
            <Separator />
            {this.props.data.max}

    );
  }
}

class AttendeeGroup extends React.Component {
  render() {
    const RegistrationRow = attendee =>

        {attendee.data}
        {attendee.data}
        {attendee.data}

;

    return (

{this.props.data.quotaName}

              Sija
              Nimi
              {typeof this.props.data !== 'undefined' ? Oma tsyssäri jos on	 : null }

            {
            this.props.data.attendees.map(
              i =>
                <RegistrationRow data={i} />)
          }

    );
  }
}

class SingleEvent extends React.Component {
  componentWillMount() {
    // get the event with correct id
    this.props.getEventInfo();
  }
  constructor(props) {
    super(props);
    this.state = {
      formOpened: false,
    };

    this.openForm = this.openForm.bind(this);
    this.closeForm = this.closeForm.bind(this);
    this.submitForm = this.submitForm.bind(this);
  }

  openForm() {
    const state = this.state;
    state.formOpened = true;
    this.setState(state);
  }

  closeForm() {
    const state = this.state;
    state.formOpened = false;
    this.setState(state);
  }

  submitForm() {
    const state = this.state;
    state.formOpened = false;
    this.setState(state);
  }
  render() {
    return (

        {this.state.formOpened ? <EnrollForm closeForm={this.closeForm} /> : '' }

{this.props.singleEvent.title}

              {this.props.singleEvent.date}

              Hinta: {this.props.singleEvent.price}

              Facebook-tapahtuma

{this.props.singleEvent.description}

Ilmoittaudu

              {(this.props.singleEvent.quota ? this.props.singleEvent.quota.map((i, index) =>
                <AttendButton openForm={this.openForm} key={index} data={i} />) : '')}

Ilmoittautuneet

              {(this.props.singleEvent.quota ? this.props.singleEvent.quota.map((i, index) =>
                <ViewProgress key={index} data={i} />) : '')}

Ilmoittautuneet

            {(this.props.singleEvent.quota ? this.props.singleEvent.quota.map((i, index) =>
              <AttendeeGroup key={index} data={i} />) : '')}

    );
  }
}

EnrollForm.propTypes = {
  closeForm: React.PropTypes.func.isRequired,
};

AttendButton.propTypes = {
  openForm: React.PropTypes.func.isRequired,
};

ViewProgress.propTypes = {
  data: React.PropTypes.shape({
    quotaName: React.PropTypes.string,
    going: React.PropTypes.number,
    max: React.PropTypes.number,
  }).isRequired,
};

AttendButton.propTypes = {
  data: React.PropTypes.shape({
    quotaName: React.PropTypes.string,
  }).isRequired,
};

AttendeeGroup.propTypes = {
  data: React.PropTypes.shape({
    quotaName: React.PropTypes.string,
    attendees: React.PropTypes.array,
  }).isRequired,
};

SingleEvent.propTypes = {
  getEventInfo: React.PropTypes.func.isRequired,
  params: React.PropTypes.shape({
    id: React.PropTypes.string,
  }).isRequired,
  singleEvent: React.PropTypes.shape({
    title: React.PropTypes.string,
    description: React.PropTypes.string,
    price: React.PropTypes.string,
    date: React.PropTypes.number,
    quota: React.PropTypes.array,
  }),
};

export default SingleEvent;
<commit_msg>Indents fixed<commit_after>import React from 'react';
import Formsy from 'formsy-react';
import { Checkbox, Select, Input, Textarea } from 'formsy-react-components';
import Separator from '../../../components/Separator';
import './SingleEvent.scss';

class EnrollForm extends React.Component {
  render() {
    const selectOptions = [
    { value: 'a', label: 'Option A' },
    { value: 'a', label: 'Option A (again)' },
    { value: 'b', label: 'Option B' },
    { value: 'c', label: 'Option C' },
    { value: 'd', label: 'Option D' },
    ];

    const singleSelectOptions = selectOptions.slice(0);
    singleSelectOptions.unshift({ value: '', label: 'Please select…' });

    return (

           this.props.closeForm()} />

Ilmoittaudu

Ilmoittautumistilanteesi on: [insert tilanne]

            <Formsy.Form
              onSubmit={this.submitForm}>
              <Input
                name="nimi"
                id="nimiId"
                value=""
                label="Nimi"
                type="text"
                placeholder="Nimesi"
                required />
              <Input
                name="email"
                value=""
                label="Sähköposti"
                type="email"
                placeholder="Sähköpostisi"
                validations="isEmail"
                validationErrors={{
                  isEmail: 'Anna sähköpostisi muodossa pekka@cto.fi',
                }}
                required
              />
              <Textarea className='open-question form-control'
                rows={3}
                cols={40}
                name="avoinKysymys"
                label="Avoin kysymys"
                placeholder="Tämä on avoimen kysymyksen ennakkoteksti."
              />
              <Checkbox
                name="checkbox1"
                value
                label="Valitse minut"
                rowLabel="Klikattava vaihtoehto"
              />
              <Select
                name="select1"
                label="Select"
                options={singleSelectOptions}
                required
              />
              <input className="btn btn-primary pull-right" formNoValidate type="submit" defaultValue="Submit" />
            </Formsy.Form>

    );
  }
}

class AttendButton extends React.Component {
  render() {
    return <button className='btn btn-success btn-block' onClick={() => this.props.openForm()} >
      {this.props.data.quotaName}</button>;
  }
}

class ViewProgress extends React.Component {
  render() {
    return (

        {this.props.data.quotaName}

          <div className="progress-bar" role="progressbar"
            style={{ minWidth: '4em', width: `${(this.props.data.going / this.props.data.max) * 100}%` }}>
            {this.props.data.going}
            <Separator />
            {this.props.data.max}

    );
  }
}

class AttendeeGroup extends React.Component {
  render() {
    const RegistrationRow = attendee =>

        {attendee.data}
        {attendee.data}
        {attendee.data}

;

    return (

{this.props.data.quotaName}

              Sija
              Nimi
              {typeof this.props.data !== 'undefined' ? Oma tsyssäri jos on	 : null }

            {
            this.props.data.attendees.map(
              i =>
                <RegistrationRow data={i} />)
          }

    );
  }
}

class SingleEvent extends React.Component {
  componentWillMount() {
    // get the event with correct id
    this.props.getEventInfo();
  }
  constructor(props) {
    super(props);
    this.state = {
      formOpened: false,
    };

    this.openForm = this.openForm.bind(this);
    this.closeForm = this.closeForm.bind(this);
    this.submitForm = this.submitForm.bind(this);
  }

  openForm() {
    const state = this.state;
    state.formOpened = true;
    this.setState(state);
  }

  closeForm() {
    const state = this.state;
    state.formOpened = false;
    this.setState(state);
  }

  submitForm() {
    const state = this.state;
    state.formOpened = false;
    this.setState(state);
  }
  render() {
    return (

        {this.state.formOpened ? <EnrollForm closeForm={this.closeForm} /> : '' }

{this.props.singleEvent.title}

              {this.props.singleEvent.date}

              Hinta: {this.props.singleEvent.price}

              Facebook-tapahtuma

{this.props.singleEvent.description}

Ilmoittaudu

              {(this.props.singleEvent.quota ? this.props.singleEvent.quota.map((i, index) =>
                <AttendButton openForm={this.openForm} key={index} data={i} />) : '')}

Ilmoittautuneet

              {(this.props.singleEvent.quota ? this.props.singleEvent.quota.map((i, index) =>
                <ViewProgress key={index} data={i} />) : '')}

Ilmoittautuneet

            {(this.props.singleEvent.quota ? this.props.singleEvent.quota.map((i, index) =>
              <AttendeeGroup key={index} data={i} />) : '')}

    );
  }
}

EnrollForm.propTypes = {
  closeForm: React.PropTypes.func.isRequired,
};

AttendButton.propTypes = {
  openForm: React.PropTypes.func.isRequired,
};

ViewProgress.propTypes = {
  data: React.PropTypes.shape({
    quotaName: React.PropTypes.string,
    going: React.PropTypes.number,
    max: React.PropTypes.number,
  }).isRequired,
};

AttendButton.propTypes = {
  data: React.PropTypes.shape({
    quotaName: React.PropTypes.string,
  }).isRequired,
};

AttendeeGroup.propTypes = {
  data: React.PropTypes.shape({
    quotaName: React.PropTypes.string,
    attendees: React.PropTypes.array,
  }).isRequired,
};

SingleEvent.propTypes = {
  getEventInfo: React.PropTypes.func.isRequired,
  params: React.PropTypes.shape({
    id: React.PropTypes.string,
  }).isRequired,
  singleEvent: React.PropTypes.shape({
    title: React.PropTypes.string,
    description: React.PropTypes.string,
    price: React.PropTypes.string,
    date: React.PropTypes.number,
    quota: React.PropTypes.array,
  }),
};

export default SingleEvent;
<|endoftext|>