From ddd83906ce4fab3d6dce0c404ec39c3b500ba96f Mon Sep 17 00:00:00 2001
From: Zog
Date: Mon, 29 Jan 2018 10:32:05 +0100
Subject: Refs #5750; Add a validation on VehicleJourneys
Ensure a time is set for all non-commercial stops
---
 app/assets/stylesheets/modules/_vj_collection.sass |  3 ++
 app/javascript/vehicle_journeys/actions/index.js   | 26 ++++++++++++++
 .../components/SaveVehicleJourneys.js              |  2 +-
 .../vehicle_journeys/components/VehicleJourney.js  |  3 ++
 .../vehicle_journeys/components/VehicleJourneys.js |  2 +-
 .../containers/SaveVehicleJourneys.js              |  3 ++
 .../vehicle_journeys/reducers/vehicleJourneys.js   |  2 ++
 app/views/vehicle_journeys/show.rabl               |  1 +
 spec/javascript/vehicle_journeys/actions_spec.js   | 41 ++++++++++++++++++++++
 9 files changed, 81 insertions(+), 2 deletions(-)
diff --git a/app/assets/stylesheets/modules/_vj_collection.sass b/app/assets/stylesheets/modules/_vj_collection.sass
index 81c1fe43e..d99c67bd7 100644
--- a/app/assets/stylesheets/modules/_vj_collection.sass
+++ b/app/assets/stylesheets/modules/_vj_collection.sass
@@ -116,6 +116,9 @@
           margin-left: 5px
 
       &.has-error
+        .errors
+          color: $red
+          font-size: 0.8em
         &:before
           content: ''
           position: absolute
diff --git a/app/javascript/vehicle_journeys/actions/index.js b/app/javascript/vehicle_journeys/actions/index.js
index 2675328e3..b01158212 100644
--- a/app/javascript/vehicle_journeys/actions/index.js
+++ b/app/javascript/vehicle_journeys/actions/index.js
@@ -380,6 +380,32 @@ const actions = {
         }
       })
   },
+
+  validate : (dispatch, vehicleJourneys, next) => {
+    let valid = true
+    let vj, vjas
+    for (vj of vehicleJourneys){
+      vj.errors = false
+      for(vjas of vj.vehicle_journey_at_stops){
+        vjas.errors = null
+        if (vjas.area_kind == "non_commercial" && parseInt(vjas.departure_time.hour) == 0 && parseInt(vjas.departure_time.minute) == 0){
+          vjas.errors = "Champ requis"
+          vj.errors = true
+          valid = false
+        }
+      }
+    }
+    dispatch(actions.didValidateVehicleJourneys(vehicleJourneys))
+    if(valid){
+      actions.submitVehicleJourneys(dispatch, vehicleJourneys, next)
+    }
+  },
+
+  didValidateVehicleJourneys : (vehicleJourneys) => ({
+    type: 'DID_VALIDATE_VEHICLE_JOURNEYS',
+    vehicleJourneys
+  }),
+
   submitVehicleJourneys : (dispatch, state, next) => {
     dispatch(actions.fetchingApi())
     let urlJSON = window.location.pathname + "_collection.json"
diff --git a/app/javascript/vehicle_journeys/components/SaveVehicleJourneys.js b/app/javascript/vehicle_journeys/components/SaveVehicleJourneys.js
index 6e94b04a3..fb921df9c 100644
--- a/app/javascript/vehicle_journeys/components/SaveVehicleJourneys.js
+++ b/app/javascript/vehicle_journeys/components/SaveVehicleJourneys.js
@@ -13,7 +13,7 @@ export default class SaveVehicleJourneys extends SaveButton{
   }
 
   submitForm(){
-    this.props.onSubmitVehicleJourneys(this.props.dispatch, this.props.vehicleJourneys)
+    this.props.validate(this.props.vehicleJourneys, this.props.dispatch)
   }
 }
 
diff --git a/app/javascript/vehicle_journeys/components/VehicleJourney.js b/app/javascript/vehicle_journeys/components/VehicleJourney.js
index d240757a3..2b5783dda 100644
--- a/app/javascript/vehicle_journeys/components/VehicleJourney.js
+++ b/app/javascript/vehicle_journeys/components/VehicleJourney.js
@@ -153,6 +153,9 @@ export default class VehicleJourney extends Component {
                       />
                   
                 
+                {vj.errors && 
+                  {vj.errors}
+                
}
             
           
         )}
diff --git a/app/javascript/vehicle_journeys/components/VehicleJourneys.js b/app/javascript/vehicle_journeys/components/VehicleJourneys.js
index b188962c2..256ca81f9 100644
--- a/app/javascript/vehicle_journeys/components/VehicleJourneys.js
+++ b/app/javascript/vehicle_journeys/components/VehicleJourneys.js
@@ -89,7 +89,7 @@ export default class VehicleJourneys extends Component {
               
             )}
 
-            { _.some(this.props.vehicleJourneys, 'errors') && (
+            { this.props.vehicleJourneys.errors && this.props.vehicleJourneys.errors.length && _.some(this.props.vehicleJourneys, 'errors') && (
               
                 Erreur : 
                 {this.props.vehicleJourneys.map((vj, index) =>
diff --git a/app/javascript/vehicle_journeys/containers/SaveVehicleJourneys.js b/app/javascript/vehicle_journeys/containers/SaveVehicleJourneys.js
index f5f879ed8..3daf831f8 100644
--- a/app/javascript/vehicle_journeys/containers/SaveVehicleJourneys.js
+++ b/app/javascript/vehicle_journeys/containers/SaveVehicleJourneys.js
@@ -23,6 +23,9 @@ const mapDispatchToProps = (dispatch) => {
     },
     onSubmitVehicleJourneys: (next, state) => {
       actions.submitVehicleJourneys(dispatch, state, next)
+    },
+    validate: (state) =>{
+      actions.validate(dispatch, state)
     }
   }
 }
diff --git a/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js b/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js
index ae45993a8..1a15ec46d 100644
--- a/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js
+++ b/app/javascript/vehicle_journeys/reducers/vehicleJourneys.js
@@ -273,6 +273,8 @@ export default function vehicleJourneys(state = [], action) {
           return vj
         }
       })
+    case 'DID_VALIDATE_VEHICLE_JOURNEYS':
+      return [...action.vehicleJourneys]
     default:
       return state
   }
diff --git a/app/views/vehicle_journeys/show.rabl b/app/views/vehicle_journeys/show.rabl
index fc65e6cb6..dca0866b3 100644
--- a/app/views/vehicle_journeys/show.rabl
+++ b/app/views/vehicle_journeys/show.rabl
@@ -45,6 +45,7 @@ child(:vehicle_journey_at_stops_matrix, :object_root => false) do |vehicle_stops
     end
 
     node(:dummy) { vehicle_stop.dummy }
+    node(:area_kind) { vehicle_stop.stop_point.stop_area.kind }
 
     node(:stop_area_object_id) do
       vehicle_stop.stop_point.stop_area.objectid
diff --git a/spec/javascript/vehicle_journeys/actions_spec.js b/spec/javascript/vehicle_journeys/actions_spec.js
index 9515b57f2..d486c9af8 100644
--- a/spec/javascript/vehicle_journeys/actions_spec.js
+++ b/spec/javascript/vehicle_journeys/actions_spec.js
@@ -37,6 +37,47 @@ describe('when clicking on add button', () => {
     expect(actions.openCreateModal()).toEqual(expectedAction)
   })
 })
+describe('when validating the form', () => {
+  it('should check that non-commercial stops have passing time', () => {
+    let state = [{
+      vehicle_journey_at_stops: [{
+        area_kind: "non_commercial",
+        departure_time: {
+          hour: "00",
+          minute: "00"
+        }
+      }]
+    }]
+
+    expect(actions.validate(dispatch, state)).toEqual(false)
+
+    state = [{
+      vehicle_journey_at_stops: [{
+        area_kind: "non_commercial",
+        departure_time: {
+          hour: "00",
+          minute: "01"
+        }
+      }]
+    }]
+
+    expect(actions.validate(dispatch, state)).toEqual(true)
+  })
+
+  it('should not check that commercial stops', () => {
+    let state = [{
+      vehicle_journey_at_stops: [{
+        area_kind: "commercial",
+        departure_time: {
+          hour: "00",
+          minute: "00"
+        }
+      }]
+    }]
+
+    expect(actions.validate(dispatch, state)).toEqual(true)
+  })
+})
 describe('when using select2 to pick a journey pattern', () => {
   it('should create an action to select a journey pattern inside modal', () => {
     let selectedJP = {
-- 
cgit v1.2.3