<commit_before>var BCLS = ( function (videoIdArray) {
    // to use another account, set the account_id value appropriately
    // the client_id and client_secret will also need to be changed in the proxy
    var account_id = '57838016001',
        account = document.getElementById('account'),
        logBody = document.getElementById('logBody'),
        loadingMessage = document.getElementById('loadingMessage'),
        clearLogBtn = document.getElementById('clearLogBtn'),
        videoNumber = 0,
        videoNumberMax = videoIdArray.length,
        // set the proxyURL to the location of the proxy app that makes Brightcove API requests
        proxyURL = './brightcove-learning-proxy.php',
        videoDataArray = [],
        videoDataItem = {},
        options = {},
        currentVideo;

        // write out the report table
        function writeReport() {
            var j,
                jMax = videoDataArray.length,
                item;
            loadingMessage.className = 'hidden';
            for (j = 0; j < jMax; j++) {
                item = videoDataArray[j];
                logBody.innerHTML += '
' + item.id + '	' + item.name + '	' + item.reference_id + '	' + item.sources + '
';
            }
        }

        // function to set up video data request
        function setVideoRequestOptions() {
          loadingMessage.textContent = 'Processing video ' + (videoNumber + 1) + ' of ' + videoNumberMax;
            options = {};
            options.url = 'https://cms.api.brightcove.com/v1/accounts/' + account_id + '/videos/' + currentVideo;
            options.proxyURL = proxyURL;
            options.requestType = 'GET';
            console.log(options.url);
            makeRequest(options, function(response) {
              var o = {};
              response = JSON.parse(response);
              o.id = response.id;
              o.reference_id = response.reference_id;
              o.name = response.name;
              videoDataArray.push(o);
              setSourcesRequestOptions();
            });
        };
        // function to set up video sources request
        function setSourcesRequestOptions() {
            options.url = 'https://cms.api.brightcove.com/v1/accounts/' + account_id + '/videos/' + currentVideo + '/sources';
            options.proxyURL = proxyURL;
            options.requestType = 'GET';

            makeRequest(options, function(response) {
              response = JSON.parse(response);
              if (response.length === 0) {
                videoDataArray[videoNumber].sources = 'Ingest failed';
              } else {
                videoDataArray[videoNumber].sources = response.length;
              }

              // increment count and go on if we're not done
              videoNumber++;
              if (videoNumber < videoNumberMax) {
                getVideoInfo();
              } else {
                // we done, write the data
                writeReport();
              }
            });
        }

        // initiates the cms api requests
        function getVideoInfo() {
            if (videoIdArray.length > 0) {
                currentVideo = videoIdArray[videoNumber];
                setVideoRequestOptions();
            } else {
                loadingMessage.innerHTML = 'No videos have been ingested';
            }
        };

        /**
         * send API request to the proxy
         * @param  {Object} options for the request
         * @param  {String} options.url the full API request URL
         * @param  {String="GET","POST","PATCH","PUT","DELETE"} requestData [options.requestType="GET"] HTTP type for the request
         * @param  {String} options.proxyURL proxyURL to send the request to
         * @param  {Function} [callback] callback function that will process the response
         */
        function makeRequest(options, callback) {
            var httpRequest = new XMLHttpRequest(),
                response,
                dataString,
                proxyURL    = options.proxyURL,
                // response handler
                getResponse = function() {
                    try {
                        if (httpRequest.readyState === 4) {
                            if (httpRequest.status >= 200 && httpRequest.status < 300) {
                                response = httpRequest.responseText;
                                // some API requests return '{null}' for empty responses - breaks JSON.parse
                                if (response === '{null}') {
                                    response = null;
                                }
                                // return the response
                                callback(response);
                            } else {
                                alert('There was a problem with the request. Request returned ' + httpRequest.status);
                            }
                        }
                    } catch (e) {
                        alert('Caught Exception: ' + e);
                    }
                };
            /**
             * set up request data
             * the proxy used here takes the following request body:
             * JSON.strinify(options)
             */
            // set response handler
            httpRequest.onreadystatechange = getResponse;
            // open the request
            httpRequest.open('POST', proxyURL);
            // set headers if there is a set header line, remove it
            // open and send request
            httpRequest.send(JSON.stringify(options));
        }

        // event handlers
        clearLogBtn.addEventListener('click', function () {
            if (window.confirm('Are you sure? This action cannot be undone!')) {
                // if your clear-log app resides in another location, change the URL
                window.location.href = 'clear-log.php';
            }
        });
        console.log('videoIdArray', videoIdArray);

        // get things started
        account.innerHTML = account_id;
        getVideoInfo();

    })(videoIdArray);
<commit_msg>placeholders<commit_after>var BCLS = ( function (videoIdArray) {
    // to use another account, set the account_id value appropriately
    // the client_id and client_secret will also need to be changed in the proxy
    var account_id = '***YOUR_ACCOUNT_ID_HERE***',
        account = document.getElementById('account'),
        logBody = document.getElementById('logBody'),
        loadingMessage = document.getElementById('loadingMessage'),
        clearLogBtn = document.getElementById('clearLogBtn'),
        videoNumber = 0,
        videoNumberMax = videoIdArray.length,
        // set the proxyURL to the location of the proxy app that makes Brightcove API requests
        proxyURL = './brightcove-learning-proxy.php',
        videoDataArray = [],
        videoDataItem = {},
        options = {},
        currentVideo;

        // write out the report table
        function writeReport() {
            var j,
                jMax = videoDataArray.length,
                item;
            loadingMessage.className = 'hidden';
            for (j = 0; j < jMax; j++) {
                item = videoDataArray[j];
                logBody.innerHTML += '
' + item.id + '	' + item.name + '	' + item.reference_id + '	' + item.sources + '
';
            }
        }

        // function to set up video data request
        function setVideoRequestOptions() {
          loadingMessage.textContent = 'Processing video ' + (videoNumber + 1) + ' of ' + videoNumberMax;
            options = {};
            options.url = 'https://cms.api.brightcove.com/v1/accounts/' + account_id + '/videos/' + currentVideo;
            options.proxyURL = proxyURL;
            options.requestType = 'GET';
            console.log(options.url);
            makeRequest(options, function(response) {
              var o = {};
              response = JSON.parse(response);
              o.id = response.id;
              o.reference_id = response.reference_id;
              o.name = response.name;
              videoDataArray.push(o);
              setSourcesRequestOptions();
            });
        };
        // function to set up video sources request
        function setSourcesRequestOptions() {
            options.url = 'https://cms.api.brightcove.com/v1/accounts/' + account_id + '/videos/' + currentVideo + '/sources';
            options.proxyURL = proxyURL;
            options.requestType = 'GET';

            makeRequest(options, function(response) {
              response = JSON.parse(response);
              if (response.length === 0) {
                videoDataArray[videoNumber].sources = 'Ingest failed';
              } else {
                videoDataArray[videoNumber].sources = response.length;
              }

              // increment count and go on if we're not done
              videoNumber++;
              if (videoNumber < videoNumberMax) {
                getVideoInfo();
              } else {
                // we done, write the data
                writeReport();
              }
            });
        }

        // initiates the cms api requests
        function getVideoInfo() {
            if (videoIdArray.length > 0) {
                currentVideo = videoIdArray[videoNumber];
                setVideoRequestOptions();
            } else {
                loadingMessage.innerHTML = 'No videos have been ingested';
            }
        };

        /**
         * send API request to the proxy
         * @param  {Object} options for the request
         * @param  {String} options.url the full API request URL
         * @param  {String="GET","POST","PATCH","PUT","DELETE"} requestData [options.requestType="GET"] HTTP type for the request
         * @param  {String} options.proxyURL proxyURL to send the request to
         * @param  {Function} [callback] callback function that will process the response
         */
        function makeRequest(options, callback) {
            var httpRequest = new XMLHttpRequest(),
                response,
                dataString,
                proxyURL    = options.proxyURL,
                // response handler
                getResponse = function() {
                    try {
                        if (httpRequest.readyState === 4) {
                            if (httpRequest.status >= 200 && httpRequest.status < 300) {
                                response = httpRequest.responseText;
                                // some API requests return '{null}' for empty responses - breaks JSON.parse
                                if (response === '{null}') {
                                    response = null;
                                }
                                // return the response
                                callback(response);
                            } else {
                                alert('There was a problem with the request. Request returned ' + httpRequest.status);
                            }
                        }
                    } catch (e) {
                        alert('Caught Exception: ' + e);
                    }
                };
            /**
             * set up request data
             * the proxy used here takes the following request body:
             * JSON.strinify(options)
             */
            // set response handler
            httpRequest.onreadystatechange = getResponse;
            // open the request
            httpRequest.open('POST', proxyURL);
            // set headers if there is a set header line, remove it
            // open and send request
            httpRequest.send(JSON.stringify(options));
        }

        // event handlers
        clearLogBtn.addEventListener('click', function () {
            if (window.confirm('Are you sure? This action cannot be undone!')) {
                // if your clear-log app resides in another location, change the URL
                window.location.href = 'clear-log.php';
            }
        });
        console.log('videoIdArray', videoIdArray);

        // get things started
        account.innerHTML = account_id;
        getVideoInfo();

    })(videoIdArray);
<|endoftext|>


<commit_before>/******************************************************************************
 *	Copyright (c) 2004 Actuate Corporation and others.
 *	All rights reserved. This program and the accompanying materials
 *	are made available under the terms of the Eclipse Public License v1.0
 *	which accompanies this distribution, and is available at
 *		http://www.eclipse.org/legal/epl-v10.html
 *
 *	Contributors:
 *		Actuate Corporation - Initial implementation.
 *****************************************************************************/

var Constants = {

	/** id of document managed BirtReportDocument*/
	documentId: "Document",

	/** element is a UI component managed by BirtReportBase */
	reportBase: "ReportBase",

	/** element is a table managed by BirtReportTable */
	reportTable: "ReportTable",

	/** element is a chart managed by BirtReportChart */
	reportChart: "ReportChart",

	/** element is a document managed BirtReportDocument */
	isDocument: "isDocument",

	/** contains number of selected column if there is one */
	selColNum: "SelColNum",

	/** contains number of selected column if there is one */
	activeIds: "activeIds",
	activeIdTypes: "activeIdTypes",

	// Report object types.
	Document : "Document",
	Table : "Table",
	Chart : "Chart",
	Label : "Label",
	Table_T : "Table_T",	// template of table type
	Chart_T : "Chart_T",	// template of chart type
	Label_T : "Label_T",	// template of label type

	// URL parameters name
	PARAM_ACTION : '__action',
	PARAM_FORMAT : '__format',
	PARAM_ASATTACHMENT : '__asattachment',
	PARAM_OVERWRITE : '__overwrite',
	PARAM_PAGE : '__page',
	PARAM_PAGERANGE : '__pagerange',
	PARAM_BOOKMARK : '__bookmark',
	PARAM_SVG : '__svg',
	PARAM_TASKID : '__taskid',
	PARAM_ISTOC : '__istoc',
	PARAM_EXPORT_ENCODING : '__exportEncoding',
	PARAM_SEP : '__sep',
	PARAM_EXPORT_DATATYPE : '__exportdatatype',
	PARAM_ISNULL : '__isnull',

	PARAM_PRINTER_NAME : '__printer',
	PARAM_PRINTER_COPIES : '__printer_copies',
	PARAM_PRINTER_COLLATE : '__printer_collate',
	PARAM_PRINTER_DUPLEX : '__printer_duplex',
	PARAM_PRINTER_MODE : '__printer_mode',
	PARAM_PRINTER_MEDIASIZE : '__printer_pagesize',

	PARAM_FITTOPAGE : '__fittopage',
	PARAM_PAGEBREAKONLY : '__pagebreakonly',

	// Parameter Data Type
	TYPE_ANY : '0',
	TYPE_STRING : '1',

	// Servlet patterns
	SERVLET_OUTPUT : 'output',

	// Output formats
	FORMAT_POSTSCRIPT : 'postscript',
	FORMAT_PDF : 'pdf',
	FORMAT_HTML : 'html',

	// Action names
	ACTION_PRINT : 'print',

	// Window names
	WINDOW_PRINT_PREVIEW : 'birtPrint',

	/**
	event.returnvalue indicating that event has already been handled
	as a selection
	*/
	select: "select",

	/**
	event.returnvalue indicated that contextmenu has already been handled
	*/
	context: "context",

	error : { },

	type: {UpdateRequest: "UpdateRequest"},
	operation: "Operation",
	target: "Target",
	operator: {show: "Show", hide: "Hide", sort: "Sort"}
}<commit_msg>Fix Bugzilla Bug 211372<commit_after>/******************************************************************************
 *	Copyright (c) 2004 Actuate Corporation and others.
 *	All rights reserved. This program and the accompanying materials
 *	are made available under the terms of the Eclipse Public License v1.0
 *	which accompanies this distribution, and is available at
 *		http://www.eclipse.org/legal/epl-v10.html
 *
 *	Contributors:
 *		Actuate Corporation - Initial implementation.
 *****************************************************************************/

var Constants = {

	/** id of document managed BirtReportDocument*/
	documentId: "Document",

	/** element is a UI component managed by BirtReportBase */
	reportBase: "ReportBase",

	/** element is a table managed by BirtReportTable */
	reportTable: "ReportTable",

	/** element is a chart managed by BirtReportChart */
	reportChart: "ReportChart",

	/** element is a document managed BirtReportDocument */
	isDocument: "isDocument",

	/** contains number of selected column if there is one */
	selColNum: "SelColNum",

	/** contains number of selected column if there is one */
	activeIds: "activeIds",
	activeIdTypes: "activeIdTypes",

	// Report object types.
	Document : "Document",
	Table : "Table",
	Chart : "Chart",
	Label : "Label",
	Table_T : "Table_T",	// template of table type
	Chart_T : "Chart_T",	// template of chart type
	Label_T : "Label_T",	// template of label type

	// URL parameters name
	PARAM_ACTION : '__action',
	PARAM_FORMAT : '__format',
	PARAM_ASATTACHMENT : '__asattachment',
	PARAM_OVERWRITE : '__overwrite',
	PARAM_PAGE : '__page',
	PARAM_PAGERANGE : '__pagerange',
	PARAM_BOOKMARK : '__bookmark',
	PARAM_SVG : '__svg',
	PARAM_TASKID : '__taskid',
	PARAM_ISTOC : '__istoc',
	PARAM_EXPORT_ENCODING : '__exportEncoding',
	PARAM_SEP : '__sep',
	PARAM_EXPORT_DATATYPE : '__exportdatatype',
	PARAM_ISNULL : '__isnull',

	PARAM_PRINTER_NAME : '__printer',
	PARAM_PRINTER_COPIES : '__printer_copies',
	PARAM_PRINTER_COLLATE : '__printer_collate',
	PARAM_PRINTER_DUPLEX : '__printer_duplex',
	PARAM_PRINTER_MODE : '__printer_mode',
	PARAM_PRINTER_MEDIASIZE : '__printer_pagesize',

	PARAM_FITTOPAGE : '__fittopage',
	PARAM_PAGEBREAKONLY : '__pagebreakonly',

	// Parameter Data Type
	TYPE_ANY : '0',
	TYPE_STRING : '1',

	// Servlet patterns
	SERVLET_OUTPUT : 'output',

	// Output formats
	FORMAT_POSTSCRIPT : 'postscript',
	FORMAT_PDF : 'pdf',
	FORMAT_HTML : 'html',
	FORMAT_PPT : 'ppt',

	// Action names
	ACTION_PRINT : 'print',

	// Window names
	WINDOW_PRINT_PREVIEW : 'birtPrint',

	/**
	event.returnvalue indicating that event has already been handled
	as a selection
	*/
	select: "select",

	/**
	event.returnvalue indicated that contextmenu has already been handled
	*/
	context: "context",

	error : { },

	type: {UpdateRequest: "UpdateRequest"},
	operation: "Operation",
	target: "Target",
	operator: {show: "Show", hide: "Hide", sort: "Sort"}
}<|endoftext|>


<commit_before>'use strict'

const uuid = require('uuid')
const NodeResque = require('node-resque')
const ActionHero = require('./../index.js')
const api = ActionHero.api

/**
 * A speical "mock" server which enables you to test actions and tasks in a simple way.  Only availalbe in the TEST environment.
 *
 * @namespace api.specHelper
 * @property {Boolean} enabled - Is the specHelper server enabled
 * @property {Object} Server - The instnace of the SpecHelper server
 * @extends ActionHero.Initializer
 */
module.exports = class SpecHelper extends ActionHero.Initializer {
  constructor () {
    super()
    this.name = 'specHelper'
    this.loadPriority = 900
    this.startPriority = 901
    this.enabled = false
  }

  initialize () {
    if (api.env === 'test' || process.env.SPECHELPER === 'true' || process.env.SPECHELPER === true) {
      this.enabled = true
    }

    if (!this.enabled) { return }

    class TestServer extends ActionHero.Server {
      constructor () {
        super()
        this.type = 'testServer'
        this.attributes = {
          canChat: true,
          logConnections: false,
          logExits: false,
          sendWelcomeMessage: true,
          verbs: api.connections.allowedVerbs
        }
      }

      start (api) {
        api.log('loading the testServer', 'warning')
        this.on('connection', (connection) => { this.handleConnection(connection) })
        this.on('actionComplete', (data) => { this.actionComplete(data) })
      }

      stop () {}

      goodbye () {}

      sendMessage (connection, message, messageCount) {
        process.nextTick(() => {
          connection.messages.push(message)
          if (typeof connection.actionCallbacks[messageCount] === 'function') {
            connection.actionCallbacks[messageCount](message, connection)
            delete connection.actionCallbacks[messageCount]
          }
        })
      }

      sendFile (connection, error, fileStream, mime, length) {
        let content = ''
        let response = {
          content: null,
          mime: mime,
          length: length
        }

        if (error) { response.error = error }

        try {
          if (!error) {
            fileStream.on('data', (d) => { content += d })
            fileStream.on('end', () => {
              response.content = content
              this.sendMessage(connection, response, connection.messageCount)
            })
          } else {
            this.sendMessage(connection, response, connection.messageCount)
          }
        } catch (e) {
          this.log(e, 'warning')
          this.sendMessage(connection, response, connection.messageCount)
        }
      }

      handleConnection (connection) {
        connection.messages = []
        connection.actionCallbacks = {}
      }

      async actionComplete (data) {
        if (typeof data.response === 'string' || Array.isArray(data.response)) {
          if (data.response.error) {
            data.response = await api.config.errors.serializers.servers.specHelper(data.response.error)
          }
        } else {
          if (data.response.error) {
            data.response.error = await api.config.errors.serializers.servers.specHelper(data.response.error)
          }

          if (api.specHelper.returnMetadata) {
            data.response.messageCount = data.messageCount

            data.response.serverInformation = {
              serverName: api.config.general.serverName,
              apiVersion: api.config.general.apiVersion
            }

            data.response.requesterInformation = {
              id: data.connection.id,
              remoteIP: data.connection.remoteIP,
              receivedParams: {}
            }

            for (let k in data.params) {
              data.response.requesterInformation.receivedParams[k] = data.params[k]
            }
          }
        }

        if (data.toRender === true) {
          this.sendMessage(data.connection, data.response, data.messageCount)
        }
      }
    }

    api.specHelper = {
      returnMetadata: true,
      Server: TestServer
    }

    /**
     * A special connection usable in tests.  Create via `new api.specHelper.Connection()`
     *
     * @type {Class}
     * @memberof api.specHelper
     */
    api.specHelper.Connection = class {
      constructor () {
        let id = uuid.v4()
        api.servers.servers.testServer.buildConnection({
          id: id,
          rawConnection: {},
          remoteAddress: 'testServer',
          remotePort: 0
        })

        return api.connections.connections[id]
      }
    }

    /**
     * Run an action via the specHelper server.
     *
     * @async
     * @param  {string}  actionName The name of the action to run.
     * @param  {Object}  input      You can provide either a pre-build connection `new api.specHelper.Connection()`, or just a Object with params for your action.
     * @return {Promise<Object>}    The `response` from the action.
     */
    api.specHelper.runAction = async (actionName, input) => {
      let connection
      if (!input) { input = {} }
      if (input.id && input.type === 'testServer') {
        connection = input
      } else {
        connection = new api.specHelper.Connection()
        connection.params = input
      }

      connection.params.action = actionName

      connection.messageCount++
      let response = await new Promise((resolve) => {
        api.servers.servers.testServer.processAction(connection)
        connection.actionCallbacks[(connection.messageCount)] = resolve
      })

      return response
    }

    /**
     * Mock a specHelper connection requesting a file from the server.
     *
     * @async
     * @param  {string}  file The name & path of the file to request.
     * @return {Promise<Object>} The body contents and metadata of the file requested.  Conatins: mime, length, body, and more.
     */
    api.specHelper.getStaticFile = async (file) => {
      let connection = new api.specHelper.Connection()
      connection.params.file = file

      connection.messageCount++
      let response = await new Promise((resolve) => {
        api.servers.servers.testServer.processFile(connection)
        connection.actionCallbacks[(connection.messageCount)] = resolve
      })

      return response
    }

    /**
     * Use the specHelper to run a task.
     * Note: this only runs the task's `run()` method, and no middleware.  This is faster than api.specHelper.runFullTask.
     *
     * @async
     * @param  {string}   taskName The name of the task.
     * @param  {Object}   params   Params to pass to the task
     * @return {Promise<Object>}   The return value from the task.
     * @see api.specHelper.runFullTask
     */
    api.specHelper.runTask = async (taskName, params) => {
      return api.tasks.tasks[taskName].run(params)
    }

    /**
     * Use the specHelper to run a task.
     * Note: this will run a full Task worker, and will also include any middleware.  This is slower than api.specHelper.runTask.
     *
     * @param  {string}   taskName The name of the task.
     * @param  {Object}   params   Params to pass to the task
     * @return {Promise<Object>}   The return value from the task.
     * @see api.specHelper.runTask
     */
    api.specHelper.runFullTask = async (taskName, params) => {
      const worker = new NodeResque.Worker({
        connection: api.redis.clients.tasks,
        queues: api.config.tasks.queues || ['default']
      }, api.tasks.jobs)

      try {
        await worker.connect()
        let result = await worker.performInline(taskName, params)
        await worker.end()
        return result
      } catch (error) {
        try {
          worker.end()
        } catch (error) {}
        throw error
      }
    }
  }

  async start () {
    if (!this.enabled) { return }

    let server = new api.specHelper.Server()
    server.config = { enabled: true }
    await server.start(api)
    api.servers.servers.testServer = server
  }
}
<commit_msg>fix redis connection in runFullTask<commit_after>'use strict'

const uuid = require('uuid')
const NodeResque = require('node-resque')
const ActionHero = require('./../index.js')
const api = ActionHero.api

/**
 * A speical "mock" server which enables you to test actions and tasks in a simple way.  Only availalbe in the TEST environment.
 *
 * @namespace api.specHelper
 * @property {Boolean} enabled - Is the specHelper server enabled
 * @property {Object} Server - The instnace of the SpecHelper server
 * @extends ActionHero.Initializer
 */
module.exports = class SpecHelper extends ActionHero.Initializer {
  constructor () {
    super()
    this.name = 'specHelper'
    this.loadPriority = 900
    this.startPriority = 901
    this.enabled = false
  }

  initialize () {
    if (api.env === 'test' || process.env.SPECHELPER === 'true' || process.env.SPECHELPER === true) {
      this.enabled = true
    }

    if (!this.enabled) { return }

    class TestServer extends ActionHero.Server {
      constructor () {
        super()
        this.type = 'testServer'
        this.attributes = {
          canChat: true,
          logConnections: false,
          logExits: false,
          sendWelcomeMessage: true,
          verbs: api.connections.allowedVerbs
        }
      }

      start (api) {
        api.log('loading the testServer', 'warning')
        this.on('connection', (connection) => { this.handleConnection(connection) })
        this.on('actionComplete', (data) => { this.actionComplete(data) })
      }

      stop () {}

      goodbye () {}

      sendMessage (connection, message, messageCount) {
        process.nextTick(() => {
          connection.messages.push(message)
          if (typeof connection.actionCallbacks[messageCount] === 'function') {
            connection.actionCallbacks[messageCount](message, connection)
            delete connection.actionCallbacks[messageCount]
          }
        })
      }

      sendFile (connection, error, fileStream, mime, length) {
        let content = ''
        let response = {
          content: null,
          mime: mime,
          length: length
        }

        if (error) { response.error = error }

        try {
          if (!error) {
            fileStream.on('data', (d) => { content += d })
            fileStream.on('end', () => {
              response.content = content
              this.sendMessage(connection, response, connection.messageCount)
            })
          } else {
            this.sendMessage(connection, response, connection.messageCount)
          }
        } catch (e) {
          this.log(e, 'warning')
          this.sendMessage(connection, response, connection.messageCount)
        }
      }

      handleConnection (connection) {
        connection.messages = []
        connection.actionCallbacks = {}
      }

      async actionComplete (data) {
        if (typeof data.response === 'string' || Array.isArray(data.response)) {
          if (data.response.error) {
            data.response = await api.config.errors.serializers.servers.specHelper(data.response.error)
          }
        } else {
          if (data.response.error) {
            data.response.error = await api.config.errors.serializers.servers.specHelper(data.response.error)
          }

          if (api.specHelper.returnMetadata) {
            data.response.messageCount = data.messageCount

            data.response.serverInformation = {
              serverName: api.config.general.serverName,
              apiVersion: api.config.general.apiVersion
            }

            data.response.requesterInformation = {
              id: data.connection.id,
              remoteIP: data.connection.remoteIP,
              receivedParams: {}
            }

            for (let k in data.params) {
              data.response.requesterInformation.receivedParams[k] = data.params[k]
            }
          }
        }

        if (data.toRender === true) {
          this.sendMessage(data.connection, data.response, data.messageCount)
        }
      }
    }

    api.specHelper = {
      returnMetadata: true,
      Server: TestServer
    }

    /**
     * A special connection usable in tests.  Create via `new api.specHelper.Connection()`
     *
     * @type {Class}
     * @memberof api.specHelper
     */
    api.specHelper.Connection = class {
      constructor () {
        let id = uuid.v4()
        api.servers.servers.testServer.buildConnection({
          id: id,
          rawConnection: {},
          remoteAddress: 'testServer',
          remotePort: 0
        })

        return api.connections.connections[id]
      }
    }

    /**
     * Run an action via the specHelper server.
     *
     * @async
     * @param  {string}  actionName The name of the action to run.
     * @param  {Object}  input      You can provide either a pre-build connection `new api.specHelper.Connection()`, or just a Object with params for your action.
     * @return {Promise<Object>}    The `response` from the action.
     */
    api.specHelper.runAction = async (actionName, input) => {
      let connection
      if (!input) { input = {} }
      if (input.id && input.type === 'testServer') {
        connection = input
      } else {
        connection = new api.specHelper.Connection()
        connection.params = input
      }

      connection.params.action = actionName

      connection.messageCount++
      let response = await new Promise((resolve) => {
        api.servers.servers.testServer.processAction(connection)
        connection.actionCallbacks[(connection.messageCount)] = resolve
      })

      return response
    }

    /**
     * Mock a specHelper connection requesting a file from the server.
     *
     * @async
     * @param  {string}  file The name & path of the file to request.
     * @return {Promise<Object>} The body contents and metadata of the file requested.  Conatins: mime, length, body, and more.
     */
    api.specHelper.getStaticFile = async (file) => {
      let connection = new api.specHelper.Connection()
      connection.params.file = file

      connection.messageCount++
      let response = await new Promise((resolve) => {
        api.servers.servers.testServer.processFile(connection)
        connection.actionCallbacks[(connection.messageCount)] = resolve
      })

      return response
    }

    /**
     * Use the specHelper to run a task.
     * Note: this only runs the task's `run()` method, and no middleware.  This is faster than api.specHelper.runFullTask.
     *
     * @async
     * @param  {string}   taskName The name of the task.
     * @param  {Object}   params   Params to pass to the task
     * @return {Promise<Object>}   The return value from the task.
     * @see api.specHelper.runFullTask
     */
    api.specHelper.runTask = async (taskName, params) => {
      return api.tasks.tasks[taskName].run(params)
    }

    /**
     * Use the specHelper to run a task.
     * Note: this will run a full Task worker, and will also include any middleware.  This is slower than api.specHelper.runTask.
     *
     * @param  {string}   taskName The name of the task.
     * @param  {Object}   params   Params to pass to the task
     * @return {Promise<Object>}   The return value from the task.
     * @see api.specHelper.runTask
     */
    api.specHelper.runFullTask = async (taskName, params) => {
      const worker = new NodeResque.Worker({
        connection: {
          redis: api.redis.clients.tasks
        },
        queues: api.config.tasks.queues || ['default']
      }, api.tasks.jobs)

      try {
        await worker.connect()
        let result = await worker.performInline(taskName, params)
        await worker.end()
        return result
      } catch (error) {
        try {
          worker.end()
        } catch (error) {}
        throw error
      }
    }
  }

  async start () {
    if (!this.enabled) { return }

    let server = new api.specHelper.Server()
    server.config = { enabled: true }
    await server.start(api)
    api.servers.servers.testServer = server
  }
}
<|endoftext|>


<commit_before>'use strict';

var app = angular.module("app",['ui.ace']);

app.controller("controller", ["$scope", function($scope) {
		$scope.aceOptions = {
			theme : 'solarized_dark',
			mode : 'r',
			useWrapMode : 'true'
		}
		$scope.example = "Example Works!";

        $scope.makecode = function(funct){
            switch(funct){
                case "rnorm":
                    $scope.code = "rnorm was selected";
                    break;
                case "qnorm":
                    $scope.code = "qnorm was selected";
                    break;
                case "pnorm":
                    $scope.code = "pnorm was selected";
                    break;
                default:
                    $scope.code = "function unknown";
            }
        }

        $scope.runcode = function(code){
            alert("Running R");
        }

}]);

app.controller("controller2",["$scope", function($scope){

	$scope.functions = [
		{ 'name' : 'rnorm' , 'description' : 'description of rnorm'},
		{ 'name' : 'qnorm' , 'description' : 'description of qnorm'},
		{ 'name' : 'pnorm' , 'description' : 'description of pnorm'}
	];

	$scope.test = "Controller 2 works!"

    ;
}]);

<commit_msg>tests<commit_after>'use strict';

var app = angular.module("app",['ui.ace']);

app.controller("controller", ["$scope", function($scope) {
		$scope.aceOptions = {
			theme : 'solarized_dark',
			mode : 'r',
			useWrapMode : 'true'
		}
		$scope.example = "Example Works!";

        $scope.makecode = function(funct){
            switch(funct){
                case "rnorm":
                    $scope.code = "rnorm was selected";
                    break;
                case "qnorm":
                    $scope.code = "qnorm was selected";
                    break;
                case "pnorm":
                    $scope.code = "pnorm was selected";
                    break;
                default:
                    $scope.code = "function unknown";
            }
        }

        $scope.runcode = function(code){
        }

}]);

app.controller("controller2",["$scope", function($scope){

	$scope.functions = [
		{ 'name' : 'rnorm' , 'description' : 'description of rnorm'},
		{ 'name' : 'qnorm' , 'description' : 'description of qnorm'},
		{ 'name' : 'pnorm' , 'description' : 'description of pnorm'}
	];

	$scope.test = "Controller 2 works!"

    ;
}]);

<|endoftext|>


<commit_before>//
// Copyright (c) 2016 Autodesk, Inc.
//
// 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.
//
// by Cyrille Fauvel
// Autodesk Forge Partner Development
//
/*jshint esversion: 6 */
/* eslint-disable no-multi-spaces */
/*jshint -W014 */

const ForgeAPI = require('forge-apis');

const ejs = require('ejs');
const fs = require('fs');
const _path = require('path');
const zlib = require('zlib');

const Bubble = require('./bubble');
const viewerFileList =require ('./viewer') ;
const utils = require('./utils');

class Forge_Other {

	static get oauth () { return (Forge_Other._oauth); }
	static set oauth (val) { Forge_Other._oauth = val; }
	static get viewerVersion () { return (Forge_Other._viewerVersion); }
	static set viewerVersion (val) { Forge_Other._viewerVersion = val; }
	static get viewerServerPath () { return ('https://developer.api.autodesk.com/modelderivative/v2/viewers'); }
	static get viewerLocalPath () { return (''); }
	static get endpoint () { return ('http://localhost:7125'); }

	// user (3legged)
	static userAboutMe (options) { // eslint-disable-line no-unused-vars
		console.log('About Me!...');
		Forge_Other.oauth.getOauth3Legged()
			.then((oa3Legged) => {
				let oa3Info = new ForgeAPI.UserProfileApi();
				return (oa3Info.getUserProfile(oa3Legged, oa3Legged.credentials));
			})
			.then((profile) => {
				console.log(JSON.stringify(profile.body, null, 4));
			})
			.catch((error) => {
				console.error('aboutme error:', error);
			});
	}

	// svf/otg bubble
	static bubble (urn, outputFolder, options) {
		console.log('Downloading Bubble for urn: ' + urn);
		if (urn.substring(0, 4) === 'urn:')
			urn = utils.safeBase64encode(urn);
		let _progress = {};
		let oauthClient = null;
		Forge_Other.oauth.getCredentials()
			.then((credentials) => {
				if (!credentials.refresh_token)
					return (Forge_Other.oauth.getOauth2Legged());
				else
					return (Forge_Other.oauth.getOauth3Legged());
			})
			.then((_oauthClient) => {
				oauthClient = _oauthClient;
				let obj = null;
				let otg = options.otg || options.parent.otg || false;
				let svf2 = options.svf2 || options.parent.svf2 || false;
				if (otg)
					obj = new Bubble.otg(_progress);
				else if ( svf2)
					obj = new Bubble.svf2(_progress);
				else
					obj = new Bubble.svf(_progress);
				obj.downloadBubble(urn, outputFolder + '/', oauthClient.credentials.access_token)
					.then((_bubble) => { // eslint-disable-line no-unused-vars
						console.log('Your bubble is ready at: ' + outputFolder);
					})
					.catch((error) => {
						throw error;
					});
			})
			.catch((error) => {
				if (error.message === 'Bubble already extracted!' || error.message === 'Bubble already being extracted!')
					return;
				console.error('Something went wrong while downloading your bubble!', error);
			});
	}

	// html/viewer
	static htmlGet (urn, outputFilename, options) { // eslint-disable-line no-unused-vars

		let render = (data, _outputFilename) => { // eslint-disable-line no-unused-vars
			return (new Promise((fulfill, reject) => {
				ejs.renderFile(_path.join(__dirname, '../views/index.ejs'), data, {}, (err, str) => {
					if (err)
						reject(err);
					fs.writeFile(outputFilename, str, (_err) => {
						if (_err)
							reject(_err);
						data.filename = outputFilename;
						fulfill(data);
					});
				});
			}));
		};

		console.log('Creating Viewer: ' + urn);
		if (urn.substring(0, 4) === 'urn:')
			urn = utils.safeBase64encode(urn);
		//let oauthClient = null;
		Forge_Other.oauth.getCredentials()
			.then((credentials) => {
				if (!credentials.refresh_token)
					return (Forge_Other.oauth.getOauth2Legged());
				else
					return (Forge_Other.oauth.getOauth3Legged());
			})
			.then((_oauthClient) => {
				//oauthClient = _oauthClient;
				let SvfOrOtg = 'svf';
				SvfOrOtg = (options.otg || options.parent.otg) ? 'otg' : SvfOrOtg;
				SvfOrOtg = (options.svf2 || options.parent.svf2) ? 'svf2' : SvfOrOtg;
				let localOptions = (/^(https?):.*$/g.test(urn) || urn[0] === '/') ? '_local' : '';
				// let isKey = (options.key || options.parent.key);
				// if ( isKey )
				// 	urn = utils.safeBase64encode (``);
				let localServer = (options.local || options.parent.local) ? '/' + Forge_Other.viewerVersion : Forge_Other.viewerServerPath;
				let data = {
					urn: urn,
					access_token: _oauthClient.credentials.access_token,
					version: Forge_Other.viewerVersion,
					viewer_path: localServer,
					endpoint: Forge_Other.endpoint,
					viewer_options: (SvfOrOtg + '_options' + localOptions)
				};
				return (render(data, outputFilename));
			})
			.then((info) => {
				console.log('Your HTML is ready at: ', info.filename);
			})
			.catch((error) => {
				console.error('Something went wrong while creating your local viewer!', error);
			});
	}

	// viewer
	static viewerGet (outputFolder, options) { // eslint-disable-line no-unused-vars
		console.log('Downloading Viewer');
		outputFolder = _path.resolve (_path.join(outputFolder, Forge_Other.viewerVersion));

		let urns =viewerFileList.map ((item) => {
			return (Forge_Other.DownloadViewerItem (`/derivativeservice/v2/viewers/${item}?v=${Forge_Other.viewerVersion}`, outputFolder, item)) ;
		}) ;
		Promise.all (urns)
			.then ((_urns) => { // eslint-disable-line no-unused-vars
				console.log ('Download completed succesfully.');
				//fulfill (data) ;
			})
			.catch ((error) => { // eslint-disable-line no-unused-vars
				console.error ('Something wrong happened during viewer files download') ;
				//reject (error) ;
			})
		;
	}

	static DownloadViewerItem (uri, outPath, item) {
		return (new Promise (function (fulfill, reject) {
			let accepted = [ 'application/octet-stream', 'image/png', 'text/html', 'text/css', 'text/javascript', 'application/json' ] ;
			let ModelDerivative =new ForgeAPI.DerivativesApi () ;
			ModelDerivative.apiClient.callApi (
				uri, 'GET',
				{}, {}, {},
				{}, null,
				[], accepted, null,
				//forgeToken.RW, forgeToken.RW.getCredentials ()
				null, null
			)
				//.pipe (zlib.createGunzip ())
				.then ((response) => {
					let body =response.body ;
					if ( ['gzip', 'deflate'].indexOf (response.headers ['content-encoding']) !== -1 )
						body =zlib.gunzipSync (response.body) ;

					if (   response.headers ['content-type'] === 'text/javascript'
						|| response.headers ['content-type'] === 'text/css'
					)
						body =body.toString ('utf8') ;
					if (   response.headers ['content-type'] === 'application/json'
						|| response.headers ['content-type'] === 'application/json; charset=utf-8'
					)
						body =JSON.stringify (body) ;
					console.log (` >> ${_path.join(outPath, item)}`) ;
					return (utils.writeFile (_path.join(outPath, item), body, null, true)) ;
				})
				.then ((response) => { // eslint-disable-line no-unused-vars
					fulfill (item) ;
				})
				.catch ((error) => {
					console.error (error, `with: ${uri}`) ;
					reject (error) ;
				});
		})) ;
	}

}

module.exports = Forge_Other;<commit_msg>support for SVF2<commit_after>//
// Copyright (c) 2016 Autodesk, Inc.
//
// 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.
//
// by Cyrille Fauvel
// Autodesk Forge Partner Development
//
/*jshint esversion: 6 */
/* eslint-disable no-multi-spaces */
/*jshint -W014 */

const ForgeAPI = require('forge-apis');

const ejs = require('ejs');
const fs = require('fs');
const _path = require('path');
const zlib = require('zlib');

const Bubble = require('./bubble');
const viewerFileList =require ('./viewer') ;
const utils = require('./utils');

class Forge_Other {

	static get oauth () { return (Forge_Other._oauth); }
	static set oauth (val) { Forge_Other._oauth = val; }
	static get viewerVersion () { return (Forge_Other._viewerVersion); }
	static set viewerVersion (val) { Forge_Other._viewerVersion = val; }
	static get viewerServerPath () { return ('https://developer.api.autodesk.com/modelderivative/v2/viewers'); }
	static get viewerLocalPath () { return (''); }
	static get endpoint () { return ('http://localhost:7124'); }

	// user (3legged)
	static userAboutMe (options) { // eslint-disable-line no-unused-vars
		console.log('About Me!...');
		Forge_Other.oauth.getOauth3Legged()
			.then((oa3Legged) => {
				let oa3Info = new ForgeAPI.UserProfileApi();
				return (oa3Info.getUserProfile(oa3Legged, oa3Legged.credentials));
			})
			.then((profile) => {
				console.log(JSON.stringify(profile.body, null, 4));
			})
			.catch((error) => {
				console.error('aboutme error:', error);
			});
	}

	// svf/otg bubble
	static bubble (urn, outputFolder, options) {
		console.log('Downloading Bubble for urn: ' + urn);
		if (urn.substring(0, 4) === 'urn:')
			urn = utils.safeBase64encode(urn);
		let _progress = {};
		let oauthClient = null;
		Forge_Other.oauth.getCredentials()
			.then((credentials) => {
				if (!credentials.refresh_token)
					return (Forge_Other.oauth.getOauth2Legged());
				else
					return (Forge_Other.oauth.getOauth3Legged());
			})
			.then((_oauthClient) => {
				oauthClient = _oauthClient;
				let obj = null;
				let otg = options.otg || options.parent.otg || false;
				let svf2 = options.svf2 || options.parent.svf2 || false;
				if (otg)
					obj = new Bubble.otg(_progress);
				else if ( svf2)
					obj = new Bubble.svf2(_progress);
				else
					obj = new Bubble.svf(_progress);
				obj.downloadBubble(urn, outputFolder + '/', oauthClient.credentials.access_token)
					.then((_bubble) => { // eslint-disable-line no-unused-vars
						console.log('Your bubble is ready at: ' + outputFolder);
					})
					.catch((error) => {
						throw error;
					});
			})
			.catch((error) => {
				if (error.message === 'Bubble already extracted!' || error.message === 'Bubble already being extracted!')
					return;
				console.error('Something went wrong while downloading your bubble!', error);
			});
	}

	// html/viewer
	static htmlGet (urn, outputFilename, options) { // eslint-disable-line no-unused-vars

		let render = (data, _outputFilename) => { // eslint-disable-line no-unused-vars
			return (new Promise((fulfill, reject) => {
				ejs.renderFile(_path.join(__dirname, '../views/index.ejs'), data, {}, (err, str) => {
					if (err)
						reject(err);
					fs.writeFile(outputFilename, str, (_err) => {
						if (_err)
							reject(_err);
						data.filename = outputFilename;
						fulfill(data);
					});
				});
			}));
		};

		console.log('Creating Viewer: ' + urn);
		if (urn.substring(0, 4) === 'urn:')
			urn = utils.safeBase64encode(urn);
		//let oauthClient = null;
		Forge_Other.oauth.getCredentials()
			.then((credentials) => {
				if (!credentials.refresh_token)
					return (Forge_Other.oauth.getOauth2Legged());
				else
					return (Forge_Other.oauth.getOauth3Legged());
			})
			.then((_oauthClient) => {
				//oauthClient = _oauthClient;
				let SvfOrOtg = 'svf';
				SvfOrOtg = (options.otg || options.parent.otg) ? 'otg' : SvfOrOtg;
				SvfOrOtg = (options.svf2 || options.parent.svf2) ? 'svf2' : SvfOrOtg;
				let localOptions = (/^(https?):.*$/g.test(urn) || urn[0] === '/') ? '_local' : '';
				// let isKey = (options.key || options.parent.key);
				// if ( isKey )
				// 	urn = utils.safeBase64encode (``);
				let localServer = (options.local || options.parent.local) ? '/' + Forge_Other.viewerVersion : Forge_Other.viewerServerPath;
				let data = {
					urn: urn,
					access_token: _oauthClient.credentials.access_token,
					version: Forge_Other.viewerVersion,
					viewer_path: localServer,
					endpoint: Forge_Other.endpoint,
					viewer_options: (SvfOrOtg + '_options' + localOptions)
				};
				return (render(data, outputFilename));
			})
			.then((info) => {
				console.log('Your HTML is ready at: ', info.filename);
			})
			.catch((error) => {
				console.error('Something went wrong while creating your local viewer!', error);
			});
	}

	// viewer
	static viewerGet (outputFolder, options) { // eslint-disable-line no-unused-vars
		console.log('Downloading Viewer');
		outputFolder = _path.resolve (_path.join(outputFolder, Forge_Other.viewerVersion));

		let urns =viewerFileList.map ((item) => {
			return (Forge_Other.DownloadViewerItem (`/derivativeservice/v2/viewers/${item}?v=${Forge_Other.viewerVersion}`, outputFolder, item)) ;
		}) ;
		Promise.all (urns)
			.then ((_urns) => { // eslint-disable-line no-unused-vars
				console.log ('Download completed succesfully.');
				//fulfill (data) ;
			})
			.catch ((error) => { // eslint-disable-line no-unused-vars
				console.error ('Something wrong happened during viewer files download') ;
				//reject (error) ;
			})
		;
	}

	static DownloadViewerItem (uri, outPath, item) {
		return (new Promise (function (fulfill, reject) {
			let accepted = [ 'application/octet-stream', 'image/png', 'text/html', 'text/css', 'text/javascript', 'application/json' ] ;
			let ModelDerivative =new ForgeAPI.DerivativesApi () ;
			ModelDerivative.apiClient.callApi (
				uri, 'GET',
				{}, {}, {},
				{}, null,
				[], accepted, null,
				//forgeToken.RW, forgeToken.RW.getCredentials ()
				null, null
			)
				//.pipe (zlib.createGunzip ())
				.then ((response) => {
					let body =response.body ;
					if ( ['gzip', 'deflate'].indexOf (response.headers ['content-encoding']) !== -1 )
						body =zlib.gunzipSync (response.body) ;

					if (   response.headers ['content-type'] === 'text/javascript'
						|| response.headers ['content-type'] === 'text/css'
					)
						body =body.toString ('utf8') ;
					if (   response.headers ['content-type'] === 'application/json'
						|| response.headers ['content-type'] === 'application/json; charset=utf-8'
					)
						body =JSON.stringify (body) ;
					console.log (` >> ${_path.join(outPath, item)}`) ;
					return (utils.writeFile (_path.join(outPath, item), body, null, true)) ;
				})
				.then ((response) => { // eslint-disable-line no-unused-vars
					fulfill (item) ;
				})
				.catch ((error) => {
					console.error (error, `with: ${uri}`) ;
					reject (error) ;
				});
		})) ;
	}

}

module.exports = Forge_Other;<|endoftext|>


<commit_before>/*global window:false, alert:false, jasmine:false, Node:false, */
/*jshint curly:false*/

'use strict';

var phantom = {};

if (window._phantom) {
  console.log = function(){
    phantom.sendMessage('verbose',Array.prototype.slice.apply(arguments).join(', '));
  };
}

phantom.sendMessage = function() {
  var args = [].slice.call( arguments );
  var payload = JSON.stringify( args );
  if (window._phantom) {
    // alerts are the communication bridge to grunt
    alert( payload );
  }
};

(function(){

  function PhantomReporter() {
    this.started = false;
    this.finished = false;
    this.suites_ = [];
    this.results_ = {};
    this.buffer = '';
  }

  PhantomReporter.prototype.reportRunnerStarting = function(runner) {
    this.started = true;

    var suites = runner.topLevelSuites();
    for (var i = 0; i < suites.length; i++) {
      var suite = suites[i];
      this.suites_.push(this.summarize_(suite));
    }
    phantom.sendMessage('jasmine.reportRunnerStarting', this.suites_);
  };

  PhantomReporter.prototype.reportSpecStarting = function(spec) {
    spec.startTime = (new Date()).getTime();
    var message = {
      suite : {
        description : spec.suite.description
      },
      description : spec.description
    };
    phantom.sendMessage('jasmine.reportSpecStarting', message);
  };

  PhantomReporter.prototype.suites = function() {
    return this.suites_;
  };

  PhantomReporter.prototype.summarize_ = function(suiteOrSpec) {
    var isSuite = suiteOrSpec instanceof jasmine.Suite;
    var summary = {
      id: suiteOrSpec.id,
      name: suiteOrSpec.description,
      type: isSuite ? 'suite' : 'spec',
      children: []
    };

    if (isSuite) {
      var children = suiteOrSpec.children();
      for (var i = 0; i < children.length; i++) {
        summary.children.push(this.summarize_(children[i]));
      }
    }
    return summary;
  };

  PhantomReporter.prototype.results = function() {
    return this.results_;
  };

  PhantomReporter.prototype.resultsForSpec = function(specId) {
    return this.results_[specId];
  };

  function map(values, f) {
    var result = [];
    for (var ii = 0; ii < values.length; ii++) {
      result.push(f(values[ii]));
    }
    return result;
  }

  PhantomReporter.prototype.reportRunnerResults = function(runner) {
    this.finished = true;
    var specIds = map(runner.specs(), function(a){return a.id;});
    var summary = this.resultsForSpecs(specIds);
    phantom.sendMessage('jasmine.reportRunnerResults',summary);
    phantom.sendMessage('jasmine.reportJUnitResults', this.generateJUnitSummary(runner));
    phantom.sendMessage('jasmine.done.PhantomReporter');
  };

  PhantomReporter.prototype.reportSuiteResults = function(suite) {
    if (suite.specs().length) {
      suite.timestamp = new Date();
      suite.duration = suite.timestamp.getTime() - suite.specs()[0].startTime;
      phantom.sendMessage('jasmine.reportSuiteResults',{
        description : suite.description,
        results : suite.results()
      });
    }
  };

  function stringify(obj) {
    if (typeof obj !== 'object') return obj;

    var cache = [], keyMap = [], index;

    var string = JSON.stringify(obj, function(key, value) {
      // Let json stringify falsy values
      if (!value) return value;

      // If we're a node
      if (value instanceof Node) return '[ Node ]';

      // jasmine-given has expectations on Specs. We intercept to return a
      // String to avoid stringifying the entire Jasmine environment, which
      // results in exponential string growth
      if (value instanceof jasmine.Spec) return '[ Spec: ' + value.description + ' ]';

      // If we're a window (logic stolen from jQuery)
      if (value.window && value.window === value.window.window) return '[ Window ]';

      // Simple function reporting
      if (typeof value === 'function') return '[ Function ]';

      if (typeof value === 'object' && value !== null) {

        if (index = cache.indexOf(value) !== -1) {
          // If we have it in cache, report the circle with the key we first found it in
          return '[ Circular {' + (keyMap[index] || 'root') + '} ]';
        }
        cache.push(value);
        keyMap.push(key);
      }
      return value;
    });
    return string;
  }

  PhantomReporter.prototype.reportSpecResults = function(spec) {
    spec.duration = (new Date()).getTime() - spec.startTime;
    var _results = spec.results();
    var results = {
      description : _results.description,
      messages    : _results.getItems(),
      failedCount : _results.failedCount,
      totalCount  : _results.totalCount,
      passedCount : _results.passedCount,
      skipped     : _results.skipped,
      passed      : _results.passed(),
      msg         : _results.failedCount > 0 ? "failed" : "passed"
    };
    this.results_[spec.id] = results;

    // Quick hack to alleviate cyclical object breaking JSONification.
    for (var ii = 0; ii < results.messages.length; ii++) {
      var item = results.messages[ii];
      if (item.expected) {
        item.expected = stringify(item.expected);
      }
      if (item.actual) {
        item.actual = stringify(item.actual);
      }
    }

    phantom.sendMessage( 'jasmine.reportSpecResults', spec.id, results, this.getFullName(spec));
  };

  PhantomReporter.prototype.getFullName = function(spec) {
    return getNestedSuiteName(spec.suite, ':: ') +  ':: ' + spec.description;
  };

  PhantomReporter.prototype.resultsForSpecs = function(specIds){
    var results = {};
    for (var i = 0; i < specIds.length; i++) {
      var specId = specIds[i];
      results[specId] = this.summarizeResult_(this.results_[specId]);
    }
    return results;
  };

  PhantomReporter.prototype.summarizeResult_ = function(result){
    var summaryMessages = [];
    var messagesLength = result.messages.length;
    for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) {
      var resultMessage = result.messages[messageIndex];
      summaryMessages.push({
        text: resultMessage.type === 'log' ? resultMessage.toString() : jasmine.undefined,
        passed: resultMessage.passed ? resultMessage.passed() : true,
        type: resultMessage.type,
        message: resultMessage.message,
        trace: {
          stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined
        }
      });
    }

    return {
      result : result.result,
      messages : summaryMessages
    };
  };

  function getNestedSuiteName(suite, sep) {
    var names = [];
    while (suite) {
      names.unshift(suite.description);
      suite = suite.parentSuite;
    }
    return names.join(sep ? sep : ' ');
  }

  function getTopLevelSuiteId(suite) {
    var id;
    while (suite) {
      id = suite.id;
      suite = suite.parentSuite;
    }
    return id;
  }

  PhantomReporter.prototype.generateJUnitSummary = function(runner) {
    var consolidatedSuites = {},
        suites = map(runner.suites(), function(suite) {
          var failures = 0;

          var testcases = map(suite.specs(), function(spec) {
            var failureMessages = [];
            if (spec.results().failedCount) {
              failures++;
              var resultsItems = spec.results().items_;
              for (var ii = 0; ii < resultsItems.length; ii++) {
                var expectation = resultsItems[ii];
                if (!expectation.passed()) {
                  failureMessages.push(expectation.message);
                }
              }
            }
            return {
              assertions: spec.results().items_.length,
              className: getNestedSuiteName(spec.suite),
              name: spec.description,
              time: spec.duration / 1000,
              failureMessages: failureMessages
            };
          });

          var data = {
              name: getNestedSuiteName(suite),
              time: suite.duration / 1000,
              timestamp: suite.timestamp,
              tests: suite.specs().length,
              errors: 0, // TODO: These exist in the JUnit XML but not sure how they map to jasmine things
              testcases: testcases,
              failures: failures
            };

          if (suite.parentSuite) {
            consolidatedSuites[getTopLevelSuiteId(suite)].push(data);
          } else {
            consolidatedSuites[suite.id] = [data];
          }
          return data;
        });

    return {
      suites: suites,
      consolidatedSuites: consolidatedSuites
    };
  };

  jasmine.getEnv().addReporter( new PhantomReporter() );
}());
<commit_msg>Slight refactor<commit_after>/*global window:false, alert:false, jasmine:false, Node:false, */
/*jshint curly:false*/

'use strict';

var phantom = {};

if (window._phantom) {
  console.log = function(){
    phantom.sendMessage('verbose',Array.prototype.slice.apply(arguments).join(', '));
  };
}

phantom.sendMessage = function() {
  var args = [].slice.call( arguments );
  var payload = JSON.stringify( args );
  if (window._phantom) {
    // alerts are the communication bridge to grunt
    alert( payload );
  }
};

(function(){

  function PhantomReporter() {
    this.started = false;
    this.finished = false;
    this.suites_ = [];
    this.results_ = {};
    this.buffer = '';
  }

  PhantomReporter.prototype.reportRunnerStarting = function(runner) {
    this.started = true;

    var suites = runner.topLevelSuites();
    for (var i = 0; i < suites.length; i++) {
      var suite = suites[i];
      this.suites_.push(this.summarize_(suite));
    }
    phantom.sendMessage('jasmine.reportRunnerStarting', this.suites_);
  };

  PhantomReporter.prototype.reportSpecStarting = function(spec) {
    spec.startTime = (new Date()).getTime();
    var message = {
      suite : {
        description : spec.suite.description
      },
      description : spec.description
    };
    phantom.sendMessage('jasmine.reportSpecStarting', message);
  };

  PhantomReporter.prototype.suites = function() {
    return this.suites_;
  };

  PhantomReporter.prototype.summarize_ = function(suiteOrSpec) {
    var isSuite = suiteOrSpec instanceof jasmine.Suite;
    var summary = {
      id: suiteOrSpec.id,
      name: suiteOrSpec.description,
      type: isSuite ? 'suite' : 'spec',
      children: []
    };

    if (isSuite) {
      var children = suiteOrSpec.children();
      for (var i = 0; i < children.length; i++) {
        summary.children.push(this.summarize_(children[i]));
      }
    }
    return summary;
  };

  PhantomReporter.prototype.results = function() {
    return this.results_;
  };

  PhantomReporter.prototype.resultsForSpec = function(specId) {
    return this.results_[specId];
  };

  function map(values, f) {
    var result = [];
    for (var ii = 0; ii < values.length; ii++) {
      result.push(f(values[ii]));
    }
    return result;
  }

  PhantomReporter.prototype.reportRunnerResults = function(runner) {
    this.finished = true;
    var specIds = map(runner.specs(), function(a){return a.id;});
    var summary = this.resultsForSpecs(specIds);
    phantom.sendMessage('jasmine.reportRunnerResults',summary);
    phantom.sendMessage('jasmine.reportJUnitResults', this.generateJUnitSummary(runner));
    phantom.sendMessage('jasmine.done.PhantomReporter');
  };

  PhantomReporter.prototype.reportSuiteResults = function(suite) {
    if (suite.specs().length) {
      suite.timestamp = new Date();
      suite.duration = suite.timestamp.getTime() - suite.specs()[0].startTime;
      phantom.sendMessage('jasmine.reportSuiteResults',{
        description : suite.description,
        results : suite.results()
      });
    }
  };

  function stringify(obj) {
    if (typeof obj !== 'object') return obj;

    var cache = [], keyMap = [], index;

    var string = JSON.stringify(obj, function(key, value) {
      // Let json stringify falsy values
      if (!value) return value;

      // If we're a node
      if (value instanceof Node) return '[ Node ]';

      // jasmine-given has expectations on Specs. We intercept to return a
      // String to avoid stringifying the entire Jasmine environment, which
      // results in exponential string growth
      if (value instanceof jasmine.Spec) return '[ Spec: ' + value.description + ' ]';

      // If we're a window (logic stolen from jQuery)
      if (value.window && value.window === value.window.window) return '[ Window ]';

      // Simple function reporting
      if (typeof value === 'function') return '[ Function ]';

      if (typeof value === 'object' && value !== null) {

        if (index = cache.indexOf(value) !== -1) {
          // If we have it in cache, report the circle with the key we first found it in
          return '[ Circular {' + (keyMap[index] || 'root') + '} ]';
        }
        cache.push(value);
        keyMap.push(key);
      }
      return value;
    });
    return string;
  }

  PhantomReporter.prototype.reportSpecResults = function(spec) {
    spec.duration = (new Date()).getTime() - spec.startTime;
    var _results = spec.results();
    var results = {
      description : _results.description,
      messages    : _results.getItems(),
      failedCount : _results.failedCount,
      totalCount  : _results.totalCount,
      passedCount : _results.passedCount,
      skipped     : _results.skipped,
      passed      : _results.passed(),
      msg         : _results.failedCount > 0 ? "failed" : "passed"
    };
    this.results_[spec.id] = results;

    // Quick hack to alleviate cyclical object breaking JSONification.
    for (var ii = 0; ii < results.messages.length; ii++) {
      var item = results.messages[ii];
      if (item.expected) {
        item.expected = stringify(item.expected);
      }
      if (item.actual) {
        item.actual = stringify(item.actual);
      }
    }

    phantom.sendMessage( 'jasmine.reportSpecResults', spec.id, results, this.getFullName(spec));
  };

  PhantomReporter.prototype.getFullName = function(spec) {
    return getNestedSuiteName(spec.suite, ':: ') +  ':: ' + spec.description;
  };

  PhantomReporter.prototype.resultsForSpecs = function(specIds){
    var results = {};
    for (var i = 0; i < specIds.length; i++) {
      var specId = specIds[i];
      results[specId] = this.summarizeResult_(this.results_[specId]);
    }
    return results;
  };

  PhantomReporter.prototype.summarizeResult_ = function(result){
    var summaryMessages = [];
    var messagesLength = result.messages.length;
    for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) {
      var resultMessage = result.messages[messageIndex];
      summaryMessages.push({
        text: resultMessage.type === 'log' ? resultMessage.toString() : jasmine.undefined,
        passed: resultMessage.passed ? resultMessage.passed() : true,
        type: resultMessage.type,
        message: resultMessage.message,
        trace: {
          stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined
        }
      });
    }

    return {
      result : result.result,
      messages : summaryMessages
    };
  };

  function getNestedSuiteName(suite, sep) {
    var names = [];
    while (suite) {
      names.unshift(suite.description);
      suite = suite.parentSuite;
    }
    return names.join(sep ? sep : ' ');
  }

  function getTopLevelSuiteId(suite) {
    var id;
    while (suite) {
      id = suite.id;
      suite = suite.parentSuite;
    }
    return id;
  }

  PhantomReporter.prototype.generateJUnitSummary = function(runner) {
    var consolidatedSuites = {},
        suites = map(runner.suites(), function(suite) {
          var failures = 0;

          var testcases = map(suite.specs(), function(spec) {
            var failureMessages = [];
            var specResults = spec.results();
            var resultsItems = specResults.items_;
            var resultsItemCount = resultsItems.length;

            if (specResults.failedCount) {
              failures++;

              for (var ii = 0; ii < resultsItemCount; ii++) {
                var expectation = resultsItems[ii];
                if (!expectation.passed()) {
                  failureMessages.push(expectation.message);
                }
              }
            }
            return {
              assertions: resultsItemCount,
              className: getNestedSuiteName(spec.suite),
              name: spec.description,
              time: spec.duration / 1000,
              failureMessages: failureMessages
            };
          });

          var data = {
              name: getNestedSuiteName(suite),
              time: suite.duration / 1000,
              timestamp: suite.timestamp,
              tests: suite.specs().length,
              errors: 0, // TODO: These exist in the JUnit XML but not sure how they map to jasmine things
              testcases: testcases,
              failures: failures
            };

          if (suite.parentSuite) {
            consolidatedSuites[getTopLevelSuiteId(suite)].push(data);
          } else {
            consolidatedSuites[suite.id] = [data];
          }
          return data;
        });

    return {
      suites: suites,
      consolidatedSuites: consolidatedSuites
    };
  };

  jasmine.getEnv().addReporter( new PhantomReporter() );
}());
<|endoftext|>


<commit_before>import Ember from "ember";
import { getLayout } from "dom-ruler";
import startApp from "../helpers/start-app";

var App;

module("Acceptance: options scroll into view", {
  setup: function () {
    App = startApp();
  },
  teardown: function () {
    Ember.run(App, "destroy");
  }
});

test("searching for an option will focus it into view", function () {
  expect(1);
  visit("/");
  keyEvent(".select-menu:last-child", "keydown", "z");
  andThen(function () {
    var popup = find("#alphabet + .popup-menu");
    var list = popup.find(".select-menu_list");
    var maxScrollTop = getLayout(list[0]).padding.height - getLayout(popup[0]).height;
    equal(popup.scrollTop(), maxScrollTop);
  });
});
<commit_msg>add tests for scrolling using arrow keys<commit_after>import Ember from "ember";
import { getLayout } from "dom-ruler";
import startApp from "../helpers/start-app";

var App;

module("Acceptance: options scroll into view", {
  setup: function () {
    App = startApp();
  },
  teardown: function () {
    Ember.run(App, "destroy");
  }
});

test("searching for an option will focus it into view", function () {
  expect(2);
  visit("/");
  keyEvent(".select-menu:last-child", "keydown", "z");
  andThen(function () {
    var popup = find("#alphabet + .popup-menu");
    var list = popup.find(".select-menu_list");
    var maxScrollTop = getLayout(list[0]).padding.height - getLayout(popup[0]).height;
    equal(list.scrollTop(), maxScrollTop);
  });

  keyEvent(".select-menu:last-child", "keydown", "a");
  andThen(function () {
    var popup = find("#alphabet + .popup-menu");
    equal(popup.scrollTop(), 0);
  });
});

test("using up and down arrows will focus the element into view", function () {
  expect(15);
  visit("/");

  var UP = 38;
  var DOWN = 40;

  var flushTop = function () {
    var list = find("#alphabet + .popup-menu .select-menu_list");
    equal(list.scrollTop(), 0);
  };
  var offset = function () {
    var list = find("#alphabet + .popup-menu .select-menu_list");
    ok(list.scrollTop() > 0);
  };

  for (var i = 0; i < 7; i++) {
    keyEvent(".select-menu:last-child", "keydown", DOWN);
    andThen(flushTop);
  }

  keyEvent(".select-menu:last-child", "keydown", DOWN);
  andThen(offset);

  for (i = 0; i < 6; i++) {
    keyEvent(".select-menu:last-child", "keydown", UP);
    andThen(offset);
  }

  keyEvent(".select-menu:last-child", "keydown", UP);
  andThen(flushTop);
});
<|endoftext|>


<commit_before>import fetch  from 'isomorphic-fetch'
import React  from 'react'
import { Grid, Row, Col, Button, Table, Input, Panel, Glyphicon } from 'react-bootstrap'
import { Link, browserHistory } from 'react-router'

import ManagerPage  from '../../common/components/ManagerPage'
import EditableTextField from '../../common/components/EditableTextField'
import { retrievalMethodString } from '../../common/util/util'
import ExternalPropertiesTable  from './ExternalPropertiesTable'
import FeedVersionNavigator  from './FeedVersionNavigator'
import NotesViewer from './NotesViewer'

const retrievalMethods = [
  'FETCHED_AUTOMATICALLY',
  'MANUALLY_UPLOADED',
  'PRODUCED_IN_HOUSE'
]

export default class FeedSourceViewer extends React.Component {

  constructor (props) {
    super(props)

    this.state = {
      snapshotVersions: []
    }

    if(this.props.feedSource && this.props.feedSource.retrievalMethod === 'PRODUCED_IN_HOUSE') {
      this.updateSnapshotVersions(this.props.feedSource)
    }
  }

  componentWillMount () {
    this.props.onComponentMount(this.props)
  }

  componentWillReceiveProps (nextProps) {
    if(nextProps.feedSource && nextProps.feedSource.retrievalMethod === 'PRODUCED_IN_HOUSE') {
      this.updateSnapshotVersions(nextProps.feedSource)
    }
  }

  updateSnapshotVersions (feedSource) {
    const url = DT_CONFIG.modules.editor.url + '/api/mgrsnapshot?sourceId=' + feedSource.id
    fetch(url)
      .then(res => res.json())
      .then(snapshots => {
        this.setState({
          snapshotVersions: snapshots
        })
      })
      .catch(err => {
        console.log('Error fetching snapshots', err)
      })
  }

  deleteFeedVersion (feedSource, feedVersion) {
    this.refs['page'].showConfirmModal({
      title: 'Delete Feed Version?',
      body: 'Are you sure you want to delete this version?',
      onConfirm: () => {
        this.props.deleteFeedVersionConfirmed(feedSource, feedVersion)
      }
    })
  }

  render () {
    const fs = this.props.feedSource

    if(!fs) {
      return <ManagerPage />
    }
    const disabled = !this.props.user.permissions.hasFeedPermission(this.props.project.id, fs.id, 'manage-feed')
    const isWatchingFeed = this.props.user.subscriptions.hasFeedSubscription(this.props.project.id, fs.id, 'feed-updated')
    return (
      <ManagerPage ref='page'>
        <Grid>
          <Row>
            <Col xs={12}>

<Link to='/'>Explore</Link>

<Link to='/project'>Projects</Link>

<Link to={`/project/${this.props.project.id}`}>{this.props.project.name}</Link>

{fs.name}

            </Col>
          </Row>

          <Row>
            <Col xs={12}>

                {fs.name}
                Private view (<Link to={`/public/feed/${fs.id}`}>View public page</Link>)
                {
                  DT_CONFIG.application.notifications_enabled ?
                  <Button
                    className={`pull-right`}
                    onClick={() => { this.props.updateUserSubscription(this.props.user.profile, fs.id, 'feed-updated') }}
                  >
                    {
                      isWatchingFeed ? <Glyphicon glyph='eye-close'/> Unwatch
                      : <Glyphicon glyph='eye-open'/> Watch
                    }
                  </Button>
                  : ''
                }

            </Col>
          </Row>

          <Panel header={(
<Glyphicon glyph='cog' /> Feed Source Properties
)}>
            <Row>
              <Col xs={12} sm={6}>

                      Property
                      Value

                      Name

                        <EditableTextField
                          value={fs.name}
                          disabled={disabled}
                          onChange={(value) => this.props.feedSourcePropertyChanged(fs, 'name', value)}
                        />

                      Retrieval Method

                        <Input type='select'
                          value={fs.retrievalMethod}
                          disabled={disabled}
                          onChange={(evt) => {
                            console.log(evt.target.value);
                            this.props.feedSourcePropertyChanged(fs, 'retrievalMethod', evt.target.value)
                          }}
                        >
                          {retrievalMethods.map(method => {
                            return <option value={method} key={method}>
                              {retrievalMethodString(method)}
                            </option>
                          })}
                        </Input>

                    {fs.retrievalMethod === 'FETCHED_AUTOMATICALLY'
                      ?

                          Retrieval URL

                            <EditableTextField
                              value={fs.url}
                              maxLength={30}
                              disabled={disabled}
                              onChange={(value) => this.props.feedSourcePropertyChanged(fs, 'url', value)}
                            />

                      : null
                    }

                    {fs.retrievalMethod === 'PRODUCED_IN_HOUSE'
                      ?

                          Editor Snapshot

                            <Input type='select'
                              value={fs.snapshotVersion}
                              onChange={(evt) => {
                                console.log(evt.target.value);
                                this.props.feedSourcePropertyChanged(fs, 'snapshotVersion', evt.target.value)
                              }}
                            >
                              <option>(None Selected)</option>
                              {this.state.snapshotVersions.map(snapshot => {
                                return <option value={snapshot.id} key={snapshot.id}>
                                  {snapshot.name}
                                </option>
                              })}
                            </Input>

                      : null
                    }

              </Col>

              <Col xs={12} sm={6}>
                {Object.keys(fs.externalProperties || {}).map(resourceType => {
                  console.log('>> resourceType=' + resourceType);
                  return (<ExternalPropertiesTable
                    resourceType={resourceType}
                    editingIsDisabled={disabled}
                    resourceProps={fs.externalProperties[resourceType]}
                    externalPropertyChanged={(name, value) => {
                      this.props.externalPropertyChanged(fs, resourceType, name, value)
                    }}
                  />)
                })}
              </Col>

            </Row>
          </Panel>

          <NotesViewer
            title='Comments for this Feed Source'
            notes={fs.notes}
            feedSource={fs}
            user={this.props.user}
            updateUserSubscription={this.props.updateUserSubscription}
            noteCount={fs.noteCount}
            notesRequested={() => { this.props.notesRequestedForFeedSource(fs) }}
            newNotePosted={(note) => { this.props.newNotePostedForFeedSource(fs, note) }}
          />

          <Panel header={(
<Glyphicon glyph='list' /> Feed Versions
)}>
            <FeedVersionNavigator
              versions={fs.feedVersions}
              feedSource={fs}
              user={this.props.user}
              updateUserSubscription={this.props.updateUserSubscription}
              updateDisabled={disabled}
              deleteDisabled={disabled}
              validationResultRequested={(version) => this.props.validationResultRequested(fs, version) }
              updateFeedClicked={() => this.props.updateFeedClicked(fs)}
              uploadFeedClicked={() => {
                console.log('showing modal');
                this.refs.page.showSelectFileModal({
                  title: 'Upload Feed',
                  body: 'Select a GTFS feed to upload:',
                  onConfirm: (files) => {
                    console.log('selected file', files[0]);
                    this.props.uploadFeedClicked(fs, files[0])
                  }
                })
              }}
              downloadFeedClicked={(version) => this.props.downloadFeedClicked(version)}
              deleteVersionClicked={(version) => {
                this.deleteFeedVersion(fs, version)
              }}
              notesRequestedForVersion={(version) => {
                  this.props.notesRequestedForVersion(version)
              }}
              newNotePostedForVersion={(version,note) => {
                this.props.newNotePostedForVersion(version, note)
              }}
              gtfsPlusDataRequested={(version) => {
                this.props.gtfsPlusDataRequested(version)
              }}
            />
          </Panel>
        </Grid>
      </ManagerPage>
    )
  }
}
<commit_msg>add public input on feedsourceviewer<commit_after>import fetch  from 'isomorphic-fetch'
import React  from 'react'
import { Grid, Row, Col, Button, Table, Input, Panel, Glyphicon } from 'react-bootstrap'
import { Link, browserHistory } from 'react-router'

import ManagerPage  from '../../common/components/ManagerPage'
import EditableTextField from '../../common/components/EditableTextField'
import { retrievalMethodString } from '../../common/util/util'
import ExternalPropertiesTable  from './ExternalPropertiesTable'
import FeedVersionNavigator  from './FeedVersionNavigator'
import NotesViewer from './NotesViewer'

const retrievalMethods = [
  'FETCHED_AUTOMATICALLY',
  'MANUALLY_UPLOADED',
  'PRODUCED_IN_HOUSE'
]

export default class FeedSourceViewer extends React.Component {

  constructor (props) {
    super(props)

    this.state = {
      snapshotVersions: []
    }

    if(this.props.feedSource && this.props.feedSource.retrievalMethod === 'PRODUCED_IN_HOUSE') {
      this.updateSnapshotVersions(this.props.feedSource)
    }
  }

  componentWillMount () {
    this.props.onComponentMount(this.props)
  }

  componentWillReceiveProps (nextProps) {
    if(nextProps.feedSource && nextProps.feedSource.retrievalMethod === 'PRODUCED_IN_HOUSE') {
      this.updateSnapshotVersions(nextProps.feedSource)
    }
  }

  updateSnapshotVersions (feedSource) {
    const url = DT_CONFIG.modules.editor.url + '/api/mgrsnapshot?sourceId=' + feedSource.id
    fetch(url)
      .then(res => res.json())
      .then(snapshots => {
        this.setState({
          snapshotVersions: snapshots
        })
      })
      .catch(err => {
        console.log('Error fetching snapshots', err)
      })
  }

  deleteFeedVersion (feedSource, feedVersion) {
    this.refs['page'].showConfirmModal({
      title: 'Delete Feed Version?',
      body: 'Are you sure you want to delete this version?',
      onConfirm: () => {
        this.props.deleteFeedVersionConfirmed(feedSource, feedVersion)
      }
    })
  }

  render () {
    const fs = this.props.feedSource

    if(!fs) {
      return <ManagerPage />
    }
    const disabled = !this.props.user.permissions.hasFeedPermission(this.props.project.id, fs.id, 'manage-feed')
    const isWatchingFeed = this.props.user.subscriptions.hasFeedSubscription(this.props.project.id, fs.id, 'feed-updated')
    return (
      <ManagerPage ref='page'>
        <Grid>
          <Row>
            <Col xs={12}>

<Link to='/'>Explore</Link>

<Link to='/project'>Projects</Link>

<Link to={`/project/${this.props.project.id}`}>{this.props.project.name}</Link>

{fs.name}

            </Col>
          </Row>

          <Row>
            <Col xs={12}>

                {fs.name}
                {fs.isPublic
                  ? Private view (<Link to={`/public/feed/${fs.id}`}>View public page</Link>)
                  : null
                }
                {
                  DT_CONFIG.application.notifications_enabled ?
                  <Button
                    className={`pull-right`}
                    onClick={() => { this.props.updateUserSubscription(this.props.user.profile, fs.id, 'feed-updated') }}
                  >
                    {
                      isWatchingFeed ? <Glyphicon glyph='eye-close'/> Unwatch
                      : <Glyphicon glyph='eye-open'/> Watch
                    }
                  </Button>
                  : null
                }

            </Col>
          </Row>

          <Panel header={(
<Glyphicon glyph='cog' /> Feed Source Properties
)}>
            <Row>
              <Col xs={12} sm={6}>

                      Property
                      Value

                      Name

                        <EditableTextField
                          value={fs.name}
                          disabled={disabled}
                          onChange={(value) => this.props.feedSourcePropertyChanged(fs, 'name', value)}
                        />

                      Retrieval Method

                        <Input type='select'
                          value={fs.retrievalMethod}
                          disabled={disabled}
                          onChange={(evt) => {
                            console.log(evt.target.value);
                            this.props.feedSourcePropertyChanged(fs, 'retrievalMethod', evt.target.value)
                          }}
                        >
                          {retrievalMethods.map(method => {
                            return <option value={method} key={method}>
                              {retrievalMethodString(method)}
                            </option>
                          })}
                        </Input>

                    {fs.retrievalMethod === 'FETCHED_AUTOMATICALLY'
                      ?

                          Retrieval URL

                            <EditableTextField
                              value={fs.url}
                              maxLength={30}
                              disabled={disabled}
                              onChange={(value) => this.props.feedSourcePropertyChanged(fs, 'url', value)}
                            />

                      : null
                    }

                    {fs.retrievalMethod === 'PRODUCED_IN_HOUSE'
                      ?

                          Editor Snapshot

                            <Input type='select'
                              value={fs.snapshotVersion}
                              onChange={(evt) => {
                                console.log(evt.target.value);
                                this.props.feedSourcePropertyChanged(fs, 'snapshotVersion', evt.target.value)
                              }}
                            >
                              <option>(None Selected)</option>
                              {this.state.snapshotVersions.map(snapshot => {
                                return <option value={snapshot.id} key={snapshot.id}>
                                  {snapshot.name}
                                </option>
                              })}
                            </Input>

                      : null
                    }

                      Public?

                        <Input
                          type='checkbox'
                          label=' '
                          disabled={disabled}
                          defaultChecked={fs.isPublic}
                          onChange={(e) => {
                            this.props.feedSourcePropertyChanged(fs, 'isPublic', e.target.checked)
                          }}
                        />

              </Col>

              <Col xs={12} sm={6}>
                {Object.keys(fs.externalProperties || {}).map(resourceType => {
                  console.log('>> resourceType=' + resourceType);
                  return (<ExternalPropertiesTable
                    resourceType={resourceType}
                    editingIsDisabled={disabled}
                    resourceProps={fs.externalProperties[resourceType]}
                    externalPropertyChanged={(name, value) => {
                      this.props.externalPropertyChanged(fs, resourceType, name, value)
                    }}
                  />)
                })}
              </Col>

            </Row>
          </Panel>

          <NotesViewer
            title='Comments for this Feed Source'
            notes={fs.notes}
            feedSource={fs}
            user={this.props.user}
            updateUserSubscription={this.props.updateUserSubscription}
            noteCount={fs.noteCount}
            notesRequested={() => { this.props.notesRequestedForFeedSource(fs) }}
            newNotePosted={(note) => { this.props.newNotePostedForFeedSource(fs, note) }}
          />

          <Panel header={(
<Glyphicon glyph='list' /> Feed Versions
)}>
            <FeedVersionNavigator
              versions={fs.feedVersions}
              feedSource={fs}
              user={this.props.user}
              updateUserSubscription={this.props.updateUserSubscription}
              updateDisabled={disabled}
              deleteDisabled={disabled}
              validationResultRequested={(version) => this.props.validationResultRequested(fs, version) }
              updateFeedClicked={() => this.props.updateFeedClicked(fs)}
              uploadFeedClicked={() => {
                console.log('showing modal');
                this.refs.page.showSelectFileModal({
                  title: 'Upload Feed',
                  body: 'Select a GTFS feed to upload:',
                  onConfirm: (files) => {
                    console.log('selected file', files[0]);
                    this.props.uploadFeedClicked(fs, files[0])
                  }
                })
              }}
              downloadFeedClicked={(version) => this.props.downloadFeedClicked(version)}
              deleteVersionClicked={(version) => {
                this.deleteFeedVersion(fs, version)
              }}
              notesRequestedForVersion={(version) => {
                  this.props.notesRequestedForVersion(version)
              }}
              newNotePostedForVersion={(version,note) => {
                this.props.newNotePostedForVersion(version, note)
              }}
              gtfsPlusDataRequested={(version) => {
                this.props.gtfsPlusDataRequested(version)
              }}
            />
          </Panel>
        </Grid>
      </ManagerPage>
    )
  }
}
<|endoftext|>