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