From 22dbab5e609e3ec578b68890d67741a99103dd0c Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 7 Aug 2017 11:45:03 +0200 Subject: Add routes to Routes#duplicate A couple of new routes for a form that will allow us to duplicate an itinéraire/route inside a line. Refs #4189 --- app/controllers/routes_controller.rb | 3 +++ config/routes.rb | 2 ++ spec/routing/routes_routing_spec.rb | 11 +++++++++++ 3 files changed, 16 insertions(+) create mode 100644 spec/routing/routes_routing_spec.rb diff --git a/app/controllers/routes_controller.rb b/app/controllers/routes_controller.rb index 7ba2c1a58..6455cb2da 100644 --- a/app/controllers/routes_controller.rb +++ b/app/controllers/routes_controller.rb @@ -69,6 +69,9 @@ class RoutesController < ChouetteController end end + def duplicate + end + # def update # update! do |success, failure| # success.html { redirect_to referential_line_path(@referential,@line) } diff --git a/config/routes.rb b/config/routes.rb index 0ed401cf5..b738c0943 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -110,6 +110,8 @@ ChouetteIhm::Application.routes.draw do member do get 'edit_boarding_alighting' put 'save_boarding_alighting' + get 'duplicate' + post 'duplicate' end resource :journey_patterns_collection, :only => [:show, :update] resources :journey_patterns do diff --git a/spec/routing/routes_routing_spec.rb b/spec/routing/routes_routing_spec.rb new file mode 100644 index 000000000..ca2d3ade9 --- /dev/null +++ b/spec/routing/routes_routing_spec.rb @@ -0,0 +1,11 @@ +RSpec.describe "routes for Routes", type: :routing do + it "routes to /referentials/:id/lines/:id/routes/:id/duplicate" do + expect( + get: '/referentials/:referential_id/lines/:line_id/routes/:id/duplicate' + ).to be_routable + + expect( + post: '/referentials/:referential_id/lines/:line_id/routes/:id/duplicate' + ).to be_routable + end +end -- cgit v1.2.3 From e1429e4a20020a156099898f35085489e9eae63e Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 7 Aug 2017 11:50:25 +0200 Subject: RoutesController: Get rid of old commented code This method was commented out in 2012. Safe to say we can remove it. --- app/controllers/routes_controller.rb | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/controllers/routes_controller.rb b/app/controllers/routes_controller.rb index 6455cb2da..c4182af56 100644 --- a/app/controllers/routes_controller.rb +++ b/app/controllers/routes_controller.rb @@ -72,11 +72,6 @@ class RoutesController < ChouetteController def duplicate end - # def update - # update! do |success, failure| - # success.html { redirect_to referential_line_path(@referential,@line) } - # end - # end protected alias_method :route, :resource -- cgit v1.2.3 From 1db9e40adc4c20372102032085521ad3eeab8d3b Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 7 Aug 2017 11:52:16 +0200 Subject: routes_controller_spec.rb: Clean up whitespace --- spec/controllers/routes_controller_spec.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/controllers/routes_controller_spec.rb b/spec/controllers/routes_controller_spec.rb index 000b799db..44f552a3b 100644 --- a/spec/controllers/routes_controller_spec.rb +++ b/spec/controllers/routes_controller_spec.rb @@ -10,6 +10,7 @@ RSpec.describe RoutesController, :type => :controller do # expect(response).to redirect_to( referential_line_path(referential,route.line) ) end end + shared_examples_for "line and referential linked" do it "assigns route.line as @line" do expect(assigns[:line]).to eq(route.line) @@ -19,6 +20,7 @@ RSpec.describe RoutesController, :type => :controller do expect(assigns[:referential]).to eq(referential) end end + shared_examples_for "route, line and referential linked" do it "assigns route as @route" do expect(assigns[:route]).to eq(route) @@ -78,4 +80,3 @@ RSpec.describe RoutesController, :type => :controller do end end - -- cgit v1.2.3 From f1ee86f4c44e6f3256fa1bc514bdc6802a9bafc3 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 7 Aug 2017 11:52:58 +0200 Subject: routes_controller_spec.rb: Remove old commented test This test was commented out in 2015. Safe to say we can remove it now. --- spec/controllers/routes_controller_spec.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/spec/controllers/routes_controller_spec.rb b/spec/controllers/routes_controller_spec.rb index 44f552a3b..4adf05ed2 100644 --- a/spec/controllers/routes_controller_spec.rb +++ b/spec/controllers/routes_controller_spec.rb @@ -73,10 +73,6 @@ RSpec.describe RoutesController, :type => :controller do expect(assigns[:map]).to be_an_instance_of(RouteMap) expect(assigns[:map].route).to eq(route) end - - #it "assigns route.stop_points.paginate(:page => nil) as @stop_points" do - # expect(assigns[:stop_points]).to eq(route.stop_points.paginate(:page => nil)) - #end end end -- cgit v1.2.3 From 0e8def20b170a094b5626c84265c08af45b8adbc Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 7 Aug 2017 12:00:53 +0200 Subject: routes_controller_spec.rb: Use lazy let Don't force creation of the `route`, create it lazily. Refs #4189 --- spec/controllers/routes_controller_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/controllers/routes_controller_spec.rb b/spec/controllers/routes_controller_spec.rb index 4adf05ed2..414583eb3 100644 --- a/spec/controllers/routes_controller_spec.rb +++ b/spec/controllers/routes_controller_spec.rb @@ -1,7 +1,7 @@ RSpec.describe RoutesController, :type => :controller do login_user - let!(:route) { create(:route) } + let(:route) { create(:route) } it { is_expected.to be_kind_of(ChouetteController) } -- cgit v1.2.3 From 3fd4e5ad97fe018de792a94618811b2c53f4640a Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 7 Aug 2017 12:16:43 +0200 Subject: routes_controller_spec.rb: Convert to new Ruby hash syntax --- spec/controllers/routes_controller_spec.rb | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/spec/controllers/routes_controller_spec.rb b/spec/controllers/routes_controller_spec.rb index 414583eb3..cf12f00b1 100644 --- a/spec/controllers/routes_controller_spec.rb +++ b/spec/controllers/routes_controller_spec.rb @@ -1,4 +1,4 @@ -RSpec.describe RoutesController, :type => :controller do +RSpec.describe RoutesController, type: :controller do login_user let(:route) { create(:route) } @@ -30,8 +30,8 @@ RSpec.describe RoutesController, :type => :controller do describe "GET /index" do before(:each) do - get :index, :line_id => route.line_id, - :referential_id => referential.id + get :index, line_id: route.line_id, + referential_id: referential.id end it_behaves_like "line and referential linked" @@ -40,9 +40,9 @@ RSpec.describe RoutesController, :type => :controller do describe "POST /create" do before(:each) do - post :create, :line_id => route.line_id, - :referential_id => referential.id, - :route => { :name => "changed"} + post :create, line_id: route.line_id, + referential_id: referential.id, + route: { name: "changed"} end it_behaves_like "line and referential linked" @@ -51,9 +51,9 @@ RSpec.describe RoutesController, :type => :controller do describe "PUT /update" do before(:each) do - put :update, :id => route.id, :line_id => route.line_id, - :referential_id => referential.id, - :route => route.attributes + put :update, id: route.id, line_id: route.line_id, + referential_id: referential.id, + route: route.attributes end it_behaves_like "route, line and referential linked" @@ -62,9 +62,9 @@ RSpec.describe RoutesController, :type => :controller do describe "GET /show" do before(:each) do - get :show, :id => route.id, - :line_id => route.line_id, - :referential_id => referential.id + get :show, id: route.id, + line_id: route.line_id, + referential_id: referential.id end it_behaves_like "route, line and referential linked" -- cgit v1.2.3 From 7a6239535d8e37bdb2622be357359ea9eceb19a4 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 7 Aug 2017 12:19:04 +0200 Subject: Add views/routes/duplicate.html.slim Duplicate of new.html.slim for now just to get the page working. Refs #4189 --- app/views/routes/duplicate.html.slim | 9 +++++++++ spec/controllers/routes_controller_spec.rb | 10 ++++++++++ 2 files changed, 19 insertions(+) create mode 100644 app/views/routes/duplicate.html.slim diff --git a/app/views/routes/duplicate.html.slim b/app/views/routes/duplicate.html.slim new file mode 100644 index 000000000..a5947049d --- /dev/null +++ b/app/views/routes/duplicate.html.slim @@ -0,0 +1,9 @@ += pageheader 'map-marker', + t('routes.new.title'), + '' + +.page_content + .container-fluid + .row + .col-lg-8.col-lg-offset-2.col-md-8.col-md-offset-2.col-sm-10.col-sm-offset-1 + == render 'form' diff --git a/spec/controllers/routes_controller_spec.rb b/spec/controllers/routes_controller_spec.rb index cf12f00b1..5c17b78b8 100644 --- a/spec/controllers/routes_controller_spec.rb +++ b/spec/controllers/routes_controller_spec.rb @@ -75,4 +75,14 @@ RSpec.describe RoutesController, type: :controller do end end + describe "GET /duplicate" do + it "returns success" do + get :duplicate, + referential_id: route.line.line_referential_id, + line_id: route.line_id, + id: route.id + + expect(response).to be_success + end + end end -- cgit v1.2.3 From 8a93cd37c0b826d3b57a7ffb182d5303ba10dbfc Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 7 Aug 2017 15:04:42 +0200 Subject: Routes#duplicate: Add page header Set header text in the locale files and display it on the page given the route ID in the URL. Remove the third argument from `pageheader` because after looking at the helper method's signature, I see that it's not necessary. Refs #4189 --- app/controllers/routes_controller.rb | 1 + app/views/routes/duplicate.html.slim | 3 +-- config/locales/routes.en.yml | 2 ++ config/locales/routes.fr.yml | 2 ++ 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/controllers/routes_controller.rb b/app/controllers/routes_controller.rb index c4182af56..7e10366b3 100644 --- a/app/controllers/routes_controller.rb +++ b/app/controllers/routes_controller.rb @@ -70,6 +70,7 @@ class RoutesController < ChouetteController end def duplicate + @route = Chouette::Route.find(params[:id]) end protected diff --git a/app/views/routes/duplicate.html.slim b/app/views/routes/duplicate.html.slim index a5947049d..2c894cc47 100644 --- a/app/views/routes/duplicate.html.slim +++ b/app/views/routes/duplicate.html.slim @@ -1,6 +1,5 @@ = pageheader 'map-marker', - t('routes.new.title'), - '' + t('routes.duplicate.title', route: @route.name) .page_content .container-fluid diff --git a/config/locales/routes.en.yml b/config/locales/routes.en.yml index 3099d4ab1..be704fe15 100644 --- a/config/locales/routes.en.yml +++ b/config/locales/routes.en.yml @@ -32,6 +32,8 @@ en: stop_area_name: "Stop area name" for_boarding: "Boarding" for_alighting: "Alighting" + duplicate: + title: "Duplicate route %{route}" route: no_journey_pattern: "No Journey pattern" wayback: diff --git a/config/locales/routes.fr.yml b/config/locales/routes.fr.yml index 0af2832a2..986e9ba9e 100644 --- a/config/locales/routes.fr.yml +++ b/config/locales/routes.fr.yml @@ -32,6 +32,8 @@ fr: stop_area_name: "Nom de l'arrêt" for_boarding: "Montée" for_alighting: "Descente" + duplicate: + title: "Dupliquer l'itinéraire %{route}" route: no_journey_pattern: "Pas de mission" wayback: -- cgit v1.2.3 From 1d490afb5b616f15837259d093d458357f17a439 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 7 Aug 2017 15:06:21 +0200 Subject: Routes#duplicate: Add breadcrumb to page Build a breadcrumb. In order to do so, we need to set the `@line` instance variable (how would I know that? I wouldn't, damn implicit dependencies). Refs #4189 --- app/controllers/routes_controller.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/routes_controller.rb b/app/controllers/routes_controller.rb index 7e10366b3..852477c5c 100644 --- a/app/controllers/routes_controller.rb +++ b/app/controllers/routes_controller.rb @@ -71,6 +71,8 @@ class RoutesController < ChouetteController def duplicate @route = Chouette::Route.find(params[:id]) + @line = @route.line + build_breadcrumb(:edit) end protected -- cgit v1.2.3 From 0b79907ea95a1f2fa9c8766474773f6555f49f37 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 7 Aug 2017 16:51:19 +0200 Subject: RoutesController: Add separate method for POST /duplicate Send POST requests for duplication to a new controller method so we can more easily handle them and separate setup and creation code. Note that the test doesn't work. The `to change` part succeeds even though it shouldn't. Still need to figure out what's going on there, but committing this to hand off the feature to Robert. Refs #4189 --- app/controllers/routes_controller.rb | 4 ++++ config/routes.rb | 2 +- spec/controllers/routes_controller_spec.rb | 17 +++++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/app/controllers/routes_controller.rb b/app/controllers/routes_controller.rb index 852477c5c..e20ae9d14 100644 --- a/app/controllers/routes_controller.rb +++ b/app/controllers/routes_controller.rb @@ -75,6 +75,10 @@ class RoutesController < ChouetteController build_breadcrumb(:edit) end + def post_duplicate + @route = Chouette::Route.find(params[:id]) + end + protected alias_method :route, :resource diff --git a/config/routes.rb b/config/routes.rb index b738c0943..e73a2a494 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -111,7 +111,7 @@ ChouetteIhm::Application.routes.draw do get 'edit_boarding_alighting' put 'save_boarding_alighting' get 'duplicate' - post 'duplicate' + post 'duplicate', to: 'routes#post_duplicate' end resource :journey_patterns_collection, :only => [:show, :update] resources :journey_patterns do diff --git a/spec/controllers/routes_controller_spec.rb b/spec/controllers/routes_controller_spec.rb index 5c17b78b8..3862d8173 100644 --- a/spec/controllers/routes_controller_spec.rb +++ b/spec/controllers/routes_controller_spec.rb @@ -85,4 +85,21 @@ RSpec.describe RoutesController, type: :controller do expect(response).to be_success end end + + describe "POST /duplicate" do + it "creates a new route" do + expect do + post :duplicate, + referential_id: route.line.line_referential_id, + line_id: route.line_id, + id: route.id, + params: { + name: '102 Route', + published_name: '102 route' + } + end.to change { Chouette::Route.count }.by(1) + + expect(Chouette::Route.last.name).to eq('102 Route') + end + end end -- cgit v1.2.3 From f282c2db36440b55044b90791dd21eb2b325f8d3 Mon Sep 17 00:00:00 2001 From: Robert Date: Tue, 8 Aug 2017 12:19:49 +0200 Subject: Refs: #4189@0.5h; routing specs updated to specify desired behavior exactly --- spec/routing/routes_routing_spec.rb | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/spec/routing/routes_routing_spec.rb b/spec/routing/routes_routing_spec.rb index ca2d3ade9..4635603d4 100644 --- a/spec/routing/routes_routing_spec.rb +++ b/spec/routing/routes_routing_spec.rb @@ -1,11 +1,18 @@ RSpec.describe "routes for Routes", type: :routing do - it "routes to /referentials/:id/lines/:id/routes/:id/duplicate" do - expect( - get: '/referentials/:referential_id/lines/:line_id/routes/:id/duplicate' - ).to be_routable + context "routes /referentials/:id/lines/:id/routes/:id/duplicate" do - expect( - post: '/referentials/:referential_id/lines/:line_id/routes/:id/duplicate' - ).to be_routable + let( :controller ){ {controller: 'routes', referential_id: ':referential_id', line_id: ':line_id', id: ':id'} } + + it 'with method get to #duplicate' do + expect( + get: '/referentials/:referential_id/lines/:line_id/routes/:id/duplicate' + ).to route_to controller.merge(action: 'duplicate') + end + + it 'with method post to #post_duplicate' do + expect( + post: '/referentials/:referential_id/lines/:line_id/routes/:id/duplicate' + ).to route_to controller.merge(action: 'post_duplicate') + end end end -- cgit v1.2.3 From 05417c824f043665cb46d9f837aaf66cd8b787e4 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 7 Aug 2017 11:45:03 +0200 Subject: Add routes to Routes#duplicate A couple of new routes for a form that will allow us to duplicate an itinéraire/route inside a line. Refs #4189 --- app/controllers/routes_controller.rb | 3 +++ config/routes.rb | 2 ++ spec/routing/routes_routing_spec.rb | 11 +++++++++++ 3 files changed, 16 insertions(+) create mode 100644 spec/routing/routes_routing_spec.rb diff --git a/app/controllers/routes_controller.rb b/app/controllers/routes_controller.rb index 7ba2c1a58..6455cb2da 100644 --- a/app/controllers/routes_controller.rb +++ b/app/controllers/routes_controller.rb @@ -69,6 +69,9 @@ class RoutesController < ChouetteController end end + def duplicate + end + # def update # update! do |success, failure| # success.html { redirect_to referential_line_path(@referential,@line) } diff --git a/config/routes.rb b/config/routes.rb index 0ed401cf5..b738c0943 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -110,6 +110,8 @@ ChouetteIhm::Application.routes.draw do member do get 'edit_boarding_alighting' put 'save_boarding_alighting' + get 'duplicate' + post 'duplicate' end resource :journey_patterns_collection, :only => [:show, :update] resources :journey_patterns do diff --git a/spec/routing/routes_routing_spec.rb b/spec/routing/routes_routing_spec.rb new file mode 100644 index 000000000..ca2d3ade9 --- /dev/null +++ b/spec/routing/routes_routing_spec.rb @@ -0,0 +1,11 @@ +RSpec.describe "routes for Routes", type: :routing do + it "routes to /referentials/:id/lines/:id/routes/:id/duplicate" do + expect( + get: '/referentials/:referential_id/lines/:line_id/routes/:id/duplicate' + ).to be_routable + + expect( + post: '/referentials/:referential_id/lines/:line_id/routes/:id/duplicate' + ).to be_routable + end +end -- cgit v1.2.3 From 257c36955ce2446fcfd08f1c1d24f32815006e7a Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 7 Aug 2017 11:50:25 +0200 Subject: RoutesController: Get rid of old commented code This method was commented out in 2012. Safe to say we can remove it. --- app/controllers/routes_controller.rb | 5 ----- 1 file changed, 5 deletions(-) diff --git a/app/controllers/routes_controller.rb b/app/controllers/routes_controller.rb index 6455cb2da..c4182af56 100644 --- a/app/controllers/routes_controller.rb +++ b/app/controllers/routes_controller.rb @@ -72,11 +72,6 @@ class RoutesController < ChouetteController def duplicate end - # def update - # update! do |success, failure| - # success.html { redirect_to referential_line_path(@referential,@line) } - # end - # end protected alias_method :route, :resource -- cgit v1.2.3 From 57d8bc73baccd53b741d2b8a17601979a5a44cb2 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 7 Aug 2017 11:52:16 +0200 Subject: routes_controller_spec.rb: Clean up whitespace --- spec/controllers/routes_controller_spec.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/controllers/routes_controller_spec.rb b/spec/controllers/routes_controller_spec.rb index 000b799db..44f552a3b 100644 --- a/spec/controllers/routes_controller_spec.rb +++ b/spec/controllers/routes_controller_spec.rb @@ -10,6 +10,7 @@ RSpec.describe RoutesController, :type => :controller do # expect(response).to redirect_to( referential_line_path(referential,route.line) ) end end + shared_examples_for "line and referential linked" do it "assigns route.line as @line" do expect(assigns[:line]).to eq(route.line) @@ -19,6 +20,7 @@ RSpec.describe RoutesController, :type => :controller do expect(assigns[:referential]).to eq(referential) end end + shared_examples_for "route, line and referential linked" do it "assigns route as @route" do expect(assigns[:route]).to eq(route) @@ -78,4 +80,3 @@ RSpec.describe RoutesController, :type => :controller do end end - -- cgit v1.2.3 From a407ae36f611c15dc7985d65b369938315eebc20 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 7 Aug 2017 11:52:58 +0200 Subject: routes_controller_spec.rb: Remove old commented test This test was commented out in 2015. Safe to say we can remove it now. --- spec/controllers/routes_controller_spec.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/spec/controllers/routes_controller_spec.rb b/spec/controllers/routes_controller_spec.rb index 44f552a3b..4adf05ed2 100644 --- a/spec/controllers/routes_controller_spec.rb +++ b/spec/controllers/routes_controller_spec.rb @@ -73,10 +73,6 @@ RSpec.describe RoutesController, :type => :controller do expect(assigns[:map]).to be_an_instance_of(RouteMap) expect(assigns[:map].route).to eq(route) end - - #it "assigns route.stop_points.paginate(:page => nil) as @stop_points" do - # expect(assigns[:stop_points]).to eq(route.stop_points.paginate(:page => nil)) - #end end end -- cgit v1.2.3 From b9861c01c1cb45b3214b2a2c4758fb971330e355 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 7 Aug 2017 12:00:53 +0200 Subject: routes_controller_spec.rb: Use lazy let Don't force creation of the `route`, create it lazily. Refs #4189 --- spec/controllers/routes_controller_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/controllers/routes_controller_spec.rb b/spec/controllers/routes_controller_spec.rb index 4adf05ed2..414583eb3 100644 --- a/spec/controllers/routes_controller_spec.rb +++ b/spec/controllers/routes_controller_spec.rb @@ -1,7 +1,7 @@ RSpec.describe RoutesController, :type => :controller do login_user - let!(:route) { create(:route) } + let(:route) { create(:route) } it { is_expected.to be_kind_of(ChouetteController) } -- cgit v1.2.3 From d4353b2edc764350befcc28a26ce1d9a774e3de2 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 7 Aug 2017 12:16:43 +0200 Subject: routes_controller_spec.rb: Convert to new Ruby hash syntax --- spec/controllers/routes_controller_spec.rb | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/spec/controllers/routes_controller_spec.rb b/spec/controllers/routes_controller_spec.rb index 414583eb3..cf12f00b1 100644 --- a/spec/controllers/routes_controller_spec.rb +++ b/spec/controllers/routes_controller_spec.rb @@ -1,4 +1,4 @@ -RSpec.describe RoutesController, :type => :controller do +RSpec.describe RoutesController, type: :controller do login_user let(:route) { create(:route) } @@ -30,8 +30,8 @@ RSpec.describe RoutesController, :type => :controller do describe "GET /index" do before(:each) do - get :index, :line_id => route.line_id, - :referential_id => referential.id + get :index, line_id: route.line_id, + referential_id: referential.id end it_behaves_like "line and referential linked" @@ -40,9 +40,9 @@ RSpec.describe RoutesController, :type => :controller do describe "POST /create" do before(:each) do - post :create, :line_id => route.line_id, - :referential_id => referential.id, - :route => { :name => "changed"} + post :create, line_id: route.line_id, + referential_id: referential.id, + route: { name: "changed"} end it_behaves_like "line and referential linked" @@ -51,9 +51,9 @@ RSpec.describe RoutesController, :type => :controller do describe "PUT /update" do before(:each) do - put :update, :id => route.id, :line_id => route.line_id, - :referential_id => referential.id, - :route => route.attributes + put :update, id: route.id, line_id: route.line_id, + referential_id: referential.id, + route: route.attributes end it_behaves_like "route, line and referential linked" @@ -62,9 +62,9 @@ RSpec.describe RoutesController, :type => :controller do describe "GET /show" do before(:each) do - get :show, :id => route.id, - :line_id => route.line_id, - :referential_id => referential.id + get :show, id: route.id, + line_id: route.line_id, + referential_id: referential.id end it_behaves_like "route, line and referential linked" -- cgit v1.2.3 From 33d5b92305e063e52500ff17a75a5bfb7fe98043 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 7 Aug 2017 12:19:04 +0200 Subject: Add views/routes/duplicate.html.slim Duplicate of new.html.slim for now just to get the page working. Refs #4189 --- app/views/routes/duplicate.html.slim | 9 +++++++++ spec/controllers/routes_controller_spec.rb | 10 ++++++++++ 2 files changed, 19 insertions(+) create mode 100644 app/views/routes/duplicate.html.slim diff --git a/app/views/routes/duplicate.html.slim b/app/views/routes/duplicate.html.slim new file mode 100644 index 000000000..a5947049d --- /dev/null +++ b/app/views/routes/duplicate.html.slim @@ -0,0 +1,9 @@ += pageheader 'map-marker', + t('routes.new.title'), + '' + +.page_content + .container-fluid + .row + .col-lg-8.col-lg-offset-2.col-md-8.col-md-offset-2.col-sm-10.col-sm-offset-1 + == render 'form' diff --git a/spec/controllers/routes_controller_spec.rb b/spec/controllers/routes_controller_spec.rb index cf12f00b1..5c17b78b8 100644 --- a/spec/controllers/routes_controller_spec.rb +++ b/spec/controllers/routes_controller_spec.rb @@ -75,4 +75,14 @@ RSpec.describe RoutesController, type: :controller do end end + describe "GET /duplicate" do + it "returns success" do + get :duplicate, + referential_id: route.line.line_referential_id, + line_id: route.line_id, + id: route.id + + expect(response).to be_success + end + end end -- cgit v1.2.3 From 2458830edbdbe6b098233d59356c7c0b2ef59b9f Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 7 Aug 2017 15:04:42 +0200 Subject: Routes#duplicate: Add page header Set header text in the locale files and display it on the page given the route ID in the URL. Remove the third argument from `pageheader` because after looking at the helper method's signature, I see that it's not necessary. Refs #4189 --- app/controllers/routes_controller.rb | 1 + app/views/routes/duplicate.html.slim | 3 +-- config/locales/routes.en.yml | 2 ++ config/locales/routes.fr.yml | 2 ++ 4 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/controllers/routes_controller.rb b/app/controllers/routes_controller.rb index c4182af56..7e10366b3 100644 --- a/app/controllers/routes_controller.rb +++ b/app/controllers/routes_controller.rb @@ -70,6 +70,7 @@ class RoutesController < ChouetteController end def duplicate + @route = Chouette::Route.find(params[:id]) end protected diff --git a/app/views/routes/duplicate.html.slim b/app/views/routes/duplicate.html.slim index a5947049d..2c894cc47 100644 --- a/app/views/routes/duplicate.html.slim +++ b/app/views/routes/duplicate.html.slim @@ -1,6 +1,5 @@ = pageheader 'map-marker', - t('routes.new.title'), - '' + t('routes.duplicate.title', route: @route.name) .page_content .container-fluid diff --git a/config/locales/routes.en.yml b/config/locales/routes.en.yml index 3099d4ab1..be704fe15 100644 --- a/config/locales/routes.en.yml +++ b/config/locales/routes.en.yml @@ -32,6 +32,8 @@ en: stop_area_name: "Stop area name" for_boarding: "Boarding" for_alighting: "Alighting" + duplicate: + title: "Duplicate route %{route}" route: no_journey_pattern: "No Journey pattern" wayback: diff --git a/config/locales/routes.fr.yml b/config/locales/routes.fr.yml index 0af2832a2..986e9ba9e 100644 --- a/config/locales/routes.fr.yml +++ b/config/locales/routes.fr.yml @@ -32,6 +32,8 @@ fr: stop_area_name: "Nom de l'arrêt" for_boarding: "Montée" for_alighting: "Descente" + duplicate: + title: "Dupliquer l'itinéraire %{route}" route: no_journey_pattern: "Pas de mission" wayback: -- cgit v1.2.3 From 8cea700c7ebc1e9daf8eda4b35e9d9c28e46249c Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 7 Aug 2017 15:06:21 +0200 Subject: Routes#duplicate: Add breadcrumb to page Build a breadcrumb. In order to do so, we need to set the `@line` instance variable (how would I know that? I wouldn't, damn implicit dependencies). Refs #4189 --- app/controllers/routes_controller.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/routes_controller.rb b/app/controllers/routes_controller.rb index 7e10366b3..852477c5c 100644 --- a/app/controllers/routes_controller.rb +++ b/app/controllers/routes_controller.rb @@ -71,6 +71,8 @@ class RoutesController < ChouetteController def duplicate @route = Chouette::Route.find(params[:id]) + @line = @route.line + build_breadcrumb(:edit) end protected -- cgit v1.2.3 From 51b73758486294862c47707d9b85e7cefeb0242a Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 7 Aug 2017 16:51:19 +0200 Subject: RoutesController: Add separate method for POST /duplicate Send POST requests for duplication to a new controller method so we can more easily handle them and separate setup and creation code. Note that the test doesn't work. The `to change` part succeeds even though it shouldn't. Still need to figure out what's going on there, but committing this to hand off the feature to Robert. Refs #4189 --- app/controllers/routes_controller.rb | 4 ++++ config/routes.rb | 2 +- spec/controllers/routes_controller_spec.rb | 17 +++++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/app/controllers/routes_controller.rb b/app/controllers/routes_controller.rb index 852477c5c..e20ae9d14 100644 --- a/app/controllers/routes_controller.rb +++ b/app/controllers/routes_controller.rb @@ -75,6 +75,10 @@ class RoutesController < ChouetteController build_breadcrumb(:edit) end + def post_duplicate + @route = Chouette::Route.find(params[:id]) + end + protected alias_method :route, :resource diff --git a/config/routes.rb b/config/routes.rb index b738c0943..e73a2a494 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -111,7 +111,7 @@ ChouetteIhm::Application.routes.draw do get 'edit_boarding_alighting' put 'save_boarding_alighting' get 'duplicate' - post 'duplicate' + post 'duplicate', to: 'routes#post_duplicate' end resource :journey_patterns_collection, :only => [:show, :update] resources :journey_patterns do diff --git a/spec/controllers/routes_controller_spec.rb b/spec/controllers/routes_controller_spec.rb index 5c17b78b8..3862d8173 100644 --- a/spec/controllers/routes_controller_spec.rb +++ b/spec/controllers/routes_controller_spec.rb @@ -85,4 +85,21 @@ RSpec.describe RoutesController, type: :controller do expect(response).to be_success end end + + describe "POST /duplicate" do + it "creates a new route" do + expect do + post :duplicate, + referential_id: route.line.line_referential_id, + line_id: route.line_id, + id: route.id, + params: { + name: '102 Route', + published_name: '102 route' + } + end.to change { Chouette::Route.count }.by(1) + + expect(Chouette::Route.last.name).to eq('102 Route') + end + end end -- cgit v1.2.3 From e5e44b82fcda9382b5ef5b7cbf0c1ef81fda0404 Mon Sep 17 00:00:00 2001 From: Robert Date: Tue, 8 Aug 2017 12:19:49 +0200 Subject: Refs: #4189@0.5h; routing specs updated to specify desired behavior exactly --- spec/routing/routes_routing_spec.rb | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/spec/routing/routes_routing_spec.rb b/spec/routing/routes_routing_spec.rb index ca2d3ade9..4635603d4 100644 --- a/spec/routing/routes_routing_spec.rb +++ b/spec/routing/routes_routing_spec.rb @@ -1,11 +1,18 @@ RSpec.describe "routes for Routes", type: :routing do - it "routes to /referentials/:id/lines/:id/routes/:id/duplicate" do - expect( - get: '/referentials/:referential_id/lines/:line_id/routes/:id/duplicate' - ).to be_routable + context "routes /referentials/:id/lines/:id/routes/:id/duplicate" do - expect( - post: '/referentials/:referential_id/lines/:line_id/routes/:id/duplicate' - ).to be_routable + let( :controller ){ {controller: 'routes', referential_id: ':referential_id', line_id: ':line_id', id: ':id'} } + + it 'with method get to #duplicate' do + expect( + get: '/referentials/:referential_id/lines/:line_id/routes/:id/duplicate' + ).to route_to controller.merge(action: 'duplicate') + end + + it 'with method post to #post_duplicate' do + expect( + post: '/referentials/:referential_id/lines/:line_id/routes/:id/duplicate' + ).to route_to controller.merge(action: 'post_duplicate') + end end end -- cgit v1.2.3 From 5aac56771ca08f414a52c6a59f502b5f371768b9 Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 14 Aug 2017 15:08:33 +0200 Subject: cosmetic ut8 removal [amend me] --- app/models/stop_area_copy.rb | 2 -- 1 file changed, 2 deletions(-) diff --git a/app/models/stop_area_copy.rb b/app/models/stop_area_copy.rb index 0fa56ff68..d3eb78557 100644 --- a/app/models/stop_area_copy.rb +++ b/app/models/stop_area_copy.rb @@ -1,5 +1,3 @@ -# -*- coding: utf-8 -*- - class StopAreaCopy include ActiveModel::Validations include ActiveModel::Conversion -- cgit v1.2.3 From c16c03b91174cf637e0bd2f0e3336e3788f43e59 Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 14 Aug 2017 18:41:14 +0200 Subject: Refs: #4189@3h; Specing Chouette::Route#duplicate (no stubbed spec, alas) --- .../chouette/route/route_duplication_spec.rb | 31 ++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 spec/models/chouette/route/route_duplication_spec.rb diff --git a/spec/models/chouette/route/route_duplication_spec.rb b/spec/models/chouette/route/route_duplication_spec.rb new file mode 100644 index 000000000..fe8d5e444 --- /dev/null +++ b/spec/models/chouette/route/route_duplication_spec.rb @@ -0,0 +1,31 @@ +# From Chouette import what we need ™ +Route = Chouette::Route +StopArea = Chouette::StopArea +StopPoint = Chouette::StopPoint + +RSpec.describe Route do + + let( :route ){ create :route } + + context 'duplicates' do + describe 'a route' do + it 'by creating a new one' do + expect{ route.duplicate }.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 ) ) + 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 + end + end + +end -- cgit v1.2.3 From 373a4089173795d011ebd6adf7382b2a5e40a51b Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 14 Aug 2017 18:42:08 +0200 Subject: 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 --- app/models/chouette/route.rb | 24 +++++++++++++++-- app/models/chouette/stop_point.rb | 19 +++++++++++--- .../chouette/route/route_duplication_spec.rb | 28 ++++++++++---------- spec/models/chouette/stop_point_spec.rb | 30 ++++++++++++++++++++-- spec/support/helpers/model_compare_helpers.rb | 12 +++++++++ 5 files changed, 92 insertions(+), 21 deletions(-) create mode 100644 spec/support/helpers/model_compare_helpers.rb 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 -- cgit v1.2.3 From f4863d7ea2e580ee1eb5f5cf498c07441e3ccff3 Mon Sep 17 00:00:00 2001 From: Robert Date: Wed, 16 Aug 2017 06:57:07 +0200 Subject: Refs: #4189@1h; Implementation of Chouette::Route#duplicate & Chouette::StopPoint#duplicate Implementing, as specified: - The duplicated Route objectid is autogenerated - The duplicated StopPoint objectids are autogenerated - the duplicated Route object_version equals the source's one (UNCHANGED) --- app/models/chouette/route.rb | 6 +-- app/models/chouette/stop_point.rb | 8 +--- .../chouette/route/route_duplication_spec.rb | 44 +++++++++++++++------- spec/models/chouette/stop_point_spec.rb | 11 ------ 4 files changed, 35 insertions(+), 34 deletions(-) diff --git a/app/models/chouette/route.rb b/app/models/chouette/route.rb index 0fe4472d3..3e20dc43e 100644 --- a/app/models/chouette/route.rb +++ b/app/models/chouette/route.rb @@ -76,11 +76,11 @@ 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} + def duplicate + keys_for_create = attributes.keys - %w{id objectid created_at updated_at} atts_for_create = attributes .slice(*keys_for_create) - .merge('objectid' => new_objectid, 'object_version' => object_version - 1) + .merge('object_version' => object_version - 1) new_route = self.class.create!(atts_for_create) duplicate_stop_points(for_route: new_route) new_route diff --git a/app/models/chouette/stop_point.rb b/app/models/chouette/stop_point.rb index de9a3e26f..89c492b91 100644 --- a/app/models/chouette/stop_point.rb +++ b/app/models/chouette/stop_point.rb @@ -40,14 +40,10 @@ module Chouette 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} + keys_for_create = attributes.keys - %w{id objectid created_at updated_at} atts_for_create = attributes .slice(*keys_for_create) - .merge('objectid' => new_objectid, 'route_id' => for_route.id) + .merge('route_id' => for_route.id) self.class.create!(atts_for_create) end diff --git a/spec/models/chouette/route/route_duplication_spec.rb b/spec/models/chouette/route/route_duplication_spec.rb index 6168d1e38..f24435cf6 100644 --- a/spec/models/chouette/route/route_duplication_spec.rb +++ b/spec/models/chouette/route/route_duplication_spec.rb @@ -6,27 +6,43 @@ StopPoint = Chouette::StopPoint RSpec.describe Route do 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 new_objectid }.to change{Route.count}.by(1) - end - it 'with the same values' do - route.duplicate new_objectid + context '#duplicate' do + describe 'properties' do + it 'same attribute values' do + route.duplicate expect( values_for_create(Route.last, except: %w{objectid}) ).to eq( values_for_create( route, except: %w{objectid} ) ) end + it 'same associated stop_areeas' do + expect( route.duplicate.stop_areas.pluck(:id) ).to eq(route.stop_areas.pluck(:id)) + end + end - it 'and also duplicating its stop points' do - expect{ route.duplicate new_objectid }.to change{StopPoint.count}.by(route.stop_points.count) + describe 'side_effects' do + it { + expect{ route.duplicate }.to change{Route.count}.by(1) + } + it 'duplicates its stop points' do + expect{ route.duplicate }.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} + it 'does bot duplicate the stop areas' do + expect{ route.duplicate }.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 + + describe 'is idempotent, concerning' do + let( :first_duplicate ){ route.duplicate } + let( :second_duplicate ){ first_duplicate.reload.duplicate } + + it 'the required attributes' do + expect( values_for_create(first_duplicate, except: %w{objectid}) ).to eq( values_for_create( second_duplicate, except: %w{objectid} ) ) + end + + it 'the stop areas' do + expect( first_duplicate.stop_areas.pluck(:id) ).to eq( route.stop_areas.pluck(:id) ) + expect( second_duplicate.stop_areas.pluck(:id) ).to eq( first_duplicate.stop_areas.pluck(:id) ) end + end end diff --git a/spec/models/chouette/stop_point_spec.rb b/spec/models/chouette/stop_point_spec.rb index c43774085..d0314b8db 100644 --- a/spec/models/chouette/stop_point_spec.rb +++ b/spec/models/chouette/stop_point_spec.rb @@ -52,16 +52,5 @@ describe StopPoint, :type => :model do 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 -- cgit v1.2.3 From 003c4689248673fbc8922a107475caa9e059bcab Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 21 Aug 2017 14:45:53 +0200 Subject: Refs: #4189@4h; Allowing change of `name` and `public_name` in `Chouette::Route#duplicate` --- app/models/chouette/route.rb | 9 +++++++-- spec/models/chouette/route/route_duplication_spec.rb | 18 +++++++++++++++++- spec/support/helpers/model_compare_helpers.rb | 7 +++++-- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/app/models/chouette/route.rb b/app/models/chouette/route.rb index 3e20dc43e..049ee2881 100644 --- a/app/models/chouette/route.rb +++ b/app/models/chouette/route.rb @@ -76,11 +76,16 @@ class Chouette::Route < Chouette::TridentActiveRecord after_commit :journey_patterns_control_route_sections - def duplicate + def duplicate name: nil, published_name: nil + overrides = { + 'name' => name || self.name, + 'published_name' => published_name || self.published_name, + 'object_version' => object_version - 1 + } keys_for_create = attributes.keys - %w{id objectid created_at updated_at} atts_for_create = attributes .slice(*keys_for_create) - .merge('object_version' => object_version - 1) + .merge(overrides) new_route = self.class.create!(atts_for_create) duplicate_stop_points(for_route: new_route) new_route diff --git a/spec/models/chouette/route/route_duplication_spec.rb b/spec/models/chouette/route/route_duplication_spec.rb index f24435cf6..74e944181 100644 --- a/spec/models/chouette/route/route_duplication_spec.rb +++ b/spec/models/chouette/route/route_duplication_spec.rb @@ -13,6 +13,22 @@ RSpec.describe Route do route.duplicate expect( values_for_create(Route.last, except: %w{objectid}) ).to eq( values_for_create( route, except: %w{objectid} ) ) end + it 'but some can be redefined optionally', :wip do + excluded_attributes = %w{objectid checksum checksum_source} + expected_attributes = values_for_create( + route, + name: 'new name', + published_name: 'new published name', + except: excluded_attributes ) + + route.duplicate name: 'new name', published_name: 'new published name' + expect( + values_for_create(Route.last, except: excluded_attributes) + ).to eq( expected_attributes ) + end + it 'and others cannot' do + expect{ route.duplicate name: 'YAN', line_id: 42 }.to raise_error(ArgumentError) + end it 'same associated stop_areeas' do expect( route.duplicate.stop_areas.pluck(:id) ).to eq(route.stop_areas.pluck(:id)) end @@ -33,7 +49,7 @@ RSpec.describe Route do describe 'is idempotent, concerning' do let( :first_duplicate ){ route.duplicate } let( :second_duplicate ){ first_duplicate.reload.duplicate } - + it 'the required attributes' do expect( values_for_create(first_duplicate, except: %w{objectid}) ).to eq( values_for_create( second_duplicate, except: %w{objectid} ) ) end diff --git a/spec/support/helpers/model_compare_helpers.rb b/spec/support/helpers/model_compare_helpers.rb index 97e26f300..a10892af0 100644 --- a/spec/support/helpers/model_compare_helpers.rb +++ b/spec/support/helpers/model_compare_helpers.rb @@ -1,8 +1,11 @@ module Support::ModelCompareHelpers - def values_for_create obj, except: [] + def values_for_create obj, **overrides + except = overrides.delete(:except) || [] keys = obj.attributes.keys - except - %w{id created_at updated_at} - obj.attributes.slice(*keys) + overrides.inject(obj.attributes.slice(*keys)){ |atts, (k,v)| + atts.merge k.to_s => v + } end end -- cgit v1.2.3 From f7bc874de79ff9a68aa03523cf653407663e7c55 Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 11 Sep 2017 09:41:03 +0200 Subject: Fixes #4189@4h Route Duplication * Duplication of Route is triggered by link and UI forwarded to edit of duplicatee - Changing route, only POST duplicate_referential_line_route --> RoutesController#duplicate - Removing route GET duplicate_referential_line_route --> RoutesController#duplicate - Removing controller action RoutesController#post_duplicate * Link in Route Decorator depends on new policy RoutePolicy#decorate? * Adapting specs --- app/controllers/routes_controller.rb | 9 ++------ app/decorators/route_decorator.rb | 12 ++++++++++ app/models/chouette/route.rb | 7 +++--- app/policies/route_policy.rb | 4 ++++ app/views/routes/duplicate.html.slim | 8 ------- config/locales/routes.en.yml | 2 +- config/locales/routes.fr.yml | 2 +- config/routes.rb | 3 +-- spec/controllers/routes_controller_spec.rb | 27 ++++++++-------------- .../chouette/route/route_duplication_spec.rb | 13 ----------- spec/policies/route_policy_spec.rb | 4 ++++ spec/routing/routes_routing_spec.rb | 8 +------ 12 files changed, 38 insertions(+), 61 deletions(-) delete mode 100644 app/views/routes/duplicate.html.slim diff --git a/app/controllers/routes_controller.rb b/app/controllers/routes_controller.rb index e20ae9d14..04f63c112 100644 --- a/app/controllers/routes_controller.rb +++ b/app/controllers/routes_controller.rb @@ -70,13 +70,8 @@ class RoutesController < ChouetteController end def duplicate - @route = Chouette::Route.find(params[:id]) - @line = @route.line - build_breadcrumb(:edit) - end - - def post_duplicate - @route = Chouette::Route.find(params[:id]) + route = Chouette::Route.find(params[:id]).duplicate + redirect_to edit_referential_line_route_path(@referential, route.line, route) end protected diff --git a/app/decorators/route_decorator.rb b/app/decorators/route_decorator.rb index 484c3db04..46cb6cd5f 100644 --- a/app/decorators/route_decorator.rb +++ b/app/decorators/route_decorator.rb @@ -58,6 +58,18 @@ class RouteDecorator < Draper::Decorator ) end + if h.policy(object).duplicate? + links << Link.new( + content: h.t('routes.duplicate.title'), + href: h.duplicate_referential_line_route_path( + context[:referential], + context[:line], + object + ), + method: :post + ) + end + links end end diff --git a/app/models/chouette/route.rb b/app/models/chouette/route.rb index 049ee2881..cab877dc7 100644 --- a/app/models/chouette/route.rb +++ b/app/models/chouette/route.rb @@ -76,11 +76,10 @@ class Chouette::Route < Chouette::TridentActiveRecord after_commit :journey_patterns_control_route_sections - def duplicate name: nil, published_name: nil + def duplicate overrides = { - 'name' => name || self.name, - 'published_name' => published_name || self.published_name, - 'object_version' => object_version - 1 + 'object_version' => object_version - 1, + 'opposite_route_id' => nil } keys_for_create = attributes.keys - %w{id objectid created_at updated_at} atts_for_create = attributes diff --git a/app/policies/route_policy.rb b/app/policies/route_policy.rb index 786b0acf4..7e9fe251a 100644 --- a/app/policies/route_policy.rb +++ b/app/policies/route_policy.rb @@ -16,4 +16,8 @@ class RoutePolicy < ApplicationPolicy def update? !archived? && organisation_match? && user.has_permission?('routes.update') end + + def duplicate? + create? + end end diff --git a/app/views/routes/duplicate.html.slim b/app/views/routes/duplicate.html.slim deleted file mode 100644 index 2c894cc47..000000000 --- a/app/views/routes/duplicate.html.slim +++ /dev/null @@ -1,8 +0,0 @@ -= pageheader 'map-marker', - t('routes.duplicate.title', route: @route.name) - -.page_content - .container-fluid - .row - .col-lg-8.col-lg-offset-2.col-md-8.col-md-offset-2.col-sm-10.col-sm-offset-1 - == render 'form' diff --git a/config/locales/routes.en.yml b/config/locales/routes.en.yml index be704fe15..e94adf490 100644 --- a/config/locales/routes.en.yml +++ b/config/locales/routes.en.yml @@ -33,7 +33,7 @@ en: for_boarding: "Boarding" for_alighting: "Alighting" duplicate: - title: "Duplicate route %{route}" + title: "Duplicate route" route: no_journey_pattern: "No Journey pattern" wayback: diff --git a/config/locales/routes.fr.yml b/config/locales/routes.fr.yml index 986e9ba9e..a494e60ec 100644 --- a/config/locales/routes.fr.yml +++ b/config/locales/routes.fr.yml @@ -33,7 +33,7 @@ fr: for_boarding: "Montée" for_alighting: "Descente" duplicate: - title: "Dupliquer l'itinéraire %{route}" + title: "Dupliquer l'itinéraire" route: no_journey_pattern: "Pas de mission" wayback: diff --git a/config/routes.rb b/config/routes.rb index e73a2a494..f6cf5e672 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -110,8 +110,7 @@ ChouetteIhm::Application.routes.draw do member do get 'edit_boarding_alighting' put 'save_boarding_alighting' - get 'duplicate' - post 'duplicate', to: 'routes#post_duplicate' + post 'duplicate', to: 'routes#duplicate' end resource :journey_patterns_collection, :only => [:show, :update] resources :journey_patterns do diff --git a/spec/controllers/routes_controller_spec.rb b/spec/controllers/routes_controller_spec.rb index 3862d8173..336f20945 100644 --- a/spec/controllers/routes_controller_spec.rb +++ b/spec/controllers/routes_controller_spec.rb @@ -1,3 +1,5 @@ +Route = Chouette::Route + RSpec.describe RoutesController, type: :controller do login_user @@ -75,31 +77,20 @@ RSpec.describe RoutesController, type: :controller do end end - describe "GET /duplicate" do - it "returns success" do - get :duplicate, - referential_id: route.line.line_referential_id, - line_id: route.line_id, - id: route.id - - expect(response).to be_success - end - end describe "POST /duplicate" do + let!( :route_prime ){ route } + it "creates a new route" do expect do post :duplicate, referential_id: route.line.line_referential_id, line_id: route.line_id, - id: route.id, - params: { - name: '102 Route', - published_name: '102 route' - } - end.to change { Chouette::Route.count }.by(1) - - expect(Chouette::Route.last.name).to eq('102 Route') + id: route.id + end.to change { Route.count }.by(1) + + expect(Route.last.name).to eq(route.name) + expect(Route.last.published_name).to eq(route.published_name) end end end diff --git a/spec/models/chouette/route/route_duplication_spec.rb b/spec/models/chouette/route/route_duplication_spec.rb index 74e944181..6645b909f 100644 --- a/spec/models/chouette/route/route_duplication_spec.rb +++ b/spec/models/chouette/route/route_duplication_spec.rb @@ -13,19 +13,6 @@ RSpec.describe Route do route.duplicate expect( values_for_create(Route.last, except: %w{objectid}) ).to eq( values_for_create( route, except: %w{objectid} ) ) end - it 'but some can be redefined optionally', :wip do - excluded_attributes = %w{objectid checksum checksum_source} - expected_attributes = values_for_create( - route, - name: 'new name', - published_name: 'new published name', - except: excluded_attributes ) - - route.duplicate name: 'new name', published_name: 'new published name' - expect( - values_for_create(Route.last, except: excluded_attributes) - ).to eq( expected_attributes ) - end it 'and others cannot' do expect{ route.duplicate name: 'YAN', line_id: 42 }.to raise_error(ArgumentError) end diff --git a/spec/policies/route_policy_spec.rb b/spec/policies/route_policy_spec.rb index 243d85acb..d7edceaef 100644 --- a/spec/policies/route_policy_spec.rb +++ b/spec/policies/route_policy_spec.rb @@ -6,6 +6,10 @@ RSpec.describe RoutePolicy, type: :policy do it_behaves_like 'permitted policy and same organisation', 'routes.create', archived: true end + permissions :duplicate? do + it_behaves_like 'permitted policy and same organisation', 'routes.create', archived: true + end + permissions :destroy? do it_behaves_like 'permitted policy and same organisation', 'routes.destroy', archived: true end diff --git a/spec/routing/routes_routing_spec.rb b/spec/routing/routes_routing_spec.rb index 4635603d4..311de9f39 100644 --- a/spec/routing/routes_routing_spec.rb +++ b/spec/routing/routes_routing_spec.rb @@ -3,16 +3,10 @@ RSpec.describe "routes for Routes", type: :routing do let( :controller ){ {controller: 'routes', referential_id: ':referential_id', line_id: ':line_id', id: ':id'} } - it 'with method get to #duplicate' do - expect( - get: '/referentials/:referential_id/lines/:line_id/routes/:id/duplicate' - ).to route_to controller.merge(action: 'duplicate') - end - it 'with method post to #post_duplicate' do expect( post: '/referentials/:referential_id/lines/:line_id/routes/:id/duplicate' - ).to route_to controller.merge(action: 'post_duplicate') + ).to route_to controller.merge(action: 'duplicate') end end end -- cgit v1.2.3 From 9810dd389cff0bd5dbda26e46806f62d28410ff4 Mon Sep 17 00:00:00 2001 From: Robert Date: Tue, 12 Sep 2017 09:10:02 +0200 Subject: Refs: #4189@2h; Fixing logical merging issues, preparing PR --- app/models/chouette/route.rb | 1 - spec/models/chouette/stop_point_spec.rb | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/models/chouette/route.rb b/app/models/chouette/route.rb index 8b04b95d0..e361b9e8c 100644 --- a/app/models/chouette/route.rb +++ b/app/models/chouette/route.rb @@ -78,7 +78,6 @@ class Chouette::Route < Chouette::TridentActiveRecord def duplicate overrides = { - 'object_version' => object_version - 1, 'opposite_route_id' => nil } keys_for_create = attributes.keys - %w{id objectid created_at updated_at} diff --git a/spec/models/chouette/stop_point_spec.rb b/spec/models/chouette/stop_point_spec.rb index 1be000b56..329e76a75 100644 --- a/spec/models/chouette/stop_point_spec.rb +++ b/spec/models/chouette/stop_point_spec.rb @@ -41,7 +41,7 @@ describe StopPoint, :type => :model do end describe '#duplicate' do - let!( :new_route ){ create :route, objectid: 'newroute:Route:1' } + let!( :new_route ){ create :route } it 'creates a new instance' do expect{ subject.duplicate(for_route: new_route) }.to change{ StopPoint.count }.by(1) -- cgit v1.2.3