diff options
| author | cedricnjanga | 2017-09-21 17:38:38 +0200 |
|---|---|---|
| committer | cedricnjanga | 2017-09-21 17:38:38 +0200 |
| commit | 59232a28f81d29a7b675ab6225c337071dbc05ef (patch) | |
| tree | 288d27f40a1addb71541c5e41fe3452383152908 | |
| parent | dbb06d00c316147a3eec022f555903d758452102 (diff) | |
| parent | 95efd2d3bf7dea6c2f659d42d1c37cbb2a5fd831 (diff) | |
| download | chouette-core-59232a28f81d29a7b675ab6225c337071dbc05ef.tar.bz2 | |
Merge branch 'master' into staging
108 files changed, 1720 insertions, 255 deletions
diff --git a/.gitignore b/.gitignore index 29cc18f2e..41d838ee0 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,7 @@ public/assets/ chouette2.war vendor/bundle .ruby-version +.byebug_history start.sh coverage @@ -120,6 +120,7 @@ gem 'acts-as-taggable-on', '~> 4.0.0' gem 'acts_as_list', '~> 0.6.0' gem 'acts_as_tree', '~> 2.1.0', require: 'acts_as_tree' +gem "hstore_accessor", "~> 1.1" gem 'rabl' gem 'carrierwave', '~> 1.0' diff --git a/Gemfile.lock b/Gemfile.lock index 1e2ac3cf8..fef3270a3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -255,6 +255,8 @@ GEM hashdiff (0.3.4) highline (1.7.8) hike (1.2.3) + hstore_accessor (1.1.0) + activerecord (>= 4.0.0) htmlbeautifier (1.3.1) httparty (0.14.0) multi_xml (>= 0.5.2) @@ -602,6 +604,7 @@ DEPENDENCIES georuby-ext (= 0.0.5) google-analytics-rails has_array_of! + hstore_accessor (~> 1.1) htmlbeautifier i18n-tasks inherited_resources 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 02ece1654..ba5d91568 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/actions/index.js +++ b/app/assets/javascripts/es6_browserified/time_tables/actions/index.js @@ -113,14 +113,26 @@ const actions = { timetableInDates, error }), - includeDateInPeriod: (index, dayTypes, date) => ({ - type: 'INCLUDE_DATE_IN_PERIOD', + addIncludedDate: (index, dayTypes, date) => ({ + type: 'ADD_INCLUDED_DATE', index, dayTypes, date }), - excludeDateFromPeriod: (index, dayTypes, date) => ({ - type: 'EXCLUDE_DATE_FROM_PERIOD', + removeIncludedDate: (index, dayTypes, date) => ({ + type: 'REMOVE_INCLUDED_DATE', + index, + dayTypes, + date + }), + addExcludedDate: (index, dayTypes, date) => ({ + type: 'ADD_EXCLUDED_DATE', + index, + dayTypes, + date + }), + removeExcludedDate: (index, dayTypes, date) => ({ + type: 'REMOVE_EXCLUDED_DATE', index, dayTypes, date @@ -157,43 +169,31 @@ const actions = { let date = new Date(strDate) return date.toLocaleDateString() }, + updateSynthesis: ({current_month, time_table_dates: dates, time_table_periods: periods}) => { + let newPeriods = _.reject(periods, 'deleted') + let improvedCM = current_month.map((d, i) => { + let isInPeriod = actions.isInPeriod(newPeriods, d.date) + let isIncluded = _.some(dates, {'date': d.date, 'in_out': true}) - updateSynthesis: (state, daytypes) => { - let periods = state.time_table_periods - - let isInPeriod = function(d){ - let currentMonth = state.current_periode_range.split('-') - let twodigitsDay = d.mday < 10 ? ('0' + d.mday) : d.mday - let currentDate = new Date(currentMonth[0] + '-' + currentMonth[1] + '-' + twodigitsDay) - - // We compare periods & currentDate, to determine if it is included or not - let testDate = false - periods.map((p, i) => { - if (p.deleted) return false - - let begin = new Date(p.period_start) - let end = new Date(p.period_end) - - if(testDate === false){ - if(currentDate >= begin && currentDate <= end) { - testDate = true - // p.include_date = false - } - } - }) - return testDate - } - - let improvedCM = state.current_month.map((d, i) => { - let bool = isInPeriod(state.current_month[i]) - return _.assign({}, state.current_month[i], { - in_periods: bool, - include_date: bool ? false : state.current_month[i].include_date, - excluded_date: !bool ? false : state.current_month[i].excluded_date + return _.assign({}, current_month[i], { + in_periods: isInPeriod, + include_date: isIncluded, + excluded_date: !isInPeriod ? false : current_month[i].excluded_date }) }) return improvedCM }, + isInPeriod: (periods, date) => { + date = new Date(date) + + for (let period of periods) { + let begin = new Date(period.period_start) + let end = new Date(period.period_end) + if (date >= begin && date <= end) return true + } + + return false + }, checkConfirmModal: (event, callback, stateChanged, dispatch, metas, timetable) => { if(stateChanged){ const error = actions.errorModalKey(timetable.time_table_periods, metas.day_types) @@ -318,13 +318,6 @@ const actions = { } }, - checkIfTTHasDate: (dates, date) => { - if (_.some(dates, date)) { - return _.reject(dates, ['date', date.date]) - } else { - return dates.concat(date) - } - } } module.exports = actions diff --git a/app/assets/javascripts/es6_browserified/time_tables/components/ExceptionsInDay.js b/app/assets/javascripts/es6_browserified/time_tables/components/ExceptionsInDay.js index 4879e537f..80c2e4b7a 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/components/ExceptionsInDay.js +++ b/app/assets/javascripts/es6_browserified/time_tables/components/ExceptionsInDay.js @@ -8,6 +8,15 @@ class ExceptionsInDay extends Component { super(props) } + handleClick() { + const {index, day, metas: {day_types} } = this.props + if (day.in_periods && day_types[day.wday]) { + day.excluded_date ? this.props.onRemoveExcludedDate(index, day_types, day.date) : this.props.onAddExcludedDate(index, day_types, day.date) + } else { + day.include_date ? this.props.onRemoveIncludedDate(index, day_types, day.date) : this.props.onAddIncludedDate(index, day_types, day.date) + } + } + render() { {/* display add or remove link, only if true in daytypes */} {/* display add or remove link, according to context (presence in period, or not) */} @@ -20,14 +29,14 @@ class ExceptionsInDay extends Component { data-actiontype='remove' onClick={(e) => { $(e.currentTarget).toggleClass('active') - this.props.onExcludeDateFromPeriod(this.props.index, this.props.metas.day_types, this.props.currentDate) + this.handleClick() }} > <span className='fa fa-times'></span> </button> </div> ) - } else if(this.props.value.current_month[this.props.index].in_periods == false) { + } else { return ( <div className='td'> <button @@ -36,20 +45,21 @@ class ExceptionsInDay extends Component { data-actiontype='add' onClick={(e) => { $(e.currentTarget).toggleClass('active') - this.props.onIncludeDateInPeriod(this.props.index, this.props.metas.day_types, this.props.currentDate) + this.handleClick() }} > <span className='fa fa-plus'></span> </button> </div> ) - } else if(this.props.value.current_month[this.props.index].in_periods == true && this.props.blueDaytype == false){ - return ( - <div className='td'></div> - ) - } else{ - return false - } + // } else if(this.props.value.current_month[this.props.index].in_periods == true && this.props.blueDaytype == false){ + // return ( + // <div className='td'></div> + // ) + // } else{ + // return false + // } + } } } diff --git a/app/assets/javascripts/es6_browserified/time_tables/components/PeriodsInDay.js b/app/assets/javascripts/es6_browserified/time_tables/components/PeriodsInDay.js index ca44d3a07..f56509b99 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/components/PeriodsInDay.js +++ b/app/assets/javascripts/es6_browserified/time_tables/components/PeriodsInDay.js @@ -35,7 +35,7 @@ class PeriodsInDay extends Component { render() { return ( <div - className={this.isIn(this.props.currentDate)} + className={this.isIn(this.props.currentDate) + (this.props.metas.day_types[this.props.day.wday] || !this.props.day.in_periods ? '' : ' out_from_daytypes')} > {this.props.value.map((p, i) => { if(!p.deleted){ 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 3af1a11a4..a613549c3 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/components/Timetable.js +++ b/app/assets/javascripts/es6_browserified/time_tables/components/Timetable.js @@ -60,13 +60,14 @@ class Timetable extends Component{ {this.props.timetable.current_month.map((d, i) => <div key={i} - className={'td-group' + (this.props.metas.day_types[d.wday] || !d.in_periods ? '' : ' out_from_daytypes') + (d.wday == 0 ? ' last_wday' : '')} + className={'td-group'+ (d.wday == 0 ? ' last_wday' : '')} > {/* day_types */} - <div className="td"></div> + <div className={"td" + (this.props.metas.day_types[d.wday] || !d.in_periods ? '' : ' out_from_daytypes') }></div> {/* periods */} <PeriodsInDay + day={d} index={i} value={this.props.timetable.time_table_periods} currentDate={this.currentDate(this.props.timetable.current_periode_range, d.mday)} @@ -77,11 +78,16 @@ class Timetable extends Component{ {/* exceptions */} <ExceptionsInDay + day={d} index={i} value={this.props.timetable} currentDate={d.date} metas={this.props.metas} blueDaytype={this.props.metas.day_types[d.wday]} + onAddIncludedDate={this.props.onAddIncludedDate} + onRemoveIncludedDate={this.props.onRemoveIncludedDate} + onAddExcludedDate={this.props.onAddExcludedDate} + onRemoveExcludedDate={this.props.onRemoveExcludedDate} onExcludeDateFromPeriod={this.props.onExcludeDateFromPeriod} onIncludeDateInPeriod={this.props.onIncludeDateInPeriod} /> diff --git a/app/assets/javascripts/es6_browserified/time_tables/containers/Timetable.js b/app/assets/javascripts/es6_browserified/time_tables/containers/Timetable.js index 639a1e2ab..a37e99982 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/containers/Timetable.js +++ b/app/assets/javascripts/es6_browserified/time_tables/containers/Timetable.js @@ -15,6 +15,18 @@ const mapDispatchToProps = (dispatch) => { onDeletePeriod: (index, dayTypes) =>{ dispatch(actions.deletePeriod(index, dayTypes)) }, + onAddIncludedDate: (index, dayTypes, date) => { + dispatch(actions.addIncludedDate(index, dayTypes, date)) + }, + onRemoveIncludedDate: (index, dayTypes, date) => { + dispatch(actions.removeIncludedDate(index, dayTypes, date)) + }, + onAddExcludedDate: (index, dayTypes, date) => { + dispatch(actions.addExcludedDate(index, dayTypes, date)) + }, + onRemoveExcludedDate: (index, dayTypes, date) => { + dispatch(actions.removeExcludedDate(index, dayTypes, date)) + }, onExcludeDateFromPeriod: (index, dayTypes, date) => { dispatch(actions.excludeDateFromPeriod(index, dayTypes, date)) }, diff --git a/app/assets/javascripts/es6_browserified/time_tables/reducers/metas.js b/app/assets/javascripts/es6_browserified/time_tables/reducers/metas.js index 2ce084efd..ab5ed3d91 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/reducers/metas.js +++ b/app/assets/javascripts/es6_browserified/time_tables/reducers/metas.js @@ -15,8 +15,10 @@ const metas = (state = {}, action) => { case 'RECEIVE_MONTH': let dt = (typeof state.day_types === 'string') ? actions.strToArrayDayTypes(state.day_types) : state.day_types return _.assign({}, state, {day_types: dt}) - case 'INCLUDE_DATE_IN_PERIOD': - case 'EXCLUDE_DATE_FROM_PERIOD': + case 'ADD_INCLUDED_DATE': + case 'REMOVE_INCLUDED_DATE': + case 'ADD_EXCLUDED_DATE': + case 'REMOVE_EXCLUDED_DATE': case 'DELETE_PERIOD': case 'VALIDATE_PERIOD_FORM': return _.assign({}, state, {calendar: null}) diff --git a/app/assets/javascripts/es6_browserified/time_tables/reducers/pagination.js b/app/assets/javascripts/es6_browserified/time_tables/reducers/pagination.js index 45fec6b5f..f38b124d9 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/reducers/pagination.js +++ b/app/assets/javascripts/es6_browserified/time_tables/reducers/pagination.js @@ -20,8 +20,10 @@ const pagination = (state = {}, action) => { case 'CHANGE_PAGE': toggleOnConfirmModal() return _.assign({}, state, {currentPage : action.page, stateChanged: false}) - case 'INCLUDE_DATE_IN_PERIOD': - case 'EXCLUDE_DATE_FROM_PERIOD': + case 'ADD_INCLUDED_DATE': + case 'REMOVE_INCLUDED_DATE': + case 'ADD_EXCLUDED_DATE': + case 'REMOVE_EXCLUDED_DATE': case 'DELETE_PERIOD': case 'VALIDATE_PERIOD_FORM': case 'UPDATE_COMMENT': 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 390bdffb0..edb965065 100644 --- a/app/assets/javascripts/es6_browserified/time_tables/reducers/timetable.js +++ b/app/assets/javascripts/es6_browserified/time_tables/reducers/timetable.js @@ -1,7 +1,6 @@ const _ = require('lodash') var actions = require('../actions') -let newState = {} -let newDates = [] +let newState, newPeriods, newDates, newCM const timetable = (state = {}, action) => { switch (action.type) { @@ -11,14 +10,14 @@ const timetable = (state = {}, action) => { current_periode_range: action.json.current_periode_range, periode_range: action.json.periode_range, time_table_periods: action.json.time_table_periods, - time_table_dates: action.json.time_table_dates + time_table_dates: _.sortBy(action.json.time_table_dates, ['date']) }) - return _.assign({}, fetchedState, {current_month: actions.updateSynthesis(fetchedState, actions.strToArrayDayTypes(action.json.day_types))}) + return _.assign({}, fetchedState, {current_month: actions.updateSynthesis(fetchedState)}) case 'RECEIVE_MONTH': newState = _.assign({}, state, { current_month: action.json.days }) - return _.assign({}, newState, {current_month: actions.updateSynthesis(newState, actions.strToArrayDayTypes(action.json.day_types))}) + return _.assign({}, newState, {current_month: actions.updateSynthesis(newState)}) case 'GO_TO_PREVIOUS_PAGE': case 'GO_TO_NEXT_PAGE': let nextPage = action.nextPage ? 1 : -1 @@ -31,34 +30,44 @@ const timetable = (state = {}, action) => { actions.fetchTimeTables(action.dispatch, action.page) return _.assign({}, state, {current_periode_range: action.page}) case 'DELETE_PERIOD': - let ttperiods = state.time_table_periods.map((period, i) =>{ + newPeriods = state.time_table_periods.map((period, i) =>{ if(i == action.index){ period.deleted = true } return period }) - newState = _.assign({}, state, {time_table_periods : ttperiods}) - return _.assign({}, newState, {current_month: actions.updateSynthesis(newState, action.dayTypes)}) - case 'INCLUDE_DATE_IN_PERIOD': - newDates = actions.checkIfTTHasDate(state.time_table_dates, {date: action.date, in_out: true}) - let newCMi = state.current_month.map((d, i) => { - if(i == action.index){ - d.include_date = !d.include_date - } + let deletedPeriod = Array.of(state.time_table_periods[action.index]) + newDates = _.reject(state.time_table_dates, d => actions.isInPeriod(deletedPeriod, d.date) && !d.in_out) + newState = _.assign({}, state, {time_table_periods : newPeriods, time_table_dates: newDates}) + return _.assign({}, newState, { current_month: actions.updateSynthesis(newState)}) + case 'ADD_INCLUDED_DATE': + newDates = state.time_table_dates.concat({date: action.date, in_out: true}) + newCM = state.current_month.map((d, i) => { + if (i == action.index) d.include_date = true return d }) - newState = _.assign({}, state, {current_month: newCMi, time_table_dates: newDates}) - return _.assign({}, newState, {current_month: actions.updateSynthesis(newState, action.dayTypes)}) - case 'EXCLUDE_DATE_FROM_PERIOD': - newDates = actions.checkIfTTHasDate(state.time_table_dates, {date: action.date, in_out: false}) - let newCMe = state.current_month.map((d, i) => { - if(i == action.index){ - d.excluded_date = !d.excluded_date - } + return _.assign({}, state, {current_month: newCM, time_table_dates: newDates}) + case 'REMOVE_INCLUDED_DATE': + newDates = _.reject(state.time_table_dates, ['date', action.date]) + newCM = state.current_month.map((d, i) => { + if (i == action.index) d.include_date = false + return d + }) + return _.assign({}, state, {current_month: newCM, time_table_dates: newDates}) + case 'ADD_EXCLUDED_DATE': + newDates = state.time_table_dates.concat({date: action.date, in_out: false}) + newCM = state.current_month.map((d, i) => { + if (i == action.index) d.excluded_date = true + return d + }) + return _.assign({}, state, {current_month: newCM, time_table_dates: newDates}) + case 'REMOVE_EXCLUDED_DATE': + newDates = _.reject(state.time_table_dates, ['date', action.date]) + newCM = state.current_month.map((d, i) => { + if (i == action.index) d.excluded_date = false return d }) - newState = _.assign({}, state, {current_month: newCMe, time_table_dates: newDates}) - return _.assign({}, newState, {current_month: actions.updateSynthesis(newState, action.dayTypes)}) + return _.assign({}, state, {current_month: newCM, time_table_dates: newDates}) case 'UPDATE_DAY_TYPES': // We get the week days of the activated day types to reject the out_dates that that are out of newDayTypes let weekDays = _.reduce(action.dayTypes, (array, dt, i) => { @@ -67,11 +76,17 @@ const timetable = (state = {}, action) => { }, []) newDates = _.reject(state.time_table_dates, (d) => { - return d.in_out == false && !weekDays.includes(new Date(d.date).getDay()) + let weekDay = new Date(d.date).getDay() + + if (d.in_out) { + return actions.isInPeriod(state.time_table_periods, d.date) && weekDays.includes(weekDay) + } else { + return !weekDays.includes(weekDay) + } }) return _.assign({}, state, {time_table_dates: newDates}) case 'UPDATE_CURRENT_MONTH_FROM_DAYTYPES': - return _.assign({}, state, {current_month: actions.updateSynthesis(state, action.dayTypes)}) + return _.assign({}, state, {current_month: actions.updateSynthesis(state)}) case 'VALIDATE_PERIOD_FORM': if (action.error != '') return state @@ -81,8 +96,10 @@ const timetable = (state = {}, action) => { let newPeriods = JSON.parse(JSON.stringify(action.timeTablePeriods)) if (action.modalProps.index !== false){ - newPeriods[action.modalProps.index].period_start = period_start - newPeriods[action.modalProps.index].period_end = period_end + updatePeriod = newPeriods[action.modalProps.index] + updatePeriod.period_start = period_start + updatePeriod.period_end = period_end + newDates = _.reject(state.time_table_dates, d => actions.isInPeriod(newPeriods, d.date) && !d.in_out) }else{ let newPeriod = { period_start: period_start, @@ -90,8 +107,10 @@ const timetable = (state = {}, action) => { } newPeriods.push(newPeriod) } - newState =_.assign({}, state, {time_table_periods: newPeriods}) - return _.assign({}, newState, {current_month: actions.updateSynthesis(newState, action.metas.day_types)}) + + newDates = newDates || state.time_table_dates + newState =_.assign({}, state, {time_table_periods: newPeriods, time_table_dates: newDates}) + return _.assign({}, newState, {current_month: actions.updateSynthesis(newState)}) default: return state } diff --git a/app/assets/stylesheets/modules/_timetables.sass b/app/assets/stylesheets/modules/_timetables.sass index 84f1af043..b06972ef9 100644 --- a/app/assets/stylesheets/modules/_timetables.sass +++ b/app/assets/stylesheets/modules/_timetables.sass @@ -85,11 +85,14 @@ &:not(:last-child) > .td border-right: 2px solid $darkgrey - &.out_from_daytypes - background-image: linear-gradient(45deg, rgba($grey, 0.15) 0%, rgba($grey, 0.15) 49%, rgba($grey, 0.5) 50%, rgba($grey, 0.15) 51%, rgba($grey, 0.15) 99%, rgba($grey, 0.15) 100%) - background-size: 25px 25px + // &.out_from_daytypes + // background-image: linear-gradient(45deg, rgba($grey, 0.15) 0%, rgba($grey, 0.15) 49%, rgba($grey, 0.5) 50%, rgba($grey, 0.15) 51%, rgba($grey, 0.15) 99%, rgba($grey, 0.15) 100%) + // background-size: 25px 25px > .td + &.out_from_daytypes + background-image: linear-gradient(45deg, rgba($grey, 0.15) 0%, rgba($grey, 0.15) 49%, rgba($grey, 0.5) 50%, rgba($grey, 0.15) 51%, rgba($grey, 0.15) 99%, rgba($grey, 0.15) 100%) + background-size: 25px 25px &.in_periods background-color: rgba($gold, 0.5) border-left-color: rgba($gold, 0.5) diff --git a/app/controllers/compliance_control_sets_controller.rb b/app/controllers/compliance_control_sets_controller.rb new file mode 100644 index 000000000..c6f4288a9 --- /dev/null +++ b/app/controllers/compliance_control_sets_controller.rb @@ -0,0 +1,38 @@ +class ComplianceControlSetsController < BreadcrumbController + defaults resource_class: ComplianceControlSet + respond_to :html + + def index + index! do |format| + @q_for_form = @compliance_control_sets.ransack(params[:q]) + format.html { + @compliance_control_sets = decorate_compliance_control_sets(@q_for_form.result) + } + end + end + + def show + show! do + @compliance_control_set = @compliance_control_set.decorate + end + end + + def decorate_compliance_control_sets(compliance_control_sets) + ModelDecorator.decorate( + compliance_control_sets, + with: ComplianceControlSetDecorator + ) + end + + protected + + # def begin_of_association_chain + # current_organisation + # end + + private + + def compliance_control_set_params + params.require(:compliance_control_set).permit(:name, :id) + end +end diff --git a/app/controllers/compliance_controls_controller.rb b/app/controllers/compliance_controls_controller.rb new file mode 100644 index 000000000..dad9b935a --- /dev/null +++ b/app/controllers/compliance_controls_controller.rb @@ -0,0 +1,38 @@ +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')) + end + + def update + path = compliance_control_set_compliance_control_path(parent, resource) + 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, + ) + end + + def compliance_control_params + params.require(:compliance_control).permit(:name, :code, :criticity, :comment, :control_attributes) + end +end diff --git a/app/controllers/imports_controller.rb b/app/controllers/imports_controller.rb index fa8919f20..3333dc535 100644 --- a/app/controllers/imports_controller.rb +++ b/app/controllers/imports_controller.rb @@ -89,7 +89,6 @@ class ImportsController < BreadcrumbController def ransack_status_params if params[:q] - binding.pry return params[:q].delete(:status_eq_any) if params[:q][:status_eq_any].empty? || ( (Import.status.values & params[:q][:status_eq_any]).length >= 4 ) params[:q][:status_eq_any].push("new", "running") if params[:q][:status_eq_any].include?("pending") params[:q][:status_eq_any].push("aborted", "canceled") if params[:q][:status_eq_any].include?("failed") diff --git a/app/decorators/compliance_control_decorator.rb b/app/decorators/compliance_control_decorator.rb new file mode 100644 index 000000000..38b968ad1 --- /dev/null +++ b/app/decorators/compliance_control_decorator.rb @@ -0,0 +1,25 @@ +class ComplianceControlDecorator < Draper::Decorator + delegate_all + + def action_links + links = [] + + 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 + + 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) + ) + end + links + end + +end diff --git a/app/decorators/compliance_control_set_decorator.rb b/app/decorators/compliance_control_set_decorator.rb new file mode 100644 index 000000000..876a54d09 --- /dev/null +++ b/app/decorators/compliance_control_set_decorator.rb @@ -0,0 +1,26 @@ +class ComplianceControlSetDecorator < Draper::Decorator + delegate_all + + def action_links + links = [] + + # if h.policy(object).destroy? + links << Link.new( + content: h.destroy_link_content, + href: h.compliance_control_set_path(object.id), + method: :delete, + data: { confirm: h.t('compliance_control_sets.actions.destroy_confirm') } + ) + # end + + # if h.policy(object).edit? + links << Link.new( + content: h.t('compliance_control_sets.actions.edit'), + href: h.edit_compliance_control_set_path(object.id) + ) + # end + links + end + +end + diff --git a/app/helpers/breadcrumb_helper.rb b/app/helpers/breadcrumb_helper.rb index 55031d4f3..a3ee9de72 100644 --- a/app/helpers/breadcrumb_helper.rb +++ b/app/helpers/breadcrumb_helper.rb @@ -50,6 +50,8 @@ module BreadcrumbHelper compliance_check_breadcrumb action when "ComplianceCheckTask" compliance_check_task_breadcrumb action + when "ComplianceControlSets" + compliance_control_sets_breadcrumb action when "RuleParameterSet" rule_parameter_breadcrumb action when "User" @@ -239,6 +241,11 @@ module BreadcrumbHelper add_breadcrumb breadcrumb_label(@compliance_check_task), referential_compliance_check_task_path(@referential, @compliance_check_task),:title => breadcrumb_tooltip(@compliance_check_task) if action == :edit end + def compliance_control_sets_breadcrumb (action) + add_breadcrumb I18n.t("breadcrumbs.referentials"), workbenches_path + #add_breadcrumb breadcrumb_label(@workbench), workbench_path(@workbench), :title => breadcrumb_tooltip(@workbench) + end + def rule_parameter_breadcrumb (action) organisation_breadcrumb add_breadcrumb Referential.human_attribute_name("rule_parameter_sets"), organisation_path unless action == :index diff --git a/app/helpers/compliance_control_sets_helper.rb b/app/helpers/compliance_control_sets_helper.rb new file mode 100644 index 000000000..6ba4bed4f --- /dev/null +++ b/app/helpers/compliance_control_sets_helper.rb @@ -0,0 +1,7 @@ +module ComplianceControlSetsHelper + + def organisations_filters_values + [current_organisation, Organisation.find_by_name("STIF")].uniq + end + +end diff --git a/app/helpers/table_builder_helper.rb b/app/helpers/table_builder_helper.rb index ec4d487c1..95f53a90d 100644 --- a/app/helpers/table_builder_helper.rb +++ b/app/helpers/table_builder_helper.rb @@ -344,7 +344,6 @@ module TableBuilderHelper ) end end - def gear_menu_link(link) content_tag( :li, diff --git a/app/helpers/table_builder_helper/url.rb b/app/helpers/table_builder_helper/url.rb index f7ba703ae..a53ac5620 100644 --- a/app/helpers/table_builder_helper/url.rb +++ b/app/helpers/table_builder_helper/url.rb @@ -3,7 +3,7 @@ module TableBuilderHelper def self.polymorphic_url_parts(item, referential) polymorph_url = [] - unless item.is_a?(Calendar) || item.is_a?(Referential) + unless item.is_a?(Calendar) || item.is_a?(Referential) || item.is_a?(ComplianceControlSet) if referential polymorph_url << referential polymorph_url << item.line if item.respond_to? :line diff --git a/app/models/chouette/vehicle_journey_at_stop.rb b/app/models/chouette/vehicle_journey_at_stop.rb index 156cc761f..a4a4a02c8 100644 --- a/app/models/chouette/vehicle_journey_at_stop.rb +++ b/app/models/chouette/vehicle_journey_at_stop.rb @@ -41,7 +41,7 @@ module Chouette :arrival_day_offset, I18n.t( 'vehicle_journey_at_stops.errors.day_offset_must_not_exceed_max', - local_id: vehicle_journey.objectid.local_id, + short_id: vehicle_journey.objectid.short_id, max: DAY_OFFSET_MAX + 1 ) ) @@ -52,7 +52,7 @@ module Chouette :departure_day_offset, I18n.t( 'vehicle_journey_at_stops.errors.day_offset_must_not_exceed_max', - local_id: vehicle_journey.objectid.local_id, + short_id: vehicle_journey.objectid.short_id, max: DAY_OFFSET_MAX + 1 ) ) diff --git a/app/models/compliance_check_result.rb b/app/models/compliance_check_message.rb index 161e45189..86899eb15 100644 --- a/app/models/compliance_check_result.rb +++ b/app/models/compliance_check_message.rb @@ -1,4 +1,4 @@ -class ComplianceCheckResult < ActiveRecord::Base +class ComplianceCheckMessage < ActiveRecord::Base belongs_to :compliance_check belongs_to :compliance_check_resource end diff --git a/app/models/compliance_control.rb b/app/models/compliance_control.rb index 64556b524..12ff4737a 100644 --- a/app/models/compliance_control.rb +++ b/app/models/compliance_control.rb @@ -2,8 +2,11 @@ class ComplianceControl < ActiveRecord::Base belongs_to :compliance_control_set belongs_to :compliance_control_block - enum criticity: [:info, :warning, :error] + 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 :compliance_control_set, presence: true end diff --git a/app/models/compliance_control_set.rb b/app/models/compliance_control_set.rb index 7801eb612..cefdfbf1f 100644 --- a/app/models/compliance_control_set.rb +++ b/app/models/compliance_control_set.rb @@ -1,3 +1,7 @@ class ComplianceControlSet < ActiveRecord::Base belongs_to :organisation + has_many :compliance_controls + + validates :name, presence: true + end diff --git a/app/models/generic_attribute_min_max.rb b/app/models/generic_attribute_min_max.rb new file mode 100644 index 000000000..e9a127c56 --- /dev/null +++ b/app/models/generic_attribute_min_max.rb @@ -0,0 +1,27 @@ +#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 new file mode 100644 index 000000000..0043f1563 --- /dev/null +++ b/app/models/generic_attribute_pattern.rb @@ -0,0 +1,23 @@ +#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 new file mode 100644 index 000000000..dcf4a16c2 --- /dev/null +++ b/app/models/generic_attribute_uniqueness.rb @@ -0,0 +1,23 @@ +#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 new file mode 100644 index 000000000..78ca07e90 --- /dev/null +++ b/app/models/journey_pattern_control/duplicates.rb @@ -0,0 +1,13 @@ +module JourneyPatternControl + class Duplicates < ComplianceControl + + @@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 new file mode 100644 index 000000000..a90c16138 --- /dev/null +++ b/app/models/journey_pattern_control/vehicle_journey.rb @@ -0,0 +1,13 @@ +module JourneyPatternControl + class VehicleJourney < ComplianceControl + + @@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 new file mode 100644 index 000000000..8ac13a080 --- /dev/null +++ b/app/models/line_control/route.rb @@ -0,0 +1,13 @@ +module LineControl + class Route < ComplianceControl + + @@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/organisation.rb b/app/models/organisation.rb index 895ca03d9..ba65ad375 100644 --- a/app/models/organisation.rb +++ b/app/models/organisation.rb @@ -4,6 +4,7 @@ class Organisation < ActiveRecord::Base has_many :users, :dependent => :destroy has_many :referentials, :dependent => :destroy has_many :rule_parameter_sets, :dependent => :destroy + has_many :compliance_control_sets, :dependent => :destroy has_many :stop_area_referential_memberships has_many :stop_area_referentials, through: :stop_area_referential_memberships diff --git a/app/models/route_control/duplicates.rb b/app/models/route_control/duplicates.rb new file mode 100644 index 000000000..379d7cf98 --- /dev/null +++ b/app/models/route_control/duplicates.rb @@ -0,0 +1,13 @@ +module RouteControl + class Duplicates < ComplianceControl + + @@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 new file mode 100644 index 000000000..0559fac42 --- /dev/null +++ b/app/models/route_control/journey_pattern.rb @@ -0,0 +1,13 @@ +module RouteControl + class JourneyPattern < ComplianceControl + + @@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 new file mode 100644 index 000000000..14bc7064f --- /dev/null +++ b/app/models/route_control/minimum_length.rb @@ -0,0 +1,13 @@ +module RouteControl + class MinimumLength < ComplianceControl + + @@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 new file mode 100644 index 000000000..2f09ff735 --- /dev/null +++ b/app/models/route_control/omnibus_journey_pattern.rb @@ -0,0 +1,13 @@ +module RouteControl + class OmnibusJourneyPattern < ComplianceControl + + @@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 new file mode 100644 index 000000000..d5f2bc59e --- /dev/null +++ b/app/models/route_control/opposite_route.rb @@ -0,0 +1,14 @@ +module RouteControl + class OppositeRoute < ComplianceControl + + @@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 new file mode 100644 index 000000000..e72229ca3 --- /dev/null +++ b/app/models/route_control/opposite_route_terminus.rb @@ -0,0 +1,13 @@ +module RouteControl + class OppositeRouteTerminus < ComplianceControl + + @@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 new file mode 100644 index 000000000..fb07b5c87 --- /dev/null +++ b/app/models/route_control/speed.rb @@ -0,0 +1,15 @@ +module VehicleJourneyControl + class Speed < ComplianceControl + + hstore_accessor :control_attributes, minimum: :integer, maximum: :integer + + @@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 new file mode 100644 index 000000000..195257a4a --- /dev/null +++ b/app/models/route_control/stop_points_in_journey_pattern.rb @@ -0,0 +1,13 @@ +module RouteControl + class StopPointInJourneyPattern < ComplianceControl + + @@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 new file mode 100644 index 000000000..911807ba9 --- /dev/null +++ b/app/models/route_control/time_table.rb @@ -0,0 +1,13 @@ +module VehicleJourneyControl + class TimeTable < ComplianceControl + + @@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 new file mode 100644 index 000000000..8ab680490 --- /dev/null +++ b/app/models/route_control/unactivated_stop_points.rb @@ -0,0 +1,13 @@ +module RouteControl + class UnactivatedStopPoint < ComplianceControl + + @@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 new file mode 100644 index 000000000..02a43fb10 --- /dev/null +++ b/app/models/route_control/vehicle_journey_at_stops.rb @@ -0,0 +1,13 @@ +module VehicleJourneyControl + class VehicleJourneyAtStops < ComplianceControl + + @@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 new file mode 100644 index 000000000..4561c9b2e --- /dev/null +++ b/app/models/route_control/zdl_stop_area.rb @@ -0,0 +1,13 @@ +module RouteControl + class ZDLStopArea < ComplianceControl + + @@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 new file mode 100644 index 000000000..fd63ffeda --- /dev/null +++ b/app/models/routing_constaint_zone_control/maximum_length.rb @@ -0,0 +1,13 @@ +module RoutingConstaintZoneControl + class MaximumLength < ComplianceControl + + @@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 new file mode 100644 index 000000000..c17bbc834 --- /dev/null +++ b/app/models/routing_constaint_zone_control/minimum_length.rb @@ -0,0 +1,13 @@ +module RoutingConstaintZoneControl + class MinimumLength < ComplianceControl + + @@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 new file mode 100644 index 000000000..92a1d1a58 --- /dev/null +++ b/app/models/routing_constaint_zone_control/unactivated_stop_point.rb @@ -0,0 +1,13 @@ +module RoutingConstaintZoneControl + class UnactivatedStopPoint < ComplianceControl + + @@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 new file mode 100644 index 000000000..d4e1e6eca --- /dev/null +++ b/app/models/vechicle_journey_control/delta.rb @@ -0,0 +1,15 @@ +module VehicleJourneyControl + class Delta < ComplianceControl + + hstore_accessor :control_attributes, delta: :integer + + @@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 new file mode 100644 index 000000000..a7e90b6ac --- /dev/null +++ b/app/models/vechicle_journey_control/waiting_time.rb @@ -0,0 +1,13 @@ +module VehicleJourneyControl + class WatingTime < ComplianceControl + + @@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/policies/api_key_policy.rb b/app/policies/api_key_policy.rb index bc5c9e433..eb7b84457 100644 --- a/app/policies/api_key_policy.rb +++ b/app/policies/api_key_policy.rb @@ -14,6 +14,7 @@ class ApiKeyPolicy < ApplicationPolicy end def update? - organisation_match? && user.has_permission?('api_keys.update') + record.try(:organisation_id) == user.organisation_id && + user.has_permission?('api_keys.update') end end diff --git a/app/policies/compliance_control_policy.rb b/app/policies/compliance_control_policy.rb new file mode 100644 index 000000000..fbea366f5 --- /dev/null +++ b/app/policies/compliance_control_policy.rb @@ -0,0 +1,19 @@ +class ComplianceControlPolicy < ApplicationPolicy + class Scope < Scope + def resolve + scope + end + end + + def destroy? + user.has_permission?('compliance_controls.destroy') + end + + def create? + user.has_permission?('compliance_controls.create') + end + + def update? + user.has_permission?('compliance_controls.update') + end +end diff --git a/app/policies/compliance_control_set_policy.rb b/app/policies/compliance_control_set_policy.rb new file mode 100644 index 000000000..12b829aa4 --- /dev/null +++ b/app/policies/compliance_control_set_policy.rb @@ -0,0 +1,7 @@ +class ComplianceControlSetPolicy < ApplicationPolicy + class Scope < Scope + def resolve + scope + end + end +end diff --git a/app/policies/login_policy.rb b/app/policies/login_policy.rb index 5b07b97f3..0360880bd 100644 --- a/app/policies/login_policy.rb +++ b/app/policies/login_policy.rb @@ -7,7 +7,7 @@ class LoginPolicy end def boiv? - (user.permissions || []).include?('sessions:create') + (user.permissions || []).include?('sessions.create') end end diff --git a/app/views/api_keys/edit.html.slim b/app/views/api_keys/edit.html.slim index b1bd1858d..9d7d1fdb7 100644 --- a/app/views/api_keys/edit.html.slim +++ b/app/views/api_keys/edit.html.slim @@ -5,7 +5,7 @@ t('last_update', time: l(@api_key.updated_at, format: :short)), '' - / Below is secundary actions & optional contents (filters, ...) + / Below are secondary actions & optional content (filters, ...) .row.mb-sm .col-lg-12.text-right = ( policy(@api_key).destroy? ? link_to(t('actions.destroy'), api_key_path(@api_key), :method => :delete, class: 'btn btn-default') : '' ) diff --git a/app/views/compliance_control_sets/_filters.html.slim b/app/views/compliance_control_sets/_filters.html.slim new file mode 100644 index 000000000..587f74ce4 --- /dev/null +++ b/app/views/compliance_control_sets/_filters.html.slim @@ -0,0 +1,15 @@ += search_form_for @q_for_form, url: compliance_control_sets_path, builder: SimpleForm::FormBuilder, class: 'form form-filter' do |f| + .ffg-row + .input-group.search_bar + = f.search_field :name_cont, class: 'form-control', placeholder: t('compliance_control_sets.filters.name') + span.input-group-btn + button.btn.btn-default type='submit' + span.fa.fa-search + .ffg-row + .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'} + + .actions + = link_to t('actions.erase'), @compliance_control_set, class: 'btn btn-link' + = f.submit t('actions.filter'), class: 'btn btn-default', id: 'referential_filter_btn'
\ No newline at end of file diff --git a/app/views/compliance_control_sets/_form.html.slim b/app/views/compliance_control_sets/_form.html.slim new file mode 100644 index 000000000..cf144bbd9 --- /dev/null +++ b/app/views/compliance_control_sets/_form.html.slim @@ -0,0 +1,8 @@ += simple_form_for @compliance_control_set, html: { class: 'form-horizontal', id: 'compliance_control_set_form' }, wrapper: :horizontal_form do |f| + .row + .col-lg-12 + = f.input :name + + .separator + + = f.button :submit, t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'compliance_control_set_form' diff --git a/app/views/compliance_control_sets/edit.html.slim b/app/views/compliance_control_sets/edit.html.slim new file mode 100644 index 000000000..a9b8d7253 --- /dev/null +++ b/app/views/compliance_control_sets/edit.html.slim @@ -0,0 +1,10 @@ +/ PageHeader += pageheader 'modele-calendrier', + t('compliance_control_sets.index.edit') + +/ PageContent +.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_control_sets/index.html.slim b/app/views/compliance_control_sets/index.html.slim new file mode 100644 index 000000000..aee1595ef --- /dev/null +++ b/app/views/compliance_control_sets/index.html.slim @@ -0,0 +1,55 @@ +/ PageHeader +- header_params = ['jeux-de-donnees', + t('compliance_control_sets.index.title'), + ''] +- header_params << link_to(t('compliance_control_sets.actions.new'), new_compliance_control_set_path, class: 'btn btn-default') if policy(Calendar).create? += pageheader(*header_params) do + + / Below is secundary actions & optional contents (filters, ...) + .row.mb-sm + .col-lg-12.text-right + +/ PageContent +.page_content + .container-fluid + .row + .col-lg-12 + = render 'filters' + .row + .col-lg-12 + .select_table + = table_builder_2 @compliance_control_sets, + [ \ + TableBuilderHelper::Column.new( \ + key: :name, \ + attribute: 'name', \ + link_to: lambda do |compliance_control_set| \ + compliance_control_set_path(compliance_control_set) \ + end \ + ), \ + TableBuilderHelper::Column.new( \ + key: :assignment, \ + attribute: 'assignment' \ + ), \ + TableBuilderHelper::Column.new( \ + key: :owner_jdc, \ + attribute: 'owner_jdc' \ + ), \ + TableBuilderHelper::Column.new( \ + key: :control_numbers, \ + attribute: 'control_numbers' \ + ), \ + TableBuilderHelper::Column.new( \ + key: :updated_at, \ + attribute: Proc.new { |n| l(n.updated_at, format: :long) if n.updated_at }, \ + ) \ + ], + sortable: true, + links: [:show], + cls: 'table has-filter has-search' + - unless @compliance_control_sets.any? + .row.mt-xs + .col-lg-12 + = replacement_msg t('compliance_control_sets.search_no_results') + + diff --git a/app/views/compliance_control_sets/new.html.slim b/app/views/compliance_control_sets/new.html.slim new file mode 100644 index 000000000..d6be41ee8 --- /dev/null +++ b/app/views/compliance_control_sets/new.html.slim @@ -0,0 +1,11 @@ +/ PageHeader += pageheader 'modele-calendrier', + t('compliance_control_sets.index.new') + + +/ PageContent +.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_control_sets/show.html.slim b/app/views/compliance_control_sets/show.html.slim new file mode 100644 index 000000000..b4a5b2260 --- /dev/null +++ b/app/views/compliance_control_sets/show.html.slim @@ -0,0 +1,25 @@ +/ PageHeader += pageheader 'jeux-de-donnees', + @compliance_control_set.name, + 'Lorem ipsum dolor sit amet' + + / Below is secondary actions & optional contents (filters, ...) + .row.mb-sm + .col-lg-12.text-right + - @compliance_control_set.action_links.each do |link| + - if link.is_a?(HTMLElement) + = link.to_html(class: 'btn btn-primary') + - else + = link_to link.href, + method: link.method, + data: link.data, + class: 'btn btn-primary' do + = link.content + +/ PageContent +.page_content + .container-fluid + .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 diff --git a/app/views/compliance_controls/_form.html.slim b/app/views/compliance_controls/_form.html.slim new file mode 100644 index 000000000..1377ed12b --- /dev/null +++ b/app/views/compliance_controls/_form.html.slim @@ -0,0 +1,12 @@ += simple_form_for [@compliance_control_set, @compliance_control], html: { class: 'form-horizontal', id: 'compliance_control_form' }, wrapper: :horizontal_form do |f| + .row + .col-lg-12 + = f.input :name + = f.input :type + = f.input :code + = f.input :criticity + = f.input :comment + + .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 new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/app/views/compliance_controls/edit.html.slim diff --git a/app/views/compliance_controls/index.html.slim b/app/views/compliance_controls/index.html.slim new file mode 100644 index 000000000..fd1293837 --- /dev/null +++ b/app/views/compliance_controls/index.html.slim @@ -0,0 +1,44 @@ +/ PageHeader +- header_params = ['jeux-de-donnees', + t('compliance_controls.index.title'), + ''] +- header_params << link_to(t('compliance_controls.actions.new'), new_compliance_control_set_compliance_control_path(@compliance_control_set), class: 'btn btn-default') if policy(ComplianceControl).create? += pageheader(*header_params) do + + .row.mb-sm + .col-lg-12.text-right + +.page_content + .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/new.html.slim b/app/views/compliance_controls/new.html.slim new file mode 100644 index 000000000..0651461cb --- /dev/null +++ b/app/views/compliance_controls/new.html.slim @@ -0,0 +1,9 @@ += pageheader 'compliance-control', + t('compliance_control.index.new') + + +.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 new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/app/views/compliance_controls/show.html.slim diff --git a/app/views/imports/index.html.slim b/app/views/imports/index.html.slim index 2203d3584..a6da730f1 100644 --- a/app/views/imports/index.html.slim +++ b/app/views/imports/index.html.slim @@ -24,7 +24,7 @@ ), \ TableBuilderHelper::Column.new( \ key: :started_at, \ - attribute: Proc.new { |n| l(n.started_at, format: :long) }, \ + attribute: Proc.new { |n| l(n.started_at, format: :long) if n.started_at }, \ ), \ TableBuilderHelper::Column.new( \ key: :name, \ diff --git a/app/views/layouts/navigation/_main_nav_left.html.slim b/app/views/layouts/navigation/_main_nav_left.html.slim index 4560f5fa0..12139c93b 100644 --- a/app/views/layouts/navigation/_main_nav_left.html.slim +++ b/app/views/layouts/navigation/_main_nav_left.html.slim @@ -11,7 +11,7 @@ .menu-item.panel .panel-heading h4.panel-title - = link_to '#miOne', data: { toggle: 'collapse', parent: '#menu-items' }, 'aria-expanded' => 'false' do + = link_to '#miOne', data: {toggle: 'collapse', parent: '#menu-items'}, 'aria-expanded' => 'false' do |Offres courantes #miOne.panel-collapse.collapse @@ -26,7 +26,7 @@ .menu-item.panel .panel-heading h4.panel-title - = link_to '#miTwo', data: { toggle: 'collapse', parent: '#menu-items' }, 'aria-expanded' => 'false' do + = link_to '#miTwo', data: {toggle: 'collapse', parent: '#menu-items'}, 'aria-expanded' => 'false' do |Espace de travail #miTwo.panel-collapse.collapse @@ -34,18 +34,18 @@ = link_to workbench_path(current_offer_workbench), class: "list-group-item #{params[:controller] == 'workbenches' ? 'active' : ''}" do span Jeux de données = link_to workbench_imports_path(current_offer_workbench), class: "list-group-item #{(params[:controller] == 'imports') ? 'active' : ''}" do - span Import + span Import = link_to calendars_path, class: 'list-group-item' do span Modèles de calendrier = link_to '#', class: 'list-group-item' do span Rapport de contrôle - = link_to '#', class: 'list-group-item' do + = link_to compliance_control_sets_path, class: 'list-group-item' do span Jeux de contrôle .menu-item.panel .panel-heading h4.panel-title - = link_to '#miThree', data: { toggle: 'collapse', parent: '#menu-items' }, 'aria-expanded' => 'false' do + = link_to '#miThree', data: {toggle: 'collapse', parent: '#menu-items'}, 'aria-expanded' => 'false' do |Données #miThree.panel-collapse.collapse @@ -74,7 +74,7 @@ .menu-item.panel .panel-heading h4.panel-title - = link_to '#miFour', data: { toggle: 'collapse', parent: '#menu-items' }, 'aria-expanded' => 'false' do + = link_to '#miFour', data: {toggle: 'collapse', parent: '#menu-items'}, 'aria-expanded' => 'false' do |Synchronisation #miFour.panel-collapse.collapse @@ -87,7 +87,7 @@ .menu-item.panel .panel-heading h4.panel-title - = link_to '#miFive', data: { toggle: 'collapse', parent: '#menu-items' }, 'aria-expanded' => 'false' do + = link_to '#miFive', data: {toggle: 'collapse', parent: '#menu-items'}, 'aria-expanded' => 'false' do |Outils #miFive.panel-collapse.collapse diff --git a/config/initializers/apartment.rb b/config/initializers/apartment.rb index 0d65c3505..b8f86a751 100644 --- a/config/initializers/apartment.rb +++ b/config/initializers/apartment.rb @@ -54,6 +54,7 @@ Apartment.configure do |config| 'ComplianceCheckSet', 'ComplianceCheckBlock', 'ComplianceCheckResource', + 'ComplianceCheckMessage' ] # use postgres schemas? diff --git a/config/locales/compliance_check_results.en.yml b/config/locales/compliance_check_results.en.yml index e0541ab36..cd22aefb1 100644 --- a/config/locales/compliance_check_results.en.yml +++ b/config/locales/compliance_check_results.en.yml @@ -1,3 +1,2 @@ en: - compliance_check_results: - + compliance_check_messages: diff --git a/config/locales/compliance_check_results.fr.yml b/config/locales/compliance_check_results.fr.yml index b3ddc53f2..d3fbf0900 100644 --- a/config/locales/compliance_check_results.fr.yml +++ b/config/locales/compliance_check_results.fr.yml @@ -1,3 +1,2 @@ fr: - compliance_check_results: - + compliance_check_messages: diff --git a/config/locales/compliance_control_sets.fr.yml b/config/locales/compliance_control_sets.fr.yml new file mode 100644 index 000000000..fedfeede7 --- /dev/null +++ b/config/locales/compliance_control_sets.fr.yml @@ -0,0 +1,24 @@ +fr: + compliance_control_sets: + index: + title: Jeux de contrôle + 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 ? + filters: + 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 + attributes: + compliance_control_set: + name: Nom + assignment: Affectation + owner_jdc: Propriétaire du jeu de contrôle + control_numbers: Nb contrôle + updated_at: Mis a jour
\ No newline at end of file diff --git a/config/locales/compliance_controls.en.yml b/config/locales/compliance_controls.en.yml new file mode 100644 index 000000000..a6b863de5 --- /dev/null +++ b/config/locales/compliance_controls.en.yml @@ -0,0 +1,124 @@ +en: + activerecord: + models: + compliance_control: "compliance control" + attributes: + compliance_control: + name: "Name" + criticity: "Criticity" + comment: "Comment" + code: "Code" + compliance_controls: + actions: + new: "Add a new compliance control" + edit: "Edit this compliance control" + destroy: "Remove this compliance control" + destroy_confirm: "Are you sure you want destroy this compliance control?" + show: + title: "Compliance control" + index: + title: "Compliance control" + new: + title: "Add a new compliance control" + edit: + title: "Update compliance control" + route: + zdl_stop_area: + messages: + 3_route_1: "The route with % objectid connect the stop points % % et % % which belong to the same ZDL" + description: "Two stop points which belong to the same ZDL cannot follow one another in a route" + opposite_route: + messages: + 3_route_2: "The route with % objectid references an incoherent oppposite route %" + description: | + "If the route has an opposite route, it must : + - reference the opposite route + - have an opposite route in relation with the tested route" + journey_pattern: + messages: + 3_route_3: "The route with % objectid doesn't have any journey pattern" + description: "A route must have at least one journey pattern" + duplicates: + messages: + 3_route_4: "The route with % objectid is identical with another route %" + description: "2 routes cannot connect the same stop points with the same order and the same boarding and alighting characteristics" + opposite_route_terminus: + messages: + 3_route_5: "The route with % objectid has a first stop from the % ZDL whereas its oppoite route's last stop is from the ZDL %" + description: "Deux itinéraires en aller/retour doivent desservir les mêmes terminus" + minimum_length: + messages: + 3_route_6: "The route with % objectid does not connect enough stop points (required 2 stop points)" + description: "A route must have at least 2 stop points" + omnibus_journey_pattern: + messages: + 3_route_9: "The route with % objectid does not have a journey pattern that connect all of its stop points" + description: "A journey pattern of a route should connect all of a route's stop points" + unactivated_stop_point: + messages: + 3_route_10: "L'itinéraire % référence un arrêt (ZDEp) désactivé % (%)" + description: "Les arrêts d'un itinéraire ne doivent pas être désactivés" + journey_pattern: + duplicates: + messages: + 3_journeypattern_1: "The journey pattern with objectid % is identical with another one %" + description: "Two journey patterns belonging to the same line must not connect the same stop points in the same order" + vehicle_journey: + messages: + 3_journeypattern_2: "The journey pattern with % objectid doesn't have any vehicle journey" + description: "A journey pattern must have at least one vehicle journey" + vehicle_journey: + waiting_time: + messages: + 3_vehiclejourney_1: "On the following vehicle journey %, the waiting time % a this stop point % (%) is greater than the threshold (%)" + description: "The waiting time at a specific stop point cannot be too big" + speed: + messages: + 3_vehiclejourney_2_1: "On the following vehicle journey %, the computed speed % between the stop points % (%) and % (%) is greater than the threshold (%)" + 3_vehiclejourney_2_2: "On the following vehicle journey %, the computed speed % between the stop points % (%) and % (%) is smaller than the threshold (%)" + description: "The speed between 2 stop points should be confined between two thresholds" + delta: + messages: + 3_vehiclejourney_3: "The travel time on the vehicle journey with % objectid between the stop points % (%) and % (% is too far off % the average waiting on the journey pattern" + description: "The travel time between two following stop points must be close to all the vehicle journey of a journey pattern" + time_table: + messages: + 3_vehiclejourney_4: "The vehicle journey with % objectid does not have a timetable" + description: "A vehicle journey must have at least one timetable" + vehicle_journey_at_stops: + messages: + 3_vehiclejourney_5_1: "The vehicle journey with % objectid has an arrival time % greater than the departure time % at the stop point % (%)" + 3_vehiclejourney_5_2: "The vehicle journey with % objectid has an departure time % at stop point % (%) greater than the arrival % at the next stop point" + description: "The arrival time of a stop point must be smaller than the departure time of this stop point AND the departure time of the stop points must be in chronological order" + routing_constraint_zone: + vehicle_journey_at_stops: + messages: + 3_itl_1: "The Routing Constraint Zone % references an unactivated stop point (ZDEp) % (%)" + description: "The stop points of a Routing Constraint Zone must be activated" + maximum_length: + messages: + 3_itl_2: "The Routing Constraint Zone % covers all the stop points of its related route : % %." + description: "A Routing Constraint Zone cannot cover all the stop points of a route" + minimum_length: + messages: + 3_itl_3: "The Routing Constraint Zone % has less than 2 stop points" + description: "A Routing Constraint Zone must have at least 2 stop points" + line: + route: + messages: + 3_line_1: "On line : % (%), no route has an opposite route" + description: "The routes of a line must have an opposite route" + generic: + content: + messages: + 3_generic_1: "% : the % attribute value (%) does not respect the following pattern : %" + description: "The object attribute must respect a patten (regular expression)" + min_max: + messages: + 3_generic_2_1: "% : the % attributes's value (%) is greater than the authorized maximum value : %" + 3_generic_2_2: "% : the % attributes's value (%) is smaller than the authorized minimum value %" + description: "The numeric value of an attribute must be contained between 2 values" + uniqueness: + messages: + 3_generic_3: "% : the % attribute's value (%) of % is in conflict with : %" + description: "The attribute's value must be unique compared to the other objects ofthe same type (related to the same line)"
\ No newline at end of file diff --git a/config/locales/compliance_controls.fr.yml b/config/locales/compliance_controls.fr.yml new file mode 100644 index 000000000..9a5400a5e --- /dev/null +++ b/config/locales/compliance_controls.fr.yml @@ -0,0 +1,124 @@ +fr: + activerecord: + models: + compliance_control: "Jeu de controle" + attributes: + compliance_control: + name: "Nom" + criticity: "Criticité" + comment: "Commentaire" + code: "Code" + compliance_controls: + actions: + new: "Ajouter un jeu de controle" + edit: "Editer un jeu de controle" + destroy: "Supprimer un jeu de controle" + destroy_confirm: "Etes vous sûr de vouloir détruire le jeu de controle ?" + show: + title: "Jeu de controle" + index: + title: "Jeux de controles" + new: + title: "Ajouter un jeu de controle" + edit: + title: "Editer le jeu de controle" + route: + zdl_stop_area: + messages: + 3_route_1: "L'itinéraire % dessert successivement les arrêts % % et % % de la même zone de lieu" + description: "Deux arrêts d’une même ZDL ne peuvent pas se succéder dans un itinéraire" + opposite_route: + messages: + 3_route_2: "L'itinéraire % référence un itinéraire retour % incohérent" + description: | + "Si l'itinéraire référence un itinéraire inverse, celui-ci doit : + - référencer l'itinéraire inverse + - avoir un sens opposé à l'itinéraire testé" + journey_pattern: + messages: + 3_route_3: "L'itinéraire % n'a pas de mission" + description: "Un itinéraire doit avoir au moins une mission" + duplicates: + messages: + 3_route_4: "L'itinéraire % est identique à l'itinéraire %" + description: "2 itinéraires ne doivent pas desservir strictement les mêmes arrêts dans le même ordre avec les mêmes critères de monté/descente" + opposite_route_terminus: + messages: + 3_route_5: "L'itinéraire % dessert au départ un arrêt de la ZDL % alors que l'itinéraire inverse dessert à l'arrivée un arrêt de la ZDL %" + description: "Deux itinéraires en aller/retour doivent desservir les mêmes terminus" + minimum_length: + messages: + 3_route_6: "L'itinéraire % ne dessert pas assez d'arrêts (minimum 2 requis)" + description: "Un itinéraire doit référencer au moins 2 arrêts" + omnibus_journey_pattern: + messages: + 3_route_9: "L'itinéraire % n'a aucune mission desservant l'ensemble de ses arrêts" + description: "Une mission de l'itinéraire devrait desservir l'ensemble des arrêts de celui-ci" + unactivated_stop_point: + messages: + 3_route_10: "L'itinéraire % référence un arrêt (ZDEp) désactivé % (%)" + description: "Les arrêts d'un itinéraire ne doivent pas être désactivés" + journey_pattern: + duplicates: + messages: + 3_journeypattern_1: "La mission % est identique à la mission %" + description: "Deux missions de la même ligne ne doivent pas desservir les mêmes arrêts dans le même ordre" + vehicle_journey: + messages: + 3_journeypattern_2: "La mission % n'a pas de course" + description: "Une mission doit avoir au moins une course" + vehicle_journey: + waiting_time: + messages: + 3_vehiclejourney_1: "Sur la course %, le temps d'attente % à l'arrêt % (%) est supérieur au seuil toléré (%)" + description: "La durée d’attente à un arrêt ne doit pas être trop grande" + speed: + messages: + 3_vehiclejourney_2_1: "Sur la course %, la vitesse calculée % entre les arrêts % (%) et % (%) est supérieur au seuil toléré (%)" + 3_vehiclejourney_2_2: "Sur la course %, la vitesse calculée % entre les arrêts % (%) et % (%) est inférieur au seuil toléré (%)" + description: "La vitesse entre deux arrêts doit être dans une fourchette paramétrable" + delta: + messages: + 3_vehiclejourney_3: "Le temps de parcours sur la course % entre les arrêts % (%) et % (% s'écarte de % du temps moyen constaté sur la mission" + description: "Les temps de parcours entre 2 arrêts successifs doivent être similaires pour toutes les courses d’une même mission" + time_table: + messages: + 3_vehiclejourney_4: "La course % n'a pas de calendrier d'application" + description: "Une course doit avoir au moins un calendrier d’application" + vehicle_journey_at_stops: + messages: + 3_vehiclejourney_5_1: "La course % a un horaire d'arrivé % supérieur à l'horaire de départ % à l'arrêt {nomArrêt} (%)" + 3_vehiclejourney_5_2: "La course % a un horaire de départ % à l'arrêt {nomArrêt} (%) supérieur à l'horaire d'arrivé % à l'arrêt suivant" + description: "L'horaire d'arrivée à un arrêt doit être antérieur à l'horaire de départ de cet arrêt ET les horaires de départ aux arrêts doivent être dans l'ordre chronologique croissant." + routing_constraint_zone: + vehicle_journey_at_stops: + messages: + 3_itl_1: "L'ITL % référence un arrêt (ZDEp) désactivé % (%)" + description: "Les arrêts d'une ITL ne doivent pas être désactivés" + maximum_length: + messages: + 3_itl_2: "L'ITL % couvre tous les arrêts de l'itinéraire %." + description: "Une ITL ne peut pas couvrir l'ensemble des arrêts de l'itinéraire" + minimum_length: + messages: + 3_itl_3: "L'ITL % n'a pas suffisament d'arrêts (minimum 2 arrêts requis)" + description: "Une ITL doit référencer au moins 2 arrêts" + line: + route: + messages: + 3_line_1: "Sur la ligne % (%), aucun itinéraire n'a d'itinéraire inverse" + description: "Les itinéraires d'une ligne doivent être associés en aller/retour" + generic: + content: + messages: + 3_generic_1: "% : l'attribut % à une valeur % qui ne respecte pas le motif %" + description: "l'attribut de l'objet doit respecter un motif (expression régulière)" + min_max: + messages: + 3_generic_2_1: "% : l'attribut % à une valeur % supérieure à la valeur maximale autorisée %" + 3_generic_2_2: "% : l'attribut % à une valeur % inférieure à la valeur minimale autorisée %" + description: "La valeur numérique de l'attribut doit rester comprise entre 2 valeurs" + uniqueness: + messages: + 3_generic_3: "La valeur de l'attribut doit être unique au sein des objets de la ligne" + description: "% : l'attribut % de % à une valeur % en conflit avec %"
\ No newline at end of file diff --git a/config/locales/import_messages.en.yml b/config/locales/import_messages.en.yml index 1ecdebcd1..4009d7c77 100644 --- a/config/locales/import_messages.en.yml +++ b/config/locales/import_messages.en.yml @@ -10,9 +10,9 @@ en: 2_netexstif_2_2: "Le fichier calendriers.xml contient une frame nommée %{error_value} non acceptée" 2_netexstif_3_1: "Le fichier %{source_filename} ne contient pas de frame nommée NETEX_OFFRE_LIGNE" 2_netexstif_3_2: "Le fichier %{source_filename} contient une frame nommée %{error_value} non acceptée" - 2_netexstif_3_3: "la frame NETEX_OFFRE_LIGNE du fichier %{source_filename} ne contient pas la frame %{NETEX_STRUCTURE|NETEX_HORAIRE} obligatoire" + 2_netexstif_3_3: "la frame NETEX_OFFRE_LIGNE du fichier %{source_filename} ne contient pas la frame %{error_value} obligatoire" 2_netexstif_3_4: "la frame NETEX_OFFRE_LIGNE du fichier %{source_filename} contient une frame %{error_value} non acceptée" - 2_netexstif_4: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'identifiant %{source_objectid} de l'objet %{source_label} ne respecte pas la syntaxe [CODESPACE]:%{source_label}:[identifiant Technique]:LOC" + 2_netexstif_4: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'identifiant %{source_objectid} de l'objet %{error_value} ne respecte pas la syntaxe %{reference_value}" 2_netexstif_6: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet %{source_label} d'identifiant %{source_objectid} a un état de modification interdit : 'delete'" 2_netexstif_7: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet %{source_label} d'identifiant %{source_objectid} définit une référence %{reference_value} de syntaxe invalide : %{error_value}" 2_netexstif_8_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet %{source_label} d'identifiant %{source_objectid} définit une référence %{error_value} de type externe : référence interne attendue" @@ -46,5 +46,6 @@ en: 2_netexstif_servicejourney_4: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} , objet ServiceJourney d'identifiant %{source_objectid} : le passingTime de rang %{error_value} fournit des horaires antérieurs au passingTime précédent." 2_netexstif_servicejourneypattern_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet ServiceJourneyPattern d'identifiant %{source_objectid} ne référence pas de Route" 2_netexstif_servicejourneypattern_2: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet ServiceJourneyPattern d'identifiant %{source_objectid} doit contenir au moins 2 StopPointInJourneyPattern" - 2_netexstif_servicejourneypattern_3: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet ServiceJourneyPattern d'identifiant %{source_objectid} n'a pas de valeur pour l'attribut ServiceJourneyPatternType" + 2_netexstif_servicejourneypattern_3_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet ServiceJourneyPattern d'identifiant %{source_objectid} n'a pas de valeur pour l'attribut ServiceJourneyPatternType" + 2_netexstif_servicejourneypattern_3_2: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet ServiceJourneyPattern d'identifiant %{source_objectid} a une valeur interdite %{error_value} pour l'attribut ServiceJourneyPatternType différente de 'passenger'" 2_netexstif_servicejourneypattern_4: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number}, objet ServiceJourneyPattern d'identifiant %{source_objectid} : les attributs 'order' des StopPointInJourneyPattern ne sont pas croissants." diff --git a/config/locales/import_messages.fr.yml b/config/locales/import_messages.fr.yml index 770cb2c30..085299bb4 100644 --- a/config/locales/import_messages.fr.yml +++ b/config/locales/import_messages.fr.yml @@ -10,9 +10,9 @@ fr: 2_netexstif_2_2: "Le fichier calendriers.xml contient une frame nommée %{error_value} non acceptée" 2_netexstif_3_1: "Le fichier %{source_filename} ne contient pas de frame nommée NETEX_OFFRE_LIGNE" 2_netexstif_3_2: "Le fichier %{source_filename} contient une frame nommée %{error_value} non acceptée" - 2_netexstif_3_3: "la frame NETEX_OFFRE_LIGNE du fichier %{source_filename} ne contient pas la frame %{NETEX_STRUCTURE|NETEX_HORAIRE} obligatoire" + 2_netexstif_3_3: "la frame NETEX_OFFRE_LIGNE du fichier %{source_filename} ne contient pas la frame %{error_value} obligatoire" 2_netexstif_3_4: "la frame NETEX_OFFRE_LIGNE du fichier %{source_filename} contient une frame %{error_value} non acceptée" - 2_netexstif_4: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'identifiant %{source_objectid} de l'objet %{source_label} ne respecte pas la syntaxe [CODESPACE]:%{source_label}:[identifiant Technique]:LOC" + 2_netexstif_4: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'identifiant %{source_objectid} de l'objet %{error_value} ne respecte pas la syntaxe %{reference_value}" 2_netexstif_6: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet %{source_label} d'identifiant %{source_objectid} a un état de modification interdit : 'delete'" 2_netexstif_7: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet %{source_label} d'identifiant %{source_objectid} définit une référence %{reference_value} de syntaxe invalide : %{error_value}" 2_netexstif_8_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet %{source_label} d'identifiant %{source_objectid} définit une référence %{error_value} de type externe : référence interne attendue" @@ -46,5 +46,6 @@ fr: 2_netexstif_servicejourney_4: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} , objet ServiceJourney d'identifiant %{source_objectid} : le passingTime de rang %{error_value} fournit des horaires antérieurs au passingTime précédent." 2_netexstif_servicejourneypattern_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet ServiceJourneyPattern d'identifiant %{source_objectid} ne référence pas de Route" 2_netexstif_servicejourneypattern_2: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet ServiceJourneyPattern d'identifiant %{source_objectid} doit contenir au moins 2 StopPointInJourneyPattern" - 2_netexstif_servicejourneypattern_3: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet ServiceJourneyPattern d'identifiant %{source_objectid} n'a pas de valeur pour l'attribut ServiceJourneyPatternType" + 2_netexstif_servicejourneypattern_3_1: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet ServiceJourneyPattern d'identifiant %{source_objectid} n'a pas de valeur pour l'attribut ServiceJourneyPatternType" + 2_netexstif_servicejourneypattern_3_2: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet ServiceJourneyPattern d'identifiant %{source_objectid} a une valeur interdite %{error_value} pour l'attribut ServiceJourneyPatternType différente de 'passenger'" 2_netexstif_servicejourneypattern_4: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number}, objet ServiceJourneyPattern d'identifiant %{source_objectid} : les attributs 'order' des StopPointInJourneyPattern ne sont pas croissants." diff --git a/config/locales/vehicle_journey_at_stops.en.yml b/config/locales/vehicle_journey_at_stops.en.yml index a96effa2b..8a3bd9394 100644 --- a/config/locales/vehicle_journey_at_stops.en.yml +++ b/config/locales/vehicle_journey_at_stops.en.yml @@ -1,4 +1,4 @@ en: vehicle_journey_at_stops: errors: - day_offset_must_not_exceed_max: "The vehicle journey with ID %{local_id} cannot have times exceeding %{max} days" + day_offset_must_not_exceed_max: "The vehicle journey with ID %{short_id} cannot have times exceeding %{max} days" diff --git a/config/locales/vehicle_journey_at_stops.fr.yml b/config/locales/vehicle_journey_at_stops.fr.yml index 3eff79cf4..f5139fb79 100644 --- a/config/locales/vehicle_journey_at_stops.fr.yml +++ b/config/locales/vehicle_journey_at_stops.fr.yml @@ -1,4 +1,4 @@ fr: vehicle_journey_at_stops: errors: - day_offset_must_not_exceed_max: "La course avec l'identifiant %{local_id} ne peut pas avoir des horaires sur plus de %{max} jours" + day_offset_must_not_exceed_max: "La course avec l'identifiant %{short_id} ne peut pas avoir des horaires sur plus de %{max} jours" diff --git a/config/routes.rb b/config/routes.rb index 0f1b22e44..ef625db1f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -69,6 +69,10 @@ ChouetteIhm::Application.routes.draw do resources :api_keys, :only => [:edit, :update, :new, :create, :destroy] + resources :compliance_control_sets do + resources :compliance_controls + end + resources :stop_area_referentials, :only => [:show] do post :sync, on: :member resources :stop_areas diff --git a/db/migrate/20170915100935_change_crticity_type_for_compliance_control.rb b/db/migrate/20170915100935_change_crticity_type_for_compliance_control.rb new file mode 100644 index 000000000..f3e7e7339 --- /dev/null +++ b/db/migrate/20170915100935_change_crticity_type_for_compliance_control.rb @@ -0,0 +1,5 @@ +class ChangeCrticityTypeForComplianceControl < ActiveRecord::Migration + def change + change_column :compliance_controls, :criticity, :string + end +end diff --git a/db/migrate/20170918103913_alter_table_compliance_check_result_to_compliance_check_message.rb b/db/migrate/20170918103913_alter_table_compliance_check_result_to_compliance_check_message.rb new file mode 100644 index 000000000..c0dc6225a --- /dev/null +++ b/db/migrate/20170918103913_alter_table_compliance_check_result_to_compliance_check_message.rb @@ -0,0 +1,5 @@ +class AlterTableComplianceCheckResultToComplianceCheckMessage < ActiveRecord::Migration + def change + rename_table :compliance_check_results, :compliance_check_messages + end +end diff --git a/db/schema.rb b/db/schema.rb index 5e2edf33d..2b62fa7f1 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: 20170913074922) do +ActiveRecord::Schema.define(version: 20170918103913) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -155,17 +155,7 @@ ActiveRecord::Schema.define(version: 20170913074922) do add_index "compliance_check_blocks", ["compliance_check_set_id"], name: "index_compliance_check_blocks_on_compliance_check_set_id", using: :btree - create_table "compliance_check_resources", id: :bigserial, force: :cascade do |t| - t.string "status" - t.string "name" - t.string "type" - t.string "reference" - t.hstore "metrics" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - end - - create_table "compliance_check_results", id: :bigserial, force: :cascade do |t| + create_table "compliance_check_messages", id: :bigserial, force: :cascade do |t| t.integer "compliance_check_id" t.integer "compliance_check_resource_id" t.string "message_key" @@ -175,8 +165,18 @@ ActiveRecord::Schema.define(version: 20170913074922) do t.datetime "updated_at", null: false end - add_index "compliance_check_results", ["compliance_check_id"], name: "index_compliance_check_results_on_compliance_check_id", using: :btree - add_index "compliance_check_results", ["compliance_check_resource_id"], name: "index_compliance_check_results_on_compliance_check_resource_id", using: :btree + add_index "compliance_check_messages", ["compliance_check_id"], name: "index_compliance_check_messages_on_compliance_check_id", using: :btree + add_index "compliance_check_messages", ["compliance_check_resource_id"], name: "index_compliance_check_messages_on_compliance_check_resource_id", using: :btree + + create_table "compliance_check_resources", id: :bigserial, force: :cascade do |t| + t.string "status" + t.string "name" + t.string "type" + t.string "reference" + t.hstore "metrics" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end create_table "compliance_check_sets", id: :bigserial, force: :cascade do |t| t.integer "referential_id" @@ -237,7 +237,7 @@ ActiveRecord::Schema.define(version: 20170913074922) do t.json "control_attributes" t.string "name" t.string "code" - t.integer "criticity" + t.string "criticity" t.text "comment" t.datetime "created_at", null: false t.datetime "updated_at", null: false @@ -270,22 +270,6 @@ ActiveRecord::Schema.define(version: 20170913074922) do add_index "connection_links", ["objectid"], name: "connection_links_objectid_key", unique: true, using: :btree - create_table "delayed_jobs", id: :bigserial, force: :cascade do |t| - t.integer "priority", default: 0 - t.integer "attempts", default: 0 - t.text "handler" - t.text "last_error" - t.datetime "run_at" - t.datetime "locked_at" - t.datetime "failed_at" - t.string "locked_by", limit: 255 - t.string "queue", limit: 255 - t.datetime "created_at" - t.datetime "updated_at" - end - - add_index "delayed_jobs", ["priority", "run_at"], name: "delayed_jobs_priority", using: :btree - create_table "exports", id: :bigserial, force: :cascade do |t| t.integer "referential_id", limit: 8 t.string "status" @@ -407,12 +391,12 @@ ActiveRecord::Schema.define(version: 20170913074922) do t.datetime "started_at" t.datetime "ended_at" t.string "token_download" - t.string "type", limit: 255 + t.string "type" t.integer "parent_id", limit: 8 t.string "parent_type" - t.integer "current_step", default: 0 - t.integer "total_steps", default: 0 t.datetime "notified_parent_at" + t.integer "current_step", default: 0 + t.integer "total_steps", default: 0 t.string "creator" end @@ -564,11 +548,6 @@ ActiveRecord::Schema.define(version: 20170913074922) do add_index "networks", ["objectid"], name: "networks_objectid_key", unique: true, using: :btree add_index "networks", ["registration_number"], name: "networks_registration_number_key", using: :btree - create_table "object_id_factories", id: :bigserial, force: :cascade do |t| - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - end - create_table "organisations", id: :bigserial, force: :cascade do |t| t.string "name" t.datetime "created_at" @@ -745,7 +724,7 @@ ActiveRecord::Schema.define(version: 20170913074922) do create_table "stop_areas", id: :bigserial, force: :cascade do |t| t.integer "parent_id", limit: 8 - t.string "objectid", null: false + t.string "objectid", null: false t.integer "object_version", limit: 8 t.string "creator_id" t.string "name" @@ -754,8 +733,8 @@ ActiveRecord::Schema.define(version: 20170913074922) do t.string "registration_number" t.string "nearest_topic_name" t.integer "fare_code" - t.decimal "longitude", precision: 19, scale: 16 - t.decimal "latitude", precision: 19, scale: 16 + t.decimal "longitude", precision: 19, scale: 16 + t.decimal "latitude", precision: 19, scale: 16 t.string "long_lat_type" t.string "country_code" t.string "street_name" @@ -773,7 +752,7 @@ ActiveRecord::Schema.define(version: 20170913074922) do t.datetime "deleted_at" t.datetime "created_at" t.datetime "updated_at" - t.string "stif_type", limit: 255 + t.string "stif_type" end add_index "stop_areas", ["name"], name: "index_stop_areas_on_name", using: :btree @@ -844,18 +823,18 @@ ActiveRecord::Schema.define(version: 20170913074922) do add_index "time_table_periods", ["time_table_id"], name: "index_time_table_periods_on_time_table_id", using: :btree create_table "time_tables", id: :bigserial, force: :cascade do |t| - t.string "objectid", null: false - t.integer "object_version", limit: 8, default: 1 + t.string "objectid", null: false + t.integer "object_version", limit: 8, default: 1 t.string "creator_id" t.string "version" t.string "comment" - t.integer "int_day_types", default: 0 + t.integer "int_day_types", default: 0 t.date "start_date" t.date "end_date" t.integer "calendar_id", limit: 8 t.datetime "created_at" t.datetime "updated_at" - t.string "color", limit: 255 + t.string "color" t.integer "created_from_id" t.string "checksum" t.text "checksum_source" @@ -987,8 +966,8 @@ ActiveRecord::Schema.define(version: 20170913074922) do add_foreign_key "access_links", "access_points", name: "aclk_acpt_fkey" add_foreign_key "api_keys", "organisations" add_foreign_key "compliance_check_blocks", "compliance_check_sets" - add_foreign_key "compliance_check_results", "compliance_check_resources" - add_foreign_key "compliance_check_results", "compliance_checks" + add_foreign_key "compliance_check_messages", "compliance_check_resources" + add_foreign_key "compliance_check_messages", "compliance_checks" add_foreign_key "compliance_check_sets", "compliance_control_sets" add_foreign_key "compliance_check_sets", "referentials" add_foreign_key "compliance_check_sets", "workbenches" @@ -999,13 +978,9 @@ ActiveRecord::Schema.define(version: 20170913074922) do 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", name: "journey_frequencies_timeband_id_fk", on_delete: :nullify add_foreign_key "journey_frequencies", "timebands", on_delete: :nullify - add_foreign_key "journey_frequencies", "vehicle_journeys", name: "journey_frequencies_vehicle_journey_id_fk", on_delete: :nullify add_foreign_key "journey_frequencies", "vehicle_journeys", on_delete: :nullify - add_foreign_key "journey_pattern_sections", "journey_patterns", name: "journey_pattern_sections_journey_pattern_id_fk", on_delete: :cascade add_foreign_key "journey_pattern_sections", "journey_patterns", on_delete: :cascade - add_foreign_key "journey_pattern_sections", "route_sections", name: "journey_pattern_sections_route_section_id_fk", on_delete: :cascade add_foreign_key "journey_pattern_sections", "route_sections", on_delete: :cascade add_foreign_key "journey_patterns", "routes", name: "jp_route_fkey", on_delete: :cascade add_foreign_key "journey_patterns", "stop_points", column: "arrival_stop_point_id", name: "arrival_point_fkey", on_delete: :nullify diff --git a/lib/stif/permission_translator.rb b/lib/stif/permission_translator.rb index 47ab2840f..2bc565968 100644 --- a/lib/stif/permission_translator.rb +++ b/lib/stif/permission_translator.rb @@ -17,13 +17,14 @@ module Stif def all_resources %w[ access_points - connection_links calendars - footnotes - journey_patterns - referentials routes routing_constraint_zones - time_tables - vehicle_journeys - api_keys + connection_links calendars + footnotes + journey_patterns + referentials routes routing_constraint_zones + time_tables + vehicle_journeys + api_keys + compliance_controls ] end @@ -38,8 +39,8 @@ module Stif def translation_table { - "boiv:read-offer" => %w{sessions:create}, - "boiv:edit-offer" => all_destructive_permissions + %w{sessions:create}, + "boiv:read-offer" => %w{sessions.create}, + "boiv:edit-offer" => all_destructive_permissions + %w{sessions.create}, } end end diff --git a/lib/tasks/erd.rake b/lib/tasks/erd.rake index a9b1a3454..6b79967de 100644 --- a/lib/tasks/erd.rake +++ b/lib/tasks/erd.rake @@ -3,10 +3,10 @@ namespace :generate do desc "Create model diagrams for Chouette" task :model_diagram => :environment do sh "bundle exec rake erd only='Organisation,Referential,User,Workbench' filename='organisation' title='Organisation'" - sh "bundle exec rake erd only='Calendar,Referential,Chouette::Line,Chouette::Route,Chouette::JourneyPattern,Chouette::VehicleJourney,Chouette::VehicleJourneyAtStop,Chouette::TimeTable,Chouette::TimeTableDate,Chouette::TimeTablePeriod,Chouette::Footnote,Chouette::Network,Chouette::Company,Chouette::StopPoint,Chouette::StopArea' filename='offer_datas' title='Offer Datas'" + sh "bundle exec rake erd only='Calendar,Referential,ReferentialMetadata,Chouette::Line,Chouette::Route,Chouette::JourneyPattern,Chouette::VehicleJourney,Chouette::VehicleJourneyAtStop,Chouette::TimeTable,Chouette::TimeTableDate,Chouette::TimeTablePeriod,Chouette::Footnote,Chouette::Network,Chouette::Company,Chouette::StopPoint,Chouette::StopArea' filename='offer_datas' title='Offer Datas'" sh "bundle exec rake erd only='Organisation,StopAreaReferential,StopAreaReferentialSync,StopAreaReferentialSyncMessage,StopAreaReferentialMembership,LineReferential,LineReferentialSync,LineReferentialSyncMessage,LineReferentialMembership' filename='referentiels_externes' title='Référentiels externes'" sh "bundle exec rake erd only='NetexImport,Import,WorkbenchImport,ImportResource,ImportMessage' filename='import' title='Import'" - #sh "bundle exec rake erd only='' filename='validation' title='Validation'" + sh "bundle exec rake erd only='ComplianceControlSet,ComplianceControlBlock,ComplianceControl,ComplianceCheckSet,ComplianceCheckBlock,ComplianceCheck,ComplianceCheckResource,ComplianceCheckMessage' filename='validation' title='Validation'" #sh "bundle exec rake erd only='VehicleJourney,VehicleJourneyExport' filename='export' title='Export'" #sh "bundle exec rake erd only='' filename='intégration' title='Integration'" #sh "bundle exec rake erd only='' filename='fusion' title='Fusion'" diff --git a/lib/tasks/referential.rake b/lib/tasks/referential.rake index d27354a40..7bab6e040 100644 --- a/lib/tasks/referential.rake +++ b/lib/tasks/referential.rake @@ -26,11 +26,11 @@ namespace :referential do route_attrs = { line: line, name: "Route #{name}", published_name: "Published #{name}" } if i.even? - route_attrs[:wayback] = :straight_forward + route_attrs[:wayback] = :outbound route = Chouette::Route.create!(route_attrs) route.stop_areas = stop_areas else - route_attrs[:wayback] = :backward + route_attrs[:wayback] = :inbound route_attrs[:opposite_route] = Chouette::Route.last if i == 3 route = Chouette::Route.create!(route_attrs) route.stop_areas = stop_areas.reverse diff --git a/spec/controllers/compliance_control_sets_controller_spec.rb b/spec/controllers/compliance_control_sets_controller_spec.rb new file mode 100644 index 000000000..25d0becfe --- /dev/null +++ b/spec/controllers/compliance_control_sets_controller_spec.rb @@ -0,0 +1,60 @@ +require 'rails_helper' + +RSpec.describe ComplianceControlSetsController, type: :controller do + login_user + + let(:compliance_control_set) { create :compliance_control_set } + + describe "GET show" do + it 'should be successful' do + get :show, id: compliance_control_set.id + expect(response).to be_success + end + end + + describe "GET index" do + it 'should be successful' do + get :index, id: compliance_control_set.id + expect(response).to be_success + end + end + + describe "GET #edit" do + it 'should be successful' do + get :edit, id: compliance_control_set.id + expect(response).to be_success + end + end + + describe 'GET #new' do + it 'should be successful' do + get :new, id: compliance_control_set.id + expect(response).to be_success + end + end + + describe 'POST #create' do + it 'should be successful' do + post :create, compliance_control_set: build(:compliance_control_set).as_json + 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, id: compliance_control_set.id, compliance_control_set: compliance_control_set.as_json + expect(response).to redirect_to compliance_control_set_path(compliance_control_set) + # expect(flash[:notice]).to eq(I18n.t('notice.compliance_control.updated')) + end + end + + describe 'DELETE #destroy' do + it 'should be successful' do + delete :destroy, id: compliance_control_set.id + # expect(flash[:notice]).to eq I18n.t('notice.compliance_control.destroyed') + end + end + + +end diff --git a/spec/controllers/compliance_controls_controller_spec.rb b/spec/controllers/compliance_controls_controller_spec.rb new file mode 100644 index 000000000..165c00329 --- /dev/null +++ b/spec/controllers/compliance_controls_controller_spec.rb @@ -0,0 +1,59 @@ +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 } + + describe "GET show" do + it 'should be successful' do + get :show, compliance_control_set_id: compliance_control_set.id, id: compliance_control.id + expect(response).to be_success + 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 + expect(response).to be_success + end + end + + describe 'GET #new' do + it 'should be successful' do + get :new, compliance_control_set_id: compliance_control_set.id + expect(response).to be_success + end + end + + 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 + 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 + 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') + end + end +end diff --git a/spec/controllers/devise/cas_sessions_controller_spec.rb b/spec/controllers/devise/cas_sessions_controller_spec.rb index c82fd2cdb..e4436f6c1 100644 --- a/spec/controllers/devise/cas_sessions_controller_spec.rb +++ b/spec/controllers/devise/cas_sessions_controller_spec.rb @@ -17,7 +17,7 @@ RSpec.describe Devise::CasSessionsController, type: :controller do end end - context 'user does not have permission sessions:create' do + context 'user does not have permission sessions.create' do let( :signed_in_user ){ build_stubbed :user } it 'cannot login and will be redirected to the login page, with a corresponding message' do @@ -27,11 +27,11 @@ RSpec.describe Devise::CasSessionsController, type: :controller do end end - context 'user does have permission sessions:create' do + context 'user does have permission sessions.create' do let( :signed_in_user ){ build_stubbed :allmighty_user } it 'can login and will be redirected to the referentials page' do - @user.permissions << 'sessions:create' + @user.permissions << 'sessions.create' get :service expect(response).to redirect_to(authenticated_root_path) end diff --git a/spec/decorators/compliance_control_set_decorator_spec.rb b/spec/decorators/compliance_control_set_decorator_spec.rb new file mode 100644 index 000000000..64e9ff9e7 --- /dev/null +++ b/spec/decorators/compliance_control_set_decorator_spec.rb @@ -0,0 +1,4 @@ +require 'spec_helper' + +describe ComplianceControlSetDecorator do +end diff --git a/spec/factories/compliance_check_results.rb b/spec/factories/compliance_check_messages.rb index a56d77ce4..1a047a242 100644 --- a/spec/factories/compliance_check_results.rb +++ b/spec/factories/compliance_check_messages.rb @@ -1,5 +1,5 @@ FactoryGirl.define do - factory :compliance_check_result do + factory :compliance_check_message do association :compliance_check association :compliance_check_resource message_key "message_key" diff --git a/spec/factories/compliance_controls.rb b/spec/factories/compliance_controls.rb index 28b760383..8aa16b674 100644 --- a/spec/factories/compliance_controls.rb +++ b/spec/factories/compliance_controls.rb @@ -1,8 +1,8 @@ FactoryGirl.define do factory :compliance_control do sequence(:name) { |n| "Compliance control #{n}" } - type "Type" - criticity :info + type "ComplianceControl" + criticity :warning code "code" comment "Text" association :compliance_control_set diff --git a/spec/features/api_keys/delete_api_key_feature_spec.rb b/spec/features/api_keys/delete_api_key_feature_spec.rb new file mode 100644 index 000000000..b58e819a6 --- /dev/null +++ b/spec/features/api_keys/delete_api_key_feature_spec.rb @@ -0,0 +1,34 @@ +RSpec.describe 'New API Key', type: :feature do + login_user + + describe "api_keys#destroy" do + + let!( :api_key ){ create :api_key, name: SecureRandom.uuid, organisation: @user.organisation } + + let( :edit_label ){ "#{api_key.name} : #{api_key.token}" } + let( :destroy_label ){ "Supprimer" } + + xit 'complete workflow' do + # /workbenches + visit workbenches_path + # the api_key is visible + click_link edit_label + + # brings us to correct page + expect(page.current_path).to eq(edit_api_key_path(api_key)) + expect(page).to have_content("Supprimer") + # click_link(destroy_label) + + # # check impact on DB + # expect(Api::V1::ApiKey.where(id: api_key.id)).to be_empty + + # # check redirect and changed display + # expect(page.current_path).to eq(workbenches_path) + # # deleted api_key's not shown anymore + # expect( page ).not_to have_content(edit_label) + end + + end + +end + diff --git a/spec/features/api_keys/edit_api_key_feature_spec.rb b/spec/features/api_keys/edit_api_key_feature_spec.rb new file mode 100644 index 000000000..411c11aaf --- /dev/null +++ b/spec/features/api_keys/edit_api_key_feature_spec.rb @@ -0,0 +1,39 @@ +RSpec.describe 'New API Key', type: :feature do + login_user + + describe "api_keys#edit" do + + let!( :api_key ){ create :api_key, name: SecureRandom.uuid, organisation: @user.organisation } + + let( :edit_label ){ "#{api_key.name} : #{api_key.token}" } + let( :name_label ){ "Nom" } + let( :validate_label ){ "Valider" } + + let( :unique_name ){ SecureRandom.uuid } + + it 'complete workflow' do + # /workbenches + visit workbenches_path + # api_key's new name does not exist yet + expect( page ).not_to have_content(unique_name) + # the api_key is visible + click_link edit_label + + # brings us to correct page + expect(page.current_path).to eq(edit_api_key_path(api_key)) + fill_in(name_label, with: unique_name) + click_button(validate_label) + + # check impact on DB + expect(api_key.reload.name).to eq(unique_name) + + # check redirect and changed display + expect(page.current_path).to eq(workbenches_path) + # changed api_key's name exists now + expect( page ).to have_content(unique_name) + end + + end + +end + diff --git a/spec/features/api_keys/new_api_key_feature_spec.rb b/spec/features/api_keys/new_api_key_feature_spec.rb new file mode 100644 index 000000000..eba873691 --- /dev/null +++ b/spec/features/api_keys/new_api_key_feature_spec.rb @@ -0,0 +1,38 @@ +RSpec.describe 'New API Key', type: :feature do + login_user + + describe "api_keys#create" do + + let( :create_label ){ "Créer une clé d'API" } + let( :name_label ){ "Nom" } + let( :validate_label ){ "Valider" } + + let( :unique_name ){ SecureRandom.uuid } + let( :last_api_key ){ Api::V1::ApiKey.last } + + + it 'complete workflow' do + # /workbenches + visit workbenches_path + expect(page).to have_link(create_label, href: new_api_key_path) + # to be created api_key does not exist yet + expect( page ).not_to have_content(unique_name) + + # /api_keys/new + click_link create_label + fill_in(name_label, with: unique_name) + click_button validate_label + + # check impact on DB + expect(last_api_key.name).to eq(unique_name) + + # check redirect and changed display + expect(page.current_path).to eq(workbenches_path) + # to be created api_key exists now + expect( page ).to have_content(unique_name) + end + + end + +end + diff --git a/spec/features/line_footnotes_permissions_spec.rb b/spec/features/line_footnotes_permissions_spec.rb index 4de2a6137..62adbfcd5 100644 --- a/spec/features/line_footnotes_permissions_spec.rb +++ b/spec/features/line_footnotes_permissions_spec.rb @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - describe 'Line Footnotes', type: :feature do login_user diff --git a/spec/features/referential_lines_spec.rb b/spec/features/referential_lines_spec.rb index 95fc596fd..e8cc8e0e1 100644 --- a/spec/features/referential_lines_spec.rb +++ b/spec/features/referential_lines_spec.rb @@ -1,6 +1,3 @@ -# -*- coding: utf-8 -*- -require 'spec_helper' - describe 'ReferentialLines', type: :feature do login_user let!(:referential_metadata) { create :referential_metadata, referential: referential } diff --git a/spec/features/referentials_spec.rb b/spec/features/referentials_spec.rb index a38577aba..9af0ed32e 100644 --- a/spec/features/referentials_spec.rb +++ b/spec/features/referentials_spec.rb @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- describe "Referentials", :type => :feature do login_user diff --git a/spec/helpers/compliance_control_sets_helper_spec.rb b/spec/helpers/compliance_control_sets_helper_spec.rb new file mode 100644 index 000000000..981368561 --- /dev/null +++ b/spec/helpers/compliance_control_sets_helper_spec.rb @@ -0,0 +1,15 @@ +require 'rails_helper' + +# Specs in this file have access to a helper object that includes +# the ComplianceControlSetsHelper. For example: +# +# describe ComplianceControlSetsHelper do +# describe "string concat" do +# it "concats two strings with spaces" do +# expect(helper.concat_strings("this","that")).to eq("this that") +# end +# end +# end +RSpec.describe ComplianceControlSetsHelper, type: :helper do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/javascripts/time_table/actions_spec.js b/spec/javascripts/time_table/actions_spec.js index f127453df..00acac0d1 100644 --- a/spec/javascripts/time_table/actions_spec.js +++ b/spec/javascripts/time_table/actions_spec.js @@ -170,28 +170,52 @@ describe('actions', () => { expect(actions.validatePeriodForm(modalProps, timeTablePeriods, metas, timetableInDates, error)).toEqual(expectedAction) }) - it('should create an action to include date in period', () => { + it('should create an action to add an included date', () => { let index = 1 let date = actions.formatDate(new Date) const expectedAction = { - type: 'INCLUDE_DATE_IN_PERIOD', + type: 'ADD_INCLUDED_DATE', index, dayTypes, date } - expect(actions.includeDateInPeriod(index, dayTypes, date)).toEqual(expectedAction) + expect(actions.addIncludedDate(index, dayTypes, date)).toEqual(expectedAction) }) - it('should create an action to exclude date from period', () => { + it('should create an action to remove an included dat', () => { let index = 1 let date = actions.formatDate(new Date) const expectedAction = { - type: 'EXCLUDE_DATE_FROM_PERIOD', + type: 'REMOVE_INCLUDED_DATE', index, dayTypes, date } - expect(actions.excludeDateFromPeriod(index, dayTypes, date)).toEqual(expectedAction) + expect(actions.removeIncludedDate(index, dayTypes, date)).toEqual(expectedAction) + }) + + it('should create an action to add an excluded date in period', () => { + let index = 1 + let date = actions.formatDate(new Date) + const expectedAction = { + type: 'ADD_EXCLUDED_DATE', + index, + dayTypes, + date + } + expect(actions.addExcludedDate(index, dayTypes, date)).toEqual(expectedAction) + }) + + it('should create an action to remove an excluded date from period', () => { + let index = 1 + let date = actions.formatDate(new Date) + const expectedAction = { + type: 'REMOVE_EXCLUDED_DATE', + index, + dayTypes, + date + } + expect(actions.removeExcludedDate(index, dayTypes, date)).toEqual(expectedAction) }) it('should create an action to open confirm modal', () => { diff --git a/spec/javascripts/time_table/reducers/modal_spec.js b/spec/javascripts/time_table/reducers/modal_spec.js index 570eb85ed..05d58a138 100644 --- a/spec/javascripts/time_table/reducers/modal_spec.js +++ b/spec/javascripts/time_table/reducers/modal_spec.js @@ -171,12 +171,14 @@ describe('modal reducer', () => { let ttperiods = [] let ttdates = [] + let metas = [] expect( modalReducer(state, { type: 'VALIDATE_PERIOD_FORM', modalProps : modProps, timeTablePeriods: ttperiods, + metas: metas, timetableInDates: ttdates, error: 'La date de départ doit être antérieure à la date de fin' }) @@ -289,9 +291,12 @@ describe('modal reducer', () => { index: false, error: '' } - let ttperiods3 = [] + let ttperiods3 = [] let ttdates3 = [{date: "2017-08-04", include_date: true}] + let metas = { + day_types: [true,true,true,true,true,true,true] + } let newModalProps3 = { active: true, @@ -315,6 +320,7 @@ describe('modal reducer', () => { modalProps : modProps3, timeTablePeriods: ttperiods3, timetableInDates: ttdates3, + metas: metas, error: "Une période ne peut chevaucher une date dans un calendrier" }) ).toEqual(Object.assign({}, state3, {modalProps: newModalProps3})) diff --git a/spec/javascripts/time_table/reducers/pagination_spec.js b/spec/javascripts/time_table/reducers/pagination_spec.js index 5da58427e..3c1edb9c5 100644 --- a/spec/javascripts/time_table/reducers/pagination_spec.js +++ b/spec/javascripts/time_table/reducers/pagination_spec.js @@ -76,20 +76,38 @@ describe('pagination reducer', () => { ).toEqual(Object.assign({}, state, {currentPage : page, stateChanged: false})) }) - it('should handle INCLUDE_DATE_IN_PERIOD', () => { + it('should handle ADD_INCLUDED_DATE', () => { expect( paginationReducer(state, { - type: 'INCLUDE_DATE_IN_PERIOD' + type: 'ADD_INCLUDED_DATE' }) ).toEqual(Object.assign({}, state, {stateChanged: true})) }) - it('should handle EXCLUDE_DATE_FROM_PERIOD', () => { + + it('should handle REMOVE_INCLUDED_DATE', () => { + expect( + paginationReducer(state, { + type: 'REMOVE_INCLUDED_DATE' + }) + ).toEqual(Object.assign({}, state, {stateChanged: true})) + }) + + it('should handle ADD_EXCLUDED_DATE', () => { expect( paginationReducer(state, { - type: 'EXCLUDE_DATE_FROM_PERIOD' + type: 'ADD_EXCLUDED_DATE' }) ).toEqual(Object.assign({}, state, {stateChanged: true})) }) + + it('should handle REMOVE_EXCLUDED_DATE', () => { + expect( + paginationReducer(state, { + type: 'REMOVE_EXCLUDED_DATE' + }) + ).toEqual(Object.assign({}, state, {stateChanged: true})) + }) + it('should handle DELETE_PERIOD', () => { expect( paginationReducer(state, { diff --git a/spec/javascripts/time_table/reducers/timetable_spec.js b/spec/javascripts/time_table/reducers/timetable_spec.js index 6585a78a0..21f6d236d 100644 --- a/spec/javascripts/time_table/reducers/timetable_spec.js +++ b/spec/javascripts/time_table/reducers/timetable_spec.js @@ -6,14 +6,13 @@ const dispatch = function(){} let arrDayTypes = [true, true, true, true, true, true, true] let strDayTypes = 'LuMaMeJeVeSaDi' let time_table_periods = [{"id":261,"period_start":"2017-02-23","period_end":"2017-03-05"},{"id":262,"period_start":"2017-03-15","period_end":"2017-03-25"},{"id":263,"period_start":"2017-04-04","period_end":"2017-04-14"},{"id":264,"period_start":"2017-04-24","period_end":"2017-05-04"},{"id":265,"period_start":"2017-05-14","period_end":"2017-05-24"}] +let time_table_dates = [] let current_periode_range = "2017-05-01" let periode_range = ["2014-05-01","2014-06-01","2014-07-01","2014-08-01","2014-09-01","2014-10-01","2014-11-01","2014-12-01","2015-01-01","2015-02-01","2015-03-01","2015-04-01","2015-05-01","2015-06-01","2015-07-01","2015-08-01","2015-09-01","2015-10-01","2015-11-01","2015-12-01","2016-01-01","2016-02-01","2016-03-01","2016-04-01","2016-05-01","2016-06-01","2016-07-01","2016-08-01","2016-09-01","2016-10-01","2016-11-01","2016-12-01","2017-01-01","2017-02-01","2017-03-01","2017-04-01","2017-05-01","2017-06-01","2017-07-01","2017-08-01","2017-09-01","2017-10-01","2017-11-01","2017-12-01","2018-01-01","2018-02-01","2018-03-01","2018-04-01","2018-05-01","2018-06-01","2018-07-01","2018-08-01","2018-09-01","2018-10-01","2018-11-01","2018-12-01","2019-01-01","2019-02-01","2019-03-01","2019-04-01","2019-05-01","2019-06-01","2019-07-01","2019-08-01","2019-09-01","2019-10-01","2019-11-01","2019-12-01","2020-01-01","2020-02-01","2020-03-01","2020-04-01","2020-05-01"] let current_month = [{"day":"lundi","date":"2017-05-01","wday":1,"wnumber":"18","mday":1,"include_date":false,"excluded_date":false},{"day":"mardi","date":"2017-05-02","wday":2,"wnumber":"18","mday":2,"include_date":false,"excluded_date":false},{"day":"mercredi","date":"2017-05-03","wday":3,"wnumber":"18","mday":3,"include_date":false,"excluded_date":false},{"day":"jeudi","date":"2017-05-04","wday":4,"wnumber":"18","mday":4,"include_date":false,"excluded_date":false},{"day":"vendredi","date":"2017-05-05","wday":5,"wnumber":"18","mday":5,"include_date":false,"excluded_date":false},{"day":"samedi","date":"2017-05-06","wday":6,"wnumber":"18","mday":6,"include_date":false,"excluded_date":false},{"day":"dimanche","date":"2017-05-07","wday":0,"wnumber":"18","mday":7,"include_date":false,"excluded_date":false},{"day":"lundi","date":"2017-05-08","wday":1,"wnumber":"19","mday":8,"include_date":false,"excluded_date":false},{"day":"mardi","date":"2017-05-09","wday":2,"wnumber":"19","mday":9,"include_date":false,"excluded_date":false},{"day":"mercredi","date":"2017-05-10","wday":3,"wnumber":"19","mday":10,"include_date":false,"excluded_date":false},{"day":"jeudi","date":"2017-05-11","wday":4,"wnumber":"19","mday":11,"include_date":false,"excluded_date":false},{"day":"vendredi","date":"2017-05-12","wday":5,"wnumber":"19","mday":12,"include_date":false,"excluded_date":false},{"day":"samedi","date":"2017-05-13","wday":6,"wnumber":"19","mday":13,"include_date":false,"excluded_date":false},{"day":"dimanche","date":"2017-05-14","wday":0,"wnumber":"19","mday":14,"include_date":false,"excluded_date":false},{"day":"lundi","date":"2017-05-15","wday":1,"wnumber":"20","mday":15,"include_date":false,"excluded_date":false},{"day":"mardi","date":"2017-05-16","wday":2,"wnumber":"20","mday":16,"include_date":false,"excluded_date":false},{"day":"mercredi","date":"2017-05-17","wday":3,"wnumber":"20","mday":17,"include_date":false,"excluded_date":false},{"day":"jeudi","date":"2017-05-18","wday":4,"wnumber":"20","mday":18,"include_date":false,"excluded_date":false},{"day":"vendredi","date":"2017-05-19","wday":5,"wnumber":"20","mday":19,"include_date":false,"excluded_date":false},{"day":"samedi","date":"2017-05-20","wday":6,"wnumber":"20","mday":20,"include_date":false,"excluded_date":false},{"day":"dimanche","date":"2017-05-21","wday":0,"wnumber":"20","mday":21,"include_date":false,"excluded_date":false},{"day":"lundi","date":"2017-05-22","wday":1,"wnumber":"21","mday":22,"include_date":false,"excluded_date":false},{"day":"mardi","date":"2017-05-23","wday":2,"wnumber":"21","mday":23,"include_date":false,"excluded_date":false},{"day":"mercredi","date":"2017-05-24","wday":3,"wnumber":"21","mday":24,"include_date":false,"excluded_date":false},{"day":"jeudi","date":"2017-05-25","wday":4,"wnumber":"21","mday":25,"include_date":false,"excluded_date":false},{"day":"vendredi","date":"2017-05-26","wday":5,"wnumber":"21","mday":26,"include_date":false,"excluded_date":false},{"day":"samedi","date":"2017-05-27","wday":6,"wnumber":"21","mday":27,"include_date":false,"excluded_date":false},{"day":"dimanche","date":"2017-05-28","wday":0,"wnumber":"21","mday":28,"include_date":false,"excluded_date":false},{"day":"lundi","date":"2017-05-29","wday":1,"wnumber":"22","mday":29,"include_date":false,"excluded_date":false},{"day":"mardi","date":"2017-05-30","wday":2,"wnumber":"22","mday":30,"include_date":false,"excluded_date":false},{"day":"mercredi","date":"2017-05-31","wday":3,"wnumber":"22","mday":31,"include_date":false,"excluded_date":false}] let newCurrentMonth = [{"day":"lundi","date":"2017-05-01","wday":1,"wnumber":"18","mday":1,"include_date":false,"excluded_date":false,"in_periods":true},{"day":"mardi","date":"2017-05-02","wday":2,"wnumber":"18","mday":2,"include_date":false,"excluded_date":false,"in_periods":true},{"day":"mercredi","date":"2017-05-03","wday":3,"wnumber":"18","mday":3,"include_date":false,"excluded_date":false,"in_periods":true},{"day":"jeudi","date":"2017-05-04","wday":4,"wnumber":"18","mday":4,"include_date":false,"excluded_date":false,"in_periods":true},{"day":"vendredi","date":"2017-05-05","wday":5,"wnumber":"18","mday":5,"include_date":false,"excluded_date":false,"in_periods":false},{"day":"samedi","date":"2017-05-06","wday":6,"wnumber":"18","mday":6,"include_date":false,"excluded_date":false,"in_periods":false},{"day":"dimanche","date":"2017-05-07","wday":0,"wnumber":"18","mday":7,"include_date":false,"excluded_date":false,"in_periods":false},{"day":"lundi","date":"2017-05-08","wday":1,"wnumber":"19","mday":8,"include_date":false,"excluded_date":false,"in_periods":false},{"day":"mardi","date":"2017-05-09","wday":2,"wnumber":"19","mday":9,"include_date":false,"excluded_date":false,"in_periods":false},{"day":"mercredi","date":"2017-05-10","wday":3,"wnumber":"19","mday":10,"include_date":false,"excluded_date":false,"in_periods":false},{"day":"jeudi","date":"2017-05-11","wday":4,"wnumber":"19","mday":11,"include_date":false,"excluded_date":false,"in_periods":false},{"day":"vendredi","date":"2017-05-12","wday":5,"wnumber":"19","mday":12,"include_date":false,"excluded_date":false,"in_periods":false},{"day":"samedi","date":"2017-05-13","wday":6,"wnumber":"19","mday":13,"include_date":false,"excluded_date":false,"in_periods":false},{"day":"dimanche","date":"2017-05-14","wday":0,"wnumber":"19","mday":14,"include_date":false,"excluded_date":false,"in_periods":true},{"day":"lundi","date":"2017-05-15","wday":1,"wnumber":"20","mday":15,"include_date":false,"excluded_date":false,"in_periods":true},{"day":"mardi","date":"2017-05-16","wday":2,"wnumber":"20","mday":16,"include_date":false,"excluded_date":false,"in_periods":true},{"day":"mercredi","date":"2017-05-17","wday":3,"wnumber":"20","mday":17,"include_date":false,"excluded_date":false,"in_periods":true},{"day":"jeudi","date":"2017-05-18","wday":4,"wnumber":"20","mday":18,"include_date":false,"excluded_date":false,"in_periods":true},{"day":"vendredi","date":"2017-05-19","wday":5,"wnumber":"20","mday":19,"include_date":false,"excluded_date":false,"in_periods":true},{"day":"samedi","date":"2017-05-20","wday":6,"wnumber":"20","mday":20,"include_date":false,"excluded_date":false,"in_periods":true},{"day":"dimanche","date":"2017-05-21","wday":0,"wnumber":"20","mday":21,"include_date":false,"excluded_date":false,"in_periods":true},{"day":"lundi","date":"2017-05-22","wday":1,"wnumber":"21","mday":22,"include_date":false,"excluded_date":false,"in_periods":true},{"day":"mardi","date":"2017-05-23","wday":2,"wnumber":"21","mday":23,"include_date":false,"excluded_date":false,"in_periods":true},{"day":"mercredi","date":"2017-05-24","wday":3,"wnumber":"21","mday":24,"include_date":false,"excluded_date":false,"in_periods":true},{"day":"jeudi","date":"2017-05-25","wday":4,"wnumber":"21","mday":25,"include_date":false,"excluded_date":false,"in_periods":false},{"day":"vendredi","date":"2017-05-26","wday":5,"wnumber":"21","mday":26,"include_date":false,"excluded_date":false,"in_periods":false},{"day":"samedi","date":"2017-05-27","wday":6,"wnumber":"21","mday":27,"include_date":false,"excluded_date":false,"in_periods":false},{"day":"dimanche","date":"2017-05-28","wday":0,"wnumber":"21","mday":28,"include_date":false,"excluded_date":false,"in_periods":false},{"day":"lundi","date":"2017-05-29","wday":1,"wnumber":"22","mday":29,"include_date":false,"excluded_date":false,"in_periods":false},{"day":"mardi","date":"2017-05-30","wday":2,"wnumber":"22","mday":30,"include_date":false,"excluded_date":false,"in_periods":false},{"day":"mercredi","date":"2017-05-31","wday":3,"wnumber":"22","mday":31,"include_date":false,"excluded_date":false,"in_periods":false}] -let time_table_dates = [] - let json = { current_month: current_month, current_periode_range: current_periode_range, @@ -46,7 +45,7 @@ describe('timetable reducer with empty state', () => { current_periode_range: current_periode_range, periode_range: periode_range, time_table_periods: time_table_periods, - time_table_dates: time_table_dates + time_table_dates: [] } expect( timetableReducer(state, { @@ -125,24 +124,46 @@ describe('timetable reducer with filled state', () => { ).toEqual(Object.assign({}, state, {current_periode_range: newPage})) }) - it('should handle DELETE_PERIOD', () => { - state.time_table_periods[0].deleted = true + it('should handle DELETE_PERIOD and remove excluded days that were in period', () => { + state.time_table_dates.push({date: "2017-05-01", in_out: false}) + state.current_month[0].excluded_date = true + state.time_table_periods[3].deleted = true + + let begin = new Date(state.time_table_periods[3].period_start) + let end = new Date(state.time_table_periods[3].period_end) + + let newState = Object.assign({}, state, { + time_table_dates: [], + current_month: state.current_month.map((d, i) => { + if (new Date(d.date) >= begin && new Date(d.date) <= end) { + d.excluded_date = false + d.in_periods = false + } + return d + }) + }) expect( timetableReducer(state, { type: 'DELETE_PERIOD', - index: 0, + index: 3, dayTypes: arrDayTypes }) - ).toEqual(state) + ).toEqual(newState) }) - it('should handle INCLUDE_DATE_IN_PERIOD and add in_day if TT doesnt have it', () => { + it('should handle ADD_INCLUDED_DATE', () => { let newDates = state.time_table_dates.concat({date: "2017-05-05", in_out: true}) - let newState = Object.assign({}, state, {time_table_dates: newDates}) - state.current_month[4].include_date = true + + let newCM = newCurrentMonth.map((d,i) => { + if (i == 4) d.include_date = true + return d + }) + + let newState = Object.assign({}, state, {time_table_dates: newDates, current_month: newCM}) + expect( timetableReducer(state, { - type: 'INCLUDE_DATE_IN_PERIOD', + type: 'ADD_INCLUDED_DATE', index: 4, dayTypes: arrDayTypes, date: "2017-05-05" @@ -150,13 +171,20 @@ describe('timetable reducer with filled state', () => { ).toEqual(newState) }) - it('should handle INCLUDE_DATE_IN_PERIOD and remove in_day if TT has it', () => { + it('should handle REMOVE_INCLUDED_DATE', () => { state.current_month[4].include_date = true state.time_table_dates.push({date: "2017-05-05", in_out: true}) - let newState = Object.assign({}, state, {time_table_dates: []}) + + let newCM = newCurrentMonth.map((d,i) => { + if (i == 4) d.include_date = false + return d + }) + + let newDates = state.time_table_dates.filter(d => d.date != "2017-05-05" && d.in_out != true ) + let newState = Object.assign({}, state, {time_table_dates: newDates, current_month: newCM}) expect( timetableReducer(state, { - type: 'INCLUDE_DATE_IN_PERIOD', + type: 'REMOVE_INCLUDED_DATE', index: 4, dayTypes: arrDayTypes, date: "2017-05-05" @@ -164,13 +192,22 @@ describe('timetable reducer with filled state', () => { ).toEqual(newState) }) - it('should handle EXCLUDE_DATE_FROM_PERIOD and add out_day if TT doesnt have it', () => { + it('should handle ADD_EXCLUDED_DATE', () => { let newDates = state.time_table_dates.concat({date: "2017-05-01", in_out: false}) - let newState = Object.assign({}, state, {time_table_dates: newDates}) - state.current_month[0].excluded_date = true + + let newCM = newCurrentMonth.map((d,i) => { + if (i == 0){ + d.include_date = false + d.excluded_date = true + } + return d + }) + + let newState = Object.assign({}, state, {time_table_dates: newDates, current_month: newCM}) + expect( timetableReducer(state, { - type: 'EXCLUDE_DATE_FROM_PERIOD', + type: 'ADD_EXCLUDED_DATE', index: 0, dayTypes: arrDayTypes, date: "2017-05-01" @@ -178,13 +215,13 @@ describe('timetable reducer with filled state', () => { ).toEqual(newState) }) - it('should handle EXCLUDE_DATE_FROM_PERIOD and remove out_day if TT has it', () => { + it('should handle REMOVE_EXCLUDED_DATE', () => { state.time_table_dates = [{date: "2017-05-01", in_out: false}] - state.current_month[0].excluded_date = true + state.current_month[0].excluded_date = false let newState = Object.assign({}, state, {time_table_dates: []}) expect( timetableReducer(state, { - type: 'EXCLUDE_DATE_FROM_PERIOD', + type: 'REMOVE_EXCLUDED_DATE', index: 0, dayTypes: arrDayTypes, date: "2017-05-01" @@ -194,9 +231,10 @@ describe('timetable reducer with filled state', () => { it('should handle UPDATE_DAY_TYPES and remove out_day that are out of day types', () => { state.time_table_dates = [{date: "2017-05-01", in_out: false}] - let newArrDayTypes = arrDayTypes.slice(0) - newArrDayTypes[1] = false - let newState = Object.assign({}, state, {time_table_dates: []}) + let newArrDayTypes = Array.from(arrDayTypes, (dt, i) => { + if (i == 1) dt = false + return dt + }) expect( timetableReducer(state, { type: 'UPDATE_DAY_TYPES', @@ -205,9 +243,19 @@ describe('timetable reducer with filled state', () => { ).toEqual([]) }) + it('should handle UPDATE_DAY_TYPES and remove in_day that are in day types and in period', () => { + state.time_table_dates = [{ date: "2017-05-16", in_out: true }] + expect( + timetableReducer(state, { + type: 'UPDATE_DAY_TYPES', + dayTypes: arrDayTypes + }).time_table_dates + ).toEqual([]) + }) + it('should handle VALIDATE_PERIOD_FORM and add period if modalProps index = false', () => { let newPeriods = state.time_table_periods.concat({"period_start": "2018-05-15", "period_end": "2018-05-24"}) - let newState = Object.assign({}, state, {time_table_periods: newPeriods}) + let newState = Object.assign({}, state, {time_table_periods: newPeriods, time_table_dates: []}) let modalProps = { active: false, begin: { @@ -236,4 +284,53 @@ describe('timetable reducer with filled state', () => { }) ).toEqual(newState) }) + + it('should handle VALIDATE_PERIOD_FORM and update period if modalProps index != false', () => { + + let begin = new Date(state.time_table_periods[0].period_start) + let end = new Date(state.time_table_periods[0].period_end) + let newCM = newCurrentMonth.map((d) => { + if (new Date (d.date) >= begin && new Date(d.date) <= end) { + d.in_periods = false + d.excluded_date = false + } + return d + }) + + let newPeriods = state.time_table_periods.map( (p,i) => { + if (i == 0) { + p.period_start = "2018-05-15" + p.period_end = "2018-05-24" + } + return p + }) + let newState = Object.assign({}, state, {time_table_periods: newPeriods}) + + let modalProps = { + active: false, + begin: { + day: '15', + month: '05', + year: '2018' + }, + end: { + day: '24', + month: '05', + year: '2018' + }, + error: '', + index: 0 + } + expect( + timetableReducer(state, { + type: 'VALIDATE_PERIOD_FORM', + modalProps: modalProps, + timeTablePeriods: state.time_table_periods, + metas: { + day_types: arrDayTypes + }, + timetableInDates: state.time_table_dates.filter(d => d.in_out == true) + }) + ).toEqual(newState) + }) }) diff --git a/spec/lib/stif/netex_file_spec.rb b/spec/lib/stif/netex_file_spec.rb index d84807fe5..ef69b994c 100644 --- a/spec/lib/stif/netex_file_spec.rb +++ b/spec/lib/stif/netex_file_spec.rb @@ -1,5 +1,3 @@ -require "rails_helper" - RSpec.describe STIF::NetexFile do let( :zip_file ){ fixtures_path 'OFFRE_TRANSDEV_2017030112251.zip' } diff --git a/spec/lib/stif/permission_translator_spec.rb b/spec/lib/stif/permission_translator_spec.rb index 9675382e6..ae1a2d1d5 100644 --- a/spec/lib/stif/permission_translator_spec.rb +++ b/spec/lib/stif/permission_translator_spec.rb @@ -1,4 +1,3 @@ -# coding: utf-8 RSpec.describe Stif::PermissionTranslator do context "No SSO Permissions" do @@ -7,8 +6,8 @@ RSpec.describe Stif::PermissionTranslator do context "SSO Permission boiv:read-offer →" do - it "sessions:create only" do - expect( described_class.translate(%w{boiv:read-offer}) ).to eq(%w{sessions:create}) + it "sessions.create only" do + expect( described_class.translate(%w{boiv:read-offer}) ).to eq(%w{sessions.create}) end end @@ -34,7 +33,7 @@ RSpec.describe Stif::PermissionTranslator do end it "remains at boiv:read-offer level" do - expect( described_class.translate(%w{referentials.create boiv:read-offer calendars.delete}) ).to eq(%w{sessions:create}) + expect( described_class.translate(%w{referentials.create boiv:read-offer calendars.delete}) ).to eq(%w{sessions.create}) end it "does not add garbage or doubletons for boiv:edit-offer level" do diff --git a/spec/models/compliance_check_result_spec.rb b/spec/models/compliance_check_message_spec.rb index 95586862f..8b424595e 100644 --- a/spec/models/compliance_check_result_spec.rb +++ b/spec/models/compliance_check_message_spec.rb @@ -1,8 +1,8 @@ require 'rails_helper' -RSpec.describe ComplianceCheckResult, type: :model do +RSpec.describe ComplianceCheckMessage, type: :model do it 'should have a valid factory' do - expect(FactoryGirl.build(:compliance_check_result)).to be_valid + expect(FactoryGirl.build(:compliance_check_message)).to be_valid end it { should belong_to :compliance_check } diff --git a/spec/models/compliance_control_set_spec.rb b/spec/models/compliance_control_set_spec.rb index fb46bc65a..ededec5e0 100644 --- a/spec/models/compliance_control_set_spec.rb +++ b/spec/models/compliance_control_set_spec.rb @@ -6,4 +6,7 @@ RSpec.describe ComplianceControlSet, type: :model do end it { should belong_to :organisation } + it { should have_many :compliance_controls } + + it { should validate_presence_of :name } end diff --git a/spec/policies/api_key_policy_spec.rb b/spec/policies/api_key_policy_spec.rb index 5b9d59fa3..f0242978e 100644 --- a/spec/policies/api_key_policy_spec.rb +++ b/spec/policies/api_key_policy_spec.rb @@ -1,28 +1,60 @@ -require 'rails_helper' - RSpec.describe ApiKeyPolicy do - let(:user) { User.new } + let( :record ){ build_stubbed :api_key } + before { stub_policy_scope(record) } subject { described_class } - permissions ".scope" do - pending "add some examples to (or delete) #{__FILE__}" + permissions :index? do + it_behaves_like 'always allowed' end permissions :show? do - pending "add some examples to (or delete) #{__FILE__}" + it_behaves_like 'always allowed' end permissions :create? do - pending "add some examples to (or delete) #{__FILE__}" + context 'permission absent → ' do + it "denies a user without organisation" do + expect_it.not_to permit(user_context, record) + end + end + context 'permission present → ' do + it 'allows a user with a different organisation' do + add_permissions('api_keys.create', for_user: user) + expect_it.to permit(user_context, record) + end + end end permissions :update? do - pending "add some examples to (or delete) #{__FILE__}" + context 'permission absent → ' do + it "denies a user with a different organisation" do + expect_it.not_to permit(user_context, record) + end + it 'and also a user with the same organisation' do + user.organisation_id = record.organisation_id + expect_it.not_to permit(user_context, record) + end + end + + context 'permission present → ' do + before do + add_permissions('api_keys.update', for_user: user) + end + + it 'denies a user with a different organisation' do + expect_it.not_to permit(user_context, record) + end + + it 'but allows it for a user with the same organisation' do + user.organisation_id = record.organisation_id + expect_it.to permit(user_context, record) + end + end end permissions :destroy? do - pending "add some examples to (or delete) #{__FILE__}" + it_behaves_like 'permitted policy and same organisation', 'api_keys.destroy' end end diff --git a/spec/policies/compliance_control_policy_spec.rb b/spec/policies/compliance_control_policy_spec.rb new file mode 100644 index 000000000..d7c80143d --- /dev/null +++ b/spec/policies/compliance_control_policy_spec.rb @@ -0,0 +1,28 @@ +require 'rails_helper' + +RSpec.describe ComplianceControlPolicy do + + let(:user) { User.new } + + subject { described_class } + + permissions ".scope" do + pending "add some examples to (or delete) #{__FILE__}" + end + + permissions :show? do + pending "add some examples to (or delete) #{__FILE__}" + end + + permissions :create? do + pending "add some examples to (or delete) #{__FILE__}" + end + + permissions :update? do + pending "add some examples to (or delete) #{__FILE__}" + end + + permissions :destroy? do + pending "add some examples to (or delete) #{__FILE__}" + end +end diff --git a/spec/support/permissions.rb b/spec/support/permissions.rb index a28b62bf2..467c07a32 100644 --- a/spec/support/permissions.rb +++ b/spec/support/permissions.rb @@ -2,7 +2,7 @@ module Support module Permissions extend self def all_permissions - @__all_permissions__ ||= _destructive_permissions << 'sessions:create' + @__all_permissions__ ||= _destructive_permissions << 'sessions.create' end private @@ -24,6 +24,7 @@ module Support routing_constraint_zones time_tables vehicle_journeys + compliance_controls ] end end |
