aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuc Donnet2017-07-03 15:37:45 +0200
committerLuc Donnet2017-07-03 15:37:45 +0200
commit9ada6224335862b51c460dc78d7487596323fef8 (patch)
tree6b8694d94abd5aaf5cee7b3a0e9b2aa98ebaefea
parentb9faf2b87816ffc67af4bf10826ea51d049e2a48 (diff)
parent5220e7bad9e252983e1bfc1850fd3459ca802267 (diff)
downloadchouette-core-9ada6224335862b51c460dc78d7487596323fef8.tar.bz2
Merge branch 'master' of github.com:AF83/stif-boiv
-rw-r--r--.gitignore5
-rw-r--r--app/assets/javascripts/es6_browserified/journey_patterns/components/JourneyPattern.js120
-rw-r--r--app/assets/javascripts/es6_browserified/journey_patterns/reducers/status.js2
-rw-r--r--app/assets/javascripts/es6_browserified/time_tables/components/PeriodForm.js16
-rw-r--r--app/assets/javascripts/es6_browserified/time_tables/containers/PeriodForm.js10
-rw-r--r--app/assets/javascripts/es6_browserified/vehicle_journeys/actions/index.js6
-rw-r--r--app/assets/javascripts/smart_date.coffee2
-rw-r--r--app/assets/stylesheets/components/_tables.sass2
-rw-r--r--app/assets/stylesheets/modules/_jp_collection.sass30
-rw-r--r--app/controllers/time_tables_controller.rb4
-rw-r--r--app/helpers/links_helper.rb2
-rw-r--r--app/models/calendar.rb2
-rw-r--r--app/models/chouette/journey_pattern.rb9
-rw-r--r--app/models/chouette/time_table.rb32
-rw-r--r--app/models/clean_up.rb12
-rw-r--r--app/models/referential_metadata.rb4
-rw-r--r--app/views/access_link_pairs/_access_link_pair.html.slim1
-rw-r--r--app/views/calendars/show.html.slim2
-rwxr-xr-xbin/bundle3
-rwxr-xr-xbin/rails9
-rwxr-xr-xbin/rake9
-rwxr-xr-xbin/spring17
-rw-r--r--config/deploy.rb2
-rw-r--r--config/locales/referentials.fr.yml1
-rw-r--r--spec/helpers/table_builder_helper_spec.rb2
-rw-r--r--spec/models/calendar_spec.rb6
-rw-r--r--spec/models/chouette/journey_pattern_spec.rb5
-rw-r--r--spec/models/chouette/time_table_spec.rb504
-rw-r--r--spec/models/clean_up_spec.rb12
-rw-r--r--spec/models/referential_metadata_spec.rb2
-rw-r--r--spec/policies/application_policy_spec.rb2
-rw-r--r--spec/policies/boiv_policy_spec.rb2
-rw-r--r--spec/policies/line_policy_spec.rb3
-rw-r--r--spec/policies/route_policy_spec.rb2
-rw-r--r--spec/policies/routing_constraint_zone_policy_spec.rb3
-rw-r--r--spec/policies/time_table_policy_spec.rb3
-rw-r--r--spec/support/pundit/policies.rb4
-rw-r--r--spec/support/pundit/shared_examples.rb26
38 files changed, 347 insertions, 531 deletions
diff --git a/.gitignore b/.gitignore
index 1bca870cb..0cdaa7c9f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -36,3 +36,8 @@ bin/
# Ignore node modules
/node_modules
+
+# Every machine shall create its binstubs
+/bin/rake
+/bin/rails
+/bin/rspec
diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/components/JourneyPattern.js b/app/assets/javascripts/es6_browserified/journey_patterns/components/JourneyPattern.js
index 43c40a4d5..18ed5f889 100644
--- a/app/assets/javascripts/es6_browserified/journey_patterns/components/JourneyPattern.js
+++ b/app/assets/javascripts/es6_browserified/journey_patterns/components/JourneyPattern.js
@@ -43,75 +43,79 @@ class JourneyPattern extends Component{
)
}
+ getErrors(errors) {
+ let err = Object.keys(errors).map((key, index) => {
+ return (
+ <li key={index} style={{listStyleType: 'disc'}}>
+ <strong>{key}</strong> { errors[key] }
+ </li>
+ )
+ })
+
+ return (
+ <ul className="alert alert-danger">{err}</ul>
+ )
+ }
+
render() {
this.previousCity = undefined
return (
- <div className={'t2e-item' + (this.props.value.deletable ? ' disabled' : '') + (this.props.value.object_id ? '' : ' to_record')}>
+ <div className={'t2e-item' + (this.props.value.deletable ? ' disabled' : '') + (this.props.value.object_id ? '' : ' to_record') + (this.props.value.errors ? ' has-error': '')}>
{/* Errors */}
- {(this.props.value.errors) && (
- <ul className='alert alert-danger small' style={{paddingLeft: 30}}>
- {Object.keys(this.props.value.errors).map(function(key, i) {
- return (
- <li key={i} style={{listStyleType: 'disc'}}>
- <strong>'{key}'</strong> {this.props.value.errors[key]}
- </li>
- )
- })}
- </ul>
- )}
+ {/* this.props.value.errors ? this.getErrors(this.props.value.errors) : '' */}
- <div className='th'>
- <div className='strong mb-xs'>{this.props.value.object_id ? actions.humanOID(this.props.value.object_id) : '-'}</div>
- <div>{this.props.value.registration_number}</div>
- <div>{actions.getChecked(this.props.value.stop_points).length} arrêt(s)</div>
+ <div className='th'>
+ <div className='strong mb-xs'>{this.props.value.object_id ? actions.humanOID(this.props.value.object_id) : '-'}</div>
+ <div>{this.props.value.registration_number}</div>
+ <div>{actions.getChecked(this.props.value.stop_points).length} arrêt(s)</div>
- <div className={this.props.value.deletable ? 'btn-group disabled' : 'btn-group'}>
- <div
- className={this.props.value.deletable ? 'btn dropdown-toggle disabled' : 'btn dropdown-toggle'}
- data-toggle='dropdown'
- >
- <span className='fa fa-cog'></span>
- </div>
- <ul className='dropdown-menu'>
- <li className={(this.props.value.deletable || this.props.status.policy['journey_patterns.edit'] == false) ? 'disabled' : ''}>
- <button
- type='button'
- onClick={this.props.onOpenEditModal}
- data-toggle='modal'
- data-target='#JourneyPatternModal'
- >
- Editer
+ <div className={this.props.value.deletable ? 'btn-group disabled' : 'btn-group'}>
+ <div
+ className={this.props.value.deletable ? 'btn dropdown-toggle disabled' : 'btn dropdown-toggle'}
+ data-toggle='dropdown'
+ >
+ <span className='fa fa-cog'></span>
+ </div>
+ <ul className='dropdown-menu'>
+ <li className={(this.props.value.deletable || this.props.status.policy['journey_patterns.edit'] == false) ? 'disabled' : ''}>
+ <button
+ type='button'
+ onClick={this.props.onOpenEditModal}
+ data-toggle='modal'
+ data-target='#JourneyPatternModal'
+ >
+ Editer
+ </button>
+ </li>
+ <li className={this.props.value.object_id ? '' : 'disabled'}>
+ {this.vehicleJourneyURL(this.props.value.object_id)}
+ </li>
+ <li className={'delete-action' + ((this.props.status.policy['journey_patterns.edit'] == false)? ' disabled' : '')}>
+ <button
+ type='button'
+ disabled={(this.props.status.policy['journey_patterns.edit'] == false)? 'disabled' : ''}
+ onClick={(e) => {
+ e.preventDefault()
+ this.props.onDeleteJourneyPattern(this.props.index)}
+ }
+ >
+ <span className='fa fa-trash'></span>Supprimer
</button>
</li>
- <li className={this.props.value.object_id ? '' : 'disabled'}>
- {this.vehicleJourneyURL(this.props.value.object_id)}
- </li>
- <li className={'delete-action' + ((this.props.status.policy['journey_patterns.edit'] == false)? ' disabled' : '')}>
- <button
- type='button'
- disabled={(this.props.status.policy['journey_patterns.edit'] == false)? 'disabled' : ''}
- onClick={(e) => {
- e.preventDefault()
- this.props.onDeleteJourneyPattern(this.props.index)}
- }
- >
- <span className='fa fa-trash'></span>Supprimer
- </button>
- </li>
- </ul>
- </div>
+ </ul>
</div>
-
- {this.props.value.stop_points.map((stopPoint, i) =>{
- return (
- <div key={i} className='td'>
- {this.cityNameChecker(stopPoint)}
- </div>
- )
- })}
</div>
- )
+
+ {this.props.value.stop_points.map((stopPoint, i) =>{
+ return (
+ <div key={i} className='td'>
+ {this.cityNameChecker(stopPoint)}
+ </div>
+ )
+ })}
+ </div>
+ )
}
}
diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/reducers/status.js b/app/assets/javascripts/es6_browserified/journey_patterns/reducers/status.js
index 6241777da..d7ef12d0b 100644
--- a/app/assets/javascripts/es6_browserified/journey_patterns/reducers/status.js
+++ b/app/assets/javascripts/es6_browserified/journey_patterns/reducers/status.js
@@ -9,6 +9,8 @@ const status = (state = {}, action) => {
return _.assign({}, state, {isFetching: true})
case 'RECEIVE_JOURNEY_PATTERNS':
return _.assign({}, state, {fetchSuccess: true, isFetching: false})
+ case 'RECEIVE_ERRORS':
+ return _.assign({}, state, {isFetching: false})
default:
return state
}
diff --git a/app/assets/javascripts/es6_browserified/time_tables/components/PeriodForm.js b/app/assets/javascripts/es6_browserified/time_tables/components/PeriodForm.js
index a8a92c522..028974fc8 100644
--- a/app/assets/javascripts/es6_browserified/time_tables/components/PeriodForm.js
+++ b/app/assets/javascripts/es6_browserified/time_tables/components/PeriodForm.js
@@ -61,30 +61,30 @@ const PeriodForm = ({modal, timetable, metas, onOpenAddPeriodForm, onClosePeriod
<div className="nested-fields">
<div className="wrapper">
<div>
- <div className={'form-group date smart_date' + (modal.modalProps.error ? ' has-error' : '')}>
+ <div className={'form-group date ' + (modal.modalProps.error ? ' has-error' : '')}>
<div className="form-inline">
- <select value={formatNumber(modal.modalProps.begin.day)} onChange={(e) => onUpdatePeriodForm(e, 'begin', 'day')} id="q_validity_period_begin_gteq_3i" className="date required form-control">
+ <select value={formatNumber(modal.modalProps.begin.day)} onChange={(e) => onUpdatePeriodForm(e, 'begin', 'day', modal.modalProps)} id="q_validity_period_begin_gteq_3i" className="date required form-control">
{makeDaysOptions(modal.modalProps.begin.day)}
</select>
- <select value={formatNumber(modal.modalProps.begin.month)} onChange={(e) => onUpdatePeriodForm(e, 'begin', 'month')} id="q_validity_period_begin_gteq_2i" className="date required form-control">
+ <select value={formatNumber(modal.modalProps.begin.month)} onChange={(e) => onUpdatePeriodForm(e, 'begin', 'month', modal.modalProps)} id="q_validity_period_begin_gteq_2i" className="date required form-control">
{makeMonthsOptions(modal.modalProps.begin.month)}
</select>
- <select value={modal.modalProps.begin.year} onChange={(e) => onUpdatePeriodForm(e, 'begin', 'year')} id="q_validity_period_begin_gteq_1i" className="date required form-control">
+ <select value={modal.modalProps.begin.year} onChange={(e) => onUpdatePeriodForm(e, 'begin', 'year', modal.modalProps)} id="q_validity_period_begin_gteq_1i" className="date required form-control">
{makeYearsOptions(modal.modalProps.begin.year)}
</select>
</div>
</div>
</div>
<div>
- <div className={'form-group date smart_date' + (modal.modalProps.error ? ' has-error' : '')}>
+ <div className={'form-group date ' + (modal.modalProps.error ? ' has-error' : '')}>
<div className="form-inline">
- <select value={formatNumber(modal.modalProps.end.day)} onChange={(e) => onUpdatePeriodForm(e, 'end', 'day')} id="q_validity_period_end_gteq_3i" className="date required form-control">
+ <select value={formatNumber(modal.modalProps.end.day)} onChange={(e) => onUpdatePeriodForm(e, 'end', 'day', modal.modalProps)} id="q_validity_period_end_gteq_3i" className="date required form-control">
{makeDaysOptions(modal.modalProps.end.day)}
</select>
- <select value={formatNumber(modal.modalProps.end.month)} onChange={(e) => onUpdatePeriodForm(e, 'end', 'month')} id="q_validity_period_end_gteq_2i" className="date required form-control">
+ <select value={formatNumber(modal.modalProps.end.month)} onChange={(e) => onUpdatePeriodForm(e, 'end', 'month', modal.modalProps)} id="q_validity_period_end_gteq_2i" className="date required form-control">
{makeMonthsOptions(modal.modalProps.end.month)}
</select>
- <select value={modal.modalProps.end.year} onChange={(e) => onUpdatePeriodForm(e, 'end', 'year')} id="q_validity_period_end_gteq_1i" className="date required form-control">
+ <select value={modal.modalProps.end.year} onChange={(e) => onUpdatePeriodForm(e, 'end', 'year', modal.modalProps)} id="q_validity_period_end_gteq_1i" className="date required form-control">
{makeYearsOptions(modal.modalProps.end.year)}
</select>
</div>
diff --git a/app/assets/javascripts/es6_browserified/time_tables/containers/PeriodForm.js b/app/assets/javascripts/es6_browserified/time_tables/containers/PeriodForm.js
index a7edbc328..7f2db785a 100644
--- a/app/assets/javascripts/es6_browserified/time_tables/containers/PeriodForm.js
+++ b/app/assets/javascripts/es6_browserified/time_tables/containers/PeriodForm.js
@@ -1,6 +1,7 @@
var connect = require('react-redux').connect
var PeriodFormComponent = require('../components/PeriodForm')
var actions = require('../actions')
+var _ = require('lodash')
const mapStateToProps = (state) => {
return {
@@ -18,10 +19,13 @@ const mapDispatchToProps = (dispatch) => {
onClosePeriodForm: () => {
dispatch(actions.closePeriodForm())
},
- onUpdatePeriodForm: (e, group, selectType) => {
+ onUpdatePeriodForm: (e, group, selectType, modalProps) => {
dispatch(actions.updatePeriodForm(e.currentTarget.value, group, selectType))
- let selector = '#q_validity_period_' + group + '_gteq_3i'
- dispatch(actions.updatePeriodForm($(selector).val(), group, 'day'))
+ let mProps = _.assign({}, modalProps)
+ mProps[group][selectType] = e.currentTarget.value
+ let val = window.correctDay([parseInt(mProps[group]['day']), parseInt(mProps[group]['month']), parseInt(mProps[group]['year'])])
+ val = (val < 10) ? '0' + String(val) : String(val)
+ dispatch(actions.updatePeriodForm(val, group, 'day'))
},
onValidatePeriodForm: (modalProps, timeTablePeriods, metas) => {
dispatch(actions.validatePeriodForm(modalProps, timeTablePeriods, metas))
diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/actions/index.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/actions/index.js
index e90d2d307..c30f460d8 100644
--- a/app/assets/javascripts/es6_browserified/vehicle_journeys/actions/index.js
+++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/actions/index.js
@@ -449,12 +449,18 @@ const actions = {
if (parseInt(schedule.departure_time.minute) < 0){
hours = Math.floor(parseInt(schedule.departure_time.minute) / 60)
minutes = (parseInt(schedule.departure_time.minute) % 60) + 60
+ if(minutes == 60){
+ minutes = 0
+ }
schedule.departure_time.minute = actions.simplePad(minutes, 'minute')
schedule.departure_time.hour = parseInt(schedule.departure_time.hour) + hours
}
if (parseInt(schedule.arrival_time.minute) < 0){
hours = Math.floor(parseInt(schedule.arrival_time.minute) / 60)
minutes = (parseInt(schedule.arrival_time.minute) % 60) + 60
+ if(minutes == 60){
+ minutes = 0
+ }
schedule.arrival_time.minute = actions.simplePad(minutes, 'minute')
schedule.arrival_time.hour = parseInt(schedule.arrival_time.hour) + hours
}
diff --git a/app/assets/javascripts/smart_date.coffee b/app/assets/javascripts/smart_date.coffee
index afc0c7ddf..48aa1c2f9 100644
--- a/app/assets/javascripts/smart_date.coffee
+++ b/app/assets/javascripts/smart_date.coffee
@@ -2,8 +2,6 @@ window.legalDaysPerMonth =
false: [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31],
true: [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
-
-window.legal
window.correctDay = (dateValues) ->
[day, month, year] = dateValues
return day unless day > 0 && month > 0 && year > 0
diff --git a/app/assets/stylesheets/components/_tables.sass b/app/assets/stylesheets/components/_tables.sass
index 20679a3ba..b991e7b8d 100644
--- a/app/assets/stylesheets/components/_tables.sass
+++ b/app/assets/stylesheets/components/_tables.sass
@@ -296,7 +296,7 @@
border-right: 1px solid rgba($grey, 0.5)
.th
- > div
+ > div:not(.btn-group)
min-height: 19px
> *:first-child
diff --git a/app/assets/stylesheets/modules/_jp_collection.sass b/app/assets/stylesheets/modules/_jp_collection.sass
index c109fc71a..f579cf87b 100644
--- a/app/assets/stylesheets/modules/_jp_collection.sass
+++ b/app/assets/stylesheets/modules/_jp_collection.sass
@@ -98,3 +98,33 @@
left: -23px
top: 50%
margin-top: -8px
+
+ // Errors
+ .table-2entries .t2e-item-list
+ .t2e-item
+ position: relative
+
+ .th .vj_tt
+ display: inline-block
+ vertical-align: top
+
+ + .vj_tt
+ margin-left: 5px
+
+ &.has-error
+ &:before
+ content: ''
+ position: absolute
+ top: 0
+ left: 0
+ right: 0
+ bottom: 0
+ border: 2px solid $red
+
+ > .th
+ > div:first-child, > div:first-child + div
+ color: $red
+
+ // Reset default behaviour
+ .form-control
+ border-color: #ccc
diff --git a/app/controllers/time_tables_controller.rb b/app/controllers/time_tables_controller.rb
index 3704f2885..6d2639981 100644
--- a/app/controllers/time_tables_controller.rb
+++ b/app/controllers/time_tables_controller.rb
@@ -49,8 +49,8 @@ class TimeTablesController < ChouetteController
calendar.dates.each_with_index do |date, i|
@time_table.dates << Chouette::TimeTableDate.new(date: date, position: i, in_out: true)
end
- calendar.date_ranges.each_with_index do |date_range, i|
- @time_table.periods << Chouette::TimeTablePeriod.new(period_start: date_range.begin, period_end: date_range.end, position: i)
+ calendar.periods.each_with_index do |period, i|
+ @time_table.periods << Chouette::TimeTablePeriod.new(period_start: period.begin, period_end: period.end, position: i)
end
end
diff --git a/app/helpers/links_helper.rb b/app/helpers/links_helper.rb
index 683b66a52..4fb7a797d 100644
--- a/app/helpers/links_helper.rb
+++ b/app/helpers/links_helper.rb
@@ -1,5 +1,5 @@
module LinksHelper
def destroy_link_content(translation_key = 'actions.destroy')
- content_tag(:span, nil, class: 'fa fa-trash') + t(translation_key)
+ content_tag(:span, nil, class: 'fa fa-trash mr-xs') + t(translation_key)
end
end
diff --git a/app/models/calendar.rb b/app/models/calendar.rb
index 70fea9619..fb575515a 100644
--- a/app/models/calendar.rb
+++ b/app/models/calendar.rb
@@ -28,7 +28,7 @@ class Calendar < ActiveRecord::Base
self.dates.each do |d|
tt.dates << Chouette::TimeTableDate.new(date: d, in_out: true)
end
- self.date_ranges.each do |p|
+ self.periods.each do |p|
tt.periods << Chouette::TimeTablePeriod.new(period_start: p.begin, period_end: p.end)
end
end
diff --git a/app/models/chouette/journey_pattern.rb b/app/models/chouette/journey_pattern.rb
index a146dcff1..868d8121e 100644
--- a/app/models/chouette/journey_pattern.rb
+++ b/app/models/chouette/journey_pattern.rb
@@ -27,7 +27,7 @@ class Chouette::JourneyPattern < Chouette::TridentActiveRecord
jp = find_by(objectid: item['object_id']) || state_create_instance(route, item)
next if item['deletable'] && jp.persisted? && jp.destroy
# Update attributes and stop_points associations
- jp.update_attributes(state_permited_attributes(item))
+ jp.update_attributes(state_permited_attributes(item)) unless item['new_record']
jp.state_stop_points_update(item) if !jp.errors.any? && jp.persisted?
item['errors'] = jp.errors if jp.errors.any?
end
@@ -53,6 +53,13 @@ class Chouette::JourneyPattern < Chouette::TridentActiveRecord
def self.state_create_instance route, item
# Flag new record, so we can unset object_id if transaction rollback
jp = route.journey_patterns.create(state_permited_attributes(item))
+
+ # FIXME
+ # DefaultAttributesSupport will trigger some weird validation on after save
+ # wich will call to valid?, wich will populate errors
+ # In this case, we mark jp to be valid if persisted? return true
+ jp.errors.clear if jp.persisted?
+
item['object_id'] = jp.objectid
item['new_record'] = true
jp
diff --git a/app/models/chouette/time_table.rb b/app/models/chouette/time_table.rb
index c566452f4..d907d797e 100644
--- a/app/models/chouette/time_table.rb
+++ b/app/models/chouette/time_table.rb
@@ -496,33 +496,39 @@ class Chouette::TimeTable < Chouette::TridentActiveRecord
self.convert_continuous_dates_to_periods
end
+ def included_days_in_dates_and_periods
+ in_day = self.dates.select {|d| d.in_out }.map(&:date)
+ out_day = self.dates.select {|d| !d.in_out }.map(&:date)
+
+ in_periods = self.periods.map{|p| (p.period_start..p.period_end).to_a }.flatten
+ days = in_periods + in_day
+ days -= out_day
+ days
+ end
+
# remove dates form tt which aren't in another_tt
def intersect!(another_tt)
transaction do
-
- # transform tt as effective dates and get common ones
- days = another_tt.intersects(self.effective_days) & self.intersects(another_tt.effective_days)
+ days = self.included_days_in_dates_and_periods & another_tt.included_days_in_dates_and_periods
self.dates.clear
- days.each {|d| self.dates << Chouette::TimeTableDate.new( :date =>d, :in_out => true)}
self.periods.clear
- self.dates.to_a.sort! { |a,b| a.date <=> b.date}
+ days.sort.each do |d|
+ self.dates << Chouette::TimeTableDate.new(:date => d, :in_out => true)
+ end
self.save!
end
self.convert_continuous_dates_to_periods
end
-
+ # remove days from another calendar
def disjoin!(another_tt)
transaction do
- # remove days from another calendar
- days_to_exclude = self.intersects(another_tt.effective_days)
- days = self.effective_days - days_to_exclude
+ days = self.included_days_in_dates_and_periods - another_tt.included_days_in_dates_and_periods
self.dates.clear
self.periods.clear
- days.each {|d| self.dates << Chouette::TimeTableDate.new( :date =>d, :in_out => true)}
-
- self.dates.to_a.sort! { |a,b| a.date <=> b.date}
- self.periods.to_a.sort! { |a,b| a.period_start <=> b.period_start}
+ days.sort.each do |d|
+ self.dates << Chouette::TimeTableDate.new(:date => d, :in_out => true)
+ end
self.save!
end
self.convert_continuous_dates_to_periods
diff --git a/app/models/clean_up.rb b/app/models/clean_up.rb
index e39928a17..cbcde72f5 100644
--- a/app/models/clean_up.rb
+++ b/app/models/clean_up.rb
@@ -16,10 +16,13 @@ class CleanUp < ActiveRecord::Base
def clean
{}.tap do |result|
- result['time_table'] = send("destroy_time_tables_#{self.date_type}").try(:count)
+ processed = send("destroy_time_tables_#{self.date_type}")
+ if processed
+ result['time_table'] = processed[:time_tables].try(:count)
+ result['vehicle_journey'] = processed[:vehicle_journeys].try(:count)
+ end
result['time_table_date'] = send("destroy_time_tables_dates_#{self.date_type}").try(:count)
result['time_table_period'] = send("destroy_time_tables_periods_#{self.date_type}").try(:count)
- result['vehicle_journey'] = destroy_vehicle_journey_without_time_table.try(:count)
self.overlapping_periods.each do |period|
exclude_dates_in_overlapping_period(period)
end
@@ -106,13 +109,16 @@ class CleanUp < ActiveRecord::Base
end
def destroy_time_tables(time_tables)
+ results = { :time_tables => [], :vehicle_journeys => [] }
# Delete vehicle_journey time_table association
time_tables.each do |time_table|
time_table.vehicle_journeys.each do |vj|
vj.time_tables.delete(time_table)
+ results[:vehicle_journeys] << vj.destroy if vj.time_tables.empty?
end
end
- time_tables.destroy_all
+ results[:time_tables] = time_tables.destroy_all
+ results
end
aasm column: :status do
diff --git a/app/models/referential_metadata.rb b/app/models/referential_metadata.rb
index 357465c63..b774072c7 100644
--- a/app/models/referential_metadata.rb
+++ b/app/models/referential_metadata.rb
@@ -44,8 +44,8 @@ class ReferentialMetadata < ActiveRecord::Base
validate :check_end_greather_than_begin
def check_end_greather_than_begin
- if self.begin and self.end and self.begin > self.end
- errors.add(:end, :invalid)
+ if self.begin and self.end and self.begin >= self.end
+ errors.add(:base, I18n.t('referentials.errors.short_period'))
end
end
diff --git a/app/views/access_link_pairs/_access_link_pair.html.slim b/app/views/access_link_pairs/_access_link_pair.html.slim
index 3eebfd7f6..c313f9044 100644
--- a/app/views/access_link_pairs/_access_link_pair.html.slim
+++ b/app/views/access_link_pairs/_access_link_pair.html.slim
@@ -1,5 +1,4 @@
tr
- - require 'pry'; binding.pry
td
.link
.access_point
diff --git a/app/views/calendars/show.html.slim b/app/views/calendars/show.html.slim
index 26248cea8..4ce5de57f 100644
--- a/app/views/calendars/show.html.slim
+++ b/app/views/calendars/show.html.slim
@@ -25,4 +25,4 @@
Calendar.human_attribute_name(:shared) => t("#{@calendar.shared}"),
'Organisation' => @calendar.organisation.name,
Calendar.human_attribute_name(:dates) => @calendar.dates.collect{|d| l(d, format: :short)}.join(', ').html_safe,
- Calendar.human_attribute_name(:date_ranges) => @calendar.date_ranges.collect{|d| t('validity_range', debut: l(d.begin, format: :short), end: l(d.end, format: :short))}.join('<br>').html_safe }
+ Calendar.human_attribute_name(:date_ranges) => @calendar.periods.map{|d| t('validity_range', debut: l(d.begin, format: :short), end: l(d.end, format: :short))}.join('<br>').html_safe }
diff --git a/bin/bundle b/bin/bundle
deleted file mode 100755
index 66e9889e8..000000000
--- a/bin/bundle
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/usr/bin/env ruby
-ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
-load Gem.bin_path('bundler', 'bundle')
diff --git a/bin/rails b/bin/rails
deleted file mode 100755
index f2b0313dd..000000000
--- a/bin/rails
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/usr/bin/env ruby
-begin
- load File.expand_path('../spring', __FILE__)
-rescue LoadError => e
- raise unless e.message.include?('spring')
-end
-APP_PATH = File.expand_path('../../config/application', __FILE__)
-require_relative '../config/boot'
-require 'rails/commands'
diff --git a/bin/rake b/bin/rake
deleted file mode 100755
index d87d5f578..000000000
--- a/bin/rake
+++ /dev/null
@@ -1,9 +0,0 @@
-#!/usr/bin/env ruby
-begin
- load File.expand_path('../spring', __FILE__)
-rescue LoadError => e
- raise unless e.message.include?('spring')
-end
-require_relative '../config/boot'
-require 'rake'
-Rake.application.run
diff --git a/bin/spring b/bin/spring
deleted file mode 100755
index fb2ec2ebb..000000000
--- a/bin/spring
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/usr/bin/env ruby
-
-# This file loads spring without using Bundler, in order to be fast.
-# It gets overwritten when you run the `spring binstub` command.
-
-unless defined?(Spring)
- require 'rubygems'
- require 'bundler'
-
- lockfile = Bundler::LockfileParser.new(Bundler.default_lockfile.read)
- spring = lockfile.specs.detect { |spec| spec.name == "spring" }
- if spring
- Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path
- gem 'spring', spring.version
- require 'spring/binstub'
- end
-end
diff --git a/config/deploy.rb b/config/deploy.rb
index 0445ec480..4ab888e92 100644
--- a/config/deploy.rb
+++ b/config/deploy.rb
@@ -51,7 +51,7 @@ namespace :deploy do
end
task :bundle_link do
- run "ln -fs #{bundle_cmd} #{release_path}/bin/bundle"
+ run "mkdir -p #{release_path}/bin && ln -fs #{bundle_cmd} #{release_path}/bin/bundle"
end
after "bundle:install", "deploy:bundle_link"
diff --git a/config/locales/referentials.fr.yml b/config/locales/referentials.fr.yml
index b9e337503..f69c26276 100644
--- a/config/locales/referentials.fr.yml
+++ b/config/locales/referentials.fr.yml
@@ -41,6 +41,7 @@ fr:
user_excluded: "%{user} est une valeur réservée"
overlapped_referential: "%{referential} couvre le même périmètre d'offre"
overlapped_period: "Une autre période chevauche cette période"
+ short_period: La durée minimum d'une période est de deux jours
activerecord:
models:
referential:
diff --git a/spec/helpers/table_builder_helper_spec.rb b/spec/helpers/table_builder_helper_spec.rb
index 8f4d98c88..67980fc2c 100644
--- a/spec/helpers/table_builder_helper_spec.rb
+++ b/spec/helpers/table_builder_helper_spec.rb
@@ -81,7 +81,7 @@ describe TableBuilderHelper, type: :helper do
<li><a href="/referentials/#{referential.id}/time_tables">Calendriers</a></li>
<li><a href="/referentials/new?from=#{referential.id}">Dupliquer</a></li>
<li><a rel="nofollow" data-method="put" href="/referentials/#{referential.id}/archive">Conserver</a></li>
- <li class="delete-action"><a data-confirm="Etes vous sûr de vouloir supprimer ce jeu de données ?" rel="nofollow" data-method="delete" href="/referentials/#{referential.id}"><span class="fa fa-trash"></span>Supprimer</a></li>
+ <li class="delete-action"><a data-confirm="Etes vous sûr de vouloir supprimer ce jeu de données ?" rel="nofollow" data-method="delete" href="/referentials/#{referential.id}"><span class="fa fa-trash mr-xs"></span>Supprimer</a></li>
</ul>
</div>
</td>
diff --git a/spec/models/calendar_spec.rb b/spec/models/calendar_spec.rb
index cf7e4aa27..f5020ebf8 100644
--- a/spec/models/calendar_spec.rb
+++ b/spec/models/calendar_spec.rb
@@ -8,13 +8,13 @@ RSpec.describe Calendar, :type => :model do
it { is_expected.to validate_uniqueness_of(:short_name) }
describe '#to_time_table' do
- let(:calendar) { create(:calendar, date_ranges: [Date.today..(Date.today + 1.month)]) }
+ let(:calendar) { create(:calendar, date_ranges: [Date.today...(Date.today + 1.month)]) }
it 'should convert calendar to an instance of Chouette::TimeTable' do
time_table = calendar.convert_to_time_table
expect(time_table).to be_an_instance_of(Chouette::TimeTable)
- expect(time_table.periods[0].period_start).to eq(calendar.date_ranges[0].begin)
- expect(time_table.periods[0].period_end).to eq(calendar.date_ranges[0].end)
+ expect(time_table.periods[0].period_start).to eq(calendar.periods[0].begin)
+ expect(time_table.periods[0].period_end).to eq(calendar.periods[0].end)
expect(time_table.dates.map(&:date)).to match_array(calendar.dates)
end
end
diff --git a/spec/models/chouette/journey_pattern_spec.rb b/spec/models/chouette/journey_pattern_spec.rb
index aaf9a694f..6601ed5f4 100644
--- a/spec/models/chouette/journey_pattern_spec.rb
+++ b/spec/models/chouette/journey_pattern_spec.rb
@@ -20,6 +20,11 @@ describe Chouette::JourneyPattern, :type => :model do
expect(journey_pattern).to_not be_valid
expect(journey_pattern.errors).to have_key(:stop_points)
end
+
+ it 'should only validate on update' do
+ jp = build(:journey_pattern_common)
+ expect(jp).to be_valid
+ end
end
describe "state_update" do
diff --git a/spec/models/chouette/time_table_spec.rb b/spec/models/chouette/time_table_spec.rb
index 76c5def5c..bd74a2d4c 100644
--- a/spec/models/chouette/time_table_spec.rb
+++ b/spec/models/chouette/time_table_spec.rb
@@ -7,6 +7,10 @@ describe Chouette::TimeTable, :type => :model do
it { is_expected.to validate_presence_of :comment }
it { is_expected.to validate_uniqueness_of :objectid }
+ def create_time_table_periode time_table, start_date, end_date
+ create(:time_table_period, time_table: time_table, :period_start => start_date, :period_end => end_date)
+ end
+
describe "#merge! with time_table" do
let(:another_tt) { create(:time_table) }
let(:another_tt_periods_to_range) { another_tt.periods.map{|p| p.period_start..p.period_end } }
@@ -72,6 +76,134 @@ describe Chouette::TimeTable, :type => :model do
end
end
+ describe "#disjoin!" do
+ let(:another_tt) { create(:time_table) }
+
+ context 'dates' do
+ before do
+ subject.periods.clear
+ another_tt.periods.clear
+ end
+
+ it 'should remove common dates' do
+ subject.disjoin!(another_tt)
+ expect(subject.reload.dates).to be_empty
+ end
+
+ it 'should remove common dates with mixed none common dates' do
+ another_tt.dates.clear
+ another_tt.dates << create(:time_table_date, time_table: another_tt, date: subject.dates[0].date)
+
+ subject.disjoin!(another_tt)
+ expect(subject.reload.dates.map(&:date)).to_not include(another_tt.dates[0].date)
+ end
+ end
+
+ context 'periods' do
+ let(:another_tt_periods_to_range) { another_tt.periods.map{|p| p.period_start..p.period_end } }
+ # Clear dates as we are testing periods
+ before do
+ subject.dates.clear
+ another_tt.dates.clear
+ end
+
+ it 'should remove common dates in periods' do
+ subject.disjoin!(another_tt)
+ expect(subject_periods_to_range).to_not include(*another_tt_periods_to_range)
+ end
+
+ it 'should build new period without common dates in periods' do
+ subject.periods.clear
+ another_tt.periods.clear
+
+ subject.periods << create_time_table_periode(subject, Date.today, Date.today + 10.day)
+ another_tt.periods << create_time_table_periode(another_tt, Date.tomorrow, Date.today + 3.day)
+
+ subject.disjoin!(another_tt)
+ expected_range = Date.tomorrow..Date.today + 3.day
+
+ expect(subject_periods_to_range).to_not include(expected_range)
+ expect(subject.periods.count).to eq 1
+ end
+ end
+ end
+
+ describe '#intersect! with time_table' do
+ let(:another_tt) { create(:time_table) }
+
+ context 'dates' do
+ # Clear periods as we are testing dates
+ before do
+ subject.periods.clear
+ another_tt.periods.clear
+ end
+
+ it 'should keep common dates' do
+ days = subject.dates.map(&:date)
+ subject.intersect!(another_tt)
+ expect(subject.included_days_in_dates_and_periods).to include(*days)
+ end
+
+ it 'should not keep dates who are not in common' do
+ # Add 1 year interval, to make sur we have not dates in common
+ another_tt.dates.map{|d| d.date = d.date + 1.year }
+ subject.intersect!(another_tt)
+
+ expect(subject.reload.dates).to be_empty
+ end
+ end
+
+ context 'periods' do
+ let(:another_tt_periods_to_range) { another_tt.periods.map{|p| p.period_start..p.period_end } }
+ # Clear dates as we are testing periods
+ before do
+ subject.dates.clear
+ another_tt.dates.clear
+ end
+
+ it 'should keep common dates in periods' do
+ subject.intersect!(another_tt)
+ expect(subject_periods_to_range).to include(*another_tt_periods_to_range)
+ end
+
+ it 'should build new period with common dates in periods' do
+ subject.periods.clear
+ another_tt.periods.clear
+
+ subject.periods << create_time_table_periode(subject, Date.today, Date.today + 10.day)
+ another_tt.periods << create_time_table_periode(another_tt, Date.tomorrow, Date.today + 3.day)
+
+ subject.intersect!(another_tt)
+ expected_range = Date.tomorrow..Date.today + 3.day
+
+ expect(subject_periods_to_range).to include(expected_range)
+ expect(subject.periods.count).to eq 1
+ end
+
+ it 'should not keep dates in periods who are not in common' do
+ another_tt.periods.map do |p|
+ p.period_start = p.period_start + 1.year
+ p.period_end = p.period_end + 1.year
+ end
+
+ subject.intersect!(another_tt)
+ expect(subject.periods).to be_empty
+ end
+
+ context 'with calendar' do
+ let(:period_start) { subject.periods[0].period_start }
+ let(:period_end) { subject.periods[0].period_end }
+ let(:another_tt) { create(:calendar, date_ranges: [period_start..period_end]).convert_to_time_table }
+
+ it 'should keep common dates in periods' do
+ subject.intersect!(another_tt)
+ expect(subject.reload.periods.count).to eq 1
+ expect(subject_periods_to_range).to include(*another_tt_periods_to_range)
+ end
+ end
+ end
+ end
+
describe "actualize" do
let(:calendar) { create(:calendar) }
let(:int_day_types) { 508 }
@@ -1037,378 +1169,6 @@ end
end
end
- describe "#intersect!" do
- context "timetables have periods with common day_types " do
- before do
- subject.periods.clear
- subject.dates.clear
- subject.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2014,8,1), :period_end => Date.new(2014,8,6))
- subject.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2014,6,30), :period_end => Date.new(2014,7,20))
- subject.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,16), :in_out => true)
- subject.int_day_types = 4|16|32|128
- another_tt = create(:time_table , :int_day_types => (4|16|64|128) )
- another_tt.periods.clear
- another_tt.dates.clear
- another_tt.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2014,8,6), :period_end => Date.new(2014,8,12))
- another_tt.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2014,7,15), :period_end => Date.new(2014,7,25))
- subject.intersect! another_tt
- subject.reload
- end
- it "should have no period" do
- expect(subject.periods.size).to eq(0)
- end
- it "should have date all common days" do
- expect(subject.dates.size).to eq(3)
- expect(subject.dates[0].date).to eq(Date.new(2014,7,16))
- expect(subject.dates[1].date).to eq(Date.new(2014,7,19))
- expect(subject.dates[2].date).to eq(Date.new(2014,8,6))
- end
- end
- context "timetables have periods or dates " do
- before do
- subject.periods.clear
- subject.dates.clear
- subject.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,16), :in_out => true)
- subject.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,17), :in_out => true)
- subject.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,18), :in_out => true)
- subject.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,19), :in_out => true)
- subject.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,20), :in_out => true)
- subject.int_day_types = 0
- another_tt = create(:time_table , :int_day_types => (4|16|64|128) )
- another_tt.periods.clear
- another_tt.dates.clear
- another_tt.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2014,8,6), :period_end => Date.new(2014,8,12))
- another_tt.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2014,7,17), :period_end => Date.new(2014,7,25))
- subject.intersect! another_tt
- subject.reload
- end
- it "should have 0 period" do
- expect(subject.periods.size).to eq(0)
- end
- it "should not modify day_types" do
- expect(subject.int_day_types).to eq(0)
- end
- it "should have date reduced for period" do
- expect(subject.dates.size).to eq(2)
- expect(subject.dates[0].date).to eq(Date.new(2014,7,18))
- expect(subject.dates[1].date).to eq(Date.new(2014,7,19))
- end
- end
- context "with only periods : intersect timetable have no one day period" do
- before do
- subject.periods.clear
- subject.dates.clear
- subject.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2014,8,1), :period_end => Date.new(2014,8,6))
- subject.int_day_types = 4|8|16
- another_tt = create(:time_table , :int_day_types => (4|8|16) )
- another_tt.periods.clear
- another_tt.dates.clear
- another_tt.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2014,8,6), :period_end => Date.new(2014,8,12))
- subject.intersect! another_tt
- subject.reload
- end
- it "should have 0 result periods" do
- expect(subject.periods.size).to eq(0)
- end
- it "should not modify day_types" do
- expect(subject.int_day_types).to eq(4|8|16)
- end
- it "should have 1 date " do
- expect(subject.dates.size).to eq(1)
- expect(subject.dates[0].date).to eq(Date.new(2014,8,6))
- end
- end
-
- end
-
- describe "#disjoin!" do
- context "timetables have periods with common day_types " do
- before do
- subject.periods.clear
- subject.dates.clear
- subject.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2014,8,1), :period_end => Date.new(2014,8,6))
- subject.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2014,6,30), :period_end => Date.new(2014,7,20))
- subject.int_day_types = 4|16|32|128
- another_tt = create(:time_table , :int_day_types => (4|16|64|128) )
- another_tt.periods.clear
- another_tt.dates.clear
- another_tt.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2014,8,6), :period_end => Date.new(2014,8,12))
- another_tt.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2014,7,15), :period_end => Date.new(2014,8,2))
- subject.disjoin! another_tt
- subject.reload
- end
- it "should have 0 periods" do
- expect(subject.periods.size).to eq(0)
- end
- it "should have only dates " do
- expect(subject.dates.size).to eq(11)
- expect(subject.dates[0].date).to eq(Date.new(2014,6,30))
- expect(subject.dates[1].date).to eq(Date.new(2014,7,2))
- expect(subject.dates[2].date).to eq(Date.new(2014,7,3))
- expect(subject.dates[3].date).to eq(Date.new(2014,7,5))
- expect(subject.dates[4].date).to eq(Date.new(2014,7,7))
- expect(subject.dates[5].date).to eq(Date.new(2014,7,9))
- expect(subject.dates[6].date).to eq(Date.new(2014,7,10))
- expect(subject.dates[7].date).to eq(Date.new(2014,7,12))
- expect(subject.dates[8].date).to eq(Date.new(2014,7,14))
- expect(subject.dates[9].date).to eq(Date.new(2014,7,17))
- expect(subject.dates[10].date).to eq(Date.new(2014,8,4))
- end
- end
- context "timetables have periods or dates " do
- before do
- subject.periods.clear
- subject.dates.clear
- subject.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,16), :in_out => true)
- subject.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,17), :in_out => true)
- subject.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,18), :in_out => true)
- subject.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,19), :in_out => true)
- subject.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,20), :in_out => true)
- subject.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,8,6), :in_out => true)
- subject.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,8,7), :in_out => true)
- subject.int_day_types = 0
- another_tt = create(:time_table , :int_day_types => (4|16|64|128) )
- another_tt.periods.clear
- another_tt.dates.clear
- another_tt.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2014,8,6), :period_end => Date.new(2014,8,12))
- another_tt.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2014,7,17), :period_end => Date.new(2014,7,25))
- subject.disjoin! another_tt
- subject.reload
- end
- it "should have 0 period" do
- expect(subject.periods.size).to eq(0)
- end
- it "should not modify day_types" do
- expect(subject.int_day_types).to eq(0)
- end
- it "should have date reduced for period" do
- expect(subject.dates.size).to eq(4)
- expect(subject.dates[0].date).to eq(Date.new(2014,7,16))
- expect(subject.dates[1].date).to eq(Date.new(2014,7,17))
- expect(subject.dates[2].date).to eq(Date.new(2014,7,20))
- expect(subject.dates[3].date).to eq(Date.new(2014,8,7))
- end
- end
- context "disjoined timetable have all periods in removed ones " do
- before do
- subject.periods.clear
- subject.dates.clear
- subject.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2014,8,1), :period_end => Date.new(2014,8,8))
- subject.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2014,6,30), :period_end => Date.new(2014,7,20))
- subject.int_day_types = 4|16|32|128
- another_tt = create(:time_table , :int_day_types => (4|16|64|128) )
- another_tt.periods.clear
- another_tt.dates.clear
- another_tt.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2014,7,31), :period_end => Date.new(2014,8,12))
- another_tt.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2014,6,30), :period_end => Date.new(2014,7,20))
- subject.disjoin! another_tt
- subject.reload
- end
- it "should have 0 result periods" do
- expect(subject.periods.size).to eq(0)
- end
- it "should have dates for period reduced" do
- expect(subject.dates.size).to eq(4)
- expect(subject.dates[0].date).to eq(Date.new(2014,7,3))
- expect(subject.dates[1].date).to eq(Date.new(2014,7,10))
- expect(subject.dates[2].date).to eq(Date.new(2014,7,17))
- expect(subject.dates[3].date).to eq(Date.new(2014,8,7))
- end
- end
-
- context "timetable with dates against timetable with dates and periods" do
- before do
- subject.periods.clear
- subject.dates.clear
- subject.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,16), :in_out => true)
- subject.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,17), :in_out => true)
- subject.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,18), :in_out => true)
- subject.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,19), :in_out => true)
- subject.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,20), :in_out => true)
- subject.int_day_types = 0
- another_tt = create(:time_table , :int_day_types => (4|16|64|128) )
- another_tt.periods.clear
- another_tt.dates.clear
- another_tt.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2014,7,31), :period_end => Date.new(2014,8,12))
- another_tt.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,17), :in_out => true)
- another_tt.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,18), :in_out => true)
- subject.disjoin! another_tt
- subject.reload
- end
- it "should have 0 result periods" do
- expect(subject.periods.size).to eq(0)
- end
- it "should have 3 dates left" do
- expect(subject.dates.size).to eq(3)
- expect(subject.dates[0].date).to eq(Date.new(2014,7,16))
- expect(subject.dates[1].date).to eq(Date.new(2014,7,19))
- expect(subject.dates[2].date).to eq(Date.new(2014,7,20))
- end
- end
-
- context "timetable with dates against timetable with dates and periods all covered" do
- before do
- subject.periods.clear
- subject.dates.clear
- subject.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,1), :in_out => true)
- subject.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,2), :in_out => true)
- subject.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,5), :in_out => true)
- subject.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,6), :in_out => true)
- subject.int_day_types = 512
- another_tt = create(:time_table , :int_day_types => (32|64|512) )
- another_tt.periods.clear
- another_tt.dates.clear
- another_tt.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2014,6,30), :period_end => Date.new(2014,7,11))
- another_tt.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,1), :in_out => true)
- another_tt.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,2), :in_out => true)
- another_tt.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,5), :in_out => true)
- another_tt.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,7,6), :in_out => true)
- subject.disjoin! another_tt
- subject.reload
- end
-
- it "should have 0 result periods" do
- expect(subject.periods.size).to eq(0)
- end
-
- it "should have 0 dates left" do
- expect(subject.dates.size).to eq(0)
- end
- end
-
- context "with only periods : disjoined timetable have no empty period" do
- before do
- subject.periods.clear
- subject.dates.clear
- subject.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2014,8,1), :period_end => Date.new(2014,8,8))
- subject.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2014,8,10), :period_end => Date.new(2014,8,31))
- subject.int_day_types = 4|8
- another_tt = create(:time_table , :int_day_types => (4|8) )
- another_tt.periods.clear
- another_tt.dates.clear
- another_tt.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2014,8,4), :period_end => Date.new(2014,8,7))
- subject.disjoin! another_tt
- subject.reload
- end
-
- it "should have 0 result periods" do
- expect(subject.periods.size).to eq(0)
- end
-
- it "should have 6 dates " do
- expect(subject.dates.size).to eq(6)
- expect(subject.dates[0].date).to eq(Date.new(2014,8,11))
- expect(subject.dates[1].date).to eq(Date.new(2014,8,12))
- expect(subject.dates[2].date).to eq(Date.new(2014,8,18))
- expect(subject.dates[3].date).to eq(Date.new(2014,8,19))
- expect(subject.dates[4].date).to eq(Date.new(2014,8,25))
- expect(subject.dates[5].date).to eq(Date.new(2014,8,26))
- end
- end
-
- context "with only periods : disjoined timetable have no one day period" do
- before do
- subject.periods.clear
- subject.dates.clear
- subject.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2014,8,1), :period_end => Date.new(2014,8,6))
- subject.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2014,8,10), :period_end => Date.new(2014,8,31))
- subject.int_day_types = 4|8|16
- another_tt = create(:time_table , :int_day_types => (4|8) )
- another_tt.periods.clear
- another_tt.dates.clear
- another_tt.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2014,8,4), :period_end => Date.new(2014,8,5))
- subject.disjoin! another_tt
- subject.reload
- end
-
- it "should have 3 result periods" do
- expect(subject.periods.size).to eq(3)
- [
- ['2014-08-11', '2014-08-13'],
- ['2014-08-18', '2014-08-20'],
- ['2014-08-25', '2014-08-27']
- ].each_with_index do |period, index|
- expect(subject.periods[index].period_start.to_s).to eq(period[0])
- expect(subject.periods[index].period_end.to_s).to eq(period[1])
- end
- end
-
- it "should not modify day_types" do
- expect(subject.int_day_types).to eq(4|8|16)
- end
-
- it "should have 1 dates " do
- expect(subject.dates.size).to eq(1)
- expect(subject.dates.first.date.to_s).to eq('2014-08-06')
- end
- end
-
- context "with periods against dates: disjoined timetable have no unused excluded date" do
- before do
- subject.periods.clear
- subject.dates.clear
- subject.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2014,8,1), :period_end => Date.new(2014,8,8))
- subject.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2014,8,10), :period_end => Date.new(2014,8,31))
- subject.int_day_types = 4|8|16
- another_tt = create(:time_table , :int_day_types => (0) )
- another_tt.periods.clear
- another_tt.dates.clear
- another_tt.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,8,4), :in_out => true)
- another_tt.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,8,5), :in_out => true)
- another_tt.dates << Chouette::TimeTableDate.new( :date => Date.new(2014,8,7), :in_out => true)
- subject.disjoin! another_tt
- subject.reload
- end
-
- it "should have same 3 result periods" do
- expect(subject.periods.size).to eq(3)
- [
- ['2014-08-11', '2014-08-13'],
- ['2014-08-18', '2014-08-20'],
- ['2014-08-25', '2014-08-27']
- ].each_with_index do |period, index|
- expect(subject.periods[index].period_start.to_s).to eq(period[0])
- expect(subject.periods[index].period_end.to_s).to eq(period[1])
- end
- end
-
- it "should not modify day_types" do
- expect(subject.int_day_types).to eq(4|8|16)
- end
-
- it "should have only 1 dates " do
- expect(subject.dates.size).to eq(1)
- expect(subject.dates.first.date.to_s).to eq('2014-08-06')
- end
- end
-
-
- context "with same definition : dsjointed timetable should be empty" do
- before do
- subject.periods.clear
- subject.dates.clear
- subject.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2015,6,1), :period_end => Date.new(2015,6,30))
- subject.dates << Chouette::TimeTableDate.new( :date => Date.new(2015,6,16), :in_out => true)
- subject.dates << Chouette::TimeTableDate.new( :date => Date.new(2015,6,22), :in_out => false)
- subject.int_day_types = 4|8|16|32|64|128|256
- another_tt = create(:time_table , :int_day_types => ( 4|8|16|32|64|128|256) )
- another_tt.periods.clear
- another_tt.dates.clear
- another_tt.periods << Chouette::TimeTablePeriod.new(:period_start => Date.new(2015,6,1), :period_end => Date.new(2015,6,30))
- another_tt.dates << Chouette::TimeTableDate.new( :date => Date.new(2015,6,16), :in_out => true)
- another_tt.dates << Chouette::TimeTableDate.new( :date => Date.new(2015,6,22), :in_out => false)
- subject.disjoin! another_tt
- subject.reload
- end
- it "should have same 0 result periods" do
- expect(subject.periods.size).to eq(0)
- end
- it "should have 0 dates " do
- expect(subject.dates.size).to eq(0)
- end
- end
- end
-
describe "#duplicate" do
it 'should also copy tags' do
subject.tag_list.add('tag1', 'tag2')
diff --git a/spec/models/clean_up_spec.rb b/spec/models/clean_up_spec.rb
index ee88ca773..4dc692ab2 100644
--- a/spec/models/clean_up_spec.rb
+++ b/spec/models/clean_up_spec.rb
@@ -200,9 +200,17 @@ RSpec.describe CleanUp, :type => :model do
end
it 'should destroy time_table vehicle_journey association' do
+ vj = create(:vehicle_journey, time_tables: [time_table, create(:time_table)])
+ cleaner.destroy_time_tables(Chouette::TimeTable.where(id: time_table.id))
+
+ expect(vj.reload.time_tables.map(&:id)).to_not include(time_table.id)
+ end
+
+ it 'should also destroy associated vehicle_journey if it belongs to any other time_table' do
vj = create(:vehicle_journey, time_tables: [time_table])
- cleaner.destroy_time_tables(Chouette::TimeTable.all)
- expect(vj.reload.time_tables).to be_empty
+ expect{cleaner.destroy_time_tables(Chouette::TimeTable.all)}.to change {
+ Chouette::VehicleJourney.count
+ }.by(-1)
end
end
diff --git a/spec/models/referential_metadata_spec.rb b/spec/models/referential_metadata_spec.rb
index 0f628c8d1..91a2a7fc2 100644
--- a/spec/models/referential_metadata_spec.rb
+++ b/spec/models/referential_metadata_spec.rb
@@ -87,7 +87,7 @@ RSpec.describe ReferentialMetadata, :type => :model do
it "should validate that end is greather than or equlals to begin" do
expect(period(begin: "2016-11-21", end: "2016-11-22")).to be_valid
- expect(period(begin: "2016-11-21", end: "2016-11-21")).to be_valid
+ expect(period(begin: "2016-11-21", end: "2016-11-21")).to_not be_valid
expect(period(begin: "2016-11-22", end: "2016-11-21")).to_not be_valid
end
diff --git a/spec/policies/application_policy_spec.rb b/spec/policies/application_policy_spec.rb
index a7234461e..3ec177209 100644
--- a/spec/policies/application_policy_spec.rb
+++ b/spec/policies/application_policy_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe ApplicationPolicy, type: :policy do
end
it "allows a user with a different organisation" do
- user.update_attribute :organisation, referential.organisation
+ user.organisation = referential.organisation
expect_it.to permit(user_context, referential)
end
end
diff --git a/spec/policies/boiv_policy_spec.rb b/spec/policies/boiv_policy_spec.rb
index 514534adc..6787ab2ac 100644
--- a/spec/policies/boiv_policy_spec.rb
+++ b/spec/policies/boiv_policy_spec.rb
@@ -1,5 +1,7 @@
RSpec.describe BoivPolicy, type: :policy do
+ let( :record ){ nil }
+
permissions :index? do
it_behaves_like 'permitted policy and same organisation', 'boiv:read-offer'
end
diff --git a/spec/policies/line_policy_spec.rb b/spec/policies/line_policy_spec.rb
index ead5918aa..e720b2bc7 100644
--- a/spec/policies/line_policy_spec.rb
+++ b/spec/policies/line_policy_spec.rb
@@ -1,5 +1,8 @@
RSpec.describe LinePolicy, type: :policy do
+ let( :record ){ build_stubbed :line }
+
+
%w{create destroy edit}.each do | permission |
footnote_permission = "#{permission}_footnote"
permissions "#{footnote_permission}?".to_sym do
diff --git a/spec/policies/route_policy_spec.rb b/spec/policies/route_policy_spec.rb
index baf14c9fc..cc949ff45 100644
--- a/spec/policies/route_policy_spec.rb
+++ b/spec/policies/route_policy_spec.rb
@@ -1,5 +1,7 @@
RSpec.describe RoutePolicy, type: :policy do
+ let( :record ){ build_stubbed :route }
+
permissions :create? do
it_behaves_like 'permitted policy', 'routes.create', archived: true
end
diff --git a/spec/policies/routing_constraint_zone_policy_spec.rb b/spec/policies/routing_constraint_zone_policy_spec.rb
index 4b0f2cafe..2508b49f9 100644
--- a/spec/policies/routing_constraint_zone_policy_spec.rb
+++ b/spec/policies/routing_constraint_zone_policy_spec.rb
@@ -1,5 +1,8 @@
RSpec.describe RoutingConstraintZonePolicy, type: :policy do
+ let( :record ){ build_stubbed :routing_constraint_zone }
+
+
permissions :create? do
it_behaves_like 'permitted policy', 'routing_constraint_zones.create', archived: true
end
diff --git a/spec/policies/time_table_policy_spec.rb b/spec/policies/time_table_policy_spec.rb
index 1283a9fcf..90e6600ea 100644
--- a/spec/policies/time_table_policy_spec.rb
+++ b/spec/policies/time_table_policy_spec.rb
@@ -1,5 +1,8 @@
RSpec.describe TimeTablePolicy, type: :policy do
+ let( :record ){ build_stubbed :time_table }
+
+
permissions :duplicate? do
it_behaves_like 'permitted policy and same organisation', 'time_tables.create', archived: true
end
diff --git a/spec/support/pundit/policies.rb b/spec/support/pundit/policies.rb
index 56433b2ee..02fea2944 100644
--- a/spec/support/pundit/policies.rb
+++ b/spec/support/pundit/policies.rb
@@ -24,8 +24,8 @@ module Support
into.module_eval do
subject { described_class }
let( :user_context ) { create_user_context(user: user, referential: referential) }
- let( :referentail ) { create :referential }
- let( :user ) { create :user }
+ let( :referential ) { build_stubbed :referential }
+ let( :user ) { build_stubbed :user }
end
end
def with_user_permission(permission, &blk)
diff --git a/spec/support/pundit/shared_examples.rb b/spec/support/pundit/shared_examples.rb
index 4d14c46da..33ed1ffae 100644
--- a/spec/support/pundit/shared_examples.rb
+++ b/spec/support/pundit/shared_examples.rb
@@ -3,11 +3,11 @@ RSpec.shared_examples 'permitted policy and same organisation' do
context 'permission absent → ' do
it "denies a user with a different organisation" do
- expect_it.not_to permit(user_context, referential)
+ expect_it.not_to permit(user_context, record)
end
it 'and also a user with the same organisation' do
- user.update_attribute :organisation, referential.organisation
- expect_it.not_to permit(user_context, referential)
+ user.organisation = referential.organisation
+ expect_it.not_to permit(user_context, record)
end
end
@@ -17,19 +17,19 @@ RSpec.shared_examples 'permitted policy and same organisation' do
end
it 'denies a user with a different organisation' do
- expect_it.not_to permit(user_context, referential)
+ expect_it.not_to permit(user_context, record)
end
it 'but allows it for a user with the same organisation' do
- user.update_attribute :organisation, referential.organisation
- expect_it.to permit(user_context, referential)
+ user.organisation = referential.organisation
+ expect_it.to permit(user_context, record)
end
if archived
it 'removes the permission for archived referentials' do
- user.update_attribute :organisation, referential.organisation
- referential.update_attribute :archived_at, 42.seconds.ago
- expect_it.not_to permit(user_context, referential)
+ user.organisation = referential.organisation
+ referential.archived_at = 42.seconds.ago
+ expect_it.not_to permit(user_context, record)
end
end
end
@@ -39,7 +39,7 @@ RSpec.shared_examples 'permitted policy' do
| permission, archived: false|
context 'permission absent → ' do
it "denies a user with a different organisation" do
- expect_it.not_to permit(user_context, referential)
+ expect_it.not_to permit(user_context, record)
end
end
context 'permission present → ' do
@@ -47,13 +47,13 @@ RSpec.shared_examples 'permitted policy' do
add_permissions(permission, for_user: user)
end
it 'allows a user with a different organisation' do
- expect_it.to permit(user_context, referential)
+ expect_it.to permit(user_context, record)
end
if archived
it 'removes the permission for archived referentials' do
- referential.update_attribute :archived_at, 42.seconds.ago
- expect_it.not_to permit(user_context, referential)
+ referential.archived_at = 42.seconds.ago
+ expect_it.not_to permit(user_context, record)
end
end
end