diff options
113 files changed, 800 insertions, 424 deletions
| @@ -114,7 +114,7 @@ gem 'sequel'  gem 'draper' -gem 'enumerize', '~> 0.10.0' +gem 'enumerize', '~> 2.1.2'  gem 'deep_cloneable', '~> 2.0.0'  gem 'acts-as-taggable-on', '~> 4.0.0' diff --git a/Gemfile.lock b/Gemfile.lock index 1d05e0540..2c04def92 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -209,7 +209,7 @@ GEM      email_spec (1.6.0)        launchy (~> 2.1)        mail (~> 2.2) -    enumerize (0.10.1) +    enumerize (2.1.2)        activesupport (>= 3.2)      erubis (2.7.0)      execjs (2.7.0) @@ -590,7 +590,7 @@ DEPENDENCIES    devise_invitable    draper    email_spec -  enumerize (~> 0.10.0) +  enumerize (~> 2.1.2)    fabrication (~> 2.14.1)    factory_girl_rails (~> 4.0)    faker diff --git a/app/assets/javascripts/es6_browserified/helpers/clone.js b/app/assets/javascripts/es6_browserified/helpers/clone.js new file mode 100644 index 000000000..c3b627858 --- /dev/null +++ b/app/assets/javascripts/es6_browserified/helpers/clone.js @@ -0,0 +1,14 @@ +const _ = require("lodash") + +/* This function helps having a bit more security when we pass data from the backend to the React parts +  It clones the obj (window variable) and then conditionnaly delete the window variable +*/ + +const clone = (window, key, deletable = false) => { +  let obj = _.cloneDeep(window[key]) +   +  if (deletable) delete window[key] +  return obj +} + +module.exports = clone
\ No newline at end of file diff --git a/app/assets/javascripts/es6_browserified/itineraries/components/App.js b/app/assets/javascripts/es6_browserified/itineraries/components/App.js index e662d140c..f4cc5e4a6 100644 --- a/app/assets/javascripts/es6_browserified/itineraries/components/App.js +++ b/app/assets/javascripts/es6_browserified/itineraries/components/App.js @@ -1,12 +1,28 @@  var React = require('react') +var { Component, PropTypes } = require('react')  var AddStopPoint = require('../containers/AddStopPoint')  var VisibleStopPoints = require('../containers/VisibleStopPoints') +const clone = require('../../helpers/clone') +const I18n = clone(window , "I18n", true) -const App = () => ( -  <div> -    <VisibleStopPoints /> -    <AddStopPoint /> -  </div> -) +class App extends Component { + +  getChildContext() { +    return { I18n } +  } + +  render() { +    return ( +      <div> +        <VisibleStopPoints /> +        <AddStopPoint /> +      </div> +    )   +  }  +} + +App.childContextTypes = { +  I18n: PropTypes.object +}  module.exports = App diff --git a/app/assets/javascripts/es6_browserified/itineraries/components/BSelect2.js b/app/assets/javascripts/es6_browserified/itineraries/components/BSelect2.js index 64c6d3ac7..9a82b7925 100644 --- a/app/assets/javascripts/es6_browserified/itineraries/components/BSelect2.js +++ b/app/assets/javascripts/es6_browserified/itineraries/components/BSelect2.js @@ -1,6 +1,6 @@  var _ = require('lodash')  var React = require('react') -var PropTypes = require('react').PropTypes +var { Component, PropTypes } = require('react')  var Select2 = require('react-select2') @@ -9,9 +9,9 @@ var origin = window.location.origin  var path = window.location.pathname.split('/', 3).join('/') -class BSelect3 extends React.Component{ -  constructor(props) { -    super(props) +class BSelect3 extends Component{ +  constructor(props, context) { +    super(props, context)    }    onChange(e) {      this.props.onChange(this.props.index, { @@ -73,7 +73,7 @@ class BSelect3 extends React.Component{    }  } -class BSelect2 extends React.Component{ +class BSelect2 extends Component{    componentDidMount() {      this.refs.newSelect.el.select2('open')    } @@ -85,7 +85,7 @@ class BSelect2 extends React.Component{          onSelect={ this.props.onSelect }          ref='newSelect'          options={{ -          placeholder: 'Sélectionnez un arrêt existant...', +          placeholder: this.context.I18n.routes.edit.select2.placeholder,            allowClear: true,            language: 'fr', /* Doesn't seem to work... :( */            theme: 'bootstrap', @@ -121,4 +121,8 @@ class BSelect2 extends React.Component{    }  } +BSelect2.contextTypes = { +  I18n: PropTypes.object +} +  module.exports = BSelect3 diff --git a/app/assets/javascripts/es6_browserified/itineraries/components/OlMap.js b/app/assets/javascripts/es6_browserified/itineraries/components/OlMap.js index b9e106c1a..937871346 100644 --- a/app/assets/javascripts/es6_browserified/itineraries/components/OlMap.js +++ b/app/assets/javascripts/es6_browserified/itineraries/components/OlMap.js @@ -1,11 +1,10 @@  var _ = require('lodash')  var React = require('react') -var Component = require('react').Component -var PropTypes = require('react').PropTypes +var { Component, PropTypes } = require('react')  class OlMap extends Component{ -  constructor(props){ -    super(props) +  constructor(props, context){ +    super(props, context)    }    fetchApiURL(id){ @@ -116,40 +115,40 @@ class OlMap extends Component{                <strong>{this.props.value.olMap.json.name}</strong>              </p>              <p> -              <strong>Type d'arrêt : </strong> +              <strong>{this.context.I18n.routes.edit.stop_point_type} : </strong>                {this.props.value.olMap.json.area_type}              </p>              <p> -              <strong>Nom court : </strong> +              <strong>{this.context.I18n.routes.edit.short_name} : </strong>                {this.props.value.olMap.json.short_name}              </p>              <p> -              <strong>ID Reflex : </strong> +              <strong>{this.context.I18n.id_reflex} : </strong>                {this.props.value.olMap.json.user_objectid}              </p> -            <p><strong>Coordonnées : </strong></p> +            <p><strong>{this.context.I18n.routes.edit.map.coordinates} : </strong></p>              <p style={{paddingLeft: 10, marginTop: 0}}> -              <em>Proj.: </em>WSG84<br/> -              <em>Lat.: </em>{this.props.value.olMap.json.latitude} <br/> -              <em>Lon.: </em>{this.props.value.olMap.json.longitude} +              <em>{this.context.I18n.routes.edit.map.proj}.: </em>WSG84<br/> +              <em>{this.context.I18n.routes.edit.map.lat}.: </em>{this.props.value.olMap.json.latitude} <br/> +              <em>{this.context.I18n.routes.edit.map.lon}.: </em>{this.props.value.olMap.json.longitude}              </p>              <p> -              <strong>Code Postal : </strong> +              <strong>{this.context.I18n.routes.edit.map.postal_code} : </strong>                {this.props.value.olMap.json.zip_code}              </p>              <p> -              <strong>Commune : </strong> +              <strong>{this.context.I18n.routes.edit.map.city} : </strong>                {this.props.value.olMap.json.city_name}              </p>              <p> -              <strong>Commentaire : </strong> +              <strong>{this.context.I18n.routes.edit.map.comment} : </strong>                {this.props.value.olMap.json.comment}              </p>              {(this.props.value.stoparea_id != this.props.value.olMap.json.stoparea_id) &&(                <div className='btn btn-outline-primary btn-sm'                  onClick= {() => {this.props.onUpdateViaOlMap(this.props.index, this.props.value.olMap.json)}} -              >Sélectionner</div> +              >{this.context.I18n.actions.select}</div>              )}            </div>              <div className='map_content'> @@ -163,7 +162,11 @@ class OlMap extends Component{    }  } -OlMap.propTypes = { +OlMap.PropTypes = { +} + +OlMap.contextTypes = { +  I18n: PropTypes.object  }  module.exports = OlMap diff --git a/app/assets/javascripts/es6_browserified/itineraries/components/StopPoint.js b/app/assets/javascripts/es6_browserified/itineraries/components/StopPoint.js index 48f77b8e9..c3996f5b3 100644 --- a/app/assets/javascripts/es6_browserified/itineraries/components/StopPoint.js +++ b/app/assets/javascripts/es6_browserified/itineraries/components/StopPoint.js @@ -3,7 +3,7 @@ var PropTypes = require('react').PropTypes  var BSelect2 = require('./BSelect2')  var OlMap = require('./OlMap') -const StopPoint = (props) => { +const StopPoint = (props, {I18n}) => {    return (      <div className='nested-fields'>        <div className='wrapper'> @@ -17,15 +17,15 @@ const StopPoint = (props) => {          <div>            <select className='form-control' value={props.value.for_boarding} id="for_boarding" onChange={props.onSelectChange}> -            <option value="normal">Montée autorisée</option> -            <option value="forbidden">Montée interdite</option> +            <option value="normal">{I18n.routes.edit.stop_point.boarding.normal}</option> +            <option value="forbidden">{I18n.routes.edit.stop_point.boarding.forbidden}</option>            </select>          </div>          <div>            <select className='form-control' value={props.value.for_alighting} id="for_alighting" onChange={props.onSelectChange}> -            <option value="normal">Descente autorisée</option> -            <option value="forbidden">Descente interdite</option> +            <option value="normal">{I18n.routes.edit.stop_point.alighting.normal}</option> +            <option value="forbidden">{I18n.routes.edit.stop_point.alighting.forbidden}</option>            </select>          </div> @@ -90,4 +90,8 @@ StopPoint.propTypes = {    value: PropTypes.object  } +StopPoint.contextTypes = { +  I18n: PropTypes.object +} +  module.exports = StopPoint diff --git a/app/assets/javascripts/es6_browserified/itineraries/components/StopPointList.js b/app/assets/javascripts/es6_browserified/itineraries/components/StopPointList.js index 77077dbd8..37a480fca 100644 --- a/app/assets/javascripts/es6_browserified/itineraries/components/StopPointList.js +++ b/app/assets/javascripts/es6_browserified/itineraries/components/StopPointList.js @@ -2,29 +2,29 @@ var React = require('react')  var PropTypes = require('react').PropTypes  var StopPoint = require('./StopPoint') -const StopPointList = ({ stopPoints, onDeleteClick, onMoveUpClick, onMoveDownClick, onChange, onSelectChange, onToggleMap, onToggleEdit, onSelectMarker, onUnselectMarker, onUpdateViaOlMap }) => { +const StopPointList = ({ stopPoints, onDeleteClick, onMoveUpClick, onMoveDownClick, onChange, onSelectChange, onToggleMap, onToggleEdit, onSelectMarker, onUnselectMarker, onUpdateViaOlMap }, {I18n}) => {    return (      <div className='subform'>        <div className='nested-head'>          <div className="wrapper">            <div style={{width: 100}}>              <div className="form-group"> -              <label className="control-label">ID Reflex</label> +              <label className="control-label">{I18n.reflex_id}</label>              </div>            </div>            <div>              <div className="form-group"> -              <label className="control-label">Arrêt</label> +              <label className="control-label">{I18n.simple_form.labels.stop_point.name}</label>              </div>            </div>            <div>              <div className="form-group"> -              <label className="control-label">Montée</label> +              <label className="control-label">{I18n.simple_form.labels.stop_point.for_boarding}</label>              </div>            </div>            <div>              <div className="form-group"> -              <label className="control-label">Descente</label> +              <label className="control-label">{I18n.simple_form.labels.stop_point.for_alighting}</label>              </div>            </div>            <div className='actions-5'></div> @@ -65,4 +65,8 @@ StopPointList.propTypes = {    onUnselectMarker : PropTypes.func.isRequired  } +StopPointList.contextTypes = { +  I18n: PropTypes.object +} +  module.exports = StopPointList diff --git a/app/assets/javascripts/es6_browserified/itineraries/index.js b/app/assets/javascripts/es6_browserified/itineraries/index.js index bb06126f7..13d89bec5 100644 --- a/app/assets/javascripts/es6_browserified/itineraries/index.js +++ b/app/assets/javascripts/es6_browserified/itineraries/index.js @@ -5,7 +5,9 @@ var createStore = require('redux').createStore  var reducers = require('./reducers')  var App = require('./components/App')  var { handleForm, handleStopPoints } = require('./form_helper') -let datas = JSON.parse(decodeURIComponent(window.itinerary_stop)) +let clone = require('../helpers/clone') +let datas = clone(window, "itinerary_stop", true) +datas = JSON.parse(decodeURIComponent(datas))  // logger, DO NOT REMOVE  // var applyMiddleware = require('redux').applyMiddleware diff --git a/app/assets/javascripts/es6_browserified/itineraries/show.js b/app/assets/javascripts/es6_browserified/itineraries/show.js index 79a11701f..e88469900 100644 --- a/app/assets/javascripts/es6_browserified/itineraries/show.js +++ b/app/assets/javascripts/es6_browserified/itineraries/show.js @@ -1,4 +1,7 @@ +const clone = require('../helpers/clone') +let route = clone(window, "route", true)  route = JSON.parse(decodeURIComponent(route)) +  const geoColPts = []  const geoColLns= []  const geoColEdges = [ diff --git a/app/assets/javascripts/es6_browserified/time_tables/actions/index.js b/app/assets/javascripts/es6_browserified/time_tables/actions/index.js index ba5d91568..a421a8ed6 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/actions/index.js +++ b/app/assets/javascripts/es6_browserified/time_tables/actions/index.js @@ -1,19 +1,21 @@  const _ = require('lodash') +const clone = require('../../helpers/clone') +const I18n = clone(window, "I18n")  const actions = { +  weekDays: (index) => { +    return _.range(1, 8).map(n => I18n.time_tables.edit.metas.days[n]) +  },    strToArrayDayTypes: (str) =>{ -    let weekDays = ['Di', 'Lu', 'Ma', 'Me', 'Je', 'Ve', 'Sa'] -    return weekDays.map((day, i) => str.indexOf(day) !== -1) +    return actions.weekDays().map(day => str.indexOf(day) !== -1)    }, -  arrayToStrDayTypes: (arr) => { -    let weekDays = ['Di', 'Lu', 'Ma', 'Me', 'Je', 'Ve', 'Sa'] -    let str = [] -    arr.map((dayActive, i) => { -      if(dayActive){ -        str.push(weekDays[i]) -      } -    }) -    return str.join(',') +  arrayToStrDayTypes: (dayTypes) => { +    let newDayTypes = dayTypes.reduce((arr, dayActive, i) => { +      if (dayActive) arr.push(actions.weekDays()[i]) +      return arr +    }, []) + +    return newDayTypes.join(',')    },    fetchingApi: () =>({      type: 'FETCH_API' @@ -149,8 +151,8 @@ const actions = {      type : 'CLOSE_MODAL'    }),    monthName(strDate) { -    let monthList = ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"] -    var date = new Date(strDate) +    let monthList = _.range(1,13).map(n => I18n.calendars.months[n]) +    let date = new Date(strDate)      return monthList[date.getMonth()]    },    getHumanDate(strDate, mLimit) { @@ -219,7 +221,7 @@ const actions = {        let period = periods[i]        if (index !== i && !period.deleted) {          if (new Date(period.period_start) <= end && new Date(period.period_end) >= start)  { -          error = 'Les périodes ne peuvent pas se chevaucher' +          error = I18n.time_tables.edit.error_submit.periods_overlaps            break          }        } @@ -233,7 +235,7 @@ const actions = {      for (let day of in_days) {        if (start <= new Date(day.date) && end >= new Date(day.date)) { -        error = 'Une période ne peut chevaucher une date dans un calendrier' +        error = I18n.time_tables.edit.error_submit.dates_overlaps          break        }      } @@ -241,7 +243,6 @@ const actions = {    },    fetchTimeTables: (dispatch, nextPage) => {      let urlJSON = window.location.pathname.split('/', 5).join('/') -    // console.log(nextPage)      if(nextPage) {        urlJSON += "/month.json?date=" + nextPage      }else{ @@ -310,9 +311,9 @@ const actions = {    errorModalMessage: (errorKey) => {      switch (errorKey) {        case "withoutPeriodsWithDaysTypes": -        return window.I18n.fr.time_tables.edit.error_modal.withoutPeriodsWithDaysTypes +        return I18n.time_tables.edit.error_modal.withoutPeriodsWithDaysTypes        case "withPeriodsWithoutDayTypes": -        return window.I18n.fr.time_tables.edit.error_modal.withPeriodsWithoutDayTypes +        return I18n.time_tables.edit.error_modal.withPeriodsWithoutDayTypes        default:          return errorKey diff --git a/app/assets/javascripts/es6_browserified/time_tables/components/ConfirmModal.js b/app/assets/javascripts/es6_browserified/time_tables/components/ConfirmModal.js index 40ae0eccf..674a03296 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/components/ConfirmModal.js +++ b/app/assets/javascripts/es6_browserified/time_tables/components/ConfirmModal.js @@ -1,18 +1,17 @@  var React = require('react') -var Component = require('react').Component -var PropTypes = require('react').PropTypes +var { PropTypes } = require('react') -const ConfirmModal = ({dispatch, modal, onModalAccept, onModalCancel, timetable, metas}) => ( +const ConfirmModal = ({dispatch, modal, onModalAccept, onModalCancel, timetable, metas}, {I18n}) => (    <div className={ 'modal fade ' + ((modal.type == 'confirm') ? 'in' : '') } id='ConfirmModal'>      <div className='modal-container'>        <div className='modal-dialog'>          <div className='modal-content'>            <div className='modal-header'> -            <h4 className='modal-title'>Confirmation</h4> +            <h4 className='modal-title'>{I18n.time_tables.edit.confirm_modal.title}</h4>            </div>            <div className='modal-body'>              <div className='mt-md mb-md'> -              <p>Vous vous apprêtez à changer de page. Voulez-vous valider vos modifications avant cela ?</p> +              <p>{I18n.time_tables.edit.confirm_modal.message}</p>              </div>            </div>            <div className='modal-footer'> @@ -22,7 +21,7 @@ const ConfirmModal = ({dispatch, modal, onModalAccept, onModalCancel, timetable,                type='button'                onClick= {() => {onModalCancel(modal.confirmModal.callback)}}                > -              Ne pas valider +              {I18n.cancel}              </button>              <button                className='btn btn-primary' @@ -30,7 +29,7 @@ const ConfirmModal = ({dispatch, modal, onModalAccept, onModalCancel, timetable,                type='button'                onClick = {() => {onModalAccept(modal.confirmModal.callback, timetable, metas)}}                > -              Valider +              {I18n.actions.submit}              </button>            </div>          </div> @@ -45,4 +44,8 @@ ConfirmModal.propTypes = {    onModalCancel: PropTypes.func.isRequired  } +ConfirmModal.contextTypes = { +  I18n: PropTypes.object +} +  module.exports = ConfirmModal diff --git a/app/assets/javascripts/es6_browserified/time_tables/components/ErrorModal.js b/app/assets/javascripts/es6_browserified/time_tables/components/ErrorModal.js index 4e8f7e363..2597a4870 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/components/ErrorModal.js +++ b/app/assets/javascripts/es6_browserified/time_tables/components/ErrorModal.js @@ -1,15 +1,14 @@  var React = require('react') -var Component = require('react').Component -var PropTypes = require('react').PropTypes -var errorModalMessage = require('../actions').errorModalMessage +var { PropTypes } = require('react') +var { errorModalMessage } = require('../actions') -const ErrorModal = ({dispatch, modal, I18n, onModalClose}) => ( +const ErrorModal = ({dispatch, modal, onModalClose}, {I18n}) => (    <div className={ 'modal fade ' + ((modal.type == 'error') ? 'in' : '') } id='ErrorModal'>      <div className='modal-container'>        <div className='modal-dialog'>          <div className='modal-content'>            <div className='modal-header'> -            <h4 className='modal-title'>{window.I18n.fr.time_tables.edit.error_modal.title}</h4> +            <h4 className='modal-title'>{I18n.time_tables.edit.error_modal.title}</h4>            </div>            <div className='modal-body'>              <div className='mt-md mb-md'> @@ -23,7 +22,7 @@ const ErrorModal = ({dispatch, modal, I18n, onModalClose}) => (                type='button'                onClick= {() => {onModalClose()}}                > -              Retour +              {I18n.back}              </button>            </div>          </div> @@ -37,4 +36,8 @@ ErrorModal.propTypes = {    onModalClose: PropTypes.func.isRequired  } +ErrorModal.contextTypes = { +  I18n: PropTypes.object +} +  module.exports = ErrorModal diff --git a/app/assets/javascripts/es6_browserified/time_tables/components/Metas.js b/app/assets/javascripts/es6_browserified/time_tables/components/Metas.js index a0fac84f3..26a96e4a6 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/components/Metas.js +++ b/app/assets/javascripts/es6_browserified/time_tables/components/Metas.js @@ -1,9 +1,9 @@  var React = require('react') -var PropTypes = require('react').PropTypes -let weekDays = ['D', 'L', 'Ma', 'Me', 'J', 'V', 'S'] +var  { PropTypes }  = require('react') +const { weekDays } = require('../actions')  var TagsSelect2 = require('./TagsSelect2') -const Metas = ({metas, onUpdateDayTypes, onUpdateComment, onUpdateColor, onSelect2Tags, onUnselect2Tags}) => { +const Metas = ({metas, onUpdateDayTypes, onUpdateComment, onUpdateColor, onSelect2Tags, onUnselect2Tags}, {I18n}) => {    let colorList = ["", "#9B9B9B", "#FFA070", "#C67300", "#7F551B", "#41CCE3", "#09B09C", "#3655D7",   "#6321A0", "#E796C6", "#DD2DAA"]    return (      <div className='form-horizontal'> @@ -12,7 +12,7 @@ const Metas = ({metas, onUpdateDayTypes, onUpdateComment, onUpdateColor, onSelec            {/* comment (name) */}            <div className="form-group">              <label htmlFor="" className="control-label col-sm-4 required"> -              Nom <abbr title="Champ requis">*</abbr> +              {I18n.time_tables.edit.metas.name} <abbr title="">*</abbr>              </label>              <div className="col-sm-8">                <input @@ -27,7 +27,7 @@ const Metas = ({metas, onUpdateDayTypes, onUpdateComment, onUpdateColor, onSelec            {/* color */}            <div className="form-group"> -            <label htmlFor="" className="control-label col-sm-4">Couleur associée</label> +            <label htmlFor="" className="control-label col-sm-4">{I18n.activerecord.attributes.time_table.color}</label>              <div className="col-sm-8">                <div className="dropdown color_selector">                  <button @@ -72,7 +72,7 @@ const Metas = ({metas, onUpdateDayTypes, onUpdateComment, onUpdateColor, onSelec            {/* tags */}            <div className="form-group"> -            <label htmlFor="" className="control-label col-sm-4">Etiquettes</label> +            <label htmlFor="" className="control-label col-sm-4">{I18n.activerecord.attributes.time_table.tag_list}</label>              <div className="col-sm-8">                <TagsSelect2                  initialTags={metas.initial_tags} @@ -85,16 +85,16 @@ const Metas = ({metas, onUpdateDayTypes, onUpdateComment, onUpdateColor, onSelec            {/* calendar */}            <div className="form-group"> -            <label htmlFor="" className="control-label col-sm-4">Modèle de calendrier associé</label> +            <label htmlFor="" className="control-label col-sm-4">{I18n.activerecord.attributes.time_table.calendar}</label>              <div className="col-sm-8"> -              <span>{metas.calendar ? metas.calendar.name : 'Aucun'}</span> +              <span>{metas.calendar ? metas.calendar.name : I18n.time_tables.edit.metas.no_calendar}</span>              </div>            </div>            {/* day_types */}            <div className="form-group">              <label htmlFor="" className="control-label col-sm-4"> -              Journées d'applications pour les périodes ci-dessous +              {I18n.time_tables.edit.metas.day_types}              </label>              <div className="col-sm-8">                <div className="form-group labelled-checkbox-group"> @@ -112,7 +112,7 @@ const Metas = ({metas, onUpdateDayTypes, onUpdateComment, onUpdateColor, onSelec                            type="checkbox"                            checked={day ? 'checked' : ''}                            /> -                        <span className='lcbx-group-item-label'>{weekDays[i]}</span> +                        <span className='lcbx-group-item-label'>{weekDays()[i]}</span>                        </label>                      </div>                    </div> @@ -135,4 +135,8 @@ Metas.propTypes = {    onUnselect2Tags: PropTypes.func.isRequired  } +Metas.contextTypes = { +  I18n: PropTypes.object +} +  module.exports = Metas diff --git a/app/assets/javascripts/es6_browserified/time_tables/components/PeriodForm.js b/app/assets/javascripts/es6_browserified/time_tables/components/PeriodForm.js index 3234a3fd7..d494109cc 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/components/PeriodForm.js +++ b/app/assets/javascripts/es6_browserified/time_tables/components/PeriodForm.js @@ -1,5 +1,5 @@  var React = require('react') -var PropTypes = require('react').PropTypes +var { PropTypes } = require('react')  var _ = require('lodash')  let monthsArray = ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'] @@ -32,7 +32,7 @@ const makeYearsOptions = (yearSelected) => {    return arr  } -const PeriodForm = ({modal, timetable, metas, onOpenAddPeriodForm, onClosePeriodForm, onUpdatePeriodForm, onValidatePeriodForm}) => ( +const PeriodForm = ({modal, timetable, metas, onOpenAddPeriodForm, onClosePeriodForm, onUpdatePeriodForm, onValidatePeriodForm}, {I18n}) => (    <div className="container-fluid">      <div className="row">        <div className="col lg-6 col-lg-offset-3"> @@ -44,7 +44,7 @@ const PeriodForm = ({modal, timetable, metas, onOpenAddPeriodForm, onClosePeriod                    <div>                      <div className="form-group">                        <label htmlFor="" className="control-label required"> -                        Début de période +                        {I18n.time_tables.edit.period_form.begin}                          <abbr title="requis">*</abbr>                        </label>                      </div> @@ -52,7 +52,7 @@ const PeriodForm = ({modal, timetable, metas, onOpenAddPeriodForm, onClosePeriod                    <div>                      <div className="form-group">                        <label htmlFor="" className="control-label required"> -                        Fin de période +                      {I18n.time_tables.edit.period_form.end}                          <abbr title="requis">*</abbr>                        </label>                      </div> @@ -103,14 +103,14 @@ const PeriodForm = ({modal, timetable, metas, onOpenAddPeriodForm, onClosePeriod                    className='btn btn-link'                    onClick={onClosePeriodForm}                  > -                  Annuler +                  {I18n.cancel}                  </button>                  <button                    type='button'                    className='btn btn-outline-primary mr-sm'                    onClick={() => onValidatePeriodForm(modal.modalProps, timetable.time_table_periods, metas, _.filter(timetable.time_table_dates, ['in_out', true]))}                  > -                  Valider +                  {I18n.actions.submit}                  </button>                </div>              </div> @@ -122,7 +122,7 @@ const PeriodForm = ({modal, timetable, metas, onOpenAddPeriodForm, onClosePeriod                  className='btn btn-outline-primary'                  onClick={onOpenAddPeriodForm}                  > -                Ajouter une période +                {I18n.time_tables.actions.add_period}                </button>              </div>            } @@ -142,4 +142,8 @@ PeriodForm.propTypes = {    timetable: PropTypes.object.isRequired  } +PeriodForm.contextTypes = { +  I18n: PropTypes.object +} +  module.exports = PeriodForm diff --git a/app/assets/javascripts/es6_browserified/time_tables/components/PeriodManager.js b/app/assets/javascripts/es6_browserified/time_tables/components/PeriodManager.js index cf4cbfb32..704e21331 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/components/PeriodManager.js +++ b/app/assets/javascripts/es6_browserified/time_tables/components/PeriodManager.js @@ -1,11 +1,10 @@  var React = require('react') -var Component = require('react').Component -var PropTypes = require('react').PropTypes +var { Component, PropTypes } = require('react')  var actions = require('../actions')  class PeriodManager extends Component { -  constructor(props) { -    super(props) +  constructor(props, context) { +    super(props, context)    }    toEndPeriod(curr, end) { @@ -82,4 +81,8 @@ PeriodManager.propTypes = {    onOpenEditPeriodForm: PropTypes.func.isRequired  } +PeriodManager.contextTypes = { +  I18n: PropTypes.object +} +  module.exports = PeriodManager diff --git a/app/assets/javascripts/es6_browserified/time_tables/components/TagsSelect2.js b/app/assets/javascripts/es6_browserified/time_tables/components/TagsSelect2.js index a1f41a693..46188cdd1 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/components/TagsSelect2.js +++ b/app/assets/javascripts/es6_browserified/time_tables/components/TagsSelect2.js @@ -9,8 +9,8 @@ var path = window.location.pathname.split('/', 4).join('/')  var _ = require('lodash')  class TagsSelect2 extends React.Component{ -  constructor(props) { -    super(props) +  constructor(props, context) { +    super(props, context)    }    mapKeys(array){ @@ -38,7 +38,7 @@ class TagsSelect2 extends React.Component{            allowClear: true,            theme: 'bootstrap',            width: '100%', -          placeholder: 'Ajoutez ou cherchez une étiquette...', +          placeholder: this.context.I18n.time_tables.edit.select2.tag.placeholder,            ajax: {              url: origin + path + '/tags.json',              dataType: 'json', @@ -74,4 +74,8 @@ const formatRepo = (props) => {    if(props.name) return props.name  } +TagsSelect2.contextTypes = { +  I18n: PropTypes.object +} +  module.exports = TagsSelect2 diff --git a/app/assets/javascripts/es6_browserified/time_tables/components/TimeTableDay.js b/app/assets/javascripts/es6_browserified/time_tables/components/TimeTableDay.js index 71621c874..93a0a90fe 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/components/TimeTableDay.js +++ b/app/assets/javascripts/es6_browserified/time_tables/components/TimeTableDay.js @@ -1,6 +1,5 @@  var React = require('react') -var Component = require('react').Component -var PropTypes = require('react').PropTypes +var { Component, PropTypes } = require('react')  class TimeTableDay extends Component {    constructor(props) { diff --git a/app/assets/javascripts/es6_browserified/time_tables/components/Timetable.js b/app/assets/javascripts/es6_browserified/time_tables/components/Timetable.js index a613549c3..22e971c6b 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/components/Timetable.js +++ b/app/assets/javascripts/es6_browserified/time_tables/components/Timetable.js @@ -1,14 +1,13 @@  var React = require('react') -var Component = require('react').Component -var PropTypes = require('react').PropTypes +var { Component, PropTypes}  = require('react')  var TimeTableDay = require('./TimeTableDay')  var PeriodsInDay = require('./PeriodsInDay')  var ExceptionsInDay = require('./ExceptionsInDay')  var actions = require('../actions')  class Timetable extends Component{ -  constructor(props){ -    super(props) +  constructor(props, context){ +    super(props, context)    }    currentDate(mFirstday, day) { @@ -31,11 +30,11 @@ class Timetable extends Component{          <div className="table table-2entries mb-sm">            <div className="t2e-head w20">              <div className="th"> -              <div className="strong">Synthèse</div> +              <div className="strong">{this.context.I18n.time_tables.synthesis}</div>              </div> -            <div className="td"><span>Journées d'application</span></div> -            <div className="td"><span>Périodes</span></div> -            <div className="td"><span>Exceptions</span></div> +            <div className="td"><span>{this.context.I18n.time_tables.edit.day_types}</span></div> +            <div className="td"><span>{this.context.I18n.time_tables.edit.periods}</span></div> +            <div className="td"><span>{this.context.I18n.time_tables.edit.exceptions}</span></div>            </div>            <div className="t2e-item-list w80">              <div> @@ -111,4 +110,8 @@ Timetable.propTypes = {    onIncludeDateInPeriod: PropTypes.func.isRequired  } +Timetable.contextTypes = { +  I18n: PropTypes.object +} +  module.exports = Timetable diff --git a/app/assets/javascripts/es6_browserified/time_tables/containers/App.js b/app/assets/javascripts/es6_browserified/time_tables/containers/App.js index 02f0ddbd8..f12fb8a71 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/containers/App.js +++ b/app/assets/javascripts/es6_browserified/time_tables/containers/App.js @@ -1,6 +1,6 @@  var React = require('react')  var connect = require('react-redux').connect -var Component = require('react').Component +var { Component, PropTypes} = require('react')  var actions = require('../actions')  var Metas = require('./Metas')  var Timetable = require('./Timetable') @@ -10,11 +10,18 @@ var SaveTimetable = require('./SaveTimetable')  var ConfirmModal = require('./ConfirmModal')  var ErrorModal = require('./ErrorModal') +const clone = require('../../helpers/clone') +const I18n = clone(window, "I18n", true) +  class App extends Component {    componentDidMount(){      this.props.onLoadFirstPage()    } +  getChildContext() { +    return { I18n } +  } +    render(){      return(        <div className='row'> @@ -41,6 +48,10 @@ const mapDispatchToProps = (dispatch) => {    }  } +App.childContextTypes = { +  I18n: PropTypes.object +} +  const timeTableApp = connect(null, mapDispatchToProps)(App)  module.exports = timeTableApp diff --git a/app/assets/javascripts/es6_browserified/time_tables/index.js b/app/assets/javascripts/es6_browserified/time_tables/index.js index a91747991..6c352df6b 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/index.js +++ b/app/assets/javascripts/es6_browserified/time_tables/index.js @@ -5,6 +5,9 @@ var createStore = require('redux').createStore  var timeTablesApp = require('./reducers')  var App = require('./containers/App') +const clone = require('../helpers/clone') +const actionType = clone(window, "actionType", true) +  // logger, DO NOT REMOVE  // var applyMiddleware = require('redux').applyMiddleware  // var createLogger = require('redux-logger') @@ -13,7 +16,7 @@ var App = require('./containers/App')  var initialState = {    status: { -    actionType: window.actionType, +    actionType: actionType,      policy: window.perms,      fetchSuccess: true,      isFetching: false diff --git a/app/assets/javascripts/es6_browserified/time_tables/reducers/timetable.js b/app/assets/javascripts/es6_browserified/time_tables/reducers/timetable.js index edb965065..712808abd 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/reducers/timetable.js +++ b/app/assets/javascripts/es6_browserified/time_tables/reducers/timetable.js @@ -96,9 +96,9 @@ const timetable = (state = {}, action) => {        let newPeriods = JSON.parse(JSON.stringify(action.timeTablePeriods))        if (action.modalProps.index !== false){ -        updatePeriod = newPeriods[action.modalProps.index] -        updatePeriod.period_start = period_start -        updatePeriod.period_end = period_end +        let updatedPeriod = newPeriods[action.modalProps.index] +        updatedPeriod.period_start = period_start +        updatedPeriod.period_end = period_end          newDates = _.reject(state.time_table_dates, d => actions.isInPeriod(newPeriods, d.date) && !d.in_out)        }else{          let newPeriod = { diff --git a/app/controllers/compliance_control_sets_controller.rb b/app/controllers/compliance_control_sets_controller.rb index c6f4288a9..306b2eac7 100644 --- a/app/controllers/compliance_control_sets_controller.rb +++ b/app/controllers/compliance_control_sets_controller.rb @@ -1,10 +1,12 @@  class ComplianceControlSetsController < BreadcrumbController    defaults resource_class: ComplianceControlSet +  before_action :ransack_updated_at_params, only: [:index]    respond_to :html    def index      index! do |format| -      @q_for_form = @compliance_control_sets.ransack(params[:q]) +      scope = ransack_period @compliance_control_sets +      @q_for_form = scope.ransack(params[:q])        format.html {          @compliance_control_sets = decorate_compliance_control_sets(@q_for_form.result)        } @@ -12,11 +14,15 @@ class ComplianceControlSetsController < BreadcrumbController    end    def show -    show! do -      @compliance_control_set = @compliance_control_set.decorate +    show! do |format| +      format.html { +        @compliance_control_set = @compliance_control_set.decorate +        @compliance_controls = decorate_compliance_controls(@compliance_control_set.compliance_controls) +      }      end    end +  private    def decorate_compliance_control_sets(compliance_control_sets)      ModelDecorator.decorate(        compliance_control_sets, @@ -31,6 +37,39 @@ class ComplianceControlSetsController < BreadcrumbController    # end    private +  def decorate_compliance_controls(compliance_controls) +    ModelDecorator.decorate( +      compliance_controls, +      with: ComplianceControlDecorator, +    ) +  end + +  def ransack_updated_at_params +    start_date = [] +    end_date = [] + +    if params[:q] && params[:q][:updated_at] && !params[:q][:updated_at].has_value?(nil) && !params[:q][:updated_at].has_value?("") +      [1, 2, 3].each do |key| +        start_date <<  params[:q][:updated_at]["begin(#{key}i)"].to_i +        end_date <<  params[:q][:updated_at]["end(#{key}i)"].to_i +      end +      params[:q].delete([:updated_at]) +      @begin_range = DateTime.new(*start_date,0,0,0) rescue nil +      @end_range = DateTime.new(*end_date,23,59,59) rescue nil +    end +  end + +  # Fake ransack filter +  def ransack_period scope +    return scope unless !!@begin_range && !!@end_range + +    if @begin_range > @end_range +      flash.now[:error] = t('imports.filters.error_period_filter') +    else +      scope = scope.where_updated_at_between(@begin_range, @end_range) +    end +    scope +  end    def compliance_control_set_params      params.require(:compliance_control_set).permit(:name, :id) diff --git a/app/controllers/compliance_controls_controller.rb b/app/controllers/compliance_controls_controller.rb index dad9b935a..eb1ba68ea 100644 --- a/app/controllers/compliance_controls_controller.rb +++ b/app/controllers/compliance_controls_controller.rb @@ -1,18 +1,11 @@  class ComplianceControlsController < BreadcrumbController -  include PolicyChecker    defaults resource_class: ComplianceControl    belongs_to :compliance_control_set -  def index -    index! do |format| -      format.html { -        @compliance_controls = decorate_compliance_controls(@compliance_controls) -      } -    end -  end - -  def create -    create!(notice: t('notice.compliance_control.created')) +  def new +    @compliance_control_set = parent +    @compliance_control = GenericAttributeControl::MinMax.new +    @compliance_control.build_compliance_control_block    end    def update @@ -20,19 +13,14 @@ class ComplianceControlsController < BreadcrumbController      update!(notice: t('notice.compliance_control.updated')) { path }    end -  def destroy -    destroy!(notice: t('notice.compliance_control.destroyed')) -  end -    private -  def decorate_compliance_controls(compliance_controls) -    ModelDecorator.decorate( -      compliance_controls, -      with: ComplianceControlDecorator, -    ) +  def dynamic_attributes_params +    params.require(:compliance_control).permit(:type).values[0].constantize.dynamic_attributes    end    def compliance_control_params -    params.require(:compliance_control).permit(:name, :code, :criticity, :comment, :control_attributes) +    base = [:name, :code, :origin_code, :criticity, :comment, :control_attributes, :type, compliance_control_block_attributes: [:name, :transport_mode]] +    permited = base + dynamic_attributes_params +    params.require(:compliance_control).permit(permited)    end  end diff --git a/app/controllers/imports_controller.rb b/app/controllers/imports_controller.rb index 3333dc535..f2e65e445 100644 --- a/app/controllers/imports_controller.rb +++ b/app/controllers/imports_controller.rb @@ -1,4 +1,5 @@  class ImportsController < BreadcrumbController +  include PolicyChecker    skip_before_action :authenticate_user!, only: [:download]    defaults resource_class: Import, collection_name: 'imports', instance_name: 'import'    before_action :ransack_started_at_params, only: [:index] diff --git a/app/decorators/company_decorator.rb b/app/decorators/company_decorator.rb index 402bd3ab6..764cce3a0 100644 --- a/app/decorators/company_decorator.rb +++ b/app/decorators/company_decorator.rb @@ -19,8 +19,6 @@ class CompanyDecorator < Draper::Decorator      links = []      if h.policy(Chouette::Company).create? -      require 'pry' -      binding.pry        links << Link.new(          content: h.t('companies.actions.new'),          href: h.new_line_referential_company_path(context[:referential]) diff --git a/app/decorators/compliance_control_decorator.rb b/app/decorators/compliance_control_decorator.rb index 38b968ad1..3a05a5c59 100644 --- a/app/decorators/compliance_control_decorator.rb +++ b/app/decorators/compliance_control_decorator.rb @@ -4,21 +4,21 @@ class ComplianceControlDecorator < Draper::Decorator    def action_links      links = [] -    if h.policy(object).destroy? +    # if h.policy(object).destroy?        links << Link.new(          content: h.destroy_link_content,          href: h.compliance_control_set_compliance_control_path(object.compliance_control_set.id, object.id),          method: :delete,          data: { confirm: h.t('compliance_controls.actions.destroy_confirm') }        ) -    end +    # end -    if h.policy(object).edit? +    # if h.policy(object).edit?        links << Link.new(          content: h.t('compliance_controls.actions.edit'), -        href:  h.edit_compliance_control_set_path(object.compliance_control_set.id, object.id) +        href:  h.edit_compliance_control_set_compliance_control_path(object.compliance_control_set.id, object.id)        ) -    end +    # end      links    end diff --git a/app/decorators/compliance_control_set_decorator.rb b/app/decorators/compliance_control_set_decorator.rb index 876a54d09..f9e4de836 100644 --- a/app/decorators/compliance_control_set_decorator.rb +++ b/app/decorators/compliance_control_set_decorator.rb @@ -19,6 +19,13 @@ class ComplianceControlSetDecorator < Draper::Decorator          href:  h.edit_compliance_control_set_path(object.id)        )      # end + +    # if h.policy(ComplianceControl).create? +      links << Link.new( +        content: h.t('compliance_control_sets.actions.add_compliance_control'), +        href:  h.new_compliance_control_set_compliance_control_path(object.id) +      ) +    # end      links    end diff --git a/app/helpers/referentials_helper.rb b/app/helpers/referentials_helper.rb index 73384bef6..f3c18d9f8 100644 --- a/app/helpers/referentials_helper.rb +++ b/app/helpers/referentials_helper.rb @@ -1,2 +1,12 @@  module ReferentialsHelper +  # Line statuses helper +  def line_status(status) +    if status +    cls = 'danger' +      content_tag :span, status ? " #{t('false')} " : " #{t('true')}", class: "fa fa-exclamation-circle fa-lg text-#{cls}" +    else +    cls = 'success' +      content_tag :span, status ? " #{t('false')} " : " #{t('true')}", class: "fa fa-check-circle fa-lg text-#{cls}" +    end +  end  end diff --git a/app/models/compliance_check.rb b/app/models/compliance_check.rb index 85cf5e37e..4c29129b9 100644 --- a/app/models/compliance_check.rb +++ b/app/models/compliance_check.rb @@ -6,4 +6,5 @@ class ComplianceCheck < ActiveRecord::Base    validates :criticity, presence: true    validates :name, presence: true    validates :code, presence: true +  validates :origin_code, presence: true  end diff --git a/app/models/compliance_control.rb b/app/models/compliance_control.rb index 12ff4737a..c5389e832 100644 --- a/app/models/compliance_control.rb +++ b/app/models/compliance_control.rb @@ -1,12 +1,42 @@  class ComplianceControl < ActiveRecord::Base +  extend Enumerize    belongs_to :compliance_control_set -  belongs_to :compliance_control_block +  has_one :compliance_control_block, dependent: :destroy +  accepts_nested_attributes_for :compliance_control_block + +  @@default_criticity = :warning +  @@default_code = "" -  extend Enumerize    enumerize :criticity, in: %i(info warning error), scope: true, default: :info    validates :criticity, presence: true    validates :name, presence: true    validates :code, presence: true +  validates :origin_code, presence: true    validates :compliance_control_set, presence: true + +  def self.policy_class +    ComplianceControlPolicy +  end + +  def self.inherited(child) +    child.instance_eval do +      def model_name +        ComplianceControl.model_name +      end +    end +    super +  end + +  before_validation(on: :create) do +   self.name ||= self.class.name +   self.code ||= @@default_code +   self.origin_code ||= @@default_code +   self.criticity ||= @@default_criticity +  end +  end + +# Ensure STI subclasses are loaded +# http://guides.rubyonrails.org/autoloading_and_reloading_constants.html#autoloading-and-sti +require_dependency 'generic_attribute_control/min_max' diff --git a/app/models/compliance_control_block.rb b/app/models/compliance_control_block.rb index cf5a9d72b..a08e271f6 100644 --- a/app/models/compliance_control_block.rb +++ b/app/models/compliance_control_block.rb @@ -1,3 +1,16 @@  class ComplianceControlBlock < ActiveRecord::Base    belongs_to :compliance_control_set +  belongs_to :compliance_control + +  before_save :set_compliance_control_set + +  hstore_accessor :condition_attributes, transport_mode: :string + +  def set_compliance_control_set +    self.compliance_control_set = self.compliance_control.compliance_control_set +  end + +  def self.transport_modes +    ["all"] + StifTransportModeEnumerations.transport_mode.values +  end  end diff --git a/app/models/compliance_control_set.rb b/app/models/compliance_control_set.rb index cefdfbf1f..f8f491cba 100644 --- a/app/models/compliance_control_set.rb +++ b/app/models/compliance_control_set.rb @@ -1,7 +1,9 @@  class ComplianceControlSet < ActiveRecord::Base    belongs_to :organisation -  has_many :compliance_controls +  has_many :compliance_controls, dependent: :destroy    validates :name, presence: true - +  scope :where_updated_at_between, ->(start_date, end_date) do +    where('updated_at BETWEEN ? AND ?', start_date, end_date) +  end  end diff --git a/app/models/generic_attribute_control/min_max.rb b/app/models/generic_attribute_control/min_max.rb new file mode 100644 index 000000000..6a2e1f284 --- /dev/null +++ b/app/models/generic_attribute_control/min_max.rb @@ -0,0 +1,17 @@ +module GenericAttributeControl +  class MinMax < ComplianceControl +    hstore_accessor :control_attributes, minimum: :integer, maximum: :integer + +    @@default_criticity = :warning +    @@default_code = "3-Generic-2" + +    validate :min_max_values +    def min_max_values +      true +    end + +    def self.dynamic_attributes +      self.hstore_metadata_for_control_attributes.keys +    end +  end +end diff --git a/app/models/generic_attribute_control/pattern.rb b/app/models/generic_attribute_control/pattern.rb new file mode 100644 index 000000000..5b27da54e --- /dev/null +++ b/app/models/generic_attribute_control/pattern.rb @@ -0,0 +1,13 @@ +module GenericAttributeControl +  class Pattern < ComplianceControl +    hstore_accessor :control_attributes, value: :string, pattern: :string + +    @@default_criticity = :warning +    @@default_code = "3-Generic-3" + +    validate :pattern_match +    def pattern_match +      true +    end +  end +end
\ No newline at end of file diff --git a/app/models/generic_attribute_control/uniqueness.rb b/app/models/generic_attribute_control/uniqueness.rb new file mode 100644 index 000000000..4f1a82083 --- /dev/null +++ b/app/models/generic_attribute_control/uniqueness.rb @@ -0,0 +1,13 @@ +module GenericAttributeControl +  class Uniqueness < ComplianceControl +    hstore_accessor :control_attributes, name: :string + +    @@default_criticity = :warning +    @@default_code = "3-Generic-3" + +    validate :unique_values +    def unique_values +      true +    end +  end +end
\ No newline at end of file diff --git a/app/models/generic_attribute_min_max.rb b/app/models/generic_attribute_min_max.rb deleted file mode 100644 index e9a127c56..000000000 --- a/app/models/generic_attribute_min_max.rb +++ /dev/null @@ -1,27 +0,0 @@ -#module ComplianceControls - -  class GenericAttributeMinMax < ComplianceControl - - -    hstore_accessor :control_attributes, minimum: :integer, maximum: :integer -    #attribute :minimum, type: :integer, optionnal: true -    #attribute :maximum, type: :integer, optionnal: true -    # #attribute :target, type: ModelAttribute - -    @@default_criticity = :warning -    @@default_code = "3-Generic-2" - -    validate :min_max_values -    def min_max_values -      true -    end - -    after_initialize do -      self.name = 'GenericAttributeMinMax' -      self.code = @@default_code -      self.criticity = @@default_criticity -    end - -  end - -#end diff --git a/app/models/generic_attribute_pattern.rb b/app/models/generic_attribute_pattern.rb deleted file mode 100644 index 0043f1563..000000000 --- a/app/models/generic_attribute_pattern.rb +++ /dev/null @@ -1,23 +0,0 @@ -#module ComplianceControls - -  class GenericAttributePattern < ComplianceControl - -    hstore_accessor :control_attributes, value: :string, pattern: :string - -    @@default_criticity = :warning -    @@default_code = "3-Generic-3" - -    validate :pattern_match -    def pattern_match -      true -    end - -    after_initialize do -      self.name = 'GenericAttributeMinMax' -      self.code = @@default_code -      self.criticity = @@default_criticity -    end - -  end - -#end
\ No newline at end of file diff --git a/app/models/generic_attribute_uniqueness.rb b/app/models/generic_attribute_uniqueness.rb deleted file mode 100644 index dcf4a16c2..000000000 --- a/app/models/generic_attribute_uniqueness.rb +++ /dev/null @@ -1,23 +0,0 @@ -#module ComplianceControls - -  class GenericAttributeUniqueness < ComplianceControl - -    hstore_accessor :control_attributes, name: :string - -    @@default_criticity = :warning -    @@default_code = "3-Generic-3" - -    validate :unique_values -    def unique_values -      true -    end - -    after_initialize do -      self.name = 'GenericAttributeMinMax' -      self.code = @@default_code -      self.criticity = @@default_criticity -    end - -  end - -#end
\ No newline at end of file diff --git a/app/models/journey_pattern_control/duplicates.rb b/app/models/journey_pattern_control/duplicates.rb index 78ca07e90..d3908cfc0 100644 --- a/app/models/journey_pattern_control/duplicates.rb +++ b/app/models/journey_pattern_control/duplicates.rb @@ -3,11 +3,5 @@ module JourneyPatternControl      @@default_criticity = :warning      @@default_code = "3-JourneyPattern-1" - -    after_initialize do -      self.name = self.class.name -      self.code = @@default_code -      self.criticity = @@default_criticity -    end    end  end diff --git a/app/models/journey_pattern_control/vehicle_journey.rb b/app/models/journey_pattern_control/vehicle_journey.rb index a90c16138..d7151f147 100644 --- a/app/models/journey_pattern_control/vehicle_journey.rb +++ b/app/models/journey_pattern_control/vehicle_journey.rb @@ -3,11 +3,5 @@ module JourneyPatternControl      @@default_criticity = :warning      @@default_code = "3-JourneyPattern-2" - -    after_initialize do -      self.name = self.class.name -      self.code = @@default_code -      self.criticity = @@default_criticity -    end    end  end
\ No newline at end of file diff --git a/app/models/line_control/route.rb b/app/models/line_control/route.rb index 8ac13a080..21c5eca06 100644 --- a/app/models/line_control/route.rb +++ b/app/models/line_control/route.rb @@ -3,11 +3,5 @@ module LineControl      @@default_criticity = :warning      @@default_code = "3-Line-1" - -    after_initialize do -      self.name = self.class.name -      self.code = @@default_code -      self.criticity = @@default_criticity -    end    end  end
\ No newline at end of file diff --git a/app/models/route_control/duplicates.rb b/app/models/route_control/duplicates.rb index 379d7cf98..fb9c34e0a 100644 --- a/app/models/route_control/duplicates.rb +++ b/app/models/route_control/duplicates.rb @@ -3,11 +3,5 @@ module RouteControl      @@default_criticity = :warning      @@default_code = "3-Route-4" - -    after_initialize do -      self.name = self.class.name -      self.code = @@default_code -      self.criticity = @@default_criticity -    end    end  end diff --git a/app/models/route_control/journey_pattern.rb b/app/models/route_control/journey_pattern.rb index 0559fac42..08f603d8f 100644 --- a/app/models/route_control/journey_pattern.rb +++ b/app/models/route_control/journey_pattern.rb @@ -3,11 +3,5 @@ module RouteControl      @@default_criticity = :warning      @@default_code = "3-Route-3" - -    after_initialize do -      self.name = self.class.name -      self.code = @@default_code -      self.criticity = @@default_criticity -    end    end  end
\ No newline at end of file diff --git a/app/models/route_control/minimum_length.rb b/app/models/route_control/minimum_length.rb index 14bc7064f..f42b88748 100644 --- a/app/models/route_control/minimum_length.rb +++ b/app/models/route_control/minimum_length.rb @@ -3,11 +3,5 @@ module RouteControl      @@default_criticity = :error      @@default_code = "3-Route-6" - -    after_initialize do -      self.name = self.class.name -      self.code = @@default_code -      self.criticity = @@default_criticity -    end    end  end diff --git a/app/models/route_control/omnibus_journey_pattern.rb b/app/models/route_control/omnibus_journey_pattern.rb index 2f09ff735..3b9f6d06f 100644 --- a/app/models/route_control/omnibus_journey_pattern.rb +++ b/app/models/route_control/omnibus_journey_pattern.rb @@ -3,11 +3,5 @@ module RouteControl      @@default_criticity = :warning      @@default_code = "3-Route-9" - -    after_initialize do -      self.name = self.class.name -      self.code = @@default_code -      self.criticity = @@default_criticity -    end    end  end diff --git a/app/models/route_control/opposite_route.rb b/app/models/route_control/opposite_route.rb index d5f2bc59e..e91b081e2 100644 --- a/app/models/route_control/opposite_route.rb +++ b/app/models/route_control/opposite_route.rb @@ -3,12 +3,5 @@ module RouteControl      @@default_criticity = :error      @@default_code = "3-Route-2" - -    after_initialize do -      self.name = self.class.name -      self.code = @@default_code -      self.criticity = @@default_criticity -    end -    end  end diff --git a/app/models/route_control/opposite_route_terminus.rb b/app/models/route_control/opposite_route_terminus.rb index e72229ca3..fd62b7684 100644 --- a/app/models/route_control/opposite_route_terminus.rb +++ b/app/models/route_control/opposite_route_terminus.rb @@ -3,11 +3,5 @@ module RouteControl      @@default_criticity = :warning      @@default_code = "3-Route-5" - -    after_initialize do -      self.name = self.class.name -      self.code = @@default_code -      self.criticity = @@default_criticity -    end    end  end
\ No newline at end of file diff --git a/app/models/route_control/speed.rb b/app/models/route_control/speed.rb index fb07b5c87..0a2b6ac76 100644 --- a/app/models/route_control/speed.rb +++ b/app/models/route_control/speed.rb @@ -5,11 +5,5 @@ module VehicleJourneyControl      @@default_criticity = :warning      @@default_code = "3-VehicleJourney-2" - -    after_initialize do -      self.name = self.class.name -      self.code = @@default_code -      self.criticity = @@default_criticity -    end    end  end diff --git a/app/models/route_control/stop_points_in_journey_pattern.rb b/app/models/route_control/stop_points_in_journey_pattern.rb index 195257a4a..dced6c005 100644 --- a/app/models/route_control/stop_points_in_journey_pattern.rb +++ b/app/models/route_control/stop_points_in_journey_pattern.rb @@ -3,11 +3,5 @@ module RouteControl      @@default_criticity = :error      @@default_code = "3-Route-6" - -    after_initialize do -      self.name = self.class.name -      self.code = @@default_code -      self.criticity = @@default_criticity -    end    end  end diff --git a/app/models/route_control/time_table.rb b/app/models/route_control/time_table.rb index 911807ba9..5d0f21b40 100644 --- a/app/models/route_control/time_table.rb +++ b/app/models/route_control/time_table.rb @@ -3,11 +3,5 @@ module VehicleJourneyControl      @@default_criticity = :error      @@default_code = "3-VehicleJourney-4" - -    after_initialize do -      self.name = self.class.name -      self.code = @@default_code -      self.criticity = @@default_criticity -    end    end  end diff --git a/app/models/route_control/unactivated_stop_points.rb b/app/models/route_control/unactivated_stop_points.rb index 8ab680490..dee846cbb 100644 --- a/app/models/route_control/unactivated_stop_points.rb +++ b/app/models/route_control/unactivated_stop_points.rb @@ -3,11 +3,5 @@ module RouteControl      @@default_criticity = :warning      @@default_code = "3-Route-10" - -    after_initialize do -      self.name = self.class.name -      self.code = @@default_code -      self.criticity = @@default_criticity -    end    end  end diff --git a/app/models/route_control/vehicle_journey_at_stops.rb b/app/models/route_control/vehicle_journey_at_stops.rb index 02a43fb10..149282fe6 100644 --- a/app/models/route_control/vehicle_journey_at_stops.rb +++ b/app/models/route_control/vehicle_journey_at_stops.rb @@ -3,11 +3,5 @@ module VehicleJourneyControl      @@default_criticity = :error      @@default_code = "3-VehicleJourney-5" - -    after_initialize do -      self.name = self.class.name -      self.code = @@default_code -      self.criticity = @@default_criticity -    end    end  end diff --git a/app/models/route_control/zdl_stop_area.rb b/app/models/route_control/zdl_stop_area.rb index 4561c9b2e..088a1d2f2 100644 --- a/app/models/route_control/zdl_stop_area.rb +++ b/app/models/route_control/zdl_stop_area.rb @@ -3,11 +3,5 @@ module RouteControl      @@default_criticity = :warning      @@default_code = "3-Route-1" - -    after_initialize do -      self.name = self.class.name -      self.code = @@default_code -      self.criticity = @@default_criticity -    end    end  end diff --git a/app/models/routing_constaint_zone_control/maximum_length.rb b/app/models/routing_constaint_zone_control/maximum_length.rb index fd63ffeda..4d289de63 100644 --- a/app/models/routing_constaint_zone_control/maximum_length.rb +++ b/app/models/routing_constaint_zone_control/maximum_length.rb @@ -3,11 +3,5 @@ module RoutingConstaintZoneControl      @@default_criticity = :warning      @@default_code = "3-ITL-2" - -    after_initialize do -      self.name = self.class.name -      self.code = @@default_code -      self.criticity = @@default_criticity -    end    end  end
\ No newline at end of file diff --git a/app/models/routing_constaint_zone_control/minimum_length.rb b/app/models/routing_constaint_zone_control/minimum_length.rb index c17bbc834..28f0791a7 100644 --- a/app/models/routing_constaint_zone_control/minimum_length.rb +++ b/app/models/routing_constaint_zone_control/minimum_length.rb @@ -3,11 +3,5 @@ module RoutingConstaintZoneControl      @@default_criticity = :warning      @@default_code = "3-ITL-3" - -    after_initialize do -      self.name = self.class.name -      self.code = @@default_code -      self.criticity = @@default_criticity -    end    end  end
\ No newline at end of file diff --git a/app/models/routing_constaint_zone_control/unactivated_stop_point.rb b/app/models/routing_constaint_zone_control/unactivated_stop_point.rb index 92a1d1a58..fe5381a34 100644 --- a/app/models/routing_constaint_zone_control/unactivated_stop_point.rb +++ b/app/models/routing_constaint_zone_control/unactivated_stop_point.rb @@ -3,11 +3,5 @@ module RoutingConstaintZoneControl      @@default_criticity = :warning      @@default_code = "3-ITL-1" - -    after_initialize do -      self.name = self.class.name -      self.code = @@default_code -      self.criticity = @@default_criticity -    end    end  end diff --git a/app/models/vechicle_journey_control/delta.rb b/app/models/vechicle_journey_control/delta.rb index d4e1e6eca..d77eff48a 100644 --- a/app/models/vechicle_journey_control/delta.rb +++ b/app/models/vechicle_journey_control/delta.rb @@ -5,11 +5,5 @@ module VehicleJourneyControl      @@default_criticity = :warning      @@default_code = "3-VehicleJourney-3" - -    after_initialize do -      self.name = self.class.name -      self.code = @@default_code -      self.criticity = @@default_criticity -    end    end  end diff --git a/app/models/vechicle_journey_control/waiting_time.rb b/app/models/vechicle_journey_control/waiting_time.rb index a7e90b6ac..cbffa5526 100644 --- a/app/models/vechicle_journey_control/waiting_time.rb +++ b/app/models/vechicle_journey_control/waiting_time.rb @@ -3,11 +3,5 @@ module VehicleJourneyControl      @@default_criticity = :warning      @@default_code = "3-VehicleJourney-1" - -    after_initialize do -      self.name = self.class.name -      self.code = @@default_code -      self.criticity = @@default_criticity -    end    end  end diff --git a/app/models/vehicle_journey_import.rb b/app/models/vehicle_journey_import.rb index 44a6d457e..250f3a9e9 100644 --- a/app/models/vehicle_journey_import.rb +++ b/app/models/vehicle_journey_import.rb @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- -  class VehicleJourneyImport    include ActiveModel::Validations    include ActiveModel::Conversion diff --git a/app/models/workbench.rb b/app/models/workbench.rb index cd90f8253..ae111a9c5 100644 --- a/app/models/workbench.rb +++ b/app/models/workbench.rb @@ -2,6 +2,7 @@ class Workbench < ActiveRecord::Base    belongs_to :organisation    belongs_to :line_referential    belongs_to :stop_area_referential +  belongs_to :output, class_name: 'ReferentialSuite'    has_many :lines, -> (workbench) { Stif::MyWorkbenchScopes.new(workbench).line_scope(self) }, through: :line_referential    has_many :networks, through: :line_referential @@ -14,10 +15,13 @@ class Workbench < ActiveRecord::Base    validates :name, presence: true    validates :organisation, presence: true +  validates :output, presence: true    has_many :referentials    has_many :referential_metadatas, through: :referentials, source: :metadatas +  before_validation :initialize_output +    def all_referentials      if line_ids.empty? @@ -27,4 +31,12 @@ class Workbench < ActiveRecord::Base      end    end +  private + +  def initialize_output +    # Don't reset `output` if it's already initialised +    return if !output.nil? + +    self.output = ReferentialSuite.create +  end  end diff --git a/app/policies/compliance_control_policy.rb b/app/policies/compliance_control_policy.rb index fbea366f5..09250f013 100644 --- a/app/policies/compliance_control_policy.rb +++ b/app/policies/compliance_control_policy.rb @@ -6,14 +6,17 @@ class ComplianceControlPolicy < ApplicationPolicy    end    def destroy? -    user.has_permission?('compliance_controls.destroy') +    # user.has_permission?('compliance_controls.destroy') +    true    end    def create? -    user.has_permission?('compliance_controls.create') +    # user.has_permission?('compliance_controls.create') +    true    end    def update? -    user.has_permission?('compliance_controls.update') +    # user.has_permission?('compliance_controls.update') +    true    end  end diff --git a/app/policies/import_policy.rb b/app/policies/import_policy.rb index 9e1d99a66..b12dcc167 100644 --- a/app/policies/import_policy.rb +++ b/app/policies/import_policy.rb @@ -4,4 +4,16 @@ class ImportPolicy < ApplicationPolicy        scope      end    end + +  def create? +    !archived? && user.has_permission?('imports.create') +  end + +  def destroy? +    !archived? && user.has_permission?('imports.destroy') +  end + +  def update? +    !archived? && user.has_permission?('imports.update') +  end  end diff --git a/app/views/compliance_control_sets/_filters.html.slim b/app/views/compliance_control_sets/_filters.html.slim index 587f74ce4..56cac8bd2 100644 --- a/app/views/compliance_control_sets/_filters.html.slim +++ b/app/views/compliance_control_sets/_filters.html.slim @@ -9,6 +9,13 @@      .form-group.togglable        = f.label t('activerecord.models.organisation.one'), required: false, class: 'control-label'        = f.input :organisation_name_eq_any, collection: organisations_filters_values, as: :check_boxes, label: false, label_method: lambda {|w| ("<span>#{w.name}</span>").html_safe}, required: false, wrapper_html: {class: 'checkbox_list'} +       +    .form-group.togglable +      = f.label Import.human_attribute_name(:updated_at), required: false, class: 'control-label' +      .filter_menu +        = f.simple_fields_for :updated_at do |p| +          = p.input :begin, as: :date, label: false, wrapper_html: {class: 'date smart_date filter_menu-item'}, default: @begin_range, include_blank: @begin_range ? false : true +          = p.input :end, as: :date, label: false, wrapper_html: {class: 'date smart_date filter_menu-item'}, default: @end_range, include_blank: @end_range ? false : true    .actions      = link_to t('actions.erase'), @compliance_control_set, class: 'btn btn-link' diff --git a/app/views/compliance_control_sets/show.html.slim b/app/views/compliance_control_sets/show.html.slim index b4a5b2260..d7d4678ba 100644 --- a/app/views/compliance_control_sets/show.html.slim +++ b/app/views/compliance_control_sets/show.html.slim @@ -22,4 +22,38 @@      .row        .col-lg-6.col-md-6.col-sm-12.col-xs-12          = definition_list t('metadatas'), -            ComplianceControlSet.human_attribute_name(:name) => @compliance_control_set.name
\ No newline at end of file +            ComplianceControlSet.human_attribute_name(:name) => @compliance_control_set.name + +  .container-fluid +    .row +      .col-lg-12 +        /= render 'filters' +      .row +        .col-lg-12 +          .select_table +            = table_builder_2 @compliance_controls, +                    [ \ +                TableBuilderHelper::Column.new( \ +                  key: :code, \ +                  attribute: 'code' \ +                ), \ +                TableBuilderHelper::Column.new( \ +                  key: :name, \ +                  attribute: 'name', \ +                  link_to: lambda do |compliance_control| \ +                      compliance_control_set_compliance_control_path(@compliance_control_set, compliance_control) \ +                    end \ +                ), \ +                TableBuilderHelper::Column.new( \ +                  key: :criticity, \ +                  attribute: 'criticity' \ +                ), \ +                TableBuilderHelper::Column.new( \ +                  key: :comment, \ +                  attribute: 'comment' \ +                ), \ +              ], +              sortable: true, +              cls: 'table has-filter has-search' + + diff --git a/app/views/compliance_controls/_form.html.slim b/app/views/compliance_controls/_form.html.slim index 1377ed12b..bb8f68464 100644 --- a/app/views/compliance_controls/_form.html.slim +++ b/app/views/compliance_controls/_form.html.slim @@ -2,11 +2,19 @@    .row      .col-lg-12        = f.input :name -      = f.input :type +      = f.input :type, as: :select, collection: ComplianceControl.subclasses        = f.input :code        = f.input :criticity        = f.input :comment +      - f.object.class.dynamic_attributes.each do |attribute| +        = f.input attribute.to_sym +      end + +      = f.simple_fields_for :compliance_control_block do |c| +        = c.input :name +        = c.input :transport_mode, as: :select, collection:ComplianceControlBlock.transport_modes +      end    .separator    = f.button :submit, t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'compliance_control_form' diff --git a/app/views/compliance_controls/edit.html.slim b/app/views/compliance_controls/edit.html.slim index e69de29bb..6824c7e40 100644 --- a/app/views/compliance_controls/edit.html.slim +++ b/app/views/compliance_controls/edit.html.slim @@ -0,0 +1,9 @@ += pageheader 'compliance-control', +        t('compliance_control.index.edit') + + +.page_content +  .container-fluid +    .row +      .col-lg-8.col-lg-offset-2.col-md-8.col-md-offset-2.col-sm-10.col-sm-offset-1 +        = render 'form' diff --git a/app/views/compliance_controls/show.html.slim b/app/views/compliance_controls/show.html.slim index e69de29bb..a665f1ab1 100644 --- a/app/views/compliance_controls/show.html.slim +++ b/app/views/compliance_controls/show.html.slim @@ -0,0 +1,3 @@ += @compliance_control.inspect +br += @compliance_control.compliance_control_block.inspect diff --git a/app/views/lines/index.html.slim b/app/views/lines/index.html.slim index dda5afd44..fb07c45a2 100644 --- a/app/views/lines/index.html.slim +++ b/app/views/lines/index.html.slim @@ -36,7 +36,7 @@                ), \                TableBuilderHelper::Column.new( \                  key: :deactivated, \ -                attribute: Proc.new{|n| n.deactivated? ? t('false') : t('true')} \ +                attribute: Proc.new { |n| line_status(n.deactivated?) } \                ), \                TableBuilderHelper::Column.new( \                  key: 'networks.name', \ diff --git a/app/views/referentials/show.html.slim b/app/views/referentials/show.html.slim index e1d89cba4..0fdd79e14 100644 --- a/app/views/referentials/show.html.slim +++ b/app/views/referentials/show.html.slim @@ -58,7 +58,7 @@                ), \                TableBuilderHelper::Column.new( \                  key: :deactivated, \ -                attribute: Proc.new { |n| n.deactivated? ? t('false') : t('true') } \ +                attribute: Proc.new { |n| line_status(n.deactivated?) } \                ), \                TableBuilderHelper::Column.new( \                  key: :transport_mode, \ diff --git a/app/views/routes/_form.html.slim b/app/views/routes/_form.html.slim index 244b427dc..24c0d3c4a 100644 --- a/app/views/routes/_form.html.slim +++ b/app/views/routes/_form.html.slim @@ -26,7 +26,8 @@  // Get JSON data for route stop points  = javascript_tag do -  | window.itinerary_stop = "#{URI.escape(route_json_for_edit(@route))}" +  | window.itinerary_stop = "#{URI.escape(route_json_for_edit(@route))}"; +  | window.I18n = #{(I18n.backend.send(:translations)[I18n.locale].to_json).html_safe};  / StopPoints Reactux component  = javascript_include_tag 'es6_browserified/itineraries/index.js' diff --git a/app/views/routes/show.html.slim b/app/views/routes/show.html.slim index e2681d215..edc2d254b 100644 --- a/app/views/routes/show.html.slim +++ b/app/views/routes/show.html.slim @@ -48,7 +48,7 @@                ), \                TableBuilderHelper::Column.new( \                  key: :deleted_at, \ -                attribute: Proc.new { |s| s.try(:stop_area).deleted_at ? t('false') : t('true') }, \ +                attribute: Proc.new { |s| line_status(s.try(:stop_area).deleted_at) } \                ), \                TableBuilderHelper::Column.new( \                  key: :zip_code, \ diff --git a/app/views/stop_areas/index.html.slim b/app/views/stop_areas/index.html.slim index 4c95761d2..95b9b1b0e 100644 --- a/app/views/stop_areas/index.html.slim +++ b/app/views/stop_areas/index.html.slim @@ -39,7 +39,7 @@                ), \                TableBuilderHelper::Column.new( \                  key: :deleted_at, \ -                attribute: Proc.new { |s| s.deleted_at ? t('false') : t('true') } \ +                attribute: Proc.new { |s| line_status(s.deleted_at) } \                ), \                TableBuilderHelper::Column.new( \                  key: :zip_code, \ diff --git a/app/views/time_tables/edit.html.slim b/app/views/time_tables/edit.html.slim index ed55dc4e3..cc6f31489 100644 --- a/app/views/time_tables/edit.html.slim +++ b/app/views/time_tables/edit.html.slim @@ -11,6 +11,6 @@  = javascript_tag do    | window.actionType = "#{raw params[:action]}"; -  | window.I18n = #{(I18n.backend.send(:translations).to_json).html_safe}; +  | window.I18n = #{(I18n.backend.send(:translations)[I18n.locale].to_json).html_safe};  = javascript_include_tag 'es6_browserified/time_tables/index.js' diff --git a/config/initializers/apartment.rb b/config/initializers/apartment.rb index b8f86a751..0393c7bdd 100644 --- a/config/initializers/apartment.rb +++ b/config/initializers/apartment.rb @@ -20,6 +20,7 @@ Apartment.configure do |config|    config.excluded_models = [      'Referential',      'ReferentialMetadata', +    'ReferentialSuite',      'Organisation',      'User',      'Api::V1::ApiKey', @@ -48,6 +49,7 @@ Apartment.configure do |config|      'ImportMessage',      'ImportResource',      'ComplianceControl', +    'GenericAttributeControl::MinMax',      'ComplianceControlSet',      'ComplianceControlBlock',      'ComplianceCheck', diff --git a/config/locales/actions.en.yml b/config/locales/actions.en.yml index 8dea51ca3..c34462d0d 100644 --- a/config/locales/actions.en.yml +++ b/config/locales/actions.en.yml @@ -20,8 +20,10 @@ en:      filter: 'Filter'      erase: 'Erase'      create_api_key: "Create an API key" +    select: Select    or: "or"    cancel: "Cancel" +  back: "Go Back"    search_hint: "Type in a search term"    no_result_text: "No Results"    searching_term: "Searching..." diff --git a/config/locales/actions.fr.yml b/config/locales/actions.fr.yml index 01fc06326..df16d2aab 100644 --- a/config/locales/actions.fr.yml +++ b/config/locales/actions.fr.yml @@ -20,8 +20,10 @@ fr:      filter: 'Filtrer'      erase: 'Effacer'      create_api_key: "Créer une clé d'API" +    select: Sélectionner    or: "ou"    cancel: "Annuler" +  back: "Retour"    search_hint: "Entrez un texte à rechercher"    no_result_text: "Aucun résultat"    searching_term: "Recherche en cours..." diff --git a/config/locales/compliance_control_sets.en.yml b/config/locales/compliance_control_sets.en.yml index 5426233bd..4e2c8f485 100644 --- a/config/locales/compliance_control_sets.en.yml +++ b/config/locales/compliance_control_sets.en.yml @@ -1,17 +1,18 @@ -fr: +en:    compliance_control_sets:      index: -      title: Control games -      new: Creating a control set -      edit: Editing a Control Game +      title: Compliance control set +      new: New compliance control set +      edit: Edit compliance control set      actions: -          new: Add -          edit: Edit -          destroy: Delete -          destroy_confirm: Are you sure to remove the control games ? +      new: Add +      edit: Edit +      destroy: Destroy +      add_compliance_control: Add a compliance control +      destroy_confirm: Are you sur ?      filters: -          name: Specify a control game name... -    search_no_results: No control game matches your search +      name: 'Enter name ...' +    search_no_results: 'No compliance control set found'    activerecord:            models:              compliance_control_set: Calendar diff --git a/config/locales/compliance_control_sets.fr.yml b/config/locales/compliance_control_sets.fr.yml index 42baf0fcf..d808698c5 100644 --- a/config/locales/compliance_control_sets.fr.yml +++ b/config/locales/compliance_control_sets.fr.yml @@ -5,13 +5,14 @@ fr:        new: Création d'un jeux de contrôle        edit: Édition d'un jeux de contrôle      actions: -          new: Ajouter -          edit: Editer -          destroy: Supprimer -          destroy_confirm: Etes vous sûr de supprimer ce jeux de contrôle ? +      new: Ajouter +      edit: Editer +      destroy: Supprimer +      add_compliance_control: Ajouter un JDC +      destroy_confirm: Etes vous sûr de supprimer ce jeux de contrôle ?      filters: -          name: Indiquez un nom de jeux de contrôle... -    search_no_results: Aucun jeu de contrôle ne correspond à votre recherche +      name: 'Indiquez un nom de jeux de contrôle...' +    search_no_results: 'Aucun jeu de contrôle ne correspond à votre recherche'    activerecord:            models:              compliance_control_set: Calendrier diff --git a/config/locales/routes.en.yml b/config/locales/routes.en.yml index 63d7b198c..3b1fd85cc 100644 --- a/config/locales/routes.en.yml +++ b/config/locales/routes.en.yml @@ -17,6 +17,25 @@ en:        title: "Add a new route"      edit:        title: "Update route %{route}" +      select2: +        placeholder: "Select a stop point..." +      map: +        stop_point_type: Stop point type +        short_name: Short name +        coordinates: Coordinates +        proj: Proj +        lat: Lat +        lon: Lon +        postal_code: Zip Code +        city: City +        comment: Comment +      stop_point: +        boarding: +          normal: Normal boarding +          forbidden: Forbidden boarding +        alighting: +          normal: Normal alighting +          forbidden: Forbidden alighting      show:        title: "Route %{route}"        stop_points: "Stop point on route list" diff --git a/config/locales/routes.fr.yml b/config/locales/routes.fr.yml index a494e60ec..43c40645d 100644 --- a/config/locales/routes.fr.yml +++ b/config/locales/routes.fr.yml @@ -17,6 +17,25 @@ fr:        title: "Ajouter un itinéraire"      edit:        title: "Editer l'itinéraire %{route}" +      select2: +        placeholder: "Sélectionnez un arrêt existant..." +      map: +        stop_point_type: Type d'arrêt +        short_name: Nom court +        coordinates: Coordonnées +        proj: Proj +        lat: Lat +        lon: Lon +        postal_code: Code Postal +        city: Commune +        comment: Commentaire +      stop_point: +        boarding: +          normal: Montée autorisée +          forbidden: Montée interdite +        alighting: +          normal: Descente autorisée +          forbidden: Descente interdite      show:        title: "Itinéraire %{route} de la ligne %{line}"        stop_points: "Liste des arrêts de l'itinéraire" diff --git a/config/locales/stop_points.en.yml b/config/locales/stop_points.en.yml index 1ef8002d0..d22d85731 100644 --- a/config/locales/stop_points.en.yml +++ b/config/locales/stop_points.en.yml @@ -52,5 +52,6 @@ en:    simple_form:      labels:        stop_point: +        name: Stop Point          for_boarding: "Pickup"          for_alighting: "Drop off" diff --git a/config/locales/stop_points.fr.yml b/config/locales/stop_points.fr.yml index d90041945..d3c873442 100644 --- a/config/locales/stop_points.fr.yml +++ b/config/locales/stop_points.fr.yml @@ -52,5 +52,6 @@ fr:    simple_form:      labels:        stop_point: +        name: Arrêt           for_boarding: "Montée"          for_alighting: "Descente" diff --git a/config/locales/time_tables.en.yml b/config/locales/time_tables.en.yml index d67e30edb..e68836f99 100644 --- a/config/locales/time_tables.en.yml +++ b/config/locales/time_tables.en.yml @@ -29,10 +29,39 @@ en:        title: "Duplicate timetable"      edit:        title: "Update timetable %{time_table}" +      day_types: Day types +      periods: Periods +      exceptions: Exceptions +      synthesis: Synthesis        error_modal:          title: "Error"          withoutPeriodsWithDaysTypes: "A timetable can't have day type(s) without period(s)." -        withPeriodsWithoutDayTypes: "A tiemetable can't have period(s) swithout day type(s)."   +        withPeriodsWithoutDayTypes: "A tiemetable can't have period(s) swithout day type(s)."  +      error_submit: +        periods_overlaps: "Periods cannot overlap in a timetable" +        dates_overlaps: "A period cannot overlap a date in a timetable" +      confirm_modal: +        title: "Confirm" +        message: "You are about to change pages. Do you want to validate your changes before this?" +      metas: +        name: Name +        calendar: Associated calendar +        no_calendar: None +        day_types: Periods day tpes +        days: +          1: Su +          2: Mo +          3: Tu +          4: We +          5: Th +          6: Fr +          7: Sa +      select2: +        tag: +          placeholder: Add or search a tag... +      period_form: +        begin: Period start +        end: Period end      show:        title: "Timetable %{time_table}"        dates: "Application dates" diff --git a/config/locales/time_tables.fr.yml b/config/locales/time_tables.fr.yml index 06d1d59e8..b85f7ca33 100644 --- a/config/locales/time_tables.fr.yml +++ b/config/locales/time_tables.fr.yml @@ -29,10 +29,39 @@ fr:        title: "Dupliquer un calendrier"      edit:        title: "Editer le calendrier %{time_table}" +      day_types: Journées d'application +      periods: Périodes +      exceptions: Exceptions +      synthesis: Synthèse        error_modal:          title: "Erreur"          withoutPeriodsWithDaysTypes: "Un calendrier d'application ne peut pas avoir de journée(s) d'application sans période(s)." -        withPeriodsWithoutDayTypes: "Un calendrier d'application ne peut pas avoir de période(s) sans journée(s) d'application."   +        withPeriodsWithoutDayTypes: "Un calendrier d'application ne peut pas avoir de période(s) sans journée(s) d'application." +      error_submit: +        periods_overlaps: "Les périodes ne peuvent pas se chevaucher" +        dates_overlaps: "Une période ne peut chevaucher une date dans un calendrier" +      confirm_modal: +        title: "Confirmation" +        message: "Vous vous apprêtez à changer de page. Voulez-vous valider vos modifications avant cela ?" +      metas: +        name: Nom +        calendar: Modèle de calendrier associée +        no_calendar: Aucun +        day_types: Journées d'applications pour les périodes ci-dessous +        days: +          1: Di +          2: Lu +          3: Ma +          4: Me +          5: Je +          6: Ve +          7: Sa +      select2: +        tag: +          placeholder: Ajoutez ou cherchez une étiquette... +      period_form: +        begin: Début de période +        end: Fin de période      show:        title: Calendrier %{time_table}        dates: "Dates d'application" diff --git a/config/routes.rb b/config/routes.rb index 6477cc145..9ee85d6e8 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -72,7 +72,7 @@ ChouetteIhm::Application.routes.draw do    resources :api_keys, :only => [:edit, :update, :new, :create, :destroy]    resources :compliance_control_sets do -    resources :compliance_controls +    resources :compliance_controls, except: :index    end    resources :stop_area_referentials, :only => [:show] do diff --git a/db/migrate/20170922121609_add_compliance_control_id_to_compliance_control_blocks.rb b/db/migrate/20170922121609_add_compliance_control_id_to_compliance_control_blocks.rb new file mode 100644 index 000000000..18a6b12cf --- /dev/null +++ b/db/migrate/20170922121609_add_compliance_control_id_to_compliance_control_blocks.rb @@ -0,0 +1,5 @@ +class AddComplianceControlIdToComplianceControlBlocks < ActiveRecord::Migration +  def change +    add_reference :compliance_control_blocks, :compliance_control, index: true, foreign_key: true +  end +end diff --git a/db/migrate/20170922123838_remove_compliance_control_block_id_from_compliance_controls.rb b/db/migrate/20170922123838_remove_compliance_control_block_id_from_compliance_controls.rb new file mode 100644 index 000000000..e3a6dfcb4 --- /dev/null +++ b/db/migrate/20170922123838_remove_compliance_control_block_id_from_compliance_controls.rb @@ -0,0 +1,5 @@ +class RemoveComplianceControlBlockIdFromComplianceControls < ActiveRecord::Migration +  def change +    remove_reference :compliance_controls, :compliance_control_block, index: true, foreign_key: true +  end +end diff --git a/db/migrate/20170925123159_add_output_to_workbenches.rb b/db/migrate/20170925123159_add_output_to_workbenches.rb new file mode 100644 index 000000000..d6aea96a0 --- /dev/null +++ b/db/migrate/20170925123159_add_output_to_workbenches.rb @@ -0,0 +1,5 @@ +class AddOutputToWorkbenches < ActiveRecord::Migration +  def change +    add_column :workbenches, :output_id, :bigint, index: true +  end +end diff --git a/db/migrate/20170925154017_create_referential_suite_for_each_existing_workbench.rb b/db/migrate/20170925154017_create_referential_suite_for_each_existing_workbench.rb new file mode 100644 index 000000000..530850a5a --- /dev/null +++ b/db/migrate/20170925154017_create_referential_suite_for_each_existing_workbench.rb @@ -0,0 +1,12 @@ +class CreateReferentialSuiteForEachExistingWorkbench < ActiveRecord::Migration +  def up +    Workbench.where(output: nil).each do |workbench| +      workbench.output = ReferentialSuite.create +      workbench.save +    end +  end + +  def down +    raise ActiveRecord::IrreversibleMigration +  end +end diff --git a/db/migrate/20170927095022_add_origin_code_to_compliance_controls.rb b/db/migrate/20170927095022_add_origin_code_to_compliance_controls.rb new file mode 100644 index 000000000..36f109b91 --- /dev/null +++ b/db/migrate/20170927095022_add_origin_code_to_compliance_controls.rb @@ -0,0 +1,5 @@ +class AddOriginCodeToComplianceControls < ActiveRecord::Migration +  def change +    add_column :compliance_controls, :origin_code, :string +  end +end diff --git a/db/migrate/20170928075431_add_origin_code_to_compliance_checks.rb b/db/migrate/20170928075431_add_origin_code_to_compliance_checks.rb new file mode 100644 index 000000000..43849bcfe --- /dev/null +++ b/db/migrate/20170928075431_add_origin_code_to_compliance_checks.rb @@ -0,0 +1,5 @@ +class AddOriginCodeToComplianceChecks < ActiveRecord::Migration +  def change +    add_column :compliance_checks, :origin_code, :string +  end +end diff --git a/db/schema.rb b/db/schema.rb index 89f002aee..a8c90b111 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@  #  # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170922165315) do +ActiveRecord::Schema.define(version: 20170925154017) do    # These are extensions that must be enabled in order to support this database    enable_extension "plpgsql" @@ -217,8 +217,10 @@ ActiveRecord::Schema.define(version: 20170922165315) do      t.integer  "compliance_control_set_id"      t.datetime "created_at",                null: false      t.datetime "updated_at",                null: false +    t.integer  "compliance_control_id"    end +  add_index "compliance_control_blocks", ["compliance_control_id"], name: "index_compliance_control_blocks_on_compliance_control_id", using: :btree    add_index "compliance_control_blocks", ["compliance_control_set_id"], name: "index_compliance_control_blocks_on_compliance_control_set_id", using: :btree    create_table "compliance_control_sets", id: :bigserial, force: :cascade do |t| @@ -232,18 +234,16 @@ ActiveRecord::Schema.define(version: 20170922165315) do    create_table "compliance_controls", id: :bigserial, force: :cascade do |t|      t.integer  "compliance_control_set_id" -    t.integer  "compliance_control_block_id"      t.string   "type"      t.json     "control_attributes"      t.string   "name"      t.string   "code"      t.string   "criticity"      t.text     "comment" -    t.datetime "created_at",                  null: false -    t.datetime "updated_at",                  null: false +    t.datetime "created_at",                null: false +    t.datetime "updated_at",                null: false    end -  add_index "compliance_controls", ["compliance_control_block_id"], name: "index_compliance_controls_on_compliance_control_block_id", using: :btree    add_index "compliance_controls", ["compliance_control_set_id"], name: "index_compliance_controls_on_compliance_control_set_id", using: :btree    create_table "connection_links", id: :bigserial, force: :cascade do |t| @@ -969,6 +969,7 @@ ActiveRecord::Schema.define(version: 20170922165315) do      t.datetime "updated_at"      t.integer  "line_referential_id",      limit: 8      t.integer  "stop_area_referential_id", limit: 8 +    t.integer  "output_id",                limit: 8    end    add_index "workbenches", ["line_referential_id"], name: "index_workbenches_on_line_referential_id", using: :btree @@ -986,8 +987,8 @@ ActiveRecord::Schema.define(version: 20170922165315) do    add_foreign_key "compliance_checks", "compliance_check_blocks"    add_foreign_key "compliance_checks", "compliance_check_sets"    add_foreign_key "compliance_control_blocks", "compliance_control_sets" +  add_foreign_key "compliance_control_blocks", "compliance_controls"    add_foreign_key "compliance_control_sets", "organisations" -  add_foreign_key "compliance_controls", "compliance_control_blocks"    add_foreign_key "compliance_controls", "compliance_control_sets"    add_foreign_key "group_of_lines_lines", "group_of_lines", name: "groupofline_group_fkey", on_delete: :cascade    add_foreign_key "journey_frequencies", "timebands", on_delete: :nullify diff --git a/lib/stif/permission_translator.rb b/lib/stif/permission_translator.rb index d8f898b62..095f726bd 100644 --- a/lib/stif/permission_translator.rb +++ b/lib/stif/permission_translator.rb @@ -20,6 +20,7 @@ module Stif          connection_links          calendars          footnotes +        imports          journey_patterns          referentials          routes @@ -34,7 +35,6 @@ module Stif      end      def destructive_permissions_for(models) -      @__destructive_permissions_for__ ||=          models.product( %w{create destroy update} ).map{ |model_action| model_action.join('.') }      end diff --git a/spec/controllers/compliance_controls_controller_spec.rb b/spec/controllers/compliance_controls_controller_spec.rb index 165c00329..a39408ccb 100644 --- a/spec/controllers/compliance_controls_controller_spec.rb +++ b/spec/controllers/compliance_controls_controller_spec.rb @@ -3,8 +3,10 @@ require 'rails_helper'  RSpec.describe ComplianceControlsController, type: :controller do    login_user -  let(:compliance_control)     { create :compliance_control } -  let(:compliance_control_set) { compliance_control.compliance_control_set } + +  let(:compliance_control)        { create(:compliance_control) } +  let!(:compliance_control_set)   { compliance_control.compliance_control_set } +  let(:compliance_control_params) { compliance_control.as_json.merge(type: 'GenericAttributeControl::MinMax') }    describe "GET show" do      it 'should be successful' do @@ -13,13 +15,6 @@ RSpec.describe ComplianceControlsController, type: :controller do      end    end -  describe "GET index" do -    it 'should be successful' do -      get :index, compliance_control_set_id: compliance_control_set.id -      expect(response).to be_success -    end -  end -    describe 'GET #edit' do      it 'should be successful' do        get :edit, compliance_control_set_id: compliance_control_set.id, id: compliance_control.id @@ -36,24 +31,24 @@ RSpec.describe ComplianceControlsController, type: :controller do    describe 'POST #create' do      it 'should be successful' do -      post :create, compliance_control_set_id: compliance_control_set.id, compliance_control: build(:compliance_control).as_json +      post :create, compliance_control_set_id: compliance_control_set.id, compliance_control: compliance_control_params        expect(response).to have_http_status(302) -      expect(flash[:notice]).to eq(I18n.t('notice.compliance_control.created'))      end    end    describe 'POST #update' do      it 'should be successful' do -      post :update, compliance_control_set_id: compliance_control_set.id, id: compliance_control.id, compliance_control: compliance_control.as_json +      post :update, compliance_control_set_id: compliance_control_set.id, id: compliance_control.id, compliance_control: compliance_control_params        expect(response).to redirect_to compliance_control_set_compliance_control_path(compliance_control_set, compliance_control) -      expect(flash[:notice]).to eq(I18n.t('notice.compliance_control.updated'))      end    end    describe 'DELETE #destroy' do      it 'should be successful' do -      delete :destroy, compliance_control_set_id: compliance_control_set.id, id: compliance_control.id -      expect(flash[:notice]).to eq I18n.t('notice.compliance_control.destroyed') +      expect { +        delete :destroy, compliance_control_set_id: compliance_control_set.id, id: compliance_control.id +      }.to change(GenericAttributeControl::MinMax, :count).by(-1) +      expect(response).to have_http_status(302)      end    end  end diff --git a/spec/controllers/imports_controller_spec.rb b/spec/controllers/imports_controller_spec.rb index f07190496..22be9f6ed 100644 --- a/spec/controllers/imports_controller_spec.rb +++ b/spec/controllers/imports_controller_spec.rb @@ -5,10 +5,16 @@ RSpec.describe ImportsController, :type => :controller do    let(:import)    { create :import, workbench: workbench }    describe 'GET #new' do -    it 'should be successful' do +    it 'should be successful if authorized' do        get :new, workbench_id: workbench.id        expect(response).to be_success      end + +    it 'should be unsuccessful unless authorized' do +      remove_permissions('imports.create', from_user: @user, save: true) +      get :new, workbench_id: workbench.id +      expect(response).not_to be_success +    end    end    describe 'GET #download' do @@ -18,4 +24,5 @@ RSpec.describe ImportsController, :type => :controller do        expect( response.body ).to eq(import.file.read)      end    end +  end diff --git a/spec/factories/compliance_checks.rb b/spec/factories/compliance_checks.rb index 4009653da..f9af62c73 100644 --- a/spec/factories/compliance_checks.rb +++ b/spec/factories/compliance_checks.rb @@ -4,6 +4,7 @@ FactoryGirl.define do      type "Type"      criticity :info      code "code" +    origin_code "code"      comment "Text"      association :compliance_check_set      association :compliance_check_block diff --git a/spec/factories/compliance_control_blocks.rb b/spec/factories/compliance_control_blocks.rb index 5bc45cc75..1b043324e 100644 --- a/spec/factories/compliance_control_blocks.rb +++ b/spec/factories/compliance_control_blocks.rb @@ -2,5 +2,6 @@ FactoryGirl.define do    factory :compliance_control_block do      sequence(:name) { |n| "Compliance control block #{n}" }      association :compliance_control_set +    association :compliance_control    end  end diff --git a/spec/factories/compliance_controls.rb b/spec/factories/compliance_controls.rb index 8aa16b674..ced505565 100644 --- a/spec/factories/compliance_controls.rb +++ b/spec/factories/compliance_controls.rb @@ -1,11 +1,11 @@  FactoryGirl.define do    factory :compliance_control do      sequence(:name) { |n| "Compliance control #{n}" } -    type "ComplianceControl" +    type "GenericAttributeControl::MinMax"      criticity :warning      code "code" +    origin_code "code"      comment "Text"      association :compliance_control_set -    association :compliance_control_block    end  end diff --git a/spec/factories/referential_suites.rb b/spec/factories/referential_suites.rb new file mode 100644 index 000000000..bb17b085c --- /dev/null +++ b/spec/factories/referential_suites.rb @@ -0,0 +1,3 @@ +FactoryGirl.define do +  factory :referential_suite +end diff --git a/spec/factories/workbenches.rb b/spec/factories/workbenches.rb index d55141513..57bef2203 100644 --- a/spec/factories/workbenches.rb +++ b/spec/factories/workbenches.rb @@ -5,5 +5,6 @@ FactoryGirl.define do      association :organisation      association :line_referential      association :stop_area_referential +    association :output, factory: :referential_suite    end  end diff --git a/spec/models/compliance_check_spec.rb b/spec/models/compliance_check_spec.rb index 4fbc23d42..acdcc3ebf 100644 --- a/spec/models/compliance_check_spec.rb +++ b/spec/models/compliance_check_spec.rb @@ -11,4 +11,5 @@ RSpec.describe ComplianceCheck, type: :model do    it { should validate_presence_of :criticity }    it { should validate_presence_of :name }    it { should validate_presence_of :code } +  it { should validate_presence_of :origin_code }  end diff --git a/spec/models/compliance_control_block_spec.rb b/spec/models/compliance_control_block_spec.rb index 248049b0c..f45ec3d42 100644 --- a/spec/models/compliance_control_block_spec.rb +++ b/spec/models/compliance_control_block_spec.rb @@ -1,9 +1,12 @@  require 'rails_helper'  RSpec.describe ComplianceControlBlock, type: :model do +  subject { create(:compliance_control_block) } +    it 'should have a valid factory' do      expect(FactoryGirl.build(:compliance_control_block)).to be_valid    end    it { should belong_to :compliance_control_set } +  it { should belong_to :compliance_control }  end diff --git a/spec/models/compliance_control_set_spec.rb b/spec/models/compliance_control_set_spec.rb index ededec5e0..edc684bbc 100644 --- a/spec/models/compliance_control_set_spec.rb +++ b/spec/models/compliance_control_set_spec.rb @@ -6,7 +6,7 @@ RSpec.describe ComplianceControlSet, type: :model do    end    it { should belong_to :organisation } -  it { should have_many :compliance_controls } +  it { should have_many(:compliance_controls).dependent(:destroy) }    it { should validate_presence_of :name }  end diff --git a/spec/models/compliance_control_spec.rb b/spec/models/compliance_control_spec.rb index b00ff4c5a..d7bffb0b2 100644 --- a/spec/models/compliance_control_spec.rb +++ b/spec/models/compliance_control_spec.rb @@ -1,14 +1,41 @@  require 'rails_helper'  RSpec.describe ComplianceControl, type: :model do + +  let(:compliance_control) { create :compliance_control } +    it 'should have a valid factory' do -    expect(FactoryGirl.build(:compliance_control)).to be_valid +    expect(compliance_control).to be_valid    end    it { should belong_to :compliance_control_set } -  it { should belong_to :compliance_control_block } +  it { should have_one(:compliance_control_block).dependent(:destroy) } + +  it 'should validate_presence_of criticity' do +    compliance_control.criticity = nil +    expect(compliance_control).not_to be_valid +  end + +  it 'should validate_presence_of name' do +    compliance_control.name = nil +    expect(compliance_control).not_to be_valid +  end + +  it 'should validate_presence_of code' do +    compliance_control.code = nil +    expect(compliance_control).not_to be_valid +  end + +  it 'should validate_presence_of origin_code' do +    compliance_control.origin_code = nil +    expect(compliance_control).not_to be_valid +  end -  it { should validate_presence_of :criticity } -  it { should validate_presence_of :name } -  it { should validate_presence_of :code } +  #TODO dont know why the 'shortcuts' below to validates presence dont work +  # That's why we dont it 'manually' +  # it { should validate_presence_of :criticity } +  # it { should validate_presence_of :name } +  # it { should validate_presence_of :code } +  # it { should validate_presence_of :origin_code } +    end diff --git a/spec/models/workbench_spec.rb b/spec/models/workbench_spec.rb index 84149ddb0..037537b60 100644 --- a/spec/models/workbench_spec.rb +++ b/spec/models/workbench_spec.rb @@ -11,6 +11,7 @@ RSpec.describe Workbench, :type => :model do    it { should belong_to(:organisation) }    it { should belong_to(:line_referential) }    it { should belong_to(:stop_area_referential) } +  it { should belong_to(:output).class_name('ReferentialSuite') }    it { should have_many(:lines).through(:line_referential) }    it { should have_many(:networks).through(:line_referential) } @@ -19,6 +20,15 @@ RSpec.describe Workbench, :type => :model do    it { should have_many(:stop_areas).through(:stop_area_referential) } +  it do +    # This callback interferes with the validation test +    Workbench.skip_callback(:validation, :before, :initialize_output) + +    should validate_presence_of(:output) + +    Workbench.set_callback(:validation, :before, :initialize_output) +  end +    context '.lines' do      let!(:ids) { ['STIF:CODIFLIGNE:Line:C00840', 'STIF:CODIFLIGNE:Line:C00086'] }      let!(:organisation) { create :organisation, sso_attributes: { functional_scope: ids.to_json } } @@ -33,4 +43,18 @@ RSpec.describe Workbench, :type => :model do        expect(lines.map(&:objectid)).to include(*ids)      end    end + +  describe ".create" do +    it "must automatically create a ReferentialSuite when being created" do +      workbench = Workbench.create +      expect(workbench.output).to be_an_instance_of(ReferentialSuite) +    end + +    it "must not overwrite a given ReferentialSuite" do +      referential_suite = create(:referential_suite) +      workbench = create(:workbench, output: referential_suite) + +      expect(workbench.output).to eq(referential_suite) +    end +  end  end diff --git a/spec/policies/api_key_policy_spec.rb b/spec/policies/api_key_policy_spec.rb index f0242978e..3638a05b2 100644 --- a/spec/policies/api_key_policy_spec.rb +++ b/spec/policies/api_key_policy_spec.rb @@ -21,7 +21,7 @@ RSpec.describe ApiKeyPolicy do      end      context 'permission present → '  do        it 'allows a user with a different organisation' do -        add_permissions('api_keys.create', for_user: user) +        add_permissions('api_keys.create', to_user: user)          expect_it.to permit(user_context, record)        end      end @@ -40,7 +40,7 @@ RSpec.describe ApiKeyPolicy do      context 'permission present → '  do        before do -        add_permissions('api_keys.update', for_user: user) +        add_permissions('api_keys.update', to_user: user)        end        it 'denies a user with a different organisation' do diff --git a/spec/policies/import_policy_spec.rb b/spec/policies/import_policy_spec.rb new file mode 100644 index 000000000..fd9f3172c --- /dev/null +++ b/spec/policies/import_policy_spec.rb @@ -0,0 +1,41 @@ +RSpec.describe ImportPolicy, type: :policy do + +  let( :record ){ build_stubbed :import } +  before { stub_policy_scope(record) } + +  # +  #  Non Destructive +  #  --------------- + +  context 'Non Destructive actions →' do +    permissions :index? do +      it_behaves_like 'always allowed', 'anything', archived: true +    end +    permissions :show? do +      it_behaves_like 'always allowed', 'anything', archived: true +    end +  end + + +  # +  #  Destructive +  #  ----------- + +  context 'Destructive actions →' do +    permissions :create? do +      it_behaves_like 'permitted policy', 'imports.create', archived: true +    end +    permissions :destroy? do +      it_behaves_like 'permitted policy', 'imports.destroy', archived: true +    end +    permissions :edit? do +      it_behaves_like 'permitted policy', 'imports.update', archived: true +    end +    permissions :new? do +      it_behaves_like 'permitted policy', 'imports.create', archived: true +    end +    permissions :update? do +      it_behaves_like 'permitted policy', 'imports.update', archived: true +    end +  end +end diff --git a/spec/policies/referential_policy_spec.rb b/spec/policies/referential_policy_spec.rb index 69d0eb17b..d00415fc6 100644 --- a/spec/policies/referential_policy_spec.rb +++ b/spec/policies/referential_policy_spec.rb @@ -9,7 +9,7 @@ RSpec.describe ReferentialPolicy, type: :policy do    permissions :create? do      it 'permissions present → allowed' do -      add_permissions('referentials.create', for_user: user) +      add_permissions('referentials.create', to_user: user)        expect_it.to permit(user_context, record)      end      it 'permissions absent → forbidden' do @@ -19,7 +19,7 @@ RSpec.describe ReferentialPolicy, type: :policy do    permissions :new? do      it 'permissions present → allowed' do -      add_permissions('referentials.create', for_user: user) +      add_permissions('referentials.create', to_user: user)        expect_it.to permit(user_context, record)      end      it 'permissions absent → forbidden' do @@ -53,7 +53,7 @@ RSpec.describe ReferentialPolicy, type: :policy do      context 'permission present →' do        before do -        add_permissions('referentials.update', for_user: user) +        add_permissions('referentials.update', to_user: user)        end        context 'same organisation →' do @@ -108,7 +108,7 @@ RSpec.describe ReferentialPolicy, type: :policy do      context 'permission present →' do        before do -        add_permissions('referentials.update', for_user: user) +        add_permissions('referentials.update', to_user: user)        end        context 'same organisation →' do diff --git a/spec/support/permissions.rb b/spec/support/permissions.rb index 467c07a32..13666aca3 100644 --- a/spec/support/permissions.rb +++ b/spec/support/permissions.rb @@ -18,6 +18,7 @@ module Support        connection_links        calendars        footnotes +      imports        journey_patterns        referentials        routes diff --git a/spec/support/pundit/policies.rb b/spec/support/pundit/policies.rb index d5bb63243..a3489d9db 100644 --- a/spec/support/pundit/policies.rb +++ b/spec/support/pundit/policies.rb @@ -3,18 +3,18 @@ require 'pundit/rspec'  module Support    module Pundit      module Policies -      def add_permissions(*permissions, for_user:) -        for_user.permissions ||= [] -        for_user.permissions += permissions.flatten +      def add_permissions(*permissions, to_user:) +        to_user.permissions ||= [] +        to_user.permissions += permissions.flatten        end        def create_user_context(user:, referential:)          UserContext.new(user, referential: referential)        end -      def add_permissions(*permissions, for_user:) -        for_user.permissions ||= [] -        for_user.permissions += permissions.flatten +      def remove_permissions(*permissions, from_user:, save: false) +        from_user.permissions -= permissions.flatten +        from_user.save! if save        end      end @@ -30,7 +30,7 @@ module Support        end        def with_user_permission(permission, &blk)          it "with user permission #{permission.inspect}" do -          add_permissions(permission, for_user: user) +          add_permissions(permission, to_user: user)            blk.()          end        end @@ -41,7 +41,7 @@ module Support          perms, options = permissions.partition{|x| String === x}          context "with permissions #{perms.inspect}...", *options do            before do -            add_permissions(*permissions, for_user: @user) +            add_permissions(*permissions, to_user: @user)            end            instance_eval(&blk)          end @@ -51,6 +51,7 @@ module Support  end  RSpec.configure do | c | +  c.include Support::Pundit::Policies, type: :controller    c.include Support::Pundit::Policies, type: :policy    c.extend Support::Pundit::PoliciesMacros, type: :policy    c.include Support::Pundit::Policies, type: :feature diff --git a/spec/support/pundit/shared_examples.rb b/spec/support/pundit/shared_examples.rb index 63a106759..49c6845da 100644 --- a/spec/support/pundit/shared_examples.rb +++ b/spec/support/pundit/shared_examples.rb @@ -18,7 +18,7 @@ RSpec.shared_examples 'always allowed' do    context 'different organisations →' do      before do -      add_permissions(permission, for_user: user) +      add_permissions(permission, to_user: user)      end      it "allows a user with a different organisation" do        expect_it.to permit(user_context, record) @@ -51,7 +51,7 @@ RSpec.shared_examples 'always forbidden' do    context 'different organisations →' do      before do -      add_permissions(permission, for_user: user) +      add_permissions(permission, to_user: user)      end      it "denies a user with a different organisation" do        expect_it.not_to permit(user_context, record) @@ -80,7 +80,7 @@ RSpec.shared_examples 'permitted policy and same organisation' do    context 'permission present → '  do      before do -      add_permissions(permission, for_user: user) +      add_permissions(permission, to_user: user)      end      it 'denies a user with a different organisation' do @@ -113,7 +113,7 @@ RSpec.shared_examples 'permitted policy' do    context 'permission present → '  do      before do -      add_permissions(permission, for_user: user) +      add_permissions(permission, to_user: user)      end      it 'allows user' do diff --git a/spec/support/referential.rb b/spec/support/referential.rb index 3b74cb639..6f60bd86b 100644 --- a/spec/support/referential.rb +++ b/spec/support/referential.rb @@ -52,8 +52,21 @@ RSpec.configure do |config|        referential.add_member organisation, owner: true      end -    workbench = Workbench.create!(:name => "Gestion de l'offre", organisation: organisation, line_referential: line_referential, stop_area_referential: stop_area_referential) -    referential = Referential.create! prefix: "first", name: "first", slug: "first", organisation: organisation, workbench: workbench +    workbench = FactoryGirl.create( +      :workbench, +      name: "Gestion de l'offre", +      organisation: organisation, +      line_referential: line_referential, +      stop_area_referential: stop_area_referential +    ) +    referential = FactoryGirl.create( +      :referential, +      prefix: "first", +      name: "first", +      slug: "first", +      organisation: organisation, +      workbench: workbench +    )    end    config.before(:each) do | 
