From c180636da2f237d44e088f677e0df1e6130866f5 Mon Sep 17 00:00:00 2001 From: Zog Date: Thu, 14 Dec 2017 16:42:00 +0100 Subject: Remove duplicate links in StopArea index view Refs #5287 --- app/views/stop_areas/index.html.slim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/stop_areas/index.html.slim b/app/views/stop_areas/index.html.slim index c4d880081..99b399f5c 100644 --- a/app/views/stop_areas/index.html.slim +++ b/app/views/stop_areas/index.html.slim @@ -51,7 +51,7 @@ attribute: Proc.new { |s| (s.area_type.nil? ? '-' : t("enumerize.stop_area.area_type.#{s.try(:area_type)}")) } \ ), \ ], - links: [:show, :edit, :delete], + links: [:show], cls: 'table has-filter has-search' = new_pagination @stop_areas, 'pull-right' -- cgit v1.2.3 From 88b8e30a415f300108be4a19a53ca9768671d21e Mon Sep 17 00:00:00 2001 From: Zog Date: Fri, 15 Dec 2017 09:11:04 +0100 Subject: Refs #5287; Add specs for the view. Refactor to come --- app/helpers/table_builder_helper.rb | 10 +++- spec/helpers/table_builder_helper_spec.rb | 6 +-- spec/support/integration_spec_helper.rb | 17 ++++++ spec/support/pundit/pundit_view_policy.rb | 16 +++--- spec/views/stop_areas/index.html.erb_spec.rb | 78 +++++++++++++++++++++++----- 5 files changed, 102 insertions(+), 25 deletions(-) create mode 100644 spec/support/integration_spec_helper.rb diff --git a/app/helpers/table_builder_helper.rb b/app/helpers/table_builder_helper.rb index 37f01ce0d..64bec6bae 100644 --- a/app/helpers/table_builder_helper.rb +++ b/app/helpers/table_builder_helper.rb @@ -188,10 +188,16 @@ module TableBuilderHelper end def tbody(collection, columns, selectable, links, overhead) + if collection.respond_to?(:model) + model_name = collection.model.name.split("::").last + else + model_name = "item" + end + content_tag :tbody do collection.map do |item| - - content_tag :tr do + klass = "#{model_name.parameterize}-#{item.id}" + content_tag :tr, class: klass do bcont = [] if selectable diff --git a/spec/helpers/table_builder_helper_spec.rb b/spec/helpers/table_builder_helper_spec.rb index 3b0a18379..3b3504c60 100644 --- a/spec/helpers/table_builder_helper_spec.rb +++ b/spec/helpers/table_builder_helper_spec.rb @@ -59,7 +59,7 @@ describe TableBuilderHelper, type: :helper do - +
@@ -213,7 +213,7 @@ describe TableBuilderHelper, type: :helper do - + #{company.get_objectid.local_id} #{company.name} @@ -326,7 +326,7 @@ describe TableBuilderHelper, type: :helper do - + #{company.get_objectid.local_id} #{company.name} diff --git a/spec/support/integration_spec_helper.rb b/spec/support/integration_spec_helper.rb new file mode 100644 index 000000000..958aab9d5 --- /dev/null +++ b/spec/support/integration_spec_helper.rb @@ -0,0 +1,17 @@ +module IntegrationSpecHelper + extend ActiveSupport::Concern + + included do + def self.with_permission permission, &block + context "with permission #{permission}" do + let(:permissions){ [permission] } + context('', &block) if block_given? + end + end + end +end + + +RSpec.configure do |config| + config.include IntegrationSpecHelper, type: :view +end diff --git a/spec/support/pundit/pundit_view_policy.rb b/spec/support/pundit/pundit_view_policy.rb index b8434cac0..02a78a4e0 100644 --- a/spec/support/pundit/pundit_view_policy.rb +++ b/spec/support/pundit/pundit_view_policy.rb @@ -3,14 +3,16 @@ module Pundit extend ActiveSupport::Concern included do + + let(:permissions){ nil } + let(:current_referential){ build_stubbed :referential } + let(:current_user){ build_stubbed :user, permissions: permissions } + let(:pundit_user){ UserContext.new(current_user, referential: current_referential) } before do - controller.singleton_class.class_eval do - def policy(instance) - Class.new do - def method_missing(*args, &block); true; end - end.new - end - helper_method :policy + allow(view).to receive(:pundit_user) { pundit_user } + + allow(view).to receive(:policy) do |instance| + ::Pundit.policy pundit_user, instance end end end diff --git a/spec/views/stop_areas/index.html.erb_spec.rb b/spec/views/stop_areas/index.html.erb_spec.rb index 2dfae1bfd..a354586d2 100644 --- a/spec/views/stop_areas/index.html.erb_spec.rb +++ b/spec/views/stop_areas/index.html.erb_spec.rb @@ -1,25 +1,77 @@ 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) { assign :stop_areas, Array.new(2) { create(:stop_area, stop_area_referential: stop_area_referential) }.paginate } + let!(:stop_areas) do + 2.times { create(:stop_area, stop_area_referential: stop_area_referential) } + assign :stop_areas, ModelDecorator.decorate( Chouette::StopArea.page(1), with: StopAreaDecorator ) + end let!(:q) { assign :q, Ransack::Search.new(Chouette::StopArea) } before :each do 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) + controller.request.path_parameters[:stop_area_referential_id] = stop_area_referential.id + render + end + + it "should render a row for each group" do + stop_areas.each do |stop_area| + expect(rendered).to have_selector("tr.stoparea-#{stop_area.id}", count: 1) + end + end + + it "should render a show link for each group" do + stop_areas.each do |stop_area| + expect(rendered).to have_selector("tr.stoparea-#{stop_area.id} .actions a[href='#{view.stop_area_referential_stop_area_path(stop_area_referential, stop_area)}']", count: 1) + end + end + + it "should render no other link for each group" do + stop_areas.each do |stop_area| + expect(rendered).to have_selector("tr.stoparea-#{stop_area.id} .actions a", count: 1) + end end - # it "should render a show link for each group" do - # render - # stop_areas.each do |stop_area| - # expect(rendered).to have_selector(".stop_area a[href='#{view.stop_area_referential_stop_area_path(stop_area_referential, stop_area)}']", :text => stop_area.name) - # end - # end - # - # it "should render a link to create a new group" do - # render - # expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{new_stop_area_referential_stop_area_path(stop_area_referential)}']") - # end + with_permission "stop_areas.create" do + it "should render a show link for each group" do + stop_areas.each do |stop_area| + expect(rendered).to have_selector("tr.stoparea-#{stop_area.id} .actions a[href='#{view.stop_area_referential_stop_area_path(stop_area_referential, stop_area)}']", count: 1) + end + end + + it "should render a create link for each group" do + stop_areas.each do |stop_area| + expect(rendered).to have_selector("tr.stoparea-#{stop_area.id} .actions a[href='#{view.new_stop_area_referential_stop_area_path(stop_area_referential)}']", count: 1) + end + end + + it "should render no other link for each group" do + stop_areas.each do |stop_area| + expect(rendered).to have_selector("tr.stoparea-#{stop_area.id} .actions a", count: 2) + end + end + end + + with_permission "stop_areas.update" do + it "should render a show link for each group" do + stop_areas.each do |stop_area| + expect(rendered).to have_selector("tr.stoparea-#{stop_area.id} .actions a[href='#{view.stop_area_referential_stop_area_path(stop_area_referential, stop_area)}']", count: 1) + end + end + + it "should render a edit link for each group" do + stop_areas.each do |stop_area| + expect(rendered).to have_selector("tr.stoparea-#{stop_area.id} .actions a[href='#{view.edit_stop_area_referential_stop_area_path(stop_area_referential, stop_area.id)}']", count: 1) + end + end + + it "should render no other link for each group" do + stop_areas.each do |stop_area| + expect(rendered).to have_selector("tr.stoparea-#{stop_area.id} .actions a", count: 2) + end + end + end end -- cgit v1.2.3 From cd92a6e07393b1b6ee57a8d980f072aa8a034874 Mon Sep 17 00:00:00 2001 From: Zog Date: Fri, 15 Dec 2017 11:27:14 +0100 Subject: - Fix specs on connections_links/index - Fix specs on connections_links/show - Update pundit view specs helper to use the current referential when it has already been defined --- spec/support/pundit/pundit_view_policy.rb | 5 +++-- spec/views/connection_links/index.html.erb_spec.rb | 8 +++++--- spec/views/connection_links/show.html.erb_spec.rb | 23 ++++++++++------------ 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/spec/support/pundit/pundit_view_policy.rb b/spec/support/pundit/pundit_view_policy.rb index 02a78a4e0..6a663a471 100644 --- a/spec/support/pundit/pundit_view_policy.rb +++ b/spec/support/pundit/pundit_view_policy.rb @@ -5,8 +5,9 @@ module Pundit included do let(:permissions){ nil } - let(:current_referential){ build_stubbed :referential } - let(:current_user){ build_stubbed :user, permissions: permissions } + let(:organisation){ referential.try(:organisation) } + let(:current_referential){ referential || build_stubbed(:referential) } + let(:current_user){ build_stubbed :user, permissions: permissions, organisation: organisation } let(:pundit_user){ UserContext.new(current_user, referential: current_referential) } before do allow(view).to receive(:pundit_user) { pundit_user } diff --git a/spec/views/connection_links/index.html.erb_spec.rb b/spec/views/connection_links/index.html.erb_spec.rb index a01380094..1f133e31e 100644 --- a/spec/views/connection_links/index.html.erb_spec.rb +++ b/spec/views/connection_links/index.html.erb_spec.rb @@ -17,9 +17,11 @@ describe "/connection_links/index", :type => :view do end end - it "should render a link to create a new group" do - render - expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{new_referential_connection_link_path(referential)}']") + with_permission "connection_links.create" do + it "should render a link to create a new group" do + render + expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{new_referential_connection_link_path(referential)}']") + end end end diff --git a/spec/views/connection_links/show.html.erb_spec.rb b/spec/views/connection_links/show.html.erb_spec.rb index c04a4f3f1..afe94fc6c 100644 --- a/spec/views/connection_links/show.html.erb_spec.rb +++ b/spec/views/connection_links/show.html.erb_spec.rb @@ -15,21 +15,18 @@ describe "/connection_links/show", :type => :view do expect(rendered).to have_selector("h2", :text => Regexp.new(connection_link.name)) end -# it "should display a map with class 'connection_link'" do -# pending ": map not yet implemented" -# render -# expect(rendered).to have_selector("#map", :class => 'connection_link') -# end - - it "should render a link to edit the connection_link" do - render - expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{view.edit_referential_connection_link_path(referential, connection_link)}']") + with_permission "connection_links.update" do + it "should render a link to edit the connection_link" do + render + expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{view.edit_referential_connection_link_path(referential, connection_link)}']") + end end - it "should render a link to remove the connection_link" do - render - expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{view.referential_connection_link_path(referential, connection_link)}'][class='remove']") + with_permission "connection_links.destroy" do + it "should render a link to remove the connection_link" do + render + expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{view.referential_connection_link_path(referential, connection_link)}'][class='remove']") + end end end - -- cgit v1.2.3 From b4551be86b397ddd441f94d8d49490f0f9891c5b Mon Sep 17 00:00:00 2001 From: Zog Date: Fri, 15 Dec 2017 14:52:33 +0100 Subject: Refactor stopareas index specs --- spec/views/stop_areas/index.html.erb_spec.rb | 78 ++++++++++------------------ 1 file changed, 27 insertions(+), 51 deletions(-) diff --git a/spec/views/stop_areas/index.html.erb_spec.rb b/spec/views/stop_areas/index.html.erb_spec.rb index a354586d2..e0c50685c 100644 --- a/spec/views/stop_areas/index.html.erb_spec.rb +++ b/spec/views/stop_areas/index.html.erb_spec.rb @@ -1,6 +1,25 @@ require 'spec_helper' +RSpec::Matchers.define :have_link_for_each_stop_area do |stop_areas, name, href| + match do |actual| + stop_areas.each do |stop_area| + expect(rendered).to have_selector("tr.stoparea-#{stop_area.id} .actions a[href='#{href.call(stop_area)}']", count: 1) + end + end + description { "have #{name} link for each stop area" } +end + +RSpec::Matchers.define :have_the_right_number_of_links do |stop_areas, count| + match do |actual| + stop_areas.each do |stop_area| + expect(rendered).to have_selector("tr.stoparea-#{stop_area.id} .actions a", count: count) + end + end + description { "have #{count} links for each stop area" } +end + describe "/stop_areas/index", :type => :view do + let!(:stop_area_referential) { assign :stop_area_referential, create(:stop_area_referential) } let!(:stop_areas) do 2.times { create(:stop_area, stop_area_referential: stop_area_referential) } @@ -16,62 +35,19 @@ describe "/stop_areas/index", :type => :view do render end - it "should render a row for each group" do - stop_areas.each do |stop_area| - expect(rendered).to have_selector("tr.stoparea-#{stop_area.id}", count: 1) - end - end - - it "should render a show link for each group" do - stop_areas.each do |stop_area| - expect(rendered).to have_selector("tr.stoparea-#{stop_area.id} .actions a[href='#{view.stop_area_referential_stop_area_path(stop_area_referential, stop_area)}']", count: 1) - end - end - - it "should render no other link for each group" do - stop_areas.each do |stop_area| - expect(rendered).to have_selector("tr.stoparea-#{stop_area.id} .actions a", count: 1) - end - end + it { should have_link_for_each_stop_area(stop_areas, "show", -> (stop_area){ view.stop_area_referential_stop_area_path(stop_area_referential, stop_area) }) } + it { should have_the_right_number_of_links(stop_areas, 1) } with_permission "stop_areas.create" do - it "should render a show link for each group" do - stop_areas.each do |stop_area| - expect(rendered).to have_selector("tr.stoparea-#{stop_area.id} .actions a[href='#{view.stop_area_referential_stop_area_path(stop_area_referential, stop_area)}']", count: 1) - end - end - - it "should render a create link for each group" do - stop_areas.each do |stop_area| - expect(rendered).to have_selector("tr.stoparea-#{stop_area.id} .actions a[href='#{view.new_stop_area_referential_stop_area_path(stop_area_referential)}']", count: 1) - end - end - - it "should render no other link for each group" do - stop_areas.each do |stop_area| - expect(rendered).to have_selector("tr.stoparea-#{stop_area.id} .actions a", count: 2) - end - end + it { should have_link_for_each_stop_area(stop_areas, "show", -> (stop_area){ view.stop_area_referential_stop_area_path(stop_area_referential, stop_area) }) } + it { should have_link_for_each_stop_area(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, 2) } end with_permission "stop_areas.update" do - it "should render a show link for each group" do - stop_areas.each do |stop_area| - expect(rendered).to have_selector("tr.stoparea-#{stop_area.id} .actions a[href='#{view.stop_area_referential_stop_area_path(stop_area_referential, stop_area)}']", count: 1) - end - end - - it "should render a edit link for each group" do - stop_areas.each do |stop_area| - expect(rendered).to have_selector("tr.stoparea-#{stop_area.id} .actions a[href='#{view.edit_stop_area_referential_stop_area_path(stop_area_referential, stop_area.id)}']", count: 1) - end - end - - it "should render no other link for each group" do - stop_areas.each do |stop_area| - expect(rendered).to have_selector("tr.stoparea-#{stop_area.id} .actions a", count: 2) - end - end + it { should have_link_for_each_stop_area(stop_areas, "show", -> (stop_area){ view.stop_area_referential_stop_area_path(stop_area_referential, stop_area) }) } + it { should have_link_for_each_stop_area(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 end -- cgit v1.2.3 From 2e8b3c13e0bb9bcc8e9026830cce47cb0c37af4a Mon Sep 17 00:00:00 2001 From: Xinhui Date: Thu, 14 Dec 2017 12:19:19 +0100 Subject: Make dashboard bloc title clickable Refs #5302 --- app/views/dashboards/_dashboard.html.slim | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/dashboards/_dashboard.html.slim b/app/views/dashboards/_dashboard.html.slim index f03301e23..e5aa5093a 100644 --- a/app/views/dashboards/_dashboard.html.slim +++ b/app/views/dashboards/_dashboard.html.slim @@ -5,7 +5,7 @@ .panel-heading h3.panel-title.with_actions div - = workbench.name + = link_to workbench.name, workbench_path(workbench) span.badge.ml-xs = workbench.referentials.count if workbench.referentials.present? div @@ -22,7 +22,7 @@ .panel.panel-default .panel-heading h3.panel-title.with_actions - = "Modèles de calendrier" + = link_to "Modèles de calendrier", calendars_path div = link_to '', calendars_path, class: ' fa fa-chevron-right pull-right' - if @dashboard.current_organisation.calendars.present? -- cgit v1.2.3 From df2f87fceea07fcf47c66666d74b47aa4b3c0eac Mon Sep 17 00:00:00 2001 From: Alban Peignier Date: Thu, 14 Dec 2017 18:39:47 +0100 Subject: Define content_for page_header_title in Devise views. Refs #5309 --- app/views/devise/invitations/edit.html.slim | 33 +++++++++++++++++------------ app/views/devise/passwords/edit.html.slim | 28 +++++++++++++----------- app/views/devise/passwords/new.html.slim | 4 ++-- app/views/devise/sessions/new.html.slim | 2 ++ 4 files changed, 39 insertions(+), 28 deletions(-) diff --git a/app/views/devise/invitations/edit.html.slim b/app/views/devise/invitations/edit.html.slim index 6c9a6f436..7a22146c0 100644 --- a/app/views/devise/invitations/edit.html.slim +++ b/app/views/devise/invitations/edit.html.slim @@ -1,14 +1,19 @@ -.col-md-offset-2.col-md-8 - .panel.panel-default - .panel-heading = t('devise.invitations.edit.header') - - .panel-body - = simple_form_for resource, as: resource_name, :url => invitation_path(resource_name), :html => { :method => :put, class: "form-horizontal" } do |form| - = form.hidden_field :invitation_token - - = form.input :name - = form.input :password, as: :password - = form.input :password_confirmation, as: :password - - .submit - = form.button :submit, value: t('devise.invitations.edit.submit_button'), class: 'btn-info' \ No newline at end of file +/ PageHeader + +- content_for :page_header_title, t('.title') + +/ PageContent +.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 + = simple_form_for resource, as: resource_name, :url => invitation_path(resource_name), :html => { :method => :put, class: "form-horizontal", id: 'invitation_form' } do |form| + .row + .col-lg-12 + = form.hidden_field :invitation_token + + = form.input :name + = form.input :password, as: :password + = form.input :password_confirmation, as: :password + + = form.button :submit, value: t('devise.invitations.edit.submit_button'), class: 'btn-info btn-default formSubmitr', form: 'invitation_form' diff --git a/app/views/devise/passwords/edit.html.slim b/app/views/devise/passwords/edit.html.slim index 864a44499..0d18f657c 100644 --- a/app/views/devise/passwords/edit.html.slim +++ b/app/views/devise/passwords/edit.html.slim @@ -1,13 +1,17 @@ -.col-md-offset-2.col-md-8 - .panel.panel-default - .panel-heading = t('.title') - .panel-body - = simple_form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :put, class: "form-horizontal" }) do |f| +/ PageHeader - = f.input :reset_password_token, as: :hidden - = f.input :password, as: :password - = f.input :password_confirmation, as: :password - - .form-actions - = link_to t("cancel"), unauthenticated_root_path, class: 'btn btn-default' - = f.button :submit, :value => t("devise.passwords.edit.commit"), class: 'btn-info' \ No newline at end of file +- content_for :page_header_title, t('.title') + +/ PageContent +.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 + = simple_form_for(resource, :as => resource_name, :url => password_path(resource_name), :html => { :method => :put, class: "form-horizontal", id: 'password_form' }) do |f| + .row + .col-lg-12 + = f.input :reset_password_token, as: :hidden + = f.input :password, as: :password + = f.input :password_confirmation, as: :password + + = f.button :submit, :value => t("devise.passwords.edit.commit"), class: 'btn btn-default formSubmitr', form: 'password_form' diff --git a/app/views/devise/passwords/new.html.slim b/app/views/devise/passwords/new.html.slim index 6e03595fc..303f78f0e 100644 --- a/app/views/devise/passwords/new.html.slim +++ b/app/views/devise/passwords/new.html.slim @@ -1,6 +1,6 @@ / PageHeader -= pageheader '', t('.title') +- content_for :page_header_title, t('.title') / PageContent .page_content @@ -12,4 +12,4 @@ .col-lg-12 = form.input :email, :as => :email, placeholder: 'user@domain.com' - = form.button :submit, :value => t("devise.passwords.new.commit"), class: 'btn btn-default formSubmitr', form: 'invitation_form' + = form.button :submit, :value => t("devise.passwords.new.commit"), class: 'btn btn-default formSubmitr', form: 'password_form' diff --git a/app/views/devise/sessions/new.html.slim b/app/views/devise/sessions/new.html.slim index 0ed17e24a..a812726e5 100644 --- a/app/views/devise/sessions/new.html.slim +++ b/app/views/devise/sessions/new.html.slim @@ -1,3 +1,5 @@ +- content_for :page_header_title, t('.title') + .page_content#devise .container-fluid #sessions_new.row -- cgit v1.2.3 From 1b2c50949d827d8f82a40d591489394f5dc2f993 Mon Sep 17 00:00:00 2001 From: Zog Date: Mon, 18 Dec 2017 09:25:10 +0100 Subject: Refs #5287; CR 1 - Get rid of ActiveSupport::Concern in the spec helpers - Rename misnamed spec files --- spec/support/integration_spec_helper.rb | 15 ++---- spec/support/pundit/pundit_view_policy.rb | 17 +++---- spec/views/connection_links/show.html.erb_spec.rb | 32 ------------- spec/views/connection_links/show.html.slim_spec.rb | 32 +++++++++++++ spec/views/stop_areas/index.html.erb_spec.rb | 53 ---------------------- spec/views/stop_areas/index.html.slim_spec.rb | 53 ++++++++++++++++++++++ 6 files changed, 97 insertions(+), 105 deletions(-) delete mode 100644 spec/views/connection_links/show.html.erb_spec.rb create mode 100644 spec/views/connection_links/show.html.slim_spec.rb delete mode 100644 spec/views/stop_areas/index.html.erb_spec.rb create mode 100644 spec/views/stop_areas/index.html.slim_spec.rb diff --git a/spec/support/integration_spec_helper.rb b/spec/support/integration_spec_helper.rb index 958aab9d5..182cadf24 100644 --- a/spec/support/integration_spec_helper.rb +++ b/spec/support/integration_spec_helper.rb @@ -1,17 +1,12 @@ module IntegrationSpecHelper - extend ActiveSupport::Concern - - included do - def self.with_permission permission, &block - context "with permission #{permission}" do - let(:permissions){ [permission] } - context('', &block) if block_given? - end + def with_permission permission, &block + context "with permission #{permission}" do + let(:permissions){ [permission] } + context('', &block) if block_given? end end end - RSpec.configure do |config| - config.include IntegrationSpecHelper, type: :view + config.extend IntegrationSpecHelper, type: :view end diff --git a/spec/support/pundit/pundit_view_policy.rb b/spec/support/pundit/pundit_view_policy.rb index 6a663a471..91be0624c 100644 --- a/spec/support/pundit/pundit_view_policy.rb +++ b/spec/support/pundit/pundit_view_policy.rb @@ -1,15 +1,12 @@ module Pundit module PunditViewPolicy - extend ActiveSupport::Concern - - included do - - let(:permissions){ nil } - let(:organisation){ referential.try(:organisation) } - let(:current_referential){ referential || build_stubbed(:referential) } - let(:current_user){ build_stubbed :user, permissions: permissions, organisation: organisation } - let(:pundit_user){ UserContext.new(current_user, referential: current_referential) } - before do + def self.included into + into.let(:permissions){ nil } + into.let(:organisation){ referential.try(:organisation) } + into.let(:current_referential){ referential || build_stubbed(:referential) } + into.let(:current_user){ build_stubbed :user, permissions: permissions, organisation: organisation } + into.let(:pundit_user){ UserContext.new(current_user, referential: current_referential) } + into.before do allow(view).to receive(:pundit_user) { pundit_user } allow(view).to receive(:policy) do |instance| diff --git a/spec/views/connection_links/show.html.erb_spec.rb b/spec/views/connection_links/show.html.erb_spec.rb deleted file mode 100644 index afe94fc6c..000000000 --- a/spec/views/connection_links/show.html.erb_spec.rb +++ /dev/null @@ -1,32 +0,0 @@ -require 'spec_helper' - -describe "/connection_links/show", :type => :view do - - assign_referential - let!(:connection_link) { assign(:connection_link, create(:connection_link)) } - let!(:map) { assign(:map, double(:to_html => '
'.html_safe)) } - - before do - allow(view).to receive_messages(current_organisation: referential.organisation) - end - - it "should render h2 with the connection_link name" do - render - expect(rendered).to have_selector("h2", :text => Regexp.new(connection_link.name)) - end - - with_permission "connection_links.update" do - it "should render a link to edit the connection_link" do - render - expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{view.edit_referential_connection_link_path(referential, connection_link)}']") - end - end - - with_permission "connection_links.destroy" do - it "should render a link to remove the connection_link" do - render - expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{view.referential_connection_link_path(referential, connection_link)}'][class='remove']") - end - end - -end diff --git a/spec/views/connection_links/show.html.slim_spec.rb b/spec/views/connection_links/show.html.slim_spec.rb new file mode 100644 index 000000000..afe94fc6c --- /dev/null +++ b/spec/views/connection_links/show.html.slim_spec.rb @@ -0,0 +1,32 @@ +require 'spec_helper' + +describe "/connection_links/show", :type => :view do + + assign_referential + let!(:connection_link) { assign(:connection_link, create(:connection_link)) } + let!(:map) { assign(:map, double(:to_html => '
'.html_safe)) } + + before do + allow(view).to receive_messages(current_organisation: referential.organisation) + end + + it "should render h2 with the connection_link name" do + render + expect(rendered).to have_selector("h2", :text => Regexp.new(connection_link.name)) + end + + with_permission "connection_links.update" do + it "should render a link to edit the connection_link" do + render + expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{view.edit_referential_connection_link_path(referential, connection_link)}']") + end + end + + with_permission "connection_links.destroy" do + it "should render a link to remove the connection_link" do + render + expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{view.referential_connection_link_path(referential, connection_link)}'][class='remove']") + end + end + +end diff --git a/spec/views/stop_areas/index.html.erb_spec.rb b/spec/views/stop_areas/index.html.erb_spec.rb deleted file mode 100644 index e0c50685c..000000000 --- a/spec/views/stop_areas/index.html.erb_spec.rb +++ /dev/null @@ -1,53 +0,0 @@ -require 'spec_helper' - -RSpec::Matchers.define :have_link_for_each_stop_area do |stop_areas, name, href| - match do |actual| - stop_areas.each do |stop_area| - expect(rendered).to have_selector("tr.stoparea-#{stop_area.id} .actions a[href='#{href.call(stop_area)}']", count: 1) - end - end - description { "have #{name} link for each stop area" } -end - -RSpec::Matchers.define :have_the_right_number_of_links do |stop_areas, count| - match do |actual| - stop_areas.each do |stop_area| - expect(rendered).to have_selector("tr.stoparea-#{stop_area.id} .actions a", count: count) - end - end - description { "have #{count} links for each stop area" } -end - -describe "/stop_areas/index", :type => :view do - - let!(:stop_area_referential) { assign :stop_area_referential, create(:stop_area_referential) } - let!(:stop_areas) do - 2.times { create(:stop_area, stop_area_referential: stop_area_referential) } - assign :stop_areas, ModelDecorator.decorate( Chouette::StopArea.page(1), with: StopAreaDecorator ) - end - let!(:q) { assign :q, Ransack::Search.new(Chouette::StopArea) } - - before :each do - 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) - controller.request.path_parameters[:stop_area_referential_id] = stop_area_referential.id - render - end - - it { should have_link_for_each_stop_area(stop_areas, "show", -> (stop_area){ view.stop_area_referential_stop_area_path(stop_area_referential, stop_area) }) } - it { should have_the_right_number_of_links(stop_areas, 1) } - - with_permission "stop_areas.create" do - it { should have_link_for_each_stop_area(stop_areas, "show", -> (stop_area){ view.stop_area_referential_stop_area_path(stop_area_referential, stop_area) }) } - it { should have_link_for_each_stop_area(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, 2) } - end - - with_permission "stop_areas.update" do - it { should have_link_for_each_stop_area(stop_areas, "show", -> (stop_area){ view.stop_area_referential_stop_area_path(stop_area_referential, stop_area) }) } - it { should have_link_for_each_stop_area(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 - -end diff --git a/spec/views/stop_areas/index.html.slim_spec.rb b/spec/views/stop_areas/index.html.slim_spec.rb new file mode 100644 index 000000000..e0c50685c --- /dev/null +++ b/spec/views/stop_areas/index.html.slim_spec.rb @@ -0,0 +1,53 @@ +require 'spec_helper' + +RSpec::Matchers.define :have_link_for_each_stop_area do |stop_areas, name, href| + match do |actual| + stop_areas.each do |stop_area| + expect(rendered).to have_selector("tr.stoparea-#{stop_area.id} .actions a[href='#{href.call(stop_area)}']", count: 1) + end + end + description { "have #{name} link for each stop area" } +end + +RSpec::Matchers.define :have_the_right_number_of_links do |stop_areas, count| + match do |actual| + stop_areas.each do |stop_area| + expect(rendered).to have_selector("tr.stoparea-#{stop_area.id} .actions a", count: count) + end + end + description { "have #{count} links for each stop area" } +end + +describe "/stop_areas/index", :type => :view do + + let!(:stop_area_referential) { assign :stop_area_referential, create(:stop_area_referential) } + let!(:stop_areas) do + 2.times { create(:stop_area, stop_area_referential: stop_area_referential) } + assign :stop_areas, ModelDecorator.decorate( Chouette::StopArea.page(1), with: StopAreaDecorator ) + end + let!(:q) { assign :q, Ransack::Search.new(Chouette::StopArea) } + + before :each do + 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) + controller.request.path_parameters[:stop_area_referential_id] = stop_area_referential.id + render + end + + it { should have_link_for_each_stop_area(stop_areas, "show", -> (stop_area){ view.stop_area_referential_stop_area_path(stop_area_referential, stop_area) }) } + it { should have_the_right_number_of_links(stop_areas, 1) } + + with_permission "stop_areas.create" do + it { should have_link_for_each_stop_area(stop_areas, "show", -> (stop_area){ view.stop_area_referential_stop_area_path(stop_area_referential, stop_area) }) } + it { should have_link_for_each_stop_area(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, 2) } + end + + with_permission "stop_areas.update" do + it { should have_link_for_each_stop_area(stop_areas, "show", -> (stop_area){ view.stop_area_referential_stop_area_path(stop_area_referential, stop_area) }) } + it { should have_link_for_each_stop_area(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 + +end -- cgit v1.2.3 From fe2351168962eba58fb140abe490490daa1739cf Mon Sep 17 00:00:00 2001 From: Alban Peignier Date: Mon, 18 Dec 2017 19:18:31 +0100 Subject: Fix link use in StopArea name into stop_areas#index. Refs #5287 --- app/views/stop_areas/index.html.slim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/stop_areas/index.html.slim b/app/views/stop_areas/index.html.slim index 99b399f5c..dbf3b848d 100644 --- a/app/views/stop_areas/index.html.slim +++ b/app/views/stop_areas/index.html.slim @@ -24,7 +24,7 @@ key: :name, \ attribute: 'name', \ link_to: lambda do |stop_area| \ - referential_stop_area_path( \ + stop_area_referential_stop_area_path( \ @stop_area_referential, \ stop_area \ ) \ -- cgit v1.2.3 From b67027e412aa731059e2783b8eccdece295b3240 Mon Sep 17 00:00:00 2001 From: Zog Date: Tue, 19 Dec 2017 13:09:47 +0100 Subject: Refs #5287@0.5h; Use I18n in dashboard For calendars panel, instead of hardcoded string --- app/assets/stylesheets/components/_panels.sass | 1 + app/views/dashboards/_dashboard.html.slim | 2 +- config/locales/calendars.en.yml | 5 +++-- config/locales/calendars.fr.yml | 5 +++-- 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/app/assets/stylesheets/components/_panels.sass b/app/assets/stylesheets/components/_panels.sass index e9f615081..ab25d8184 100644 --- a/app/assets/stylesheets/components/_panels.sass +++ b/app/assets/stylesheets/components/_panels.sass @@ -34,6 +34,7 @@ a text-decoration: none color: $blue + text-transform: capitalize &:hover, &:focus color: $darkblue diff --git a/app/views/dashboards/_dashboard.html.slim b/app/views/dashboards/_dashboard.html.slim index e5aa5093a..7d547bf4c 100644 --- a/app/views/dashboards/_dashboard.html.slim +++ b/app/views/dashboards/_dashboard.html.slim @@ -22,7 +22,7 @@ .panel.panel-default .panel-heading h3.panel-title.with_actions - = link_to "Modèles de calendrier", calendars_path + = link_to I18n.t("activerecord.models.calendar", count: @dashboard.current_organisation.calendars.size), calendars_path div = link_to '', calendars_path, class: ' fa fa-chevron-right pull-right' - if @dashboard.current_organisation.calendars.present? diff --git a/config/locales/calendars.en.yml b/config/locales/calendars.en.yml index 0076e5207..d3cc57677 100644 --- a/config/locales/calendars.en.yml +++ b/config/locales/calendars.en.yml @@ -56,8 +56,9 @@ en: end: End activerecord: models: - one: calendar - other: calendars + calendar: + one: calendar + other: calendars attributes: calendar: name: Name diff --git a/config/locales/calendars.fr.yml b/config/locales/calendars.fr.yml index fddb47d64..fc895bf89 100644 --- a/config/locales/calendars.fr.yml +++ b/config/locales/calendars.fr.yml @@ -56,8 +56,9 @@ fr: end: Fin activerecord: models: - one: "calendrier" - other: "calendriers" + calendar: + one: "calendrier" + other: "calendriers" attributes: calendar: name: Nom -- cgit v1.2.3 From 892f3448bc65358ce2ab3f1ef83888a25b8524e9 Mon Sep 17 00:00:00 2001 From: Alban Peignier Date: Tue, 12 Dec 2017 21:24:24 +0100 Subject: Move logic to ReferentialCloning. Improve specs. Refs #5283 --- app/models/referential_cloning.rb | 21 ++++++-- app/workers/referential_cloning_worker.rb | 29 ++--------- spec/models/referential_cloning_spec.rb | 64 ++++++++++++++++++++++++- spec/workers/referential_cloning_worker_spec.rb | 53 +++++++------------- 4 files changed, 100 insertions(+), 67 deletions(-) diff --git a/app/models/referential_cloning.rb b/app/models/referential_cloning.rb index 5bf283814..24117e6c8 100644 --- a/app/models/referential_cloning.rb +++ b/app/models/referential_cloning.rb @@ -2,14 +2,27 @@ class ReferentialCloning < ActiveRecord::Base include AASM belongs_to :source_referential, class_name: 'Referential' belongs_to :target_referential, class_name: 'Referential' - after_commit :perform_clone, :on => :create + after_commit :clone, on: :create - private - def perform_clone + def clone ReferentialCloningWorker.perform_async(id) - # ReferentialCloningWorker.new.perform(id) end + def clone! + run! + + AF83::SchemaCloner + .new(source_referential.slug, target_referential.slug) + .clone_schema + + successful! + rescue Exception => e + Rails.logger.error "Clone failed : #{e}" + failed! + end + + private + aasm column: :status do state :new, :initial => true state :pending diff --git a/app/workers/referential_cloning_worker.rb b/app/workers/referential_cloning_worker.rb index 6592160ec..60dc1a4bc 100644 --- a/app/workers/referential_cloning_worker.rb +++ b/app/workers/referential_cloning_worker.rb @@ -1,32 +1,9 @@ class ReferentialCloningWorker include Sidekiq::Worker - # Replace default apartment created schema with clone schema from source referential def perform(id) - ref_cloning = ReferentialCloning.find id - - source_schema = ref_cloning.source_referential.slug - target_schema = ref_cloning.target_referential.slug - - clone_schema ref_cloning, source_schema, target_schema - end - - private - - def clone_schema ref_cloning, source_schema, target_schema - ref_cloning.run! - - AF83::SchemaCloner - .new(source_schema, target_schema) - .clone_schema - - ref_cloning.successful! - rescue Exception => e - Rails.logger.error "ReferentialCloningWorker : #{e}" - ref_cloning.failed! - end - - def execute_sql sql - ActiveRecord::Base.connection.execute sql + if operation = ReferentialCloning.find(id) + operation.clone! + end end end diff --git a/spec/models/referential_cloning_spec.rb b/spec/models/referential_cloning_spec.rb index 5acd433ec..c01be20a9 100644 --- a/spec/models/referential_cloning_spec.rb +++ b/spec/models/referential_cloning_spec.rb @@ -1,6 +1,8 @@ require 'spec_helper' RSpec.describe ReferentialCloning, :type => :model do + alias_method :referential_cloning, :subject + it 'should have a valid factory' do expect(FactoryGirl.build(:referential_cloning)).to be_valid end @@ -8,11 +10,69 @@ RSpec.describe ReferentialCloning, :type => :model do it { should belong_to :source_referential } it { should belong_to :target_referential } - describe "ReferentialCloningWorker" do + describe 'after commit' do + let(:referential_cloning) { FactoryGirl.create(:referential_cloning) } + + it 'invoke clone method' do + expect(referential_cloning).to receive(:clone) + referential_cloning.run_callbacks(:commit) + end + end + + describe '#clone' do let(:referential_cloning) { FactoryGirl.create(:referential_cloning) } it "should schedule a job in worker" do - expect{referential_cloning.run_callbacks(:commit)}.to change {ReferentialCloningWorker.jobs.count}.by(1) + expect{referential_cloning.clone}.to change {ReferentialCloningWorker.jobs.count}.by(1) + end + end + + describe '#clone!' do + let(:source_referential) { Referential.new slug: "source"} + let(:target_referential) { Referential.new slug: "target"} + let(:referential_cloning) do + ReferentialCloning.new source_referential: source_referential, + target_referential: target_referential + end + + let(:cloner) { double } + + before do + allow(AF83::SchemaCloner).to receive(:new).and_return cloner + allow(cloner).to receive(:clone_schema) end + + it 'creates a schema cloner with source and target schemas and clone schema' do + expect(AF83::SchemaCloner).to receive(:new).with(source_referential.slug, target_referential.slug).and_return(cloner) + expect(cloner).to receive(:clone_schema) + + referential_cloning.clone! + end + + context 'when clone_schema is performed without error' do + it "should have successful status" do + referential_cloning.clone! + expect(referential_cloning.status).to eq("successful") + end + end + + context 'when clone_schema raises an error' do + it "should have failed status" do + expect(cloner).to receive(:clone_schema).and_raise("#fail") + referential_cloning.clone! + expect(referential_cloning.status).to eq("failed") + end + end + + it "defines started_at" do + referential_cloning.clone! + expect(referential_cloning.started_at).not_to be(nil) + end + + it "defines ended_at" do + referential_cloning.clone! + expect(referential_cloning.ended_at).not_to be(nil) + end + end end diff --git a/spec/workers/referential_cloning_worker_spec.rb b/spec/workers/referential_cloning_worker_spec.rb index 7e4a2357a..2b9a54805 100644 --- a/spec/workers/referential_cloning_worker_spec.rb +++ b/spec/workers/referential_cloning_worker_spec.rb @@ -2,52 +2,35 @@ require 'spec_helper' require 'ostruct' RSpec.describe ReferentialCloningWorker do + alias_method :worker, :subject context "given a referential cloning" do + let(:id) { double } + let(:referential_cloning) { double } - let( :id ){ double } + it "invokes the clone! method of the associated ReferentialCloning" do + expect(ReferentialCloning).to receive(:find).with(id).and_return(referential_cloning) + expect(referential_cloning).to receive(:clone!) - let( :worker ){ described_class.new } - - def make_referential(schema_name) - return OpenStruct.new( slug: schema_name ) - end - - let( :source_schema ){ "source_schema" } - let( :target_schema ){ "target_schema" } - let( :referential_cloning ){ OpenStruct.new(source_referential: make_referential(source_schema), - target_referential: make_referential(target_schema)) } - let( :cloner ){ 'cloner' } - - - before do - expect( ReferentialCloning ).to receive(:find).with(id).and_return(referential_cloning) - expect( AF83::SchemaCloner ).to receive(:new).with( source_schema, target_schema ).and_return(cloner) - expect( cloner ).to receive(:clone_schema) - - expect( referential_cloning ).to receive(:run!) - end - - it "invokes the correct stored procedure, updates the database and the AASM" do - expect( referential_cloning ).to receive(:successful!) worker.perform(id) end end - it "should clone an existing Referential" do - source_referential = create :referential - - source_referential.switch - source_time_table = create :time_table + context 'with existing Referential' do + it "preserve existing data" do + source_referential = create :referential - target_referential = create :referential, created_from: source_referential + source_referential.switch + source_time_table = create :time_table - cloning = ReferentialCloning.create source_referential: source_referential, target_referential: target_referential - ReferentialCloningWorker.new.perform(cloning) + target_referential = create :referential, created_from: source_referential - target_referential.switch - expect(Chouette::TimeTable.where(objectid: source_time_table.objectid).exists?) - end + cloning = ReferentialCloning.create source_referential: source_referential, target_referential: target_referential + worker.perform(cloning.id) + target_referential.switch + expect(Chouette::TimeTable.where(objectid: source_time_table.objectid).exists?) + end + end end -- cgit v1.2.3 From 24df9992da672f84ec22435449bcd985fb2d3ed0 Mon Sep 17 00:00:00 2001 From: Alban Peignier Date: Wed, 13 Dec 2017 09:30:11 +0100 Subject: Use ReferentialCloning.find result without test on ReferentialCloningWorker#perform. Refs #5283 --- app/workers/referential_cloning_worker.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/app/workers/referential_cloning_worker.rb b/app/workers/referential_cloning_worker.rb index 60dc1a4bc..e20148055 100644 --- a/app/workers/referential_cloning_worker.rb +++ b/app/workers/referential_cloning_worker.rb @@ -2,8 +2,6 @@ class ReferentialCloningWorker include Sidekiq::Worker def perform(id) - if operation = ReferentialCloning.find(id) - operation.clone! - end + ReferentialCloning.find(id).clone! end end -- cgit v1.2.3 From a8dee986c3b9666c1727c1a65e4bcc6a20deed6b Mon Sep 17 00:00:00 2001 From: Xinhui Date: Thu, 14 Dec 2017 11:54:40 +0100 Subject: Fix duplicate link on dropdown menu & label Refs #5300 --- app/decorators/company_decorator.rb | 2 +- app/views/companies/index.html.slim | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/decorators/company_decorator.rb b/app/decorators/company_decorator.rb index 9416c73ae..96a5175bc 100644 --- a/app/decorators/company_decorator.rb +++ b/app/decorators/company_decorator.rb @@ -37,7 +37,7 @@ class CompanyDecorator < Draper::Decorator if h.policy(object).destroy? links << Link.new( - content: t('companies.actions.destroy'), + content: h.t('companies.actions.destroy'), href: h.line_referential_company_path( context[:referential], object diff --git a/app/views/companies/index.html.slim b/app/views/companies/index.html.slim index 5d746642f..e031f3776 100644 --- a/app/views/companies/index.html.slim +++ b/app/views/companies/index.html.slim @@ -34,7 +34,7 @@ end \ ) \ ], - links: [:show, :edit], + links: [:show], cls: 'table has-search' = new_pagination @companies, 'pull-right' -- cgit v1.2.3 From 8ca8824b490d139e9eafce439688aaf3c6658b13 Mon Sep 17 00:00:00 2001 From: Xinhui Date: Thu, 14 Dec 2017 14:12:12 +0100 Subject: Enable unaccent extension Refs #5305 --- db/migrate/20171214130636_enable_unaccent_extension.rb | 9 +++++++++ db/schema.rb | 3 ++- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20171214130636_enable_unaccent_extension.rb diff --git a/db/migrate/20171214130636_enable_unaccent_extension.rb b/db/migrate/20171214130636_enable_unaccent_extension.rb new file mode 100644 index 000000000..f7411b1f4 --- /dev/null +++ b/db/migrate/20171214130636_enable_unaccent_extension.rb @@ -0,0 +1,9 @@ +class EnableUnaccentExtension < ActiveRecord::Migration + def up + execute 'CREATE EXTENSION IF NOT EXISTS unaccent SCHEMA shared_extensions;' + end + + def down + execute 'DROP EXTENSION IF EXISTS unaccent SCHEMA shared_extensions;' + end +end diff --git a/db/schema.rb b/db/schema.rb index 4a04dac26..f2642f8fc 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,12 +11,13 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20171130180144) do +ActiveRecord::Schema.define(version: 20171214130636) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" enable_extension "postgis" enable_extension "hstore" + enable_extension "unaccent" create_table "access_links", id: :bigserial, force: :cascade do |t| t.integer "access_point_id", limit: 8 -- cgit v1.2.3 From c8ae1cde1def7f1765e3cc7bc1a20689ae605521 Mon Sep 17 00:00:00 2001 From: Xinhui Date: Thu, 14 Dec 2017 14:12:50 +0100 Subject: Autocomplete stop area, use unaccent in query search Refs #5305 --- app/controllers/autocomplete_stop_areas_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/autocomplete_stop_areas_controller.rb b/app/controllers/autocomplete_stop_areas_controller.rb index 233012028..be1badff0 100644 --- a/app/controllers/autocomplete_stop_areas_controller.rb +++ b/app/controllers/autocomplete_stop_areas_controller.rb @@ -18,7 +18,7 @@ class AutocompleteStopAreasController < ChouetteController scope = scope.possible_parents if relation_children? end args = [].tap{|arg| 4.times{arg << "%#{params[:q]}%"}} - @stop_areas = scope.where("name ILIKE ? OR city_name ILIKE ? OR registration_number ILIKE ? OR objectid ILIKE ?", *args).limit(50) + @stop_areas = scope.where("unaccent(name) ILIKE unaccent(?) OR unaccent(city_name) ILIKE unaccent(?) OR registration_number ILIKE ? OR objectid ILIKE ?", *args).limit(50) @stop_areas end -- cgit v1.2.3 From b05efc905c3acc6fcc72cf5135799d692c80593e Mon Sep 17 00:00:00 2001 From: Xinhui Date: Fri, 15 Dec 2017 16:22:55 +0100 Subject: Remove edit duplicate edit link Refs #5300 --- app/views/referential_companies/index.html.slim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/referential_companies/index.html.slim b/app/views/referential_companies/index.html.slim index de0f7de69..07de2bc9d 100644 --- a/app/views/referential_companies/index.html.slim +++ b/app/views/referential_companies/index.html.slim @@ -46,7 +46,7 @@ attribute: 'url' \ ) \ ], - links: [:show, :edit], + links: [:show], cls: 'table has-search' = new_pagination @companies, 'pull-right' -- cgit v1.2.3 From 49952f6be36a59f167310db6f902a84a165150a0 Mon Sep 17 00:00:00 2001 From: Xinhui Date: Fri, 15 Dec 2017 16:24:10 +0100 Subject: Refactoring use destroy_link_content & remove create link Refs #5300 --- app/decorators/company_decorator.rb | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/app/decorators/company_decorator.rb b/app/decorators/company_decorator.rb index 96a5175bc..50b82d276 100644 --- a/app/decorators/company_decorator.rb +++ b/app/decorators/company_decorator.rb @@ -18,13 +18,6 @@ class CompanyDecorator < Draper::Decorator def action_links links = [] - if h.policy(Chouette::Company).create? - links << Link.new( - content: h.t('companies.actions.new'), - href: h.new_line_referential_company_path(context[:referential]) - ) - end - if h.policy(object).update? links << Link.new( content: h.t('companies.actions.edit'), @@ -37,7 +30,7 @@ class CompanyDecorator < Draper::Decorator if h.policy(object).destroy? links << Link.new( - content: h.t('companies.actions.destroy'), + content: h.destroy_link_content('companies.actions.destroy'), href: h.line_referential_company_path( context[:referential], object -- cgit v1.2.3 From aef2f87d6a64072bab3766094f483127d2e7bb38 Mon Sep 17 00:00:00 2001 From: Alban Peignier Date: Mon, 18 Dec 2017 11:08:02 +0100 Subject: Remove unless subject alias_method. Use be_nil when possible. Refs #5283 --- spec/models/referential_cloning_spec.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/spec/models/referential_cloning_spec.rb b/spec/models/referential_cloning_spec.rb index c01be20a9..4327c98aa 100644 --- a/spec/models/referential_cloning_spec.rb +++ b/spec/models/referential_cloning_spec.rb @@ -1,7 +1,6 @@ require 'spec_helper' RSpec.describe ReferentialCloning, :type => :model do - alias_method :referential_cloning, :subject it 'should have a valid factory' do expect(FactoryGirl.build(:referential_cloning)).to be_valid @@ -66,12 +65,12 @@ RSpec.describe ReferentialCloning, :type => :model do it "defines started_at" do referential_cloning.clone! - expect(referential_cloning.started_at).not_to be(nil) + expect(referential_cloning.started_at).not_to be_nil end it "defines ended_at" do referential_cloning.clone! - expect(referential_cloning.ended_at).not_to be(nil) + expect(referential_cloning.ended_at).not_to be_nil end end -- cgit v1.2.3 From 69271aaae3df5fb50249dd0428945804135b1f8e Mon Sep 17 00:00:00 2001 From: Zog Date: Mon, 18 Dec 2017 11:19:05 +0100 Subject: Refs #5231@0.1h; Fix wrong I18n Fix wrong french translation for Line.number --- config/locales/lines.fr.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/lines.fr.yml b/config/locales/lines.fr.yml index 35f8792f4..36254d754 100644 --- a/config/locales/lines.fr.yml +++ b/config/locales/lines.fr.yml @@ -74,7 +74,7 @@ fr: deactivated: "Activé" name: "Nom de la ligne" published_name: "Nom public" - number: "Nom court" + number: "Numéro" transport_mode: "Mode de transport" transport_submode: "Sous mode de transport" seasonal: "Saisonnière" -- cgit v1.2.3 From b97d6c4af9f3d9f4f9be82031557c05b83e3b1d4 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 18 Dec 2017 12:53:48 +0100 Subject: Imports#create: Add flash message Add a message to let users know that the import has started and to be patient while it does its thing. Refs #5317 --- config/locales/imports.en.yml | 4 ++++ config/locales/imports.fr.yml | 4 ++++ spec/controllers/imports_controller_spec.rb | 14 ++++++++++++++ 3 files changed, 22 insertions(+) diff --git a/config/locales/imports.en.yml b/config/locales/imports.en.yml index 0bb54d90d..462b17196 100644 --- a/config/locales/imports.en.yml +++ b/config/locales/imports.en.yml @@ -74,3 +74,7 @@ en: max_distance_for_connection_link: "Max distance for connection link" ignore_last_word: "ignore last word" ignore_end_chars: "ignore last chars" + flash: + imports: + create: + notice: "The import is in progress. Please wait and refresh the page in a few moments." diff --git a/config/locales/imports.fr.yml b/config/locales/imports.fr.yml index 207f5cc31..b545f90df 100644 --- a/config/locales/imports.fr.yml +++ b/config/locales/imports.fr.yml @@ -74,3 +74,7 @@ fr: max_distance_for_connection_link: "Distance max pour créer les correspondances" ignore_last_word: "ignorer le dernier mot" ignore_end_chars: "ignorer les n derniers caractères" + flash: + imports: + create: + notice: "L'import est en cours, veuillez patienter. Actualiser votre page si vous voulez voir l'avancement de votre traitement." diff --git a/spec/controllers/imports_controller_spec.rb b/spec/controllers/imports_controller_spec.rb index 22be9f6ed..08495ff47 100644 --- a/spec/controllers/imports_controller_spec.rb +++ b/spec/controllers/imports_controller_spec.rb @@ -17,6 +17,20 @@ RSpec.describe ImportsController, :type => :controller do end end + describe "POST #create" do + it "displays a flash message" do + post :create, workbench_id: workbench.id, + import: { + name: 'Offre', + file: fixture_file_upload('nozip.zip') + } + + expect(controller).to set_flash[:notice].to( + I18n.t('flash.imports.create.notice') + ) + end + end + describe 'GET #download' do it 'should be successful' do get :download, workbench_id: workbench.id, id: import.id, token: import.token_download -- cgit v1.2.3 From cdfd4e184be3cb84400bb26b313d92384332123b Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 18 Dec 2017 13:36:29 +0100 Subject: Referentials#validate: Update flash message * Luc specified a new flash message string to use here. Update the old one with the new version. * Move the translation key to `notice.referentials.validate` because we have multiple "operation_in_progress" messages (this one for validation, and another for referential cloning/duplication). * Add a test to confirm that the flash message is set. Refs #5317 --- app/controllers/referentials_controller.rb | 2 +- config/locales/referentials.en.yml | 2 +- config/locales/referentials.fr.yml | 2 +- spec/controllers/referentials_controller_spec.rb | 12 ++++++++++++ 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/app/controllers/referentials_controller.rb b/app/controllers/referentials_controller.rb index ee1236912..f97e2c211 100644 --- a/app/controllers/referentials_controller.rb +++ b/app/controllers/referentials_controller.rb @@ -60,7 +60,7 @@ class ReferentialsController < ChouetteController def validate ComplianceControlSetCopyWorker.perform_async(params[:compliance_control_set], params[:id]) - flash[:notice] = I18n.t("referentials.operation_in_progress") + flash[:notice] = I18n.t('notice.referentials.validate') redirect_to(referential_path) end diff --git a/config/locales/referentials.en.yml b/config/locales/referentials.en.yml index 8420e9539..f3a9cdfd1 100644 --- a/config/locales/referentials.en.yml +++ b/config/locales/referentials.en.yml @@ -5,7 +5,6 @@ en: name: 'Search by name' line: 'Seach by associated lines' search_no_results: 'No data space matching your query' - operation_in_progress: The validation process is in progress error_period_filter: "The period filter must have valid bounding dates" index: title: 'Data spaces' @@ -126,6 +125,7 @@ en: notice: referentials: deleted: "Datasets has been successfully destroyed" + validate: "The validation is in progress. Please wait and refresh the page in a few moments." referential: archived: "The data space has been successfully archived" unarchived: "The data space has been successfully unarchived" diff --git a/config/locales/referentials.fr.yml b/config/locales/referentials.fr.yml index ec7ed776d..7f986ed93 100644 --- a/config/locales/referentials.fr.yml +++ b/config/locales/referentials.fr.yml @@ -5,7 +5,6 @@ fr: name: 'Indiquez un nom de jeu de données...' line: 'Indiquez une ligne...' search_no_results: 'Aucun jeu de données ne correspond à votre recherche' - operation_in_progress: L'opération de validation est en cours error_period_filter: "Le filtre par période doit contenir une date de début et de fin valides" index: title: 'Jeux de données' @@ -124,6 +123,7 @@ fr: notice: referentials: deleted: "Les jeux de données on été supprimés" + validate: "La validation est en cours, veuillez patienter. Actualiser votre page si vous voulez voir l'avancement de votre traitement." referential: archived: "Le jeu de données a été correctement conservé" unarchived: "Le jeu de données a été correctement déconservé" diff --git a/spec/controllers/referentials_controller_spec.rb b/spec/controllers/referentials_controller_spec.rb index fba063085..dad2b3c8f 100644 --- a/spec/controllers/referentials_controller_spec.rb +++ b/spec/controllers/referentials_controller_spec.rb @@ -30,4 +30,16 @@ describe ReferentialsController, :type => :controller do expect(assigns[:compliance_control_sets]).to eq([compliance_control_set]) end end + + describe "POST #validate" do + it "displays a flash message" do + post :validate, id: referential.id, params: { + compliance_control_set: create(:compliance_control_set).id + } + + expect(controller).to set_flash[:notice].to( + I18n.t('notice.referentials.validate') + ) + end + end end -- cgit v1.2.3 From 75f583ab29ebc29ad6b51f02f93b02c193e1a601 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 18 Dec 2017 13:42:57 +0100 Subject: Referentials#validate: Remove `I18n.` prefix Call `#t` directly since we can and because the rest of the controller does this without the `I18n.` prefix. Refs #5317 --- app/controllers/referentials_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/referentials_controller.rb b/app/controllers/referentials_controller.rb index f97e2c211..773de04fd 100644 --- a/app/controllers/referentials_controller.rb +++ b/app/controllers/referentials_controller.rb @@ -60,7 +60,7 @@ class ReferentialsController < ChouetteController def validate ComplianceControlSetCopyWorker.perform_async(params[:compliance_control_set], params[:id]) - flash[:notice] = I18n.t('notice.referentials.validate') + flash[:notice] = t('notice.referentials.validate') redirect_to(referential_path) end -- cgit v1.2.3 From f5ea5fc7d198eb0c183d76e06582909150befc40 Mon Sep 17 00:00:00 2001 From: Zog Date: Mon, 18 Dec 2017 14:23:36 +0100 Subject: Refs #5331; Show user's name ... ... instead of user's username in the top bar --- app/views/layouts/navigation/_main_nav_top.html.slim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/layouts/navigation/_main_nav_top.html.slim b/app/views/layouts/navigation/_main_nav_top.html.slim index d6c849d3f..363a89b48 100644 --- a/app/views/layouts/navigation/_main_nav_top.html.slim +++ b/app/views/layouts/navigation/_main_nav_top.html.slim @@ -11,7 +11,7 @@ span.fa.fa-lg.fa-tasks = link_to '#', class: 'menu-item', data: { panel: 'toggle', target: '#profile_panel' }, title: 'Profil' do - span = current_user.username + span = current_user.name span.fa.fa-lg.fa-user -- cgit v1.2.3 From 3fdd836fc62ef3164569e322b789cbe096226c04 Mon Sep 17 00:00:00 2001 From: Teddy Wing Date: Mon, 18 Dec 2017 17:23:04 +0100 Subject: Referentials#create: Add flash message on referential duplication When a "duplicate referential" action is initiated, show a flash message to let users know that it started and is in progress (and will take a while since it's an asynchronous task). Refs #5317 --- app/controllers/referentials_controller.rb | 2 ++ config/locales/referentials.en.yml | 1 + config/locales/referentials.fr.yml | 1 + spec/controllers/referentials_controller_spec.rb | 17 +++++++++++++++++ 4 files changed, 21 insertions(+) diff --git a/app/controllers/referentials_controller.rb b/app/controllers/referentials_controller.rb index 773de04fd..40e8264ce 100644 --- a/app/controllers/referentials_controller.rb +++ b/app/controllers/referentials_controller.rb @@ -17,6 +17,8 @@ class ReferentialsController < ChouetteController build_referenial if !!@referential.created_from_id + flash[:notice] = t('notice.referentials.duplicate') + format.html { redirect_to workbench_path(@referential.workbench) } end end diff --git a/config/locales/referentials.en.yml b/config/locales/referentials.en.yml index f3a9cdfd1..f41e35446 100644 --- a/config/locales/referentials.en.yml +++ b/config/locales/referentials.en.yml @@ -125,6 +125,7 @@ en: notice: referentials: deleted: "Datasets has been successfully destroyed" + duplicate: "The duplication is in progress. Please wait and refresh the page in a few moments." validate: "The validation is in progress. Please wait and refresh the page in a few moments." referential: archived: "The data space has been successfully archived" diff --git a/config/locales/referentials.fr.yml b/config/locales/referentials.fr.yml index 7f986ed93..9250a033c 100644 --- a/config/locales/referentials.fr.yml +++ b/config/locales/referentials.fr.yml @@ -123,6 +123,7 @@ fr: notice: referentials: deleted: "Les jeux de données on été supprimés" + duplicate: "La duplication est en cours, veuillez patienter. Actualiser votre page si vous voulez voir l'avancement de votre traitement." validate: "La validation est en cours, veuillez patienter. Actualiser votre page si vous voulez voir l'avancement de votre traitement." referential: archived: "Le jeu de données a été correctement conservé" diff --git a/spec/controllers/referentials_controller_spec.rb b/spec/controllers/referentials_controller_spec.rb index dad2b3c8f..4050a8812 100644 --- a/spec/controllers/referentials_controller_spec.rb +++ b/spec/controllers/referentials_controller_spec.rb @@ -42,4 +42,21 @@ describe ReferentialsController, :type => :controller do ) end end + + describe "POST #create" do + context "when duplicating" do + it "displays a flash message" do + post :create, + from: referential.id, + current_workbench_id: referential.workbench_id, + referential: { + name: 'Duplicated' + } + + expect(controller).to set_flash[:notice].to( + I18n.t('notice.referentials.duplicate') + ) + end + end + end end -- cgit v1.2.3 From 4084c176a305cfed393f8090d3ec8d998865ea4a Mon Sep 17 00:00:00 2001 From: Xinhui Date: Tue, 19 Dec 2017 12:02:06 +0100 Subject: Controller spec AutocompleteStopAreas Refs #5305 --- .../autocomplete_stop_areas_controller_spec.rb | 29 ++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 spec/controllers/autocomplete_stop_areas_controller_spec.rb diff --git a/spec/controllers/autocomplete_stop_areas_controller_spec.rb b/spec/controllers/autocomplete_stop_areas_controller_spec.rb new file mode 100644 index 000000000..50fc877dd --- /dev/null +++ b/spec/controllers/autocomplete_stop_areas_controller_spec.rb @@ -0,0 +1,29 @@ +require 'rails_helper' + +RSpec.describe AutocompleteStopAreasController, type: :controller do + login_user + + let(:referential) { Referential.first } + let!(:stop_area) { create :stop_area, name: 'écolà militaire' } + + describe 'GET #index' do + it 'should be successful' do + get :index, referential_id: referential.id + expect(response).to be_success + end + + context 'search by name' do + it 'should be successful' do + get :index, referential_id: referential.id, q: 'écolà', :format => :json + expect(response).to be_success + expect(assigns(:stop_areas)).to eq([stop_area]) + end + + it 'should be accent insensitive' do + get :index, referential_id: referential.id, q: 'ecola', :format => :json + expect(response).to be_success + expect(assigns(:stop_areas)).to eq([stop_area]) + end + end + end +end -- cgit v1.2.3 From 74a601f6f35e0a547d3cde0501081e6e9f509959 Mon Sep 17 00:00:00 2001 From: Zog Date: Fri, 15 Dec 2017 17:01:49 +0100 Subject: Ref #5291@2h; Specs setup - Refactor specs helper to be more generic - Write missing specs for the Workbenches#show view We now have failing tests highlighting the bug --- app/helpers/table_builder_helper.rb | 18 ++++++++-- spec/support/integration_spec_helper.rb | 30 ++++++++++++++++ spec/views/offer_workbenches/show.html.erb_spec.rb | 41 ++++++++++++++++++++-- spec/views/stop_areas/index.html.slim_spec.rb | 31 ++++------------ 4 files changed, 91 insertions(+), 29 deletions(-) diff --git a/app/helpers/table_builder_helper.rb b/app/helpers/table_builder_helper.rb index 37f01ce0d..59906dc87 100644 --- a/app/helpers/table_builder_helper.rb +++ b/app/helpers/table_builder_helper.rb @@ -95,6 +95,18 @@ module TableBuilderHelper class: cls end + def self.item_row_class_name collection + if collection.respond_to?(:model) + model_name = collection.model.name + elsif collection.respond_to?(:first) + model_name = collection.first.class.name + else + model_name = "item" + end + + model_name.split("::").last.parameterize + end + private def thead(collection, columns, sortable, selectable, has_links, overhead, model ) @@ -188,10 +200,12 @@ module TableBuilderHelper end def tbody(collection, columns, selectable, links, overhead) + model_name = TableBuilderHelper.item_row_class_name collection + content_tag :tbody do collection.map do |item| - - content_tag :tr do + klass = "#{model_name}-#{item.id}" + content_tag :tr, class: klass do bcont = [] if selectable diff --git a/spec/support/integration_spec_helper.rb b/spec/support/integration_spec_helper.rb index 182cadf24..5bcf0bd3a 100644 --- a/spec/support/integration_spec_helper.rb +++ b/spec/support/integration_spec_helper.rb @@ -4,9 +4,39 @@ module IntegrationSpecHelper let(:permissions){ [permission] } context('', &block) if block_given? end + + def paginate_collection klass, decorator, page=1 + ModelDecorator.decorate( klass.page(page), with: decorator ) + end + + def build_paginated_collection factory, decorator, opts={} + count = opts.delete(:count) || 2 + page = opts.delete(:page) || 1 + klass = nil + count.times { klass ||= create(factory, opts).class } + paginate_collection klass, decorator, page + end end end RSpec.configure do |config| config.extend IntegrationSpecHelper, type: :view end + +RSpec::Matchers.define :have_link_for_each_item do |collection, name, href| + match do |actual| + collection.each do |item| + expect(rendered).to have_selector("tr.#{TableBuilderHelper.item_row_class_name(collection)}-#{item.id} .actions a[href='#{href.call(item)}']", count: 1) + end + end + description { "have #{name} link for each item" } +end + +RSpec::Matchers.define :have_the_right_number_of_links do |collection, count| + match do |actual| + collection.each do |item| + expect(rendered).to have_selector("tr.#{TableBuilderHelper.item_row_class_name(collection)}-#{item.id} .actions a", count: count) + end + end + description { "have #{count} links for each item" } +end diff --git a/spec/views/offer_workbenches/show.html.erb_spec.rb b/spec/views/offer_workbenches/show.html.erb_spec.rb index 40b09268a..597335166 100644 --- a/spec/views/offer_workbenches/show.html.erb_spec.rb +++ b/spec/views/offer_workbenches/show.html.erb_spec.rb @@ -1,5 +1,42 @@ -require 'rails_helper' +require 'spec_helper' -RSpec.describe "workbenches/show.html.erb", :type => :view do +describe "workbenches/show", :type => :view do + let!(:ids) { ['STIF:CODIFLIGNE:Line:C00840', 'STIF:CODIFLIGNE:Line:C00086'] } + let!(:lines) { + ids.map do |id| + create :line, objectid: id, line_referential: workbench.line_referential + end + } + let!(:workbench){ assign :workbench, create(:workbench) } + let!(:same_organisation_referential){ create :workbench_referential, workbench: workbench, metadatas: [create(:referential_metadata, lines: lines)] } + let!(:different_organisation_referential){ create :workbench_referential, metadatas: [create(:referential_metadata, lines: lines)] } + let!(:referentials){ + same_organisation_referential && different_organisation_referential + assign :wbench_refs, paginate_collection(Referential, ReferentialDecorator) + } + let!(:q) { assign :q_for_form, Ransack::Search.new(Referential) } + before :each do + + lines + controller.request.path_parameters[:id] = workbench.id + expect(workbench.referentials).to include same_organisation_referential + expect(workbench.referentials).to_not include different_organisation_referential + expect(workbench.all_referentials).to include same_organisation_referential + expect(workbench.all_referentials).to include different_organisation_referential + render + end + + it { should have_link_for_each_item(referentials, "show", -> (referential){ view.referential_path(referential) }) } + it "should enable the checkbox for the referential which belongs to the same organisation" do + klass = "#{TableBuilderHelper.item_row_class_name(referentials)}-#{same_organisation_referential.id}" + selector = "tr.#{klass} [type=checkbox][value='#{same_organisation_referential.id}']:not([disabled])" + expect(rendered).to have_selector(selector, count: 1) + end + + it "should disable the checkbox for the referential which does not belong to the same organisation" do + klass = "#{TableBuilderHelper.item_row_class_name(referentials)}-#{different_organisation_referential.id}" + selector = "tr.#{klass} [type=checkbox][disabled][value='#{different_organisation_referential.id}']" + expect(rendered).to have_selector(selector, count: 1) + 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 e0c50685c..ecd76fb03 100644 --- a/spec/views/stop_areas/index.html.slim_spec.rb +++ b/spec/views/stop_areas/index.html.slim_spec.rb @@ -1,29 +1,10 @@ require 'spec_helper' -RSpec::Matchers.define :have_link_for_each_stop_area do |stop_areas, name, href| - match do |actual| - stop_areas.each do |stop_area| - expect(rendered).to have_selector("tr.stoparea-#{stop_area.id} .actions a[href='#{href.call(stop_area)}']", count: 1) - end - end - description { "have #{name} link for each stop area" } -end - -RSpec::Matchers.define :have_the_right_number_of_links do |stop_areas, count| - match do |actual| - stop_areas.each do |stop_area| - expect(rendered).to have_selector("tr.stoparea-#{stop_area.id} .actions a", count: count) - end - end - description { "have #{count} links for each stop area" } -end - describe "/stop_areas/index", :type => :view do let!(:stop_area_referential) { assign :stop_area_referential, create(:stop_area_referential) } let!(:stop_areas) do - 2.times { create(:stop_area, stop_area_referential: stop_area_referential) } - assign :stop_areas, ModelDecorator.decorate( Chouette::StopArea.page(1), with: StopAreaDecorator ) + 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) } @@ -35,18 +16,18 @@ describe "/stop_areas/index", :type => :view do render end - it { should have_link_for_each_stop_area(stop_areas, "show", -> (stop_area){ view.stop_area_referential_stop_area_path(stop_area_referential, stop_area) }) } + it { should have_link_for_each_item(stop_areas, "show", -> (stop_area){ view.stop_area_referential_stop_area_path(stop_area_referential, stop_area) }) } it { should have_the_right_number_of_links(stop_areas, 1) } with_permission "stop_areas.create" do - it { should have_link_for_each_stop_area(stop_areas, "show", -> (stop_area){ view.stop_area_referential_stop_area_path(stop_area_referential, stop_area) }) } - it { should have_link_for_each_stop_area(stop_areas, "create", -> (stop_area){ view.new_stop_area_referential_stop_area_path(stop_area_referential) }) } + it { should have_link_for_each_item(stop_areas, "show", -> (stop_area){ view.stop_area_referential_stop_area_path(stop_area_referential, stop_area) }) } + it { should 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, 2) } end with_permission "stop_areas.update" do - it { should have_link_for_each_stop_area(stop_areas, "show", -> (stop_area){ view.stop_area_referential_stop_area_path(stop_area_referential, stop_area) }) } - it { should have_link_for_each_stop_area(stop_areas, "edit", -> (stop_area){ view.edit_stop_area_referential_stop_area_path(stop_area_referential, stop_area) }) } + it { should have_link_for_each_item(stop_areas, "show", -> (stop_area){ view.stop_area_referential_stop_area_path(stop_area_referential, stop_area) }) } + 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 -- cgit v1.2.3 From 3a78b0d44affe79ec297f1a25ee3cfe4ecd32a74 Mon Sep 17 00:00:00 2001 From: Zog Date: Fri, 15 Dec 2017 17:54:31 +0100 Subject: Refs: #5291@1h; Update TableBuilderHelper Update TableBuilderHelper to allow the `selectable` param to be a lambda, thus allowing us to have row-based granularity. --- app/helpers/table_builder_helper.rb | 131 +++++++++++---------- spec/helpers/table_builder_helper_spec.rb | 81 +++++++++++++ spec/views/offer_workbenches/show.html.erb_spec.rb | 2 - 3 files changed, 149 insertions(+), 65 deletions(-) diff --git a/app/helpers/table_builder_helper.rb b/app/helpers/table_builder_helper.rb index 59906dc87..de78e903d 100644 --- a/app/helpers/table_builder_helper.rb +++ b/app/helpers/table_builder_helper.rb @@ -199,88 +199,92 @@ module TableBuilderHelper end end - def tbody(collection, columns, selectable, links, overhead) - model_name = TableBuilderHelper.item_row_class_name collection - - content_tag :tbody do - collection.map do |item| - klass = "#{model_name}-#{item.id}" - content_tag :tr, class: klass do - bcont = [] - - if selectable - bcont << content_tag( - :td, - checkbox(id_name: item.try(:id), value: item.try(:id)) - ) - end - - columns.each do |column| - value = column.value(item) - - if column.linkable? - path = column.link_to(item) - link = link_to(value, path) + def tr item, columns, selectable, links, overhead, model_name + klass = "#{model_name}-#{item.id}" + content_tag :tr, class: klass do + bcont = [] + if selectable + disabled = selectable.respond_to?(:call) && !selectable.call(item) + bcont << content_tag( + :td, + checkbox(id_name: item.try(:id), value: item.try(:id), disabled: disabled) + ) + end - if overhead.empty? - bcont << content_tag(:td, link, title: 'Voir') + columns.each do |column| + value = column.value(item) - else - i = columns.index(column) + if column.linkable? + path = column.link_to(item) + link = link_to(value, path) - if overhead[i].blank? - if (i > 0) && (overhead[i - 1][:width] > 1) - clsArrayAlt = overhead[i - 1][:cls].split + if overhead.empty? + bcont << content_tag(:td, link, title: 'Voir') - bcont << content_tag(:td, link, title: 'Voir', class: td_cls(clsArrayAlt)) + else + i = columns.index(column) - else - bcont << content_tag(:td, link, title: 'Voir') - end + if overhead[i].blank? + if (i > 0) && (overhead[i - 1][:width] > 1) + clsArrayAlt = overhead[i - 1][:cls].split - else - clsArray = overhead[columns.index(column)][:cls].split + bcont << content_tag(:td, link, title: 'Voir', class: td_cls(clsArrayAlt)) - bcont << content_tag(:td, link, title: 'Voir', class: td_cls(clsArray)) - end + else + bcont << content_tag(:td, link, title: 'Voir') end else - if overhead.empty? - bcont << content_tag(:td, value) + clsArray = overhead[columns.index(column)][:cls].split - else - i = columns.index(column) + bcont << content_tag(:td, link, title: 'Voir', class: td_cls(clsArray)) + end + end - if overhead[i].blank? - if (i > 0) && (overhead[i - 1][:width] > 1) - clsArrayAlt = overhead[i - 1][:cls].split + else + if overhead.empty? + bcont << content_tag(:td, value) - bcont << content_tag(:td, value, class: td_cls(clsArrayAlt)) + else + i = columns.index(column) - else - bcont << content_tag(:td, value) - end + if overhead[i].blank? + if (i > 0) && (overhead[i - 1][:width] > 1) + clsArrayAlt = overhead[i - 1][:cls].split - else - clsArray = overhead[i][:cls].split + bcont << content_tag(:td, value, class: td_cls(clsArrayAlt)) - bcont << content_tag(:td, value, class: td_cls(clsArray)) - end + else + bcont << content_tag(:td, value) end + + else + clsArray = overhead[i][:cls].split + + bcont << content_tag(:td, value, class: td_cls(clsArray)) end end + end + end - if links.any? || item.try(:action_links).try(:any?) - bcont << content_tag( - :td, - build_links(item, links), - class: 'actions' - ) - end + if links.any? || item.try(:action_links).try(:any?) + bcont << content_tag( + :td, + build_links(item, links), + class: 'actions' + ) + end - bcont.join.html_safe - end + bcont.join.html_safe + end + end + + def tbody(collection, columns, selectable, links, overhead) + model_name = TableBuilderHelper.item_row_class_name collection + + content_tag :tbody do + collection.map do |item| + tr item, columns, selectable, links, overhead, model_name end.join.html_safe end end @@ -355,13 +359,14 @@ module TableBuilderHelper end end - def checkbox(id_name:, value:) + def checkbox(id_name:, value:, disabled: false) content_tag :div, '', class: 'checkbox' do - check_box_tag(id_name, value).concat( + check_box_tag(id_name, value, nil, disabled: disabled).concat( content_tag(:label, '', for: id_name) ) end end + def gear_menu_link(link) content_tag( :li, diff --git a/spec/helpers/table_builder_helper_spec.rb b/spec/helpers/table_builder_helper_spec.rb index 3b0a18379..8c77bd465 100644 --- a/spec/helpers/table_builder_helper_spec.rb +++ b/spec/helpers/table_builder_helper_spec.rb @@ -381,5 +381,86 @@ describe TableBuilderHelper, type: :helper do expect(beautified_html).to eq(expected.chomp) end + + context "on a single row" do + let(:referential){ build_stubbed :referential } + let(:other_referential){ build_stubbed :referential } + let(:user_context){ + UserContext.new( + build_stubbed( + :user, + organisation: referential.organisation, + permissions: [ + 'referentials.create', + 'referentials.update', + 'referentials.destroy', + ] + ), + referential: referential + ) + } + let(:columns){ + [ + TableBuilderHelper::Column.new( + key: :name, + attribute: 'name' + ), + ] + } + let(:item){ referential.decorate } + let(:other_item){ other_referential.decorate } + let(:selectable){ false } + let(:links){ [:show] } + let(:overhead){ [] } + let(:model_name){ "referential" } + let(:other_tr){ helper.send(:tr, other_item, columns, selectable, links, overhead, model_name) } + let(:items){ [item, other_item] } + + before(:each){ + allow(helper).to receive(:current_user).and_return(user_context) + } + + context "with all rows non-selectable" do + let(:selectable){ false } + it "sets all rows as non selectable" do + items.each do |i| + tr = helper.send(:tr, i, columns, selectable, links, overhead, model_name) + klass = "#{TableBuilderHelper.item_row_class_name([referential])}-#{i.id}" + selector = "tr.#{klass} [type=checkbox]" + expect(tr).to_not have_selector selector + end + end + end + + context "with all rows selectable" do + let(:selectable){ true } + it "adds a checkbox in all rows" do + items.each do |i| + tr = helper.send(:tr, i, columns, selectable, links, overhead, model_name) + klass = "#{TableBuilderHelper.item_row_class_name([referential])}-#{i.id}" + selector = "tr.#{klass} [type=checkbox]" + expect(tr).to have_selector selector + end + end + end + + context "with THIS row non selectable" do + let(:selectable){ ->(i){ i.id != item.id } } + it "adds a checkbox in all rows" do + items.each do |i| + tr = helper.send(:tr, i, columns, selectable, links, overhead, model_name) + klass = "#{TableBuilderHelper.item_row_class_name([referential])}-#{i.id}" + selector = "tr.#{klass} [type=checkbox]" + expect(tr).to have_selector selector + end + end + it "disables this rows checkbox" do + tr = helper.send(:tr, item, columns, selectable, links, overhead, model_name) + klass = "#{TableBuilderHelper.item_row_class_name([referential])}-#{item.id}" + selector = "tr.#{klass} [type=checkbox][disabled]" + expect(tr).to have_selector selector + end + end + end end end diff --git a/spec/views/offer_workbenches/show.html.erb_spec.rb b/spec/views/offer_workbenches/show.html.erb_spec.rb index 597335166..44dfe88f1 100644 --- a/spec/views/offer_workbenches/show.html.erb_spec.rb +++ b/spec/views/offer_workbenches/show.html.erb_spec.rb @@ -7,7 +7,6 @@ describe "workbenches/show", :type => :view do create :line, objectid: id, line_referential: workbench.line_referential end } - let!(:workbench){ assign :workbench, create(:workbench) } let!(:same_organisation_referential){ create :workbench_referential, workbench: workbench, metadatas: [create(:referential_metadata, lines: lines)] } let!(:different_organisation_referential){ create :workbench_referential, metadatas: [create(:referential_metadata, lines: lines)] } @@ -17,7 +16,6 @@ describe "workbenches/show", :type => :view do } let!(:q) { assign :q_for_form, Ransack::Search.new(Referential) } before :each do - lines controller.request.path_parameters[:id] = workbench.id expect(workbench.referentials).to include same_organisation_referential -- cgit v1.2.3 From 0403917aab03cfc3200f62e70f255bc7887cdcdf Mon Sep 17 00:00:00 2001 From: Zog Date: Mon, 18 Dec 2017 08:52:18 +0100 Subject: Refs #5291@0.5h; Update view Update the view to match the actual controller behaviour. --- app/views/workbenches/show.html.slim | 2 +- spec/views/offer_workbenches/show.html.erb_spec.rb | 35 ++++++++++++++++------ 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/app/views/workbenches/show.html.slim b/app/views/workbenches/show.html.slim index af312fc08..1c82c34b7 100644 --- a/app/views/workbenches/show.html.slim +++ b/app/views/workbenches/show.html.slim @@ -57,7 +57,7 @@ attribute: '' \ ) \ ], - selectable: true, + selectable: ->(ref){ @workbench.referentials.include?(ref) }, links: [:show, :edit], cls: 'table has-filter has-search' diff --git a/spec/views/offer_workbenches/show.html.erb_spec.rb b/spec/views/offer_workbenches/show.html.erb_spec.rb index 44dfe88f1..cc01c9d0e 100644 --- a/spec/views/offer_workbenches/show.html.erb_spec.rb +++ b/spec/views/offer_workbenches/show.html.erb_spec.rb @@ -1,5 +1,18 @@ require 'spec_helper' +RSpec::Matchers.define :have_box_for_item do |item, disabled| + match do |actual| + klass = "#{TableBuilderHelper.item_row_class_name([item])}-#{item.id}" + if disabled + selector = "tr.#{klass} [type=checkbox][disabled][value='#{item.id}']" + else + selector = "tr.#{klass} [type=checkbox][value='#{item.id}']:not([disabled])" + end + expect(actual).to have_selector(selector, count: 1) + end + description { "have a #{disabled ? "disabled ": ""}box for the item ##{item.id}" } +end + describe "workbenches/show", :type => :view do let!(:ids) { ['STIF:CODIFLIGNE:Line:C00840', 'STIF:CODIFLIGNE:Line:C00086'] } let!(:lines) { @@ -18,7 +31,7 @@ describe "workbenches/show", :type => :view do before :each do lines controller.request.path_parameters[:id] = workbench.id - expect(workbench.referentials).to include same_organisation_referential + expect(workbench.referentials).to include same_organisation_referential expect(workbench.referentials).to_not include different_organisation_referential expect(workbench.all_referentials).to include same_organisation_referential expect(workbench.all_referentials).to include different_organisation_referential @@ -26,15 +39,19 @@ describe "workbenches/show", :type => :view do end it { should have_link_for_each_item(referentials, "show", -> (referential){ view.referential_path(referential) }) } - it "should enable the checkbox for the referential which belongs to the same organisation" do - klass = "#{TableBuilderHelper.item_row_class_name(referentials)}-#{same_organisation_referential.id}" - selector = "tr.#{klass} [type=checkbox][value='#{same_organisation_referential.id}']:not([disabled])" - expect(rendered).to have_selector(selector, count: 1) + + context "without permission" do + it "should disable all the checkboxes" do + expect(rendered).to have_box_for_item same_organisation_referential, false + expect(rendered).to have_box_for_item different_organisation_referential, true + end end - it "should disable the checkbox for the referential which does not belong to the same organisation" do - klass = "#{TableBuilderHelper.item_row_class_name(referentials)}-#{different_organisation_referential.id}" - selector = "tr.#{klass} [type=checkbox][disabled][value='#{different_organisation_referential.id}']" - expect(rendered).to have_selector(selector, count: 1) + with_permission "referentials.destroy" do + it "should enable the checkbox for the referential which belongs to the same organisation and disable the other one" do + expect(rendered).to have_box_for_item same_organisation_referential, false + expect(rendered).to have_box_for_item different_organisation_referential, true + end end + end -- cgit v1.2.3 From f875a1b07db4f877f406952ef9074d7ed54f5a6d Mon Sep 17 00:00:00 2001 From: Zog Date: Mon, 18 Dec 2017 09:11:03 +0100 Subject: Refs #5291@0.1h; Add missing styles Add missing styles for disabled checkboxes --- app/assets/stylesheets/base/_config.sass | 1 + app/assets/stylesheets/components/_forms.sass | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/app/assets/stylesheets/base/_config.sass b/app/assets/stylesheets/base/_config.sass index 65444479f..ec1c43e7f 100644 --- a/app/assets/stylesheets/base/_config.sass +++ b/app/assets/stylesheets/base/_config.sass @@ -16,6 +16,7 @@ $blue: #007fbb $darkgrey: #4b4b4b $grey: #a4a4a4 +$lightgrey: rgba($grey, 0.15) $green: #70b12b $red: #da2f36 diff --git a/app/assets/stylesheets/components/_forms.sass b/app/assets/stylesheets/components/_forms.sass index 9a363ab97..47faf19b1 100644 --- a/app/assets/stylesheets/components/_forms.sass +++ b/app/assets/stylesheets/components/_forms.sass @@ -229,6 +229,13 @@ $cbx-size-xs: 15px &[type='checkbox']:checked + label:before background-color: $blue + &[type='checkbox']:disabled + label + &:before + border-color: $grey + background-color: $lightgrey + cursor: not-allowed + &:after + display: none // Table adjustments table, .table .td, td, .th, th -- cgit v1.2.3 From 3aa5ff0d1f5e74b4c46c14e6240e7def82f0451d Mon Sep 17 00:00:00 2001 From: Zog Date: Mon, 18 Dec 2017 09:34:15 +0100 Subject: Refs #5291@0.1h; Fix rebase Fix integration_spec_helper after rebase --- spec/support/integration_spec_helper.rb | 37 ++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/spec/support/integration_spec_helper.rb b/spec/support/integration_spec_helper.rb index 5bcf0bd3a..78efb9027 100644 --- a/spec/support/integration_spec_helper.rb +++ b/spec/support/integration_spec_helper.rb @@ -1,26 +1,33 @@ module IntegrationSpecHelper - def with_permission permission, &block - context "with permission #{permission}" do - let(:permissions){ [permission] } - context('', &block) if block_given? - end - def paginate_collection klass, decorator, page=1 - ModelDecorator.decorate( klass.page(page), with: decorator ) - end + def paginate_collection klass, decorator, page=1 + ModelDecorator.decorate( klass.page(page), with: decorator ) + end - def build_paginated_collection factory, decorator, opts={} - count = opts.delete(:count) || 2 - page = opts.delete(:page) || 1 - klass = nil - count.times { klass ||= create(factory, opts).class } - paginate_collection klass, decorator, page + def build_paginated_collection factory, decorator, opts={} + count = opts.delete(:count) || 2 + page = opts.delete(:page) || 1 + klass = nil + count.times { klass ||= create(factory, opts).class } + paginate_collection klass, decorator, page + end + + module Methods + def with_permission permission, &block + context "with permission #{permission}" do + let(:permissions){ [permission] } + context('', &block) if block_given? + end end end + + def self.included into + into.extend Methods + end end RSpec.configure do |config| - config.extend IntegrationSpecHelper, type: :view + config.include IntegrationSpecHelper, type: :view end RSpec::Matchers.define :have_link_for_each_item do |collection, name, href| -- cgit v1.2.3 From 98c08c6fae5b0bf59231b3e402ca91307c200297 Mon Sep 17 00:00:00 2001 From: Zog Date: Mon, 18 Dec 2017 17:18:25 +0100 Subject: Refs #5333@1.5h; Use permissions to sync StopAreas and Lines - add missing policies - update permissions translator - update views to check for the permission - update views helper to check for the permission - uipdate controllers to check for the permission --- app/controllers/line_referentials_controller.rb | 1 + .../stop_area_referentials_controller.rb | 1 + app/helpers/application_helper.rb | 16 +++++++++++----- app/models/user.rb | 2 +- app/policies/calendar_policy.rb | 17 +++++++---------- app/policies/line_referential_policy.rb | 14 ++++++++++++++ app/policies/stop_area_referential_policy.rb | 14 ++++++++++++++ app/views/line_referentials/show.html.slim | 5 +++-- app/views/stop_area_referentials/show.html.slim | 5 +++-- lib/stif/permission_translator.rb | 15 +++++++++++---- .../line_referentials_controller_spec.rb | 14 ++++++++++++++ .../stop_area_referentials_controller_spec.rb | 17 +++++++++++++++++ spec/lib/stif/permission_translator_spec.rb | 15 +++++++++++++++ spec/policies/calendar_policy_spec.rb | 3 +++ spec/policies/line_referential_policy_spec.rb | 9 +++++++++ spec/policies/sto_area_referential_policy_spec.rb | 9 +++++++++ spec/support/controller_spec_helper.rb | 18 ++++++++++++++++++ .../views/line_referentials/show.html.slim_spec.rb | 22 ++++++++++++++++++++++ .../stop_area_referentials/show.html.slim_spec.rb | 22 ++++++++++++++++++++++ 19 files changed, 195 insertions(+), 24 deletions(-) create mode 100644 app/policies/line_referential_policy.rb create mode 100644 app/policies/stop_area_referential_policy.rb create mode 100644 spec/controllers/stop_area_referentials_controller_spec.rb create mode 100644 spec/policies/line_referential_policy_spec.rb create mode 100644 spec/policies/sto_area_referential_policy_spec.rb create mode 100644 spec/support/controller_spec_helper.rb create mode 100644 spec/views/line_referentials/show.html.slim_spec.rb create mode 100644 spec/views/line_referentials/stop_area_referentials/show.html.slim_spec.rb diff --git a/app/controllers/line_referentials_controller.rb b/app/controllers/line_referentials_controller.rb index 39c2cdb89..03dab3f8f 100644 --- a/app/controllers/line_referentials_controller.rb +++ b/app/controllers/line_referentials_controller.rb @@ -3,6 +3,7 @@ class LineReferentialsController < ChouetteController defaults :resource_class => LineReferential def sync + authorize resource, :synchronize? @sync = resource.line_referential_syncs.build if @sync.save flash[:notice] = t('notice.line_referential_sync.created') diff --git a/app/controllers/stop_area_referentials_controller.rb b/app/controllers/stop_area_referentials_controller.rb index 85541230d..f2d375e49 100644 --- a/app/controllers/stop_area_referentials_controller.rb +++ b/app/controllers/stop_area_referentials_controller.rb @@ -2,6 +2,7 @@ class StopAreaReferentialsController < ChouetteController defaults :resource_class => StopAreaReferential def sync + authorize resource, :synchronize? @sync = resource.stop_area_referential_syncs.build if @sync.save flash[:notice] = t('notice.stop_area_referential_sync.created') diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 124604cd9..713542ff4 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -23,12 +23,18 @@ module ApplicationHelper end def page_header_meta(object) - info = t('last_update', time: l(object.updated_at, format: :short)) - if object.try(:versions) - author = object.versions.try(:last).try(:whodunnit) || t('default_whodunnit') - info = "#{info}
#{t('whodunnit', author: author)}" + out = "" + display = true + display = policy(object).synchronize? if policy(object).respond_to?(:synchronize?) rescue false + if display + info = t('last_update', time: l(object.updated_at, format: :short)) + if object.try(:versions) + author = object.versions.try(:last).try(:whodunnit) || t('default_whodunnit') + info = "#{info}
#{t('whodunnit', author: author)}" + end + out += content_tag :div, info.html_safe, class: 'small last-update' end - content_tag :div, info.html_safe, class: 'small' + out.html_safe end def page_header_content_for(object) diff --git a/app/models/user.rb b/app/models/user.rb index 37d35209a..1342f60ed 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -36,7 +36,7 @@ class User < ActiveRecord::Base self.name = extra[:full_name] self.email = extra[:email] self.organisation = Organisation.sync_update extra[:organisation_code], extra[:organisation_name], extra[:functional_scope] - self.permissions = Stif::PermissionTranslator.translate(extra[:permissions]) + self.permissions = Stif::PermissionTranslator.translate(extra[:permissions], self.organisation) end def self.portail_api_request diff --git a/app/policies/calendar_policy.rb b/app/policies/calendar_policy.rb index 074c41d8d..3ba708ec9 100644 --- a/app/policies/calendar_policy.rb +++ b/app/policies/calendar_policy.rb @@ -5,18 +5,15 @@ class CalendarPolicy < ApplicationPolicy end end - def create? + def create? !archived? && user.has_permission?('calendars.create') end - def destroy? - !archived? & organisation_match? && user.has_permission?('calendars.destroy') - end - def update? - !archived? && organisation_match? && user.has_permission?('calendars.update') - end + def destroy?; instance_permission("destroy") end + def update?; instance_permission("update") end + def share?; instance_permission("share") end - def share? - user.organisation.name == 'STIF' # FIXME + private + def instance_permission permission + !archived? & organisation_match? && user.has_permission?("calendars.#{permission}") end - end diff --git a/app/policies/line_referential_policy.rb b/app/policies/line_referential_policy.rb new file mode 100644 index 000000000..ee742a083 --- /dev/null +++ b/app/policies/line_referential_policy.rb @@ -0,0 +1,14 @@ +class LineReferentialPolicy < ApplicationPolicy + class Scope < Scope + def resolve + scope + end + end + + def synchronize?; instance_permission("synchronize") end + + private + def instance_permission permission + user.has_permission?("line_referentials.#{permission}") + end +end diff --git a/app/policies/stop_area_referential_policy.rb b/app/policies/stop_area_referential_policy.rb new file mode 100644 index 000000000..e370babf8 --- /dev/null +++ b/app/policies/stop_area_referential_policy.rb @@ -0,0 +1,14 @@ +class StopAreaReferentialPolicy < ApplicationPolicy + class Scope < Scope + def resolve + scope + end + end + + def synchronize?; instance_permission("synchronize") end + + private + def instance_permission permission + user.has_permission?("stop_area_referentials.#{permission}") + end +end diff --git a/app/views/line_referentials/show.html.slim b/app/views/line_referentials/show.html.slim index b4b32bc52..763eb076e 100644 --- a/app/views/line_referentials/show.html.slim +++ b/app/views/line_referentials/show.html.slim @@ -1,7 +1,8 @@ - breadcrumb :line_referential, @line_referential - page_header_content_for @line_referential -- content_for :page_header_actions do - = link_to(t('actions.sync'), sync_line_referential_path(@line_referential), method: :post, class: 'btn btn-default') +- if policy(@line_referential).synchronize? + - content_for :page_header_actions do + = link_to(t('actions.sync'), sync_line_referential_path(@line_referential), method: :post, class: 'btn btn-default') - content_for :page_header_content do .row.mb-md diff --git a/app/views/stop_area_referentials/show.html.slim b/app/views/stop_area_referentials/show.html.slim index d43333fd9..f66db89f4 100644 --- a/app/views/stop_area_referentials/show.html.slim +++ b/app/views/stop_area_referentials/show.html.slim @@ -1,6 +1,7 @@ - breadcrumb :stop_area_referential, @stop_area_referential -- content_for :page_header_actions do - = link_to(t('actions.sync'), sync_stop_area_referential_path(@stop_area_referential), method: :post, class: 'btn btn-default') +- if policy(@stop_area_referential).synchronize? + - content_for :page_header_actions do + = link_to(t('actions.sync'), sync_stop_area_referential_path(@stop_area_referential), method: :post, class: 'btn btn-default') - content_for :page_header_content do .row.mb-md diff --git a/lib/stif/permission_translator.rb b/lib/stif/permission_translator.rb index 2d267bc7b..78a4bac18 100644 --- a/lib/stif/permission_translator.rb +++ b/lib/stif/permission_translator.rb @@ -1,11 +1,11 @@ module Stif module PermissionTranslator extend self - def translate(sso_extra_permissions) - sso_extra_permissions - .sort + def translate(sso_extra_permissions, organisation=nil) + permissions = sso_extra_permissions.sort .flat_map(&method(:extra_permission_translation)) - .uniq + permissions += extra_organisation_permissions(organisation) + permissions.uniq end private @@ -49,5 +49,12 @@ module Stif "boiv:edit-offer" => all_destructive_permissions + %w{sessions.create}, } end + + def extra_organisation_permissions organisation + if organisation&.name&.downcase == "stif" + return %w{calendars.share stop_area_referentials.synchronize line_referentials.synchronize} + end + [] + end end end diff --git a/spec/controllers/line_referentials_controller_spec.rb b/spec/controllers/line_referentials_controller_spec.rb index aee24b0fa..380fe32fd 100644 --- a/spec/controllers/line_referentials_controller_spec.rb +++ b/spec/controllers/line_referentials_controller_spec.rb @@ -1,3 +1,17 @@ RSpec.describe LineReferentialsController, :type => :controller do + login_user + let(:line_referential) { create :line_referential } + + describe 'PUT sync' do + let(:request){ put :sync, id: line_referential.id } + + it { request.should redirect_to "/403" } + + with_permission "line_referentials.synchronize" do + it 'returns HTTP success' do + expect(request).to redirect_to [line_referential] + end + end + end end diff --git a/spec/controllers/stop_area_referentials_controller_spec.rb b/spec/controllers/stop_area_referentials_controller_spec.rb new file mode 100644 index 000000000..c8d7e1736 --- /dev/null +++ b/spec/controllers/stop_area_referentials_controller_spec.rb @@ -0,0 +1,17 @@ +RSpec.describe StopAreaReferentialsController, :type => :controller do + login_user + + let(:stop_area_referential) { create :stop_area_referential } + + describe 'PUT sync' do + let(:request){ put :sync, id: stop_area_referential.id } + + it { request.should redirect_to "/403" } + + with_permission "stop_area_referentials.synchronize" do + it 'returns HTTP success' do + expect(request).to redirect_to [stop_area_referential] + end + end + end +end diff --git a/spec/lib/stif/permission_translator_spec.rb b/spec/lib/stif/permission_translator_spec.rb index ae1a2d1d5..04fc1c6f3 100644 --- a/spec/lib/stif/permission_translator_spec.rb +++ b/spec/lib/stif/permission_translator_spec.rb @@ -42,4 +42,19 @@ RSpec.describe Stif::PermissionTranslator do ).to match_array(Support::Permissions.all_permissions) end end + + context "For the STIF organisation" do + let(:organisation){ build_stubbed :organisation, name: "STIF" } + let(:permissions){ %w{calendars.share stop_area_referentials.synchronize line_referentials.synchronize}.sort } + it "adds the calendars.share permission" do + expect(described_class.translate([], organisation).sort).to eq permissions + end + + context "with the case changed" do + let(:organisation){ build_stubbed :organisation, name: "StiF" } + it "adds the calendars.share permission" do + expect(described_class.translate([], organisation).sort).to eq permissions + end + end + end end diff --git a/spec/policies/calendar_policy_spec.rb b/spec/policies/calendar_policy_spec.rb index 294be8198..8b1facc71 100644 --- a/spec/policies/calendar_policy_spec.rb +++ b/spec/policies/calendar_policy_spec.rb @@ -7,6 +7,9 @@ RSpec.describe CalendarPolicy, type: :policy do permissions :create? do it_behaves_like 'permitted policy', 'calendars.create', archived: true end + permissions :share? do + it_behaves_like 'permitted policy and same organisation', 'calendars.share', archived: true + end permissions :destroy? do it_behaves_like 'permitted policy and same organisation', 'calendars.destroy', archived: true end diff --git a/spec/policies/line_referential_policy_spec.rb b/spec/policies/line_referential_policy_spec.rb new file mode 100644 index 000000000..7e0a9da8e --- /dev/null +++ b/spec/policies/line_referential_policy_spec.rb @@ -0,0 +1,9 @@ +RSpec.describe LineReferentialPolicy, type: :policy do + + let( :record ){ build_stubbed :line_referential } + before { stub_policy_scope(record) } + + permissions :synchronize? do + it_behaves_like 'permitted policy', 'line_referentials.synchronize' + end +end diff --git a/spec/policies/sto_area_referential_policy_spec.rb b/spec/policies/sto_area_referential_policy_spec.rb new file mode 100644 index 000000000..5bd6da427 --- /dev/null +++ b/spec/policies/sto_area_referential_policy_spec.rb @@ -0,0 +1,9 @@ +RSpec.describe StopAreaReferentialPolicy, type: :policy do + + let( :record ){ build_stubbed :stop_area_referential } + before { stub_policy_scope(record) } + + permissions :synchronize? do + it_behaves_like 'permitted policy', 'stop_area_referentials.synchronize' + end +end diff --git a/spec/support/controller_spec_helper.rb b/spec/support/controller_spec_helper.rb new file mode 100644 index 000000000..1d0288dea --- /dev/null +++ b/spec/support/controller_spec_helper.rb @@ -0,0 +1,18 @@ +module ControllerSpecHelper + def with_permission permission, &block + context "with permission #{permission}" do + login_user + before(:each) do + @user.permissions << permission + @user.save! + sign_in @user + end + context('', &block) if block_given? + end + end + +end + +RSpec.configure do |config| + config.extend ControllerSpecHelper, type: :controller +end diff --git a/spec/views/line_referentials/show.html.slim_spec.rb b/spec/views/line_referentials/show.html.slim_spec.rb new file mode 100644 index 000000000..0516677cb --- /dev/null +++ b/spec/views/line_referentials/show.html.slim_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper' + +describe "/line_referentials/show", :type => :view do + + let!(:line_referential) { assign :line_referential, create(:line_referential) } + + before :each do + render + end + + it "should not present syncing infos and button" do + expect(view.content_for(:page_header_actions)).to_not have_selector("a[href=\"#{view.sync_line_referential_path(line_referential)}\"]") + expect(view.content_for(:page_header_meta)).to_not have_selector(".last-update") + end + + with_permission "line_referentials.synchronize" do + it "should present syncing infos and button" do + expect(view.content_for(:page_header_actions)).to have_selector("a[href=\"#{view.sync_line_referential_path(line_referential)}\"]", count: 1) + expect(view.content_for(:page_header_meta)).to have_selector(".last-update", count: 1) + end + end +end diff --git a/spec/views/line_referentials/stop_area_referentials/show.html.slim_spec.rb b/spec/views/line_referentials/stop_area_referentials/show.html.slim_spec.rb new file mode 100644 index 000000000..71a8d16f5 --- /dev/null +++ b/spec/views/line_referentials/stop_area_referentials/show.html.slim_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper' + +describe "/stop_area_referentials/show", :type => :view do + + let!(:stop_area_referential) { assign :stop_area_referential, create(:stop_area_referential) } + + before :each do + render + end + + it "should not present syncing infos and button" do + expect(view.content_for(:page_header_actions)).to_not have_selector("a[href=\"#{view.sync_stop_area_referential_path(stop_area_referential)}\"]") + expect(view.content_for(:page_header_meta)).to_not have_selector(".last-update") + end + + with_permission "stop_area_referentials.synchronize" do + it "should present syncing infos and button" do + expect(view.content_for(:page_header_actions)).to have_selector("a[href=\"#{view.sync_stop_area_referential_path(stop_area_referential)}\"]", count: 1) + expect(view.content_for(:page_header_meta)).to have_selector(".last-update", count: 1) + end + end +end -- cgit v1.2.3 From 023fdab6840c7bb2d87d8ffee2df478574158d6e Mon Sep 17 00:00:00 2001 From: Zog Date: Tue, 19 Dec 2017 14:24:10 +0100 Subject: Refs #5333; Minor CR improvement --- spec/controllers/line_referentials_controller_spec.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/spec/controllers/line_referentials_controller_spec.rb b/spec/controllers/line_referentials_controller_spec.rb index 380fe32fd..17ffb670d 100644 --- a/spec/controllers/line_referentials_controller_spec.rb +++ b/spec/controllers/line_referentials_controller_spec.rb @@ -6,7 +6,9 @@ RSpec.describe LineReferentialsController, :type => :controller do describe 'PUT sync' do let(:request){ put :sync, id: line_referential.id } - it { request.should redirect_to "/403" } + it 'should redirect to 403' do + expect(request).to redirect_to "/403" + end with_permission "line_referentials.synchronize" do it 'returns HTTP success' do -- cgit v1.2.3