diff options
| author | Zog | 2017-12-20 17:48:17 +0100 |
|---|---|---|
| committer | Alban Peignier | 2017-12-21 21:35:02 +0100 |
| commit | e8285678efc9a62115fe0af4086c7a3959666bf8 (patch) | |
| tree | 64b18197dff4d6707be10bfccca9240c601ffded | |
| parent | 01b2d2b785d99c9b031269fc741b70ee9c248f16 (diff) | |
| download | chouette-core-5349-deactivate-stop-areas.tar.bz2 | |
Refs #5349 @1h; Deactivate StopAreas instead of destroying them5349-deactivate-stop-areas
- Update decorators (had to split `action_links` because of
`StopPointDecorator` inheriting from `StopAreaDecorator`)
- Add methods on model
- Add routes
- Add actions on controller (`Activatable` concern, shared with
`LinesController`)
- Add I18n keys
| -rw-r--r-- | app/controllers/concerns/activatable.rb | 11 | ||||
| -rw-r--r-- | app/controllers/lines_controller.rb | 10 | ||||
| -rw-r--r-- | app/controllers/stop_areas_controller.rb | 3 | ||||
| -rw-r--r-- | app/decorators/stop_area_decorator.rb | 38 | ||||
| -rw-r--r-- | app/decorators/stop_point_decorator.rb | 2 | ||||
| -rw-r--r-- | app/models/chouette/stop_area.rb | 15 | ||||
| -rw-r--r-- | app/policies/stop_area_policy.rb | 8 | ||||
| -rw-r--r-- | config/locales/stop_areas.en.yml | 4 | ||||
| -rw-r--r-- | config/locales/stop_areas.fr.yml | 4 | ||||
| -rw-r--r-- | config/routes.rb | 12 | ||||
| -rw-r--r-- | spec/controllers/stop_areas_controller_spec.rb | 38 | ||||
| -rw-r--r-- | spec/factories/chouette_stop_areas.rb | 4 | ||||
| -rw-r--r-- | spec/views/stop_areas/index.html.slim_spec.rb | 54 |
13 files changed, 177 insertions, 26 deletions
diff --git a/app/controllers/concerns/activatable.rb b/app/controllers/concerns/activatable.rb new file mode 100644 index 000000000..1a34551a9 --- /dev/null +++ b/app/controllers/concerns/activatable.rb @@ -0,0 +1,11 @@ +module Activatable + extend ActiveSupport::Concern + + %w(activate deactivate).each do |action| + define_method action do + authorize resource, "#{action}?" + resource.send "#{action}!" + redirect_to request.referer || [current_referential, resource] + end + end +end diff --git a/app/controllers/lines_controller.rb b/app/controllers/lines_controller.rb index 676581076..f446e1d37 100644 --- a/app/controllers/lines_controller.rb +++ b/app/controllers/lines_controller.rb @@ -1,6 +1,8 @@ class LinesController < ChouetteController include ApplicationHelper + include Activatable include PolicyChecker + defaults :resource_class => Chouette::Line respond_to :html respond_to :xml @@ -50,14 +52,6 @@ class LinesController < ChouetteController super end - %w(activate deactivate).each do |action| - define_method action do - authorize resource, "#{action}?" - resource.send "#{action}!" - redirect_to request.referer || [resource.line_referential, resource] - end - end - # overwrite inherited resources to use delete instead of destroy # foreign keys will propagate deletion) def destroy_resource(object) diff --git a/app/controllers/stop_areas_controller.rb b/app/controllers/stop_areas_controller.rb index 498493f1e..b478d38fa 100644 --- a/app/controllers/stop_areas_controller.rb +++ b/app/controllers/stop_areas_controller.rb @@ -1,6 +1,7 @@ class StopAreasController < ChouetteController include ApplicationHelper - + include Activatable + defaults :resource_class => Chouette::StopArea belongs_to :stop_area_referential diff --git a/app/decorators/stop_area_decorator.rb b/app/decorators/stop_area_decorator.rb index cf3612f79..32f6e1d2b 100644 --- a/app/decorators/stop_area_decorator.rb +++ b/app/decorators/stop_area_decorator.rb @@ -3,12 +3,12 @@ class StopAreaDecorator < Draper::Decorator delegate_all - def action_links(stop_area = nil) - links = [] + def common_action_links(stop_area = nil) + top_links, bottom_links = [], [] stop_area ||= object if h.policy(stop_area).update? - links << Link.new( + top_links << Link.new( content: h.t('stop_areas.actions.edit'), href: h.edit_stop_area_referential_stop_area_path( stop_area.stop_area_referential, @@ -18,7 +18,7 @@ class StopAreaDecorator < Draper::Decorator end if h.policy(stop_area).destroy? - links << Link.new( + bottom_links << Link.new( content: h.destroy_link_content('stop_areas.actions.destroy'), href: h.stop_area_referential_stop_area_path( stop_area.stop_area_referential, @@ -29,7 +29,35 @@ class StopAreaDecorator < Draper::Decorator ) end - links + [top_links, bottom_links] + end + + def action_links(stop_area = nil) + stop_area ||= object + top_links, bottom_links = common_action_links(stop_area) + links = [] + + if h.policy(object).deactivate? + links << Link.new( + content: h.deactivate_link_content('stop_areas.actions.deactivate'), + href: h.deactivate_stop_area_referential_stop_area_path(stop_area.stop_area_referential, object), + method: :put, + data: {confirm: h.t('stop_areas.actions.deactivate_confirm')}, + extra_class: "delete-action" + ) + end + + if h.policy(object).activate? + links << Link.new( + content: h.activate_link_content('stop_areas.actions.activate'), + href: h.activate_stop_area_referential_stop_area_path(stop_area.stop_area_referential, object), + method: :put, + data: {confirm: h.t('stop_areas.actions.activate_confirm')}, + extra_class: "delete-action" + ) + end + + top_links + links + bottom_links end def waiting_time_text diff --git a/app/decorators/stop_point_decorator.rb b/app/decorators/stop_point_decorator.rb index 196d6d490..27e1a7058 100644 --- a/app/decorators/stop_point_decorator.rb +++ b/app/decorators/stop_point_decorator.rb @@ -4,6 +4,6 @@ class StopPointDecorator < StopAreaDecorator delegate_all def action_links - super(object.stop_area) + common_action_links(object.stop_area).flatten end end diff --git a/app/models/chouette/stop_area.rb b/app/models/chouette/stop_area.rb index 3a9b44d59..2f8d7c096 100644 --- a/app/models/chouette/stop_area.rb +++ b/app/models/chouette/stop_area.rb @@ -328,5 +328,20 @@ module Chouette end end + def activated? + deleted_at.nil? + end + + def deactivated? + !activated? + end + + def activate! + update_attribute :deleted_at, nil + end + + def deactivate! + update_attribute :deleted_at, Time.now + end end end diff --git a/app/policies/stop_area_policy.rb b/app/policies/stop_area_policy.rb index faeebbc2a..e5921ef61 100644 --- a/app/policies/stop_area_policy.rb +++ b/app/policies/stop_area_policy.rb @@ -16,4 +16,12 @@ class StopAreaPolicy < ApplicationPolicy def update? user.has_permission?('stop_areas.update') end + + def deactivate? + !record.deactivated? && user.has_permission?('stop_areas.change_status') + end + + def activate? + record.deactivated? && user.has_permission?('stop_areas.change_status') + end end diff --git a/config/locales/stop_areas.en.yml b/config/locales/stop_areas.en.yml index 3ef3835e2..4d84d1191 100644 --- a/config/locales/stop_areas.en.yml +++ b/config/locales/stop_areas.en.yml @@ -17,6 +17,10 @@ en: new: "Add a new stop" edit: "Edit this stop" destroy: "Remove" + activate: "Activate this stop" + deactivate: "Deactivate this stop" + activate_confirm: "Are you sure you want to activate this stop ?" + deactivate_confirm: "Are you sure you want tode activate this stop ?" deleted_at: "Activated" destroy_confirm: "Are you sure you want destroy this stop and all of his children ?" select_parent: "Create or modify the relation child -> parent" diff --git a/config/locales/stop_areas.fr.yml b/config/locales/stop_areas.fr.yml index 69e3ba71e..eda1e4e3d 100644 --- a/config/locales/stop_areas.fr.yml +++ b/config/locales/stop_areas.fr.yml @@ -17,6 +17,10 @@ fr: new: "Ajouter un arrêt" edit: "Editer cet arrêt" destroy: "Supprimer" + activate: "Activer cet arrêt" + deactivate: "Désactiver cet arrêt" + activate_confirm: "Etes vous sûr d'activer cet arrêt ?" + deactivate_confirm: "Etes vous sûr de désactiver cet arrêt ?" deleted_at: "Activé" destroy_confirm: "Etes vous sûr de supprimer cet arrêt ainsi que tous ses fils?" select_parent: "Créer ou éditer la relation enfant -> parent" diff --git a/config/routes.rb b/config/routes.rb index a36ecc36e..e05f5d365 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -86,17 +86,19 @@ ChouetteIhm::Application.routes.draw do resources :compliance_control_blocks, :except => [:show, :index] end + deactivable = Proc.new do + put :deactivate, on: :member + put :activate, on: :member + end + resources :stop_area_referentials, :only => [:show] do post :sync, on: :member - resources :stop_areas + resources :stop_areas, &deactivable end resources :line_referentials, :only => [:show, :edit, :update] do post :sync, on: :member - resources :lines do - put :deactivate, on: :member - put :activate, on: :member - end + resources :lines, &deactivable resources :group_of_lines resources :companies resources :networks diff --git a/spec/controllers/stop_areas_controller_spec.rb b/spec/controllers/stop_areas_controller_spec.rb new file mode 100644 index 000000000..2b5f8c3e2 --- /dev/null +++ b/spec/controllers/stop_areas_controller_spec.rb @@ -0,0 +1,38 @@ +RSpec.describe StopAreasController, :type => :controller do + login_user + + let(:stop_area_referential) { create :stop_area_referential } + let(:stop_area) { create :stop_area, stop_area_referential: stop_area_referential } + + describe 'PUT deactivate' do + let(:request){ put :deactivate, id: stop_area.id, stop_area_referential_id: stop_area_referential.id } + + it 'should redirect to 403' do + expect(request).to redirect_to "/403" + end + + with_permission "stop_areas.change_status" do + it 'returns HTTP success' do + expect(request).to redirect_to [stop_area_referential, stop_area] + expect(stop_area.reload).to be_deactivated + end + end + end + + describe 'PUT activate' do + let(:request){ put :activate, id: stop_area.id, stop_area_referential_id: stop_area_referential.id } + before(:each){ + stop_area.deactivate! + } + it 'should redirect to 403' do + expect(request).to redirect_to "/403" + end + + with_permission "stop_areas.change_status" do + it 'returns HTTP success' do + expect(request).to redirect_to [stop_area_referential, stop_area] + expect(stop_area.reload).to be_activated + end + end + end +end diff --git a/spec/factories/chouette_stop_areas.rb b/spec/factories/chouette_stop_areas.rb index 7f937e361..94517f856 100644 --- a/spec/factories/chouette_stop_areas.rb +++ b/spec/factories/chouette_stop_areas.rb @@ -8,5 +8,9 @@ FactoryGirl.define do longitude {10.0 * rand} association :stop_area_referential + + trait :deactivated do + deleted_at { 1.hour.ago } + end end end diff --git a/spec/views/stop_areas/index.html.slim_spec.rb b/spec/views/stop_areas/index.html.slim_spec.rb index 8daa5eb4b..520cecc1a 100644 --- a/spec/views/stop_areas/index.html.slim_spec.rb +++ b/spec/views/stop_areas/index.html.slim_spec.rb @@ -1,14 +1,15 @@ require 'spec_helper' describe "/stop_areas/index", :type => :view do - - let!(:stop_area_referential) { assign :stop_area_referential, create(:stop_area_referential) } - let!(:stop_areas) do + let(:deactivated_stop_area){ nil } + let(:stop_area_referential) { assign :stop_area_referential, create(:stop_area_referential) } + let(:stop_areas) do assign :stop_areas, build_paginated_collection(:stop_area, StopAreaDecorator, stop_area_referential: stop_area_referential) end let!(:q) { assign :q, Ransack::Search.new(Chouette::StopArea) } before :each do + deactivated_stop_area allow(view).to receive(:link_with_search).and_return("#") allow(view).to receive(:collection).and_return(stop_areas) allow(view).to receive(:current_referential).and_return(stop_area_referential) @@ -16,19 +17,60 @@ describe "/stop_areas/index", :type => :view do render end - it { should have_link_for_each_item(stop_areas, "show", -> (stop_area){ view.stop_area_referential_stop_area_path(stop_area_referential, stop_area) }) } + common_items = ->{ + it { should have_link_for_each_item(stop_areas, "show", -> (stop_area){ view.stop_area_referential_stop_area_path(stop_area_referential, stop_area) }) } + } + + common_items.call() it { should have_the_right_number_of_links(stop_areas, 1) } with_permission "stop_areas.create" do - it { should have_link_for_each_item(stop_areas, "show", -> (stop_area){ view.stop_area_referential_stop_area_path(stop_area_referential, stop_area) }) } + common_items.call() it { should_not have_link_for_each_item(stop_areas, "create", -> (stop_area){ view.new_stop_area_referential_stop_area_path(stop_area_referential) }) } it { should have_the_right_number_of_links(stop_areas, 1) } end with_permission "stop_areas.update" do - it { should have_link_for_each_item(stop_areas, "show", -> (stop_area){ view.stop_area_referential_stop_area_path(stop_area_referential, stop_area) }) } + common_items.call() it { should have_link_for_each_item(stop_areas, "edit", -> (stop_area){ view.edit_stop_area_referential_stop_area_path(stop_area_referential, stop_area) }) } it { should have_the_right_number_of_links(stop_areas, 2) } end + with_permission "stop_areas.change_status" do + common_items.call() + it { should have_link_for_each_item(stop_areas, "deactivate", -> (stop_area){ view.deactivate_stop_area_referential_stop_area_path(stop_area_referential, stop_area) }) } + it { should have_the_right_number_of_links(stop_areas, 2) } + end + + with_permission "stop_areas.destroy" do + common_items.call() + it { + should have_link_for_each_item(stop_areas, "destroy", { + href: ->(stop_area){ view.stop_area_referential_stop_area_path(stop_area_referential, stop_area)}, + method: :delete + }) + } + it { should have_the_right_number_of_links(stop_areas, 2) } + end + + context "with a deactivated item" do + with_permission "stop_areas.change_status" do + let(:deactivated_stop_area){ create :stop_area, :deactivated, stop_area_referential: stop_area_referential } + + common_items.call() + it "should display an activate link for the deactivated one" do + stop_areas.each do |stop_area| + if stop_area == deactivated_stop_area + href = view.activate_stop_area_referential_stop_area_path(stop_area_referential, stop_area) + else + href = view.deactivate_stop_area_referential_stop_area_path(stop_area_referential, stop_area) + end + selector = "tr.#{TableBuilderHelper.item_row_class_name(stop_areas)}-#{stop_area.id} .actions a[href='#{href}']" + expect(rendered).to have_selector(selector, count: 1) + end + end + it { should have_the_right_number_of_links(stop_areas, 2) } + end + end + end |
