diff options
| author | Vlatka Pavisic | 2017-04-11 15:35:01 +0200 | 
|---|---|---|
| committer | Vlatka Pavisic | 2017-04-11 15:35:01 +0200 | 
| commit | aa481c087b162bc775b4418e205f91c5b6bead19 (patch) | |
| tree | 914ba9b39e0338317bcc2bfd839f745647beda1a | |
| parent | 8adf909694b52959483818bf839d6e180015eb99 (diff) | |
| download | chouette-core-aa481c087b162bc775b4418e205f91c5b6bead19.tar.bz2 | |
Refs #3047: Associate RoutingConstraintZone with StopPoints
18 files changed, 157 insertions, 32 deletions
| diff --git a/app/assets/javascripts/routing_constraint_zones.coffee b/app/assets/javascripts/routing_constraint_zones.coffee new file mode 100644 index 000000000..57f94e654 --- /dev/null +++ b/app/assets/javascripts/routing_constraint_zones.coffee @@ -0,0 +1,18 @@ +fill_stop_points_options = -> +  stop_point_select = $('#routing_constraint_zone_stop_point_ids') +  stop_point_select.empty() +  route_id = $('#routing_constraint_zone_route_id').val() +  $.ajax +    url: "/referentials/5/lines/162/routes/#{route_id}/stop_points" +    dataType: 'json' +    success: (data, textStatus, jqXHR) -> +      for stop_point in data +        stop_point_select.append "<option value='#{stop_point.id}'>#{stop_point.name}</option>" +    error: (jqXHR, textStatus, errorThrown) -> +      console.log textStatus +      console.log errorThrown + +$ -> +  if document.location.pathname.endsWith('new') +    fill_stop_points_options() +  $('#routing_constraint_zone_route_id').change(fill_stop_points_options) diff --git a/app/controllers/route_stop_points_controller.rb b/app/controllers/route_stop_points_controller.rb new file mode 100644 index 000000000..e12acb33b --- /dev/null +++ b/app/controllers/route_stop_points_controller.rb @@ -0,0 +1,18 @@ +class RouteStopPointsController < ChouetteController +  defaults resource_class: Chouette::StopPoint +  actions :index +  respond_to :json, only: :index + +  belongs_to :referential do +    belongs_to :line, :parent_class => Chouette::Line do +      belongs_to :route, :parent_class => Chouette::Route +    end +  end + +  def index +    respond_to do |format| +      format.json { render json: referential.lines.find(params[:line_id]).routes.find(params[:route_id]).stop_points.map { |sp| { id: sp.id, name: sp.name } } } +    end +  end +end + diff --git a/app/controllers/routing_constraint_zones_controller.rb b/app/controllers/routing_constraint_zones_controller.rb index bc3dcdfd4..f2f74e801 100644 --- a/app/controllers/routing_constraint_zones_controller.rb +++ b/app/controllers/routing_constraint_zones_controller.rb @@ -3,6 +3,8 @@ class RoutingConstraintZonesController < ChouetteController    respond_to :html, :xml, :json +  before_action :remove_empty_stop_point, only: [:create, :update] +    belongs_to :referential do      belongs_to :line, parent_class: Chouette::Line    end @@ -11,7 +13,10 @@ class RoutingConstraintZonesController < ChouetteController    private    def routing_constraint_zone_params -    params.require(:routing_constraint_zone).permit(:name, { stop_area_ids: [] }, :line_id, :route_id, :objectid, :object_version, :creator_id) +    params.require(:routing_constraint_zone).permit(:name, { stop_point_ids: [] }, :line_id, :route_id, :objectid, :object_version, :creator_id)    end +  def remove_empty_stop_point +    params.require(:routing_constraint_zone)[:stop_point_ids].delete('') +  end  end diff --git a/app/helpers/newapplication_helper.rb b/app/helpers/newapplication_helper.rb index c4b8ee7ab..f5b898731 100644 --- a/app/helpers/newapplication_helper.rb +++ b/app/helpers/newapplication_helper.rb @@ -51,12 +51,11 @@ module NewapplicationHelper              if attribute == 'name'                lnk = [] -              unless item.class.to_s == 'Calendar' or item.class.to_s == 'Referential' +              unless item.class == Calendar or item.class == Referential                  if current_referential                    lnk << current_referential                    lnk << item.line if item.respond_to? :line -                  lnk << item.route.line if item.class.to_s == 'Chouette::RoutingConstraintZone' -                  lnk << item if item.class.to_s == 'Chouette::RoutingConstraintZone' +                  lnk << item.route.line if item.class == Chouette::RoutingConstraintZone                    lnk << item if item.respond_to? :line_referential                    lnk << item.stop_area if item.respond_to? :stop_area                    lnk << item if item.respond_to? :stop_points @@ -103,12 +102,11 @@ module NewapplicationHelper            polymorph_url << action          end -        unless item.class.to_s == 'Calendar' or item.class.to_s == 'Referential' +        unless item.class == Calendar or item.class == Referential            if current_referential              polymorph_url << current_referential              polymorph_url << item.line if item.respond_to? :line -            polymorph_url << item.route.line if item.class.to_s == 'Chouette::RoutingConstraintZone' -            polymorph_url << item if item.class.to_s == 'Chouette::RoutingConstraintZone' +            polymorph_url << item.route.line if item.class == Chouette::RoutingConstraintZone              polymorph_url << item if item.respond_to? :line_referential              polymorph_url << item.stop_area if item.respond_to? :stop_area              polymorph_url << item if item.respond_to? :stop_points diff --git a/app/models/chouette/routing_constraint_zone.rb b/app/models/chouette/routing_constraint_zone.rb index 2c8583ec1..d548ce048 100644 --- a/app/models/chouette/routing_constraint_zone.rb +++ b/app/models/chouette/routing_constraint_zone.rb @@ -1,9 +1,12 @@  class Chouette::RoutingConstraintZone < Chouette::TridentActiveRecord    belongs_to :route -  has_array_of :stop_areas, class_name: 'Chouette::StopArea' +  has_array_of :stop_points, class_name: 'Chouette::StopPoint' -  validates_presence_of :name, :stop_area_ids, :route_id -  validates :stop_areas, length: { minimum: 2 } +  validates_presence_of :name, :stop_point_ids, :route_id +  validates :stop_point_ids, length: { minimum: 2, too_short: I18n.t('activerecord.errors.models.routing_constraint_zone.attributes.stop_points.not_enough_stop_points') } +  validate :stop_points_belong_to_route -  self.primary_key = 'id' +  def stop_points_belong_to_route +    errors.add(:stop_points, I18n.t('activerecord.errors.models.routing_constraint_zone.attributes.stop_points.stop_points_not_from_route')) unless stop_points.all? { |sp| route.stop_points.include? sp } +  end  end diff --git a/app/models/chouette/stop_point.rb b/app/models/chouette/stop_point.rb index b77189fc1..96b79c9e7 100644 --- a/app/models/chouette/stop_point.rb +++ b/app/models/chouette/stop_point.rb @@ -2,7 +2,7 @@ module Chouette    class StopPoint < TridentActiveRecord      include ForBoardingEnumerations      include ForAlightingEnumerations -     +      # FIXME http://jira.codehaus.org/browse/JRUBY-6358      self.primary_key = "id" @@ -18,6 +18,8 @@ module Chouette      scope :default_order, order("position") +    delegate :name, to: :stop_area +      before_destroy :remove_dependent_journey_pattern_stop_points      def remove_dependent_journey_pattern_stop_points        route.journey_patterns.each do |jp| @@ -25,7 +27,7 @@ module Chouette            jp.stop_point_ids = jp.stop_point_ids - [id]          end        end -    end   +    end      def stop_area_id_validation        if stop_area_id.nil? diff --git a/app/views/routing_constraint_zones/_form.html.slim b/app/views/routing_constraint_zones/_form.html.slim index f72dd1471..e07b21fec 100644 --- a/app/views/routing_constraint_zones/_form.html.slim +++ b/app/views/routing_constraint_zones/_form.html.slim @@ -4,13 +4,15 @@        = f.input :name    .row      .col-lg-6.col-sm-12 -      = f.input :route_id, collection: @line.routes +      = f.input :route_id, collection: @line.routes, include_blank: false    .row      .col-lg-6.col-sm-12 -      / Temporarily limit the collection to 10 items... otherwise it kills RoR -      = f.input :stop_area_ids, as: :select, collection: Chouette::StopArea.limit(10), selected: @routing_constraint_zone.stop_area_ids, label: Chouette::StopArea.model_name.human.pluralize.capitalize, label_method: :name, input_html: { 'data-select2ed': 'true', 'data-select2ed-placeholder': 'Sélection de arrêts', 'multiple': 'multiple', style: 'width: 100%' } +      - stop_points_collection = @routing_constraint_zone.persisted? ? @routing_constraint_zone.route.stop_points : [] +      = f.input :stop_point_ids, id: 'stop_point_ids', as: :select, collection: stop_points_collection, selected: @routing_constraint_zone.stop_point_ids, label: Chouette::StopPoint.model_name.human.pluralize.capitalize, label_method: :name, input_html: { 'data-select2ed': 'true', 'data-select2ed-placeholder': 'Sélection des arrêts sur séquence d\'arrêts', 'multiple': 'multiple', style: 'width: 100%' }    .row      .col-lg-12.text-right        = link_to 'Annuler', :back, class: 'btn btn-link'        = f.button :submit, class: 'btn btn-danger' + + diff --git a/app/views/routing_constraint_zones/show.html.slim b/app/views/routing_constraint_zones/show.html.slim index 7b7b63623..351784ecc 100644 --- a/app/views/routing_constraint_zones/show.html.slim +++ b/app/views/routing_constraint_zones/show.html.slim @@ -9,10 +9,9 @@ p    = link_to @routing_constraint_zone.route.name, referential_line_route_path(@referential, @line, @routing_constraint_zone.route)  p -  label => "#{Chouette::StopArea.model_name.human.pluralize.capitalize} : " +  label => "#{Chouette::StopPoint.model_name.human.pluralize.capitalize} : "    br -  - @routing_constraint_zone.stop_areas.each do |stop_area| -    = link_to stop_area.name, referential_stop_area_path(@referential, stop_area) +  - @routing_constraint_zone.stop_points.each do |stop_point| +    = link_to stop_point.name, referential_stop_area_path(@referential, stop_point.stop_area)      br - diff --git a/config/locales/routing_constraint_zones.en.yml b/config/locales/routing_constraint_zones.en.yml index 7012a1493..e3e281d38 100644 --- a/config/locales/routing_constraint_zones.en.yml +++ b/config/locales/routing_constraint_zones.en.yml @@ -9,6 +9,12 @@ en:          line: Line          created_at: Created at          updated_at: Updated at +    errors: +      models: +        routing_constraint_zone: +          attributes: +            stop_points: +              stop_points_not_from_route: 'Stop point does not belong to the Route of this Routing constraint zone.'    routing_constraint_zones:      actions:        new: New routing constraint zone @@ -21,3 +27,4 @@ en:        title: "Update routing constraint zone %{routing_constraint_zone}"      show:        title: "Routing constraint zone %{routing_constraint_zone}" + diff --git a/config/locales/routing_constraint_zones.fr.yml b/config/locales/routing_constraint_zones.fr.yml index bb4d8bcd2..5b663e00c 100644 --- a/config/locales/routing_constraint_zones.fr.yml +++ b/config/locales/routing_constraint_zones.fr.yml @@ -9,6 +9,13 @@ fr:          line: Ligne          created_at: "Créé le"          updated_at: "Edité le" +    errors: +      models: +        routing_constraint_zone: +          attributes: +            stop_points: +              not_enough_stop_points: "Il faut mettre au moins deux arrêts sur séquence d'arrêts." +              stop_points_not_from_route: "Arrêt sur séquence d'arrêts n'appartient pas à la Route de cette Zone de contrainte."    routing_constraint_zones:      actions:        new: Ajouter une zone de contrainte diff --git a/config/routes.rb b/config/routes.rb index 12dbf0986..692972315 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -123,6 +123,7 @@ ChouetteIhm::Application.routes.draw do          end          resources :vehicle_journey_imports          resources :vehicle_journey_exports +        resources :stop_points, only: :index, controller: 'route_stop_points'        end        resources :routing_constraint_zones      end diff --git a/db/migrate/20170405122823_rm_stop_areas_add_stop_points_to_routing_constraint_zone.rb b/db/migrate/20170405122823_rm_stop_areas_add_stop_points_to_routing_constraint_zone.rb new file mode 100644 index 000000000..67bc2623c --- /dev/null +++ b/db/migrate/20170405122823_rm_stop_areas_add_stop_points_to_routing_constraint_zone.rb @@ -0,0 +1,6 @@ +class RmStopAreasAddStopPointsToRoutingConstraintZone < ActiveRecord::Migration +  def change +    remove_column :routing_constraint_zones, :stop_area_ids, :integer, array: true +    add_column :routing_constraint_zones, :stop_point_ids, :bigint, array: true +  end +end diff --git a/db/schema.rb b/db/schema.rb index 53e3ad57c..967722d5c 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@  #  # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170404122930) do +ActiveRecord::Schema.define(version: 20170405122823) do    # These are extensions that must be enabled in order to support this database    enable_extension "plpgsql" @@ -542,13 +542,13 @@ ActiveRecord::Schema.define(version: 20170404122930) do    create_table "routing_constraint_zones", force: true do |t|      t.string   "name" -    t.integer  "stop_area_ids",                         array: true      t.datetime "created_at"      t.datetime "updated_at"      t.string   "objectid",                 null: false      t.integer  "object_version", limit: 8      t.string   "creator_id"      t.integer  "route_id",       limit: 8 +    t.integer  "stop_point_ids", limit: 8,              array: true    end    create_table "routing_constraints_lines", id: false, force: true do |t| diff --git a/spec/controllers/route_stop_points_controller_spec.rb b/spec/controllers/route_stop_points_controller_spec.rb new file mode 100644 index 000000000..2f5fa41c7 --- /dev/null +++ b/spec/controllers/route_stop_points_controller_spec.rb @@ -0,0 +1,23 @@ +require 'spec_helper' + +RSpec.describe RouteStopPointsController, type: :controller do +  login_user + +  let(:referential) { Referential.first } +  let!(:line) { create :line } +  let!(:route) { create :route, line: line } + +  describe 'GET index' do +    before(:each) { get :index, referential_id: referential.id, line_id: line.id, route_id: route.id, format: :json } + +    it 'returns HTTP success' do +      expect(response).to be_success +    end + +    it 'returns a JSON of stop areas' do +      expect(response.body).to eq(route.stop_points.map { |sp| { id: sp.id, name: sp.name } }.to_json) +    end +  end +end + + diff --git a/spec/factories/chouette_routing_constraint_zones.rb b/spec/factories/chouette_routing_constraint_zones.rb index 2f707e6a6..8ef2ddb43 100644 --- a/spec/factories/chouette_routing_constraint_zones.rb +++ b/spec/factories/chouette_routing_constraint_zones.rb @@ -1,7 +1,10 @@  FactoryGirl.define do    factory :routing_constraint_zone, class: Chouette::RoutingConstraintZone do      sequence(:name) { |n| "Routing constraint zone #{n}" } -    stop_area_ids { [create(:stop_area).id, create(:stop_area).id] }      association :route, factory: :route +    after(:build) do |zone| +      route = Chouette::Route.find(zone.route_id) +      zone.stop_point_ids = route.stop_points.pluck(:id).first(2) +    end    end  end diff --git a/spec/features/lines_spec.rb b/spec/features/lines_spec.rb index bbe3c757b..e7e1e601c 100644 --- a/spec/features/lines_spec.rb +++ b/spec/features/lines_spec.rb @@ -20,10 +20,10 @@ describe "Lines", :type => :feature do      end      it 'allows only R in CRUD' do -      expect(page).to have_content(I18n.t('actions.show')) -      expect(page).not_to have_content(I18n.t('actions.edit')) -      expect(page).not_to have_content(I18n.t('actions.destroy')) -      expect(page).not_to have_content(I18n.t('actions.add')) +      expect(page).to have_link(I18n.t('actions.show')) +      expect(page).not_to have_link(I18n.t('actions.edit'), href: edit_referential_line_path(referential, lines.first)) +      expect(page).not_to have_link(I18n.t('actions.destroy'), href: referential_line_path(referential, lines.first)) +      expect(page).not_to have_link(I18n.t('actions.add'), href: new_referential_line_path(referential))      end      context 'filtering' do diff --git a/spec/features/routes_spec.rb b/spec/features/routes_spec.rb index 36d0e8f87..4b90a6ec6 100644 --- a/spec/features/routes_spec.rb +++ b/spec/features/routes_spec.rb @@ -102,7 +102,7 @@ describe "Routes", :type => :feature do        it 'does not show edit buttons for routes' do          @user.update_attribute(:permissions, [])          visit referential_line_path(referential, line) -        expect(page).not_to have_content(I18n.t('actions.edit')) +        expect(page).not_to have_link(I18n.t('actions.edit'), href: edit_referential_line_route_path(referential, line, route))        end      end @@ -136,7 +136,7 @@ describe "Routes", :type => :feature do        it 'does not show destroy buttons for routes' do          @user.update_attribute(:permissions, [])          visit referential_line_path(referential, line) -        expect(page).not_to have_content(I18n.t('actions.destroy')) +        expect(page).not_to have_link(I18n.t('actions.destroy'), href: referential_line_route_path(referential, line, route))        end      end    end diff --git a/spec/models/chouette/routing_constraint_zone_spec.rb b/spec/models/chouette/routing_constraint_zone_spec.rb index f737872bf..c83942456 100644 --- a/spec/models/chouette/routing_constraint_zone_spec.rb +++ b/spec/models/chouette/routing_constraint_zone_spec.rb @@ -5,9 +5,42 @@ describe Chouette::RoutingConstraintZone, type: :model do    subject { create(:routing_constraint_zone) }    it { is_expected.to validate_presence_of :name } -  it { is_expected.to validate_presence_of :stop_area_ids } -  it { is_expected.to validate_presence_of :route_id }    # shoulda matcher to validate length of array ? -  xit { is_expected.to validate_length_of(:stop_area_ids).is_at_least(2) } +  xit { is_expected.to validate_length_of(:stop_point_ids).is_at_least(2) } + +  describe 'validations' do +    it 'validates the presence of route_id' do +      routing_constraint_zone = create(:routing_constraint_zone) +      expect { +        routing_constraint_zone.update!(route_id: nil) +      }.to raise_error +    end + +    it 'validates the presence of stop_point_ids' do +      routing_constraint_zone = create(:routing_constraint_zone) +      expect { +        routing_constraint_zone.update!(stop_point_ids: []) +      }.to raise_error(ActiveRecord::RecordInvalid) +    end + +    it 'validates that stop points belong to the route' do +      routing_constraint_zone = create(:routing_constraint_zone) +      route = create(:route) +      expect { +        routing_constraint_zone.update!(route_id: route.id) +      }.to raise_error(ActiveRecord::RecordInvalid) +    end +  end + +  describe 'deleted stop areas' do +    it 'does not have them in stop_area_ids' do +      routing_constraint_zone = create(:routing_constraint_zone) +      stop_point = routing_constraint_zone.route.stop_points.last +      routing_constraint_zone.stop_points << stop_point +      routing_constraint_zone.save! +      routing_constraint_zone.route.stop_points.last.destroy! +      expect(routing_constraint_zone.stop_points.map(&:id)).not_to include(stop_point.id) +    end +  end  end | 
