aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert2017-05-09 17:01:16 +0200
committerRobert2017-05-09 17:01:16 +0200
commit1c9e056f078e89ddfbe1d3c06ce00a4035d4ef98 (patch)
treeaec4a6003c02c8e12055a5df5c6b41abed4aaa70
parent85c6f283fb3cbff9a937ebe6d74f8ed0499c27ef (diff)
parentc007b5f1442b903948373337a6cc7d7d42364b41 (diff)
downloadchouette-core-1c9e056f078e89ddfbe1d3c06ce00a4035d4ef98.tar.bz2
Manual Conflict Resolution
-rw-r--r--INSTALL.md39
-rw-r--r--app/assets/javascripts/es6_browserified/journey_patterns/actions/index.js4
-rw-r--r--app/assets/javascripts/es6_browserified/journey_patterns/components/JourneyPattern.js4
-rw-r--r--app/assets/javascripts/es6_browserified/time_tables/actions/index.js12
-rw-r--r--app/assets/javascripts/es6_browserified/time_tables/components/ExceptionsInDay.js4
-rw-r--r--app/assets/javascripts/es6_browserified/time_tables/components/Navigate.js2
-rw-r--r--app/assets/javascripts/es6_browserified/time_tables/components/PeriodManager.js22
-rw-r--r--app/assets/javascripts/es6_browserified/time_tables/components/PeriodsInDay.js3
-rw-r--r--app/assets/javascripts/es6_browserified/time_tables/containers/Timetable.js8
-rw-r--r--app/assets/javascripts/es6_browserified/vehicle_journeys/actions/index.js4
-rw-r--r--app/assets/javascripts/es6_browserified/vehicle_journeys/components/VehicleJourney.js5
-rw-r--r--app/assets/stylesheets/modules/_jp_collection.sass16
-rw-r--r--app/assets/stylesheets/modules/_routes_stopoints.sass18
-rw-r--r--app/assets/stylesheets/modules/_timetables.sass18
-rw-r--r--app/assets/stylesheets/modules/_vj_collection.sass22
-rw-r--r--app/controllers/application_controller.rb5
-rw-r--r--app/controllers/calendars_controller.rb7
-rw-r--r--app/controllers/routes_controller.rb6
-rw-r--r--app/controllers/vehicle_journeys_controller.rb4
-rw-r--r--app/models/calendar.rb10
-rw-r--r--app/models/chouette/route.rb2
-rw-r--r--app/models/chouette/time_table.rb25
-rw-r--r--app/models/chouette/vehicle_journey.rb13
-rw-r--r--app/models/route_observer.rb4
-rw-r--r--app/models/time_table_combination.rb40
-rw-r--r--app/views/line_referentials/show.html.slim11
-rw-r--r--app/views/referentials/show.html.slim4
-rw-r--r--app/views/stop_area_referentials/show.html.slim5
-rw-r--r--app/views/time_tables/index.html.slim2
-rw-r--r--config/application.rb2
-rw-r--r--config/locales/en.yml2
-rw-r--r--config/locales/fr.yml2
-rw-r--r--config/locales/line_referentials.en.yml3
-rw-r--r--config/locales/line_referentials.fr.yml3
-rw-r--r--db/schema.rb18
-rw-r--r--lib/stif/codif_line_synchronization.rb10
-rw-r--r--lib/stif/reflex_synchronization.rb2
-rw-r--r--spec/factories/chouette_routes.rb11
-rw-r--r--spec/factories/chouette_vehicle_journey.rb30
-rw-r--r--spec/javascripts/time_table/actions_spec.js155
-rw-r--r--spec/javascripts/time_table/reducers/metas_spec.js2
-rw-r--r--spec/javascripts/time_table/reducers/modal_spec.js249
-rw-r--r--spec/javascripts/time_table/reducers/pagination_spec.js128
-rw-r--r--spec/javascripts/time_table/reducers/status_spec.js50
-rw-r--r--spec/javascripts/time_table/reducers/timetable_spec.js184
-rw-r--r--spec/models/chouette/route/route_base_spec.rb69
-rw-r--r--spec/models/chouette/route/route_destroy_spec.rb45
-rw-r--r--spec/models/chouette/route/route_stop_points_spec.rb (renamed from spec/models/chouette/route_spec.rb)69
-rw-r--r--spec/models/chouette/vehicle_journey_spec.rb89
-rw-r--r--spec/models/time_table_combination_spec.rb32
50 files changed, 1307 insertions, 167 deletions
diff --git a/INSTALL.md b/INSTALL.md
index 4e052a0db..1d5badb79 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -9,7 +9,7 @@ and install that version.
Example with [rvm](https://rvm.io/):
- rvm install 2.3.0
+ rvm install 2.3.1
Add the bundler gem
@@ -92,6 +92,43 @@ To create Referential with some data (Route, JourneyPattern, VehicleJourney, etc
If PG complains about illegal type `hstore` in your tests that is probably because the shared extension is not installed, here is what to do:
+#### Check installation
+
+* Run tests
+
+ bundle exec rake spec
+ bundle exec rake teaspoon
+
+* Start local server
+
+ bundle exec rails server
+
+
+#### Synchronize With STIF
+
+If you have access to STIF CodifLigne and Reflex :
+
+* Launch Sidekiq
+
+ bundle exec sidekiq
+
+* Execute the Synchronization Tasks
+
+ bundle exec rake codifligne:sync
+ bundle exec rake reflex:sync
+
+**N.B.** These are asynchronious tasks, you can observe the launched jobs in your [Sidekiq Console](http://localhost:3000/sidekiq)
+
+#### Data in various Apartments (Referentials)
+
+To create `Referential` objects with some data (`Route`, `JourneyPattern`, `VehicleJourney`, etc) :
+
+ bundle exec rake referential:create
+
+# Troubleshooting
+
+If Postgres complains about illegal type `hstore` in your tests that is probably because the shared extension is not installed, here is what to do:
+
bundle exec rake db:test:purge
Thanks to `lib/tasks/extensions.rake`.
diff --git a/app/assets/javascripts/es6_browserified/journey_patterns/actions/index.js b/app/assets/javascripts/es6_browserified/journey_patterns/actions/index.js
index 54d62f999..0ed961f44 100644
--- a/app/assets/javascripts/es6_browserified/journey_patterns/actions/index.js
+++ b/app/assets/javascripts/es6_browserified/journey_patterns/actions/index.js
@@ -84,6 +84,10 @@ const actions = {
resetValidation: (target) => {
$(target).parent().removeClass('has-error').children('.help-block').remove()
},
+ humanOID : (oid) => {
+ var a = oid.split(':')
+ return a[a.length - 1]
+ },
validateFields : (fields) => {
const test = []
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 d9f6d5550..14ddf2b99 100644
--- a/app/assets/javascripts/es6_browserified/journey_patterns/components/JourneyPattern.js
+++ b/app/assets/javascripts/es6_browserified/journey_patterns/components/JourneyPattern.js
@@ -14,7 +14,7 @@ class JourneyPattern extends Component{
let vjURL = routeURL + '/vehicle_journeys?jp=' + jpOid
return (
- <a data-no-turbolink="true" href={vjURL}>Horaires des courses</a>
+ <a data-turbolinks="false" href={vjURL}>Horaires des courses</a>
)
}
@@ -62,7 +62,7 @@ class JourneyPattern extends Component{
)}
<div className='th'>
- <div className='strong mb-xs'>{this.props.value.object_id ? this.props.value.object_id : '-'}</div>
+ <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>
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 cef9bc75d..3f15b7f01 100644
--- a/app/assets/javascripts/es6_browserified/time_tables/actions/index.js
+++ b/app/assets/javascripts/es6_browserified/time_tables/actions/index.js
@@ -45,7 +45,7 @@ const actions = {
pagination,
nextPage : true
}),
- changePage : (dispatch, pagination, val) => ({
+ changePage : (dispatch, val) => ({
type: 'CHANGE_PAGE',
dispatch,
page: val
@@ -104,16 +104,14 @@ const actions = {
timeTablePeriods,
metas
}),
- includeDateInPeriod: (index, day, dayTypes) => ({
+ includeDateInPeriod: (index, dayTypes) => ({
type: 'INCLUDE_DATE_IN_PERIOD',
index,
- day,
dayTypes
}),
- excludeDateFromPeriod: (index, day, dayTypes) => ({
+ excludeDateFromPeriod: (index, dayTypes) => ({
type: 'EXCLUDE_DATE_FROM_PERIOD',
index,
- day,
dayTypes
}),
openConfirmModal : (callback) => ({
@@ -140,6 +138,10 @@ const actions = {
return (D + ' ' + M + ' ' + Y)
},
+ getLocaleDate(strDate) {
+ let date = new Date(strDate)
+ return date.toLocaleDateString()
+ },
updateSynthesis: (state, daytypes) => {
let periods = state.time_table_periods
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 13615a6ef..e90099283 100644
--- a/app/assets/javascripts/es6_browserified/time_tables/components/ExceptionsInDay.js
+++ b/app/assets/javascripts/es6_browserified/time_tables/components/ExceptionsInDay.js
@@ -21,7 +21,7 @@ class ExceptionsInDay extends Component {
data-actiontype='remove'
onClick={(e) => {
$(e.currentTarget).toggleClass('active')
- this.props.onExcludeDateFromPeriod(this.props.index, this.props.value.current_month[this.props.index], this.props.metas.day_types)
+ this.props.onExcludeDateFromPeriod(this.props.index, this.props.metas.day_types)
}}
>
<span className='fa fa-times'></span>
@@ -37,7 +37,7 @@ class ExceptionsInDay extends Component {
data-actiontype='add'
onClick={(e) => {
$(e.currentTarget).toggleClass('active')
- this.props.onIncludeDateInPeriod(this.props.index, this.props.value.current_month[this.props.index], this.props.metas.day_types)
+ this.props.onIncludeDateInPeriod(this.props.index, this.props.metas.day_types)
}}
>
<span className='fa fa-plus'></span>
diff --git a/app/assets/javascripts/es6_browserified/time_tables/components/Navigate.js b/app/assets/javascripts/es6_browserified/time_tables/components/Navigate.js
index c43cd025a..74ca36ea6 100644
--- a/app/assets/javascripts/es6_browserified/time_tables/components/Navigate.js
+++ b/app/assets/javascripts/es6_browserified/time_tables/components/Navigate.js
@@ -39,7 +39,7 @@ let Navigate = ({ dispatch, metas, timetable, pagination, status, filters}) => {
value={month}
onClick={e => {
e.preventDefault()
- dispatch(actions.checkConfirmModal(e, actions.changePage(dispatch, pagination, e.currentTarget.value), pagination.stateChanged, dispatch))
+ dispatch(actions.checkConfirmModal(e, actions.changePage(dispatch, e.currentTarget.value), pagination.stateChanged, dispatch))
}}
>
{actions.monthName(month) + ' ' + new Date(month).getFullYear()}
diff --git a/app/assets/javascripts/es6_browserified/time_tables/components/PeriodManager.js b/app/assets/javascripts/es6_browserified/time_tables/components/PeriodManager.js
index de3f31ee0..cf4cbfb32 100644
--- a/app/assets/javascripts/es6_browserified/time_tables/components/PeriodManager.js
+++ b/app/assets/javascripts/es6_browserified/time_tables/components/PeriodManager.js
@@ -8,14 +8,33 @@ class PeriodManager extends Component {
super(props)
}
+ toEndPeriod(curr, end) {
+ let diff
+
+ let startCurrM = curr.split('-')[1]
+ let endPeriodM = end.split('-')[1]
+
+ let lastDayInM = new Date(curr.split('-')[2], startCurrM + 1, 0)
+ lastDayInM = lastDayInM.toJSON().substr(0, 10).split('-')[2]
+
+ if(startCurrM === endPeriodM) {
+ diff = (end.split('-')[2] - curr.split('-')[2])
+ } else {
+ diff = (lastDayInM - curr.split('-')[2])
+ }
+
+ return diff
+ }
+
render() {
return (
<div
className='period_manager'
id={this.props.value.id}
+ data-toendperiod={this.toEndPeriod(this.props.currentDate.toJSON().substr(0, 10), this.props.value.period_end)}
>
<p className='strong'>
- {actions.getHumanDate(this.props.value.period_start, 3).substr(0, 7) + ' > ' + actions.getHumanDate(this.props.value.period_end, 3)}
+ {actions.getLocaleDate(this.props.value.period_start) + ' > ' + actions.getLocaleDate(this.props.value.period_end)}
</p>
<div className='dropdown'>
@@ -58,6 +77,7 @@ class PeriodManager extends Component {
PeriodManager.propTypes = {
value: PropTypes.object.isRequired,
+ currentDate: PropTypes.object.isRequired,
onDeletePeriod: PropTypes.func.isRequired,
onOpenEditPeriodForm: PropTypes.func.isRequired
}
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 93a8fe433..ca44d3a07 100644
--- a/app/assets/javascripts/es6_browserified/time_tables/components/PeriodsInDay.js
+++ b/app/assets/javascripts/es6_browserified/time_tables/components/PeriodsInDay.js
@@ -50,9 +50,10 @@ class PeriodsInDay extends Component {
key={i}
index={i}
value={p}
+ metas={this.props.metas}
+ currentDate={this.props.currentDate}
onDeletePeriod={this.props.onDeletePeriod}
onOpenEditPeriodForm={this.props.onOpenEditPeriodForm}
- metas={this.props.metas}
/>
)
} else {
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 2a17d3dea..c6b5fcc6b 100644
--- a/app/assets/javascripts/es6_browserified/time_tables/containers/Timetable.js
+++ b/app/assets/javascripts/es6_browserified/time_tables/containers/Timetable.js
@@ -15,11 +15,11 @@ const mapDispatchToProps = (dispatch) => {
onDeletePeriod: (index, dayTypes) =>{
dispatch(actions.deletePeriod(index, dayTypes))
},
- onExcludeDateFromPeriod: (index, day, dayTypes) => {
- dispatch(actions.excludeDateFromPeriod(index, day, dayTypes))
+ onExcludeDateFromPeriod: (index, dayTypes) => {
+ dispatch(actions.excludeDateFromPeriod(index, dayTypes))
},
- onIncludeDateInPeriod: (index, day, dayTypes) => {
- dispatch(actions.includeDateInPeriod(index, day, dayTypes))
+ onIncludeDateInPeriod: (index, dayTypes) => {
+ dispatch(actions.includeDateInPeriod(index, dayTypes))
},
onOpenEditPeriodForm: (period, index) => {
dispatch(actions.openEditPeriodForm(period, index))
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 ea03694bd..0e6f5ed12 100644
--- a/app/assets/javascripts/es6_browserified/vehicle_journeys/actions/index.js
+++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/actions/index.js
@@ -248,6 +248,10 @@ const actions = {
type: 'RECEIVE_TOTAL_COUNT',
total
}),
+ humanOID : (oid) => {
+ var a = oid.split(':')
+ return a[a.length - 1]
+ },
fetchVehicleJourneys : (dispatch, currentPage, nextPage, queryString) => {
if(currentPage == undefined){
currentPage = 1
diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/VehicleJourney.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/VehicleJourney.js
index d795d76e3..6f338f747 100644
--- a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/VehicleJourney.js
+++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/VehicleJourney.js
@@ -1,6 +1,7 @@
var React = require('react')
var Component = require('react').Component
var PropTypes = require('react').PropTypes
+var actions = require('../actions')
class VehicleJourney extends Component {
constructor(props) {
@@ -48,8 +49,8 @@ class VehicleJourney extends Component {
return (
<div className={'t2e-item' + (this.props.value.deletable ? ' disabled' : '') + (this.props.value.errors ? ' has-error': '')}>
<div className='th'>
- <div className='strong mb-xs'>{this.props.value.objectid ? this.props.value.objectid : '-'}</div>
- <div>{this.props.value.journey_pattern.objectid}</div>
+ <div className='strong mb-xs'>{this.props.value.objectid ? actions.humanOID(this.props.value.objectid) : '-'}</div>
+ <div>{actions.humanOID(this.props.value.journey_pattern.objectid)}</div>
{this.props.value.time_tables.map((tt, i)=>
<div key={i}>{this.timeTableURL(tt)}</div>
)}
diff --git a/app/assets/stylesheets/modules/_jp_collection.sass b/app/assets/stylesheets/modules/_jp_collection.sass
index d1f864e5c..c109fc71a 100644
--- a/app/assets/stylesheets/modules/_jp_collection.sass
+++ b/app/assets/stylesheets/modules/_jp_collection.sass
@@ -82,3 +82,19 @@
.t2e-head > .td:last-child > div > span
&:after
bottom: 50%
+
+ .t2e-head > .td:nth-child(2) > div,
+ .t2e-head > .td:last-child > div
+ > span:before
+ content: '•'
+ color: $blue
+ text-align: center
+ font-size: 28px
+ letter-spacing: 0
+ text-indent: -0.01em
+ line-height: 12px
+ width: 15px
+ height: 15px
+ left: -23px
+ top: 50%
+ margin-top: -8px
diff --git a/app/assets/stylesheets/modules/_routes_stopoints.sass b/app/assets/stylesheets/modules/_routes_stopoints.sass
index 735e91df7..88e662849 100644
--- a/app/assets/stylesheets/modules/_routes_stopoints.sass
+++ b/app/assets/stylesheets/modules/_routes_stopoints.sass
@@ -12,7 +12,7 @@
height: 100%
> div:first-child
position: relative
- padding-left: 20px /* intial value is 10 */
+ padding-left: 25px /* intial value is 10 */
overflow: hidden
span
@@ -70,3 +70,19 @@
.nested-head + .nested-fields > .wrapper > div:first-child
span:after
top: 5px
+
+ .nested-head + .nested-fields > .wrapper > div:first-child,
+ .nested-fields:last-child > .wrapper:last-child > div:first-child
+ span:before
+ content: '•'
+ color: $blue
+ text-align: center
+ font-size: 28px
+ letter-spacing: 0
+ text-indent: -0.01em
+ line-height: 12px
+ width: 15px
+ height: 15px
+ left: -23px
+ top: 50%
+ margin-top: -8px
diff --git a/app/assets/stylesheets/modules/_timetables.sass b/app/assets/stylesheets/modules/_timetables.sass
index 03dba3e23..84f1af043 100644
--- a/app/assets/stylesheets/modules/_timetables.sass
+++ b/app/assets/stylesheets/modules/_timetables.sass
@@ -125,21 +125,35 @@
display: block
height: auto
word-wrap: normal
- white-space: nowrap
+ white-space: normal
position: absolute
- left: 8px
+ left: 0
top: 50%
transform: translateY(-50%)
z-index: 5
+ padding: 0 8px
+
+ @for $i from 0 through 31
+ &[data-toendperiod='#{$i}']
+ width: 40px * ($i + 1)
> *
display: inline-block
vertical-align: middle
margin: 0
+ max-width: calc(100% - 30px)
&.dropdown
margin-left: 5px
+ &[data-toendperiod='0'], &[data-toendperiod='1'], &[data-toendperiod='2']
+ max-width: none
+ > *
+ display: none
+
+ &.dropdown
+ display: inline-block
+
.btn.dropdown-toggle
color: $blue
background-color: rgba(#fff, 0)
diff --git a/app/assets/stylesheets/modules/_vj_collection.sass b/app/assets/stylesheets/modules/_vj_collection.sass
index 50ad1cd54..8ff983310 100644
--- a/app/assets/stylesheets/modules/_vj_collection.sass
+++ b/app/assets/stylesheets/modules/_vj_collection.sass
@@ -79,6 +79,27 @@
&:after
bottom: -6px
+ .t2e-head > .td:last-child > div > span
+ &:after
+ bottom: 50%
+
+ .table-2entries .t2e-head > .td:nth-child(2) > div,
+ .table-2entries .t2e-head > .td:last-child > div,
+ .table-2entries.no_result .t2e-head > .td:last-child > div
+ > span:before
+ content: '•'
+ color: $blue
+ text-align: center
+ font-size: 28px
+ letter-spacing: 0
+ text-indent: -0.01em
+ line-height: 12px
+ width: 15px
+ height: 15px
+ left: -23px
+ top: 50%
+ margin-top: -8px
+
// Errors
.table-2entries .t2e-item-list
.t2e-item
@@ -92,7 +113,6 @@
left: 0
right: 0
bottom: 0
- z-index: 5
border: 2px solid $red
> .th
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index f2c9b4c6f..42b7c2a25 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -12,7 +12,10 @@ class ApplicationController < ActionController::Base
helper LanguageEngine::Engine.helpers
def set_locale
- I18n.locale = session[:language] || I18n.default_locale
+ # I18n.locale = session[:language] || I18n.default_locale
+ # For testing different locales w/o restarting the server
+ I18n.locale = (params['lang'] || session[:language] || I18n.default_locale).to_sym
+ logger.info "locale set to #{I18n.locale.inspect}"
end
def pundit_user
diff --git a/app/controllers/calendars_controller.rb b/app/controllers/calendars_controller.rb
index d18e165d2..5370d9cbb 100644
--- a/app/controllers/calendars_controller.rb
+++ b/app/controllers/calendars_controller.rb
@@ -45,14 +45,13 @@ class CalendarsController < BreadcrumbController
end
def ransack_contains_date
- # 3 parts to date object, in order to use in ransackable_scopes
+ date =[]
if params[:q] && !params[:q]['contains_date(1i)'].empty?
- date =[]
['contains_date(1i)', 'contains_date(2i)', 'contains_date(3i)'].each do |key|
- date << params[:q][key]
+ date << params[:q][key].to_i
params[:q].delete(key)
end
- params[:q]['contains_date'] = Date.parse(date.join('-'))
+ params[:q]['contains_date'] = Date.new(*date)
end
end
diff --git a/app/controllers/routes_controller.rb b/app/controllers/routes_controller.rb
index a1aadf883..73febc4b9 100644
--- a/app/controllers/routes_controller.rb
+++ b/app/controllers/routes_controller.rb
@@ -46,12 +46,6 @@ class RoutesController < ChouetteController
end
end
- # overwrite inherited resources to use delete instead of destroy
- # foreign keys will propagate deletion)
- def destroy_resource(object)
- object.delete
- end
-
def destroy
destroy! do |success, failure|
success.html { redirect_to referential_line_path(@referential,@line) }
diff --git a/app/controllers/vehicle_journeys_controller.rb b/app/controllers/vehicle_journeys_controller.rb
index c084b592a..316652ca2 100644
--- a/app/controllers/vehicle_journeys_controller.rb
+++ b/app/controllers/vehicle_journeys_controller.rb
@@ -77,14 +77,14 @@ class VehicleJourneysController < ChouetteController
protected
def collection
- scope = route.vehicle_journeys.joins(:journey_pattern).joins('LEFT JOIN "vehicle_journey_at_stops" ON "vehicle_journey_at_stops"."vehicle_journey_id" = "vehicle_journeys"."id"')
+ scope = route.vehicle_journeys.with_stops
@q = scope.search filtered_ransack_params
grouping = ransack_periode_filter
@q.build_grouping(grouping) if grouping
@ppage = 20
- @vehicle_journeys = @q.result(distinct: true).paginate(:page => params[:page], :per_page => @ppage)
+ @vehicle_journeys = @q.result.paginate(:page => params[:page], :per_page => @ppage)
@footnotes = route.line.footnotes.to_json
@matrix = resource_class.matrix(@vehicle_journeys)
@vehicle_journeys
diff --git a/app/models/calendar.rb b/app/models/calendar.rb
index cd945a67f..91a17e853 100644
--- a/app/models/calendar.rb
+++ b/app/models/calendar.rb
@@ -118,9 +118,18 @@ class Calendar < ActiveRecord::Base
end
end
+ def flatten_date_array attributes, key
+ date_int = %w(1 2 3).map {|e| attributes["#{key}(#{e}i)"].to_i }
+ Date.new(*date_int)
+ end
+
def periods_attributes=(attributes = {})
@periods = []
attributes.each do |index, period_attribute|
+ # Convert date_select to date
+ ['begin', 'end'].map do |attr|
+ period_attribute[attr] = flatten_date_array(period_attribute, attr)
+ end
period = Period.new(period_attribute.merge(id: index))
@periods << period unless period.marked_for_destruction?
end
@@ -223,6 +232,7 @@ class Calendar < ActiveRecord::Base
def date_values_attributes=(attributes = {})
@date_values = []
attributes.each do |index, date_value_attribute|
+ date_value_attribute['value'] = flatten_date_array(date_value_attribute, 'value')
date_value = DateValue.new(date_value_attribute.merge(id: index))
@date_values << date_value unless date_value.marked_for_destruction?
end
diff --git a/app/models/chouette/route.rb b/app/models/chouette/route.rb
index 429189ff5..9f6344055 100644
--- a/app/models/chouette/route.rb
+++ b/app/models/chouette/route.rb
@@ -105,7 +105,7 @@ class Chouette::Route < Chouette::TridentActiveRecord
end
def time_tables
- self.vehicle_journeys.joins(:time_tables).map(&:"time_tables").flatten.uniq
+ vehicle_journeys.joins(:time_tables).map(&:"time_tables").flatten.uniq
end
def sorted_vehicle_journeys(journey_category_model)
diff --git a/app/models/chouette/time_table.rb b/app/models/chouette/time_table.rb
index 798fa81b4..37f609163 100644
--- a/app/models/chouette/time_table.rb
+++ b/app/models/chouette/time_table.rb
@@ -33,6 +33,31 @@ class Chouette::TimeTable < Chouette::TridentActiveRecord
validates_associated :dates
validates_associated :periods
+ def continuous_dates
+ chunk = {}
+ group = nil
+ self.dates.where(in_out: true).each_with_index do |date, index|
+ group ||= index
+ group = (date.date == dates[index - 1].date + 1.day) ? group : group + 1
+ chunk[group] ||= []
+ chunk[group] << date
+ end
+ chunk.values
+ end
+
+ def convert_continuous_dates_to_periods
+ chunks = self.continuous_dates
+ # Remove less than 3 continuous day chunk
+ chunks.delete_if {|chunk| chunk.count < 3}
+
+ transaction do
+ chunks.each do |chunk|
+ self.periods.create!(period_start: chunk.first.date, period_end: chunk.last.date)
+ chunk.map(&:destroy)
+ end
+ end
+ end
+
def state_update state
update_attributes(self.class.state_permited_attributes(state))
self.tag_list = state['tags'].collect{|t| t['name']}.join(', ')
diff --git a/app/models/chouette/vehicle_journey.rb b/app/models/chouette/vehicle_journey.rb
index 4d7d596d8..297e462f0 100644
--- a/app/models/chouette/vehicle_journey.rb
+++ b/app/models/chouette/vehicle_journey.rb
@@ -209,5 +209,18 @@ module Chouette
end
end
+ def self.with_stops
+ self
+ .joins(:journey_pattern)
+ .joins('
+ LEFT JOIN "vehicle_journey_at_stops"
+ ON "vehicle_journey_at_stops"."vehicle_journey_id" =
+ "vehicle_journeys"."id"
+ AND "vehicle_journey_at_stops"."stop_point_id" =
+ "journey_patterns"."departure_stop_point_id"
+ ')
+ .order("vehicle_journey_at_stops.departure_time")
+ end
+
end
end
diff --git a/app/models/route_observer.rb b/app/models/route_observer.rb
index 71578c6da..1848bbc85 100644
--- a/app/models/route_observer.rb
+++ b/app/models/route_observer.rb
@@ -14,8 +14,8 @@ class RouteObserver < ActiveRecord::Observer
end
end
- def after_destroy(route)
+ def before_destroy(route)
Rails.logger.debug "after_destroy(#{route.inspect})"
- line.routes.where(opposite_route: route).update_all(opposite_route: nil)
+ route.line.routes.where(opposite_route: route).update_all(opposite_route_id: nil)
end
end
diff --git a/app/models/time_table_combination.rb b/app/models/time_table_combination.rb
index 783ef53ef..519c02f2b 100644
--- a/app/models/time_table_combination.rb
+++ b/app/models/time_table_combination.rb
@@ -1,33 +1,33 @@
class TimeTableCombination
- include ActiveModel::Validations
- include ActiveModel::Conversion
+ include ActiveModel::Validations
+ include ActiveModel::Conversion
extend ActiveModel::Naming
-
- attr_accessor :source_id, :combined_id, :operation
-
- validates_presence_of :source_id, :combined_id, :operation
+
+ attr_accessor :source_id, :combined_id, :operation
+
+ validates_presence_of :source_id, :combined_id, :operation
validates_inclusion_of :operation, :in => %w( union intersection disjunction), :allow_nil => true
-
+
def clean
self.source_id = nil
self.combined_id = nil
self.operation = nil
self.errors.clear
- end
-
+ end
+
def self.operations
%w( union intersection disjunction)
end
- def initialize(attributes = {})
- attributes.each do |name, value|
- send("#{name}=", value)
- end
- end
-
- def persisted?
- false
- end
+ def initialize(attributes = {})
+ attributes.each do |name, value|
+ send("#{name}=", value)
+ end
+ end
+
+ def persisted?
+ false
+ end
def combine
source = Chouette::TimeTable.find( source_id)
@@ -38,10 +38,10 @@ class TimeTableCombination
source.intersect! combined
elsif operation == "disjunction"
source.disjoin! combined
- else
+ else
raise "unknown operation"
end
source
end
-
+
end
diff --git a/app/views/line_referentials/show.html.slim b/app/views/line_referentials/show.html.slim
index 5c0df1a71..95c2c02b0 100644
--- a/app/views/line_referentials/show.html.slim
+++ b/app/views/line_referentials/show.html.slim
@@ -27,9 +27,9 @@
table.table
thead
tr
- th Synchronisé
- th Statut
- th Message
+ th = t('.synchronized')
+ th = t('.status')
+ th = t('.message')
tbody
- @line_referential.line_referential_syncs.each_with_index do |sync, i|
@@ -39,8 +39,9 @@
- sync.line_referential_sync_messages.last.tap do |log|
- if log.criticity = log.criticity
tr
- td = l(log.created_at, format: :short)
- td
+ td style='width: 150px'
+ = l(log.created_at, format: :short_with_time)
+ td.text-center
.fa.fa-circle class="text-#{criticity_class(log.criticity)}"
td
- data = log.message_attributs.symbolize_keys!
diff --git a/app/views/referentials/show.html.slim b/app/views/referentials/show.html.slim
index 45fffe6a1..befa851ab 100644
--- a/app/views/referentials/show.html.slim
+++ b/app/views/referentials/show.html.slim
@@ -50,8 +50,8 @@
{ 'ID Codif' => Proc.new { |n| n.objectid.local_id },
:number => 'number',
:name => 'name',
- :deactivated => Proc.new{|n| n.deactivated? ? t('false') : t('true')},
- :transport_mode => 'transport_mode',
+ :deactivated => Proc.new{ |n| n.deactivated? ? t('false') : t('true') },
+ :transport_mode => Proc.new{ |n| n.transport_mode ? t("enumerize.line.transport_mode.#{n.transport_mode}") : '' },
'networks.name' => Proc.new { |n| n.try(:network).try(:name) },
'companies.name' => Proc.new { |n| n.try(:company).try(:name) } },
[:show],
diff --git a/app/views/stop_area_referentials/show.html.slim b/app/views/stop_area_referentials/show.html.slim
index 24428eea4..56ecbf6da 100644
--- a/app/views/stop_area_referentials/show.html.slim
+++ b/app/views/stop_area_referentials/show.html.slim
@@ -32,8 +32,9 @@
- sync.stop_area_referential_sync_messages.last.tap do |log|
- if log.criticity = log.criticity
tr
- td = l(log.created_at, format: :short)
- td
+ td style='width:150px'
+ = l(log.created_at, format: :short_with_time)
+ td.text-center
.fa.fa-circle class="text-#{criticity_class(log.criticity)}"
td
- data = log.message_attributs.symbolize_keys!
diff --git a/app/views/time_tables/index.html.slim b/app/views/time_tables/index.html.slim
index 01b65653c..c17f96c85 100644
--- a/app/views/time_tables/index.html.slim
+++ b/app/views/time_tables/index.html.slim
@@ -15,7 +15,7 @@
.row
.col-lg-12
= table_builder @time_tables,
- { :color => Proc.new{|tt| tt.color ? content_tag(:span, '', class: 'fa fa-circle', style: "color:#{tt.color}") : '-' }, :comment => 'comment',
+ { 'OiD' => Proc.new { |n| n.objectid.local_id }, :color => Proc.new{|tt| tt.color ? content_tag(:span, '', class: 'fa fa-circle', style: "color:#{tt.color}") : '-' }, :comment => 'comment',
"Période englobante" => Proc.new{ |tt| tt.bounding_dates.empty? ? '-' : t('bounding_dates', debut: l(tt.bounding_dates.min), end: l(tt.bounding_dates.max)) },
"Nombre de courses associées" => Proc.new{ |tt| tt.vehicle_journeys.count },
"Journées d'application" => Proc.new{ |tt| (%w(monday tuesday wednesday thursday friday saturday sunday).collect{|d| tt.send(d) ? t("calendars.days.#{d}") : '' }).reject{|a| a.empty?}.join(', ').html_safe },
diff --git a/config/application.rb b/config/application.rb
index 8606a3156..6c8de781d 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -25,7 +25,7 @@ module ChouetteIhm
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
- config.i18n.default_locale = :fr
+ config.i18n.default_locale = ENV.fetch('RAILS_LOCALE', 'fr').to_sym
# Configure Browserify to use babelify to compile ES6
config.browserify_rails.commandline_options = "-t [ babelify --presets [ react es2015 ] ]"
diff --git a/config/locales/en.yml b/config/locales/en.yml
index 5ed0b9ec5..3f6a68f8d 100644
--- a/config/locales/en.yml
+++ b/config/locales/en.yml
@@ -8,10 +8,12 @@ en:
hour: "%Hh%M"
minute: "%M min"
short: "%Y/%m/%d"
+ short_with_time: "%Y/%m/%d at %Hh%M"
date:
formats:
short: "%Y/%m/%d"
+ short_with_time: "%Y/%m/%d at %Hh%M"
last_update: 'Last update on<br>%{time}'
last_sync: 'Last sync on %{time}'
diff --git a/config/locales/fr.yml b/config/locales/fr.yml
index db8a3608d..49d1c5bb7 100644
--- a/config/locales/fr.yml
+++ b/config/locales/fr.yml
@@ -8,10 +8,12 @@ fr:
hour: "%Hh%M"
minute: "%M min"
short: "%d/%m/%Y"
+ short_with_time: "%d/%m/%Y à %Hh%M"
date:
formats:
short: "%d/%m/%Y"
+ short_with_time: "%d/%m/%Y à %Hh%M"
last_update: 'Dernière mise à jour<br>le %{time}'
last_sync: 'Dernière mise à jour le %{time}'
diff --git a/config/locales/line_referentials.en.yml b/config/locales/line_referentials.en.yml
index 7d84a24f8..78083912d 100644
--- a/config/locales/line_referentials.en.yml
+++ b/config/locales/line_referentials.en.yml
@@ -8,6 +8,9 @@ en:
title: "Edit %{line_referential} referential"
show:
title: "iLICO synchronization"
+ synchronized: Synchronized
+ status: Status
+ message: Message
activerecord:
models:
line_referential:
diff --git a/config/locales/line_referentials.fr.yml b/config/locales/line_referentials.fr.yml
index fe8496d99..c8dfbd640 100644
--- a/config/locales/line_referentials.fr.yml
+++ b/config/locales/line_referentials.fr.yml
@@ -8,6 +8,9 @@ fr:
title: "Editer le référentiel %{line_referential}"
show:
title: 'Synchronisation iLICO'
+ synchronized: Synchronisé
+ status: Statut
+ message: Message
activerecord:
models:
line_referential:
diff --git a/db/schema.rb b/db/schema.rb
index 17df3c34f..a45181687 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -283,7 +283,7 @@ ActiveRecord::Schema.define(version: 20170502130327) do
t.datetime "started_at"
t.datetime "ended_at"
t.string "token_download"
- t.string "type", limit: 255
+ t.string "type"
end
add_index "imports", ["referential_id"], name: "index_imports_on_referential_id", using: :btree
@@ -601,7 +601,7 @@ ActiveRecord::Schema.define(version: 20170502130327) 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"
@@ -610,8 +610,8 @@ ActiveRecord::Schema.define(version: 20170502130327) 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"
@@ -629,7 +629,7 @@ ActiveRecord::Schema.define(version: 20170502130327) 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
@@ -696,18 +696,18 @@ ActiveRecord::Schema.define(version: 20170502130327) 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"
end
diff --git a/lib/stif/codif_line_synchronization.rb b/lib/stif/codif_line_synchronization.rb
index feb313f45..2bb4d8778 100644
--- a/lib/stif/codif_line_synchronization.rb
+++ b/lib/stif/codif_line_synchronization.rb
@@ -11,18 +11,18 @@ module Stif
def processed_counts
{
- imported: self.imported_count,
- updated: self.updated_count,
- deleted: self.deleted_count
+ imported: imported_count,
+ updated: updated_count,
+ deleted: deleted_count
}
end
def increment_counts prop_name, value
- self.send("#{prop_name}=", self.send(prop_name) + value)
+ send("#{prop_name}=", self.send(prop_name) + value)
end
def synchronize
- self.reset_counts
+ reset_counts
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC, :second)
# Fetch Codifline data
client = Codifligne::API.new
diff --git a/lib/stif/reflex_synchronization.rb b/lib/stif/reflex_synchronization.rb
index 6d8497bce..675486265 100644
--- a/lib/stif/reflex_synchronization.rb
+++ b/lib/stif/reflex_synchronization.rb
@@ -35,7 +35,7 @@ module Stif
end
def synchronize
- self.reset_counts
+ reset_counts
['getOR', 'getOP'].each do |method|
start = Time.now
results = Reflex::API.new().process(method)
diff --git a/spec/factories/chouette_routes.rb b/spec/factories/chouette_routes.rb
index e872d24f5..c1a9423c5 100644
--- a/spec/factories/chouette_routes.rb
+++ b/spec/factories/chouette_routes.rb
@@ -20,7 +20,18 @@ FactoryGirl.define do
create_list(:stop_point, evaluator.stop_points_count, route: route)
end
+ factory :route_with_journey_patterns do
+ transient do
+ journey_patterns_count 2
+ end
+
+ after(:create) do |route, evaluator|
+ create_list(:journey_pattern, evaluator.journey_patterns_count, route: route)
+ end
+
+ end
end
+
end
end
diff --git a/spec/factories/chouette_vehicle_journey.rb b/spec/factories/chouette_vehicle_journey.rb
index b7c5e37d5..9ba660800 100644
--- a/spec/factories/chouette_vehicle_journey.rb
+++ b/spec/factories/chouette_vehicle_journey.rb
@@ -3,29 +3,31 @@ FactoryGirl.define do
factory :vehicle_journey_common, :class => Chouette::VehicleJourney do
sequence(:objectid) { |n| "test:VehicleJourney:#{n}" }
- factory :vehicle_journey do
+ factory :vehicle_journey_empty do
association :journey_pattern, :factory => :journey_pattern
after(:build) do |vehicle_journey|
vehicle_journey.route = vehicle_journey.journey_pattern.route
end
- after(:create) do |vehicle_journey|
- vehicle_journey.journey_pattern.stop_points.each_with_index do |stop_point, index|
- vehicle_journey.vehicle_journey_at_stops << create(:vehicle_journey_at_stop,
- :vehicle_journey => vehicle_journey,
- :stop_point => stop_point,
- :arrival_time => '2000-01-01 01:00:00 UTC',
- :departure_time => '2000-01-01 03:00:00 UTC')
+ factory :vehicle_journey do
+ after(:create) do |vehicle_journey|
+ vehicle_journey.journey_pattern.stop_points.each_with_index do |stop_point, index|
+ vehicle_journey.vehicle_journey_at_stops << create(:vehicle_journey_at_stop,
+ :vehicle_journey => vehicle_journey,
+ :stop_point => stop_point,
+ :arrival_time => '2000-01-01 01:00:00 UTC',
+ :departure_time => '2000-01-01 03:00:00 UTC')
+ end
end
- end
- factory :vehicle_journey_odd do
- association :journey_pattern, :factory => :journey_pattern_odd
- end
+ factory :vehicle_journey_odd do
+ association :journey_pattern, :factory => :journey_pattern_odd
+ end
- factory :vehicle_journey_even do
- association :journey_pattern, :factory => :journey_pattern_even
+ factory :vehicle_journey_even do
+ association :journey_pattern, :factory => :journey_pattern_even
+ end
end
end
end
diff --git a/spec/javascripts/time_table/actions_spec.js b/spec/javascripts/time_table/actions_spec.js
index eac2f86bb..1ab5635a0 100644
--- a/spec/javascripts/time_table/actions_spec.js
+++ b/spec/javascripts/time_table/actions_spec.js
@@ -1,5 +1,16 @@
var actions = require('es6_browserified/time_tables/actions')
-
+const dispatch = function(){}
+const dayTypes = [true, true, true, true, true, true, true]
+const day = {
+ date : "2017-05-01",
+ day : "lundi",
+ excluded_date : false,
+ in_periods : true,
+ include_date : false,
+ mday : 1,
+ wday : 1,
+ wnumber : "18"
+}
describe('actions', () => {
it('should create an action to update dayTypes', () => {
const expectedAction = {
@@ -48,4 +59,146 @@ describe('actions', () => {
}
expect(actions.unselect2Tags(selectedItem)).toEqual(expectedAction)
})
+
+ it('should create an action to go to previous page', () => {
+ let pagination = {
+ currentPage: '2017-01-01',
+ periode_range: [],
+ stateChanged: false
+ }
+ const expectedAction = {
+ type: 'GO_TO_PREVIOUS_PAGE',
+ dispatch,
+ pagination,
+ nextPage: false
+ }
+ expect(actions.goToPreviousPage(dispatch, pagination)).toEqual(expectedAction)
+ })
+
+ it('should create an action to go to next page', () => {
+ let pagination = {
+ currentPage: '2017-01-01',
+ periode_range: [],
+ stateChanged: false
+ }
+ const expectedAction = {
+ type: 'GO_TO_NEXT_PAGE',
+ dispatch,
+ pagination,
+ nextPage: true
+ }
+ expect(actions.goToNextPage(dispatch, pagination)).toEqual(expectedAction)
+ })
+
+ it('should create an action to change page', () => {
+ let page = '2017-05-04'
+ const expectedAction = {
+ type: 'CHANGE_PAGE',
+ dispatch,
+ page: page
+ }
+ expect(actions.changePage(dispatch, page)).toEqual(expectedAction)
+ })
+
+ it('should create an action to delete period', () => {
+ let index = 1
+ const expectedAction = {
+ type: 'DELETE_PERIOD',
+ index,
+ dayTypes
+ }
+ expect(actions.deletePeriod(index, dayTypes)).toEqual(expectedAction)
+ })
+
+ it('should create an action to open add period form', () => {
+ const expectedAction = {
+ type: 'OPEN_ADD_PERIOD_FORM',
+ }
+ expect(actions.openAddPeriodForm()).toEqual(expectedAction)
+ })
+
+ it('should create an action to open edit period form', () => {
+ let period = {
+ id : 1,
+ period_end : "2017-03-05",
+ period_start : "2017-02-23"
+ }
+ let index = 1
+ const expectedAction = {
+ type: 'OPEN_EDIT_PERIOD_FORM',
+ period,
+ index
+ }
+ expect(actions.openEditPeriodForm(period, index)).toEqual(expectedAction)
+ })
+
+ it('should create an action to close period form', () => {
+ const expectedAction = {
+ type: 'CLOSE_PERIOD_FORM',
+ }
+ expect(actions.closePeriodForm()).toEqual(expectedAction)
+ })
+
+ it('should create an action to update period form', () => {
+ let val = "11"
+ let group = "start"
+ let selectType = "day"
+ const expectedAction = {
+ type: 'UPDATE_PERIOD_FORM',
+ val,
+ group,
+ selectType
+ }
+ expect(actions.updatePeriodForm(val, group, selectType)).toEqual(expectedAction)
+ })
+
+ it('should create an action to validate period form', () => {
+ let modalProps = {}
+ let timeTablePeriods = []
+ let metas = {}
+ const expectedAction = {
+ type: 'VALIDATE_PERIOD_FORM',
+ modalProps,
+ timeTablePeriods,
+ metas
+ }
+ expect(actions.validatePeriodForm(modalProps, timeTablePeriods, metas)).toEqual(expectedAction)
+ })
+
+ it('should create an action to include date in period', () => {
+ let index = 1
+ const expectedAction = {
+ type: 'INCLUDE_DATE_IN_PERIOD',
+ index,
+ dayTypes
+ }
+ expect(actions.includeDateInPeriod(index, dayTypes)).toEqual(expectedAction)
+ })
+
+ it('should create an action to exclude date from period', () => {
+ let index = 1
+ const expectedAction = {
+ type: 'EXCLUDE_DATE_FROM_PERIOD',
+ index,
+ dayTypes
+ }
+ expect(actions.excludeDateFromPeriod(index, dayTypes)).toEqual(expectedAction)
+ })
+
+ it('should create an action to open confirm modal', () => {
+ let callback = function(){}
+ const expectedAction = {
+ type: 'OPEN_CONFIRM_MODAL',
+ callback
+ }
+ expect(actions.openConfirmModal(callback)).toEqual(expectedAction)
+ })
+
+ it('should create an action to close modal', () => {
+ const expectedAction = {
+ type: 'CLOSE_MODAL',
+ }
+ expect(actions.closeModal()).toEqual(expectedAction)
+ })
+
})
diff --git a/spec/javascripts/time_table/reducers/metas_spec.js b/spec/javascripts/time_table/reducers/metas_spec.js
index adc6a9d05..61e3048db 100644
--- a/spec/javascripts/time_table/reducers/metas_spec.js
+++ b/spec/javascripts/time_table/reducers/metas_spec.js
@@ -2,7 +2,7 @@ var metasReducer = require('es6_browserified/time_tables/reducers/metas')
let state = {}
-describe('status reducer', () => {
+describe('metas reducer', () => {
beforeEach(() => {
let tag = {
id: 0,
diff --git a/spec/javascripts/time_table/reducers/modal_spec.js b/spec/javascripts/time_table/reducers/modal_spec.js
new file mode 100644
index 000000000..4246027b8
--- /dev/null
+++ b/spec/javascripts/time_table/reducers/modal_spec.js
@@ -0,0 +1,249 @@
+var modalReducer = require('es6_browserified/time_tables/reducers/modal')
+
+let state = {}
+
+describe('modal reducer', () => {
+ beforeEach(() => {
+ state = {
+ confirmModal: {},
+ modalProps: {
+ active: false,
+ begin: {
+ day: '01',
+ month: '01',
+ year: String(new Date().getFullYear())
+ },
+ end: {
+ day: '01',
+ month: '01',
+ year: String(new Date().getFullYear())
+ },
+ index: false,
+ error: ''
+ },
+ type: ""
+ }
+ })
+
+ it('should return the initial state', () => {
+ expect(
+ modalReducer(undefined, {})
+ ).toEqual({})
+ })
+
+ it('should handle OPEN_CONFIRM_MODAL', () => {
+ let callback = function(){}
+ expect(
+ modalReducer(state, {
+ type: 'OPEN_CONFIRM_MODAL',
+ callback
+ })
+ ).toEqual(Object.assign({}, state, {type: "confirm", confirmModal: { callback: callback }}))
+ })
+
+ it('should handle CLOSE_PERIOD_FORM', () => {
+ let newModalProps = Object.assign({}, state.modalProps, {active: false})
+ expect(
+ modalReducer(state, {
+ type: 'CLOSE_PERIOD_FORM'
+ })
+ ).toEqual(Object.assign({}, state, {modalProps: newModalProps}))
+ })
+
+ it('should handle OPEN_EDIT_PERIOD_FORM', () => {
+ let period = {
+ id : 1,
+ period_end : "2017-03-05",
+ period_start : "2017-02-23"
+ }
+ let period_start = period.period_start.split('-')
+ let period_end = period.period_end.split('-')
+
+ let index = 1
+
+ let newModalProps = {
+ active: true,
+ begin: {
+ day: period_start[2],
+ month: period_start[1],
+ year: period_start[0]
+ },
+ end: {
+ day: period_end[2],
+ month: period_end[1],
+ year: period_end[0]
+ },
+ index: index,
+ error: ''
+ }
+ expect(
+ modalReducer(state, {
+ type: 'OPEN_EDIT_PERIOD_FORM',
+ period,
+ index
+ })
+ ).toEqual(Object.assign({}, state, {modalProps: newModalProps}))
+ })
+
+ it('should handle OPEN_ADD_PERIOD_FORM', () => {
+ let emptyDate = {
+ day: '01',
+ month: '01',
+ year: String(new Date().getFullYear())
+ }
+ let newModalProps = Object.assign({}, state.modalProps, {
+ active: true,
+ begin: emptyDate,
+ end: emptyDate,
+ index: false,
+ error: ""
+ })
+
+ expect(
+ modalReducer(state, {
+ type: 'OPEN_ADD_PERIOD_FORM'
+ })
+ ).toEqual(Object.assign({}, state, {modalProps: newModalProps}))
+ })
+
+ it('should handle UPDATE_PERIOD_FORM', () => {
+ let val = "11"
+ let group = "begin"
+ let selectType = "day"
+
+ let newModalProps = {
+ active: false,
+ begin: {
+ day: val,
+ month: '01',
+ year: String(new Date().getFullYear())
+ },
+ end: {
+ day: '01',
+ month: '01',
+ year: String(new Date().getFullYear())
+ },
+ index: false,
+ error: ''
+ }
+
+ expect(
+ modalReducer(state, {
+ type: 'UPDATE_PERIOD_FORM',
+ val,
+ group,
+ selectType
+ })
+ ).toEqual(Object.assign({}, state, {modalProps: newModalProps}))
+ })
+
+ it('should handle VALIDATE_PERIOD_FORM and throw error if period starts after the end', () => {
+ let modProps = {
+ active: false,
+ begin: {
+ day: '13',
+ month: '01',
+ year: String(new Date().getFullYear())
+ },
+ end: {
+ day: '01',
+ month: '01',
+ year: String(new Date().getFullYear())
+ },
+ index: false,
+ error: ''
+ }
+ let newModalProps = {
+ active: false,
+ begin: {
+ day: '01',
+ month: '01',
+ year: String(new Date().getFullYear())
+ },
+ end: {
+ day: '01',
+ month: '01',
+ year: String(new Date().getFullYear())
+ },
+ index: false,
+ error: 'La date de départ doit être antérieure à la date de fin'
+ }
+
+ let ttperiods = []
+
+ expect(
+ modalReducer(state, {
+ type: 'VALIDATE_PERIOD_FORM',
+ modalProps : modProps,
+ timeTablePeriods: ttperiods
+ })
+ ).toEqual(Object.assign({}, state, {modalProps: newModalProps}))
+ })
+
+ it('should handle VALIDATE_PERIOD_FORM and throw error if periods overlap', () => {
+ let state2 = {
+ confirmModal: {},
+ modalProps: {
+ active: false,
+ begin: {
+ day: '03',
+ month: '05',
+ year: '2017'
+ },
+ end: {
+ day: '09',
+ month: '05',
+ year: '2017'
+ },
+ index: false,
+ error: ''
+ },
+ type: ''
+ }
+ let modProps2 = {
+ active: false,
+ begin: {
+ day: '03',
+ month: '05',
+ year: '2017'
+ },
+ end: {
+ day: '09',
+ month: '05',
+ year: '2017'
+ },
+ index: false,
+ error: ''
+ }
+ let ttperiods2 = [
+ {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: 264, period_start: '2017-04-24', period_end: '2017-05-04'},
+ {id: 265, period_start: '2017-05-14', period_end: '2017-05-24'}
+ ]
+
+ let newModalProps2 = {
+ active: true,
+ begin: {
+ day: '03',
+ month: '05',
+ year: '2017'
+ },
+ end: {
+ day: '09',
+ month: '05',
+ year: '2017'
+ },
+ index: false,
+ error: "Les périodes ne peuvent pas se chevaucher"
+ }
+
+ expect(
+ modalReducer(state2, {
+ type: 'VALIDATE_PERIOD_FORM',
+ modalProps : modProps2,
+ timeTablePeriods: ttperiods2
+ })
+ ).toEqual(Object.assign({}, state2, {modalProps: newModalProps2}))
+ })
+})
diff --git a/spec/javascripts/time_table/reducers/pagination_spec.js b/spec/javascripts/time_table/reducers/pagination_spec.js
new file mode 100644
index 000000000..740ded3ac
--- /dev/null
+++ b/spec/javascripts/time_table/reducers/pagination_spec.js
@@ -0,0 +1,128 @@
+var paginationReducer = require('es6_browserified/time_tables/reducers/pagination')
+
+const dispatch = function(){}
+
+let pagination = {
+ currentPage: "1982-02-15",
+ periode_range: ["1982-02-01", "1982-02-02", "1982-02-03"],
+ stateChanged: false
+}
+
+let state = {}
+
+describe('pagination reducer', () => {
+ beforeEach(() => {
+ state = {
+ currentPage: "",
+ periode_range: [],
+ stateChanged: false
+ }
+ })
+
+ it('should return the initial state', () => {
+ expect(
+ paginationReducer(undefined, {})
+ ).toEqual({})
+ })
+
+ it('should handle RECEIVE_TIME_TABLES', () => {
+ let json = [{
+ current_periode_range: "1982-02-15",
+ periode_range: ["1982-02-01", "1982-02-02", "1982-02-03"]
+ }]
+ expect(
+ paginationReducer(state, {
+ type: 'RECEIVE_TIME_TABLES',
+ json
+ })
+ ).toEqual(Object.assign({}, state, {currentPage: json.current_periode_range, periode_range: json.periode_range}))
+ })
+
+ it('should handle GO_TO_PREVIOUS_PAGE', () => {
+ let nextPage = nextPage ? 1 : -1
+ let newPage = pagination.periode_range[pagination.periode_range.indexOf(pagination.currentPage) + nextPage]
+
+ expect(
+ paginationReducer(state, {
+ type: 'GO_TO_PREVIOUS_PAGE',
+ dispatch,
+ pagination,
+ nextPage: false
+ })
+ ).toEqual(Object.assign({}, state, {currentPage : newPage, stateChanged: false}))
+ })
+ it('should handle GO_TO_NEXT_PAGE', () => {
+ let nextPage = nextPage ? 1 : -1
+ let newPage = pagination.periode_range[pagination.periode_range.indexOf(pagination.currentPage) + nextPage]
+
+ expect(
+ paginationReducer(state, {
+ type: 'GO_TO_NEXT_PAGE',
+ dispatch,
+ pagination,
+ nextPage: false
+ })
+ ).toEqual(Object.assign({}, state, {currentPage : newPage, stateChanged: false}))
+ })
+
+ it('should handle CHANGE_PAGE', () => {
+ let page = "1982-02-15"
+ expect(
+ paginationReducer(state, {
+ type: 'CHANGE_PAGE',
+ dispatch,
+ page
+ })
+ ).toEqual(Object.assign({}, state, {currentPage : page, stateChanged: false}))
+ })
+
+ it('should handle INCLUDE_DATE_IN_PERIOD', () => {
+ expect(
+ paginationReducer(state, {
+ type: 'INCLUDE_DATE_IN_PERIOD'
+ })
+ ).toEqual(Object.assign({}, state, {stateChanged: true}))
+ })
+ it('should handle EXCLUDE_DATE_FROM_PERIOD', () => {
+ expect(
+ paginationReducer(state, {
+ type: 'EXCLUDE_DATE_FROM_PERIOD'
+ })
+ ).toEqual(Object.assign({}, state, {stateChanged: true}))
+ })
+ it('should handle DELETE_PERIOD', () => {
+ expect(
+ paginationReducer(state, {
+ type: 'DELETE_PERIOD'
+ })
+ ).toEqual(Object.assign({}, state, {stateChanged: true}))
+ })
+ it('should handle VALIDATE_PERIOD_FORM', () => {
+ expect(
+ paginationReducer(state, {
+ type: 'VALIDATE_PERIOD_FORM'
+ })
+ ).toEqual(Object.assign({}, state, {stateChanged: true}))
+ })
+ it('should handle UPDATE_COMMENT', () => {
+ expect(
+ paginationReducer(state, {
+ type: 'UPDATE_COMMENT'
+ })
+ ).toEqual(Object.assign({}, state, {stateChanged: true}))
+ })
+ it('should handle UPDATE_COLOR', () => {
+ expect(
+ paginationReducer(state, {
+ type: 'UPDATE_COLOR'
+ })
+ ).toEqual(Object.assign({}, state, {stateChanged: true}))
+ })
+ it('should handle UPDATE_DAY_TYPES', () => {
+ expect(
+ paginationReducer(state, {
+ type: 'UPDATE_DAY_TYPES'
+ })
+ ).toEqual(Object.assign({}, state, {stateChanged: true}))
+ })
+})
diff --git a/spec/javascripts/time_table/reducers/status_spec.js b/spec/javascripts/time_table/reducers/status_spec.js
new file mode 100644
index 000000000..f000324cc
--- /dev/null
+++ b/spec/javascripts/time_table/reducers/status_spec.js
@@ -0,0 +1,50 @@
+var statusReducer = require('es6_browserified/time_tables/reducers/status')
+
+let state = {}
+
+describe('status reducer', () => {
+ beforeEach(() => {
+ state = {
+ actionType: "edit",
+ fetchSuccess: true,
+ isFetching: false
+ }
+ })
+
+ it('should return the initial state', () => {
+ expect(
+ statusReducer(undefined, {})
+ ).toEqual({})
+ })
+
+ it('should handle UNAVAILABLE_SERVER', () => {
+ expect(
+ statusReducer(state, {
+ type: 'UNAVAILABLE_SERVER'
+ })
+ ).toEqual(Object.assign({}, state, {fetchSuccess: false}))
+ })
+
+ it('should handle FETCH_API', () => {
+ expect(
+ statusReducer(state, {
+ type: 'FETCH_API'
+ })
+ ).toEqual(Object.assign({}, state, {isFetching: true}))
+ })
+
+ it('should handle RECEIVE_TIME_TABLES', () => {
+ expect(
+ statusReducer(state, {
+ type: 'RECEIVE_TIME_TABLES'
+ })
+ ).toEqual(Object.assign({}, state, {fetchSuccess: true, isFetching: false}))
+ })
+ it('should handle RECEIVE_MONTH', () => {
+ expect(
+ statusReducer(state, {
+ type: 'RECEIVE_MONTH'
+ })
+ ).toEqual(Object.assign({}, state, {fetchSuccess: true, isFetching: false}))
+ })
+})
diff --git a/spec/javascripts/time_table/reducers/timetable_spec.js b/spec/javascripts/time_table/reducers/timetable_spec.js
new file mode 100644
index 000000000..0b418a52e
--- /dev/null
+++ b/spec/javascripts/time_table/reducers/timetable_spec.js
@@ -0,0 +1,184 @@
+require('whatwg-fetch')
+var timetableReducer = require('es6_browserified/time_tables/reducers/timetable')
+
+let state = {}
+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 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 json = {
+ current_month: current_month,
+ current_periode_range: current_periode_range,
+ periode_range: periode_range,
+ time_table_periods: time_table_periods,
+ day_types: strDayTypes
+}
+
+describe('timetable reducer with empty state', () => {
+ beforeEach(() => {
+ state = {
+ current_month: [],
+ current_periode_range: "",
+ periode_range: [],
+ time_table_periods: []
+ }
+ })
+
+ it('should return the initial state', () => {
+ expect(
+ timetableReducer(undefined, {})
+ ).toEqual({})
+ })
+
+ it('should handle RECEIVE_TIME_TABLES', () => {
+ let newState = {
+ current_month: newCurrentMonth,
+ current_periode_range: current_periode_range,
+ periode_range: periode_range,
+ time_table_periods: time_table_periods,
+ }
+ expect(
+ timetableReducer(state, {
+ type: 'RECEIVE_TIME_TABLES',
+ json
+ })
+ ).toEqual(newState)
+ })
+})
+
+describe('timetable reducer with filled state', () => {
+ beforeEach(() => {
+ state = {
+ current_month: newCurrentMonth,
+ current_periode_range: current_periode_range,
+ periode_range: periode_range,
+ time_table_periods: time_table_periods,
+ }
+ })
+
+ it('should handle RECEIVE_MONTH', () => {
+ expect(
+ timetableReducer(state, {
+ type: 'RECEIVE_MONTH',
+ json: {
+ days: current_month,
+ day_types: strDayTypes
+ }
+ })
+ ).toEqual(state)
+ })
+
+
+ it('should handle GO_TO_PREVIOUS_PAGE', () => {
+ let pagination = {
+ periode_range: periode_range,
+ currentPage: current_periode_range
+ }
+ expect(
+ timetableReducer(state, {
+ type: 'GO_TO_PREVIOUS_PAGE',
+ dispatch,
+ pagination,
+ nextPage: false
+ })
+ ).toEqual(Object.assign({}, state, {current_periode_range: '2017-04-01'}))
+ })
+
+ it('should handle GO_TO_NEXT_PAGE', () => {
+ let pagination = {
+ periode_range: periode_range,
+ currentPage: current_periode_range
+ }
+ expect(
+ timetableReducer(state, {
+ type: 'GO_TO_NEXT_PAGE',
+ dispatch,
+ pagination,
+ nextPage: true
+ })
+ ).toEqual(Object.assign({}, state, {current_periode_range: '2017-06-01'}))
+ })
+
+ it('should handle CHANGE_PAGE', () => {
+ const actions = {
+ fetchTimeTables: function(){}
+ }
+ let newPage = '2017-05-01'
+ expect(
+ timetableReducer(state, {
+ type: 'CHANGE_PAGE',
+ dispatch,
+ page: newPage
+ })
+ ).toEqual(Object.assign({}, state, {current_periode_range: newPage}))
+ })
+
+ it('should handle DELETE_PERIOD', () => {
+ state.time_table_periods[0].deleted = true
+ expect(
+ timetableReducer(state, {
+ type: 'DELETE_PERIOD',
+ index: 0,
+ dayTypes: arrDayTypes
+ })
+ ).toEqual(state)
+ })
+
+ it('should handle INCLUDE_DATE_IN_PERIOD', () => {
+ state.current_month[4].include_date = true
+ expect(
+ timetableReducer(state, {
+ type: 'INCLUDE_DATE_IN_PERIOD',
+ index: 4,
+ dayTypes: arrDayTypes
+ })
+ ).toEqual(state)
+ })
+
+ it('should handle EXCLUDE_DATE_FROM_PERIOD', () => {
+ state.current_month[0].excluded_date = true
+ expect(
+ timetableReducer(state, {
+ type: 'EXCLUDE_DATE_FROM_PERIOD',
+ index: 0,
+ dayTypes: arrDayTypes
+ })
+ ).toEqual(state)
+ })
+
+ it('should handle VALIDATE_PERIOD_FORM', () => {
+ state.current_month[13].in_periods = false
+ state.time_table_periods[4].period_start = '2017-05-15'
+ let modalProps = {
+ active: false,
+ begin: {
+ day: '15',
+ month: '05',
+ year: '2017'
+ },
+ end: {
+ day: '24',
+ month: '05',
+ year: '2017'
+ },
+ error: '',
+ index: 4
+ }
+ expect(
+ timetableReducer(state, {
+ type: 'VALIDATE_PERIOD_FORM',
+ modalProps: modalProps,
+ timeTablePeriods: state.time_table_periods,
+ metas: {
+ day_types: arrDayTypes
+ }
+ })
+ ).toEqual(state)
+ })
+})
diff --git a/spec/models/chouette/route/route_base_spec.rb b/spec/models/chouette/route/route_base_spec.rb
new file mode 100644
index 000000000..08f201022
--- /dev/null
+++ b/spec/models/chouette/route/route_base_spec.rb
@@ -0,0 +1,69 @@
+RSpec.describe Chouette::Route, :type => :model do
+
+ subject { create(:route) }
+
+ describe '#objectid' do
+ subject { super().objectid }
+ it { is_expected.to be_kind_of(Chouette::ObjectId) }
+ end
+
+ it { is_expected.to enumerize(:direction).in(:straight_forward, :backward, :clockwise, :counter_clockwise, :north, :north_west, :west, :south_west, :south, :south_east, :east, :north_east) }
+ it { is_expected.to enumerize(:wayback).in(:straight_forward, :backward) }
+
+ #it { is_expected.to validate_presence_of :name }
+ it { is_expected.to validate_presence_of :line }
+ it { is_expected.to validate_uniqueness_of :objectid }
+ #it { is_expected.to validate_presence_of :wayback_code }
+ #it { is_expected.to validate_presence_of :direction_code }
+ it { is_expected.to validate_inclusion_of(:direction).in_array(%i(straight_forward backward clockwise counter_clockwise north north_west west south_west south south_east east north_east)) }
+ it { is_expected.to validate_inclusion_of(:wayback).in_array(%i(straight_forward backward)) }
+
+ context "reordering methods" do
+ let(:bad_stop_point_ids){subject.stop_points.map { |sp| sp.id + 1}}
+ let(:ident){subject.stop_points.map(&:id)}
+ let(:first_last_swap){ [ident.last] + ident[1..-2] + [ident.first]}
+
+ describe "#reorder!" do
+ context "invalid stop_point_ids" do
+ let(:new_stop_point_ids) { bad_stop_point_ids}
+ it { expect(subject.reorder!( new_stop_point_ids)).to be_falsey}
+ end
+
+ context "swaped last and first stop_point_ids" do
+ let!(:new_stop_point_ids) { first_last_swap}
+ let!(:old_stop_point_ids) { subject.stop_points.map(&:id) }
+ let!(:old_stop_area_ids) { subject.stop_areas.map(&:id) }
+
+ it "should keep stop_point_ids order unchanged" do
+ expect(subject.reorder!( new_stop_point_ids)).to be_truthy
+ expect(subject.stop_points.map(&:id)).to eq( old_stop_point_ids)
+ end
+ # This test is no longer relevant, as reordering is done with Reactux
+ # it "should have changed stop_area_ids order" do
+ # expect(subject.reorder!( new_stop_point_ids)).to be_truthy
+ # subject.reload
+ # expect(subject.stop_areas.map(&:id)).to eq( [old_stop_area_ids.last] + old_stop_area_ids[1..-2] + [old_stop_area_ids.first])
+ # end
+ end
+ end
+
+ describe "#stop_point_permutation?" do
+ context "invalid stop_point_ids" do
+ let( :new_stop_point_ids ) { bad_stop_point_ids}
+ it { is_expected.not_to be_stop_point_permutation( new_stop_point_ids)}
+ end
+ context "unchanged stop_point_ids" do
+ let(:new_stop_point_ids) { ident}
+ it { is_expected.to be_stop_point_permutation( new_stop_point_ids)}
+ end
+ context "swaped last and first stop_point_ids" do
+ let(:new_stop_point_ids) { first_last_swap}
+ it { is_expected.to be_stop_point_permutation( new_stop_point_ids)}
+ end
+ end
+ end
+
+end
+
+
+
diff --git a/spec/models/chouette/route/route_destroy_spec.rb b/spec/models/chouette/route/route_destroy_spec.rb
new file mode 100644
index 000000000..930ce521a
--- /dev/null
+++ b/spec/models/chouette/route/route_destroy_spec.rb
@@ -0,0 +1,45 @@
+RSpec.describe Chouette::Route, :type => :model do
+
+ subject { create( :route_with_journey_patterns ) }
+
+
+ context "delete a route" do
+ let( :vehicle_journey ){ create :vehicle_journey }
+
+ it "deletes the associated journey_patterns" do
+ expected_delta = subject.journey_patterns.count
+ expect( expected_delta > 0 ).to eq(true)
+ expect{ subject.destroy }.to change{Chouette::JourneyPattern.count}.by -expected_delta
+ end
+
+ it "deletes the associated stop_points" do
+ expected_delta = subject.stop_points.count
+ expect( expected_delta > 0 ).to eq(true)
+ expect{ subject.destroy }.to change{Chouette::StopPoint.count}.by -expected_delta
+ end
+
+ it "does not delete the associated stop_areas" do
+ count = subject.stop_points.count
+ expect( count > 0 ).to eq(true)
+ expect{ subject.destroy }.not_to change{Chouette::StopArea.count}
+ end
+
+ it "deletes the associated vehicle_journeys" do
+ vehicle_journey
+ expect{ vehicle_journey.route.destroy}.to change{Chouette::VehicleJourney.count}.by -1
+ end
+
+ it "does not delete the corresponding time_tables" do
+ tt = create :time_table
+ tt.vehicle_journeys << vehicle_journey
+ tables = vehicle_journey.route.time_tables
+ expect( tables ).not_to be_empty
+ expect{ vehicle_journey.route.destroy }.not_to change{Chouette::TimeTable.count}
+ end
+
+ it "does not delete the associated line" do
+ expect( subject.line ).not_to be_nil
+ expect{ subject.destroy }.not_to change{Chouette::Line.count}
+ end
+ end
+end
diff --git a/spec/models/chouette/route_spec.rb b/spec/models/chouette/route/route_stop_points_spec.rb
index 6138f28b9..03c53b4cf 100644
--- a/spec/models/chouette/route_spec.rb
+++ b/spec/models/chouette/route/route_stop_points_spec.rb
@@ -1,72 +1,10 @@
-require 'spec_helper'
+RSpec.describe Chouette::Route, :type => :model do
-describe Chouette::Route, :type => :model do
subject { create(:route) }
- describe '#objectid' do
- subject { super().objectid }
- it { is_expected.to be_kind_of(Chouette::ObjectId) }
- end
-
- it { is_expected.to enumerize(:direction).in(:straight_forward, :backward, :clockwise, :counter_clockwise, :north, :north_west, :west, :south_west, :south, :south_east, :east, :north_east) }
- it { is_expected.to enumerize(:wayback).in(:straight_forward, :backward) }
-
- #it { is_expected.to validate_presence_of :name }
- it { is_expected.to validate_presence_of :line }
- it { is_expected.to validate_uniqueness_of :objectid }
- #it { is_expected.to validate_presence_of :wayback_code }
- #it { is_expected.to validate_presence_of :direction_code }
- it { is_expected.to validate_inclusion_of(:direction).in_array(%i(straight_forward backward clockwise counter_clockwise north north_west west south_west south south_east east north_east)) }
- it { is_expected.to validate_inclusion_of(:wayback).in_array(%i(straight_forward backward)) }
-
- context "reordering methods" do
- let( :bad_stop_point_ids){subject.stop_points.map { |sp| sp.id + 1}}
- let( :ident){subject.stop_points.map(&:id)}
- let( :first_last_swap){ [ident.last] + ident[1..-2] + [ident.first]}
-
- describe "#reorder!" do
- context "invalid stop_point_ids" do
- let( :new_stop_point_ids) { bad_stop_point_ids}
- it { expect(subject.reorder!( new_stop_point_ids)).to be_falsey}
- end
-
- context "swaped last and first stop_point_ids" do
- let!( :new_stop_point_ids) { first_last_swap}
- let!( :old_stop_point_ids) { subject.stop_points.map(&:id) }
- let!( :old_stop_area_ids) { subject.stop_areas.map(&:id) }
-
- it "should keep stop_point_ids order unchanged" do
- expect(subject.reorder!( new_stop_point_ids)).to be_truthy
- expect(subject.stop_points.map(&:id)).to eq( old_stop_point_ids)
- end
- # This test is no longer relevant, as reordering is done with Reactux
- # it "should have changed stop_area_ids order" do
- # expect(subject.reorder!( new_stop_point_ids)).to be_truthy
- # subject.reload
- # expect(subject.stop_areas.map(&:id)).to eq( [old_stop_area_ids.last] + old_stop_area_ids[1..-2] + [old_stop_area_ids.first])
- # end
- end
- end
-
- describe "#stop_point_permutation?" do
- context "invalid stop_point_ids" do
- let( :new_stop_point_ids) { bad_stop_point_ids}
- it { is_expected.not_to be_stop_point_permutation( new_stop_point_ids)}
- end
- context "unchanged stop_point_ids" do
- let( :new_stop_point_ids) { ident}
- it { is_expected.to be_stop_point_permutation( new_stop_point_ids)}
- end
- context "swaped last and first stop_point_ids" do
- let( :new_stop_point_ids) { first_last_swap}
- it { is_expected.to be_stop_point_permutation( new_stop_point_ids)}
- end
- end
- end
-
describe "#stop_points_attributes=" do
- let( :journey_pattern) { create( :journey_pattern, :route => subject )}
- let( :vehicle_journey) { create( :vehicle_journey, :journey_pattern => journey_pattern)}
+ let(:journey_pattern) { create( :journey_pattern, :route => subject )}
+ let(:vehicle_journey) { create( :vehicle_journey, :journey_pattern => journey_pattern)}
def subject_stop_points_attributes
{}.tap do |hash|
subject.stop_points.each_with_index { |sp,index| hash[ index.to_s ] = sp.attributes }
@@ -171,3 +109,4 @@ describe Chouette::Route, :type => :model do
end
end
end
+
diff --git a/spec/models/chouette/vehicle_journey_spec.rb b/spec/models/chouette/vehicle_journey_spec.rb
index 3d3a948bc..b22183ab6 100644
--- a/spec/models/chouette/vehicle_journey_spec.rb
+++ b/spec/models/chouette/vehicle_journey_spec.rb
@@ -221,6 +221,95 @@ describe Chouette::VehicleJourney, :type => :model do
end
end
+ describe ".with_stops" do
+ def initialize_stop_times(vehicle_journey, &block)
+ vehicle_journey
+ .vehicle_journey_at_stops
+ .each_with_index do |at_stop, index|
+ at_stop.update(
+ departure_time: at_stop.departure_time + block.call(index),
+ arrival_time: at_stop.arrival_time + block.call(index)
+ )
+ end
+ end
+
+ it "selects vehicle journeys including stops in order or earliest departure time" do
+ # Create later vehicle journey to give it a later id, such that it should
+ # appear last if the order in the query isn't right.
+ journey_late = create(:vehicle_journey)
+ journey_early = create(
+ :vehicle_journey,
+ route: journey_late.route,
+ journey_pattern: journey_late.journey_pattern
+ )
+
+ initialize_stop_times(journey_early) do |index|
+ (index + 5).minutes
+ end
+ initialize_stop_times(journey_late) do |index|
+ (index + 65).minutes
+ end
+
+ expected_journey_order = [journey_early, journey_late]
+
+ expect(
+ journey_late
+ .route
+ .vehicle_journeys
+ .with_stops
+ .to_a
+ ).to eq(expected_journey_order)
+ end
+
+ it "orders journeys with nil times at the end" do
+ journey_nil = create(:vehicle_journey_empty)
+ journey = create(
+ :vehicle_journey,
+ route: journey_nil.route,
+ journey_pattern: journey_nil.journey_pattern
+ )
+
+ expected_journey_order = [journey, journey_nil]
+
+ expect(
+ journey
+ .route
+ .vehicle_journeys
+ .with_stops
+ .to_a
+ ).to eq(expected_journey_order)
+ end
+
+ it "journeys that skip the first stop(s) get ordered by the time of the \
+ first stop that they make" do
+ journey_missing_stop = create(:vehicle_journey)
+ journey_early = create(
+ :vehicle_journey,
+ route: journey_missing_stop.route,
+ journey_pattern: journey_missing_stop.journey_pattern
+ )
+
+ initialize_stop_times(journey_early) do |index|
+ (index + 5).minutes
+ end
+ initialize_stop_times(journey_missing_stop) do |index|
+ (index + 65).minutes
+ end
+
+ journey_missing_stop.vehicle_journey_at_stops.first.destroy
+
+ expected_journey_order = [journey_early, journey_missing_stop]
+
+ expect(
+ journey_missing_stop
+ .route
+ .vehicle_journeys
+ .with_stops
+ .to_a
+ ).to eq(expected_journey_order)
+ end
+ end
+
subject { create(:vehicle_journey_odd) }
describe "in_relation_to_a_journey_pattern methods" do
let!(:route) { create(:route)}
diff --git a/spec/models/time_table_combination_spec.rb b/spec/models/time_table_combination_spec.rb
index 46d5f8504..4c99a14fa 100644
--- a/spec/models/time_table_combination_spec.rb
+++ b/spec/models/time_table_combination_spec.rb
@@ -4,7 +4,37 @@ describe TimeTableCombination, :type => :model do
let!(:source){ create(:time_table)}
let!(:combined){create(:time_table)}
subject {build(:time_table_combination)}
-
+
+ describe '#continuous_dates' do
+ it 'should group continuous dates' do
+ dates = source.dates.where(in_out: true)
+ expect(source.continuous_dates[0].count).to eq(dates.count)
+
+ # 6 more continuous date, 1 isolated date
+ (10..15).each do |n|
+ source.dates.create(date: Date.today + n.day, in_out: true)
+ end
+ source.dates.create(date: Date.today + 1.year, in_out: true)
+ expect(source.reload.continuous_dates[1].count).to eq(6)
+ expect(source.reload.continuous_dates[2].count).to eq(1)
+ end
+ end
+
+ describe '#convert_continuous_dates_to_periods' do
+ it 'should convert continuous dates to periods' do
+ (10..12).each do |n|
+ source.dates.create(date: Date.today + n.day, in_out: true)
+ end
+ source.dates.create(date: Date.today + 1.year, in_out: true)
+
+ expect {
+ source.reload.convert_continuous_dates_to_periods
+ }.to change {source.periods.count}.by(2)
+
+ expect(source.reload.dates.where(in_out: true).count).to eq(1)
+ end
+ end
+
describe "#combine" do
context "when operation is union" do
before(:each) do