aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRobert2017-08-14 18:42:08 +0200
committerRobert2017-08-15 17:22:34 +0200
commit373a4089173795d011ebd6adf7382b2a5e40a51b (patch)
tree1f5580f5d57f08b7361a19b21a161ac98b04d255
parentc16c03b91174cf637e0bd2f0e3336e3788f43e59 (diff)
downloadchouette-core-373a4089173795d011ebd6adf7382b2a5e40a51b.tar.bz2
Refs: #4189@2h; Iimplementation of Chouette::Route#duplicate & Chouette::StopPoint#duplicate
With the following unspecified behaviour concerning `objectid` and `object_version` - The duplicated Route objectid is passed into Route#duplicate - The duplicated StopPoint objectids are constructed from the source's objectids (parts 2 & 3) and the route's objectid (part 1) - the duplicated Route object_version equals the source's one
-rw-r--r--app/models/chouette/route.rb24
-rw-r--r--app/models/chouette/stop_point.rb19
-rw-r--r--spec/models/chouette/route/route_duplication_spec.rb28
-rw-r--r--spec/models/chouette/stop_point_spec.rb30
-rw-r--r--spec/support/helpers/model_compare_helpers.rb12
5 files changed, 92 insertions, 21 deletions
diff --git a/app/models/chouette/route.rb b/app/models/chouette/route.rb
index 6774e8a86..0fe4472d3 100644
--- a/app/models/chouette/route.rb
+++ b/app/models/chouette/route.rb
@@ -16,6 +16,7 @@ class Chouette::Route < Chouette::TridentActiveRecord
end
belongs_to :line
+ belongs_to :opposite_route, :class_name => 'Chouette::Route', :foreign_key => :opposite_route_id
has_many :routing_constraint_zones
has_many :journey_patterns, :dependent => :destroy
@@ -30,7 +31,6 @@ class Chouette::Route < Chouette::TridentActiveRecord
Chouette::Route.vehicle_journeys_timeless(proxy_association.owner.journey_patterns.pluck( :departure_stop_point_id))
end
end
- belongs_to :opposite_route, :class_name => 'Chouette::Route', :foreign_key => :opposite_route_id
has_many :stop_points, -> { order("position") }, :dependent => :destroy do
def find_by_stop_area(stop_area)
stop_area_ids = Integer === stop_area ? [stop_area] : (stop_area.children_in_depth + [stop_area]).map(&:id)
@@ -56,12 +56,13 @@ class Chouette::Route < Chouette::TridentActiveRecord
end
has_many :stop_areas, -> { order('stop_points.position ASC') }, :through => :stop_points do
def between(departure, arrival)
- departure, arrival = [departure, arrival].collect do |endpoint|
+ departure, arrival = [departure, arrival].map do |endpoint|
String === endpoint ? Chouette::StopArea.find_by_objectid(endpoint) : endpoint
end
proxy_owner.stop_points.between(departure, arrival).includes(:stop_area).collect(&:stop_area)
end
end
+
accepts_nested_attributes_for :stop_points, :allow_destroy => :true
validates_presence_of :name
@@ -75,6 +76,25 @@ class Chouette::Route < Chouette::TridentActiveRecord
after_commit :journey_patterns_control_route_sections
+ def duplicate new_objectid
+ keys_for_create = attributes.keys - %w{id created_at updated_at}
+ atts_for_create = attributes
+ .slice(*keys_for_create)
+ .merge('objectid' => new_objectid, 'object_version' => object_version - 1)
+ new_route = self.class.create!(atts_for_create)
+ duplicate_stop_points(for_route: new_route)
+ new_route
+ end
+
+ def duplicate_stop_points(for_route:)
+ stop_points.each(&duplicate_stop_point(for_route: for_route))
+ end
+ def duplicate_stop_point(for_route:)
+ -> stop_point do
+ stop_point.duplicate(for_route: for_route)
+ end
+ end
+
def geometry_presenter
Chouette::Geometry::RoutePresenter.new self
end
diff --git a/app/models/chouette/stop_point.rb b/app/models/chouette/stop_point.rb
index 8fe79dc0c..de9a3e26f 100644
--- a/app/models/chouette/stop_point.rb
+++ b/app/models/chouette/stop_point.rb
@@ -20,6 +20,11 @@ module Chouette
validates_presence_of :stop_area
validate :stop_area_id_validation
+ def stop_area_id_validation
+ if stop_area_id.nil?
+ errors.add(:stop_area_id, I18n.t("stop_areas.errors.empty"))
+ end
+ end
scope :default_order, -> { order("position") }
@@ -34,10 +39,16 @@ module Chouette
end
end
- def stop_area_id_validation
- if stop_area_id.nil?
- errors.add(:stop_area_id, I18n.t("stop_areas.errors.empty"))
- end
+ def duplicate(for_route:)
+ new_objectid = [
+ for_route.objectid.split(':').first,
+ *objectid.split(':')[1..2]
+ ].join(':')
+ keys_for_create = attributes.keys - %w{id created_at updated_at}
+ atts_for_create = attributes
+ .slice(*keys_for_create)
+ .merge('objectid' => new_objectid, 'route_id' => for_route.id)
+ self.class.create!(atts_for_create)
end
def self.area_candidates
diff --git a/spec/models/chouette/route/route_duplication_spec.rb b/spec/models/chouette/route/route_duplication_spec.rb
index fe8d5e444..6168d1e38 100644
--- a/spec/models/chouette/route/route_duplication_spec.rb
+++ b/spec/models/chouette/route/route_duplication_spec.rb
@@ -5,27 +5,29 @@ StopPoint = Chouette::StopPoint
RSpec.describe Route do
- let( :route ){ create :route }
+ let!( :route ){ create :route }
+ let( :new_objectid ){ [SecureRandom.hex, 'Route', SecureRandom.hex].join(':') }
context 'duplicates' do
describe 'a route' do
it 'by creating a new one' do
- expect{ route.duplicate }.to change{Route.count}.by(1)
+ expect{ route.duplicate new_objectid }.to change{Route.count}.by(1)
end
it 'with the same values' do
- expect( values_for_create(Route.last) ).to eq( values_for_create( route ) )
+ route.duplicate new_objectid
+ expect( values_for_create(Route.last, except: %w{objectid}) ).to eq( values_for_create( route, except: %w{objectid} ) )
end
- it 'and also duplicating its stop points' do
- expect{ route.dublicate }.to change{StopPoint.count}.by(route.stop_points.count)
- end
- it 'but leaving the stop areas alone' do
- expect{ route.duplicate }.not_to change{StopArea.count}
- end
- it "which are still accessible by the new route though" do
- expect( route.duplicate.stop_areas ).to eq(route.stop_areas)
- end
+ it 'and also duplicating its stop points' do
+ expect{ route.duplicate new_objectid }.to change{StopPoint.count}.by(route.stop_points.count)
+ end
+ it 'but leaving the stop areas alone' do
+ expect{ route.duplicate new_objectid }.not_to change{StopArea.count}
+ end
+ it "which are still accessible by the new route though" do
+ expect( route.duplicate( new_objectid ).stop_areas.pluck(:id) ).to eq(route.stop_areas.pluck(:id))
+ end
end
end
-
+
end
diff --git a/spec/models/chouette/stop_point_spec.rb b/spec/models/chouette/stop_point_spec.rb
index 212c32e1a..c43774085 100644
--- a/spec/models/chouette/stop_point_spec.rb
+++ b/spec/models/chouette/stop_point_spec.rb
@@ -1,6 +1,7 @@
-require 'spec_helper'
+# From Chouette import what we need ™
+StopPoint = Chouette::StopPoint
-describe Chouette::StopPoint, :type => :model do
+describe StopPoint, :type => :model do
let!(:vehicle_journey) { create(:vehicle_journey)}
subject { Chouette::Route.find( vehicle_journey.route_id).stop_points.first }
@@ -38,4 +39,29 @@ describe Chouette::StopPoint, :type => :model do
expect(jpsp_stop_point_ids(@vehicle.journey_pattern_id)).not_to include(@stop_point.id)
end
end
+
+ describe '#duplicate' do
+ let!( :new_route ){ create :route, objectid: 'newroute:Route:1' }
+
+ it 'creates a new instance' do
+ expect{ subject.duplicate(for_route: new_route) }.to change{ StopPoint.count }.by(1)
+ end
+ it 'new instance has a new route' do
+ expect(subject.duplicate(for_route: new_route).route).to eq(new_route)
+ end
+ it 'and old stop_area' do
+ expect(subject.duplicate(for_route: new_route).stop_area).to eq(subject.stop_area)
+ end
+ it 'has an objectid, related to the new route' do
+ new_stop_point = subject.duplicate(for_route: new_route)
+
+ old_objectid_parts = subject.objectid.split(':')
+ new_objectid_parts = new_stop_point.objectid.split(':')
+ route_object_id_part = new_route.objectid.split(':').first
+
+ expect(new_objectid_parts.first).to eq(route_object_id_part)
+ expect(new_objectid_parts.second).to eq(old_objectid_parts.second)
+ expect(new_objectid_parts.third).to eq(old_objectid_parts.third)
+ end
+ end
end
diff --git a/spec/support/helpers/model_compare_helpers.rb b/spec/support/helpers/model_compare_helpers.rb
new file mode 100644
index 000000000..97e26f300
--- /dev/null
+++ b/spec/support/helpers/model_compare_helpers.rb
@@ -0,0 +1,12 @@
+module Support::ModelCompareHelpers
+
+ def values_for_create obj, except: []
+ keys = obj.attributes.keys - except - %w{id created_at updated_at}
+ obj.attributes.slice(*keys)
+ end
+
+end
+
+RSpec.configure do | rspec |
+ rspec.include Support::ModelCompareHelpers, type: :model
+end