diff options
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 |
