<commit_before>function getTime(day, monthIndex) {
    return moment.utc().subtract(monthIndex, "month").date(day).format("YYYY-MM-DD");
}

function getMeasurementsTypes(sensorId) {
    if (sensorId.indexOf("IT-") >= 0) {
        return ["weather-humidity", "weather-cloudeness", "weather-temperature", "weather-id"];
    } else if (sensorId.indexOf("ZTHL") >= 0) {
        return ["temperature", "humidity", "illuminance"];
    } else if (sensorId.indexOf("COOV") >= 0) {
        return ["co2"];
    } else {
        return ["activeEnergy", "reactiveEnergy", "maxPower"];
    }
}

function getUnitOfMeasurement(measurementType) {
    switch (measurementType) {
        case "activeEnergy":
            return "kWh";
        case "reactiveEnergy":
            return "kVArh";
        case "maxPower":
            return "VAr";
        case "temperature":
            return "°C";
        case "humidity":
            return "%";
        case "illuminance":
            return "Lux";
        case "co2":
            return "ppm";
        case "weather-humidity":
            return "%";
        case "weather-cloudeness":
            return "%";
        case "weather-temperature":
            return "°C";
        case "weather-id":
            return "id";
    }
}

function getRandomArbitrary(min, max, source) {
    var value = Math.random() * (max - min) + min;
    if (source === "forecast") {
        value += 5;
    }
    return value.toFixed(2);
}

function createMeasurementValues(measurements, measurementType, source) {
    // weather-id is an id, so it should be fixed to existent integer values.
    if (measurementType.indexOf("weather-id") >= 0) {
        return measurements[measurementType];
    }
    var filteredMeasurements = measurements[measurementType].split(",").filter(x => !isNaN(parseFloat(x)));
    var values = filteredMeasurements.map(x => {
        const measurementsValue = parseFloat(x);
        const max = (measurementsValue + (measurementsValue * 2 / 100));
        const min = (measurementsValue - (measurementsValue * 2 / 100));
        return getRandomArbitrary(max, min, source);
    }).sort();
    return values.join(",");
}

function createMeasurementTimes(measurements, measurementType, date) {
    var dayStart = moment.utc(date).valueOf();
    var dayEnd = moment.utc(date).endOf('day').valueOf();
    if (measurementType.indexOf("weather") >= 0) {
        var timesWeather = [];
        for (var i = 1; i <= 12; i++) {
            timesWeather.push(moment(dayStart).add({ hours: i * 2 }).valueOf());
        }
        return timesWeather.join(",");
    }
    var filteredMeasurements = measurements[measurementType].split(",").filter(x => !isNaN(parseFloat(x)));
    var times = filteredMeasurements.map(x => {
        return Math.floor((Math.random() * (dayEnd - dayStart)) + dayStart);
    }).sort();
    return times.join(",");
}

function insertDataFromJSON(path, sensorsIds, source) {
    const numberOfMonth = 2
    const data = JSON.parse(Assets.getText(path));
    sensorsIds.map(sensorId => {
        for (var monthIdx = 0; monthIdx < numberOfMonth; monthIdx++) {
            for (var dayOfMonth = 1; dayOfMonth <= moment().subtract(monthIdx, "month").daysInMonth(); dayOfMonth++) {
                const date = getTime(dayOfMonth, monthIdx);
                const measurementsTypes = getMeasurementsTypes(sensorId);
                measurementsTypes.forEach(measurementType => {
                    var obj = {
                        _id: `${sensorId}-${date}-${source}-${measurementType}`,
                        sensorId,
                        day: date,
                        source,
                        measurementType,
                        measurementValues: createMeasurementValues(data.measurements, measurementType, source),
                        measurementTimes: createMeasurementTimes(data.measurements, measurementType, date),
                        unitOfMeasurement: getUnitOfMeasurement(measurementType)
                    }
                    if (obj.measurementValues.split(",").length !== obj.measurementTimes.split(",").length) {
                        console.log(`values=${obj.measurementValues.split(",").length} timestamps=${obj.measurementTimes.split(",").length}`);
                        throw Error("Values and timestamps number do not match");
                    }
                    ReadingsDailyAggregates.insert(obj);
                });
            }
        };
    });
}

/*
*   Expected structure of the db:
*   {
*       _id: "sensorId-day-source-measurementType",
*       day = "YYYY-MM-DD",
*       sensorId = "sensorId",
*       source: "",
*       measurementType = "",
*       measurementValues: "",
*       measurementTimes: "",
*       unitOfMeasurement: ""
*   }
*/

function getAlarms(sensorId) {
    const alarms = [];
    for (i = 0; i < 28; i++) {
        const date = parseInt(moment().startOf("month").subtract(1, "month").add({ day: i, hour: 12 }).valueOf())
        const alarm = {
            _id: `${sensorId}-${date}`,
            date
        };
        alarms.push(alarm)
    }
    return alarms;
}
Meteor.startup(() => {
    if (
        process.env.ENVIRONMENT !== "production" &&
        ReadingsDailyAggregates.find().count() === 0
    ) {
        const path = "fixtures/readings-daily-aggregates";
        const listOfSensorIdInSiteTest1 = ["SitoDiTest1", "IT001", "ANZ01", "IT002", "ANZ02", "ZTHL01", "ZTHL02",
            "ZTHL03", "ZTHL04", "COOV01", "COOV02"];
        const listOfSensorIdInSiteTest2 = ["SitoDiTest2", "IT003", "ANZ03", "IT004", "ANZ04", "ANZ05", "ANZ06",
            "ZTHL05", "ZTHL06", "ZTHL07", "ZTHL08", "ZTHL09", "ZTHL10", "ZTHL11",
            "COOV03", "COOV04", "COOV05"];
        const listOfWeatherSensor = ["IT-CO", "IT-SO", "IT-MI", "IT-BG"];
        const allowedSource = ["reading", "forecast"];

        // FIXTURES FOR CHARTS
        allowedSource.map(source => {
            insertDataFromJSON(`${path}/test-sites-value.json`, listOfSensorIdInSiteTest1, source);
            insertDataFromJSON(`${path}/test-sites-value.json`, listOfSensorIdInSiteTest2, source);
            insertDataFromJSON(`${path}/test-sites-value.json`, listOfWeatherSensor, source);
        });

        // FINTECO DATA FIXTURES
        const fintecoSensors = [
            "SitoDiTest1-daily-avg",
            "SitoDiTest1-peers-avg",
            "SitoDiTest2-daily-avg",
            "SitoDiTest2-peers-avg"
        ];
        insertDataFromJSON(`${path}/test-sites-value.json`, fintecoSensors, ["reading"]);

        // FIXTURES FOR ALARMS
        ["SitoDiTest1", "SitoDiTest2", "IT001", "ANZ01", "IT002", "ANZ02", "IT003", "ANZ03", "IT004", "ANZ04", "ANZ05", "ANZ06"].map(sensorId => {
            Alarms.insert({
                podId: sensorId,
                name: sensorId,
                type: "automatic",
                active: true,
                notifications: getAlarms(sensorId)
            })
        });

    }
});
<commit_msg>Fix fixtures's weather sensorIds<commit_after>function getTime(day, monthIndex) {
    return moment.utc().subtract(monthIndex, "month").date(day).format("YYYY-MM-DD");
}

function getMeasurementsTypes(sensorId) {
    if (sensorId.indexOf("IT-") >= 0) {
        return ["weather-humidity", "weather-cloudeness", "weather-temperature", "weather-id"];
    } else if (sensorId.indexOf("ZTHL") >= 0) {
        return ["temperature", "humidity", "illuminance"];
    } else if (sensorId.indexOf("COOV") >= 0) {
        return ["co2"];
    } else {
        return ["activeEnergy", "reactiveEnergy", "maxPower"];
    }
}

function getUnitOfMeasurement(measurementType) {
    switch (measurementType) {
        case "activeEnergy":
            return "kWh";
        case "reactiveEnergy":
            return "kVArh";
        case "maxPower":
            return "VAr";
        case "temperature":
            return "°C";
        case "humidity":
            return "%";
        case "illuminance":
            return "Lux";
        case "co2":
            return "ppm";
        case "weather-humidity":
            return "%";
        case "weather-cloudeness":
            return "%";
        case "weather-temperature":
            return "°C";
        case "weather-id":
            return "id";
    }
}

function getRandomArbitrary(min, max, source) {
    var value = Math.random() * (max - min) + min;
    if (source === "forecast") {
        value += 5;
    }
    return value.toFixed(2);
}

function createMeasurementValues(measurements, measurementType, source) {
    // weather-id is an id, so it should be fixed to existent integer values.
    if (measurementType.indexOf("weather-id") >= 0) {
        return measurements[measurementType];
    }
    var filteredMeasurements = measurements[measurementType].split(",").filter(x => !isNaN(parseFloat(x)));
    var values = filteredMeasurements.map(x => {
        const measurementsValue = parseFloat(x);
        const max = (measurementsValue + (measurementsValue * 2 / 100));
        const min = (measurementsValue - (measurementsValue * 2 / 100));
        return getRandomArbitrary(max, min, source);
    }).sort();
    return values.join(",");
}

function createMeasurementTimes(measurements, measurementType, date) {
    var dayStart = moment.utc(date).valueOf();
    var dayEnd = moment.utc(date).endOf('day').valueOf();
    if (measurementType.indexOf("weather") >= 0) {
        var timesWeather = [];
        for (var i = 1; i <= 12; i++) {
            timesWeather.push(moment(dayStart).add({ hours: i * 2 }).valueOf());
        }
        return timesWeather.join(",");
    }
    var filteredMeasurements = measurements[measurementType].split(",").filter(x => !isNaN(parseFloat(x)));
    var times = filteredMeasurements.map(x => {
        return Math.floor((Math.random() * (dayEnd - dayStart)) + dayStart);
    }).sort();
    return times.join(",");
}

function insertDataFromJSON(path, sensorsIds, source) {
    const numberOfMonth = 2
    const data = JSON.parse(Assets.getText(path));
    sensorsIds.map(sensorId => {
        for (var monthIdx = 0; monthIdx < numberOfMonth; monthIdx++) {
            for (var dayOfMonth = 1; dayOfMonth <= moment().subtract(monthIdx, "month").daysInMonth(); dayOfMonth++) {
                const date = getTime(dayOfMonth, monthIdx);
                const measurementsTypes = getMeasurementsTypes(sensorId);
                measurementsTypes.forEach(measurementType => {
                    var obj = {
                        _id: `${sensorId}-${date}-${source}-${measurementType}`,
                        sensorId,
                        day: date,
                        source,
                        measurementType,
                        measurementValues: createMeasurementValues(data.measurements, measurementType, source),
                        measurementTimes: createMeasurementTimes(data.measurements, measurementType, date),
                        unitOfMeasurement: getUnitOfMeasurement(measurementType)
                    }
                    if (obj.measurementValues.split(",").length !== obj.measurementTimes.split(",").length) {
                        console.log(`values=${obj.measurementValues.split(",").length} timestamps=${obj.measurementTimes.split(",").length}`);
                        throw Error("Values and timestamps number do not match");
                    }
                    ReadingsDailyAggregates.insert(obj);
                });
            }
        };
    });
}

/*
*   Expected structure of the db:
*   {
*       _id: "sensorId-day-source-measurementType",
*       day = "YYYY-MM-DD",
*       sensorId = "sensorId",
*       source: "",
*       measurementType = "",
*       measurementValues: "",
*       measurementTimes: "",
*       unitOfMeasurement: ""
*   }
*/

function getAlarms(sensorId) {
    const alarms = [];
    for (i = 0; i < 28; i++) {
        const date = parseInt(moment().startOf("month").subtract(1, "month").add({ day: i, hour: 12 }).valueOf())
        const alarm = {
            _id: `${sensorId}-${date}`,
            date
        };
        alarms.push(alarm)
    }
    return alarms;
}
Meteor.startup(() => {
    if (
        process.env.ENVIRONMENT !== "production" &&
        ReadingsDailyAggregates.find().count() === 0
    ) {
        const path = "fixtures/readings-daily-aggregates";
        const listOfSensorIdInSiteTest1 = ["SitoDiTest1", "IT001", "ANZ01", "IT002", "ANZ02", "ZTHL01", "ZTHL02",
            "ZTHL03", "ZTHL04", "COOV01", "COOV02"];
        const listOfSensorIdInSiteTest2 = ["SitoDiTest2", "IT003", "ANZ03", "IT004", "ANZ04", "ANZ05", "ANZ06",
            "ZTHL05", "ZTHL06", "ZTHL07", "ZTHL08", "ZTHL09", "ZTHL10", "ZTHL11",
            "COOV03", "COOV04", "COOV05"];
        const listOfWeatherSensor = ["IT-como", "IT-sondrio", "IT-milano", "IT-bergamo"];
        const allowedSource = ["reading", "forecast"];

        // FIXTURES FOR CHARTS
        allowedSource.map(source => {
            insertDataFromJSON(`${path}/test-sites-value.json`, listOfSensorIdInSiteTest1, source);
            insertDataFromJSON(`${path}/test-sites-value.json`, listOfSensorIdInSiteTest2, source);
            insertDataFromJSON(`${path}/test-sites-value.json`, listOfWeatherSensor, source);
        });

        // FINTECO DATA FIXTURES
        const fintecoSensors = [
            "SitoDiTest1-daily-avg",
            "SitoDiTest1-peers-avg",
            "SitoDiTest2-daily-avg",
            "SitoDiTest2-peers-avg"
        ];
        insertDataFromJSON(`${path}/test-sites-value.json`, fintecoSensors, ["reading"]);

        // FIXTURES FOR ALARMS
        ["SitoDiTest1", "SitoDiTest2", "IT001", "ANZ01", "IT002", "ANZ02", "IT003", "ANZ03", "IT004", "ANZ04", "ANZ05", "ANZ06"].map(sensorId => {
            Alarms.insert({
                podId: sensorId,
                name: sensorId,
                type: "automatic",
                active: true,
                notifications: getAlarms(sensorId)
            })
        });

    }
});
<|endoftext|>


<commit_before>"use strict";
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import createReactClass from 'create-react-class';
import { FormMixin, Input } from '../../libs/bootstrap/form';
import { external_url_map } from '../globals';

import { DiseaseModal } from './modal';
import ModalComponent from '../../libs/bootstrap/modal';

var curator = require('../curator');
var CuratorHistory = require('../curator_history');
var RestMixin = require('../rest').RestMixin;
var parseAndLogError = require('../mixins').parseAndLogError;

/**
 * Component for adding/deleting disease associated with an interpretation in VCI
 */
const InterpretationDisease = module.exports.InterpretationDisease = createReactClass({
    mixins: [RestMixin, FormMixin, CuratorHistory],

    propTypes: {
        interpretation: PropTypes.object,
        variantData: PropTypes.object,
        hasAssociatedDisease: PropTypes.bool,
        editKey: PropTypes.string,
        updateInterpretationObj: PropTypes.func,
        calculatedAssertion: PropTypes.string,
        provisionalPathogenicity: PropTypes.string,
        diseaseObj: PropTypes.object,
        updateDiseaseObj: PropTypes.func,
        session: PropTypes.object
    },

    getInitialState() {
        return {
            interpretation: this.props.interpretation,
            diseaseObj: this.props.diseaseObj,
            diseaseId: '',
            diseaseTerm: null,
            diseaseDescription: null,
            synonyms: [],
            phenotypes: [],
            diseaseFreeTextConfirm: false,
            submitResourceBusy: false
        };
    },

    componentDidMount() {
        let interpretation = this.props.interpretation;
        if (interpretation && interpretation.disease) {
            this.setDiseaseObjectStates(interpretation.disease);
        }
    },

    componentWillReceiveProps(nextProps)  {
        if (nextProps.interpretation) {
            this.setState({interpretation: nextProps.interpretation});
        }
        if (nextProps.diseaseObj) {
            this.setState({diseaseObj: nextProps.diseaseObj}, () => {
                let diseaseObj = this.state.diseaseObj;
                if (Object.keys(diseaseObj).length) {
                    this.setDiseaseObjectStates(diseaseObj);
                }
            });
        }
    },

    /**
     * Shared method called by componentDidMount(), componentWillReceiveProps(nextProps)
     * @param {*} disease
     */
    setDiseaseObjectStates(disease) {
        if (disease.diseaseId) { this.setState({diseaseId: disease.diseaseId}); }
        if (disease.term) { this.setState({diseaseTerm: disease.term}); }
        if (disease.description) { this.setState({diseaseDescription: disease.description}); }
        if (disease.synonyms) { this.setState({synonyms: disease.synonyms}); }
        if (disease.phenotypes) { this.setState({phenotypes: disease.phenotypes}); }
        if (disease.freetext) { this.setState({diseaseFreeTextConfirm: disease.freetext}); }
    },

    passDataToParent(diseaseId, term, description, synonyms, phenotypes, freetext) {
        let diseaseObj = this.state.diseaseObj;

        if (diseaseId) {
            /**
             * Changing colon to underscore in id string for database
             */
            diseaseObj['diseaseId'] = diseaseId.replace(':', '_');
            this.setState({diseaseId: diseaseId});
        }
        if (term) {
            diseaseObj['term'] = term;
            this.setState({diseaseTerm: term});
        }
        if (description) {
            diseaseObj['description'] = description;
            this.setState({diseaseDescription: description});
        } else {
            if (diseaseObj['description']) { delete diseaseObj['description']; }
            this.setState({diseaseDescription: null});
        }
        if (synonyms && synonyms.length) {
            diseaseObj['synonyms'] = synonyms;
            this.setState({synonyms: synonyms});
        } else {
            if (diseaseObj['synonyms']) { delete diseaseObj['synonyms']; }
            this.setState({synonyms: []});
        }
        if (phenotypes && phenotypes.length) {
            diseaseObj['phenotypes'] = phenotypes;
            this.setState({phenotypes: phenotypes});
        } else {
            if (diseaseObj['phenotypes']) { delete diseaseObj['phenotypes']; }
            this.setState({phenotypes: []});
        }
        if (freetext) {
            diseaseObj['freetext'] = true;
            this.setState({diseaseFreeTextConfirm: true});
        } else {
            if (diseaseObj['freetext']) { delete diseaseObj['freetext']; }
            this.setState({diseaseFreeTextConfirm: false});
        }
        this.setState({diseaseObj: diseaseObj}, () => {
            this.updateInterpretationWithDisease();
            // Pass data object back to parent
            this.props.updateDiseaseObj(this.state.diseaseObj);
        });
    },

    // When the form is submitted...
    updateInterpretationWithDisease() {
        this.setState({submitResourceBusy: true});

        let diseaseObj = this.state.diseaseObj;
        let interpretationDisease, currInterpretation, flatInterpretation;

        if (diseaseObj && diseaseObj.term) {
            this.getRestData('/search?type=disease&diseaseId=' + diseaseObj.diseaseId).then(diseaseSearch => {
                let diseaseUuid;
                if (diseaseSearch.total === 0) {
                    return this.postRestData('/diseases/', diseaseObj).then(result => {
                        let newDisease = result['@graph'][0];
                        diseaseUuid = newDisease['uuid'];
                        this.setState({diseaseUuid: diseaseUuid}, () => {
                            interpretationDisease = diseaseUuid;
                            return Promise.resolve(result);
                        });
                    });
                } else {
                    let _id = diseaseSearch['@graph'][0]['@id'];
                    diseaseUuid = _id.slice(10, -1);
                    this.setState({diseaseUuid: diseaseUuid}, () => {
                        interpretationDisease = diseaseUuid;
                    });
                }

            }, e => {
                // The given disease couldn't be retrieved for some reason.
                this.setState({submitResourceBusy: false}); // submit error; re-enable submit button
                this.setState({diseaseError: 'Error on validating disease.'});
                throw e;
            }).then(data => {
                this.getRestData('/interpretation/' + this.props.interpretation.uuid).then(interpretation => {
                    currInterpretation = interpretation;
                    // get up-to-date copy of interpretation object and flatten it
                    flatInterpretation = curator.flatten(currInterpretation);
                    // if the interpretation object does not have a disease object, create it
                    if (!('disease' in flatInterpretation)) {
                        flatInterpretation.disease = '';
                        // Return the newly flattened interpretation object in a Promise
                        return Promise.resolve(flatInterpretation);
                    } else {
                        return Promise.resolve(flatInterpretation);
                    }
                }).then(interpretationObj => {
                    if (interpretationDisease) {
                        // Set the disease '@id' to the newly flattened interpretation object's 'disease' property
                        interpretationObj.disease = interpretationDisease;
                        // Update the intepretation object partially with the new disease property value
                        return this.putRestData('/interpretation/' + this.props.interpretation.uuid, interpretationObj).then(result => {
                            this.props.updateInterpretationObj();
                            var meta = {
                                interpretation: {
                                    variant: this.props.variantData['@id'],
                                    disease: interpretationDisease,
                                    mode: 'edit-disease'
                                }
                            };
                            if (flatInterpretation.modeInheritance) {
                                meta.interpretation.modeInheritance = flatInterpretation.modeInheritance;
                            }
                            return this.recordHistory('modify', currInterpretation, meta).then(result => {
                                this.setState({submitResourceBusy: false});
                            });
                        });
                    }
                });
            }).catch(e => {
                // Some unexpected error happened
                this.setState({submitResourceBusy: false});
                parseAndLogError.bind(undefined, 'fetchedRequest');
            });
        } else {
            this.getRestData('/interpretation/' + this.props.interpretation.uuid).then(interpretation => {
                currInterpretation = interpretation;
                // get up-to-date copy of interpretation object and flatten it
                var flatInterpretation = curator.flatten(currInterpretation);
                // if the interpretation object does not have a disease object, create it
                if ('disease' in flatInterpretation) {
                    delete flatInterpretation['disease'];
                    let provisionalPathogenicity = this.props.provisionalPathogenicity;
                    let calculatedAssertion = this.props.calculatedAssertion;
                    if (provisionalPathogenicity === 'Likely pathogenic' || provisionalPathogenicity === 'Pathogenic') {
                        flatInterpretation['markAsProvisional'] = false;
                    } else if (!provisionalPathogenicity) {
                        if (calculatedAssertion === 'Likely pathogenic' || calculatedAssertion === 'Pathogenic' ) {
                            flatInterpretation['markAsProvisional'] = false;
                        }
                    }

                    // Update the intepretation object partially with the new disease property value
                    this.putRestData('/interpretation/' + this.props.interpretation.uuid, flatInterpretation).then(result => {
                        var meta = {
                            interpretation: {
                                variant: this.props.variantData['@id'],
                                disease: interpretationDisease,
                                mode: 'edit-disease'
                            }
                        };
                        this.recordHistory('modify', currInterpretation, meta).then(result => {
                            this.setState({submitResourceBusy: false}, () => {
                                // Need 'submitResourceBusy' state to proceed closing modal
                                this.props.updateInterpretationObj();
                            });
                        });
                    });
                } else {
                    this.setState({submitResourceBusy: false});
                }
            }).catch(e => {
                // Some unexpected error happened
                this.setState({submitResourceBusy: false});
                parseAndLogError.bind(undefined, 'fetchedRequest');
            });
        }
    },

    /**
     * Handler for button press event to delete disease from the evidence
     */
    handleDeleteDisease() {
        let diseaseObj = this.state.diseaseObj;
        this.setState({
            diseaseId: '',
            diseaseTerm: null,
            diseaseDescription: null,
            synonyms: [],
            phenotypes: [],
            diseaseFreeTextConfirm: false,
            diseaseObj: {},
            error: null
        }, () => {
            this.updateInterpretationWithDisease();
            // Pass data object back to parent
            this.props.updateDiseaseObj(this.state.diseaseObj);
        });
    },

    /**
     * Called when either one of the alert modal buttons is clicked.
     * True if the 'Confirm' button was clicked.
     * False if the 'Cancel' button was clicked.
     */
    handleDeleteConfirm(confirm, e) {
        if (confirm) {
            this.handleDeleteDisease();
        }
        this.confirm.closeModal();
    },

    /**
     * Handler for button press event to alert/confirm disease deletion
     * if the interpretation had been marked as 'Provisional'
     */
    renderDeleteDiseaseBtn() {
        let interpretation = this.props.interpretation;

        if (interpretation && interpretation.markAsProvisional) {
            return (
                <ModalComponent modalTitle="Confirm disease deletion" modalClass="modal-default" modalWrapperClass="confirm-interpretation-delete-disease-modal pull-right"
                    bootstrapBtnClass="btn btn-primary disease-delete " actuatorClass="interpretation-delete-disease-btn" actuatorTitle={Disease}
                    onRef={ref => (this.confirm = ref)}>

                                Warning: This interpretation is marked as "Provisional." If it has a Modified Pathogenicity of "Likely pathogenic" or "Pathogenic,"
                                or no Modified Pathogenicity but a Calculated Pathogenicity of "Likely pathogenic" or "Pathogenic," it must be associated with a disease.

                                If you still wish to delete the disease, select "Cancel," then select "View Summary" and remove the "Provisional" selection
                                - otherwise, deleting the disease will automatically remove the "Provisional" status.

                            <Input type="button" inputClassName="btn-default btn-inline-spacer" clickHandler={this.handleDeleteConfirm.bind(null, false)} title="Cancel" />
                            <Input type="button" inputClassName="btn-primary btn-inline-spacer" clickHandler={this.handleDeleteConfirm.bind(null, true)} title="Confirm" />

                </ModalComponent>
            );
        } else if (interpretation && !interpretation.markAsProvisional) {
            return (

                    Disease

            );
        }
    },

    render() {
        let diseaseId = this.state.diseaseId;
        let diseaseTerm = this.state.diseaseTerm;
        let diseaseDescription = this.state.diseaseDescription;
        let diseaseFreeTextConfirm = this.state.diseaseFreeTextConfirm;
        let phenotypes = this.state.phenotypes;
        let synonyms = this.state.synonyms;
        let addDiseaseModalBtn = diseaseTerm ? Disease : Disease;

        return (

                {!diseaseTerm ?

                        <DiseaseModal
                            addDiseaseModalBtn={addDiseaseModalBtn}
                            diseaseId={diseaseId}
                            diseaseTerm={diseaseTerm}
                            diseaseDescription={diseaseDescription}
                            diseaseFreeTextConfirm={diseaseFreeTextConfirm}
                            phenotypes={phenotypes}
                            synonyms={synonyms}
                            passDataToParent={this.passDataToParent}
                            addDiseaseModalBtnLayoutClass=" evidence-disease pull-right"
                        />

                    :

                        {this.renderDeleteDiseaseBtn()}

                }

        );
    }
});
<commit_msg>:bug: Incorrect bootstrap @class for disease deletion button in interpretation<commit_after>"use strict";
import React, { Component } from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
import createReactClass from 'create-react-class';
import { FormMixin, Input } from '../../libs/bootstrap/form';
import { external_url_map } from '../globals';

import { DiseaseModal } from './modal';
import ModalComponent from '../../libs/bootstrap/modal';

var curator = require('../curator');
var CuratorHistory = require('../curator_history');
var RestMixin = require('../rest').RestMixin;
var parseAndLogError = require('../mixins').parseAndLogError;

/**
 * Component for adding/deleting disease associated with an interpretation in VCI
 */
const InterpretationDisease = module.exports.InterpretationDisease = createReactClass({
    mixins: [RestMixin, FormMixin, CuratorHistory],

    propTypes: {
        interpretation: PropTypes.object,
        variantData: PropTypes.object,
        hasAssociatedDisease: PropTypes.bool,
        editKey: PropTypes.string,
        updateInterpretationObj: PropTypes.func,
        calculatedAssertion: PropTypes.string,
        provisionalPathogenicity: PropTypes.string,
        diseaseObj: PropTypes.object,
        updateDiseaseObj: PropTypes.func,
        session: PropTypes.object
    },

    getInitialState() {
        return {
            interpretation: this.props.interpretation,
            diseaseObj: this.props.diseaseObj,
            diseaseId: '',
            diseaseTerm: null,
            diseaseDescription: null,
            synonyms: [],
            phenotypes: [],
            diseaseFreeTextConfirm: false,
            submitResourceBusy: false
        };
    },

    componentDidMount() {
        let interpretation = this.props.interpretation;
        if (interpretation && interpretation.disease) {
            this.setDiseaseObjectStates(interpretation.disease);
        }
    },

    componentWillReceiveProps(nextProps)  {
        if (nextProps.interpretation) {
            this.setState({interpretation: nextProps.interpretation});
        }
        if (nextProps.diseaseObj) {
            this.setState({diseaseObj: nextProps.diseaseObj}, () => {
                let diseaseObj = this.state.diseaseObj;
                if (Object.keys(diseaseObj).length) {
                    this.setDiseaseObjectStates(diseaseObj);
                }
            });
        }
    },

    /**
     * Shared method called by componentDidMount(), componentWillReceiveProps(nextProps)
     * @param {*} disease
     */
    setDiseaseObjectStates(disease) {
        if (disease.diseaseId) { this.setState({diseaseId: disease.diseaseId}); }
        if (disease.term) { this.setState({diseaseTerm: disease.term}); }
        if (disease.description) { this.setState({diseaseDescription: disease.description}); }
        if (disease.synonyms) { this.setState({synonyms: disease.synonyms}); }
        if (disease.phenotypes) { this.setState({phenotypes: disease.phenotypes}); }
        if (disease.freetext) { this.setState({diseaseFreeTextConfirm: disease.freetext}); }
    },

    passDataToParent(diseaseId, term, description, synonyms, phenotypes, freetext) {
        let diseaseObj = this.state.diseaseObj;

        if (diseaseId) {
            /**
             * Changing colon to underscore in id string for database
             */
            diseaseObj['diseaseId'] = diseaseId.replace(':', '_');
            this.setState({diseaseId: diseaseId});
        }
        if (term) {
            diseaseObj['term'] = term;
            this.setState({diseaseTerm: term});
        }
        if (description) {
            diseaseObj['description'] = description;
            this.setState({diseaseDescription: description});
        } else {
            if (diseaseObj['description']) { delete diseaseObj['description']; }
            this.setState({diseaseDescription: null});
        }
        if (synonyms && synonyms.length) {
            diseaseObj['synonyms'] = synonyms;
            this.setState({synonyms: synonyms});
        } else {
            if (diseaseObj['synonyms']) { delete diseaseObj['synonyms']; }
            this.setState({synonyms: []});
        }
        if (phenotypes && phenotypes.length) {
            diseaseObj['phenotypes'] = phenotypes;
            this.setState({phenotypes: phenotypes});
        } else {
            if (diseaseObj['phenotypes']) { delete diseaseObj['phenotypes']; }
            this.setState({phenotypes: []});
        }
        if (freetext) {
            diseaseObj['freetext'] = true;
            this.setState({diseaseFreeTextConfirm: true});
        } else {
            if (diseaseObj['freetext']) { delete diseaseObj['freetext']; }
            this.setState({diseaseFreeTextConfirm: false});
        }
        this.setState({diseaseObj: diseaseObj}, () => {
            this.updateInterpretationWithDisease();
            // Pass data object back to parent
            this.props.updateDiseaseObj(this.state.diseaseObj);
        });
    },

    // When the form is submitted...
    updateInterpretationWithDisease() {
        this.setState({submitResourceBusy: true});

        let diseaseObj = this.state.diseaseObj;
        let interpretationDisease, currInterpretation, flatInterpretation;

        if (diseaseObj && diseaseObj.term) {
            this.getRestData('/search?type=disease&diseaseId=' + diseaseObj.diseaseId).then(diseaseSearch => {
                let diseaseUuid;
                if (diseaseSearch.total === 0) {
                    return this.postRestData('/diseases/', diseaseObj).then(result => {
                        let newDisease = result['@graph'][0];
                        diseaseUuid = newDisease['uuid'];
                        this.setState({diseaseUuid: diseaseUuid}, () => {
                            interpretationDisease = diseaseUuid;
                            return Promise.resolve(result);
                        });
                    });
                } else {
                    let _id = diseaseSearch['@graph'][0]['@id'];
                    diseaseUuid = _id.slice(10, -1);
                    this.setState({diseaseUuid: diseaseUuid}, () => {
                        interpretationDisease = diseaseUuid;
                    });
                }

            }, e => {
                // The given disease couldn't be retrieved for some reason.
                this.setState({submitResourceBusy: false}); // submit error; re-enable submit button
                this.setState({diseaseError: 'Error on validating disease.'});
                throw e;
            }).then(data => {
                this.getRestData('/interpretation/' + this.props.interpretation.uuid).then(interpretation => {
                    currInterpretation = interpretation;
                    // get up-to-date copy of interpretation object and flatten it
                    flatInterpretation = curator.flatten(currInterpretation);
                    // if the interpretation object does not have a disease object, create it
                    if (!('disease' in flatInterpretation)) {
                        flatInterpretation.disease = '';
                        // Return the newly flattened interpretation object in a Promise
                        return Promise.resolve(flatInterpretation);
                    } else {
                        return Promise.resolve(flatInterpretation);
                    }
                }).then(interpretationObj => {
                    if (interpretationDisease) {
                        // Set the disease '@id' to the newly flattened interpretation object's 'disease' property
                        interpretationObj.disease = interpretationDisease;
                        // Update the intepretation object partially with the new disease property value
                        return this.putRestData('/interpretation/' + this.props.interpretation.uuid, interpretationObj).then(result => {
                            this.props.updateInterpretationObj();
                            var meta = {
                                interpretation: {
                                    variant: this.props.variantData['@id'],
                                    disease: interpretationDisease,
                                    mode: 'edit-disease'
                                }
                            };
                            if (flatInterpretation.modeInheritance) {
                                meta.interpretation.modeInheritance = flatInterpretation.modeInheritance;
                            }
                            return this.recordHistory('modify', currInterpretation, meta).then(result => {
                                this.setState({submitResourceBusy: false});
                            });
                        });
                    }
                });
            }).catch(e => {
                // Some unexpected error happened
                this.setState({submitResourceBusy: false});
                parseAndLogError.bind(undefined, 'fetchedRequest');
            });
        } else {
            this.getRestData('/interpretation/' + this.props.interpretation.uuid).then(interpretation => {
                currInterpretation = interpretation;
                // get up-to-date copy of interpretation object and flatten it
                var flatInterpretation = curator.flatten(currInterpretation);
                // if the interpretation object does not have a disease object, create it
                if ('disease' in flatInterpretation) {
                    delete flatInterpretation['disease'];
                    let provisionalPathogenicity = this.props.provisionalPathogenicity;
                    let calculatedAssertion = this.props.calculatedAssertion;
                    if (provisionalPathogenicity === 'Likely pathogenic' || provisionalPathogenicity === 'Pathogenic') {
                        flatInterpretation['markAsProvisional'] = false;
                    } else if (!provisionalPathogenicity) {
                        if (calculatedAssertion === 'Likely pathogenic' || calculatedAssertion === 'Pathogenic' ) {
                            flatInterpretation['markAsProvisional'] = false;
                        }
                    }

                    // Update the intepretation object partially with the new disease property value
                    this.putRestData('/interpretation/' + this.props.interpretation.uuid, flatInterpretation).then(result => {
                        var meta = {
                            interpretation: {
                                variant: this.props.variantData['@id'],
                                disease: interpretationDisease,
                                mode: 'edit-disease'
                            }
                        };
                        this.recordHistory('modify', currInterpretation, meta).then(result => {
                            this.setState({submitResourceBusy: false}, () => {
                                // Need 'submitResourceBusy' state to proceed closing modal
                                this.props.updateInterpretationObj();
                            });
                        });
                    });
                } else {
                    this.setState({submitResourceBusy: false});
                }
            }).catch(e => {
                // Some unexpected error happened
                this.setState({submitResourceBusy: false});
                parseAndLogError.bind(undefined, 'fetchedRequest');
            });
        }
    },

    /**
     * Handler for button press event to delete disease from the evidence
     */
    handleDeleteDisease() {
        let diseaseObj = this.state.diseaseObj;
        this.setState({
            diseaseId: '',
            diseaseTerm: null,
            diseaseDescription: null,
            synonyms: [],
            phenotypes: [],
            diseaseFreeTextConfirm: false,
            diseaseObj: {},
            error: null
        }, () => {
            this.updateInterpretationWithDisease();
            // Pass data object back to parent
            this.props.updateDiseaseObj(this.state.diseaseObj);
        });
    },

    /**
     * Called when either one of the alert modal buttons is clicked.
     * True if the 'Confirm' button was clicked.
     * False if the 'Cancel' button was clicked.
     */
    handleDeleteConfirm(confirm, e) {
        if (confirm) {
            this.handleDeleteDisease();
        }
        this.confirm.closeModal();
    },

    /**
     * Handler for button press event to alert/confirm disease deletion
     * if the interpretation had been marked as 'Provisional'
     */
    renderDeleteDiseaseBtn() {
        let interpretation = this.props.interpretation;

        if (interpretation && interpretation.markAsProvisional) {
            return (
                <ModalComponent modalTitle="Confirm disease deletion" modalClass="modal-default" modalWrapperClass="confirm-interpretation-delete-disease-modal pull-right"
                    bootstrapBtnClass="btn btn-danger disease-delete " actuatorClass="interpretation-delete-disease-btn" actuatorTitle={Disease}
                    onRef={ref => (this.confirm = ref)}>

                                Warning: This interpretation is marked as "Provisional." If it has a Modified Pathogenicity of "Likely pathogenic" or "Pathogenic,"
                                or no Modified Pathogenicity but a Calculated Pathogenicity of "Likely pathogenic" or "Pathogenic," it must be associated with a disease.

                                If you still wish to delete the disease, select "Cancel," then select "View Summary" and remove the "Provisional" selection
                                - otherwise, deleting the disease will automatically remove the "Provisional" status.

                            <Input type="button" inputClassName="btn-default btn-inline-spacer" clickHandler={this.handleDeleteConfirm.bind(null, false)} title="Cancel" />
                            <Input type="button" inputClassName="btn-primary btn-inline-spacer" clickHandler={this.handleDeleteConfirm.bind(null, true)} title="Confirm" />

                </ModalComponent>
            );
        } else if (interpretation && !interpretation.markAsProvisional) {
            return (

                    Disease

            );
        }
    },

    render() {
        let diseaseId = this.state.diseaseId;
        let diseaseTerm = this.state.diseaseTerm;
        let diseaseDescription = this.state.diseaseDescription;
        let diseaseFreeTextConfirm = this.state.diseaseFreeTextConfirm;
        let phenotypes = this.state.phenotypes;
        let synonyms = this.state.synonyms;
        let addDiseaseModalBtn = diseaseTerm ? Disease : Disease;

        return (

                {!diseaseTerm ?

                        <DiseaseModal
                            addDiseaseModalBtn={addDiseaseModalBtn}
                            diseaseId={diseaseId}
                            diseaseTerm={diseaseTerm}
                            diseaseDescription={diseaseDescription}
                            diseaseFreeTextConfirm={diseaseFreeTextConfirm}
                            phenotypes={phenotypes}
                            synonyms={synonyms}
                            passDataToParent={this.passDataToParent}
                            addDiseaseModalBtnLayoutClass=" evidence-disease pull-right"
                        />

                    :

                        {this.renderDeleteDiseaseBtn()}

                }

        );
    }
});
<|endoftext|>


<commit_before>/* jshint ignore:start */
'use strict';

var testHelper = require('../../../common/tests/test-helper');
var setupFile = require('./decision-setup');

var dashboardPage = require('../pages/dashboard');
var decisionsPage = require('../pages/decisions');
var definitionPage = require('../pages/decision-definition');
var instancePage = require('../pages/decision-instance');

describe.only('Cockpit Decision Instance Spec', function() {

  describe('page navigation', function() {

    before(function() {
      return testHelper(setupFile.setup1, function() {

        dashboardPage.navigateToWebapp('Cockpit');
        dashboardPage.authentication.userLogin('admin', 'admin');
        dashboardPage.goToSection('Decisions');
      });
    });

    it('should go to decision definition view', function() {

      // given
      decisionsPage.deployedDecisionsList.decisionName(0).then(function(decisionName) {

        // when
        decisionsPage.deployedDecisionsList.selectDecision(0).then(function() {

          // then
          expect(dashboardPage.breadcrumb.activeCrumb().getText()).to.eventually.eql(decisionName);
        });
      })
    });

    it('should go to process instance view', function() {

      // given
      definitionPage.decisionInstancesTab.instanceId(0).then(function(instanceId) {

        // when
        definitionPage.decisionInstancesTab.selectInstanceId(0).then(function() {

          // then
          expect(instancePage.information.instanceId()).to.eventually.eql(instanceId);
          expect(dashboardPage.breadcrumb.activeCrumb().getText()).to.eventually.eql(instanceId);
        });
      });
    });

  });

  describe('table interaction', function() {

    before(function() {
      return testHelper(setupFile.setup1, function() {

        dashboardPage.navigateToWebapp('Cockpit');
        dashboardPage.authentication.userLogin('admin', 'admin');
        dashboardPage.goToSection('Decisions');
      });
    });

    it('should display decision table', function() {

      // when
      decisionsPage.deployedDecisionsList.selectDecision(0);
      definitionPage.decisionInstancesTab.selectInstanceId(0);

      // then
      expect(instancePage.table.tableElement().isDisplayed()).to.eventually.be.true;
    });

    it('should highlight fired rules', function() {
      expect(instancePage.table.row(0).getAttribute('class')).to.eventually.contain('fired');
    });

    it('should show the inputs on the table', function() {
      expect(instancePage.table.labelRow().getInputText(0)).to.eventually.eql('Invoice Amount = 100');
      expect(instancePage.table.labelRow().getInputText(1)).to.eventually.eql('Invoice Category = travelExpenses');
    });

    it('should show the outputs on the table', function() {
      expect(instancePage.table.ruleRow(0).getCellText(3)).to.eventually.eql('"accounting" = accounting');
    });

  });

  describe('in-/outputs', function() {

    before(function() {
      return testHelper(setupFile.setup1, function() {

        dashboardPage.navigateToWebapp('Cockpit');
        dashboardPage.authentication.userLogin('admin', 'admin');
        dashboardPage.goToSection('Decisions');
      });
    });

    it('should go to decision instance view', function() {
      // when
      decisionsPage.deployedDecisionsList.selectDecision(0);

      definitionPage.decisionInstancesTab.instanceId(0).then(function(instanceId) {
        definitionPage.decisionInstancesTab.selectInstanceId(0);

        // then
        expect(dashboardPage.breadcrumb.activeCrumb().getText()).to.eventually.eql(instanceId);
      });
    });

    it('show inputs for the decision instance', function() {

      // when
      instancePage.inputsTab.selectTab();

      // then
      expect(instancePage.inputsTab.variableValue(0)).to.eventually.eql('100');
    });

    it('show outputs for the decision instance', function() {

      // when
      instancePage.outputsTab.selectTab();

      // then
      expect(instancePage.outputsTab.variableValue(0)).to.eventually.eql('accounting');
    });

  });

  describe('in-/outputs without clause name', function() {

    before(function() {
      return testHelper(setupFile.setup3, function() {

        dashboardPage.navigateToWebapp('Cockpit');
        dashboardPage.authentication.userLogin('admin', 'admin');
        dashboardPage.goToSection('Decisions');
      });
    });

    it('should go to decision instance view', function() {
      // when
      decisionsPage.deployedDecisionsList.selectDecision(0);

      definitionPage.decisionInstancesTab.instanceId(0).then(function(instanceId) {
        definitionPage.decisionInstancesTab.selectInstanceId(0);

        // then
        expect(dashboardPage.breadcrumb.activeCrumb().getText()).to.eventually.eql(instanceId);
      });
    });

    it('show inputs clause id', function() {

      // when
      instancePage.inputsTab.selectTab();

      // then
      expect(instancePage.inputsTab.variableName(0)).to.eventually.eql('clause1');
    });

    it('show outputs clause id', function() {

      // when
      instancePage.outputsTab.selectTab();

      // then
      expect(instancePage.outputsTab.variableName(0)).to.eventually.eql('clause3');
    });

  });

  describe('actions', function() {

    describe('navigate to process instance', function() {

      before(function() {
        return testHelper(setupFile.setup1, function() {

          dashboardPage.navigateToWebapp('Cockpit');
          dashboardPage.authentication.userLogin('admin', 'admin');
          dashboardPage.goToSection('Decisions');
        });
      });

      it('go to decision instance view', function() {

        // when
        decisionsPage.deployedDecisionsList.selectDecision(0);
        definitionPage.decisionInstancesTab.selectInstanceId(0);
      });

      it('go to the process instance page', function() {

        // when
        instancePage.gotoProcessInstanceAction.gotoProcessInstance();

        // then
        expect(browser.getCurrentUrl()).to.eventually.contain('#/process-instance/');
      });

    });

    describe('navigation action', function() {

      before(function() {
        return testHelper(setupFile.setup4, function() {

          dashboardPage.navigateToWebapp('Cockpit');
          dashboardPage.authentication.userLogin('admin', 'admin');
          dashboardPage.goToSection('Decisions');
          decisionsPage.deployedDecisionsList.selectDecision(0);
          definitionPage.decisionInstancesTab.selectInstanceId(0);
        });
      });

      it('is not displayed', function() {

        // then
        expect(instancePage.gotoProcessInstanceAction.gotoProcessInstanceButton().isDisplayed()).to.eventually.eql(false);
      });

    });

  });

  describe.skip('multi tenancy', function() {

    before(function() {
      return testHelper(setupFile.multiTenancySetup, function() {

        dashboardPage.navigateToWebapp('Cockpit');
        dashboardPage.authentication.userLogin('admin', 'admin');
      });
    });

    it.skip('should not display tenant id of instance if not exists', function() {

      // given
      dashboardPage.goToSection('Decisions');

      // when
      // HEADS UP, you cannot rely on the table sorting in cockpit! Test skipped due to CAM-6007
      decisionsPage.deployedDecisionsList.selectDecision(0);
      definitionPage.decisionInstancesTab.selectInstanceId(0);

      // then
      expect(instancePage.information.tenantId()).to.eventually.contain('tenant1');
    });

    it.skip('should display tenant id of instance', function() {

      // given
      dashboardPage.navigateToWebapp('Cockpit');
      dashboardPage.goToSection('Decisions');

      // when
      // HEADS UP, you cannot rely on the table sorting in cockpit! Test skipped due to CAM-6007
      decisionsPage.deployedDecisionsList.selectDecision(1);
      definitionPage.decisionInstancesTab.selectInstanceId(0);

      // then
      expect(instancePage.information.tenantId()).to.eventually.contain('tenant1');
    });

  });

});
<commit_msg>chore(cockpit test): enable decision multi tenancy test<commit_after>/* jshint ignore:start */
'use strict';

var testHelper = require('../../../common/tests/test-helper');
var setupFile = require('./decision-setup');

var dashboardPage = require('../pages/dashboard');
var decisionsPage = require('../pages/decisions');
var definitionPage = require('../pages/decision-definition');
var instancePage = require('../pages/decision-instance');

describe('Cockpit Decision Instance Spec', function() {

  describe('page navigation', function() {

    before(function() {
      return testHelper(setupFile.setup1, function() {

        dashboardPage.navigateToWebapp('Cockpit');
        dashboardPage.authentication.userLogin('admin', 'admin');
        dashboardPage.goToSection('Decisions');
      });
    });

    it('should go to decision definition view', function() {

      // given
      decisionsPage.deployedDecisionsList.decisionName(0).then(function(decisionName) {

        // when
        decisionsPage.deployedDecisionsList.selectDecision(0).then(function() {

          // then
          expect(dashboardPage.breadcrumb.activeCrumb().getText()).to.eventually.eql(decisionName);
        });
      })
    });

    it('should go to process instance view', function() {

      // given
      definitionPage.decisionInstancesTab.instanceId(0).then(function(instanceId) {

        // when
        definitionPage.decisionInstancesTab.selectInstanceId(0).then(function() {

          // then
          expect(instancePage.information.instanceId()).to.eventually.eql(instanceId);
          expect(dashboardPage.breadcrumb.activeCrumb().getText()).to.eventually.eql(instanceId);
        });
      });
    });

  });

  describe('table interaction', function() {

    before(function() {
      return testHelper(setupFile.setup1, function() {

        dashboardPage.navigateToWebapp('Cockpit');
        dashboardPage.authentication.userLogin('admin', 'admin');
        dashboardPage.goToSection('Decisions');
      });
    });

    it('should display decision table', function() {

      // when
      decisionsPage.deployedDecisionsList.selectDecision(0);
      definitionPage.decisionInstancesTab.selectInstanceId(0);

      // then
      expect(instancePage.table.tableElement().isDisplayed()).to.eventually.be.true;
    });

    it('should highlight fired rules', function() {
      expect(instancePage.table.row(0).getAttribute('class')).to.eventually.contain('fired');
    });

    it('should show the inputs on the table', function() {
      expect(instancePage.table.labelRow().getInputText(0)).to.eventually.eql('Invoice Amount = 100');
      expect(instancePage.table.labelRow().getInputText(1)).to.eventually.eql('Invoice Category = travelExpenses');
    });

    it('should show the outputs on the table', function() {
      expect(instancePage.table.ruleRow(0).getCellText(3)).to.eventually.eql('"accounting" = accounting');
    });

  });

  describe('in-/outputs', function() {

    before(function() {
      return testHelper(setupFile.setup1, function() {

        dashboardPage.navigateToWebapp('Cockpit');
        dashboardPage.authentication.userLogin('admin', 'admin');
        dashboardPage.goToSection('Decisions');
      });
    });

    it('should go to decision instance view', function() {
      // when
      decisionsPage.deployedDecisionsList.selectDecision(0);

      definitionPage.decisionInstancesTab.instanceId(0).then(function(instanceId) {
        definitionPage.decisionInstancesTab.selectInstanceId(0);

        // then
        expect(dashboardPage.breadcrumb.activeCrumb().getText()).to.eventually.eql(instanceId);
      });
    });

    it('show inputs for the decision instance', function() {

      // when
      instancePage.inputsTab.selectTab();

      // then
      expect(instancePage.inputsTab.variableValue(0)).to.eventually.eql('100');
    });

    it('show outputs for the decision instance', function() {

      // when
      instancePage.outputsTab.selectTab();

      // then
      expect(instancePage.outputsTab.variableValue(0)).to.eventually.eql('accounting');
    });

  });

  describe('in-/outputs without clause name', function() {

    before(function() {
      return testHelper(setupFile.setup3, function() {

        dashboardPage.navigateToWebapp('Cockpit');
        dashboardPage.authentication.userLogin('admin', 'admin');
        dashboardPage.goToSection('Decisions');
      });
    });

    it('should go to decision instance view', function() {
      // when
      decisionsPage.deployedDecisionsList.selectDecision(0);

      definitionPage.decisionInstancesTab.instanceId(0).then(function(instanceId) {
        definitionPage.decisionInstancesTab.selectInstanceId(0);

        // then
        expect(dashboardPage.breadcrumb.activeCrumb().getText()).to.eventually.eql(instanceId);
      });
    });

    it('show inputs clause id', function() {

      // when
      instancePage.inputsTab.selectTab();

      // then
      expect(instancePage.inputsTab.variableName(0)).to.eventually.eql('clause1');
    });

    it('show outputs clause id', function() {

      // when
      instancePage.outputsTab.selectTab();

      // then
      expect(instancePage.outputsTab.variableName(0)).to.eventually.eql('clause3');
    });

  });

  describe('actions', function() {

    describe('navigate to process instance', function() {

      before(function() {
        return testHelper(setupFile.setup1, function() {

          dashboardPage.navigateToWebapp('Cockpit');
          dashboardPage.authentication.userLogin('admin', 'admin');
          dashboardPage.goToSection('Decisions');
        });
      });

      it('go to decision instance view', function() {

        // when
        decisionsPage.deployedDecisionsList.selectDecision(0);
        definitionPage.decisionInstancesTab.selectInstanceId(0);
      });

      it('go to the process instance page', function() {

        // when
        instancePage.gotoProcessInstanceAction.gotoProcessInstance();

        // then
        expect(browser.getCurrentUrl()).to.eventually.contain('#/process-instance/');
      });

    });

    describe('navigation action', function() {

      before(function() {
        return testHelper(setupFile.setup4, function() {

          dashboardPage.navigateToWebapp('Cockpit');
          dashboardPage.authentication.userLogin('admin', 'admin');
          dashboardPage.goToSection('Decisions');
          decisionsPage.deployedDecisionsList.selectDecision(0);
          definitionPage.decisionInstancesTab.selectInstanceId(0);
        });
      });

      it('is not displayed', function() {

        // then
        expect(instancePage.gotoProcessInstanceAction.gotoProcessInstanceButton().isDisplayed()).to.eventually.eql(false);
      });

    });

  });

  describe('multi tenancy', function() {

    before(function() {
      return testHelper(setupFile.multiTenancySetup, function() {

        dashboardPage.navigateToWebapp('Cockpit');
        dashboardPage.authentication.userLogin('admin', 'admin');
      });
    });

    it('should not display tenant id of instance if not exists', function() {

      // given
      dashboardPage.goToSection('Decisions');

      // when
      decisionsPage.deployedDecisionsList.selectDecision(0);
      definitionPage.decisionInstancesTab.selectInstanceId(0);

      // then
      expect(instancePage.information.tenantId()).to.eventually.contain('null');
    });

    it('should display tenant id of instance', function() {

      // given
      dashboardPage.navigateToWebapp('Cockpit');
      dashboardPage.goToSection('Decisions');

      // when
      decisionsPage.deployedDecisionsList.selectDecision(1);
      definitionPage.decisionInstancesTab.selectInstanceId(0);

      // then
      expect(instancePage.information.tenantId()).to.eventually.contain('tenant1');
    });

  });

});
<|endoftext|>


<commit_before>import React, { Component } from 'react'

export default class TextEditor extends Component {
  constructor(props){
    super(props);
    this.state = {
      keyCode: {},
      keepInputIme: false
    }
  }

  onKeyDown(e){
    let keepInputIme = false;
    // keyDown時のkeyCode
    // Firefox[0],IE,Chrome,Safari[229]の時はIME入力中
    if (e.keyCode == 0 || e.keyCode == 229) {
      keepInputIme = true;
    }
    this.setState({
      keyCode: {
        down: (this.state.keyCode.down) ? this.state.keyCode.down.concat(e.keyCode) : [e.keyCode]
      },
      keepInputIme: keepInputIme
    });
  }

  onKeyUp(e){
    if (this.state.keyCode.down.includes(e.keyCode) && e.keyCode == 13) {
      let data = this.state.keyCode;
      // IME入力中はfalseを返す
      if (this.state.keepInputIme) {
        data = false;
      }
      this.props.onPressEnterKey(data);
    }
    this.setState({
      keyCode: {
        down: []
      },
      keepInputIme: false
    })
  }

  onChange(e){
    this.props.onChange(e.target.value);
  }

  render() {
    if (this.props.multiline) {
      return (
        <textarea
          name={this.props.name}
          rows={this.props.rows}
          cols={this.props.cols}
          placeholder={this.props.placeholder}
          onChange={(e) => this.onChange(e)}
          onKeyDown={(e) => this.onKeyDown(e)}
          onKeyUp={(e) => this.onKeyUp(e)}
        >
          {this.props.value}
        </textarea>
      )
    } else {
      return (
        <input
          type="text"
          name={this.props.name}
          value={this.props.value}
          placeholder={this.props.placeholder}
          onChange={(e) => this.onChange(e)}
          onKeyDown={(e) => this.onKeyDown(e)}
          onKeyUp={(e) => this.onKeyUp(e)}
        />
      )
    }
  }
}<commit_msg>IME入力中の真偽値を返すkeepInputImeをメンバー変数に変更<commit_after>import React, { Component } from 'react'

export default class TextEditor extends Component {
  constructor(props){
    super(props);
    this.state = {
      keyCode: {}
    }
    this.keepInputIme = false;
  }

  onKeyDown(e){
    // keyDown時のkeyCode
    // Firefox[0],IE,Chrome,Safari[229]の時はIME入力中
    if (e.keyCode == 0 || e.keyCode == 229) {
      this.keepInputIme = true;
    }
    this.setState({
      keyCode: {
        down: (this.state.keyCode.down) ? this.state.keyCode.down.concat(e.keyCode) : [e.keyCode]
      }
    });
  }

  onKeyUp(e){
    if (this.state.keyCode.down.includes(e.keyCode) && e.keyCode == 13) {
      let data = this.state.keyCode;
      // IME入力中はfalseを返す
      if (this.keepInputIme) {
        data = false;
      }
      this.props.onPressEnterKey(data);
    }
    this.setState({
      keyCode: {
        down: []
      }
    });
    this.keepInputIme = false;
  }

  onChange(e){
    this.props.onChange(e.target.value);
  }

  render() {
    if (this.props.multiline) {
      return (
        <textarea
          name={this.props.name}
          rows={this.props.rows}
          cols={this.props.cols}
          placeholder={this.props.placeholder}
          onChange={(e) => this.onChange(e)}
          onKeyDown={(e) => this.onKeyDown(e)}
          onKeyUp={(e) => this.onKeyUp(e)}
        >
          {this.props.value}
        </textarea>
      )
    } else {
      return (
        <input
          type="text"
          name={this.props.name}
          value={this.props.value}
          placeholder={this.props.placeholder}
          onChange={(e) => this.onChange(e)}
          onKeyDown={(e) => this.onKeyDown(e)}
          onKeyUp={(e) => this.onKeyUp(e)}
        />
      )
    }
  }
}<|endoftext|>


<commit_before>import swPrecache from 'sw-precache';
import { resolve } from 'path';
import fs from 'fs';
import uglifyJs from 'uglify-js';
import webpackConfig from './webpack.config.prod';
import pkg from './package.json';

const publicDir = webpackConfig.output.path;

swPrecache.generate({
  cacheId: pkg.name,
  dontCacheBustUrlsMatching: /./,
  dynamicUrlToDependencies: {
    '/': [resolve(__dirname, 'views', 'index.ejs')]
  },
  staticFileGlobs: [
    `${publicDir}/bundle.*.{js,css}`,
    `${publicDir}/vendor.*.{js,css}`
  ],
  navigateFallback: '/',
  navigateFallbackWhitelist: [
    /^\/posts\//,
    /^\/about/
  ],
  stripPrefix: publicDir,
  runtimeCaching: [{
    urlPattern: /api/,
    handler: 'networkFirst'
  }]
}).then((serviceWorkerString) => {
  fs.writeFile(`${publicDir}/sw.js`, uglifyJs.minify(serviceWorkerString).code, (err) => {
    if (err) {
      return console.log(err);
    }
  });
});
<commit_msg>Update precache<commit_after>import swPrecache from 'sw-precache';
import { resolve } from 'path';
import fs from 'fs';
import uglifyJs from 'uglify-js';
import webpackConfig from './webpack.config.prod';
import pkg from './package.json';

const publicDir = webpackConfig.output.path;

swPrecache.generate({
  cacheId: pkg.name,
  dontCacheBustUrlsMatching: /./,
  dynamicUrlToDependencies: {
    '/': [resolve(__dirname, 'views', 'index.ejs')]
  },
  staticFileGlobs: [
    `${publicDir}/{bundle,vendor}.*.{js,css}`
  ],
  navigateFallback: '/',
  navigateFallbackWhitelist: [
    /^\/posts\//,
    /^\/about/
  ],
  stripPrefix: publicDir,
  runtimeCaching: [{
    urlPattern: /api/,
    handler: 'networkFirst'
  }]
}).then((serviceWorkerString) => {
  fs.writeFile(`${publicDir}/sw.js`, uglifyJs.minify(serviceWorkerString).code, (err) => {
    if (err) {
      return console.log(err);
    }
  });
});
<|endoftext|>


<commit_before>// Created By Stuart Yamartino | MIT License | 2015

// Wrap the entire library in a self executing anonymous function so as to no conflict
(function(window){

  //--------------------- Public API Section ---------------------//
  // This is the start of the Pressure Object, this is the only object that is accessible to the end user
  // Only the methods in this object can be called, making it the "public api"
  var Pressure = {

    // This method is to determine if the browser and/or user have support for force touch of 3D touch
    // When this method is run, it will immediatly return if the browser does not support the force/3D touch,
    // however it will not return if the user has an supported trackpad or device until a click happens somewhere on the page
    supported: function(closure){
      Browser.checkSupport(closure);
    },

    // This method will return a force value from the user and will automatically determine if the user has force or 3D touch
    // It also accepts an optional type, this type is passed in by the next 2 methods to be explicit about which change event type they want
    change: function(selector, closure, type){
      Event.build(selector, closure, function(){

        // if type is set explicitly to 'force' and the user has 'force' support
        if(Support.type === 'force' && type === 'force'){
          Event.changeForceTouch(selector, closure);
        }
        // if type is set explicitly to '3d' and the user has '3d' support
        else if(Support.type === '3d' && type === '3d'){
          Event.change3DTouch(selector, closure);
        }
        // if the user has 'force' touch support
        else if(Support.type === 'force'){
          Event.changeForceTouch(selector, closure);
        }
        // if the user has '3d' touch support
        else if(Support.type === '3d'){
          Event.change3DTouch(selector, closure);
        }
      }.bind(this))
    },

    // This method is meant to be called when targeting ONLY devices with force touch
    changeForceTouch: function(selector, closure){
      this.change(selector, closure, 'force');
    },

    // This method is meant to be called when targeting ONLY devices with 3D touch
    change3DTouch: function(selector, closure){
      this.change(selector, closure, '3d');
    }
  }

  var Event = {

    // this method builds events and handles event support on ever public method called by user
    build: function(selector, userClosure, closure){
      if(Support.forPressure){
        closure();
      } else if(Support.hasRun){
        getFailClosure(userClosure)();
      } else {
        Browser.checkSupport({
          success: function(){
            closure();
          },
          fail: getFailClosure(userClosure)
        });
      }
    },

    // this handles the executing of the Force Touch change event
    changeForceTouch: function(selector, closure){
      // loop over each item that is returned
      forEach(queryElement(selector), function(index, element){
        element.addEventListener('webkitmouseforcechanged', function(event){
          getSuccessClosure(closure).call(element, event.webkitForce, event);
        }, false);
      });
    },

    // this handles the executing of the 3D Touch change event
    change3DTouch: function(selector, closure){
      // loop over each item that is returned
      forEach(queryElement(selector), function(index, element){

        // add event for touch start and set changeExecute
        element.addEventListener('touchstart', function(event){
          // Touch3D.changeExecute = success;
          Touch3D.startCheckingForce(event, closure);
        }, false);

        // // add event for touch move and set changeExecute
        // element.addEventListener('touchmove', function(event){
        //   // Touch3D.changeExecute = success;
        //   Touch3D.startCheckingForce(event, closure);
        // }, false);

        // add event touch end to stop the change from running
        element.addEventListener('touchend', function(event){
          Touch3D.touchDown = false;
        }, false);
      });
    },
  }

  var Browser = {

    checkSupport: function(closure){
      if(Support.hasRun){
        return Support.forPressure ? callClosure(closure, 'success') : callClosure(closure, 'fail');
      }
      if(this.browserSupported()){
        this.testDeviceSupport(closure);
      } else {
        Support.browserFail();
        callClosure(closure, 'fail');
      }
    },

    browserSupported: function(){
      return ('onwebkitmouseforcewillbegin' in document) || ('ontouchstart' in document);
    },

    testDeviceSupport: function(closure){
      Support.forPressure = false;
      this.returnSupportBind = this.returnSupport.bind(this, closure);
      document.addEventListener('webkitmouseforcewillbegin', this.touchForceEnabled, false);
      document.addEventListener('touchstart', this.touch3DEnabled, false);
      document.addEventListener('mousedown', this.returnSupportBind, false);
    },

    removeDocumentListeners: function(){
      document.removeEventListener('webkitmouseforcewillbegin', this.touchForceEnabled);
      document.removeEventListener('touchstart', this.touch3DEnabled);
      document.removeEventListener('mousedown', this.returnSupportBind);
    },

    touchForceEnabled: function(){
      Support.type = 'force';
      Support.forPressure = true;
    },

    touch3DEnabled: function(event){
      if(event.touches[0].force !== undefined){
        Support.type = '3d';
        Support.forPressure = true;
      }
      this.returnSupport();
    },

    returnSupport: function(closure){
      this.removeDocumentListeners();
      if(Support.forPressure){
        callClosure(closure, 'success');
      } else {
        Support.deviceFail();
        callClosure(closure, 'fail');
      }
    }
  }

  // This class holds the states of the the Pressure support the user has
  var Support = {

    hasRun: false,

    forPressure: false,

    type: '',

    failureType: '',

    browserFail: function(){
      this.didFail('browser');
    },

    deviceFail: function(){
      this.didFail('device');
    },

    didFail: function(type){
      this.hasRun = true;
      this.forPressure = false;
      this.failureType = type;
    }
  }

  // 3D Touch class force handlers
  var Touch3D = {

    // initialize the checking of the force pressure
    startCheckingForce: function(event, closure) {
      this.touchDown = true;
      this.touch = event.touches[0];
      if(this.touch){
        this.fetchForce(closure);
      }
    },

    // if this.touchDown is still set to true, setTimeout to call itself ver and over again
    fetchForce: function(event, closure) {
      if(this.touchDown !== false) {
        setTimeout(this.fetchForce, 10, closure, event);
        closure(this.touch.force || 0, event);
      }
    }
  }

  // return all elements that match the query selector
  var queryElement = function(selector){
    return document.querySelectorAll(selector);
  }

  // loops over each item quered and calls the closure
  var forEach = function (array, callback, scope) {
    for (var i = 0; i < array.length; i++) {
      callback.call(scope, i, array[i]); // passes back stuff we need
    }
  };

  var callClosure = function(closure, status){
    if(isObject(closure)){
      runObjectClosure(closure, status, 'success');
      runObjectClosure(closure, status, 'fail');
    } else {
      if(status === 'success'){
        closure();
      }
    }
  }

  // http://stackoverflow.com/questions/135448/how-do-i-check-if-an-object-has-a-property-in-javascript
  var hasOwnProperty = function(obj, prop) {
    var proto = obj.__proto__ || obj.constructor.prototype;
    return (prop in obj) &&
        (!(prop in proto) || proto[prop] !== obj[prop]);
  }

  // run the closure based on the returned status
  var runObjectClosure = function(closure, status, statusCheck){
    if(hasOwnProperty(closure, statusCheck) && status === statusCheck){
      if(status === 'fail'){
        closure[statusCheck](failureObject());
      } else {
        closure[statusCheck]();
      }
    }
  }

  // Standardized error reporting
  var failureObject = function(){
    switch (Support.failureType) {
      case 'browser':
        var message = 'Browser does not support Force Touch or 3D Touch.';
        break;
      case 'device':
        var message = 'Device does not support Force Touch or 3D Touch.';
        break;
    }
    return {
      'error' : {
        'type'    : Support.failureType,
        'message' : message
      }
    }
  }

  var getSuccessClosure = function(closure){
    if(isObject(closure)){
      if(hasOwnProperty(closure, 'success')){
        return closure.success;
      }
    } else {
      return closure;
    }
  }

  var getFailClosure = function(closure){
    var fail = function(){}
    if(isObject(closure)){
      if(hasOwnProperty(closure, 'fail')){
        fail = closure.fail;
      }
    }
    return fail;
  }

  // Helper to check if input it an object
  var isObject = function(input){
    return input !== null && typeof input === 'object'
  }

  // Assign the Pressure object to the global object so it can be called from inside the self executing anonymous function
  window.Pressure = Pressure;
}(window));

<commit_msg>only 3D or Force touch methods now work<commit_after>// Created By Stuart Yamartino | MIT License | 2015

// Wrap the entire library in a self executing anonymous function so as to no conflict
(function(window){

  //--------------------- Public API Section ---------------------//
  // This is the start of the Pressure Object, this is the only object that is accessible to the end user
  // Only the methods in this object can be called, making it the "public api"
  var Pressure = {

    // This method is to determine if the browser and/or user have support for force touch of 3D touch
    // When this method is run, it will immediatly return if the browser does not support the force/3D touch,
    // however it will not return if the user has an supported trackpad or device until a click happens somewhere on the page
    supported: function(closure){
      Browser.checkSupport(closure);
    },

    // This method will return a force value from the user and will automatically determine if the user has Force or 3D Touch
    // It also accepts an optional type, this type is passed in by the following 2 methods to be explicit about which change event type they want
    change: function(selector, closure, type){
      Event.build(selector, closure, function(){
        // Call ONLY the Force Touch method and only if the user supports it
        if(Support.type === 'force' && type === 'force'){
          Event.changeForceTouch(selector, closure);
        }
        // Call ONLY the 3D Touch method and only if the user supports it
        else if(Support.type === '3d' && type === '3d'){
          Event.change3DTouch(selector, closure);
        }
        // Call Force Touch if the user supports it
        else if(Support.type === 'force' && type !== '3d'){
          Event.changeForceTouch(selector, closure);
        }
        // Call 3D Touch if the user supports it
        else if(Support.type === '3d' && type !== force){
          Event.change3DTouch(selector, closure);
        }
      }.bind(this))
    },

    // targets ONLY devices with Force Touch
    changeForceTouch: function(selector, closure){
      this.change(selector, closure, 'force');
    },

    // targets ONLY devices with 3D touch
    change3DTouch: function(selector, closure){
      this.change(selector, closure, '3d');
    }
  }

  var Event = {

    // this method builds events and handles event support on ever public method called by user
    build: function(selector, userClosure, closure){

      // if the user has pressure support
      if(Support.forPressure){
        closure();
      }
      // if the user doesn't have pressure support, run failure closure if it exists
      else if(Support.hasRun){
        getFailClosure(userClosure)();
      } else {
        Browser.checkSupport({
          success: function(){
            closure();
          },
          fail: getFailClosure(userClosure)
        });
      }
    },

    // this handles the executing of the Force Touch change event
    changeForceTouch: function(selector, closure){
      // loop over each item that is returned
      forEach(queryElement(selector), function(index, element){
        element.addEventListener('webkitmouseforcechanged', function(event){
          getSuccessClosure(closure).call(element, event.webkitForce, event);
        }, false);
      });
    },

    // this handles the executing of the 3D Touch change event
    change3DTouch: function(selector, closure){
      // loop over each item that is returned
      forEach(queryElement(selector), function(index, element){

        // add event for touch start and set changeExecute
        element.addEventListener('touchstart', function(event){
          // Touch3D.changeExecute = success;
          Touch3D.startCheckingForce(event, closure);
        }, false);

        // // add event for touch move and set changeExecute
        // element.addEventListener('touchmove', function(event){
        //   // Touch3D.changeExecute = success;
        //   Touch3D.startCheckingForce(event, closure);
        // }, false);

        // add event touch end to stop the change from running
        element.addEventListener('touchend', function(event){
          Touch3D.touchDown = false;
        }, false);
      });
    },
  }

  var Browser = {

    checkSupport: function(closure){
      if(Support.hasRun){
        return Support.forPressure ? callClosure(closure, 'success') : callClosure(closure, 'fail');
      }
      if(this.browserSupported()){
        this.testDeviceSupport(closure);
      } else {
        Support.browserFail();
        callClosure(closure, 'fail');
      }
    },

    browserSupported: function(){
      return ('onwebkitmouseforcewillbegin' in document) || ('ontouchstart' in document);
    },

    testDeviceSupport: function(closure){
      Support.forPressure = false;
      this.returnSupportBind = this.returnSupport.bind(this, closure);
      document.addEventListener('webkitmouseforcewillbegin', this.touchForceEnabled, false);
      document.addEventListener('touchstart', this.touch3DEnabled, false);
      document.addEventListener('mousedown', this.returnSupportBind, false);
    },

    removeDocumentListeners: function(){
      document.removeEventListener('webkitmouseforcewillbegin', this.touchForceEnabled);
      document.removeEventListener('touchstart', this.touch3DEnabled);
      document.removeEventListener('mousedown', this.returnSupportBind);
    },

    touchForceEnabled: function(){
      Support.type = 'force';
      Support.forPressure = true;
    },

    touch3DEnabled: function(event){
      if(event.touches[0].force !== undefined){
        Support.type = '3d';
        Support.forPressure = true;
      }
      this.returnSupport();
    },

    returnSupport: function(closure){
      this.removeDocumentListeners();
      if(Support.forPressure){
        callClosure(closure, 'success');
      } else {
        Support.deviceFail();
        callClosure(closure, 'fail');
      }
    }
  }

  // This class holds the states of the the Pressure support the user has
  var Support = {

    hasRun: false,

    forPressure: false,

    type: '',

    failureType: '',

    browserFail: function(){
      this.didFail('browser');
    },

    deviceFail: function(){
      this.didFail('device');
    },

    didFail: function(type){
      this.hasRun = true;
      this.forPressure = false;
      this.failureType = type;
    }
  }

  // 3D Touch class force handlers
  var Touch3D = {

    // initialize the checking of the force pressure
    startCheckingForce: function(event, closure) {
      this.touchDown = true;
      this.touch = event.touches[0];
      if(this.touch){
        this.fetchForce(closure);
      }
    },

    // if this.touchDown is still set to true, setTimeout to call itself ver and over again
    fetchForce: function(event, closure) {
      if(this.touchDown !== false) {
        setTimeout(this.fetchForce, 10, closure, event);
        closure(this.touch.force || 0, event);
      }
    }
  }

  // return all elements that match the query selector
  var queryElement = function(selector){
    return document.querySelectorAll(selector);
  }

  // loops over each item quered and calls the closure
  var forEach = function (array, callback, scope) {
    for (var i = 0; i < array.length; i++) {
      callback.call(scope, i, array[i]); // passes back stuff we need
    }
  };

  var callClosure = function(closure, status){
    if(isObject(closure)){
      runObjectClosure(closure, status, 'success');
      runObjectClosure(closure, status, 'fail');
    } else {
      if(status === 'success'){
        closure();
      }
    }
  }

  // http://stackoverflow.com/questions/135448/how-do-i-check-if-an-object-has-a-property-in-javascript
  var hasOwnProperty = function(obj, prop) {
    var proto = obj.__proto__ || obj.constructor.prototype;
    return (prop in obj) &&
        (!(prop in proto) || proto[prop] !== obj[prop]);
  }

  // run the closure based on the returned status
  var runObjectClosure = function(closure, status, statusCheck){
    if(hasOwnProperty(closure, statusCheck) && status === statusCheck){
      if(status === 'fail'){
        closure[statusCheck](failureObject());
      } else {
        closure[statusCheck]();
      }
    }
  }

  // Standardized error reporting
  var failureObject = function(){
    switch (Support.failureType) {
      case 'browser':
        var message = 'Browser does not support Force Touch or 3D Touch.';
        break;
      case 'device':
        var message = 'Device does not support Force Touch or 3D Touch.';
        break;
    }
    return {
      'error' : {
        'type'    : Support.failureType,
        'message' : message
      }
    }
  }

  var getSuccessClosure = function(closure){
    if(isObject(closure)){
      if(hasOwnProperty(closure, 'success')){
        return closure.success;
      }
    } else {
      return closure;
    }
  }

  var getFailClosure = function(closure){
    var fail = function(){}
    if(isObject(closure)){
      if(hasOwnProperty(closure, 'fail')){
        fail = closure.fail;
      }
    }
    return fail;
  }

  // Helper to check if input it an object
  var isObject = function(input){
    return input !== null && typeof input === 'object'
  }

  // Assign the Pressure object to the global object so it can be called from inside the self executing anonymous function
  window.Pressure = Pressure;
}(window));

<|endoftext|>


<commit_before>import MultiSelect from '../'

it('test <MultiSelect /> with props `options`, `selectedIdx`, `displayKey`, and `isDisabled`', () => {
  const selectedItems = [0, 1]
  const pokemon = [
    { value: 'Piglet', id: 23 },
    { value: 'Winnie the Pooh', id: 26 },
    { value: 'pikachu', id: 24 },
  ]
  const vm = shallow({
    render(h) {
      return (
        <MultiSelect displayKey="value" selectedIdx={selectedItems} options={pokemon} isDisabled />
      )
    }
  })
  expect(vm.displayIdx).toEqual([0, 1, 2])
  expect(vm.labels).toEqual([
    { value: 'Piglet', id: 23 },
    { value: 'Winnie the Pooh', id: 26 },
  ])
  $(vm.$el.children[0]).trigger('click')
  expect(vm.disable).toBe(true)
  expect(vm.opened).toBe(false)
})

it('test <MultiSelect /> dynamic change props `selectedIdx`, `isOpened`, `isDisabled` and `loading`', async() => {
  let vm
  const pokemon = [
    { value: 'Piglet', id: 23 },
    { value: 'Winnie the Pooh', id: 26 },
    { value: 'pikachu', id: 24 },
  ]
  await new Promise((done) => {
    vm = shallow({
      data() {
        return {
          selectedItems: [0, 1],
          open: false,
          disable: true,
          loading: true,
        }
      },
      mounted() {
        this.selectedItems = [2]
        this.open = true
        this.disable = false
        this.loading = false
        this.$nextTick(done)
      },
      render(h) {
        return (
          <MultiSelect displayKey="value"
                       selectedIdx={this.selectedItems}
                       options={pokemon}
                       isOpened={this.open}
                       isDisabled={this.disable}
                       loading={this.loading} />
        )
      }
    })
  })
  expect(vm.displayIdx).toEqual([0, 1, 2])
  expect(vm.labels).toEqual([
    { value: 'pikachu', id: 24 }
  ])
  expect(vm.opened).toBe(true)
  expect(vm.disable).toBe(false)
  expect(vm.loading).toBe(false)
})

it('test <MultiSelect /> search feature', async() => {
  let vm
  const selectedItems = [0, 1]
  const pokemon = [
    { value: 'Piglet', id: 23 },
    { value: 'Winnie the Pooh', id: 26 },
    { value: 'raticate', id: 18 },
  ]
  await new Promise((done) => {
    vm = shallow({
      render(h) {
        return (
          <MultiSelect displayKey="value" selectedIdx={selectedItems} options={pokemon} />
        )
      }
    })
    //toggleMenu
    $(vm.$el.children[0]).trigger('click')
    //input
    $(vm.$el.children[0].children[1]).val('ca')
    //trigger keydown ENTER
    vm.handleInput()
    vm.$nextTick(done)
  })
  expect(vm.displayIdx).toEqual([2])
})

it('test <MultiSelect /> case insensitive search', async() => {
  let vm
  const selectedItems = [0, 1]
  const pokemon = [
    { value: 'Caterpie', id: 23 },
    { value: 'raticate', id: 26 },
    { value: 'Raticate', id: 18 },
  ]
  await new Promise((done) => {
    vm = shallow({
      render(h) {
        return (
          <MultiSelect displayKey="value" selectedIdx={selectedItems} options={pokemon} caseInsensitive />
        )
      }
    })
    //toggleMenu
    $(vm.$el.children[0]).trigger('click')
    //input
    $(vm.$el.children[0].children[1]).val('ra')
    //trigger keydown ENTER
    vm.handleInput()
    vm.$nextTick(done)
  })
  expect(vm.displayIdx).toEqual([1, 2])
})

it('test <MultiSelect /> select and unselect feature', async() => {
  let vm
  const selectedItems = [0, 1]
  const pokemon = [
    { value: 'Piglet', id: 23 },
    { title: 'Raticate', value: 'raticate', id: 18 },
    { value: 'pikachu', id: 24 },
  ]
  await new Promise((done) => {
    vm = shallow({
      render(h) {
        return (
          <MultiSelect displayKey="value" selectedIdx={selectedItems} options={pokemon} />
        )
      }
    })
    vm.$nextTick(done)
  })
  $(vm.$el).find(`[data-role="select-option"]`).eq(1).trigger('click')
  $(vm.$el).find(`[data-role="select-option"]`).eq(2).trigger('click')
  expect(vm.selectedIdx).toEqual([0, 2])
})

it('test <MultiSelect /> mouse event', async() => {
  let vm
  const selectedItems = [0, 1]
  const pokemon = [
    { value: 'Piglet', id: 23 },
    { title: 'Raticate', value: 'raticate', id: 18 },
    { value: 'pikachu', id: 24 },
  ]
  await new Promise((done) => {
    vm = shallow({
      render(h) {
        return (
          <MultiSelect displayKey="value" selectedIdx={selectedItems} options={pokemon} />
        )
      }
    })
    vm.$nextTick(done)
  })
  $(vm.$el.children[1]).trigger('mouseenter')
  expect(vm.optionsHovered).toBe(true)
  $(vm.$el.children[1]).trigger('mouseleave')
  expect(vm.optionsHovered).toBe(false)
  $(vm.$el.children[1].children[1]).trigger('mouseover')
  expect(vm.optionsHovered).toBe(true)
})

it('test <MultiSelect /> keyboard event', async() => {
  let vm
  const selectedItems = [0, 1]
  const pokemon = [
    { value: 'Piglet', id: 23 },
    { title: 'Raticate', value: 'raticate', id: 18 },
    { value: 'pikachu', id: 24 },
  ]
  await new Promise((done) => {
    vm = shallow({
      render(h) {
        return (
          <MultiSelect displayKey="value" selectedIdx={selectedItems} options={pokemon} />
        )
      }
    })
    vm.$nextTick(done)
  })

  const key40 = new window.KeyboardEvent('keydown', { keyCode: 40, which: 40 })
  const key38 = new window.KeyboardEvent('keydown', { keyCode: 38, which: 38 })
  const key13 = new window.KeyboardEvent('keydown', { keyCode: 13, which: 13 })

  await new Promise((done) => {
    $(vm.$el.children[0].children[1]).trigger('keydown')
    vm.$el.children[0].children[1].dispatchEvent(key40)
    vm.$nextTick(done)
  })

  expect(vm.optionsHovered).toBe(true)
  expect(vm.focusedIdx).toBe(0)
  // $(vm.$el.children[1].children[0]).trigger('keydown')
  vm.$el.children[1].children[0].dispatchEvent(key40)

  //not finished
})

it('test <MultiSelect /> delete Label feature', async() => {
  let vm
  const selectedItems = [0, 1]
  const pokemon = [
    { value: 'Piglet', id: 23 },
    { title: 'Raticate', value: 'raticate', id: 18 },
    { value: 'pikachu', id: 24 },
  ]
  await new Promise((done) => {
    vm = shallow({
      render(h) {
        return (
          <MultiSelect displayKey="value" selectedIdx={selectedItems} options={pokemon} />
        )
      }
    })
    vm.$nextTick(done)
  })
  $(vm.$el.children[0].children[0].children[0]).trigger('click')
  expect(vm.selectedIdx).toEqual([1])
})
<commit_msg>[MultiSelect] finish keyboard event test<commit_after>import MultiSelect from '../'

it('test <MultiSelect /> with props `options`, `selectedIdx`, `displayKey`, and `isDisabled`', () => {
  const selectedItems = [0, 1]
  const pokemon = [
    { value: 'Piglet', id: 23 },
    { value: 'Winnie the Pooh', id: 26 },
    { value: 'pikachu', id: 24 },
  ]
  const vm = shallow({
    render(h) {
      return (
        <MultiSelect displayKey="value" selectedIdx={selectedItems} options={pokemon} isDisabled />
      )
    }
  })
  expect(vm.displayIdx).toEqual([0, 1, 2])
  expect(vm.labels).toEqual([
    { value: 'Piglet', id: 23 },
    { value: 'Winnie the Pooh', id: 26 },
  ])
  $(vm.$el.children[0]).trigger('click')
  expect(vm.disable).toBe(true)
  expect(vm.opened).toBe(false)
})

it('test <MultiSelect /> dynamic change props `selectedIdx`, `isOpened`, `isDisabled` and `loading`', async() => {
  let vm
  const pokemon = [
    { value: 'Piglet', id: 23 },
    { value: 'Winnie the Pooh', id: 26 },
    { value: 'pikachu', id: 24 },
  ]
  await new Promise((done) => {
    vm = shallow({
      data() {
        return {
          selectedItems: [0, 1],
          open: false,
          disable: true,
          loading: true,
        }
      },
      mounted() {
        this.selectedItems = [2]
        this.open = true
        this.disable = false
        this.loading = false
        this.$nextTick(done)
      },
      render(h) {
        return (
          <MultiSelect displayKey="value"
                       selectedIdx={this.selectedItems}
                       options={pokemon}
                       isOpened={this.open}
                       isDisabled={this.disable}
                       loading={this.loading} />
        )
      }
    })
  })
  expect(vm.displayIdx).toEqual([0, 1, 2])
  expect(vm.labels).toEqual([
    { value: 'pikachu', id: 24 }
  ])
  expect(vm.opened).toBe(true)
  expect(vm.disable).toBe(false)
  expect(vm.loading).toBe(false)
})

it('test <MultiSelect /> search feature', async() => {
  let vm
  const selectedItems = [0, 1]
  const pokemon = [
    { value: 'Piglet', id: 23 },
    { value: 'Winnie the Pooh', id: 26 },
    { value: 'raticate', id: 18 },
  ]
  await new Promise((done) => {
    vm = shallow({
      render(h) {
        return (
          <MultiSelect displayKey="value" selectedIdx={selectedItems} options={pokemon} />
        )
      }
    })
    //toggleMenu
    $(vm.$el.children[0]).trigger('click')
    //input
    $(vm.$el.children[0].children[1]).val('ca')
    //trigger keydown ENTER
    vm.handleInput()
    vm.$nextTick(done)
  })
  expect(vm.displayIdx).toEqual([2])
})

it('test <MultiSelect /> case insensitive search', async() => {
  let vm
  const selectedItems = [0, 1]
  const pokemon = [
    { value: 'Caterpie', id: 23 },
    { value: 'raticate', id: 26 },
    { value: 'Raticate', id: 18 },
  ]
  await new Promise((done) => {
    vm = shallow({
      render(h) {
        return (
          <MultiSelect displayKey="value" selectedIdx={selectedItems} options={pokemon} caseInsensitive />
        )
      }
    })
    //toggleMenu
    $(vm.$el.children[0]).trigger('click')
    //input
    $(vm.$el.children[0].children[1]).val('ra')
    //trigger keydown ENTER
    vm.handleInput()
    vm.$nextTick(done)
  })
  expect(vm.displayIdx).toEqual([1, 2])
})

it('test <MultiSelect /> select and unselect feature', async() => {
  let vm
  const selectedItems = [0, 1]
  const pokemon = [
    { value: 'Piglet', id: 23 },
    { title: 'Raticate', value: 'raticate', id: 18 },
    { value: 'pikachu', id: 24 },
  ]
  await new Promise((done) => {
    vm = shallow({
      render(h) {
        return (
          <MultiSelect displayKey="value" selectedIdx={selectedItems} options={pokemon} />
        )
      }
    })
    vm.$nextTick(done)
  })
  $(vm.$el).find(`[data-role="select-option"]`).eq(1).trigger('click')
  $(vm.$el).find(`[data-role="select-option"]`).eq(2).trigger('click')
  expect(vm.selectedIdx).toEqual([0, 2])
})

it('test <MultiSelect /> mouse event', async() => {
  let vm
  const selectedItems = [0, 1]
  const pokemon = [
    { value: 'Piglet', id: 23 },
    { title: 'Raticate', value: 'raticate', id: 18 },
    { value: 'pikachu', id: 24 },
  ]
  await new Promise((done) => {
    vm = shallow({
      render(h) {
        return (
          <MultiSelect displayKey="value" selectedIdx={selectedItems} options={pokemon} />
        )
      }
    })
    vm.$nextTick(done)
  })
  $(vm.$el.children[1]).trigger('mouseenter')
  expect(vm.optionsHovered).toBe(true)
  $(vm.$el.children[1]).trigger('mouseleave')
  expect(vm.optionsHovered).toBe(false)
  $(vm.$el.children[1].children[1]).trigger('mouseover')
  expect(vm.optionsHovered).toBe(true)
})

it('test <MultiSelect /> keyboard event', async() => {
  let vm
  const selectedItems = [1]
  const pokemon = [
    { value: 'Piglet', id: 23 },
    { title: 'Raticate', value: 'raticate', id: 18 },
    { value: 'pikachu', id: 24 },
  ]
  await new Promise((done) => {
    vm = shallow({
      render(h) {
        return (
          <MultiSelect displayKey="value" selectedIdx={selectedItems} options={pokemon} />
        )
      }
    })
    vm.$nextTick(done)
  })

  const key40 = new window.KeyboardEvent('keydown', { keyCode: 40, which: 40 })
  const key38 = new window.KeyboardEvent('keydown', { keyCode: 38, which: 38 })
  const key13 = new window.KeyboardEvent('keydown', { keyCode: 13, which: 13 })

  await new Promise((done) => {
    vm.$el.children[0].children[1].dispatchEvent(key40)
    vm.$nextTick(done)
  })

  expect(vm.optionsHovered).toBe(true)
  expect(vm.focusedIdx).toBe(0)

  await new Promise((done) => {
    vm.$el.children[0].children[1].dispatchEvent(key40)
    vm.$nextTick(done)
  })

  expect(vm.optionsHovered).toBe(true)
  expect(vm.focusedIdx).toBe(1)

  await new Promise((done) => { //unselect
    vm.$el.children[0].children[1].dispatchEvent(key13)
    vm.$nextTick(done)
  })

  expect(vm.selectedIdx).toEqual([])

  await new Promise((done) => {
    vm.$el.children[0].children[1].dispatchEvent(key38)
    vm.$nextTick(done)
  })

  expect(vm.optionsHovered).toBe(true)
  expect(vm.focusedIdx).toBe(0)

  await new Promise((done) => { //select
    vm.$el.children[0].children[1].dispatchEvent(key13)
    vm.$nextTick(done)
  })

  expect(vm.selectedIdx).toEqual([0])
})

it('test <MultiSelect /> delete Label feature', async() => {
  let vm
  const selectedItems = [0, 1]
  const pokemon = [
    { value: 'Piglet', id: 23 },
    { title: 'Raticate', value: 'raticate', id: 18 },
    { value: 'pikachu', id: 24 },
  ]
  await new Promise((done) => {
    vm = shallow({
      render(h) {
        return (
          <MultiSelect displayKey="value" selectedIdx={selectedItems} options={pokemon} />
        )
      }
    })
    vm.$nextTick(done)
  })
  $(vm.$el.children[0].children[0].children[0]).trigger('click')
  expect(vm.selectedIdx).toEqual([1])
})
<|endoftext|>