<commit_before>'use strict';
// External dependencies
const config = require('config');

// Internal dependencies
const Review = require('../../models/review');
const Thing = require('../../models/thing');
const Team = require('../../models/team');
const AbstractBREADProvider = require('./abstract-bread-provider');
const flashError = require('../helpers/flash-error');
const mlString = require('../../models/helpers/ml-string.js');
const urlUtils = require('../../util/url-utils');
const ErrorMessage = require('../../util/error.js');
const md = require('../../util/md');

class ReviewProvider extends AbstractBREADProvider {

  constructor(req, res, next, options) {

    super(req, res, next, options);
    this.actions.add.titleKey = 'new review';
    this.actions.edit.titleKey = 'edit review';
    this.actions.delete.titleKey = 'delete review';
    this.messageKeyPrefix = 'review';

    this.actions.addFromThing = {
      GET: this.addFromThing_GET,
      POST: this.add_POST,
      loadData: this.loadThing,
      titleKey: 'new review',
      preFlightChecks: [this.userIsSignedIn]
    };

  }

  read_GET(review) {

    let titleParam;
    if (review.thing) {
      if (review.thing.label)
        titleParam = mlString.resolve(this.req.locale, review.thing.label).str;
      else
        titleParam = urlUtils.prettify(review.thing.urls[0]);
    }

    // No permission checks on reads, so we have to do this manually
    review.populateUserInfo(this.req.user);

    this.renderTemplate('review', {
      titleKey: titleParam ? 'review of' : 'review',
      titleParam,
      deferPageHeader: true,
      review
    });

  }

  add_GET(formValues, thing) {

    let pageErrors = this.req.flash('pageErrors');
    let pageMessages = this.req.flash('pageMessages');
    let user = this.req.user;
    let showLanguageNotice = true;

    // For easier processing in the template
    if (formValues) {
      if (formValues.starRating)
        formValues.hasRating = {
          [formValues.starRating]: true
        };
      formValues.hasTeam = {};
      if (Array.isArray(formValues.teams))
       formValues.teams.forEach(team => (formValues.hasTeam[team.id] = true));
    }

    if (user.suppressedNotices &&
      user.suppressedNotices.indexOf('language-notice-review') !== -1)
      showLanguageNotice = false;

    this.renderTemplate('review-form', {
      formValues,
      titleKey: this.actions[this.action].titleKey,
      pageErrors: !this.isPreview ? pageErrors : undefined, // Don't show errors on preview
      isPreview: this.isPreview,
      preview: this.preview,
      scripts: ['markdown.min.js', 'review.js'],
      showLanguageNotice,
      pageMessages,
      thing,
      editing: this.editing ? true : false
    }, {
      editing: this.editing ? true : false,
      messages: md.getMarkdownMessages(this.req.locale)
    });
  }

  addFromThing_GET(thing) {

    thing
      .getReviewsByUser(this.req.user)
      .then(reviews => {
        if (reviews.length) {
          this.req.flash('pageMessages', this.req.__('you already wrote a review'));
          return this.res.redirect(`/review/${reviews[0].id}/edit`);
        }
        this.add_GET(undefined, thing);
      })
      .catch(this.next);

  }

  add_POST(thing) {

    this.isPreview = this.req.body['review-action'] == 'preview' ? true : false;

    let formKey = 'new-review';
    let language = this.req.body['review-language'];
    let formData = this.parseForm({
      formDef: ReviewProvider.formDefs[formKey],
      formKey,
      language,
      // We don't need a URL if we're adding a review to an existing thing
      skipRequiredCheck: thing && thing.id ? ['review-url'] : []
    });

    formData.formValues.createdBy = this.req.user.id;
    formData.formValues.createdOn = new Date();
    formData.formValues.originalLanguage = language;

    // We're previewing or have basic problems with the submission -- back to form
    if (this.isPreview || this.req.flashHas('pageErrors')) {
      formData.formValues.creator = this.req.user; // Needed for username link
      return this.add_GET(formData.formValues, thing);
    }

    let reviewObj = Object.assign({}, formData.formValues);

    if (thing && thing.id)
      reviewObj.thing = thing;

    this
      .validateAndGetTeams(formData.formValues.teams)
      .then(teams => {

        reviewObj.teams = teams;

        Review
          .create(reviewObj, {
            tags: ['create-via-form']
          })
          .then(review => {
            this.req.app.locals.webHooks.trigger('newReview', {
              event: 'new-review',
              data: this.getWebHookData(review, this.req.user)
            });
            this.req.user.inviteLinkCount++;
            this.req.user
              .save()
              .then(() => {
                this.res.redirect(`/${review.thing.id}#your-review`);
              })
              .catch(this.next); // Problem updating invite count
          })
          .catch(errorMessage => {
            flashError(this.req, errorMessage, 'saving review');
            this.add_GET(formData.formValues, thing);
          });

      })
      .catch(error => {
        if (error.name == 'DocumentNotFoundError' || error.name == 'RevisionDeletedError')
          error = new ErrorMessage('submitted team could not be found', [], error);

        flashError(this.req, error, 'add review->get team data');
        this.add_GET(formData.formValues, thing);
      });

  }

  loadData() {

    return new Promise((resolve, reject) => {
      Review.getWithData(this.id).then(review => {
          // For permission checks on associated thing
          review.thing.populateUserInfo(this.req.user);
          resolve(review);
        })
        .catch(error => {
          reject(error);
        });
    });

  }

  loadThing() {

    // Ensure we show "thing not found" error if user tries to create
    // review from a nonexistent/stale/deleted thing
    this.messageKeyPrefix = 'thing';
    return Thing.getNotStaleOrDeleted(this.id);

  }

  edit_GET(review) {

    this.editing = true;
    this.add_GET(review, review.thing);

  }

  edit_POST(review) {

    let formKey = 'edit-review';
    let language = this.req.body['review-language'];
    let formData = this.parseForm({
      formDef: ReviewProvider.formDefs[formKey],
      formKey,
      language
    });

    // We no longer accept URL edits if we're in edit-mode
    this.editing = true;

    if (this.req.body['review-action'] == 'preview') {
      // Pass along original authorship info for preview
      formData.formValues.createdOn = review.createdOn;
      formData.formValues.creator = review.creator;
      this.isPreview = true;
    }
    // As with creation, back to edit form if we have errors or
    // are previewing
    if (this.isPreview || this.req.flashHas('pageErrors'))
      return this.add_GET(formData.formValues);

    this
      .validateAndGetTeams(formData.formValues.teams)
      .then(teams => {
        // Save the edit
        review
          .newRevision(this.req.user, {
            tags: ['edit-via-form']
          })
          .then(newRev => {
            let f = formData.formValues;
            newRev.title[language] = f.title[language];
            newRev.text[language] = f.text[language];
            newRev.html[language] = f.html[language];
            newRev.starRating = f.starRating;
            newRev.teams = teams;
            newRev.thing = review.thing;
            newRev
              .saveAll({ // Do not save changes to joined user
                teams: true,
                thing: true
              })
              .then(() => {
                this.req.flash('pageMessages', this.req.__('edit saved'));
                this.res.redirect(`/review/${newRev.id}`);
              })
              .catch(error => {
                flashError(this.req, error, 'edit review->save');
                this.add_GET(formData.formValues);
              });
          })
          .catch(error => {
            flashError(this.req, error, 'edit review->new revision');
            this.add_GET(formData.formValues);
          });
      })
      .catch(error => {
        if (error.name == 'DocumentNotFoundError' || error.name == 'RevisionDeletedError')
          error = new ErrorMessage('submitted team could not be found', [], error);

        flashError(this.req, error, 'edit review->get team data');
        this.add_GET(formData.formValues);
      });

  }

  validateAndGetTeams(teamObj) {

    return new Promise((resolve, reject) => {

      if (typeof teamObj !== 'object' || !Object.keys(teamObj).length)
        return resolve([]);

      let p = [];
      for (let id in teamObj)
        p.push(Team.getWithData(id));

      Promise
        .all(p)
        .then(teams => {

          teams.forEach(team => {
            team.populateUserInfo(this.req.user);
            if (!team.userIsMember)
              throw new ErrorMessage('user is not member of submitted team');
          });
          resolve(teams);

        })
        .catch(error => reject(error));
    });

  }

  delete_GET(review) {
    let pageErrors = this.req.flash('pageErrors');

    this.renderTemplate('delete-review', {
      review,
      pageErrors
    });
  }

  delete_POST(review) {
    let withThing = this.req.body['delete-thing'] ? true : false;
    this.parseForm({
      formDef: ReviewProvider.formDefs['delete-review'],
      formKey: 'delete-review'
    });

    // Trying to delete recursively, but can't!
    if (withThing && !review.thing.userCanDelete)
      return this.renderPermissionError({
        titleKey: this.actions[this.action].titleKey
      });

    if (this.req.flashHas('pageErrors'))
      return this.delete_GET(review);

    let deleteFunc = withThing ?
      review.deleteAllRevisionsWithThing :
      review.deleteAllRevisions;

    Reflect.apply(deleteFunc, review, [this.req.user])
      .then(() => {
        this.renderTemplate('review-deleted', {
          titleKey: 'review deleted'
        });
      })
      .catch(this.next);
  }

  // Return data for easy external processing after publication, e.g. via IRC
  // feeds
  getWebHookData(review, user) {

    return {
      title: review.title,
      thingURLs: review.thing.urls,
      thingLabel: review.thing.label,
      starRating: review.starRating,
      html: review.html,
      text: review.text,
      createdOn: review.createdOn,
      author: user.displayName,
      reviewURL: `${config.qualifiedURL}review/${review.id}`,
      thingURL: `${config.qualifiedURL}thing/${review.thing.id}`,
      authorURL: `${config.qualifiedURL}user/${user.urlName}`
    };

  }

}

module.exports = ReviewProvider;

// Shared across instances
ReviewProvider.formDefs = {
  'new-review': [{
      name: 'review-url',
      required: true,
      type: 'url',
      key: 'url'
    }, {
      name: 'review-title',
      required: true,
      type: 'text',
      key: 'title'
    }, {
      name: 'review-text',
      required: true,
      type: 'markdown',
      key: 'text',
      flat: true,
      htmlKey: 'html'
    }, {
      name: 'review-rating',
      required: true,
      type: 'number',
      key: 'starRating'
    }, {
      name: 'review-language',
      required: false,
      key: 'originalLanguage'
    }, {
      name: 'review-action',
      required: true,
      skipValue: true // Logic, not saved
    },
    {
      name: 'review-team-%uuid',
      required: false,
      type: 'boolean',
      keyValueMap: 'teams'
    }
  ],
  'delete-review': [{
    name: 'delete-action',
    required: true
  }, {
    name: 'delete-thing',
    required: false
  }],
  'edit-review': [{
      name: 'review-title',
      required: true,
      type: 'text',
      key: 'title'
    }, {
      name: 'review-text',
      required: true,
      type: 'markdown',
      key: 'text',
      flat: true,
      htmlKey: 'html'
    }, {
      name: 'review-rating',
      required: true,
      type: 'number',
      key: 'starRating'
    }, {
      name: 'review-language',
      required: true
    }, {
      name: 'review-action',
      required: true,
      skipValue: true
    },
    {
      name: 'review-team-%uuid',
      required: false,
      type: 'boolean',
      keyValueMap: 'teams'
    }
  ]
};
<commit_msg>Properly resolve things when starting a new review for existing thing<commit_after>'use strict';
// External dependencies
const config = require('config');

// Internal dependencies
const Review = require('../../models/review');
const Team = require('../../models/team');
const AbstractBREADProvider = require('./abstract-bread-provider');
const flashError = require('../helpers/flash-error');
const mlString = require('../../models/helpers/ml-string.js');
const urlUtils = require('../../util/url-utils');
const ErrorMessage = require('../../util/error.js');
const md = require('../../util/md');
const slugs = require('../helpers/slugs');

class ReviewProvider extends AbstractBREADProvider {

  constructor(req, res, next, options) {

    super(req, res, next, options);
    this.actions.add.titleKey = 'new review';
    this.actions.edit.titleKey = 'edit review';
    this.actions.delete.titleKey = 'delete review';
    this.messageKeyPrefix = 'review';

    this.actions.addFromThing = {
      GET: this.addFromThing_GET,
      POST: this.add_POST,
      loadData: this.loadThing,
      titleKey: 'new review',
      preFlightChecks: [this.userIsSignedIn]
    };

  }

  read_GET(review) {

    let titleParam;
    if (review.thing) {
      if (review.thing.label)
        titleParam = mlString.resolve(this.req.locale, review.thing.label).str;
      else
        titleParam = urlUtils.prettify(review.thing.urls[0]);
    }

    // No permission checks on reads, so we have to do this manually
    review.populateUserInfo(this.req.user);

    this.renderTemplate('review', {
      titleKey: titleParam ? 'review of' : 'review',
      titleParam,
      deferPageHeader: true,
      review
    });

  }

  add_GET(formValues, thing) {

    let pageErrors = this.req.flash('pageErrors');
    let pageMessages = this.req.flash('pageMessages');
    let user = this.req.user;
    let showLanguageNotice = true;

    // For easier processing in the template
    if (formValues) {
      if (formValues.starRating)
        formValues.hasRating = {
          [formValues.starRating]: true
        };
      formValues.hasTeam = {};
      if (Array.isArray(formValues.teams))
       formValues.teams.forEach(team => (formValues.hasTeam[team.id] = true));
    }

    if (user.suppressedNotices &&
      user.suppressedNotices.indexOf('language-notice-review') !== -1)
      showLanguageNotice = false;

    this.renderTemplate('review-form', {
      formValues,
      titleKey: this.actions[this.action].titleKey,
      pageErrors: !this.isPreview ? pageErrors : undefined, // Don't show errors on preview
      isPreview: this.isPreview,
      preview: this.preview,
      scripts: ['markdown.min.js', 'review.js'],
      showLanguageNotice,
      pageMessages,
      thing,
      editing: this.editing ? true : false
    }, {
      editing: this.editing ? true : false,
      messages: md.getMarkdownMessages(this.req.locale)
    });
  }

  addFromThing_GET(thing) {

    thing
      .getReviewsByUser(this.req.user)
      .then(reviews => {
        if (reviews.length) {
          this.req.flash('pageMessages', this.req.__('you already wrote a review'));
          return this.res.redirect(`/review/${reviews[0].id}/edit`);
        }
        this.add_GET(undefined, thing);
      })
      .catch(this.next);

  }

  add_POST(thing) {

    this.isPreview = this.req.body['review-action'] == 'preview' ? true : false;

    let formKey = 'new-review';
    let language = this.req.body['review-language'];
    let formData = this.parseForm({
      formDef: ReviewProvider.formDefs[formKey],
      formKey,
      language,
      // We don't need a URL if we're adding a review to an existing thing
      skipRequiredCheck: thing && thing.id ? ['review-url'] : []
    });

    formData.formValues.createdBy = this.req.user.id;
    formData.formValues.createdOn = new Date();
    formData.formValues.originalLanguage = language;

    // We're previewing or have basic problems with the submission -- back to form
    if (this.isPreview || this.req.flashHas('pageErrors')) {
      formData.formValues.creator = this.req.user; // Needed for username link
      return this.add_GET(formData.formValues, thing);
    }

    let reviewObj = Object.assign({}, formData.formValues);

    if (thing && thing.id)
      reviewObj.thing = thing;

    this
      .validateAndGetTeams(formData.formValues.teams)
      .then(teams => {

        reviewObj.teams = teams;

        Review
          .create(reviewObj, {
            tags: ['create-via-form']
          })
          .then(review => {
            this.req.app.locals.webHooks.trigger('newReview', {
              event: 'new-review',
              data: this.getWebHookData(review, this.req.user)
            });
            this.req.user.inviteLinkCount++;
            this.req.user
              .save()
              .then(() => {
                this.res.redirect(`/${review.thing.id}#your-review`);
              })
              .catch(this.next); // Problem updating invite count
          })
          .catch(errorMessage => {
            flashError(this.req, errorMessage, 'saving review');
            this.add_GET(formData.formValues, thing);
          });

      })
      .catch(error => {
        if (error.name == 'DocumentNotFoundError' || error.name == 'RevisionDeletedError')
          error = new ErrorMessage('submitted team could not be found', [], error);

        flashError(this.req, error, 'add review->get team data');
        this.add_GET(formData.formValues, thing);
      });

  }

  loadData() {

    return new Promise((resolve, reject) => {
      Review.getWithData(this.id).then(review => {
          // For permission checks on associated thing
          review.thing.populateUserInfo(this.req.user);
          resolve(review);
        })
        .catch(error => {
          reject(error);
        });
    });

  }

  loadThing() {

    // Ensure we show "thing not found" error if user tries to create
    // review from a nonexistent/stale/deleted thing
    this.messageKeyPrefix = 'thing';
    return slugs.resolveAndLoadThing(this.req, this.res, this.id);

  }

  edit_GET(review) {

    this.editing = true;
    this.add_GET(review, review.thing);

  }

  edit_POST(review) {

    let formKey = 'edit-review';
    let language = this.req.body['review-language'];
    let formData = this.parseForm({
      formDef: ReviewProvider.formDefs[formKey],
      formKey,
      language
    });

    // We no longer accept URL edits if we're in edit-mode
    this.editing = true;

    if (this.req.body['review-action'] == 'preview') {
      // Pass along original authorship info for preview
      formData.formValues.createdOn = review.createdOn;
      formData.formValues.creator = review.creator;
      this.isPreview = true;
    }
    // As with creation, back to edit form if we have errors or
    // are previewing
    if (this.isPreview || this.req.flashHas('pageErrors'))
      return this.add_GET(formData.formValues);

    this
      .validateAndGetTeams(formData.formValues.teams)
      .then(teams => {
        // Save the edit
        review
          .newRevision(this.req.user, {
            tags: ['edit-via-form']
          })
          .then(newRev => {
            let f = formData.formValues;
            newRev.title[language] = f.title[language];
            newRev.text[language] = f.text[language];
            newRev.html[language] = f.html[language];
            newRev.starRating = f.starRating;
            newRev.teams = teams;
            newRev.thing = review.thing;
            newRev
              .saveAll({ // Do not save changes to joined user
                teams: true,
                thing: true
              })
              .then(() => {
                this.req.flash('pageMessages', this.req.__('edit saved'));
                this.res.redirect(`/review/${newRev.id}`);
              })
              .catch(error => {
                flashError(this.req, error, 'edit review->save');
                this.add_GET(formData.formValues);
              });
          })
          .catch(error => {
            flashError(this.req, error, 'edit review->new revision');
            this.add_GET(formData.formValues);
          });
      })
      .catch(error => {
        if (error.name == 'DocumentNotFoundError' || error.name == 'RevisionDeletedError')
          error = new ErrorMessage('submitted team could not be found', [], error);

        flashError(this.req, error, 'edit review->get team data');
        this.add_GET(formData.formValues);
      });

  }

  validateAndGetTeams(teamObj) {

    return new Promise((resolve, reject) => {

      if (typeof teamObj !== 'object' || !Object.keys(teamObj).length)
        return resolve([]);

      let p = [];
      for (let id in teamObj)
        p.push(Team.getWithData(id));

      Promise
        .all(p)
        .then(teams => {

          teams.forEach(team => {
            team.populateUserInfo(this.req.user);
            if (!team.userIsMember)
              throw new ErrorMessage('user is not member of submitted team');
          });
          resolve(teams);

        })
        .catch(error => reject(error));
    });

  }

  delete_GET(review) {
    let pageErrors = this.req.flash('pageErrors');

    this.renderTemplate('delete-review', {
      review,
      pageErrors
    });
  }

  delete_POST(review) {
    let withThing = this.req.body['delete-thing'] ? true : false;
    this.parseForm({
      formDef: ReviewProvider.formDefs['delete-review'],
      formKey: 'delete-review'
    });

    // Trying to delete recursively, but can't!
    if (withThing && !review.thing.userCanDelete)
      return this.renderPermissionError({
        titleKey: this.actions[this.action].titleKey
      });

    if (this.req.flashHas('pageErrors'))
      return this.delete_GET(review);

    let deleteFunc = withThing ?
      review.deleteAllRevisionsWithThing :
      review.deleteAllRevisions;

    Reflect.apply(deleteFunc, review, [this.req.user])
      .then(() => {
        this.renderTemplate('review-deleted', {
          titleKey: 'review deleted'
        });
      })
      .catch(this.next);
  }

  // Return data for easy external processing after publication, e.g. via IRC
  // feeds
  getWebHookData(review, user) {

    return {
      title: review.title,
      thingURLs: review.thing.urls,
      thingLabel: review.thing.label,
      starRating: review.starRating,
      html: review.html,
      text: review.text,
      createdOn: review.createdOn,
      author: user.displayName,
      reviewURL: `${config.qualifiedURL}review/${review.id}`,
      thingURL: `${config.qualifiedURL}thing/${review.thing.id}`,
      authorURL: `${config.qualifiedURL}user/${user.urlName}`
    };

  }

}

module.exports = ReviewProvider;

// Shared across instances
ReviewProvider.formDefs = {
  'new-review': [{
      name: 'review-url',
      required: true,
      type: 'url',
      key: 'url'
    }, {
      name: 'review-title',
      required: true,
      type: 'text',
      key: 'title'
    }, {
      name: 'review-text',
      required: true,
      type: 'markdown',
      key: 'text',
      flat: true,
      htmlKey: 'html'
    }, {
      name: 'review-rating',
      required: true,
      type: 'number',
      key: 'starRating'
    }, {
      name: 'review-language',
      required: false,
      key: 'originalLanguage'
    }, {
      name: 'review-action',
      required: true,
      skipValue: true // Logic, not saved
    },
    {
      name: 'review-team-%uuid',
      required: false,
      type: 'boolean',
      keyValueMap: 'teams'
    }
  ],
  'delete-review': [{
    name: 'delete-action',
    required: true
  }, {
    name: 'delete-thing',
    required: false
  }],
  'edit-review': [{
      name: 'review-title',
      required: true,
      type: 'text',
      key: 'title'
    }, {
      name: 'review-text',
      required: true,
      type: 'markdown',
      key: 'text',
      flat: true,
      htmlKey: 'html'
    }, {
      name: 'review-rating',
      required: true,
      type: 'number',
      key: 'starRating'
    }, {
      name: 'review-language',
      required: true
    }, {
      name: 'review-action',
      required: true,
      skipValue: true
    },
    {
      name: 'review-team-%uuid',
      required: false,
      type: 'boolean',
      keyValueMap: 'teams'
    }
  ]
};
<|endoftext|>


<commit_before>/*
 * Copyright 2005-2012 The Kuali Foundation
 *
 * Licensed under the Educational Community License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.opensource.org/licenses/ecl2.php
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 *  This function "patches" an input field (or other element) to use a calendar
 *  widget for date selection.
 *
 *  The "params" is a single object that can have the following properties:
 *
 *    prop. name   | description
 *  -------------------------------------------------------------------------------------------------
 *   inputField    | the ID of an input field to store the date
 *   displayArea   | the ID of a DIV or other element to show the date
 *   button        | ID of a button or other element that will trigger the calendar
 *   eventName     | event that will trigger the calendar, without the "on" prefix (default: "click")
 *   ifFormat      | date format that will be stored in the input field
 *   daFormat      | the date format that will be used to display the date in displayArea
 *   singleClick   | (true/false) wether the calendar is in single click mode or not (default: true)
 *   firstDay      | numeric: 0 to 6.  "0" means display Sunday first, "1" means display Monday first, etc.
 *   align         | alignment (default: "Br"); if you don't know what's this see the calendar documentation
 *   range         | array with 2 elements.  Default: [1900, 2999] -- the range of years available
 *   weekNumbers   | (true/false) if it's true (default) the calendar will display week numbers
 *   flat          | null or element ID; if not null the calendar will be a flat calendar having the parent with the given ID
 *   flatCallback  | function that receives a JS Date object and returns an URL to point the browser to (for flat calendar)
 *   disableFunc   | function that receives a JS Date object and should return true if that date has to be disabled in the calendar
 *   onSelect      | function that gets called when a date is selected.  You don't _have_ to supply this (the default is generally okay)
 *   onClose       | function that gets called when the calendar is closed.  [default]
 *   onUpdate      | function that gets called after the date is updated in the input field.  Receives a reference to the calendar.
 *   date          | the date that the calendar will be initially displayed to
 *   showsTime     | default: false; if true the calendar will include a time selector
 *   timeFormat    | the time format; can be "12" or "24", default is "12"
 *   electric      | if true (default) then given fields/date areas are updated for each move; otherwise they're updated only on close
 *   step          | configures the step of the years in drop-down boxes; default: 2
 *   position      | configures the calendar absolute position; default: null
 *   cache         | if "true" (but default: "false") it will reuse the same calendar object, where possible
 *   showOthers    | if "true" (but default: "false") it will show days from other months too
 *
 *  None of them is required, they all have default values.  However, if you
 *  pass none of "inputField", "displayArea" or "button" you'll get a warning
 *  saying "nothing to setup".
 */
Calendar.setup = function (params) {
	function param_default(pname, def) { if (typeof params[pname] == "undefined") { params[pname] = def; } };

	param_default("inputField",     null);
	param_default("displayArea",    null);
	param_default("button",         null);
	param_default("eventName",      "click");
	param_default("ifFormat",       "%Y/%m/%d");
	param_default("daFormat",       "%Y/%m/%d");
	param_default("singleClick",    true);
	param_default("disableFunc",    null);
	param_default("dateStatusFunc", params["disableFunc"]);	// takes precedence if both are defined
	param_default("dateText",       null);
	param_default("firstDay",       null);
	param_default("align",          "Br");
	param_default("range",          [1900, 2999]);
	param_default("weekNumbers",    true);
	param_default("flat",           null);
	param_default("flatCallback",   null);
	param_default("onSelect",       null);
	param_default("onClose",        null);
	param_default("onUpdate",       null);
	param_default("date",           null);
	param_default("showsTime",      false);
	param_default("timeFormat",     "24");
	param_default("electric",       true);
	param_default("step",           1);
	param_default("position",       null);
	param_default("cache",          false);
	param_default("showOthers",     false);
	param_default("multiple",       null);

	var tmp = ["inputField", "displayArea", "button"];
	for (var i in tmp) {
		if (typeof params[tmp[i]] == "string") {
			params[tmp[i]] = document.getElementById(params[tmp[i]]);
		}
	}
	if (!(params.flat || params.multiple || params.inputField || params.displayArea || params.button)) {
		alert("Calendar.setup:\n  Nothing to setup (no fields found).  Please check your code");
		return false;
	}

	function onSelect(cal) {
		var p = cal.params;
		var update = (cal.dateClicked || p.electric);
		if (update && p.inputField) {
			p.inputField.value = cal.date.print(p.ifFormat);
			if (typeof p.inputField.onchange == "function")
				p.inputField.onchange();
		}
		if (update && p.displayArea)
			p.displayArea.innerHTML = cal.date.print(p.daFormat);
		if (update && typeof p.onUpdate == "function")
			p.onUpdate(cal);
		if (update && p.flat) {
			if (typeof p.flatCallback == "function")
				p.flatCallback(cal);
		}
		if (update && p.singleClick && cal.dateClicked)
			cal.callCloseHandler();
	};

	if (params.flat != null) {
		if (typeof params.flat == "string")
			params.flat = document.getElementById(params.flat);
		if (!params.flat) {
			alert("Calendar.setup:\n  Flat specified but can't find parent.");
			return false;
		}
		var cal = new Calendar(params.firstDay, params.date, params.onSelect || onSelect);
		cal.showsOtherMonths = params.showOthers;
		cal.showsTime = params.showsTime;
		cal.time24 = (params.timeFormat == "24");
		cal.params = params;
		cal.weekNumbers = params.weekNumbers;
		cal.setRange(params.range[0], params.range[1]);
		cal.setDateStatusHandler(params.dateStatusFunc);
		cal.getDateText = params.dateText;
		if (params.ifFormat) {
			cal.setDateFormat(params.ifFormat);
		}
		if (params.inputField && typeof params.inputField.value == "string") {
			cal.parseDate(params.inputField.value);
		}
		cal.create(params.flat);
		cal.show();
		return false;
	}

	var triggerEl = params.button || params.displayArea || params.inputField;
	triggerEl["on" + params.eventName] = function() {
		var dateEl = params.inputField || params.displayArea;
		var dateFmt = params.inputField ? params.ifFormat : params.daFormat;
		var mustCreate = false;
		var cal = window.calendar;
		if (dateEl)
			params.date = Date.parseDate(dateEl.value || dateEl.innerHTML, dateFmt);
		if (!(cal && params.cache)) {
			window.calendar = cal = new Calendar(params.firstDay,
							     params.date,
							     params.onSelect || onSelect,
							     params.onClose || function(cal) { cal.hide(); });
			cal.showsTime = params.showsTime;
			cal.time24 = (params.timeFormat == "24");
			cal.weekNumbers = params.weekNumbers;
			mustCreate = true;
		} else {
			if (params.date)
				cal.setDate(params.date);
			cal.hide();
		}
		if (params.multiple) {
			cal.multiple = {};
			for (var i = params.multiple.length; --i >= 0;) {
				var d = params.multiple[i];
				var ds = d.print("%Y%m%d");
				cal.multiple[ds] = d;
			}
		}
		cal.showsOtherMonths = params.showOthers;
		cal.yearStep = params.step;
		cal.setRange(params.range[0], params.range[1]);
		cal.params = params;
		cal.setDateStatusHandler(params.dateStatusFunc);
		cal.getDateText = params.dateText;
		cal.setDateFormat(dateFmt);
		if (mustCreate)
			cal.create();
		cal.refresh();
		if (!params.position)
			cal.showAtElement(params.button || params.displayArea || params.inputField, params.align);
		else
			cal.showAt(params.position[0], params.position[1]);
		return false;
	};

	return cal;
};
<commit_msg>KULRICE-7027 - Returning focus to date control after date selection.<commit_after>/*
 * Copyright 2005-2012 The Kuali Foundation
 *
 * Licensed under the Educational Community License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.opensource.org/licenses/ecl2.php
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 *  This function "patches" an input field (or other element) to use a calendar
 *  widget for date selection.
 *
 *  The "params" is a single object that can have the following properties:
 *
 *    prop. name   | description
 *  -------------------------------------------------------------------------------------------------
 *   inputField    | the ID of an input field to store the date
 *   displayArea   | the ID of a DIV or other element to show the date
 *   button        | ID of a button or other element that will trigger the calendar
 *   eventName     | event that will trigger the calendar, without the "on" prefix (default: "click")
 *   ifFormat      | date format that will be stored in the input field
 *   daFormat      | the date format that will be used to display the date in displayArea
 *   singleClick   | (true/false) wether the calendar is in single click mode or not (default: true)
 *   firstDay      | numeric: 0 to 6.  "0" means display Sunday first, "1" means display Monday first, etc.
 *   align         | alignment (default: "Br"); if you don't know what's this see the calendar documentation
 *   range         | array with 2 elements.  Default: [1900, 2999] -- the range of years available
 *   weekNumbers   | (true/false) if it's true (default) the calendar will display week numbers
 *   flat          | null or element ID; if not null the calendar will be a flat calendar having the parent with the given ID
 *   flatCallback  | function that receives a JS Date object and returns an URL to point the browser to (for flat calendar)
 *   disableFunc   | function that receives a JS Date object and should return true if that date has to be disabled in the calendar
 *   onSelect      | function that gets called when a date is selected.  You don't _have_ to supply this (the default is generally okay)
 *   onClose       | function that gets called when the calendar is closed.  [default]
 *   onUpdate      | function that gets called after the date is updated in the input field.  Receives a reference to the calendar.
 *   date          | the date that the calendar will be initially displayed to
 *   showsTime     | default: false; if true the calendar will include a time selector
 *   timeFormat    | the time format; can be "12" or "24", default is "12"
 *   electric      | if true (default) then given fields/date areas are updated for each move; otherwise they're updated only on close
 *   step          | configures the step of the years in drop-down boxes; default: 2
 *   position      | configures the calendar absolute position; default: null
 *   cache         | if "true" (but default: "false") it will reuse the same calendar object, where possible
 *   showOthers    | if "true" (but default: "false") it will show days from other months too
 *
 *  None of them is required, they all have default values.  However, if you
 *  pass none of "inputField", "displayArea" or "button" you'll get a warning
 *  saying "nothing to setup".
 */
Calendar.setup = function (params) {
	function param_default(pname, def) { if (typeof params[pname] == "undefined") { params[pname] = def; } };

	param_default("inputField",     null);
	param_default("displayArea",    null);
	param_default("button",         null);
	param_default("eventName",      "click");
	param_default("ifFormat",       "%Y/%m/%d");
	param_default("daFormat",       "%Y/%m/%d");
	param_default("singleClick",    true);
	param_default("disableFunc",    null);
	param_default("dateStatusFunc", params["disableFunc"]);	// takes precedence if both are defined
	param_default("dateText",       null);
	param_default("firstDay",       null);
	param_default("align",          "Br");
	param_default("range",          [1900, 2999]);
	param_default("weekNumbers",    true);
	param_default("flat",           null);
	param_default("flatCallback",   null);
	param_default("onSelect",       null);
	param_default("onClose",        null);
	param_default("onUpdate",       null);
	param_default("date",           null);
	param_default("showsTime",      false);
	param_default("timeFormat",     "24");
	param_default("electric",       true);
	param_default("step",           1);
	param_default("position",       null);
	param_default("cache",          false);
	param_default("showOthers",     false);
	param_default("multiple",       null);

	var tmp = ["inputField", "displayArea", "button"];
	for (var i in tmp) {
		if (typeof params[tmp[i]] == "string") {
			params[tmp[i]] = document.getElementById(params[tmp[i]]);
		}
	}
	if (!(params.flat || params.multiple || params.inputField || params.displayArea || params.button)) {
		alert("Calendar.setup:\n  Nothing to setup (no fields found).  Please check your code");
		return false;
	}

	function onSelect(cal) {
		var p = cal.params;
		var update = (cal.dateClicked || p.electric);
		if (update && p.inputField) {
			p.inputField.value = cal.date.print(p.ifFormat);
			if (typeof p.inputField.onchange == "function")
				p.inputField.onchange();
		}
		if (update && p.displayArea)
			p.displayArea.innerHTML = cal.date.print(p.daFormat);
		if (update && typeof p.onUpdate == "function")
			p.onUpdate(cal);
		if (update && p.flat) {
			if (typeof p.flatCallback == "function")
				p.flatCallback(cal);
		}
		if (update && p.singleClick && cal.dateClicked) {
			cal.callCloseHandler();
            p.inputField.focus();
        }
	};

	if (params.flat != null) {
		if (typeof params.flat == "string")
			params.flat = document.getElementById(params.flat);
		if (!params.flat) {
			alert("Calendar.setup:\n  Flat specified but can't find parent.");
			return false;
		}
		var cal = new Calendar(params.firstDay, params.date, params.onSelect || onSelect);
		cal.showsOtherMonths = params.showOthers;
		cal.showsTime = params.showsTime;
		cal.time24 = (params.timeFormat == "24");
		cal.params = params;
		cal.weekNumbers = params.weekNumbers;
		cal.setRange(params.range[0], params.range[1]);
		cal.setDateStatusHandler(params.dateStatusFunc);
		cal.getDateText = params.dateText;
		if (params.ifFormat) {
			cal.setDateFormat(params.ifFormat);
		}
		if (params.inputField && typeof params.inputField.value == "string") {
			cal.parseDate(params.inputField.value);
		}
		cal.create(params.flat);
		cal.show();
		return false;
	}

	var triggerEl = params.button || params.displayArea || params.inputField;
	triggerEl["on" + params.eventName] = function() {
		var dateEl = params.inputField || params.displayArea;
		var dateFmt = params.inputField ? params.ifFormat : params.daFormat;
		var mustCreate = false;
		var cal = window.calendar;
		if (dateEl)
			params.date = Date.parseDate(dateEl.value || dateEl.innerHTML, dateFmt);
		if (!(cal && params.cache)) {
			window.calendar = cal = new Calendar(params.firstDay,
							     params.date,
							     params.onSelect || onSelect,
							     params.onClose || function(cal) { cal.hide(); });
			cal.showsTime = params.showsTime;
			cal.time24 = (params.timeFormat == "24");
			cal.weekNumbers = params.weekNumbers;
			mustCreate = true;
		} else {
			if (params.date)
				cal.setDate(params.date);
			cal.hide();
		}
		if (params.multiple) {
			cal.multiple = {};
			for (var i = params.multiple.length; --i >= 0;) {
				var d = params.multiple[i];
				var ds = d.print("%Y%m%d");
				cal.multiple[ds] = d;
			}
		}
		cal.showsOtherMonths = params.showOthers;
		cal.yearStep = params.step;
		cal.setRange(params.range[0], params.range[1]);
		cal.params = params;
		cal.setDateStatusHandler(params.dateStatusFunc);
		cal.getDateText = params.dateText;
		cal.setDateFormat(dateFmt);
		if (mustCreate)
			cal.create();
		cal.refresh();
		if (!params.position)
			cal.showAtElement(params.button || params.displayArea || params.inputField, params.align);
		else
			cal.showAt(params.position[0], params.position[1]);
		return false;
	};

	return cal;
};
<|endoftext|>


<commit_before>#!/usr/bin/env node

'use strict';

var fs = require('fs');
var Q = require('q');
var sys = require('sys');
var exec = require('child_process').exec;
var _ = require('underscore');
var argv = require('minimist')(process.argv.slice(2));

module.exports = (function () {

  var readdir = Q.nfbind(fs.readdir);

  var motionContentDir = argv.motionContentDir || '/media/iomega/motion';
  var lastCheckDir = argv.lastCheckDir || '/bigopt/house-monitor';
  var lastCheckFile = 'lastCheck.json';
  var ec2key = argv.ec2key || '/bigopt/house-monitor/ec2-march-2014.pem';
  var ec2UserAndHost = argv.ec2UserAndHost || 'ubuntu@cjparker.us';
  var movieUploadLocation = argv.movieUploadLocation || '/opt/house-monitor/new-vids/';
  var picUploadLocation = argv.picUploadLocation || '/opt/house-monitor/live-vids/';
  var tempsDir = argv.tempsDir || '/bigopt/house-monitor';
  var tempsFilename = 'temps.json';
  var tempUploadLocation = argv.tempUploadLocation || '/opt/house-monitor';

  readdir(motionContentDir)
    .then(function (motionFiles) {

      var lastCheck;

      try {
        var lastCheckJSON = JSON.parse(fs.readFileSync(lastCheckDir + '/' + lastCheckFile, {encoding: 'utf-8'}));
        lastCheck = {
          date: new Date(lastCheckJSON.date)
        }
      } catch (err) {
        console.log('looks like a first run ', err);
        lastCheck = {date: new Date(0)}
      }
      console.log('looking for files written since ', lastCheck);

      var motionFileStats = _.map(motionFiles, function (file) {
        var fd = fs.openSync(motionContentDir + '/' + file, 'r');
        var stat = fs.fstatSync(fd);
        fs.closeSync(fd);
        return {
          name: motionContentDir + '/' + file,
          stat: stat
        };
      });

      // which files are newer than since we last checked
      var newFiles = _.filter(motionFileStats, function (fileStat) {
        if (fileStat.stat.ctime > lastCheck.date) {
          console.log('found a new file ', fileStat.name);
          return true;
        }
      });

      var movieUploadCommand = '/usr/bin/scp -p -i $1 $2 $3:$4'
        .replace('$1', ec2key)
        .replace('$3', ec2UserAndHost)
        .replace('$4', movieUploadLocation);

      var picUploadCommand = '/usr/bin/scp -p -i $1 $2 $3:$4'
        .replace('$1', ec2key)
        .replace('$3', ec2UserAndHost)
        .replace('$4', picUploadLocation);

      // uploads temps.json file to cloud
      var tempUploadCommand = '/usr/bin/scp -p -i $1 $2 $3:$4'
        .replace('$1', ec2key)
        .replace('$2', tempsDir + '/' + tempsFilename)
        .replace('$3', ec2UserAndHost)
        .replace('$4', tempUploadLocation);

      var movies = _.filter(newFiles, function (f) {
        return f.name.match('.avi' + '$') == '.avi';
      });

      var pics = _.filter(newFiles, function (f) {
        return f.name.match('.jpg' + '$') == '.jpg';
      });

      // MOVIES
      _.each(movies, function (fileToUpload) {
        try {
          console.log('running ', movieUploadCommand.replace('$2', fileToUpload.name));
          exec(movieUploadCommand.replace('$2', fileToUpload.name), function (err, stdout, stderr) {
            if (err) {
              console.log(err);
            }
            sys.puts(stdout);
            sys.puts(stderr);

          });
        } catch (err) {
          console.log('caught ', err, ' skipping file');
        }
      });

      // PICS
      _.each(pics, function (fileToUpload) {
        try {
          console.log('running ', picUploadCommand.replace('$2', fileToUpload.name));
          exec(picUploadCommand.replace('$2', fileToUpload.name), function (err, stdout, stderr) {
            if (err) {
              console.log(err);
            }
            sys.puts(stdout);
            sys.puts(stderr);

          });
        } catch (err) {
          console.log('caught ', err, ' skipping file');
        }
      });

      // TEMP
      try {
        exec(tempUploadCommand, function (err, stdout, stderr) {
          if (err) {
            console.log(err);
          }
          sys.puts(stdout);
          sys.puts(stderr);
        });

      } catch (err) {
        console.log('caught error uploading temps', err);
      }

      fs.writeFileSync(lastCheckDir + '/' + lastCheckFile, JSON.stringify({date: new Date()}));
    })
    .catch(function (err) {
      console.log('caught ', err);
    })

})();
<commit_msg>make uploads happen in sequence<commit_after>#!/usr/bin/env node

'use strict';

var fs = require('fs');
var Q = require('q');
var sys = require('sys');
var exec = require('child_process').exec;
var _ = require('underscore');
var argv = require('minimist')(process.argv.slice(2));

module.exports = (function () {

  var readdir = Q.nfbind(fs.readdir);
  var execPromise = Q.nfbind(exec);

  var motionContentDir = argv.motionContentDir || '/media/iomega/motion';
  var lastCheckDir = argv.lastCheckDir || '/bigopt/house-monitor';
  var lastCheckFile = 'lastCheck.json';
  var ec2key = argv.ec2key || '/bigopt/house-monitor/ec2-march-2014.pem';
  var ec2UserAndHost = argv.ec2UserAndHost || 'ubuntu@cjparker.us';
  var movieUploadLocation = argv.movieUploadLocation || '/opt/house-monitor/new-vids/';
  var picUploadLocation = argv.picUploadLocation || '/opt/house-monitor/live-vids/';
  var tempsDir = argv.tempsDir || '/bigopt/house-monitor';
  var tempsFilename = 'temps.json';
  var tempUploadLocation = argv.tempUploadLocation || '/opt/house-monitor';

  readdir(motionContentDir)
    .then(function (motionFiles) {

      var lastCheck;

      try {
        var lastCheckJSON = JSON.parse(fs.readFileSync(lastCheckDir + '/' + lastCheckFile, {encoding: 'utf-8'}));
        lastCheck = {
          date: new Date(lastCheckJSON.date)
        }
      } catch (err) {
        console.log('looks like a first run ', err);
        lastCheck = {date: new Date(0)}
      }
      console.log('looking for files written since ', lastCheck);

      var motionFileStats = _.map(motionFiles, function (file) {
        var fd = fs.openSync(motionContentDir + '/' + file, 'r');
        var stat = fs.fstatSync(fd);
        fs.closeSync(fd);
        return {
          name: motionContentDir + '/' + file,
          stat: stat
        };
      });

      // which files are newer than since we last checked
      var newFiles = _.filter(motionFileStats, function (fileStat) {
        if (fileStat.stat.ctime > lastCheck.date) {
          console.log('found a new file ', fileStat.name);
          return true;
        }
      });

      var movieUploadCommand = '/usr/bin/scp -p -i $1 $2 $3:$4'
        .replace('$1', ec2key)
        .replace('$3', ec2UserAndHost)
        .replace('$4', movieUploadLocation);

      var picUploadCommand = '/usr/bin/scp -p -i $1 $2 $3:$4'
        .replace('$1', ec2key)
        .replace('$3', ec2UserAndHost)
        .replace('$4', picUploadLocation);

      // uploads temps.json file to cloud
      var tempUploadCommand = '/usr/bin/scp -p -i $1 $2 $3:$4'
        .replace('$1', ec2key)
        .replace('$2', tempsDir + '/' + tempsFilename)
        .replace('$3', ec2UserAndHost)
        .replace('$4', tempUploadLocation);

      var movies = _.filter(newFiles, function (f) {
        return f.name.match('.avi' + '$') == '.avi';
      });

      var pics = _.filter(newFiles, function (f) {
        return f.name.match('.jpg' + '$') == '.jpg';
      });

      var logExecIO = function (io) {
        console.log('STDIN: ', io[0]);
        console.log('STDERR: ', io[1]);
      };

      var logExecErr = function (err) {
        console.log('error during exec', err);
      };

      // MOVIES
      var movieUploadPromises = _.map(movies, function (fileToUpload) {
        return function () {
          var command = movieUploadCommand.replace('$2', fileToUpload.name);
          console.log('running', command);

          return execPromise(command)
            .then(logExecIO).catch(logExecErr);
        }
      });

      // PICS
      var picUploadPromises = _.map(pics, function (fileToUpload) {
        var command = picUploadCommand.replace('$2', fileToUpload.name);
        console.log('running ', command);
        return function () {
          return execPromise(command)
            .then(logExecIO).catch(logExecErr);
        }
      });

      // TEMP
      var tempUploadPromise = function () {
        console.log('uploading temperature readings');
        return execPromise(tempUploadCommand)
          .then(logExecIO)
          .catch(logExecErr);
      };

      var writeLastCheck = function () {
        console.log('finishing up');
        return fs.writeFile(lastCheckDir + '/' + lastCheckFile, JSON.stringify({date: new Date()}))
          .then(function () {

          })
          .catch(function (err) {
            console.log('error writing lastCheck', err);
          })
      };

      var allPromises = movieUploadPromises.concat(picUploadPromises).concat([writeLastCheck])
      allPromises.reduce(Q.when, Q('init'));

    })
    .catch(function (err) {
      console.log('caught ', err);
    })

})();
<|endoftext|>


<commit_before>/**
 * jspsych-survey-likert
 * a jspsych plugin for measuring items on a likert scale
 *
 * Josh de Leeuw
 *
 * documentation: docs.jspsych.org
 *
 */

jsPsych.plugins['survey-likert'] = (function() {

  var plugin = {};

  plugin.trial = function(display_element, trial) {

    // default parameters for the trial
    trial.preamble = typeof trial.preamble === 'undefined' ? "" : trial.preamble;
	trial.stim = typeof trial.stim === 'undefined' ? "" : trial.stim;
	trial.condition = typeof trial.condition === 'undefined' ? "" : trial.condition;
	trial.video = typeof trial.video === 'undefined' ? "" : trial.video;

    // if any trial variables are functions
    // this evaluates the function and replaces
    // it with the output of the function
    trial = jsPsych.pluginAPI.evaluateFunctionParameters(trial);

    // show preamble text
    display_element.append($('
', {
      "id": 'jspsych-survey-likert-preamble',
      "class": 'jspsych-survey-likert-preamble'
    }));

    $('#jspsych-survey-likert-preamble').html(trial.preamble);

	display_element.append($('
', {
		"id": 'sentence_stim',
		"class": 'sentence_stim'
	}));
	$('#sentence_stim').html(trial.stim);

    display_element.append('<form id="jspsych-survey-likert-form">');
    // add likert scale questions
    for (var i = 0; i < trial.questions.length; i++) {
      form_element = $('#jspsych-survey-likert-form');
      // add question
      form_element.append('' + trial.questions[i] + '');
      // add options
      var width = 100 / trial.labels[i].length;
      options_string = '
';
      for (var j = 0; j < trial.labels[i].length; j++) {
        options_string += '
<input type="radio" name="Q' + i + '" value="' + j + '">' + trial.labels[i][j] + '
';
      }
      options_string += '
';
      form_element.append(options_string);
    }

    // add submit button
    display_element.append($('<button>', {
      'id': 'jspsych-survey-likert-next',
      'class': 'jspsych-survey-likert jspsych-btn'
    }));
    $("#jspsych-survey-likert-next").html('Submit Answers');
    $("#jspsych-survey-likert-next").click(function() {
      // measure response time
      var endTime = (new Date()).getTime();
      var response_time = endTime - startTime;

      // create object to hold responses
      var question_data = {};
      $("#jspsych-survey-likert-form .jspsych-survey-likert-opts").each(function(index) {
        var id = $(this).data('radio-group');
        var response = $('input[name="' + id + '"]:checked').val();
        if (typeof response == 'undefined') {
          response = -1;
        }
        var obje = {};
        obje[id] = response;
        $.extend(question_data, obje);
      });

      // save data
      var trial_data = {
		  "rt": response_time,
		  "video": JSON.stringify(trial.video),
		  "stim": JSON.stringify(trial.stim),
		  "condition": JSON.stringify(trial.condition),
          "responses": JSON.stringify(question_data),
      };

      display_element.html('');

      // next trial
      jsPsych.finishTrial(trial_data);
    });

    var startTime = (new Date()).getTime();
  };

  return plugin;
})();
<commit_msg>adding a comment field<commit_after>/**
 * jspsych-survey-likert
 * a jspsych plugin for measuring items on a likert scale
 *
 * Josh de Leeuw
 *
 * documentation: docs.jspsych.org
 *
 */

jsPsych.plugins['survey-likert'] = (function() {

  var plugin = {};

  plugin.trial = function(display_element, trial) {

    // default parameters for the trial
    trial.preamble = typeof trial.preamble === 'undefined' ? "" : trial.preamble;
	trial.stim = typeof trial.stim === 'undefined' ? "" : trial.stim;
	trial.condition = typeof trial.condition === 'undefined' ? "" : trial.condition;
	trial.video = typeof trial.video === 'undefined' ? "" : trial.video;
	trial.comment = typeof trial.comment === 'undefined' ? false: trial.comment;

    // if any trial variables are functions
    // this evaluates the function and replaces
    // it with the output of the function
    trial = jsPsych.pluginAPI.evaluateFunctionParameters(trial);

    // show preamble text
    display_element.append($('
', {
      "id": 'jspsych-survey-likert-preamble',
      "class": 'jspsych-survey-likert-preamble'
    }));

    $('#jspsych-survey-likert-preamble').html(trial.preamble);

	display_element.append($('
', {
		"id": 'sentence_stim',
		"class": 'sentence_stim'
	}));
	$('#sentence_stim').html(trial.stim);

    display_element.append('<form id="jspsych-survey-likert-form">');
    // add likert scale questions
    for (var i = 0; i < trial.questions.length; i++) {
      form_element = $('#jspsych-survey-likert-form');
      // add question
      form_element.append('' + trial.questions[i] + '');
      // add options
      var width = 100 / trial.labels[i].length;
      options_string = '
';
      for (var j = 0; j < trial.labels[i].length; j++) {
        options_string += '
<input type="radio" name="Q' + i + '" value="' + j + '">' + trial.labels[i][j] + '
';
      }
      options_string += '
';
      form_element.append(options_string);
    }

	//comment
	if (trial.comment == true){
		display_element.append('
 If you would like to leave a comment, you can put it in the box below:
');
		display_element.append('<textarea id="comment-text" cols="50" rows="4"></textarea>');
	}

    // add submit button
    display_element.append($('<button>', {
      'id': 'jspsych-survey-likert-next',
      'class': 'jspsych-survey-likert jspsych-btn'
    }));
    $("#jspsych-survey-likert-next").html('Submit Answers');
    $("#jspsych-survey-likert-next").click(function() {
      // measure response time
      var endTime = (new Date()).getTime();
      var response_time = endTime - startTime;

      // create object to hold responses
      var question_data = {};
	  var comment_data = {};
      $("#jspsych-survey-likert-form .jspsych-survey-likert-opts").each(function(index) {
        var id = $(this).data('radio-group');
        var response = $('input[name="' + id + '"]:checked').val();
        if (typeof response == 'undefined') {
          response = -1;
        }
        var obje = {};
        obje[id] = response;
        $.extend(question_data, obje);
		//comment object
		var comm = $('textarea').val();
		var c_obje = {};
		c_obje[id] = comm;
		$.extend(comment_data, c_obje);
      });

      // save data
      var trial_data = {
		  "rt": response_time,
		  "video": JSON.stringify(trial.video),
		  "stim": JSON.stringify(trial.stim),
		  "condition": JSON.stringify(trial.condition),
          "responses": JSON.stringify(question_data),
		  "comment": JSON.stringify(trial.correct)
      };

      display_element.html('');

      // next trial
      jsPsych.finishTrial(trial_data);
    });

    var startTime = (new Date()).getTime();
  };

  return plugin;
})();
<|endoftext|>


<commit_before>'use strict';

var testHelper = require('../../test-helper');
var setupFile = require('./repository-setup');

var repositoryPage = require('../pages/repository');
var deploymentsPage = repositoryPage.deployments;
var resourcesPage = repositoryPage.resources;
var resourcePage = repositoryPage.resource;

describe('Repository Spec', function() {

  describe('deployments sorting', function() {

    before(function() {
      return testHelper(setupFile.setup1, function() {
        repositoryPage.navigateToWebapp('Cockpit');
        repositoryPage.authentication.userLogin('admin', 'admin');
        repositoryPage.navigateTo();
      });
    });

    it('shows an active link in the header', function () {
      expect(repositoryPage.navbarItem(1).getText()).to.eventually.eql('Deployments');
      browser.sleep(2000).then(function () {
        expect(repositoryPage.navbarItem(1).getAttribute('class')).to.eventually.contain('active');
      });
    });

    it('should change sorting by', function() {
      // given
      expect(deploymentsPage.sortingBy()).to.eventually.eql('Deployment Time');

      // when
      deploymentsPage.changeSortingBy('Name');

      // then
      expect(deploymentsPage.sortingBy()).to.eventually.eql('Name');
      expect(deploymentsPage.deploymentName(0)).to.eventually.eql('third-deployment');
    });

    it('should change sorting order', function() {
      // given
      expect(deploymentsPage.isSortingDescending()).to.eventually.be.true;

      // when
      deploymentsPage.changeSortingDirection();

      // then
      expect(deploymentsPage.isSortingDescending()).to.eventually.be.false;
      expect(deploymentsPage.isSortingAscending()).to.eventually.be.true;
      expect(deploymentsPage.deploymentName(0)).to.eventually.eql('first-deployment');
    });

  });

  describe('deployments search', function() {

    before(function() {
      return testHelper(setupFile.setup1, function() {
        repositoryPage.navigateToWebapp('Cockpit');
        repositoryPage.authentication.userLogin('admin', 'admin');
        repositoryPage.navigateTo();
      });
    });

    describe('add a search pill', function() {

      it('should use wrong deployment name and find nothing', function() {

        // when
        deploymentsPage.createSearch('Name', '=', 'xyz');

        //then
        expect(deploymentsPage.deploymentList().count()).to.eventually.eql(0);
      });

      it('should change deployment name and find one deployment', function() {

        // when
        deploymentsPage.changeValue(0, 'second-deployment');

        // then
        expect(deploymentsPage.deploymentList().count()).to.eventually.eql(1);
        expect(deploymentsPage.deploymentName(0)).to.eventually.eql('second-deployment');
      });

      it('should change operator and find one deployment', function() {

        // when
        deploymentsPage.changeOperator(0, 'like');

        // then
        expect(deploymentsPage.deploymentList().count()).to.eventually.eql(1);
        expect(deploymentsPage.deploymentName(0)).to.eventually.eql('second-deployment');
      });

      it('should change value and find all deployments', function() {

        // when
        deploymentsPage.changeValue(0, '-deployment');

        // then
        expect(deploymentsPage.deploymentList().count()).to.eventually.eql(3);
      });

    });

    describe('add more search pills', function() {

      it('should add Date search and find nothing', function() {

        // when
        deploymentsPage.createSearch('Time', 'before', '2015-01-01T00:00:00', true);

        // then
        expect(deploymentsPage.deploymentList().count()).to.eventually.eql(0);
      });

      it('should change operator and find all deployments', function() {

        // when
        deploymentsPage.changeOperator(1, 'after');

        // then
        expect(deploymentsPage.deploymentList().count()).to.eventually.eql(3);
      });

      it('should keep search pills after page refresh', function() {

        // given
        deploymentsPage.changeOperator(0, '=');
        deploymentsPage.changeValue(0, 'first-deployment');

        expect(deploymentsPage.deploymentList().count()).to.eventually.eql(1);
        expect(deploymentsPage.deploymentName(0)).to.eventually.eql('first-deployment');

        // when
        browser.getCurrentUrl().then(function(url) {
          browser.get(url).then(function() {
            browser.sleep(500);
          });
        });

        // then
        expect(deploymentsPage.deploymentList().count()).to.eventually.eql(1);
        expect(deploymentsPage.deploymentName(0)).to.eventually.eql('first-deployment');
      });
    });

    describe('remove search pill', function() {

      it('should remove Name search', function() {

        // when
        deploymentsPage.deleteSearch(0);

        // then
        expect(deploymentsPage.deploymentList().count()).to.eventually.eql(3);
      });

      it('should remove Deployment Time search', function() {

        // when
        deploymentsPage.deleteSearch(0);

        // then
        expect(deploymentsPage.deploymentList().count()).to.eventually.eql(3);
      });

    });

    describe('search by deployment source', function() {

      it('should search by invalid deployment source', function() {

        // when
        deploymentsPage.createSearch('Source', '=', 'xyz');

        //then
        expect(deploymentsPage.deploymentList().count()).to.eventually.eql(0);
      });

      it('should search by process application deployment source', function() {

        // when
        deploymentsPage.changeValue(0, 'process application');

        // then
        expect(deploymentsPage.deploymentList().count()).to.eventually.eql(1);
        expect(deploymentsPage.deploymentName(0)).to.eventually.eql('first-deployment');
        expect(deploymentsPage.deploymentSource(0)).to.eventually.eql('process application');
      });

      it('should search for undefined deployment sources', function() {

        // when
        deploymentsPage.changeType(0, 'Source Undefined');

        // then
        expect(deploymentsPage.deploymentList().count()).to.eventually.eql(1);
        expect(deploymentsPage.deploymentName(0)).to.eventually.eql('second-deployment');
        expect(deploymentsPage.deploymentSource(0)).to.eventually.eql('<undefined>');
      });

    });

  });

  describe('deployment selection', function() {

    before(function() {
      return testHelper(setupFile.setup1, function() {
        repositoryPage.navigateToWebapp('Cockpit');
        repositoryPage.authentication.userLogin('admin', 'admin');
        repositoryPage.navigateTo();
      });
    });

    it('should initially select first deployment', function() {
      // then
      expect(deploymentsPage.isDeploymentSelected(0)).to.eventually.be.true;
    });

    it('should select a deployment', function() {
      // given
      expect(deploymentsPage.isDeploymentSelected(0)).to.eventually.be.true;
      expect(deploymentsPage.isDeploymentSelected(1)).to.eventually.be.false;
      expect(deploymentsPage.isDeploymentSelected(2)).to.eventually.be.false;

      // when
      deploymentsPage.selectDeployment(2);

      // then
      expect(deploymentsPage.isDeploymentSelected(0)).to.eventually.be.false;
      expect(deploymentsPage.isDeploymentSelected(1)).to.eventually.be.false;
      expect(deploymentsPage.isDeploymentSelected(2)).to.eventually.be.true;
    });

  });

  describe('delete deployment', function() {

    before(function() {
      return testHelper(setupFile.setup1, function() {
        repositoryPage.navigateToWebapp('Cockpit');
        repositoryPage.authentication.userLogin('admin', 'admin');
        repositoryPage.navigateTo();
      });
    });

    it('should open delete deployment modal', function() {
      // given
      deploymentsPage.deploymentName(2).then(function(name) {

        // when
        deploymentsPage.selectDeployment(2);
        deploymentsPage.openDeleteDeployment(2);

        // then
        expect(deploymentsPage.modalTitle()).to.eventually.eql('Delete Deployment: ' + name);

        expect(deploymentsPage.infobox().isPresent()).to.eventually.be.true;

        expect(deploymentsPage.cascadeCheckbox().isSelected()).to.eventually.be.false;
        expect(deploymentsPage.skipCustomListenersCheckbox().isSelected()).to.eventually.be.true;

        expect(deploymentsPage.deleteButton().isPresent()).to.eventually.be.true;
        expect(deploymentsPage.deleteButton().isEnabled()).to.eventually.be.false;

        expect(deploymentsPage.closeButton().isPresent()).to.eventually.be.true;
      });

    });

    it('should close delete deployment modal', function() {

      // when
      deploymentsPage.closeModal();

      // then
      expect(deploymentsPage.modalContent().isPresent()).to.eventually.be.false;
    });

    it('should enable delete button', function() {
      // given
      deploymentsPage.selectDeployment(2);
      deploymentsPage.openDeleteDeployment(2);

      expect(deploymentsPage.cascadeCheckbox().isSelected()).to.eventually.be.false;

      expect(deploymentsPage.deleteButton().isPresent()).to.eventually.be.true;
      expect(deploymentsPage.deleteButton().isEnabled()).to.eventually.be.false;

      // when
      deploymentsPage.cascadeCheckbox().click();

      // then
      expect(deploymentsPage.cascadeCheckbox().isSelected()).to.eventually.be.true;
      expect(deploymentsPage.deleteButton().isEnabled()).to.eventually.be.true;
    });

    it('should delete deployment', function() {

      // when
      deploymentsPage.deleteDeployment();

      // then
      expect(deploymentsPage.deploymentList().count()).to.eventually.eql(2);
    });

    it('should initially select first deployment', function() {
      // then
      expect(deploymentsPage.isDeploymentSelected(0)).to.eventually.be.true;
    });

  });

  describe('resource details view', function () {

    before(function() {
      return testHelper(setupFile.setup1, function() {
        repositoryPage.navigateToWebapp('Cockpit');
        repositoryPage.authentication.userLogin('admin', 'admin');
        repositoryPage.navigateTo();
      });
    });

    it('should display info text when no resource is selected', function() {

      // then
      expect(resourcePage.noResourceInfoText()).to.eventually.eql('Select a resource in the list.');
    });

    it('should appear when a resource is selected', function() {

      // when
      resourcesPage.resourceName(0).then(function(name) {

        resourcesPage.selectResource(0);

        // then
        expect(resourcePage.resourceName()).to.eventually.eql(name);

      });

    });
  });

  describe('diagram', function() {

    before(function() {
      return testHelper(setupFile.setup2, function() {
        repositoryPage.navigateToWebapp('Cockpit');
        repositoryPage.authentication.userLogin('admin', 'admin');
        repositoryPage.navigateTo();
      });
    });

    it('should display bpmn diagram', function() {
      // given
      expect(resourcePage.bpmnDiagramFormElement().isPresent()).to.eventually.be.false;

      // when
      deploymentsPage.selectDeployment('bpmn');
      resourcesPage.selectResource(0);

      // then
      expect(resourcePage.bpmnDiagramFormElement().isPresent()).to.eventually.be.true;

    });

    it('should display cmmn diagram', function() {
      // given
      expect(resourcePage.cmmnDiagramFormElement().isPresent()).to.eventually.be.false;

      // when
      deploymentsPage.selectDeployment('cmmn');
      resourcesPage.selectResource(0);

      // then
      expect(resourcePage.cmmnDiagramFormElement().isPresent()).to.eventually.be.true;

    });

    it('should display dmn diagram', function() {
      // given
      expect(resourcePage.dmnDiagramFormElement().isPresent()).to.eventually.be.false;

      // when
      deploymentsPage.selectDeployment('dmn');
      resourcesPage.selectResource(0);

      // then
      expect(resourcePage.dmnDiagramFormElement().isPresent()).to.eventually.be.true;

    });

    it('should display image', function() {
      // given
      expect(resourcePage.imageFormElement().isPresent()).to.eventually.be.false;

      // when
      deploymentsPage.selectDeployment('image');
      resourcesPage.selectResource(0);

      // then
      expect(resourcePage.imageFormElement().isPresent()).to.eventually.be.true;

    });

    it('should display script', function() {
      // given
      expect(resourcePage.unkownResourceFormElement().isPresent()).to.eventually.be.false;

      // when
      deploymentsPage.selectDeployment('script');
      resourcesPage.selectResource(0);

      // then
      expect(resourcePage.unkownResourceFormElement().isPresent()).to.eventually.be.true;

    });

  });

  describe('download button', function() {

    before(function() {
      return testHelper(setupFile.setup1, function() {
        repositoryPage.navigateToWebapp('Cockpit');
        repositoryPage.authentication.userLogin('admin', 'admin');
        repositoryPage.navigateTo();
      });
    });

    it('should not display download button', function() {

      // then
      expect(resourcePage.downloadButton().isPresent()).to.eventually.be.false;
    });

    it('should display download button', function() {
      // whe
      resourcesPage.selectResource(0);

      // then
      expect(resourcePage.downloadButton().isPresent()).to.eventually.be.true;
    });

  });

  describe('definitions tab', function() {

    before(function() {
      return testHelper(setupFile.setup2, function() {
        repositoryPage.navigateToWebapp('Cockpit');
        repositoryPage.authentication.userLogin('admin', 'admin');
        repositoryPage.navigateTo();
      });
    });

    it('should display deployed process definitions', function() {

      // when
      deploymentsPage.selectDeployment('bpmn');
      resourcesPage.selectResource(0);

      // then
      expect(resourcePage.definitions.isTabSelected()).to.eventually.be.true;
      expect(resourcePage.definitions.table().count()).to.eventually.eql(1);

      expect(resourcePage.definitions.name(0).getText()).to.eventually.eql('User Tasks');
      expect(resourcePage.definitions.key(0).getText()).to.eventually.eql('user-tasks');
      expect(resourcePage.definitions.instanceCount(0).getText()).to.eventually.eql('2');
    });

    it('should be empty', function() {

      // when
      deploymentsPage.selectDeployment('script');
      resourcesPage.selectResource(0);

      // then
      expect(resourcePage.definitions.isTabSelected()).to.eventually.be.true;
      expect(resourcePage.definitions.table().count()).to.eventually.eql(0);
    });

    it('should display deployed case definitions', function() {

      // when
      deploymentsPage.selectDeployment('cmmn');
      resourcesPage.selectResource(0);

      // then
      expect(resourcePage.definitions.isTabSelected()).to.eventually.be.true;
      expect(resourcePage.definitions.table().count()).to.eventually.eql(1);

      expect(resourcePage.definitions.name(0).getText()).to.eventually.eql('Loan Application');
      expect(resourcePage.definitions.key(0).getText()).to.eventually.eql('loanApplicationCase');
      expect(resourcePage.definitions.instanceCount(0).getText()).to.eventually.eql('3');
    });

    it('should display deployed decision definitions', function() {

      // when
      deploymentsPage.selectDeployment('dmn');
      resourcesPage.selectResource(0);

      // then
      expect(resourcePage.definitions.isTabSelected()).to.eventually.be.true;
      expect(resourcePage.definitions.table().count()).to.eventually.eql(1);

      expect(resourcePage.definitions.name(0).getText()).to.eventually.eql('Assign Approver');
      expect(resourcePage.definitions.key(0).getText()).to.eventually.eql('invoice-assign-approver');
    });

  });

});
<commit_msg>test(repository): test preservation of sorting<commit_after>'use strict';

var testHelper = require('../../test-helper');
var setupFile = require('./repository-setup');

var repositoryPage = require('../pages/repository');
var deploymentsPage = repositoryPage.deployments;
var resourcesPage = repositoryPage.resources;
var resourcePage = repositoryPage.resource;

describe('Repository Spec', function() {

  describe('deployments sorting', function() {

    before(function() {
      return testHelper(setupFile.setup1, function() {
        repositoryPage.navigateToWebapp('Cockpit');
        repositoryPage.authentication.userLogin('admin', 'admin');
        repositoryPage.navigateTo();
      });
    });

    it('shows an active link in the header', function () {
      expect(repositoryPage.navbarItem(1).getText()).to.eventually.eql('Deployments');
      browser.sleep(2000).then(function () {
        expect(repositoryPage.navbarItem(1).getAttribute('class')).to.eventually.contain('active');
      });
    });

    it('should change sorting by', function() {
      // given
      expect(deploymentsPage.sortingBy()).to.eventually.eql('Deployment Time');

      // when
      deploymentsPage.changeSortingBy('Name');

      // then
      expect(deploymentsPage.sortingBy()).to.eventually.eql('Name');
      expect(deploymentsPage.deploymentName(0)).to.eventually.eql('third-deployment');
    });

    it('should change sorting order', function() {
      // given
      expect(deploymentsPage.isSortingDescending()).to.eventually.be.true;

      // when
      deploymentsPage.changeSortingDirection();

      // then
      expect(deploymentsPage.isSortingDescending()).to.eventually.be.false;
      expect(deploymentsPage.isSortingAscending()).to.eventually.be.true;
      expect(deploymentsPage.deploymentName(0)).to.eventually.eql('first-deployment');
    });

    it('should change sorting order on URL change', function() {
      browser.getLocationAbsUrl().then(function(url) {

        expect(url).to.contain('deploymentsSortBy=name');

        var location = url.substr(url.indexOf('#') + 2);

        location = location.replace('deploymentsSortBy=name', 'deploymentsSortBy=id');

        browser.setLocation(location).then(function() {
          expect(deploymentsPage.sortingBy()).to.eventually.eql('Id');
        });

      });
    });

    it('should preserve sorting order on unrelated URL change', function() {
      browser.setLocation('repository').then(function() {
        expect(deploymentsPage.sortingBy()).to.eventually.eql('Id');
      });
    });

  });

  describe('deployments search', function() {

    before(function() {
      return testHelper(setupFile.setup1, function() {
        repositoryPage.navigateToWebapp('Cockpit');
        repositoryPage.authentication.userLogin('admin', 'admin');
        repositoryPage.navigateTo();
      });
    });

    describe('add a search pill', function() {

      it('should use wrong deployment name and find nothing', function() {

        // when
        deploymentsPage.createSearch('Name', '=', 'xyz');

        //then
        expect(deploymentsPage.deploymentList().count()).to.eventually.eql(0);
      });

      it('should change deployment name and find one deployment', function() {

        // when
        deploymentsPage.changeValue(0, 'second-deployment');

        // then
        expect(deploymentsPage.deploymentList().count()).to.eventually.eql(1);
        expect(deploymentsPage.deploymentName(0)).to.eventually.eql('second-deployment');
      });

      it('should change operator and find one deployment', function() {

        // when
        deploymentsPage.changeOperator(0, 'like');

        // then
        expect(deploymentsPage.deploymentList().count()).to.eventually.eql(1);
        expect(deploymentsPage.deploymentName(0)).to.eventually.eql('second-deployment');
      });

      it('should change value and find all deployments', function() {

        // when
        deploymentsPage.changeValue(0, '-deployment');

        // then
        expect(deploymentsPage.deploymentList().count()).to.eventually.eql(3);
      });

    });

    describe('add more search pills', function() {

      it('should add Date search and find nothing', function() {

        // when
        deploymentsPage.createSearch('Time', 'before', '2015-01-01T00:00:00', true);

        // then
        expect(deploymentsPage.deploymentList().count()).to.eventually.eql(0);
      });

      it('should change operator and find all deployments', function() {

        // when
        deploymentsPage.changeOperator(1, 'after');

        // then
        expect(deploymentsPage.deploymentList().count()).to.eventually.eql(3);
      });

      it('should keep search pills after page refresh', function() {

        // given
        deploymentsPage.changeOperator(0, '=');
        deploymentsPage.changeValue(0, 'first-deployment');

        expect(deploymentsPage.deploymentList().count()).to.eventually.eql(1);
        expect(deploymentsPage.deploymentName(0)).to.eventually.eql('first-deployment');

        // when
        browser.getCurrentUrl().then(function(url) {
          browser.get(url).then(function() {
            browser.sleep(500);
          });
        });

        // then
        expect(deploymentsPage.deploymentList().count()).to.eventually.eql(1);
        expect(deploymentsPage.deploymentName(0)).to.eventually.eql('first-deployment');
      });
    });

    describe('remove search pill', function() {

      it('should remove Name search', function() {

        // when
        deploymentsPage.deleteSearch(0);

        // then
        expect(deploymentsPage.deploymentList().count()).to.eventually.eql(3);
      });

      it('should remove Deployment Time search', function() {

        // when
        deploymentsPage.deleteSearch(0);

        // then
        expect(deploymentsPage.deploymentList().count()).to.eventually.eql(3);
      });

    });

    describe('search by deployment source', function() {

      it('should search by invalid deployment source', function() {

        // when
        deploymentsPage.createSearch('Source', '=', 'xyz');

        //then
        expect(deploymentsPage.deploymentList().count()).to.eventually.eql(0);
      });

      it('should search by process application deployment source', function() {

        // when
        deploymentsPage.changeValue(0, 'process application');

        // then
        expect(deploymentsPage.deploymentList().count()).to.eventually.eql(1);
        expect(deploymentsPage.deploymentName(0)).to.eventually.eql('first-deployment');
        expect(deploymentsPage.deploymentSource(0)).to.eventually.eql('process application');
      });

      it('should search for undefined deployment sources', function() {

        // when
        deploymentsPage.changeType(0, 'Source Undefined');

        // then
        expect(deploymentsPage.deploymentList().count()).to.eventually.eql(1);
        expect(deploymentsPage.deploymentName(0)).to.eventually.eql('second-deployment');
        expect(deploymentsPage.deploymentSource(0)).to.eventually.eql('<undefined>');
      });

    });

  });

  describe('deployment selection', function() {

    before(function() {
      return testHelper(setupFile.setup1, function() {
        repositoryPage.navigateToWebapp('Cockpit');
        repositoryPage.authentication.userLogin('admin', 'admin');
        repositoryPage.navigateTo();
      });
    });

    it('should initially select first deployment', function() {
      // then
      expect(deploymentsPage.isDeploymentSelected(0)).to.eventually.be.true;
    });

    it('should select a deployment', function() {
      // given
      expect(deploymentsPage.isDeploymentSelected(0)).to.eventually.be.true;
      expect(deploymentsPage.isDeploymentSelected(1)).to.eventually.be.false;
      expect(deploymentsPage.isDeploymentSelected(2)).to.eventually.be.false;

      // when
      deploymentsPage.selectDeployment(2);

      // then
      expect(deploymentsPage.isDeploymentSelected(0)).to.eventually.be.false;
      expect(deploymentsPage.isDeploymentSelected(1)).to.eventually.be.false;
      expect(deploymentsPage.isDeploymentSelected(2)).to.eventually.be.true;
    });

  });

  describe('delete deployment', function() {

    before(function() {
      return testHelper(setupFile.setup1, function() {
        repositoryPage.navigateToWebapp('Cockpit');
        repositoryPage.authentication.userLogin('admin', 'admin');
        repositoryPage.navigateTo();
      });
    });

    it('should open delete deployment modal', function() {
      // given
      deploymentsPage.deploymentName(2).then(function(name) {

        // when
        deploymentsPage.selectDeployment(2);
        deploymentsPage.openDeleteDeployment(2);

        // then
        expect(deploymentsPage.modalTitle()).to.eventually.eql('Delete Deployment: ' + name);

        expect(deploymentsPage.infobox().isPresent()).to.eventually.be.true;

        expect(deploymentsPage.cascadeCheckbox().isSelected()).to.eventually.be.false;
        expect(deploymentsPage.skipCustomListenersCheckbox().isSelected()).to.eventually.be.true;

        expect(deploymentsPage.deleteButton().isPresent()).to.eventually.be.true;
        expect(deploymentsPage.deleteButton().isEnabled()).to.eventually.be.false;

        expect(deploymentsPage.closeButton().isPresent()).to.eventually.be.true;
      });

    });

    it('should close delete deployment modal', function() {

      // when
      deploymentsPage.closeModal();

      // then
      expect(deploymentsPage.modalContent().isPresent()).to.eventually.be.false;
    });

    it('should enable delete button', function() {
      // given
      deploymentsPage.selectDeployment(2);
      deploymentsPage.openDeleteDeployment(2);

      expect(deploymentsPage.cascadeCheckbox().isSelected()).to.eventually.be.false;

      expect(deploymentsPage.deleteButton().isPresent()).to.eventually.be.true;
      expect(deploymentsPage.deleteButton().isEnabled()).to.eventually.be.false;

      // when
      deploymentsPage.cascadeCheckbox().click();

      // then
      expect(deploymentsPage.cascadeCheckbox().isSelected()).to.eventually.be.true;
      expect(deploymentsPage.deleteButton().isEnabled()).to.eventually.be.true;
    });

    it('should delete deployment', function() {

      // when
      deploymentsPage.deleteDeployment();

      // then
      expect(deploymentsPage.deploymentList().count()).to.eventually.eql(2);
    });

    it('should initially select first deployment', function() {
      // then
      expect(deploymentsPage.isDeploymentSelected(0)).to.eventually.be.true;
    });

  });

  describe('resource details view', function () {

    before(function() {
      return testHelper(setupFile.setup1, function() {
        repositoryPage.navigateToWebapp('Cockpit');
        repositoryPage.authentication.userLogin('admin', 'admin');
        repositoryPage.navigateTo();
      });
    });

    it('should display info text when no resource is selected', function() {

      // then
      expect(resourcePage.noResourceInfoText()).to.eventually.eql('Select a resource in the list.');
    });

    it('should appear when a resource is selected', function() {

      // when
      resourcesPage.resourceName(0).then(function(name) {

        resourcesPage.selectResource(0);

        // then
        expect(resourcePage.resourceName()).to.eventually.eql(name);

      });

    });
  });

  describe('diagram', function() {

    before(function() {
      return testHelper(setupFile.setup2, function() {
        repositoryPage.navigateToWebapp('Cockpit');
        repositoryPage.authentication.userLogin('admin', 'admin');
        repositoryPage.navigateTo();
      });
    });

    it('should display bpmn diagram', function() {
      // given
      expect(resourcePage.bpmnDiagramFormElement().isPresent()).to.eventually.be.false;

      // when
      deploymentsPage.selectDeployment('bpmn');
      resourcesPage.selectResource(0);

      // then
      expect(resourcePage.bpmnDiagramFormElement().isPresent()).to.eventually.be.true;

    });

    it('should display cmmn diagram', function() {
      // given
      expect(resourcePage.cmmnDiagramFormElement().isPresent()).to.eventually.be.false;

      // when
      deploymentsPage.selectDeployment('cmmn');
      resourcesPage.selectResource(0);

      // then
      expect(resourcePage.cmmnDiagramFormElement().isPresent()).to.eventually.be.true;

    });

    it('should display dmn diagram', function() {
      // given
      expect(resourcePage.dmnDiagramFormElement().isPresent()).to.eventually.be.false;

      // when
      deploymentsPage.selectDeployment('dmn');
      resourcesPage.selectResource(0);

      // then
      expect(resourcePage.dmnDiagramFormElement().isPresent()).to.eventually.be.true;

    });

    it('should display image', function() {
      // given
      expect(resourcePage.imageFormElement().isPresent()).to.eventually.be.false;

      // when
      deploymentsPage.selectDeployment('image');
      resourcesPage.selectResource(0);

      // then
      expect(resourcePage.imageFormElement().isPresent()).to.eventually.be.true;

    });

    it('should display script', function() {
      // given
      expect(resourcePage.unkownResourceFormElement().isPresent()).to.eventually.be.false;

      // when
      deploymentsPage.selectDeployment('script');
      resourcesPage.selectResource(0);

      // then
      expect(resourcePage.unkownResourceFormElement().isPresent()).to.eventually.be.true;

    });

  });

  describe('download button', function() {

    before(function() {
      return testHelper(setupFile.setup1, function() {
        repositoryPage.navigateToWebapp('Cockpit');
        repositoryPage.authentication.userLogin('admin', 'admin');
        repositoryPage.navigateTo();
      });
    });

    it('should not display download button', function() {

      // then
      expect(resourcePage.downloadButton().isPresent()).to.eventually.be.false;
    });

    it('should display download button', function() {
      // whe
      resourcesPage.selectResource(0);

      // then
      expect(resourcePage.downloadButton().isPresent()).to.eventually.be.true;
    });

  });

  describe('definitions tab', function() {

    before(function() {
      return testHelper(setupFile.setup2, function() {
        repositoryPage.navigateToWebapp('Cockpit');
        repositoryPage.authentication.userLogin('admin', 'admin');
        repositoryPage.navigateTo();
      });
    });

    it('should display deployed process definitions', function() {

      // when
      deploymentsPage.selectDeployment('bpmn');
      resourcesPage.selectResource(0);

      // then
      expect(resourcePage.definitions.isTabSelected()).to.eventually.be.true;
      expect(resourcePage.definitions.table().count()).to.eventually.eql(1);

      expect(resourcePage.definitions.name(0).getText()).to.eventually.eql('User Tasks');
      expect(resourcePage.definitions.key(0).getText()).to.eventually.eql('user-tasks');
      expect(resourcePage.definitions.instanceCount(0).getText()).to.eventually.eql('2');
    });

    it('should be empty', function() {

      // when
      deploymentsPage.selectDeployment('script');
      resourcesPage.selectResource(0);

      // then
      expect(resourcePage.definitions.isTabSelected()).to.eventually.be.true;
      expect(resourcePage.definitions.table().count()).to.eventually.eql(0);
    });

    it('should display deployed case definitions', function() {

      // when
      deploymentsPage.selectDeployment('cmmn');
      resourcesPage.selectResource(0);

      // then
      expect(resourcePage.definitions.isTabSelected()).to.eventually.be.true;
      expect(resourcePage.definitions.table().count()).to.eventually.eql(1);

      expect(resourcePage.definitions.name(0).getText()).to.eventually.eql('Loan Application');
      expect(resourcePage.definitions.key(0).getText()).to.eventually.eql('loanApplicationCase');
      expect(resourcePage.definitions.instanceCount(0).getText()).to.eventually.eql('3');
    });

    it('should display deployed decision definitions', function() {

      // when
      deploymentsPage.selectDeployment('dmn');
      resourcesPage.selectResource(0);

      // then
      expect(resourcePage.definitions.isTabSelected()).to.eventually.be.true;
      expect(resourcePage.definitions.table().count()).to.eventually.eql(1);

      expect(resourcePage.definitions.name(0).getText()).to.eventually.eql('Assign Approver');
      expect(resourcePage.definitions.key(0).getText()).to.eventually.eql('invoice-assign-approver');
    });

  });

});
<|endoftext|>