aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcedricnjanga2018-02-14 06:26:04 -0800
committerGitHub2018-02-14 06:26:04 -0800
commit3916476c64dc690195a1273dab7188bb48f69152 (patch)
tree4b0c02015b4e41ffb8bad34d3694266eae25ca20
parent2b37ca3b2f57d4c8cb00e18ce39371e7aefc1db3 (diff)
parent385a9e1b68f3eea51f71386a8f4856477ba6a273 (diff)
downloadchouette-core-3562_ccset_affectation.tar.bz2
Merge branch 'master' into 3562_ccset_affectation3562_ccset_affectation
-rw-r--r--app/controllers/statuses_controller.rb20
-rw-r--r--app/decorators/time_table_decorator.rb2
-rw-r--r--app/helpers/table_builder_helper.rb2
-rw-r--r--app/javascript/routes/components/BSelect2.js2
-rw-r--r--app/javascript/routes/components/OlMap.js24
-rw-r--r--app/javascript/routes/components/StopPoint.js12
-rw-r--r--app/javascript/routes/components/StopPointList.js8
-rw-r--r--app/javascript/time_tables/actions/index.js12
-rw-r--r--app/javascript/time_tables/components/ConfirmModal.js10
-rw-r--r--app/javascript/time_tables/components/ErrorModal.js6
-rw-r--r--app/javascript/time_tables/components/Metas.js12
-rw-r--r--app/javascript/time_tables/components/PeriodForm.js14
-rw-r--r--app/javascript/time_tables/components/TagsSelect2.js2
-rw-r--r--app/javascript/time_tables/components/Timetable.js8
-rw-r--r--app/models/chouette/route.rb2
-rw-r--r--app/models/chouette/routing_constraint_zone.rb4
-rw-r--r--app/models/compliance_check_set.rb14
-rw-r--r--app/models/concerns/checksum_support.rb25
-rw-r--r--app/models/concerns/min_max_values_validation.rb1
-rw-r--r--app/models/concerns/timetable_support.rb2
-rw-r--r--app/models/import.rb10
-rw-r--r--app/models/referential.rb1
-rw-r--r--app/models/vehicle_journey_control/delta.rb1
-rw-r--r--app/models/vehicle_journey_control/waiting_time.rb1
-rw-r--r--app/services/parent_import_notifier.rb15
-rw-r--r--app/services/parent_notifier.rb19
-rw-r--r--app/views/calendars/index.html.slim2
-rw-r--r--app/views/time_tables/_form.html.slim2
-rw-r--r--config/deploy.rb2
-rw-r--r--config/locales/journey_patterns.en.yml1
-rw-r--r--config/locales/stop_points.en.yml1
-rw-r--r--config/locales/stop_points.fr.yml3
-rw-r--r--config/routes.rb2
-rw-r--r--config/schedule.rb6
-rw-r--r--lib/tasks/compliance_check_sets.rb11
-rw-r--r--lib/tasks/imports.rake7
-rw-r--r--spec/controllers/statuses_controller_spec.rb50
-rw-r--r--spec/factories/chouette_routes.rb1
-rw-r--r--spec/factories/compliance_controls/vehicle_journey_control_factories.rb2
-rw-r--r--spec/models/chouette/footnote_spec.rb12
-rw-r--r--spec/models/chouette/journey_pattern_spec.rb3
-rw-r--r--spec/models/chouette/route/route_base_spec.rb4
-rw-r--r--spec/models/chouette/routing_constraint_zone_spec.rb2
-rw-r--r--spec/models/chouette/time_table_period_spec.rb2
-rw-r--r--spec/models/chouette/time_table_spec.rb2
-rw-r--r--spec/models/chouette/vehicle_journey_at_stop_spec.rb4
-rw-r--r--spec/models/chouette/vehicle_journey_spec.rb4
-rw-r--r--spec/models/compliance_check_spec.rb32
-rw-r--r--spec/models/import_spec.rb52
-rw-r--r--spec/services/parent_notifier_spec.rb (renamed from spec/services/parent_import_notifier_spec.rb)16
-rw-r--r--spec/support/checksum_support.rb67
51 files changed, 397 insertions, 122 deletions
diff --git a/app/controllers/statuses_controller.rb b/app/controllers/statuses_controller.rb
new file mode 100644
index 000000000..e38a92982
--- /dev/null
+++ b/app/controllers/statuses_controller.rb
@@ -0,0 +1,20 @@
+class StatusesController < ChouetteController
+ respond_to :json
+
+ def index
+
+ status = {
+ referentials_blocked: Referential.blocked.count,
+ imports_blocked: Import.blocked.count,
+ compliance_check_sets_blocked: ComplianceCheckSet.blocked.count
+ }
+ status[:status] = global_status status
+ render json: status.to_json
+ end
+
+ private
+
+ def global_status status
+ status.values.all?(&:zero?) ? 'ok' : 'ko'
+ end
+end
diff --git a/app/decorators/time_table_decorator.rb b/app/decorators/time_table_decorator.rb
index 95b1fd959..e4f9d7dbc 100644
--- a/app/decorators/time_table_decorator.rb
+++ b/app/decorators/time_table_decorator.rb
@@ -14,7 +14,7 @@ class TimeTableDecorator < AF83::Decorator
l.href { [:edit, context[:referential], object] }
end
- instance_decorator.action_link if: ->{ object.calendar }, secondary: true do |l|
+ instance_decorator.action_link policy: :actualize, if: ->{ object.calendar }, secondary: true do |l|
l.content t('actions.actualize')
l.href do
h.actualize_referential_time_table_path(
diff --git a/app/helpers/table_builder_helper.rb b/app/helpers/table_builder_helper.rb
index 279995741..2068dd23c 100644
--- a/app/helpers/table_builder_helper.rb
+++ b/app/helpers/table_builder_helper.rb
@@ -330,7 +330,7 @@ module TableBuilderHelper
else
menu = content_tag :ul, class: 'dropdown-menu' do
(
- CustomLinks.new(item, pundit_user, links, referential).links +
+ CustomLinks.new(item, pundit_user, links, referential, workgroup).links +
action_links.select { |link| link.is_a?(Link) }
).map do |link|
gear_menu_link(link)
diff --git a/app/javascript/routes/components/BSelect2.js b/app/javascript/routes/components/BSelect2.js
index 158deaa17..035bce155 100644
--- a/app/javascript/routes/components/BSelect2.js
+++ b/app/javascript/routes/components/BSelect2.js
@@ -85,7 +85,7 @@ class BSelect2 extends Component{
onSelect={ this.props.onSelect }
ref='newSelect'
options={{
- placeholder: this.context.I18n.routes.edit.select2.placeholder,
+ placeholder: this.context.I18n.t("routes.edit.select2.placeholder"),
allowClear: true,
language: 'fr', /* Doesn't seem to work... :( */
theme: 'bootstrap',
diff --git a/app/javascript/routes/components/OlMap.js b/app/javascript/routes/components/OlMap.js
index 056bddbcb..4beb02872 100644
--- a/app/javascript/routes/components/OlMap.js
+++ b/app/javascript/routes/components/OlMap.js
@@ -115,40 +115,40 @@ export default class OlMap extends Component{
<strong>{this.props.value.olMap.json.name}</strong>
</p>
<p>
- <strong>{this.context.I18n.routes.edit.stop_point_type} : </strong>
+ <strong>{this.context.I18n.t('routes.edit.map.stop_point_type')} : </strong>
{this.props.value.olMap.json.area_type}
</p>
<p>
- <strong>{this.context.I18n.routes.edit.short_name} : </strong>
+ <strong>{this.context.I18n.t('routes.edit.map.short_name')} : </strong>
{this.props.value.olMap.json.short_name}
</p>
<p>
- <strong>{this.context.I18n.id_reflex} : </strong>
+ <strong>{this.context.I18n.t('id_reflex')} : </strong>
{this.props.value.olMap.json.user_objectid}
</p>
- <p><strong>{this.context.I18n.routes.edit.map.coordinates} : </strong></p>
+ <p><strong>{this.context.I18n.t('routes.edit.map.coordinates')} : </strong></p>
<p style={{paddingLeft: 10, marginTop: 0}}>
- <em>{this.context.I18n.routes.edit.map.proj}.: </em>WSG84<br/>
- <em>{this.context.I18n.routes.edit.map.lat}.: </em>{this.props.value.olMap.json.latitude} <br/>
- <em>{this.context.I18n.routes.edit.map.lon}.: </em>{this.props.value.olMap.json.longitude}
+ <em>{this.context.I18n.t('routes.edit.map.proj')}.: </em>WSG84<br/>
+ <em>{this.context.I18n.t('routes.edit.map.lat')}.: </em>{this.props.value.olMap.json.latitude} <br/>
+ <em>{this.context.I18n.t('routes.edit.map.lon')}.: </em>{this.props.value.olMap.json.longitude}
</p>
<p>
- <strong>{this.context.I18n.routes.edit.map.postal_code} : </strong>
+ <strong>{this.context.I18n.t('routes.edit.map.postal_code')} : </strong>
{this.props.value.olMap.json.zip_code}
</p>
<p>
- <strong>{this.context.I18n.routes.edit.map.city} : </strong>
+ <strong>{this.context.I18n.t('routes.edit.map.city')} : </strong>
{this.props.value.olMap.json.city_name}
</p>
<p>
- <strong>{this.context.I18n.routes.edit.map.comment} : </strong>
+ <strong>{this.context.I18n.t('routes.edit.map.comment')} : </strong>
{this.props.value.olMap.json.comment}
</p>
{(this.props.value.stoparea_id != this.props.value.olMap.json.stoparea_id) &&(
<div className='btn btn-outline-primary btn-sm'
onClick= {() => {this.props.onUpdateViaOlMap(this.props.index, this.props.value.olMap.json)}}
- >{this.context.I18n.actions.select}</div>
+ >{this.context.I18n.t('actions.select')}</div>
)}
</div>
<div className='map_content'>
@@ -162,7 +162,7 @@ export default class OlMap extends Component{
}
}
-OlMap.PropTypes = {
+OlMap.propTypes = {
}
OlMap.contextTypes = {
diff --git a/app/javascript/routes/components/StopPoint.js b/app/javascript/routes/components/StopPoint.js
index 2d47e802b..af51a6bb4 100644
--- a/app/javascript/routes/components/StopPoint.js
+++ b/app/javascript/routes/components/StopPoint.js
@@ -18,15 +18,15 @@ export default function StopPoint(props, {I18n}) {
<div>
<select className='form-control' value={props.value.for_boarding} id="for_boarding" onChange={props.onSelectChange}>
- <option value="normal">{I18n.routes.edit.stop_point.boarding.normal}</option>
- <option value="forbidden">{I18n.routes.edit.stop_point.boarding.forbidden}</option>
+ <option value="normal">{I18n.t('routes.edit.stop_point.boarding.normal')}</option>
+ <option value="forbidden">{I18n.t('routes.edit.stop_point.boarding.forbidden')}</option>
</select>
</div>
<div>
<select className='form-control' value={props.value.for_alighting} id="for_alighting" onChange={props.onSelectChange}>
- <option value="normal">{I18n.routes.edit.stop_point.alighting.normal}</option>
- <option value="forbidden">{I18n.routes.edit.stop_point.alighting.forbidden}</option>
+ <option value="normal">{I18n.t('routes.edit.stop_point.alighting.normal')}</option>
+ <option value="forbidden">{I18n.t('routes.edit.stop_point.alighting.forbidden')}</option>
</select>
</div>
@@ -77,7 +77,7 @@ export default function StopPoint(props, {I18n}) {
)
}
-StopPoint.PropTypes = {
+StopPoint.propTypes = {
onToggleMap: PropTypes.func.isRequired,
onToggleEdit: PropTypes.func.isRequired,
onDeleteClick: PropTypes.func.isRequired,
@@ -93,4 +93,4 @@ StopPoint.PropTypes = {
StopPoint.contextTypes = {
I18n: PropTypes.object
-} \ No newline at end of file
+}
diff --git a/app/javascript/routes/components/StopPointList.js b/app/javascript/routes/components/StopPointList.js
index b39fa0c9c..b227abdea 100644
--- a/app/javascript/routes/components/StopPointList.js
+++ b/app/javascript/routes/components/StopPointList.js
@@ -10,22 +10,22 @@ export default function StopPointList({ stopPoints, onDeleteClick, onMoveUpClick
<div className="wrapper">
<div style={{width: 100}}>
<div className="form-group">
- <label className="control-label">{I18n.reflex_id}</label>
+ <label className="control-label">{I18n.t('simple_form.labels.stop_point.reflex_id')}</label>
</div>
</div>
<div>
<div className="form-group">
- <label className="control-label">{I18n.simple_form.labels.stop_point.name}</label>
+ <label className="control-label">{I18n.t('simple_form.labels.stop_point.name')}</label>
</div>
</div>
<div>
<div className="form-group">
- <label className="control-label">{I18n.simple_form.labels.stop_point.for_boarding}</label>
+ <label className="control-label">{I18n.t('simple_form.labels.stop_point.for_boarding')}</label>
</div>
</div>
<div>
<div className="form-group">
- <label className="control-label">{I18n.simple_form.labels.stop_point.for_alighting}</label>
+ <label className="control-label">{I18n.t('simple_form.labels.stop_point.for_alighting')}</label>
</div>
</div>
<div className='actions-5'></div>
diff --git a/app/javascript/time_tables/actions/index.js b/app/javascript/time_tables/actions/index.js
index 4a36ec4e1..98b9eab4b 100644
--- a/app/javascript/time_tables/actions/index.js
+++ b/app/javascript/time_tables/actions/index.js
@@ -8,7 +8,7 @@ const I18n = clone(window, "I18n")
const actions = {
weekDays: (index) => {
- return range(1, 8).map(n => I18n.time_tables.edit.metas.days[n])
+ return range(1, 8).map(n => I18n.t('time_tables.edit.metas.days')[n])
},
strToArrayDayTypes: (str) =>{
return actions.weekDays().map(day => str.indexOf(day) !== -1)
@@ -155,7 +155,7 @@ const actions = {
type : 'CLOSE_MODAL'
}),
monthName(strDate) {
- let monthList = range(1,13).map(n => I18n.calendars.months[n])
+ let monthList = range(1,13).map(n => I18n.t('calendars.months.'+ n ))
let date = new Date(strDate)
return monthList[date.getUTCMonth()]
},
@@ -225,7 +225,7 @@ const actions = {
let period = periods[i]
if (index !== i && !period.deleted) {
if (new Date(period.period_start) <= end && new Date(period.period_end) >= start) {
- error = I18n.time_tables.edit.error_submit.periods_overlaps
+ error = I18n.t('time_tables.edit.error_submit.periods_overlaps')
break
}
}
@@ -239,7 +239,7 @@ const actions = {
for (let day of in_days) {
if (start <= new Date(day.date) && end >= new Date(day.date)) {
- error = I18n.time_tables.edit.error_submit.dates_overlaps
+ error = I18n.t('time_tables.edit.error_submit.dates_overlaps')
break
}
}
@@ -316,9 +316,9 @@ const actions = {
errorModalMessage: (errorKey) => {
switch (errorKey) {
case "withoutPeriodsWithDaysTypes":
- return I18n.time_tables.edit.error_modal.withoutPeriodsWithDaysTypes
+ return I18n.t('time_tables.edit.error_modal.withoutPeriodsWithDaysTypes')
case "withPeriodsWithoutDayTypes":
- return I18n.time_tables.edit.error_modal.withPeriodsWithoutDayTypes
+ return I18n.t('time_tables.edit.error_modal.withPeriodsWithoutDayTypes')
default:
return errorKey
diff --git a/app/javascript/time_tables/components/ConfirmModal.js b/app/javascript/time_tables/components/ConfirmModal.js
index 845e7ed1b..4e8583bc0 100644
--- a/app/javascript/time_tables/components/ConfirmModal.js
+++ b/app/javascript/time_tables/components/ConfirmModal.js
@@ -9,11 +9,11 @@ export default function ConfirmModal({dispatch, modal, onModalAccept, onModalCan
<div className='modal-dialog'>
<div className='modal-content'>
<div className='modal-header'>
- <h4 className='modal-title'>{I18n.time_tables.edit.confirm_modal.title}</h4>
+ <h4 className='modal-title'>{I18n.t('time_tables.edit.confirm_modal.title')}</h4>
</div>
<div className='modal-body'>
<div className='mt-md mb-md'>
- <p>{I18n.time_tables.edit.confirm_modal.message}</p>
+ <p>{I18n.t('time_tables.edit.confirm_modal.message')}</p>
</div>
</div>
<div className='modal-footer'>
@@ -23,7 +23,7 @@ export default function ConfirmModal({dispatch, modal, onModalAccept, onModalCan
type='button'
onClick={() => { onModalCancel(modal.confirmModal.callback) }}
>
- {I18n.cancel}
+ {I18n.t('cancel')}
</button>
<button
className='btn btn-primary'
@@ -31,7 +31,7 @@ export default function ConfirmModal({dispatch, modal, onModalAccept, onModalCan
type='button'
onClick={() => { onModalAccept(modal.confirmModal.callback, timetable, metas) }}
>
- {I18n.actions.submit}
+ {I18n.t('actions.submit')}
</button>
</div>
</div>
@@ -49,4 +49,4 @@ ConfirmModal.propTypes = {
ConfirmModal.contextTypes = {
I18n: PropTypes.object
-} \ No newline at end of file
+}
diff --git a/app/javascript/time_tables/components/ErrorModal.js b/app/javascript/time_tables/components/ErrorModal.js
index 543177e54..8af12f1d1 100644
--- a/app/javascript/time_tables/components/ErrorModal.js
+++ b/app/javascript/time_tables/components/ErrorModal.js
@@ -10,7 +10,7 @@ export default function ErrorModal({dispatch, modal, onModalClose}, {I18n}) {
<div className='modal-dialog'>
<div className='modal-content'>
<div className='modal-header'>
- <h4 className='modal-title'>{I18n.time_tables.edit.error_modal.title}</h4>
+ <h4 className='modal-title'>{I18n.t('time_tables.edit.error_modal.title')}</h4>
</div>
<div className='modal-body'>
<div className='mt-md mb-md'>
@@ -24,7 +24,7 @@ export default function ErrorModal({dispatch, modal, onModalClose}, {I18n}) {
type='button'
onClick={() => { onModalClose() }}
>
- {I18n.back}
+ {I18n.t('back')}
</button>
</div>
</div>
@@ -41,4 +41,4 @@ ErrorModal.propTypes = {
ErrorModal.contextTypes = {
I18n: PropTypes.object
-} \ No newline at end of file
+}
diff --git a/app/javascript/time_tables/components/Metas.js b/app/javascript/time_tables/components/Metas.js
index 3c6848d27..08a6e26fe 100644
--- a/app/javascript/time_tables/components/Metas.js
+++ b/app/javascript/time_tables/components/Metas.js
@@ -13,7 +13,7 @@ export default function Metas({metas, onUpdateDayTypes, onUpdateComment, onUpdat
{/* comment (name) */}
<div className="form-group">
<label htmlFor="" className="control-label col-sm-4 required">
- {I18n.time_tables.edit.metas.name} <abbr title="">*</abbr>
+ {I18n.t('time_tables.edit.metas.name')} <abbr title="">*</abbr>
</label>
<div className="col-sm-8">
<input
@@ -28,7 +28,7 @@ export default function Metas({metas, onUpdateDayTypes, onUpdateComment, onUpdat
{/* color */}
{metas.color !== undefined && <div className="form-group">
- <label htmlFor="" className="control-label col-sm-4">{I18n.activerecord.attributes.time_table.color}</label>
+ <label htmlFor="" className="control-label col-sm-4">{I18n.attribute_name('time_table', 'color')}</label>
<div className="col-sm-8">
<div className="dropdown color_selector">
<button
@@ -73,7 +73,7 @@ export default function Metas({metas, onUpdateDayTypes, onUpdateComment, onUpdat
{/* tags */}
{metas.tags !== undefined && <div className="form-group">
- <label htmlFor="" className="control-label col-sm-4">{I18n.activerecord.attributes.time_table.tag_list}</label>
+ <label htmlFor="" className="control-label col-sm-4">{I18n.attribute_name('time_table', 'tag_list')}</label>
<div className="col-sm-8">
<TagsSelect2
initialTags={metas.initial_tags}
@@ -86,16 +86,16 @@ export default function Metas({metas, onUpdateDayTypes, onUpdateComment, onUpdat
{/* calendar */}
{metas.calendar !== null && <div className="form-group">
- <label htmlFor="" className="control-label col-sm-4">{I18n.activerecord.attributes.time_table.calendar}</label>
+ <label htmlFor="" className="control-label col-sm-4">{I18n.attribute_name('time_table', 'calendar')}</label>
<div className="col-sm-8">
- <span>{metas.calendar ? metas.calendar.name : I18n.time_tables.edit.metas.no_calendar}</span>
+ <span>{metas.calendar ? metas.calendar.name : I18n.t('time_tables.edit.metas.no_calendar')}</span>
</div>
</div>}
{/* day_types */}
<div className="form-group">
<label htmlFor="" className="control-label col-sm-4">
- {I18n.time_tables.edit.metas.day_types}
+ {I18n.t('time_tables.edit.metas.day_types')}
</label>
<div className="col-sm-8">
<div className="form-group labelled-checkbox-group">
diff --git a/app/javascript/time_tables/components/PeriodForm.js b/app/javascript/time_tables/components/PeriodForm.js
index 085654a88..d17a246f7 100644
--- a/app/javascript/time_tables/components/PeriodForm.js
+++ b/app/javascript/time_tables/components/PeriodForm.js
@@ -46,7 +46,7 @@ export default function PeriodForm({modal, timetable, metas, onOpenAddPeriodForm
<div>
<div className="form-group">
<label htmlFor="" className="control-label required">
- {I18n.time_tables.edit.period_form.begin}
+ {I18n.t('time_tables.edit.period_form.begin')}
<abbr title="requis">*</abbr>
</label>
</div>
@@ -54,7 +54,7 @@ export default function PeriodForm({modal, timetable, metas, onOpenAddPeriodForm
<div>
<div className="form-group">
<label htmlFor="" className="control-label required">
- {I18n.time_tables.edit.period_form.end}
+ {I18n.t('time_tables.edit.period_form.end')}
<abbr title="requis">*</abbr>
</label>
</div>
@@ -105,14 +105,14 @@ export default function PeriodForm({modal, timetable, metas, onOpenAddPeriodForm
className='btn btn-link'
onClick={onClosePeriodForm}
>
- {I18n.cancel}
+ {I18n.t('cancel')}
</button>
<button
type='button'
className='btn btn-outline-primary mr-sm'
onClick={() => onValidatePeriodForm(modal.modalProps, timetable.time_table_periods, metas, filter(timetable.time_table_dates, ['in_out', true]))}
>
- {I18n.actions.submit}
+ {I18n.t('actions.submit')}
</button>
</div>
</div>
@@ -124,7 +124,7 @@ export default function PeriodForm({modal, timetable, metas, onOpenAddPeriodForm
className='btn btn-outline-primary'
onClick={onOpenAddPeriodForm}
>
- {I18n.time_tables.actions.add_period}
+ {I18n.t('time_tables.actions.add_period')}
</button>
</div>
}
@@ -132,7 +132,7 @@ export default function PeriodForm({modal, timetable, metas, onOpenAddPeriodForm
</div>
</div>
</div>
- )
+ )
}
PeriodForm.propTypes = {
@@ -147,4 +147,4 @@ PeriodForm.propTypes = {
PeriodForm.contextTypes = {
I18n: PropTypes.object
-} \ No newline at end of file
+}
diff --git a/app/javascript/time_tables/components/TagsSelect2.js b/app/javascript/time_tables/components/TagsSelect2.js
index dc3739d58..43cf59fdf 100644
--- a/app/javascript/time_tables/components/TagsSelect2.js
+++ b/app/javascript/time_tables/components/TagsSelect2.js
@@ -40,7 +40,7 @@ export default class TagsSelect2 extends Component {
allowClear: true,
theme: 'bootstrap',
width: '100%',
- placeholder: this.context.I18n.time_tables.edit.select2.tag.placeholder,
+ placeholder: this.context.I18n.t('time_tables.edit.select2.tag.placeholder'),
ajax: {
url: origin + path + '/tags.json',
dataType: 'json',
diff --git a/app/javascript/time_tables/components/Timetable.js b/app/javascript/time_tables/components/Timetable.js
index c44f2a134..991f31435 100644
--- a/app/javascript/time_tables/components/Timetable.js
+++ b/app/javascript/time_tables/components/Timetable.js
@@ -31,11 +31,11 @@ export default class Timetable extends Component {
<div className="table table-2entries mb-sm">
<div className="t2e-head w20">
<div className="th">
- <div className="strong">{this.context.I18n.time_tables.synthesis}</div>
+ <div className="strong">{this.context.I18n.t('time_tables.edit.synthesis')}</div>
</div>
- <div className="td"><span>{this.context.I18n.time_tables.edit.day_types}</span></div>
- <div className="td"><span>{this.context.I18n.time_tables.edit.periods}</span></div>
- <div className="td"><span>{this.context.I18n.time_tables.edit.exceptions}</span></div>
+ <div className="td"><span>{this.context.I18n.t('time_tables.edit.day_types')}</span></div>
+ <div className="td"><span>{this.context.I18n.t('time_tables.edit.periods')}</span></div>
+ <div className="td"><span>{this.context.I18n.t('time_tables.edit.exceptions')}</span></div>
</div>
<div className="t2e-item-list w80">
<div>
diff --git a/app/models/chouette/route.rb b/app/models/chouette/route.rb
index 47c18af09..5cc5d8b0d 100644
--- a/app/models/chouette/route.rb
+++ b/app/models/chouette/route.rb
@@ -133,7 +133,7 @@ module Chouette
def checksum_attributes
values = self.slice(*['name', 'published_name', 'wayback']).values
values.tap do |attrs|
- attrs << self.stop_points.sort_by(&:position).map{|sp| "#{sp.stop_area.user_objectid}#{sp.for_boarding}#{sp.for_alighting}" }.join
+ attrs << self.stop_points.sort_by(&:position).map{|sp| [sp.stop_area.user_objectid, sp.for_boarding, sp.for_alighting]}
attrs << self.routing_constraint_zones.map(&:checksum)
end
end
diff --git a/app/models/chouette/routing_constraint_zone.rb b/app/models/chouette/routing_constraint_zone.rb
index 903922241..58703598e 100644
--- a/app/models/chouette/routing_constraint_zone.rb
+++ b/app/models/chouette/routing_constraint_zone.rb
@@ -25,7 +25,9 @@ module Chouette
end
def checksum_attributes
- self.stop_points.map(&:stop_area).map(&:user_objectid)
+ [
+ self.stop_points.map(&:stop_area).map(&:user_objectid)
+ ]
end
def stop_points_belong_to_route
diff --git a/app/models/compliance_check_set.rb b/app/models/compliance_check_set.rb
index f4c44d26d..289fc134f 100644
--- a/app/models/compliance_check_set.rb
+++ b/app/models/compliance_check_set.rb
@@ -19,6 +19,20 @@ class ComplianceCheckSet < ActiveRecord::Base
where('created_at BETWEEN :begin AND :end', begin: period_range.begin, end: period_range.end)
end
+ scope :blocked, -> { where('created_at < ? AND status = ?', 4.hours.ago, 'running') }
+
+ def self.finished_statuses
+ %w(successful failed warning aborted canceled)
+ end
+
+ def self.abort_old
+ where(
+ 'created_at < ? AND status NOT IN (?)',
+ 4.hours.ago,
+ finished_statuses
+ ).update_all(status: 'aborted')
+ end
+
def notify_parent
if parent
# parent.child_change
diff --git a/app/models/concerns/checksum_support.rb b/app/models/concerns/checksum_support.rb
index a76995b0f..92103798e 100644
--- a/app/models/concerns/checksum_support.rb
+++ b/app/models/concerns/checksum_support.rb
@@ -24,10 +24,29 @@ module ChecksumSupport
self.attributes.values
end
+ def checksum_replace_nil_or_empty_values values
+ # Replace empty array by nil & nil by VALUE_FOR_NIL_ATTRIBUTE
+ values
+ .map { |x| x.present? && x || VALUE_FOR_NIL_ATTRIBUTE }
+ .map do |item|
+ item =
+ if item.kind_of?(Array)
+ checksum_replace_nil_or_empty_values(item)
+ else
+ item
+ end
+ end
+ end
+
def current_checksum_source
- source = self.checksum_attributes.map{ |x| x unless x.try(:empty?) }
- source = source.map{ |x| x || VALUE_FOR_NIL_ATTRIBUTE }
- source.map(&:to_s).join(SEPARATOR)
+ source = checksum_replace_nil_or_empty_values(self.checksum_attributes)
+ source.map{ |item|
+ if item.kind_of?(Array)
+ item.map{ |x| x.kind_of?(Array) ? "(#{x.join(',')})" : x }.join(',')
+ else
+ item
+ end
+ }.join(SEPARATOR)
end
def set_current_checksum_source
diff --git a/app/models/concerns/min_max_values_validation.rb b/app/models/concerns/min_max_values_validation.rb
index 9b2e0d548..eff779d81 100644
--- a/app/models/concerns/min_max_values_validation.rb
+++ b/app/models/concerns/min_max_values_validation.rb
@@ -2,6 +2,7 @@ module MinMaxValuesValidation
extend ActiveSupport::Concern
included do
+ validates_presence_of :minimum, :maximum
validate :min_max_values_validation
end
diff --git a/app/models/concerns/timetable_support.rb b/app/models/concerns/timetable_support.rb
index 8c49723fe..5242abc33 100644
--- a/app/models/concerns/timetable_support.rb
+++ b/app/models/concerns/timetable_support.rb
@@ -101,7 +101,7 @@ module TimetableSupport
period.period_start = Date.parse(item['period_start'])
period.period_end = Date.parse(item['period_end'])
- period.save if period === ActiveRecord::Base && period.changed?
+ period.save if period.is_a?(ActiveRecord::Base) && period.changed?
item['id'] = period.id
end
diff --git a/app/models/import.rb b/app/models/import.rb
index 049a65f40..29aadcd56 100644
--- a/app/models/import.rb
+++ b/app/models/import.rb
@@ -13,6 +13,8 @@ class Import < ActiveRecord::Base
where('started_at BETWEEN :begin AND :end', begin: period_range.begin, end: period_range.end)
end
+ scope :blocked, -> { where('created_at < ? AND status = ?', 4.hours.ago, 'running') }
+
extend Enumerize
enumerize :status, in: %w(new pending successful warning failed running aborted canceled), scope: true, default: :new
@@ -42,6 +44,14 @@ class Import < ActiveRecord::Base
%w(successful failed warning aborted canceled)
end
+ def self.abort_old
+ where(
+ 'created_at < ? AND status NOT IN (?)',
+ 4.hours.ago,
+ finished_statuses
+ ).update_all(status: 'aborted')
+ end
+
def notify_parent
parent.child_change
update(notified_parent_at: DateTime.now)
diff --git a/app/models/referential.rb b/app/models/referential.rb
index f64db4ebf..509e0412f 100644
--- a/app/models/referential.rb
+++ b/app/models/referential.rb
@@ -62,6 +62,7 @@ class Referential < ActiveRecord::Base
scope :order_by_validity_period, ->(dir) { joins(:metadatas).order("unnest(periodes) #{dir}") }
scope :order_by_lines, ->(dir) { joins(:metadatas).group("referentials.id").order("sum(array_length(referential_metadata.line_ids,1)) #{dir}") }
scope :not_in_referential_suite, -> { where referential_suite_id: nil }
+ scope :blocked, -> { where('ready = ? AND created_at < ?', false, 4.hours.ago) }
def save_with_table_lock_timeout(options = {})
save_without_table_lock_timeout(options)
diff --git a/app/models/vehicle_journey_control/delta.rb b/app/models/vehicle_journey_control/delta.rb
index f061b9fdd..737b7d78c 100644
--- a/app/models/vehicle_journey_control/delta.rb
+++ b/app/models/vehicle_journey_control/delta.rb
@@ -4,6 +4,7 @@ module VehicleJourneyControl
store_accessor :control_attributes, :maximum
validates_numericality_of :maximum, allow_nil: true, greater_than_or_equal_to: 0
+ validates_presence_of :maximum
def self.default_code; "3-VehicleJourney-3" end
end
diff --git a/app/models/vehicle_journey_control/waiting_time.rb b/app/models/vehicle_journey_control/waiting_time.rb
index f2666cb72..89a18a5d9 100644
--- a/app/models/vehicle_journey_control/waiting_time.rb
+++ b/app/models/vehicle_journey_control/waiting_time.rb
@@ -3,6 +3,7 @@ module VehicleJourneyControl
store_accessor :control_attributes, :maximum
validates_numericality_of :maximum, allow_nil: true, greater_than_or_equal_to: 0
+ validates_presence_of :maximum
def self.default_code; "3-VehicleJourney-1" end
end
diff --git a/app/services/parent_import_notifier.rb b/app/services/parent_import_notifier.rb
deleted file mode 100644
index 47e6755e4..000000000
--- a/app/services/parent_import_notifier.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-class ParentImportNotifier
- def self.notify_when_finished(imports = nil)
- imports ||= imports_pending_notification
- imports.each(&:notify_parent)
- end
-
- def self.imports_pending_notification
- Import
- .where(
- notified_parent_at: nil,
- status: Import.finished_statuses
- )
- .where.not(parent: nil)
- end
-end
diff --git a/app/services/parent_notifier.rb b/app/services/parent_notifier.rb
new file mode 100644
index 000000000..653c98aff
--- /dev/null
+++ b/app/services/parent_notifier.rb
@@ -0,0 +1,19 @@
+class ParentNotifier
+ def initialize(klass)
+ @klass = klass
+ end
+
+ def notify_when_finished(collection = nil)
+ collection ||= objects_pending_notification
+ collection.each(&:notify_parent)
+ end
+
+ def objects_pending_notification
+ @klass
+ .where(
+ notified_parent_at: nil,
+ status: @klass.finished_statuses
+ )
+ .where.not(parent: nil)
+ end
+end
diff --git a/app/views/calendars/index.html.slim b/app/views/calendars/index.html.slim
index f17b5d4d4..0b58c0c72 100644
--- a/app/views/calendars/index.html.slim
+++ b/app/views/calendars/index.html.slim
@@ -16,7 +16,7 @@
key: :name, \
attribute: 'name', \
link_to: lambda do |calendar| \
- workgroup_calendar_path(current_workgroup, calendar) \
+ workgroup_calendar_path(workgroup, calendar) \
end \
), \
TableBuilderHelper::Column.new( \
diff --git a/app/views/time_tables/_form.html.slim b/app/views/time_tables/_form.html.slim
index d06fdf444..007044e65 100644
--- a/app/views/time_tables/_form.html.slim
+++ b/app/views/time_tables/_form.html.slim
@@ -5,7 +5,7 @@
= form.input :comment, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.time_table.comment")}
- if @time_table.new_record? && !@time_table.created_from
- = form.input :calendar_id, as: :select, input_html: { class: 'tt_target', style: "width: 100%", data: { 'select2-ajax': 'true', 'select2ed-placeholder': 'Indiquez un modèle de calendrier...', term: 'name_cont', url: autocomplete_calendars_path}}
+ = form.input :calendar_id, as: :select, input_html: { class: 'tt_target', style: "width: 100%", data: { 'select2-ajax': 'true', 'select2ed-placeholder': 'Indiquez un modèle de calendrier...', term: 'name_cont', url: autocomplete_workgroup_calendars_path(current_workgroup)}}
- if @time_table.created_from
= form.input :created_from, disabled: true, input_html: { value: @time_table.created_from.comment }
diff --git a/config/deploy.rb b/config/deploy.rb
index 3353b4186..833ecfbbe 100644
--- a/config/deploy.rb
+++ b/config/deploy.rb
@@ -104,6 +104,6 @@ namespace :deploy do
desc "Run db:seed"
task :seed do
- run "cd #{release_path} && RAILS_ENV=#{rails_env} #{rake} db:seed"
+ run "cd #{current_path} && RAILS_ENV=#{rails_env} #{rake} db:seed"
end
end
diff --git a/config/locales/journey_patterns.en.yml b/config/locales/journey_patterns.en.yml
index e5248c29c..9d9bc21e2 100644
--- a/config/locales/journey_patterns.en.yml
+++ b/config/locales/journey_patterns.en.yml
@@ -6,6 +6,7 @@ en:
vehicle_journeys_count: "Vehicle journeys: %{count}"
vehicle_journey_at_stops: "Vehicle journey at stops"
actions:
+ index: "Journey patterns"
new: "Add a new journey_pattern"
edit: "Edit this journey pattern"
destroy: "Remove this journey pattern"
diff --git a/config/locales/stop_points.en.yml b/config/locales/stop_points.en.yml
index d22d85731..72e138270 100644
--- a/config/locales/stop_points.en.yml
+++ b/config/locales/stop_points.en.yml
@@ -55,3 +55,4 @@ en:
name: Stop Point
for_boarding: "Pickup"
for_alighting: "Drop off"
+ reflex_id: ID
diff --git a/config/locales/stop_points.fr.yml b/config/locales/stop_points.fr.yml
index d3c873442..71be684f6 100644
--- a/config/locales/stop_points.fr.yml
+++ b/config/locales/stop_points.fr.yml
@@ -52,6 +52,7 @@ fr:
simple_form:
labels:
stop_point:
- name: Arrêt
+ name: Arrêt
for_boarding: "Montée"
for_alighting: "Descente"
+ reflex_id: ID
diff --git a/config/routes.rb b/config/routes.rb
index 681b36c59..b01bba18d 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -256,4 +256,6 @@ ChouetteIhm::Application.routes.draw do
match '/422', to: 'errors#server_error', via: :all, as: 'unprocessable_entity'
match '/500', to: 'errors#server_error', via: :all, as: 'server_error'
+ match '/status', to: 'statuses#index', via: :get
+
end
diff --git a/config/schedule.rb b/config/schedule.rb
index 08488c255..0d2a24f31 100644
--- a/config/schedule.rb
+++ b/config/schedule.rb
@@ -40,9 +40,15 @@ every :day, :at => '4:00 am' do
end
every 5.minutes do
+ rake "import:netex_abort_old"
rake "import:notify_parent"
end
+every 5.minutes do
+ rake "compliance_check_sets:abort_old"
+ rake "compliance_check_sets:notify_parent"
+end
+
every 1.minute do
command "/bin/echo HeartBeat"
end
diff --git a/lib/tasks/compliance_check_sets.rb b/lib/tasks/compliance_check_sets.rb
new file mode 100644
index 000000000..c53c7f9ed
--- /dev/null
+++ b/lib/tasks/compliance_check_sets.rb
@@ -0,0 +1,11 @@
+namespace :compliance_check_sets do
+ desc "Notify parent check sets when children finish"
+ task notify_parent: :environment do
+ ParentNotifier.new(ComplianceCheckSet).notify_when_finished
+ end
+
+ desc "Mark old unfinished check sets as 'aborted'"
+ task abort_old: :environment do
+ ComplianceCheckSet.abort_old
+ end
+end
diff --git a/lib/tasks/imports.rake b/lib/tasks/imports.rake
index 6bc84acc8..02e32fd3d 100644
--- a/lib/tasks/imports.rake
+++ b/lib/tasks/imports.rake
@@ -1,6 +1,11 @@
namespace :import do
desc "Notify parent imports when children finish"
task notify_parent: :environment do
- ParentImportNotifier.notify_when_finished
+ ParentNotifier.new(Import).notify_when_finished
+ end
+
+ desc "Mark old unfinished Netex imports as 'aborted'"
+ task netex_abort_old: :environment do
+ NetexImport.abort_old
end
end
diff --git a/spec/controllers/statuses_controller_spec.rb b/spec/controllers/statuses_controller_spec.rb
new file mode 100644
index 000000000..8a6db8e28
--- /dev/null
+++ b/spec/controllers/statuses_controller_spec.rb
@@ -0,0 +1,50 @@
+RSpec.describe StatusesController, :type => :controller do
+
+ describe "GET index" do
+ login_user
+ render_views
+
+
+ let(:request){ get :index}
+ let(:parsed_response){ JSON.parse response.body }
+ it "should be ok" do
+ request
+ expect(response).to have_http_status 200
+ expect(parsed_response["status"]).to eq "ok"
+ end
+ context "without blocked object" do
+ before do
+ create :referential
+ create :import
+ create :compliance_check_set
+ request
+ end
+
+ it "should be ok" do
+ expect(response).to have_http_status 200
+ expect(parsed_response["status"]).to eq "ok"
+ expect(parsed_response["referentials_blocked"]).to eq 0
+ expect(parsed_response["imports_blocked"]).to eq 0
+ expect(parsed_response["imports_blocked"]).to eq 0
+ end
+ end
+
+ context "with a blocked object" do
+ before do
+ create :referential, created_at: 5.hours.ago, ready: false
+ create :import
+ create :compliance_check_set
+ request
+ end
+
+ it "should be ko" do
+ expect(Referential.blocked.count).to eq 1
+ expect(response).to have_http_status 200
+ expect(parsed_response["status"]).to eq "ko"
+ expect(parsed_response["referentials_blocked"]).to eq 1
+ expect(parsed_response["imports_blocked"]).to eq 0
+ expect(parsed_response["imports_blocked"]).to eq 0
+ end
+ end
+ end
+end
diff --git a/spec/factories/chouette_routes.rb b/spec/factories/chouette_routes.rb
index 7443d08bc..92a50b924 100644
--- a/spec/factories/chouette_routes.rb
+++ b/spec/factories/chouette_routes.rb
@@ -19,6 +19,7 @@ FactoryGirl.define do
after(:create) do |route, evaluator|
create_list(:stop_point, evaluator.stop_points_count, route: route)
route.reload
+ route.update_checksum!
end
factory :route_with_journey_patterns do
diff --git a/spec/factories/compliance_controls/vehicle_journey_control_factories.rb b/spec/factories/compliance_controls/vehicle_journey_control_factories.rb
index e8f68cbdf..86a335aba 100644
--- a/spec/factories/compliance_controls/vehicle_journey_control_factories.rb
+++ b/spec/factories/compliance_controls/vehicle_journey_control_factories.rb
@@ -1,10 +1,12 @@
FactoryGirl.define do
factory :vehicle_journey_control_wating_time, class: 'VehicleJourneyControl::WaitingTime' do
+ maximum 10
association :compliance_control_set
end
factory :vehicle_journey_control_delta, class: 'VehicleJourneyControl::Delta' do
+ maximum 10
association :compliance_control_set
end
diff --git a/spec/models/chouette/footnote_spec.rb b/spec/models/chouette/footnote_spec.rb
index fc5e5f306..05f55c2f0 100644
--- a/spec/models/chouette/footnote_spec.rb
+++ b/spec/models/chouette/footnote_spec.rb
@@ -1,12 +1,12 @@
require 'spec_helper'
describe Chouette::Footnote, type: :model do
- let(:footnote) { create(:footnote) }
+ subject { create(:footnote) }
it { should validate_presence_of :line }
describe 'data_source_ref' do
it 'should set default if omitted' do
- expect(footnote.data_source_ref).to eq "DATASOURCEREF_EDITION_BOIV"
+ expect(subject.data_source_ref).to eq "DATASOURCEREF_EDITION_BOIV"
end
it 'should not set default if not omitted' do
@@ -18,16 +18,16 @@ describe Chouette::Footnote, type: :model do
end
describe 'checksum' do
- it_behaves_like 'checksum support', :footnote
+ it_behaves_like 'checksum support'
context '#checksum_attributes' do
it 'should return code and label' do
- expected = [footnote.code, footnote.label]
- expect(footnote.checksum_attributes).to include(*expected)
+ expected = [subject.code, subject.label]
+ expect(subject.checksum_attributes).to include(*expected)
end
it 'should not return other atrributes' do
- expect(footnote.checksum_attributes).to_not include(footnote.updated_at)
+ expect(subject.checksum_attributes).to_not include(subject.updated_at)
end
end
end
diff --git a/spec/models/chouette/journey_pattern_spec.rb b/spec/models/chouette/journey_pattern_spec.rb
index b5eb9004c..19a74a0e7 100644
--- a/spec/models/chouette/journey_pattern_spec.rb
+++ b/spec/models/chouette/journey_pattern_spec.rb
@@ -2,9 +2,10 @@ require 'spec_helper'
describe Chouette::JourneyPattern, :type => :model do
it { is_expected.to be_versioned }
+ subject { create(:journey_pattern) }
describe 'checksum' do
- it_behaves_like 'checksum support', :journey_pattern
+ it_behaves_like 'checksum support'
end
# context 'validate minimum stop_points size' do
diff --git a/spec/models/chouette/route/route_base_spec.rb b/spec/models/chouette/route/route_base_spec.rb
index 26f57eae5..98cb3e358 100644
--- a/spec/models/chouette/route/route_base_spec.rb
+++ b/spec/models/chouette/route/route_base_spec.rb
@@ -1,8 +1,8 @@
RSpec.describe Chouette::Route, :type => :model do
-
subject { create(:route) }
+
describe 'checksum' do
- it_behaves_like 'checksum support', :route
+ it_behaves_like 'checksum support'
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) }
diff --git a/spec/models/chouette/routing_constraint_zone_spec.rb b/spec/models/chouette/routing_constraint_zone_spec.rb
index 0282cb8b1..bda6bb04a 100644
--- a/spec/models/chouette/routing_constraint_zone_spec.rb
+++ b/spec/models/chouette/routing_constraint_zone_spec.rb
@@ -11,7 +11,7 @@ describe Chouette::RoutingConstraintZone, type: :model do
it { is_expected.to be_versioned }
describe 'checksum' do
- it_behaves_like 'checksum support', :routing_constraint_zone
+ it_behaves_like 'checksum support'
end
describe 'validations' do
diff --git a/spec/models/chouette/time_table_period_spec.rb b/spec/models/chouette/time_table_period_spec.rb
index cc1a3ae09..e14d38ade 100644
--- a/spec/models/chouette/time_table_period_spec.rb
+++ b/spec/models/chouette/time_table_period_spec.rb
@@ -10,7 +10,7 @@ describe Chouette::TimeTablePeriod, :type => :model do
it { is_expected.to validate_presence_of :period_end }
describe 'checksum' do
- it_behaves_like 'checksum support', :time_table_period
+ it_behaves_like 'checksum support'
end
describe "#overlap" do
diff --git a/spec/models/chouette/time_table_spec.rb b/spec/models/chouette/time_table_spec.rb
index 6e5da2c67..fe4bd3cfa 100644
--- a/spec/models/chouette/time_table_spec.rb
+++ b/spec/models/chouette/time_table_spec.rb
@@ -1048,7 +1048,7 @@ end
# it { is_expected.to validate_uniqueness_of :objectid }
describe 'checksum' do
- it_behaves_like 'checksum support', :time_table
+ it_behaves_like 'checksum support'
it "handles newly built dates and periods" do
time_table = build(:time_table)
diff --git a/spec/models/chouette/vehicle_journey_at_stop_spec.rb b/spec/models/chouette/vehicle_journey_at_stop_spec.rb
index 02306883c..a97559a0c 100644
--- a/spec/models/chouette/vehicle_journey_at_stop_spec.rb
+++ b/spec/models/chouette/vehicle_journey_at_stop_spec.rb
@@ -1,10 +1,12 @@
require 'spec_helper'
RSpec.describe Chouette::VehicleJourneyAtStop, type: :model do
+ subject { create(:vehicle_journey_at_stop) }
+
describe 'checksum' do
let(:at_stop) { build_stubbed(:vehicle_journey_at_stop) }
- it_behaves_like 'checksum support', :vehicle_journey_at_stop
+ it_behaves_like 'checksum support'
context '#checksum_attributes' do
it 'should return attributes' do
diff --git a/spec/models/chouette/vehicle_journey_spec.rb b/spec/models/chouette/vehicle_journey_spec.rb
index 7279980a3..76e73d9cf 100644
--- a/spec/models/chouette/vehicle_journey_spec.rb
+++ b/spec/models/chouette/vehicle_journey_spec.rb
@@ -1,6 +1,8 @@
require 'spec_helper'
describe Chouette::VehicleJourney, :type => :model do
+ subject { create(:vehicle_journey) }
+
it { is_expected.to be_versioned }
it { should have_and_belong_to_many(:purchase_windows) }
@@ -21,7 +23,7 @@ describe Chouette::VehicleJourney, :type => :model do
end
describe 'checksum' do
- it_behaves_like 'checksum support', :vehicle_journey
+ it_behaves_like 'checksum support'
it "changes when a vjas is updated" do
vehicle_journey = create(:vehicle_journey)
expect{vehicle_journey.vehicle_journey_at_stops.last.update_attribute(:departure_time, Time.now)}.to change{vehicle_journey.reload.checksum}
diff --git a/spec/models/compliance_check_spec.rb b/spec/models/compliance_check_spec.rb
index f83d78c29..ffa59245c 100644
--- a/spec/models/compliance_check_spec.rb
+++ b/spec/models/compliance_check_spec.rb
@@ -15,4 +15,36 @@ RSpec.describe ComplianceCheck, type: :model do
it { should validate_presence_of :name }
it { should validate_presence_of :code }
it { should validate_presence_of :origin_code }
+
+ describe ".abort_old" do
+ it "changes check sets older than 4 hours to aborted" do
+ Timecop.freeze(Time.now) do
+ old_check_set = create(
+ :compliance_check_set,
+ status: 'pending',
+ created_at: 4.hours.ago - 1.minute
+ )
+ current_check_set = create(:compliance_check_set, status: 'pending')
+
+ ComplianceCheckSet.abort_old
+
+ expect(current_check_set.reload.status).to eq('pending')
+ expect(old_check_set.reload.status).to eq('aborted')
+ end
+ end
+
+ it "doesn't work on check sets with a `finished_status`" do
+ Timecop.freeze(Time.now) do
+ check_set = create(
+ :compliance_check_set,
+ status: 'successful',
+ created_at: 4.hours.ago - 1.minute
+ )
+
+ ComplianceCheckSet.abort_old
+
+ expect(check_set.reload.status).to eq('successful')
+ end
+ end
+ end
end
diff --git a/spec/models/import_spec.rb b/spec/models/import_spec.rb
index ffb2360c2..8b85f151b 100644
--- a/spec/models/import_spec.rb
+++ b/spec/models/import_spec.rb
@@ -29,6 +29,58 @@ RSpec.describe Import, type: :model do
)
end
+ describe ".abort_old" do
+ it "changes imports older than 4 hours to aborted" do
+ Timecop.freeze(Time.now) do
+ old_import = create(
+ :workbench_import,
+ status: 'pending',
+ created_at: 4.hours.ago - 1.minute
+ )
+ current_import = create(:workbench_import, status: 'pending')
+
+ Import.abort_old
+
+ expect(current_import.reload.status).to eq('pending')
+ expect(old_import.reload.status).to eq('aborted')
+ end
+ end
+
+ it "doesn't work on imports with a `finished_status`" do
+ Timecop.freeze(Time.now) do
+ import = create(
+ :workbench_import,
+ status: 'successful',
+ created_at: 4.hours.ago - 1.minute
+ )
+
+ Import.abort_old
+
+ expect(import.reload.status).to eq('successful')
+ end
+ end
+
+ it "only works on the caller type" do
+ Timecop.freeze(Time.now) do
+ workbench_import = create(
+ :workbench_import,
+ status: 'pending',
+ created_at: 4.hours.ago - 1.minute
+ )
+ netex_import = create(
+ :netex_import,
+ status: 'pending',
+ created_at: 4.hours.ago - 1.minute
+ )
+
+ NetexImport.abort_old
+
+ expect(workbench_import.reload.status).to eq('pending')
+ expect(netex_import.reload.status).to eq('aborted')
+ end
+ end
+ end
+
describe "#destroy" do
it "must destroy all child imports" do
netex_import = create(:netex_import)
diff --git a/spec/services/parent_import_notifier_spec.rb b/spec/services/parent_notifier_spec.rb
index 3ab505f88..ecf508fcd 100644
--- a/spec/services/parent_import_notifier_spec.rb
+++ b/spec/services/parent_notifier_spec.rb
@@ -1,4 +1,4 @@
-RSpec.describe ParentImportNotifier do
+RSpec.describe ParentNotifier do
let(:workbench_import) { create(:workbench_import) }
describe ".notify_when_finished" do
@@ -20,7 +20,7 @@ RSpec.describe ParentImportNotifier do
expect(netex_import).to receive(:notify_parent)
end
- ParentImportNotifier.notify_when_finished(netex_imports)
+ ParentNotifier.new(Import).notify_when_finished(netex_imports)
end
it "doesn't call #notify_parent if its `notified_parent_at` is set" do
@@ -33,11 +33,11 @@ RSpec.describe ParentImportNotifier do
expect(netex_import).not_to receive(:notify_parent)
- ParentImportNotifier.notify_when_finished
+ ParentNotifier.new(Import).notify_when_finished
end
end
- describe ".imports_pending_notification" do
+ describe ".objects_pending_notification" do
it "includes imports with a parent and `notified_parent_at` unset" do
netex_import = create(
:netex_import,
@@ -47,7 +47,7 @@ RSpec.describe ParentImportNotifier do
)
expect(
- ParentImportNotifier.imports_pending_notification
+ ParentNotifier.new(Import).objects_pending_notification
).to eq([netex_import])
end
@@ -55,7 +55,7 @@ RSpec.describe ParentImportNotifier do
create(:import, parent: nil)
expect(
- ParentImportNotifier.imports_pending_notification
+ ParentNotifier.new(Import).objects_pending_notification
).to be_empty
end
@@ -70,7 +70,7 @@ RSpec.describe ParentImportNotifier do
end
expect(
- ParentImportNotifier.imports_pending_notification
+ ParentNotifier.new(Import).objects_pending_notification
).to be_empty
end
@@ -83,7 +83,7 @@ RSpec.describe ParentImportNotifier do
)
expect(
- ParentImportNotifier.imports_pending_notification
+ ParentNotifier.new(Import).objects_pending_notification
).to be_empty
end
end
diff --git a/spec/support/checksum_support.rb b/spec/support/checksum_support.rb
index e02d9f9f3..f8dffb1b7 100644
--- a/spec/support/checksum_support.rb
+++ b/spec/support/checksum_support.rb
@@ -1,25 +1,23 @@
-shared_examples 'checksum support' do |factory_name|
- let(:instance) { create(factory_name) }
-
+shared_examples 'checksum support' do
describe '#current_checksum_source' do
let(:attributes) { ['code_value', 'label_value'] }
- let(:seperator) { ChecksumSupport::SEPARATOR }
+ let(:separator) { ChecksumSupport::SEPARATOR }
let(:nil_value) { ChecksumSupport::VALUE_FOR_NIL_ATTRIBUTE }
before do
- allow_any_instance_of(instance.class).to receive(:checksum_attributes).and_return(attributes)
+ allow_any_instance_of(subject.class).to receive(:checksum_attributes).and_return(attributes)
end
- it 'should separate attribute by seperator' do
- expect(instance.current_checksum_source).to eq("code_value#{seperator}label_value")
+ it 'should separate attribute by separator' do
+ expect(subject.current_checksum_source).to eq("code_value#{separator}label_value")
end
context 'nil value' do
let(:attributes) { ['code_value', nil] }
it 'should replace nil attributes by default value' do
- source = "code_value#{seperator}#{nil_value}"
- expect(instance.current_checksum_source).to eq(source)
+ source = "code_value#{separator}#{nil_value}"
+ expect(subject.current_checksum_source).to eq(source)
end
end
@@ -27,27 +25,62 @@ shared_examples 'checksum support' do |factory_name|
let(:attributes) { ['code_value', []] }
it 'should convert to nil' do
- source = "code_value#{seperator}#{nil_value}"
- expect(instance.current_checksum_source).to eq(source)
+ source = "code_value#{separator}#{nil_value}"
+ expect(subject.current_checksum_source).to eq(source)
+ end
+ end
+
+ context 'array value' do
+ let(:attributes) { [['v1', 'v2', 'v3'], 'code_value'] }
+
+ it 'should convert to list' do
+ source = "v1,v2,v3#{separator}code_value"
+ expect(subject.current_checksum_source).to eq(source)
+ end
+ end
+
+ context 'array of array value' do
+ let(:attributes) { [[['a1', 'a2', 'a3'], ['b1', 'b2', 'b3']], 'code_value'] }
+
+ it 'should convert to list' do
+ source = "(a1,a2,a3),(b1,b2,b3)#{separator}code_value"
+ expect(subject.current_checksum_source).to eq(source)
+ end
+ end
+
+ context 'array of array value, with empty array' do
+ let(:attributes) { [[['a1', 'a2', 'a3'], []], 'code_value'] }
+
+ it 'should convert to list' do
+ source = "(a1,a2,a3),-#{separator}code_value"
+ expect(subject.current_checksum_source).to eq(source)
end
end
end
it 'should save checksum on create' do
- expect(instance.checksum).to_not be_nil
+ expect(subject.checksum).to_not be_nil
end
it 'should save checksum_source' do
- expect(instance.checksum_source).to_not be_nil
+ expect(subject.checksum_source).to_not be_nil
end
it 'should trigger set_current_checksum_source on save' do
- expect(instance).to receive(:set_current_checksum_source).at_least(:once)
- instance.save
+ expect(subject).to receive(:set_current_checksum_source).at_least(:once)
+ subject.save
end
it 'should trigger update_checksum on save' do
- expect(instance).to receive(:update_checksum).at_least(:once)
- instance.save
+ expect(subject).to receive(:update_checksum).at_least(:once)
+ subject.save
+ end
+
+ it "doesn't change the checksum on save if the source hasn't been changed" do
+ checksum = subject.checksum
+
+ subject.save
+
+ expect(subject.checksum).to eq(checksum)
end
end