aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorXinhui2017-05-29 16:29:32 +0200
committerXinhui2017-05-29 16:29:32 +0200
commit6886441ce86bcd720b27cdd089567def5b9d771a (patch)
treebda614b5fce39f51a794304615a7252ef86b012e
parent4f5cc7d35777f3b4bfa1c63c1223c679f713424e (diff)
parent54bf18da9a74295c327e39c659ef3a28719a2631 (diff)
downloadchouette-core-6886441ce86bcd720b27cdd089567def5b9d771a.tar.bz2
Merge branch 'master' into staging
-rw-r--r--app/assets/javascripts/es6_browserified/itineraries/containers/VisibleStopPoints.js1
-rw-r--r--app/assets/javascripts/es6_browserified/time_tables/components/Metas.js2
-rw-r--r--app/assets/javascripts/es6_browserified/time_tables/index.js2
-rw-r--r--app/assets/javascripts/es6_browserified/time_tables/reducers/metas.js6
-rw-r--r--app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/CreateModal.js11
-rw-r--r--app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/TimetablesEditVehicleJourney.js12
-rw-r--r--app/assets/javascripts/es6_browserified/vehicle_journeys/containers/tools/TimetablesEditVehicleJourney.js2
-rw-r--r--app/assets/javascripts/es6_browserified/vehicle_journeys/index.js14
-rw-r--r--app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/modal.js11
-rw-r--r--app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/vehicleJourneys.js1
-rw-r--r--app/controllers/autocomplete_calendars_controller.rb2
-rw-r--r--app/controllers/time_table_combinations_controller.rb1
-rw-r--r--app/controllers/time_tables_controller.rb2
-rw-r--r--app/models/chouette/time_table.rb3
-rw-r--r--app/models/chouette/vehicle_journey.rb11
-rw-r--r--app/models/chouette/vehicle_journey_at_stop.rb25
-rw-r--r--app/models/chouette/vehicle_journey_at_stops_are_in_increasing_time_order_validator.rb50
-rw-r--r--app/models/time_table_combination.rb3
-rw-r--r--app/models/user.rb4
-rw-r--r--app/policies/acces_point_policy.rb2
-rw-r--r--app/policies/access_link_policy.rb2
-rw-r--r--app/policies/application_policy.rb9
-rw-r--r--app/policies/boiv_policy.rb15
-rw-r--r--app/policies/calendar_policy.rb2
-rw-r--r--app/policies/chain.rb57
-rw-r--r--app/policies/company_policy.rb2
-rw-r--r--app/policies/connection_link_policy.rb2
-rw-r--r--app/policies/group_of_line_policy.rb2
-rw-r--r--app/policies/journey_pattern_policy.rb2
-rw-r--r--app/policies/line_policy.rb9
-rw-r--r--app/policies/network_policy.rb2
-rw-r--r--app/policies/referential_policy.rb2
-rw-r--r--app/policies/route_policy.rb5
-rw-r--r--app/policies/routing_constraint_zone_policy.rb5
-rw-r--r--app/policies/stop_area_policy.rb2
-rw-r--r--app/policies/time_table_policy.rb14
-rw-r--r--app/policies/vehicle_journey_policy.rb2
-rw-r--r--app/views/referential_lines/_filters.html.slim2
-rw-r--r--app/views/time_table_combinations/_form.html.slim2
-rw-r--r--app/views/time_tables/_form.html.slim2
-rw-r--r--lib/time_duration.rb20
-rw-r--r--spec/features/line_footnotes_spec.rb3
-rw-r--r--spec/features/time_tables_spec.rb4
-rw-r--r--spec/javascripts/time_table/reducers/metas_spec.js2
-rw-r--r--spec/javascripts/vehicle_journeys/reducers/vehicle_journeys_spec.js4
-rw-r--r--spec/lib/time_duration_spec.rb33
-rw-r--r--spec/models/chouette/time_table_spec.rb9
-rw-r--r--spec/models/chouette/vehicle_journey_at_stop_spec.rb47
-rw-r--r--spec/models/chouette/vehicle_journey_at_stops_are_in_increasing_time_order_validator_spec.rb67
-rw-r--r--spec/models/chouette/vehicle_journey_spec.rb12
-rw-r--r--spec/policies/application_policy_spec.rb6
-rw-r--r--spec/policies/boiv_policy_spec.rb15
-rw-r--r--spec/policies/line_policy_spec.rb18
-rw-r--r--spec/policies/route_policy_spec.rb22
-rw-r--r--spec/policies/routing_constraint_zone_policy_spec.rb22
-rw-r--r--spec/policies/time_table_policy_spec.rb32
-rw-r--r--spec/support/pundit.rb31
-rw-r--r--spec/support/pundit/policies.rb37
-rw-r--r--spec/support/pundit/pundit_view_policy.rb22
-rw-r--r--spec/support/pundit/shared_examples.rb60
-rw-r--r--spec/support/pundit_view_policy.rb20
61 files changed, 564 insertions, 227 deletions
diff --git a/app/assets/javascripts/es6_browserified/itineraries/containers/VisibleStopPoints.js b/app/assets/javascripts/es6_browserified/itineraries/containers/VisibleStopPoints.js
index 11c58d9c2..8b08a1e5f 100644
--- a/app/assets/javascripts/es6_browserified/itineraries/containers/VisibleStopPoints.js
+++ b/app/assets/javascripts/es6_browserified/itineraries/containers/VisibleStopPoints.js
@@ -25,6 +25,7 @@ const mapDispatchToProps = (dispatch) => {
onChange: (index, text) =>{
dispatch(actions.updateInputValue(index, text))
dispatch(actions.closeMaps())
+ dispatch(actions.toggleEdit(index))
},
onSelectChange: (e, index) =>{
dispatch(actions.updateSelectValue(e, index))
diff --git a/app/assets/javascripts/es6_browserified/time_tables/components/Metas.js b/app/assets/javascripts/es6_browserified/time_tables/components/Metas.js
index 502320c27..a0fac84f3 100644
--- a/app/assets/javascripts/es6_browserified/time_tables/components/Metas.js
+++ b/app/assets/javascripts/es6_browserified/time_tables/components/Metas.js
@@ -87,7 +87,7 @@ const Metas = ({metas, onUpdateDayTypes, onUpdateComment, onUpdateColor, onSelec
<div className="form-group">
<label htmlFor="" className="control-label col-sm-4">Modèle de calendrier associé</label>
<div className="col-sm-8">
- <span>{metas.calendar.name}</span>
+ <span>{metas.calendar ? metas.calendar.name : 'Aucun'}</span>
</div>
</div>
diff --git a/app/assets/javascripts/es6_browserified/time_tables/index.js b/app/assets/javascripts/es6_browserified/time_tables/index.js
index 1fe6ee84b..01f8c428e 100644
--- a/app/assets/javascripts/es6_browserified/time_tables/index.js
+++ b/app/assets/javascripts/es6_browserified/time_tables/index.js
@@ -30,7 +30,7 @@ var initialState = {
tags: [],
initial_tags: [],
color: '',
- calendar: {}
+ calendar: null
},
pagination: {
stateChanged: false,
diff --git a/app/assets/javascripts/es6_browserified/time_tables/reducers/metas.js b/app/assets/javascripts/es6_browserified/time_tables/reducers/metas.js
index 97de90225..4f1e7a528 100644
--- a/app/assets/javascripts/es6_browserified/time_tables/reducers/metas.js
+++ b/app/assets/javascripts/es6_browserified/time_tables/reducers/metas.js
@@ -10,15 +10,15 @@ const metas = (state = {}, action) => {
tags: action.json.tags,
initial_tags: action.json.tags,
color: action.json.color,
- calendar: action.json.calendar ? action.json.calendar : {name : 'Aucun'}
+ calendar: action.json.calendar ? action.json.calendar : null
})
case 'INCLUDE_DATE_IN_PERIOD':
case 'EXCLUDE_DATE_FROM_PERIOD':
case 'DELETE_PERIOD':
case 'VALIDATE_PERIOD_FORM':
- return _.assign({}, state, {calendar: {name: 'Aucun'}})
+ return _.assign({}, state, {calendar: null})
case 'UPDATE_DAY_TYPES':
- return _.assign({}, state, {day_types: action.dayTypes, calendar : {name: 'Aucun'}})
+ return _.assign({}, state, {day_types: action.dayTypes, calendar : null})
case 'UPDATE_COMMENT':
return _.assign({}, state, {comment: action.comment})
case 'UPDATE_COLOR':
diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/CreateModal.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/CreateModal.js
index 314d481d4..c1e40b3bc 100644
--- a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/CreateModal.js
+++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/CreateModal.js
@@ -77,6 +77,17 @@ class CreateModal extends Component {
/>
</div>
</div>
+ <div className='col-lg-6 col-md-6 col-sm-6 col-xs-12'>
+ <div className='form-group'>
+ <label className='control-label'>Numéro de train</label>
+ <input
+ type='text'
+ ref='published_journey_identifier'
+ className='form-control'
+ onKeyDown={(e) => actions.resetValidation(e.currentTarget)}
+ />
+ </div>
+ </div>
</div>
</div>
<div className='modal-footer'>
diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/TimetablesEditVehicleJourney.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/TimetablesEditVehicleJourney.js
index d6c1179ba..82fed23d9 100644
--- a/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/TimetablesEditVehicleJourney.js
+++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/components/tools/TimetablesEditVehicleJourney.js
@@ -84,17 +84,6 @@ class TimetablesEditVehicleJourney extends Component {
isFilter={false}
/>
</div>
- <div>
- <a
- href='#'
- title='Ajouter'
- className='fa fa-plus'
- onClick={(e) => {
- e.preventDefault()
- this.props.onAddSelectedTimetable()
- }}
- ></a>
- </div>
</div>
</div>
</div>
@@ -140,7 +129,6 @@ TimetablesEditVehicleJourney.propTypes = {
onTimetablesEditVehicleJourney: PropTypes.func.isRequired,
onDeleteCalendarModal: PropTypes.func.isRequired,
onSelect2Timetable: PropTypes.func.isRequired,
- onAddSelectedTimetable: PropTypes.func.isRequired,
filters: PropTypes.object.isRequired
}
diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/containers/tools/TimetablesEditVehicleJourney.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/containers/tools/TimetablesEditVehicleJourney.js
index 6d0096019..1cfff407c 100644
--- a/app/assets/javascripts/es6_browserified/vehicle_journeys/containers/tools/TimetablesEditVehicleJourney.js
+++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/containers/tools/TimetablesEditVehicleJourney.js
@@ -27,8 +27,6 @@ const mapDispatchToProps = (dispatch) => {
},
onSelect2Timetable: (e) =>{
dispatch(actions.selectTTCalendarsModal(e.params.data))
- },
- onAddSelectedTimetable: () => {
dispatch(actions.addSelectedTimetable())
}
}
diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/index.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/index.js
index 489446ab9..2a76ae43a 100644
--- a/app/assets/javascripts/es6_browserified/vehicle_journeys/index.js
+++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/index.js
@@ -8,10 +8,10 @@ var actions = require("./actions")
var enableBatching = require('./batch').enableBatching
// logger, DO NOT REMOVE
-var applyMiddleware = require('redux').applyMiddleware
-var createLogger = require('redux-logger')
-var thunkMiddleware = require('redux-thunk').default
-var promise = require('redux-promise')
+// var applyMiddleware = require('redux').applyMiddleware
+// var createLogger = require('redux-logger')
+// var thunkMiddleware = require('redux-thunk').default
+// var promise = require('redux-promise')
var selectedJP = []
@@ -85,12 +85,12 @@ if (window.jpOrigin){
initialState.filters.queryString = actions.encodeParams(params)
}
-const loggerMiddleware = createLogger()
+// const loggerMiddleware = createLogger()
let store = createStore(
enableBatching(vehicleJourneysApp),
- initialState,
- applyMiddleware(thunkMiddleware, promise, loggerMiddleware)
+ initialState
+ // applyMiddleware(thunkMiddleware, promise, loggerMiddleware)
)
render(
diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/modal.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/modal.js
index e504c2531..9f071069d 100644
--- a/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/modal.js
+++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/modal.js
@@ -88,9 +88,18 @@ const modal = (state = {}, action) => {
newModalProps.timetables = timetablesModal
return _.assign({}, state, {modalProps: newModalProps})
case 'CREATE_VEHICLEJOURNEY_MODAL':
+ let selectedJP = {}
+ if (window.jpOrigin){
+ selectedJP = {
+ id: window.jpOrigin.id,
+ name: window.jpOrigin.name,
+ published_name: window.jpOrigin.published_name,
+ objectid: window.jpOrigin.objectid
+ }
+ }
return {
type: 'create',
- modalProps: {},
+ modalProps: window.jpOrigin ? {selectedJPModal: selectedJP} : {},
confirmModal: {}
}
case 'SELECT_JP_CREATE_MODAL':
diff --git a/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/vehicleJourneys.js b/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/vehicleJourneys.js
index d153739ce..9dea63e07 100644
--- a/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/vehicleJourneys.js
+++ b/app/assets/javascripts/es6_browserified/vehicle_journeys/reducers/vehicleJourneys.js
@@ -36,6 +36,7 @@ const vehicleJourney= (state = {}, action, keep) => {
company: action.selectedCompany,
journey_pattern: action.selectedJourneyPattern,
published_journey_name: action.data.published_journey_name.value,
+ published_journey_identifier: action.data.published_journey_identifier.value,
objectid: '',
footnotes: [],
time_tables: [],
diff --git a/app/controllers/autocomplete_calendars_controller.rb b/app/controllers/autocomplete_calendars_controller.rb
index dbdd1a9fc..f85f529fc 100644
--- a/app/controllers/autocomplete_calendars_controller.rb
+++ b/app/controllers/autocomplete_calendars_controller.rb
@@ -2,6 +2,6 @@ class AutocompleteCalendarsController < ApplicationController
respond_to :json, :only => [:autocomplete]
def autocomplete
- @calendars = Calendar.search(params[:q]).result.paginate(page: params[:page])
+ @calendars = current_organisation.referentials.search(params[:q]).result.paginate(page: params[:page])
end
end
diff --git a/app/controllers/time_table_combinations_controller.rb b/app/controllers/time_table_combinations_controller.rb
index bbb262247..32f1818b0 100644
--- a/app/controllers/time_table_combinations_controller.rb
+++ b/app/controllers/time_table_combinations_controller.rb
@@ -5,6 +5,7 @@ class TimeTableCombinationsController < ChouetteController
def new
@combination = TimeTableCombination.new(source_id: parent.id)
+ @combination.combined_type = 'time_table'
end
def create
diff --git a/app/controllers/time_tables_controller.rb b/app/controllers/time_tables_controller.rb
index dcf8f3e5e..5c4552afb 100644
--- a/app/controllers/time_tables_controller.rb
+++ b/app/controllers/time_tables_controller.rb
@@ -43,7 +43,7 @@ class TimeTablesController < ChouetteController
if calendar
calendar.dates.each_with_index do |date, i|
- @time_table.dates << Chouette::TimeTableDate.new(date: date, position: i)
+ @time_table.dates << Chouette::TimeTableDate.new(date: date, position: i, in_out: true)
end
calendar.date_ranges.each_with_index do |date_range, i|
@time_table.periods << Chouette::TimeTablePeriod.new(period_start: date_range.begin, period_end: date_range.end, position: i)
diff --git a/app/models/chouette/time_table.rb b/app/models/chouette/time_table.rb
index eacc5c827..42879c6d5 100644
--- a/app/models/chouette/time_table.rb
+++ b/app/models/chouette/time_table.rb
@@ -64,7 +64,8 @@ class Chouette::TimeTable < Chouette::TridentActiveRecord
def state_update state
update_attributes(self.class.state_permited_attributes(state))
- self.tag_list = state['tags'].collect{|t| t['name']}.join(', ')
+ self.tag_list = state['tags'].collect{|t| t['name']}.join(', ')
+ self.calendar_id = nil unless state['calendar']
days = state['day_types'].split(',')
Date::DAYNAMES.map(&:underscore).each do |name|
diff --git a/app/models/chouette/vehicle_journey.rb b/app/models/chouette/vehicle_journey.rb
index d20a3d315..72d554e96 100644
--- a/app/models/chouette/vehicle_journey.rb
+++ b/app/models/chouette/vehicle_journey.rb
@@ -28,7 +28,8 @@ module Chouette
has_and_belongs_to_many :time_tables, :class_name => 'Chouette::TimeTable', :foreign_key => "vehicle_journey_id", :association_foreign_key => "time_table_id"
has_many :stop_points, -> { order("stop_points.position") }, :through => :vehicle_journey_at_stops
- validate :increasing_times
+ validates :vehicle_journey_at_stops,
+ vehicle_journey_at_stops_are_in_increasing_time_order: true
validates_presence_of :number
before_validation :set_default_values
@@ -156,14 +157,6 @@ module Chouette
attrs
end
- def increasing_times
- previous = nil
- vehicle_journey_at_stops.select{|vjas| vjas.departure_time && vjas.arrival_time}.each do |vjas|
- errors.add( :vehicle_journey_at_stops, 'time gap overflow') unless vjas.increasing_times_validate( previous)
- previous = vjas
- end
- end
-
def missing_stops_in_relation_to_a_journey_pattern(selected_journey_pattern)
selected_journey_pattern.stop_points - self.stop_points
end
diff --git a/app/models/chouette/vehicle_journey_at_stop.rb b/app/models/chouette/vehicle_journey_at_stop.rb
index 7d6414f55..553531422 100644
--- a/app/models/chouette/vehicle_journey_at_stop.rb
+++ b/app/models/chouette/vehicle_journey_at_stop.rb
@@ -16,8 +16,11 @@ module Chouette
# security against nil values
return unless arrival_time && departure_time
- if exceeds_gap?( arrival_time, departure_time)
- errors.add(:arrival_time,I18n.t("activerecord.errors.models.vehicle_journey_at_stop.arrival_must_be_before_departure"))
+ if TimeDuration.exceeds_gap?(4.hours, arrival_time, departure_time)
+ errors.add(
+ :arrival_time,
+ I18n.t("activerecord.errors.models.vehicle_journey_at_stop.arrival_must_be_before_departure")
+ )
end
end
@@ -26,23 +29,5 @@ module Chouette
@_destroy = false
end
- def increasing_times_validate( previous)
- result = true
- return result unless previous
-
- if exceeds_gap?( previous.departure_time, departure_time)
- result = false
- errors.add( :departure_time, 'departure time gap overflow')
- end
- if exceeds_gap?( previous.arrival_time, arrival_time)
- result = false
- errors.add( :arrival_time, 'arrival time gap overflow')
- end
- result
- end
- def exceeds_gap?(first, second)
- (4 * 3600) < ((second - first) % (3600 * 24))
- end
-
end
end
diff --git a/app/models/chouette/vehicle_journey_at_stops_are_in_increasing_time_order_validator.rb b/app/models/chouette/vehicle_journey_at_stops_are_in_increasing_time_order_validator.rb
new file mode 100644
index 000000000..95f0cdc3e
--- /dev/null
+++ b/app/models/chouette/vehicle_journey_at_stops_are_in_increasing_time_order_validator.rb
@@ -0,0 +1,50 @@
+module Chouette
+ class VehicleJourneyAtStopsAreInIncreasingTimeOrderValidator <
+ ActiveModel::EachValidator
+ def validate_each(vehicle_journey, attribute, value)
+ previous_at_stop = nil
+
+ vehicle_journey
+ .vehicle_journey_at_stops
+ .select { |vjas| vjas.departure_time && vjas.arrival_time }
+ .each do |vjas|
+ unless self.class.validate_at_stop_times_must_increase(
+ vjas,
+ previous_at_stop
+ )
+ vehicle_journey.errors.add(
+ :vehicle_journey_at_stops,
+ 'time gap overflow'
+ )
+ end
+
+ previous_at_stop = vjas
+ end
+ end
+
+ def self.validate_at_stop_times_must_increase(at_stop, previous_at_stop)
+ valid = true
+ return valid unless previous_at_stop
+
+ if TimeDuration.exceeds_gap?(
+ 4.hours,
+ previous_at_stop.departure_time,
+ at_stop.departure_time
+ )
+ valid = false
+ at_stop.errors.add(:departure_time, 'departure time gap overflow')
+ end
+
+ if TimeDuration.exceeds_gap?(
+ 4.hours,
+ previous_at_stop.arrival_time,
+ at_stop.arrival_time
+ )
+ valid = false
+ at_stop.errors.add(:arrival_time, 'arrival time gap overflow')
+ end
+
+ valid
+ end
+ end
+end
diff --git a/app/models/time_table_combination.rb b/app/models/time_table_combination.rb
index 9b5111014..0ca9e9253 100644
--- a/app/models/time_table_combination.rb
+++ b/app/models/time_table_combination.rb
@@ -31,7 +31,6 @@ class TimeTableCombination
attributes.each do |name, value|
send("#{name}=", value)
end
- self.combined_type = "time_table"
end
def persisted?
@@ -40,7 +39,7 @@ class TimeTableCombination
def target
id = self.send("#{combined_type}_id")
- klass = combined_type == 'calendar' ? Calendar : Chouette::TimeTable
+ klass = combined_type == "calendar" ? Calendar : Chouette::TimeTable
target = klass.find id
target = target.convert_to_time_table unless target.is_a? Chouette::TimeTable
target
diff --git a/app/models/user.rb b/app/models/user.rb
index 1230a64a1..14dbeb4d7 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -1,4 +1,3 @@
-# coding: utf-8
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable, :database_authenticatable
@@ -52,7 +51,7 @@ class User < ActiveRecord::Base
raise 'Rails.application.config.stif_portail_api settings is not defined' unless conf
conn = Faraday.new(:url => conf[:url]) do |c|
- c.headers['Authorization'] = "Token token=\"#{conf[:key]}\""
+ c.headers['Authorization'] = %{Token token="#{conf[:key]}"}
c.adapter Faraday.default_adapter
end
@@ -73,6 +72,7 @@ class User < ActiveRecord::Base
user.organisation = Organisation.sync_update el['organization_code'], el['organization_name'], el['functional_scope']
user.synced_at = Time.now
user.permissions = el['permissions'].include?('boiv:edit-offer') ? @@edit_offer_permissions : []
+ user.permissions += el['permissions'].grep( %r{^\Aboiv:read-offer\z} )
user.save
puts "✓ user #{user.username} has been updated" unless Rails.env.test?
end
diff --git a/app/policies/acces_point_policy.rb b/app/policies/acces_point_policy.rb
index 904b7a242..08af5981a 100644
--- a/app/policies/acces_point_policy.rb
+++ b/app/policies/acces_point_policy.rb
@@ -1,4 +1,4 @@
-class AccessPointPolicy < ApplicationPolicy
+class AccessPointPolicy < BoivPolicy
class Scope < Scope
def resolve
scope
diff --git a/app/policies/access_link_policy.rb b/app/policies/access_link_policy.rb
index 73b2d1baa..654739d06 100644
--- a/app/policies/access_link_policy.rb
+++ b/app/policies/access_link_policy.rb
@@ -1,4 +1,4 @@
-class AccessLinkPolicy < ApplicationPolicy
+class AccessLinkPolicy < BoivPolicy
class Scope < Scope
def resolve
scope
diff --git a/app/policies/application_policy.rb b/app/policies/application_policy.rb
index 4a2d760fb..a863404ae 100644
--- a/app/policies/application_policy.rb
+++ b/app/policies/application_policy.rb
@@ -7,7 +7,10 @@ class ApplicationPolicy
@record = record
end
- attr_accessor :referential
+ def archived?
+ !!referential.try(:archived_at)
+ end
+
def referential
@referential ||= record_referential
end
@@ -48,6 +51,10 @@ class ApplicationPolicy
Pundit.policy_scope!(user, record.class)
end
+ def boiv_read_offer?
+ organisation_match? && user.has_permission?('boiv:read-offer')
+ end
+
def organisation_match?
user.organisation == organisation
end
diff --git a/app/policies/boiv_policy.rb b/app/policies/boiv_policy.rb
new file mode 100644
index 000000000..4270dc686
--- /dev/null
+++ b/app/policies/boiv_policy.rb
@@ -0,0 +1,15 @@
+require_relative 'chain'
+class BoivPolicy < ApplicationPolicy
+
+ def boiv_read_offer?
+ organisation_match? && user.has_permission?('boiv:read-offer')
+ end
+
+ def index?
+ boiv_read_offer?
+ end
+
+ def show?
+ boiv_read_offer?
+ end
+end
diff --git a/app/policies/calendar_policy.rb b/app/policies/calendar_policy.rb
index 4248bccc7..9d6b09a9b 100644
--- a/app/policies/calendar_policy.rb
+++ b/app/policies/calendar_policy.rb
@@ -1,4 +1,4 @@
-class CalendarPolicy < ApplicationPolicy
+class CalendarPolicy < BoivPolicy
class Scope < Scope
def resolve
scope
diff --git a/app/policies/chain.rb b/app/policies/chain.rb
new file mode 100644
index 000000000..4bf96bd84
--- /dev/null
+++ b/app/policies/chain.rb
@@ -0,0 +1,57 @@
+module Policies
+ # Implements the `chain_policies` macro as follows
+ #
+ # chain_policies <method_chain>, policies:
+ #
+ # e.g.
+ #
+ # chain_policies [:archived?, :!], policies: %i{create? edit?}
+ #
+ # which would establish a precondition `not archived` for the `create?` and `edit?`
+ # method, it is semantically identical to instrumenting both methods
+ # as follows:
+ #
+ # def create? # or edit?
+ # archived?.! && <original code of method>
+ # end
+ module Chain
+
+ # A local chain store implemented to avoid any possible side effect on client policies.
+ defined_chains = {}
+
+ # Using `define_method` in order to close over `defined_chains`
+ # We need to store the chains because the methods they will apply to
+ # are not defined yet.
+ define_method :chain_policies do |*conditions, policies:|
+ policies.each do | meth_name |
+ # self represents the client Policy
+ defined_chains[[self, meth_name]] = conditions
+ end
+ end
+ # Intercept method definition and check if a policy_chain has been registered for it‥.
+ define_method :method_added do |meth_name, *args, &blk|
+ # Delete potentially registered criteria conditions to‥.
+ # (i) protect against endless recursion via (:merthod_added → :define_method → :method_added → ‥.
+ # (ii) get the condition
+ conditions = defined_chains.delete([self, meth_name])
+ return unless conditions
+
+ instrument_method(meth_name, conditions)
+ end
+
+ private
+
+ # Access to the closure is not necessary anymore, normal metaprogramming can take place :)
+ def instrument_method(meth_name, conditions)
+ orig_method = instance_method(meth_name)
+ # In case of warnings remove original method here, depends on Ruby Version, ok in 2.3.1
+ define_method meth_name do |*a, &b|
+ # Method chain describing the chained policy precondition.
+ conditions.inject(self) do | result, msg |
+ result.send msg
+ end &&
+ orig_method.bind(self).(*a, &b)
+ end
+ end
+ end
+end
diff --git a/app/policies/company_policy.rb b/app/policies/company_policy.rb
index d28e9b515..95d607f3d 100644
--- a/app/policies/company_policy.rb
+++ b/app/policies/company_policy.rb
@@ -1,4 +1,4 @@
-class CompanyPolicy < ApplicationPolicy
+class CompanyPolicy < BoivPolicy
class Scope < Scope
def resolve
scope
diff --git a/app/policies/connection_link_policy.rb b/app/policies/connection_link_policy.rb
index abefd741c..21414efb9 100644
--- a/app/policies/connection_link_policy.rb
+++ b/app/policies/connection_link_policy.rb
@@ -1,4 +1,4 @@
-class ConnectionLinkPolicy < ApplicationPolicy
+class ConnectionLinkPolicy < BoivPolicy
class Scope < Scope
def resolve
scope
diff --git a/app/policies/group_of_line_policy.rb b/app/policies/group_of_line_policy.rb
index 5d42a23bd..86d522545 100644
--- a/app/policies/group_of_line_policy.rb
+++ b/app/policies/group_of_line_policy.rb
@@ -1,4 +1,4 @@
-class GroupOfLinePolicy < ApplicationPolicy
+class GroupOfLinePolicy < BoivPolicy
class Scope < Scope
def resolve
scope
diff --git a/app/policies/journey_pattern_policy.rb b/app/policies/journey_pattern_policy.rb
index 56f32613c..9d13624c5 100644
--- a/app/policies/journey_pattern_policy.rb
+++ b/app/policies/journey_pattern_policy.rb
@@ -1,4 +1,4 @@
-class JourneyPatternPolicy < ApplicationPolicy
+class JourneyPatternPolicy < BoivPolicy
class Scope < Scope
def resolve
scope
diff --git a/app/policies/line_policy.rb b/app/policies/line_policy.rb
index 2ea1ecda9..c3e0051c8 100644
--- a/app/policies/line_policy.rb
+++ b/app/policies/line_policy.rb
@@ -1,4 +1,9 @@
-class LinePolicy < ApplicationPolicy
+require_relative 'chain'
+class LinePolicy < BoivPolicy
+ extend Policies::Chain
+
+ chain_policies :archived?, :!, policies: %i{create_footnote? destroy_footnote? edit_footnote?}
+
class Scope < Scope
def resolve
scope
@@ -22,7 +27,7 @@ class LinePolicy < ApplicationPolicy
end
def destroy_footnote?
- user.has_permission?('routes.destroy')
+ user.has_permission?('footnotes.destroy')
end
def update_footnote? ; edit_footnote? end
diff --git a/app/policies/network_policy.rb b/app/policies/network_policy.rb
index 427eace93..4c1ea1090 100644
--- a/app/policies/network_policy.rb
+++ b/app/policies/network_policy.rb
@@ -1,4 +1,4 @@
-class NetworkPolicy < ApplicationPolicy
+class NetworkPolicy < BoivPolicy
class Scope < Scope
def resolve
scope
diff --git a/app/policies/referential_policy.rb b/app/policies/referential_policy.rb
index 8d366aff7..4a5e85ead 100644
--- a/app/policies/referential_policy.rb
+++ b/app/policies/referential_policy.rb
@@ -1,4 +1,4 @@
-class ReferentialPolicy < ApplicationPolicy
+class ReferentialPolicy < BoivPolicy
class Scope < Scope
def resolve
scope
diff --git a/app/policies/route_policy.rb b/app/policies/route_policy.rb
index c4d048f2a..dba3a27da 100644
--- a/app/policies/route_policy.rb
+++ b/app/policies/route_policy.rb
@@ -1,10 +1,13 @@
-class RoutePolicy < ApplicationPolicy
+class RoutePolicy < BoivPolicy
+ extend Policies::Chain
class Scope < Scope
def resolve
scope
end
end
+ chain_policies :archived?, :!, policies: %i{create? destroy? edit?}
+
def create?
user.has_permission?('routes.create') # organisation match via referential is checked in the view
end
diff --git a/app/policies/routing_constraint_zone_policy.rb b/app/policies/routing_constraint_zone_policy.rb
index 3126241f0..abba5639c 100644
--- a/app/policies/routing_constraint_zone_policy.rb
+++ b/app/policies/routing_constraint_zone_policy.rb
@@ -1,10 +1,13 @@
-class RoutingConstraintZonePolicy < ApplicationPolicy
+class RoutingConstraintZonePolicy < BoivPolicy
+ extend Policies::Chain
class Scope < Scope
def resolve
scope
end
end
+ chain_policies :archived?, :!, policies: %i{create? destroy? edit?}
+
def create?
user.has_permission?('routing_constraint_zones.create') # organisation match via referential is checked in the view
end
diff --git a/app/policies/stop_area_policy.rb b/app/policies/stop_area_policy.rb
index 4fa426ff6..79b7178ce 100644
--- a/app/policies/stop_area_policy.rb
+++ b/app/policies/stop_area_policy.rb
@@ -1,4 +1,4 @@
-class StopAreaPolicy < ApplicationPolicy
+class StopAreaPolicy < BoivPolicy
class Scope < Scope
def resolve
scope
diff --git a/app/policies/time_table_policy.rb b/app/policies/time_table_policy.rb
index 82e4ca194..efab6ac00 100644
--- a/app/policies/time_table_policy.rb
+++ b/app/policies/time_table_policy.rb
@@ -1,24 +1,28 @@
-class TimeTablePolicy < ApplicationPolicy
+class TimeTablePolicy < BoivPolicy
+ extend Policies::Chain
+
class Scope < Scope
def resolve
scope
end
end
+ chain_policies :archived?, :!, policies: %i{create? destroy? duplicate? edit?}
+
def create?
- user.has_permission?('time_tables.create') # organisation match via referential is checked in the view
+ user.has_permission?('time_tables.create') # organisation match via referential is checked in the view
end
def edit?
- organisation_match? && user.has_permission?('time_tables.edit')
+ organisation_match? && user.has_permission?('time_tables.edit')
end
def destroy?
- organisation_match? && user.has_permission?('time_tables.destroy')
+ organisation_match? && user.has_permission?('time_tables.destroy')
end
def duplicate?
- organisation_match? && create?
+ organisation_match? && create?
end
def update? ; edit? end
diff --git a/app/policies/vehicle_journey_policy.rb b/app/policies/vehicle_journey_policy.rb
index ae3680adf..de6dd7088 100644
--- a/app/policies/vehicle_journey_policy.rb
+++ b/app/policies/vehicle_journey_policy.rb
@@ -1,4 +1,4 @@
-class VehicleJourneyPolicy < ApplicationPolicy
+class VehicleJourneyPolicy < BoivPolicy
class Scope < Scope
def resolve
scope
diff --git a/app/views/referential_lines/_filters.html.slim b/app/views/referential_lines/_filters.html.slim
index aa355884b..93d449507 100644
--- a/app/views/referential_lines/_filters.html.slim
+++ b/app/views/referential_lines/_filters.html.slim
@@ -9,7 +9,7 @@
.ffg-row
.form-group.togglable
= f.label Chouette::Route.human_attribute_name(:wayback), required: false, class: 'control-label'
- = f.input :wayback_eq_any, as: :checkboxes, class: 'form-control', collection: Chouette::Route.wayback.values, as: :check_boxes, label: false, required: false, wrapper_html: { class: 'checkbox_list'}, label_method: lambda{|l| ("<span>" + t("enumerize.route.wayback.#{l}") + "</span>").html_safe}
+ = f.input :wayback_eq_any, class: 'form-control', collection: Chouette::Route.wayback.values, as: :check_boxes, label: false, required: false, wrapper_html: { class: 'checkbox_list'}, label_method: lambda{|l| ("<span>" + t("enumerize.route.wayback.#{l}") + "</span>").html_safe}
.actions
= link_to 'Effacer', referential_line_path(@referential, @line), class: 'btn btn-link'
diff --git a/app/views/time_table_combinations/_form.html.slim b/app/views/time_table_combinations/_form.html.slim
index 3716f6713..d8bebf0c4 100644
--- a/app/views/time_table_combinations/_form.html.slim
+++ b/app/views/time_table_combinations/_form.html.slim
@@ -8,7 +8,7 @@
= f.input :combined_type, as: :boolean, checked_value: 'time_table', unchecked_value: 'calendar', required: false, label: content_tag(:span, t("time_table_combinations.combined_type.#{@combination.combined_type}"), class: 'switch-label', data: { checkedValue: 'Calendriers', uncheckedValue: 'Modèles de calendriers' }), wrapper_html: { class: 'col-sm-8' }
= f.input :time_table_id, as: :select, input_html: {class: 'tt_combination_target', style: "width: 100%", data: { 'select2-ajax': 'true', term: 'comment_or_objectid_cont', url: referential_autocomplete_time_tables_path(@referential, format: :json)}}, wrapper_html: {class: @combination.combined_type != 'time_table' ? 'hidden' : ''}
-
+
= f.input :calendar_id, as: :select, input_html: { class: 'tt_combination_target', style: "width: 100%", data: { 'select2-ajax': 'true', term: 'name_cont', url: autocomplete_calendars_path}}, wrapper_html: {class: @combination.combined_type != 'calendar' ? 'hidden' : ''}
.separator
diff --git a/app/views/time_tables/_form.html.slim b/app/views/time_tables/_form.html.slim
index 196682823..d4e1d838e 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, as: :select, collection: current_organisation.calendars
+ = form.input :calendar_id, as: :select, collection: current_organisation.calendars
- if @time_table.created_from
= form.input :created_from, disabled: true, input_html: { value: @time_table.created_from.comment }
diff --git a/lib/time_duration.rb b/lib/time_duration.rb
new file mode 100644
index 000000000..12419fdc8
--- /dev/null
+++ b/lib/time_duration.rb
@@ -0,0 +1,20 @@
+module TimeDuration
+ # `earlier` and `later` are times. Get the duration between those times and
+ # check whether it's longer than the given `duration`.
+ #
+ # Example:
+ # TimeDuration.exceeds_gap?(
+ # 4.hours,
+ # Time.now,
+ # Time.now + 2.hours
+ # )
+ def self.exceeds_gap?(duration, earlier, later)
+ duration < self.duration_without_24_hour_cycles(later - earlier)
+ end
+
+ private
+
+ def self.duration_without_24_hour_cycles(duration)
+ duration % 24.hours
+ end
+end
diff --git a/spec/features/line_footnotes_spec.rb b/spec/features/line_footnotes_spec.rb
index 4d77cba41..6a359ad50 100644
--- a/spec/features/line_footnotes_spec.rb
+++ b/spec/features/line_footnotes_spec.rb
@@ -1,6 +1,3 @@
-# -*- coding: utf-8 -*-
-require 'spec_helper'
-
describe 'Line Footnotes', type: :feature do
login_user
diff --git a/spec/features/time_tables_spec.rb b/spec/features/time_tables_spec.rb
index 06ae9bac3..58a1dc98f 100644
--- a/spec/features/time_tables_spec.rb
+++ b/spec/features/time_tables_spec.rb
@@ -67,6 +67,10 @@ describe "TimeTables", :type => :feature do
expect(page).to have_content(time_tables.first.comment)
end
+ it 'should not show actualize link on time_tabl without calendar' do
+ expect(page).not_to have_content(I18n.t('time_tables.actions.actualize'))
+ end
+
# context 'user has permission to create time tables' do
# it 'shows a create link for time tables' do
# expect(page).to have_content(I18n.t('time_tables.actions.new'))
diff --git a/spec/javascripts/time_table/reducers/metas_spec.js b/spec/javascripts/time_table/reducers/metas_spec.js
index 79dbe1ea3..5ec7a0034 100644
--- a/spec/javascripts/time_table/reducers/metas_spec.js
+++ b/spec/javascripts/time_table/reducers/metas_spec.js
@@ -30,7 +30,7 @@ describe('metas reducer', () => {
type: 'UPDATE_DAY_TYPES',
dayTypes: arr
})
- ).toEqual(Object.assign({}, state, {day_types: arr, calendar: {name: 'Aucun'}}))
+ ).toEqual(Object.assign({}, state, {day_types: arr, calendar: null}))
})
it('should handle UPDATE_COMMENT', () => {
diff --git a/spec/javascripts/vehicle_journeys/reducers/vehicle_journeys_spec.js b/spec/javascripts/vehicle_journeys/reducers/vehicle_journeys_spec.js
index f805852c7..662c3d82f 100644
--- a/spec/javascripts/vehicle_journeys/reducers/vehicle_journeys_spec.js
+++ b/spec/javascripts/vehicle_journeys/reducers/vehicle_journeys_spec.js
@@ -88,7 +88,8 @@ describe('vehicleJourneys reducer', () => {
dummy: true
}]
let fakeData = {
- published_journey_name: {value: 'test'}
+ published_journey_name: {value: 'test'},
+ published_journey_identifier: {value : ''}
}
let fakeSelectedJourneyPattern = {id: "1"}
let fakeSelectedCompany = {name: "ALBATRANS"}
@@ -104,6 +105,7 @@ describe('vehicleJourneys reducer', () => {
journey_pattern: fakeSelectedJourneyPattern,
company: fakeSelectedCompany,
published_journey_name: 'test',
+ published_journey_identifier: '',
objectid: '',
footnotes: [],
time_tables: [],
diff --git a/spec/lib/time_duration_spec.rb b/spec/lib/time_duration_spec.rb
new file mode 100644
index 000000000..1cba1f6d5
--- /dev/null
+++ b/spec/lib/time_duration_spec.rb
@@ -0,0 +1,33 @@
+require 'spec_helper'
+
+describe TimeDuration do
+ describe ".exceeds_gap?" do
+ context "when duration is 4.hours" do
+ it "should return false if gap < 1.hour" do
+ t1 = Time.now
+ t2 = Time.now + 3.minutes
+ expect(TimeDuration.exceeds_gap?(4.hours, t1, t2)).to be_falsey
+ end
+
+ it "should return true if gap > 4.hour" do
+ t1 = Time.now
+ t2 = Time.now + (4.hours + 1.minutes)
+ expect(TimeDuration.exceeds_gap?(4.hours, t1, t2)).to be_truthy
+ end
+
+ it "returns true when `earlier` is later than `later`" do
+ earlier = Time.new(2000, 1, 1, 11, 0, 0, 0)
+ later = Time.new(2000, 1, 1, 12, 0, 0, 0)
+
+ expect(TimeDuration.exceeds_gap?(4.hours, later, earlier)).to be true
+ end
+
+ it "returns false when `earlier` == `later`" do
+ earlier = Time.new(2000, 1, 1, 1, 0, 0, 0)
+ later = earlier
+
+ expect(TimeDuration.exceeds_gap?(4.hours, later, earlier)).to be false
+ end
+ end
+ end
+end
diff --git a/spec/models/chouette/time_table_spec.rb b/spec/models/chouette/time_table_spec.rb
index 505ca12be..3d45bd346 100644
--- a/spec/models/chouette/time_table_spec.rb
+++ b/spec/models/chouette/time_table_spec.rb
@@ -51,6 +51,15 @@ describe Chouette::TimeTable, :type => :model do
}.to change {subject.periods.count}.by(-1)
end
+ it 'should update caldendar association' do
+ subject.calendar = create(:calendar)
+ subject.save
+ state['calendar'] = nil
+
+ subject.state_update state
+ expect(subject.reload.calendar).to eq(nil)
+ end
+
it 'should update color' do
state['color'] = '#FFA070'
subject.state_update state
diff --git a/spec/models/chouette/vehicle_journey_at_stop_spec.rb b/spec/models/chouette/vehicle_journey_at_stop_spec.rb
deleted file mode 100644
index fbd544a28..000000000
--- a/spec/models/chouette/vehicle_journey_at_stop_spec.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-require 'spec_helper'
-require 'pp'
-
-describe Chouette::VehicleJourneyAtStop, :type => :model do
- let!(:vehicle_journey) { create(:vehicle_journey_odd)}
- subject { vehicle_journey.vehicle_journey_at_stops.first }
-
- describe "#exceeds_gap?" do
- it "should return false if gap < 1.hour" do
- t1 = Time.now
- t2 = Time.now + 3.minutes
- expect(subject.exceeds_gap?(t1, t2)).to be_falsey
- end
- it "should return true if gap > 4.hour" do
- t1 = Time.now
- t2 = Time.now + (4.hours + 1.minutes)
- expect(subject.exceeds_gap?(t1, t2)).to be_truthy
- end
- end
-
- describe "#increasing_times_validate" do
- let(:vjas1){ vehicle_journey.vehicle_journey_at_stops[0]}
- let(:vjas2){ vehicle_journey.vehicle_journey_at_stops[1]}
- context "when vjas#arrival_time exceeds gap" do
- it "should add errors on arrival_time" do
- vjas1.arrival_time = vjas2.arrival_time - 5.hour
- expect(vjas2.increasing_times_validate(vjas1)).to be_falsey
- expect(vjas2.errors).not_to be_empty
- expect(vjas2.errors[:arrival_time]).not_to be_blank
- end
- end
- context "when vjas#departure_time exceeds gap" do
- it "should add errors on departure_time" do
- vjas1.departure_time = vjas2.departure_time - 5.hour
- expect(vjas2.increasing_times_validate(vjas1)).to be_falsey
- expect(vjas2.errors).not_to be_empty
- expect(vjas2.errors[:departure_time]).not_to be_blank
- end
- end
- context "when vjas does'nt exceed gap" do
- it "should not add errors" do
- expect(vjas2.increasing_times_validate(vjas1)).to be_truthy
- expect(vjas2.errors).to be_empty
- end
- end
- end
-end
diff --git a/spec/models/chouette/vehicle_journey_at_stops_are_in_increasing_time_order_validator_spec.rb b/spec/models/chouette/vehicle_journey_at_stops_are_in_increasing_time_order_validator_spec.rb
new file mode 100644
index 000000000..c30e0dbd8
--- /dev/null
+++ b/spec/models/chouette/vehicle_journey_at_stops_are_in_increasing_time_order_validator_spec.rb
@@ -0,0 +1,67 @@
+require 'spec_helper'
+
+describe Chouette::VehicleJourneyAtStopsAreInIncreasingTimeOrderValidator do
+ subject { create(:vehicle_journey_odd) }
+
+ describe "#validate" do
+ before(:each) do
+ subject.vehicle_journey_at_stops[0].departure_time =
+ subject.vehicle_journey_at_stops[1].departure_time - 5.hour
+ subject.vehicle_journey_at_stops[0].arrival_time =
+ subject.vehicle_journey_at_stops[0].departure_time
+ subject.vehicle_journey_at_stops[1].arrival_time =
+ subject.vehicle_journey_at_stops[1].departure_time
+ end
+
+ it "should make instance invalid if departure time exceeds gap" do
+ subject.validate
+
+ expect(
+ subject.vehicle_journey_at_stops[1].errors[:departure_time]
+ ).not_to be_blank
+ expect(subject).not_to be_valid
+ end
+ end
+
+ describe ".validate_at_stop_times_must_increase" do
+ let!(:vehicle_journey) { create(:vehicle_journey_odd) }
+ subject { vehicle_journey.vehicle_journey_at_stops.first }
+
+ let(:vjas1) { vehicle_journey.vehicle_journey_at_stops[0] }
+ let(:vjas2) { vehicle_journey.vehicle_journey_at_stops[1] }
+
+ context "when vjas#arrival_time exceeds gap" do
+ it "should add errors on arrival_time" do
+ vjas1.arrival_time = vjas2.arrival_time - 5.hour
+ expect(
+ Chouette::VehicleJourneyAtStopsAreInIncreasingTimeOrderValidator
+ .validate_at_stop_times_must_increase(vjas2, vjas1)
+ ).to be_falsey
+ expect(vjas2.errors).not_to be_empty
+ expect(vjas2.errors[:arrival_time]).not_to be_blank
+ end
+ end
+
+ context "when vjas#departure_time exceeds gap" do
+ it "should add errors on departure_time" do
+ vjas1.departure_time = vjas2.departure_time - 5.hour
+ expect(
+ Chouette::VehicleJourneyAtStopsAreInIncreasingTimeOrderValidator
+ .validate_at_stop_times_must_increase(vjas2, vjas1)
+ ).to be_falsey
+ expect(vjas2.errors).not_to be_empty
+ expect(vjas2.errors[:departure_time]).not_to be_blank
+ end
+ end
+
+ context "when vjas doesn't exceed gap" do
+ it "should not add errors" do
+ expect(
+ Chouette::VehicleJourneyAtStopsAreInIncreasingTimeOrderValidator
+ .validate_at_stop_times_must_increase(vjas2, vjas1)
+ ).to be_truthy
+ expect(vjas2.errors).to be_empty
+ end
+ end
+ end
+end
diff --git a/spec/models/chouette/vehicle_journey_spec.rb b/spec/models/chouette/vehicle_journey_spec.rb
index ed76c278c..4a108d7c0 100644
--- a/spec/models/chouette/vehicle_journey_spec.rb
+++ b/spec/models/chouette/vehicle_journey_spec.rb
@@ -466,18 +466,6 @@ describe Chouette::VehicleJourney, :type => :model do
end
context "when following departure times exceeds gap" do
- describe "#increasing_times" do
- before(:each) do
- subject.vehicle_journey_at_stops[0].departure_time = subject.vehicle_journey_at_stops[1].departure_time - 5.hour
- subject.vehicle_journey_at_stops[0].arrival_time = subject.vehicle_journey_at_stops[0].departure_time
- subject.vehicle_journey_at_stops[1].arrival_time = subject.vehicle_journey_at_stops[1].departure_time
- end
- it "should make instance invalid" do
- subject.increasing_times
- expect(subject.vehicle_journey_at_stops[1].errors[:departure_time]).not_to be_blank
- expect(subject).not_to be_valid
- end
- end
describe "#update_attributes" do
let!(:params){ {"vehicle_journey_at_stops_attributes" => {
"0"=>{"id" => subject.vehicle_journey_at_stops[0].id ,"arrival_time" => 1.minutes.ago,"departure_time" => 1.minutes.ago},
diff --git a/spec/policies/application_policy_spec.rb b/spec/policies/application_policy_spec.rb
index d7e8e5e27..a7234461e 100644
--- a/spec/policies/application_policy_spec.rb
+++ b/spec/policies/application_policy_spec.rb
@@ -1,11 +1,6 @@
RSpec.describe ApplicationPolicy, type: :policy do
- subject { described_class }
-
permissions :organisation_match? do
- let( :user_context ) { create_user_context(user: user, referential: referential) }
- let( :referentail ) { create :referential }
- let( :user ) { create :user }
it "denies a user with a different organisation" do
expect_it.not_to permit(user_context, referential)
@@ -16,4 +11,5 @@ RSpec.describe ApplicationPolicy, type: :policy do
expect_it.to permit(user_context, referential)
end
end
+
end
diff --git a/spec/policies/boiv_policy_spec.rb b/spec/policies/boiv_policy_spec.rb
new file mode 100644
index 000000000..bf09cdcd9
--- /dev/null
+++ b/spec/policies/boiv_policy_spec.rb
@@ -0,0 +1,15 @@
+RSpec.describe BoivPolicy, type: :policy do
+
+ permissions :index? do
+ it_behaves_like 'permitted policy and same organisation', 'boiv:read-offer'
+ end
+
+ permissions :boiv_read_offer? do
+ it_behaves_like 'permitted policy and same organisation', 'boiv:read-offer'
+ end
+
+ permissions :show? do
+ it_behaves_like 'permitted policy and same organisation', 'boiv:read-offer'
+ end
+
+end
diff --git a/spec/policies/line_policy_spec.rb b/spec/policies/line_policy_spec.rb
new file mode 100644
index 000000000..ead5918aa
--- /dev/null
+++ b/spec/policies/line_policy_spec.rb
@@ -0,0 +1,18 @@
+RSpec.describe LinePolicy, type: :policy do
+
+ %w{create destroy edit}.each do | permission |
+ footnote_permission = "#{permission}_footnote"
+ permissions "#{footnote_permission}?".to_sym do
+ it_behaves_like 'permitted policy', "footnotes.#{permission}", archived: true
+ end
+ end
+
+ permissions :new_footnote? do
+ it_behaves_like 'permitted policy', 'footnotes.create', archived: true
+ end
+
+ permissions :update_footnote? do
+ it_behaves_like 'permitted policy', 'footnotes.edit', archived: true
+ end
+
+end
diff --git a/spec/policies/route_policy_spec.rb b/spec/policies/route_policy_spec.rb
new file mode 100644
index 000000000..baf14c9fc
--- /dev/null
+++ b/spec/policies/route_policy_spec.rb
@@ -0,0 +1,22 @@
+RSpec.describe RoutePolicy, type: :policy do
+
+ permissions :create? do
+ it_behaves_like 'permitted policy', 'routes.create', archived: true
+ end
+
+ permissions :destroy? do
+ it_behaves_like 'permitted policy and same organisation', 'routes.destroy', archived: true
+ end
+
+ permissions :edit? do
+ it_behaves_like 'permitted policy and same organisation', 'routes.edit', archived: true
+ end
+
+ permissions :new? do
+ it_behaves_like 'permitted policy', 'routes.create', archived: true
+ end
+
+ permissions :update? do
+ it_behaves_like 'permitted policy and same organisation', 'routes.edit', archived: true
+ end
+end
diff --git a/spec/policies/routing_constraint_zone_policy_spec.rb b/spec/policies/routing_constraint_zone_policy_spec.rb
new file mode 100644
index 000000000..4b0f2cafe
--- /dev/null
+++ b/spec/policies/routing_constraint_zone_policy_spec.rb
@@ -0,0 +1,22 @@
+RSpec.describe RoutingConstraintZonePolicy, type: :policy do
+
+ permissions :create? do
+ it_behaves_like 'permitted policy', 'routing_constraint_zones.create', archived: true
+ end
+
+ permissions :destroy? do
+ it_behaves_like 'permitted policy and same organisation', 'routing_constraint_zones.destroy', archived: true
+ end
+
+ permissions :edit? do
+ it_behaves_like 'permitted policy and same organisation', 'routing_constraint_zones.edit', archived: true
+ end
+
+ permissions :new? do
+ it_behaves_like 'permitted policy', 'routing_constraint_zones.create', archived: true
+ end
+
+ permissions :update? do
+ it_behaves_like 'permitted policy and same organisation', 'routing_constraint_zones.edit', archived: true
+ end
+end
diff --git a/spec/policies/time_table_policy_spec.rb b/spec/policies/time_table_policy_spec.rb
index 63bd316e4..1283a9fcf 100644
--- a/spec/policies/time_table_policy_spec.rb
+++ b/spec/policies/time_table_policy_spec.rb
@@ -1,26 +1,18 @@
RSpec.describe TimeTablePolicy, type: :policy do
permissions :duplicate? do
- context "user of a different organisation" do
- it "is denied" do
- expect_it.not_to permit(user_context, referential)
- end
- it "even if she has the time_tables.create permission" do
- add_permissions 'time_tables.create', for_user: user
- expect_it.not_to permit(user_context, referential)
- end
- end
- context "user of the same organisation" do
- before do
- user.update_attribute :organisation, referential.organisation
- end
- it "is denied" do
- expect_it.not_to permit(user_context, referential)
- end
- it "unless she has the time_tables.create permission" do
- add_permissions 'time_tables.create', for_user: user
- expect_it.to permit(user_context, referential)
- end
+ it_behaves_like 'permitted policy and same organisation', 'time_tables.create', archived: true
+ end
+
+ %w{destroy edit}.each do | permission |
+ permissions "#{permission}?".to_sym do
+ it_behaves_like 'permitted policy and same organisation', "time_tables.#{permission}", archived: true
end
end
+
+ permissions :create? do
+ it_behaves_like 'permitted policy', 'time_tables.create', archived: true
+ end
+
+
end
diff --git a/spec/support/pundit.rb b/spec/support/pundit.rb
deleted file mode 100644
index d818ce754..000000000
--- a/spec/support/pundit.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-require 'pundit/rspec'
-
-module Support
- module ApplicationPolicy
- def add_permissions(*permissions, for_user:)
- for_user.permissions ||= []
- for_user.permissions += permissions.flatten
- end
-
- def create_user_context(user:, referential:)
- OpenStruct.new(user: user, context: {referential: referential})
- end
- end
-
- module ApplicationPolicyMacros
- def self.extended into
- into.module_eval do
- subject { described_class }
- let( :user_context ) { create_user_context(user: user, referential: referential) }
- let( :referentail ) { create :referential }
- let( :user ) { create :user }
- end
- end
-
- end
-end
-
-RSpec.configure do | c |
- c.include Support::ApplicationPolicy, type: :policy
- c.extend Support::ApplicationPolicyMacros, type: :policy
-end
diff --git a/spec/support/pundit/policies.rb b/spec/support/pundit/policies.rb
new file mode 100644
index 000000000..637a2a528
--- /dev/null
+++ b/spec/support/pundit/policies.rb
@@ -0,0 +1,37 @@
+require 'pundit/rspec'
+
+module Support
+ module Pundit
+ module Policies
+ def add_permissions(*permissions, for_user:)
+ for_user.permissions ||= []
+ for_user.permissions += permissions.flatten
+ end
+
+ def create_user_context(user:, referential:)
+ OpenStruct.new(user: user, context: {referential: referential})
+ end
+
+ def add_permissions(*permissions, for_user:)
+ for_user.permissions ||= []
+ for_user.permissions += permissions.flatten
+ end
+ end
+
+ module PoliciesMacros
+ def self.extended into
+ into.module_eval do
+ subject { described_class }
+ let( :user_context ) { create_user_context(user: user, referential: referential) }
+ let( :referentail ) { create :referential }
+ let( :user ) { create :user }
+ end
+ end
+ end
+ end
+end
+
+RSpec.configure do | c |
+ c.include Support::Pundit::Policies, type: :policy
+ c.extend Support::Pundit::PoliciesMacros, type: :policy
+end
diff --git a/spec/support/pundit/pundit_view_policy.rb b/spec/support/pundit/pundit_view_policy.rb
new file mode 100644
index 000000000..b8434cac0
--- /dev/null
+++ b/spec/support/pundit/pundit_view_policy.rb
@@ -0,0 +1,22 @@
+module Pundit
+ module PunditViewPolicy
+ extend ActiveSupport::Concern
+
+ included do
+ before do
+ controller.singleton_class.class_eval do
+ def policy(instance)
+ Class.new do
+ def method_missing(*args, &block); true; end
+ end.new
+ end
+ helper_method :policy
+ end
+ end
+ end
+ end
+end
+
+RSpec.configure do |config|
+ config.include Pundit::PunditViewPolicy, type: :view
+end
diff --git a/spec/support/pundit/shared_examples.rb b/spec/support/pundit/shared_examples.rb
new file mode 100644
index 000000000..4d14c46da
--- /dev/null
+++ b/spec/support/pundit/shared_examples.rb
@@ -0,0 +1,60 @@
+RSpec.shared_examples 'permitted policy and same organisation' do
+ | permission, archived: false|
+
+ context 'permission absent → ' do
+ it "denies a user with a different organisation" do
+ expect_it.not_to permit(user_context, referential)
+ end
+ it 'and also a user with the same organisation' do
+ user.update_attribute :organisation, referential.organisation
+ expect_it.not_to permit(user_context, referential)
+ end
+ end
+
+ context 'permission present → ' do
+ before do
+ add_permissions(permission, for_user: user)
+ end
+
+ it 'denies a user with a different organisation' do
+ expect_it.not_to permit(user_context, referential)
+ end
+
+ it 'but allows it for a user with the same organisation' do
+ user.update_attribute :organisation, referential.organisation
+ expect_it.to permit(user_context, referential)
+ end
+
+ if archived
+ it 'removes the permission for archived referentials' do
+ user.update_attribute :organisation, referential.organisation
+ referential.update_attribute :archived_at, 42.seconds.ago
+ expect_it.not_to permit(user_context, referential)
+ end
+ end
+ end
+end
+
+RSpec.shared_examples 'permitted policy' do
+ | permission, archived: false|
+ context 'permission absent → ' do
+ it "denies a user with a different organisation" do
+ expect_it.not_to permit(user_context, referential)
+ end
+ end
+ context 'permission present → ' do
+ before do
+ add_permissions(permission, for_user: user)
+ end
+ it 'allows a user with a different organisation' do
+ expect_it.to permit(user_context, referential)
+ end
+
+ if archived
+ it 'removes the permission for archived referentials' do
+ referential.update_attribute :archived_at, 42.seconds.ago
+ expect_it.not_to permit(user_context, referential)
+ end
+ end
+ end
+end
diff --git a/spec/support/pundit_view_policy.rb b/spec/support/pundit_view_policy.rb
deleted file mode 100644
index 2945b9aac..000000000
--- a/spec/support/pundit_view_policy.rb
+++ /dev/null
@@ -1,20 +0,0 @@
-module PunditViewPolicy
- extend ActiveSupport::Concern
-
- included do
- before do
- controller.singleton_class.class_eval do
- def policy(instance)
- Class.new do
- def method_missing(*args, &block); true; end
- end.new
- end
- helper_method :policy
- end
- end
- end
-end
-
-RSpec.configure do |config|
- config.include PunditViewPolicy, type: :view
-end