aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/assets/stylesheets/base/_config.sass1
-rw-r--r--app/assets/stylesheets/components/_forms.sass7
-rw-r--r--app/assets/stylesheets/components/_panels.sass1
-rw-r--r--app/controllers/autocomplete_stop_areas_controller.rb2
-rw-r--r--app/controllers/line_referentials_controller.rb1
-rw-r--r--app/controllers/referentials_controller.rb4
-rw-r--r--app/controllers/stop_area_referentials_controller.rb1
-rw-r--r--app/controllers/stop_areas_controller.rb2
-rw-r--r--app/decorators/company_decorator.rb9
-rw-r--r--app/decorators/compliance_check_set_decorator.rb9
-rw-r--r--app/decorators/referential_line_decorator.rb15
-rw-r--r--app/decorators/stop_area_decorator.rb9
-rw-r--r--app/helpers/application_helper.rb16
-rw-r--r--app/helpers/table_builder_helper.rb141
-rw-r--r--app/models/chouette/area_type.rb37
-rw-r--r--app/models/chouette/stop_area.rb4
-rw-r--r--app/models/referential_cloning.rb21
-rw-r--r--app/models/user.rb2
-rw-r--r--app/policies/calendar_policy.rb19
-rw-r--r--app/policies/line_referential_policy.rb14
-rw-r--r--app/policies/stop_area_referential_policy.rb14
-rw-r--r--app/views/companies/index.html.slim2
-rw-r--r--app/views/compliance_check_sets/index.html.slim4
-rw-r--r--app/views/dashboards/_dashboard.html.slim4
-rw-r--r--app/views/devise/invitations/edit.html.slim33
-rw-r--r--app/views/devise/passwords/edit.html.slim28
-rw-r--r--app/views/devise/passwords/new.html.slim4
-rw-r--r--app/views/devise/sessions/new.html.slim2
-rw-r--r--app/views/layouts/navigation/_main_nav_top.html.slim2
-rw-r--r--app/views/line_referentials/show.html.slim5
-rw-r--r--app/views/referential_companies/index.html.slim2
-rw-r--r--app/views/stop_area_referentials/show.html.slim7
-rw-r--r--app/views/stop_areas/_filters.html.slim2
-rw-r--r--app/views/stop_areas/_form.html.slim2
-rw-r--r--app/views/stop_areas/index.html.slim6
-rw-r--r--app/views/stop_areas/show.html.slim2
-rw-r--r--app/views/stop_points/_stop_point.html.slim4
-rw-r--r--app/views/workbenches/show.html.slim2
-rw-r--r--app/workers/referential_cloning_worker.rb27
-rw-r--r--config/deploy.rb2
-rw-r--r--config/locales/calendars.en.yml5
-rw-r--r--config/locales/calendars.fr.yml5
-rw-r--r--config/locales/compliance_check_sets.fr.yml4
-rw-r--r--config/locales/imports.en.yml4
-rw-r--r--config/locales/imports.fr.yml4
-rw-r--r--config/locales/lines.fr.yml2
-rw-r--r--config/locales/referentials.en.yml3
-rw-r--r--config/locales/referentials.fr.yml3
-rw-r--r--config/locales/stop_areas.en.yml2
-rw-r--r--config/locales/stop_areas.fr.yml2
-rw-r--r--db/migrate/20171214130636_enable_unaccent_extension.rb9
-rw-r--r--db/schema.rb3
-rw-r--r--lib/stif/permission_translator.rb15
-rw-r--r--spec/controllers/autocomplete_stop_areas_controller_spec.rb29
-rw-r--r--spec/controllers/imports_controller_spec.rb14
-rw-r--r--spec/controllers/line_referentials_controller_spec.rb16
-rw-r--r--spec/controllers/referentials_controller_spec.rb29
-rw-r--r--spec/controllers/stop_area_referentials_controller_spec.rb17
-rw-r--r--spec/factories/chouette_stop_areas.rb2
-rw-r--r--spec/features/compliance_check_sets_spec.rb20
-rw-r--r--spec/helpers/table_builder_helper_spec.rb87
-rw-r--r--spec/lib/stif/permission_translator_spec.rb16
-rw-r--r--spec/models/chouette/area_type_spec.rb32
-rw-r--r--spec/models/referential_cloning_spec.rb63
-rw-r--r--spec/policies/calendar_policy_spec.rb16
-rw-r--r--spec/policies/line_referential_policy_spec.rb9
-rw-r--r--spec/policies/sto_area_referential_policy_spec.rb9
-rw-r--r--spec/support/controller_spec_helper.rb18
-rw-r--r--spec/support/integration_spec_helper.rb49
-rw-r--r--spec/support/pundit/pundit_view_policy.rb20
-rw-r--r--spec/views/connection_links/index.html.erb_spec.rb8
-rw-r--r--spec/views/connection_links/show.html.erb_spec.rb35
-rw-r--r--spec/views/connection_links/show.html.slim_spec.rb32
-rw-r--r--spec/views/line_referentials/show.html.slim_spec.rb22
-rw-r--r--spec/views/line_referentials/stop_area_referentials/show.html.slim_spec.rb22
-rw-r--r--spec/views/offer_workbenches/show.html.erb_spec.rb55
-rw-r--r--spec/views/stop_areas/index.html.erb_spec.rb25
-rw-r--r--spec/views/stop_areas/index.html.slim_spec.rb34
-rw-r--r--spec/workers/referential_cloning_worker_spec.rb53
79 files changed, 911 insertions, 351 deletions
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
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/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
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/referentials_controller.rb b/app/controllers/referentials_controller.rb
index ee1236912..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
@@ -60,7 +62,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] = t('notice.referentials.validate')
redirect_to(referential_path)
end
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/controllers/stop_areas_controller.rb b/app/controllers/stop_areas_controller.rb
index 133518324..d4d996adb 100644
--- a/app/controllers/stop_areas_controller.rb
+++ b/app/controllers/stop_areas_controller.rb
@@ -171,7 +171,7 @@ class StopAreasController < ChouetteController
helper_method :current_referential
def stop_area_params
- params.require(:stop_area).permit( :routing_stop_ids, :routing_line_ids, :children_ids, :stop_area_type, :parent_id, :objectid, :object_version, :name, :comment, :area_type, :registration_number, :nearest_topic_name, :fare_code, :longitude, :latitude, :long_lat_type, :country_code, :street_name, :zip_code, :city_name, :mobility_restricted_suitability, :stairs_availability, :lift_availability, :int_user_needs, :coordinates, :url, :time_zone )
+ params.require(:stop_area).permit( :routing_stop_ids, :routing_line_ids, :children_ids, :parent_id, :objectid, :object_version, :name, :comment, :area_type, :registration_number, :nearest_topic_name, :fare_code, :longitude, :latitude, :long_lat_type, :country_code, :street_name, :zip_code, :city_name, :mobility_restricted_suitability, :stairs_availability, :lift_availability, :int_user_needs, :coordinates, :url, :time_zone )
end
end
diff --git a/app/decorators/company_decorator.rb b/app/decorators/company_decorator.rb
index 9416c73ae..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: t('companies.actions.destroy'),
+ content: h.destroy_link_content('companies.actions.destroy'),
href: h.line_referential_company_path(
context[:referential],
object
diff --git a/app/decorators/compliance_check_set_decorator.rb b/app/decorators/compliance_check_set_decorator.rb
index 096596b19..c58e14d88 100644
--- a/app/decorators/compliance_check_set_decorator.rb
+++ b/app/decorators/compliance_check_set_decorator.rb
@@ -3,15 +3,6 @@ class ComplianceCheckSetDecorator < Draper::Decorator
def action_links
links = []
-
- links << Link.new(
- content: h.destroy_link_content,
- href: h.workbench_compliance_check_sets_path(object.id),
- method: :delete,
- data: {confirm: h.t('imports.actions.destroy_confirm')}
- )
-
- links
end
def lines_status
diff --git a/app/decorators/referential_line_decorator.rb b/app/decorators/referential_line_decorator.rb
index 55acf7ed9..654f68bf5 100644
--- a/app/decorators/referential_line_decorator.rb
+++ b/app/decorators/referential_line_decorator.rb
@@ -24,21 +24,6 @@ class ReferentialLineDecorator < Draper::Decorator
)
)
- if h.policy(Chouette::Line).create? &&
- context[:referential].organisation == context[:current_organisation]
- links << Link.new(
- content: h.t('actions.new'),
- href: h.new_referential_line_path(context[:referential])
- )
- end
-
- if h.policy(object).update?
- links << Link.new(
- content: h.t('actions.edit'),
- href: h.edit_referential_line_path(context[:referential], object)
- )
- end
-
if h.policy(object).destroy?
links << Link.new(
content: h.destroy_link_content('actions.destroy'),
diff --git a/app/decorators/stop_area_decorator.rb b/app/decorators/stop_area_decorator.rb
index 4e777292d..8b2ebf490 100644
--- a/app/decorators/stop_area_decorator.rb
+++ b/app/decorators/stop_area_decorator.rb
@@ -7,15 +7,6 @@ class StopAreaDecorator < Draper::Decorator
links = []
stop_area ||= object
- if h.policy(Chouette::StopArea).new?
- links << Link.new(
- content: h.t('stop_areas.actions.new'),
- href: h.new_stop_area_referential_stop_area_path(
- stop_area.stop_area_referential
- )
- )
- end
-
if h.policy(stop_area).update?
links << Link.new(
content: h.t('stop_areas.actions.edit'),
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} <br/> #{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} <br/> #{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/helpers/table_builder_helper.rb b/app/helpers/table_builder_helper.rb
index 37f01ce0d..de78e903d 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 )
@@ -187,86 +199,92 @@ module TableBuilderHelper
end
end
- def tbody(collection, columns, selectable, links, overhead)
- content_tag :tbody do
- collection.map do |item|
-
- content_tag :tr 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)
+ 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 column.linkable?
- path = column.link_to(item)
- link = link_to(value, path)
+ columns.each do |column|
+ value = column.value(item)
- if overhead.empty?
- bcont << content_tag(:td, link, title: 'Voir')
+ if column.linkable?
+ path = column.link_to(item)
+ link = link_to(value, path)
- else
- i = columns.index(column)
-
- 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
@@ -341,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/app/models/chouette/area_type.rb b/app/models/chouette/area_type.rb
new file mode 100644
index 000000000..f295fe7ae
--- /dev/null
+++ b/app/models/chouette/area_type.rb
@@ -0,0 +1,37 @@
+class Chouette::AreaType
+
+ ALL = %i(zdep zder zdlp zdlr lda).freeze
+
+ @@all = ALL
+ mattr_accessor :all
+
+ def self.all=(values)
+ @@all = ALL & values
+ reset_caches!
+ end
+
+ @@instances = {}
+ def self.find(code)
+ code = code.to_sym
+ @@instances[code] ||= new(code) if ALL.include? code
+ end
+
+ def self.reset_caches!
+ @@instances = {}
+ @@options = nil
+ end
+
+ def self.options
+ @@options ||= all.map { |c| find(c) }.map { |t| [ t.label, t.code ] }
+ end
+
+ attr_reader :code
+ def initialize(code)
+ @code = code
+ end
+
+ def label
+ I18n.translate code, scope: 'area_types.label'
+ end
+
+end
diff --git a/app/models/chouette/stop_area.rb b/app/models/chouette/stop_area.rb
index cc7170728..f216ce449 100644
--- a/app/models/chouette/stop_area.rb
+++ b/app/models/chouette/stop_area.rb
@@ -9,7 +9,7 @@ module Chouette
include ObjectidSupport
extend Enumerize
- enumerize :area_type, in: %i(zdep zder zdlp zdlr lda)
+ enumerize :area_type, in: Chouette::AreaType::ALL
with_options dependent: :destroy do |assoc|
assoc.has_many :stop_points
@@ -196,10 +196,12 @@ module Chouette
GeoRuby::SimpleFeatures::Envelope.from_coordinates coordinates
end
+ # DEPRECATED use StopArea#area_type
def stop_area_type
area_type ? area_type : " "
end
+ # DEPRECATED use StopArea#area_type
def stop_area_type=(stop_area_type)
self.area_type = (stop_area_type ? stop_area_type.camelcase : nil)
end
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/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..c2da8c924 100644
--- a/app/policies/calendar_policy.rb
+++ b/app/policies/calendar_policy.rb
@@ -5,18 +5,15 @@ class CalendarPolicy < ApplicationPolicy
end
end
- 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')
+ def create?
+ user.has_permission?('calendars.create')
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
+ 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/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'
diff --git a/app/views/compliance_check_sets/index.html.slim b/app/views/compliance_check_sets/index.html.slim
index f5d1bd777..f109845b4 100644
--- a/app/views/compliance_check_sets/index.html.slim
+++ b/app/views/compliance_check_sets/index.html.slim
@@ -12,7 +12,7 @@
[ \
TableBuilderHelper::Column.new( \
key: :ref, \
- attribute: 'compliance_check_set_id' \
+ attribute: 'id' \
), \
TableBuilderHelper::Column.new( \
key: :creation_date, \
@@ -41,5 +41,3 @@
.row.mt-xs
.col-lg-12
= replacement_msg t('compliance_check_sets.search_no_results')
-
-
diff --git a/app/views/dashboards/_dashboard.html.slim b/app/views/dashboards/_dashboard.html.slim
index f03301e23..7d547bf4c 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 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/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
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
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/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'
diff --git a/app/views/stop_area_referentials/show.html.slim b/app/views/stop_area_referentials/show.html.slim
index d43333fd9..911006c39 100644
--- a/app/views/stop_area_referentials/show.html.slim
+++ b/app/views/stop_area_referentials/show.html.slim
@@ -1,13 +1,14 @@
- 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
.col-lg-12.text-right
= link_to stop_area_referential_stop_areas_path(@stop_area_referential), class: 'btn btn-primary' do
= Referential.human_attribute_name(:stop_areas)
- em.small = " (#{@stop_area_referential.stop_areas.size})"
+ em.small = " (#{@stop_area_referential.stop_areas.count})"
- page_header_content_for @stop_area_referential
.page_content
diff --git a/app/views/stop_areas/_filters.html.slim b/app/views/stop_areas/_filters.html.slim
index 3b99f377c..90368dff4 100644
--- a/app/views/stop_areas/_filters.html.slim
+++ b/app/views/stop_areas/_filters.html.slim
@@ -12,7 +12,7 @@
.form-group.togglable
= f.label Chouette::StopArea.human_attribute_name(:area_type), required: false, class: 'control-label'
- = f.input :area_type_eq_any, collection: Chouette::StopArea.area_type.options.sort, as: :check_boxes, label: false, label_method: lambda{|w| ("<span>" + t("enumerize.stop_area.area_type.#{w[1]}") + "</span>").html_safe}, required: false, wrapper_html: { class: 'checkbox_list' }
+ = f.input :area_type_eq_any, collection: Chouette::AreaType.options, as: :check_boxes, label: false, label_method: lambda{|w| ("<span>" + w[0] + "</span>").html_safe}, required: false, wrapper_html: { class: 'checkbox_list' }
.actions
= link_to 'Effacer', @workbench, class: 'btn btn-link'
diff --git a/app/views/stop_areas/_form.html.slim b/app/views/stop_areas/_form.html.slim
index 20c7c0468..ac2cb4e87 100644
--- a/app/views/stop_areas/_form.html.slim
+++ b/app/views/stop_areas/_form.html.slim
@@ -6,7 +6,7 @@
/= @map.to_html
= f.input :id, as: :hidden
= f.input :name, :input_html => {:title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.stop_area.name")}
- = f.input :area_type, as: :select, :input_html => {:disabled => !@stop_area.new_record?}, :collection => Chouette::StopArea.area_type.options, :include_blank => false
+ = f.input :area_type, as: :select, :input_html => {:disabled => !@stop_area.new_record?}, :collection => Chouette::AreaType.options, :include_blank => false
.location_info
h3 = t("stop_areas.stop_area.localisation")
diff --git a/app/views/stop_areas/index.html.slim b/app/views/stop_areas/index.html.slim
index c4d880081..63e99fd75 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 \
) \
@@ -48,10 +48,10 @@
), \
TableBuilderHelper::Column.new( \
key: :area_type, \
- attribute: Proc.new { |s| (s.area_type.nil? ? '-' : t("enumerize.stop_area.area_type.#{s.try(:area_type)}")) } \
+ attribute: Proc.new { |s| Chouette::AreaType.find(s.area_type).try :label } \
), \
],
- links: [:show, :edit, :delete],
+ links: [:show],
cls: 'table has-filter has-search'
= new_pagination @stop_areas, 'pull-right'
diff --git a/app/views/stop_areas/show.html.slim b/app/views/stop_areas/show.html.slim
index af673bb25..1b1209a68 100644
--- a/app/views/stop_areas/show.html.slim
+++ b/app/views/stop_areas/show.html.slim
@@ -17,7 +17,7 @@
.col-lg-6.col-md-6.col-sm-12.col-xs-12
= definition_list t('metadatas'),
{ t('id_reflex') => @stop_area.get_objectid.short_id,
- @stop_area.human_attribute_name(:stop_area_type) => t("area_types.label.#{@stop_area.stop_area_type}"),
+ @stop_area.human_attribute_name(:stop_area_type) => Chouette::AreaType.find(@stop_area.area_type).try(:label),
@stop_area.human_attribute_name(:registration_number) => @stop_area.registration_number,
'Coordonnées' => geo_data(@stop_area, @stop_area_referential),
@stop_area.human_attribute_name(:zip_code) => @stop_area.zip_code,
diff --git a/app/views/stop_points/_stop_point.html.slim b/app/views/stop_points/_stop_point.html.slim
index ca86e339a..e54158cef 100644
--- a/app/views/stop_points/_stop_point.html.slim
+++ b/app/views/stop_points/_stop_point.html.slim
@@ -5,7 +5,7 @@
= link_to [@referential, stop_point.stop_area], class: "preview", title: "#{Chouette::StopArea.model_name.human.capitalize} #{stop_point.stop_area.name}" do
span.name
span.label.label-primary = stop_point.position + 1
- = image_tag "map/" + stop_point.stop_area.stop_area_type + ".png"
+ = image_tag "map/" + stop_point.stop_area.area_type + ".png"
= truncate(stop_point.stop_area.name, length: 20)
.panel-body
@@ -27,4 +27,4 @@
= t(".no_object")
- else
- stop_point.stop_area.lines.each do |line|
- span.label.label-default.line = line.number || truncate( line.name, length: 4 ) \ No newline at end of file
+ span.label.label-default.line = line.number || truncate( line.name, length: 4 )
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/app/workers/referential_cloning_worker.rb b/app/workers/referential_cloning_worker.rb
index 6592160ec..e20148055 100644
--- a/app/workers/referential_cloning_worker.rb
+++ b/app/workers/referential_cloning_worker.rb
@@ -1,32 +1,7 @@
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
+ ReferentialCloning.find(id).clone!
end
end
diff --git a/config/deploy.rb b/config/deploy.rb
index a8d44d3e5..33771507f 100644
--- a/config/deploy.rb
+++ b/config/deploy.rb
@@ -90,6 +90,6 @@ namespace :deploy do
desc "Run db:seed"
task :seed do
- run "cd #{current_path} && #{bundle_cmd} exec /var/lib/gems/2.2.0/bin/rake db:seed RAILS_ENV=#{rails_env}"
+ run "cd #{current_path} && #{rake} db:seed RAILS_ENV=#{rails_env}"
end
end
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
diff --git a/config/locales/compliance_check_sets.fr.yml b/config/locales/compliance_check_sets.fr.yml
index 8f1c066e7..8c4561ae9 100644
--- a/config/locales/compliance_check_sets.fr.yml
+++ b/config/locales/compliance_check_sets.fr.yml
@@ -10,7 +10,7 @@ fr:
name_compliance_control_set: Indiquez le nom d'un jeu de contrôle
error_period_filter: La date de fin doit être supérieure ou égale à la date de début0
index:
- title: "Liste des jeux de contrôles"
+ title: "Liste des rapports de contrôles"
search_no_results: Aucun rapport de contrôle ne correspond à votre recherche
executed:
title: Jeu de contrôles exécutés %{name}
@@ -24,7 +24,7 @@ fr:
activerecord:
attributes:
compliance_check_set:
- ref: réf
+ ref: Ref
creation_date: Date et heure de création
associated_object: Objet associé
assigned_to: Affectation
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/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"
diff --git a/config/locales/referentials.en.yml b/config/locales/referentials.en.yml
index 8420e9539..f41e35446 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,8 @@ 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"
unarchived: "The data space has been successfully unarchived"
diff --git a/config/locales/referentials.fr.yml b/config/locales/referentials.fr.yml
index ec7ed776d..9250a033c 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,8 @@ 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é"
unarchived: "Le jeu de données a été correctement déconservé"
diff --git a/config/locales/stop_areas.en.yml b/config/locales/stop_areas.en.yml
index 324294892..54a5ebae5 100644
--- a/config/locales/stop_areas.en.yml
+++ b/config/locales/stop_areas.en.yml
@@ -15,7 +15,7 @@ en:
actions:
new: "Add a new stop"
edit: "Edit this stop"
- destroy: "Remove this stop"
+ destroy: "Remove"
deleted_at: "Activated"
destroy_confirm: "Are you sure you want destroy this stop and all of his children ?"
select_parent: "Create or modify the relation child -> parent"
diff --git a/config/locales/stop_areas.fr.yml b/config/locales/stop_areas.fr.yml
index bf4dd832f..f96a2e564 100644
--- a/config/locales/stop_areas.fr.yml
+++ b/config/locales/stop_areas.fr.yml
@@ -15,7 +15,7 @@ fr:
actions:
new: "Ajouter un arrêt"
edit: "Editer cet arrêt"
- destroy: "Supprimer cet arrêt"
+ destroy: "Supprimer"
deleted_at: "Activé"
destroy_confirm: "Etes vous sûr de supprimer cet arrêt ainsi que tous ses fils?"
select_parent: "Créer ou éditer la relation enfant -> parent"
diff --git a/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
diff --git a/lib/stif/permission_translator.rb b/lib/stif/permission_translator.rb
index 2d267bc7b..4acf42884 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/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
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
diff --git a/spec/controllers/line_referentials_controller_spec.rb b/spec/controllers/line_referentials_controller_spec.rb
index aee24b0fa..17ffb670d 100644
--- a/spec/controllers/line_referentials_controller_spec.rb
+++ b/spec/controllers/line_referentials_controller_spec.rb
@@ -1,3 +1,19 @@
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 'should redirect to 403' do
+ expect(request).to redirect_to "/403"
+ end
+
+ 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/referentials_controller_spec.rb b/spec/controllers/referentials_controller_spec.rb
index fba063085..4050a8812 100644
--- a/spec/controllers/referentials_controller_spec.rb
+++ b/spec/controllers/referentials_controller_spec.rb
@@ -30,4 +30,33 @@ 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
+
+ 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
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/factories/chouette_stop_areas.rb b/spec/factories/chouette_stop_areas.rb
index 8b64c227b..7f937e361 100644
--- a/spec/factories/chouette_stop_areas.rb
+++ b/spec/factories/chouette_stop_areas.rb
@@ -3,7 +3,7 @@ FactoryGirl.define do
sequence(:objectid) { |n| "FR:#{n}:ZDE:#{n}:STIF" }
sequence(:name) { |n| "stop_area_#{n}" }
sequence(:registration_number) { |n| "test-#{n}" }
- area_type { Chouette::StopArea.area_type.values.sample }
+ area_type { Chouette::AreaType.all.sample }
latitude {10.0 * rand}
longitude {10.0 * rand}
diff --git a/spec/features/compliance_check_sets_spec.rb b/spec/features/compliance_check_sets_spec.rb
index 7ba64b6b8..6b7d7a4f8 100644
--- a/spec/features/compliance_check_sets_spec.rb
+++ b/spec/features/compliance_check_sets_spec.rb
@@ -29,7 +29,7 @@ RSpec.describe "ComplianceCheckSets", type: :feature do
it 'we can see the expected content' do
# Breadcrumbs
- expect_breadcrumb_links "Accueil", "Gestion de l'offre", "Liste des jeux de contrôles"
+ expect_breadcrumb_links "Accueil", "Gestion de l'offre", "Liste des rapports de contrôles"
# Headline
expect( page ).to have_content("Jeu de contrôles exécutés #{compliance_check_set.name}")
@@ -49,10 +49,10 @@ RSpec.describe "ComplianceCheckSets", type: :feature do
# Direct Children
within(:xpath, xpath_for_div_of_block) do
direct_checks.each do | direct_check |
- expect( page ).to have_content( direct_check.code )
- expect( page ).to have_content( direct_check.name )
- expect( page ).to have_content( direct_check.criticity )
- expect( page ).to have_content( direct_check.comment )
+ expect( page ).to have_content( direct_check.code )
+ expect( page ).to have_content( direct_check.name )
+ expect( page ).to have_content( direct_check.criticity )
+ expect( page ).to have_content( direct_check.comment )
end
end
@@ -60,10 +60,10 @@ RSpec.describe "ComplianceCheckSets", type: :feature do
compliance_check_set.compliance_check_blocks.each do | block |
within(:xpath, xpath_for_div_of_block(block)) do
block.compliance_checks.each do | check |
- expect( page ).to have_content( check.code )
- expect( page ).to have_content( check.name )
- expect( page ).to have_content( check.criticity )
- expect( page ).to have_content( check.comment )
+ expect( page ).to have_content( check.code )
+ expect( page ).to have_content( check.name )
+ expect( page ).to have_content( check.criticity )
+ expect( page ).to have_content( check.comment )
end
end
end
@@ -86,7 +86,7 @@ RSpec.describe "ComplianceCheckSets", type: :feature do
all_checks.each do | check |
expect( page ).to have_content(check.code)
end
-
+
end
end
diff --git a/spec/helpers/table_builder_helper_spec.rb b/spec/helpers/table_builder_helper_spec.rb
index 3b0a18379..83b746d4b 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
</tr>
</thead>
<tbody>
- <tr>
+ <tr class="referential-#{referential.id}">
<td>
<div class="checkbox"><input type="checkbox" name="#{referential.id}" id="#{referential.id}" value="#{referential.id}" /><label for="#{referential.id}"></label></div>
</td>
@@ -213,7 +213,7 @@ describe TableBuilderHelper, type: :helper do
</tr>
</thead>
<tbody>
- <tr>
+ <tr class="company-#{company.id}">
<td>#{company.get_objectid.local_id}</td>
<td title="Voir"><a href="/referentials/#{referential.id}/companies/#{company.id}">#{company.name}</a></td>
<td></td>
@@ -326,7 +326,7 @@ describe TableBuilderHelper, type: :helper do
</tr>
</thead>
<tbody>
- <tr>
+ <tr class="company-#{company.id}">
<td>#{company.get_objectid.local_id}</td>
<td title="Voir"><a href="/referentials/#{referential.id}/companies/#{company.id}">#{company.name}</a></td>
<td></td>
@@ -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/lib/stif/permission_translator_spec.rb b/spec/lib/stif/permission_translator_spec.rb
index ae1a2d1d5..9771af187 100644
--- a/spec/lib/stif/permission_translator_spec.rb
+++ b/spec/lib/stif/permission_translator_spec.rb
@@ -1,3 +1,4 @@
+# coding: utf-8
RSpec.describe Stif::PermissionTranslator do
context "No SSO Permissions" do
@@ -42,4 +43,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 STIF 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 STIF permission" do
+ expect(described_class.translate([], organisation).sort).to eq permissions
+ end
+ end
+ end
end
diff --git a/spec/models/chouette/area_type_spec.rb b/spec/models/chouette/area_type_spec.rb
new file mode 100644
index 000000000..470e3a066
--- /dev/null
+++ b/spec/models/chouette/area_type_spec.rb
@@ -0,0 +1,32 @@
+require "rails_helper"
+
+RSpec.describe Chouette::AreaType do
+
+ describe "::ALL" do
+ it "includes all supported types" do
+ expect(Chouette::AreaType::ALL).to match_array( %i(zdep zder zdlp zdlr lda) )
+ end
+ end
+
+ describe ".find" do
+ it "returns nil if the given code is unknown" do
+ expect(Chouette::AreaType.find('dummy')).to be_nil
+ end
+
+ it "returns an AreaType associated to the code" do
+ expect(Chouette::AreaType.find('zdep').code).to eq :zdep
+ end
+ end
+
+ describe ".options" do
+ before do
+ Chouette::AreaType.reset_caches!
+ end
+
+ it "returns an array with label and code for each type" do
+ allow(Chouette::AreaType).to receive(:all).and_return(%i{zdep lda})
+ expect(Chouette::AreaType.options).to eq([["ZDEp", :zdep], ["LDA", :lda]])
+ end
+ end
+
+end
diff --git a/spec/models/referential_cloning_spec.rb b/spec/models/referential_cloning_spec.rb
index 5acd433ec..4327c98aa 100644
--- a/spec/models/referential_cloning_spec.rb
+++ b/spec/models/referential_cloning_spec.rb
@@ -1,6 +1,7 @@
require 'spec_helper'
RSpec.describe ReferentialCloning, :type => :model do
+
it 'should have a valid factory' do
expect(FactoryGirl.build(:referential_cloning)).to be_valid
end
@@ -8,11 +9,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/policies/calendar_policy_spec.rb b/spec/policies/calendar_policy_spec.rb
index 294be8198..a881d0e80 100644
--- a/spec/policies/calendar_policy_spec.rb
+++ b/spec/policies/calendar_policy_spec.rb
@@ -5,18 +5,24 @@ RSpec.describe CalendarPolicy, type: :policy do
permissions :create? do
- it_behaves_like 'permitted policy', 'calendars.create', archived: true
+ it_behaves_like 'permitted policy', 'calendars.create'
+ end
+ permissions :share? do
+ it_behaves_like 'permitted policy and same organisation', 'calendars.share'
+ 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
+ it_behaves_like 'permitted policy and same organisation', 'calendars.destroy'
end
permissions :edit? do
- it_behaves_like 'permitted policy and same organisation', 'calendars.update', archived: true
+ it_behaves_like 'permitted policy and same organisation', 'calendars.update'
end
permissions :new? do
- it_behaves_like 'permitted policy', 'calendars.create', archived: true
+ it_behaves_like 'permitted policy', 'calendars.create'
end
permissions :update? do
- it_behaves_like 'permitted policy and same organisation', 'calendars.update', archived: true
+ it_behaves_like 'permitted policy and same organisation', 'calendars.update'
end
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/support/integration_spec_helper.rb b/spec/support/integration_spec_helper.rb
new file mode 100644
index 000000000..78efb9027
--- /dev/null
+++ b/spec/support/integration_spec_helper.rb
@@ -0,0 +1,49 @@
+module IntegrationSpecHelper
+
+ 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
+
+ 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.include 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/support/pundit/pundit_view_policy.rb b/spec/support/pundit/pundit_view_policy.rb
index b8434cac0..91be0624c 100644
--- a/spec/support/pundit/pundit_view_policy.rb
+++ b/spec/support/pundit/pundit_view_policy.rb
@@ -1,16 +1,16 @@
module Pundit
module PunditViewPolicy
- extend ActiveSupport::Concern
+ 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 }
- included do
- 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(:policy) do |instance|
+ ::Pundit.policy pundit_user, instance
end
end
end
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
deleted file mode 100644
index c04a4f3f1..000000000
--- a/spec/views/connection_links/show.html.erb_spec.rb
+++ /dev/null
@@ -1,35 +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 => '<div id="map"/>'.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
-
-# 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)}']")
- 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']")
- 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 => '<div id="map"/>'.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/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
diff --git a/spec/views/offer_workbenches/show.html.erb_spec.rb b/spec/views/offer_workbenches/show.html.erb_spec.rb
index 40b09268a..138a1560d 100644
--- a/spec/views/offer_workbenches/show.html.erb_spec.rb
+++ b/spec/views/offer_workbenches/show.html.erb_spec.rb
@@ -1,5 +1,56 @@
-require 'rails_helper'
+require 'spec_helper'
-RSpec.describe "workbenches/show.html.erb", :type => :view do
+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) {
+ 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) }) }
+
+ 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
+ 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
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 2dfae1bfd..000000000
--- a/spec/views/stop_areas/index.html.erb_spec.rb
+++ /dev/null
@@ -1,25 +0,0 @@
-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!(:q) { assign :q, Ransack::Search.new(Chouette::StopArea) }
-
- before :each do
- allow(view).to receive(:link_with_search).and_return("#")
- 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
-
-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..8daa5eb4b
--- /dev/null
+++ b/spec/views/stop_areas/index.html.slim_spec.rb
@@ -0,0 +1,34 @@
+require 'spec_helper'
+
+describe "/stop_areas/index", :type => :view do
+
+ let!(:stop_area_referential) { assign :stop_area_referential, create(:stop_area_referential) }
+ let!(:stop_areas) do
+ assign :stop_areas, build_paginated_collection(:stop_area, StopAreaDecorator, stop_area_referential: stop_area_referential)
+ end
+ let!(:q) { assign :q, Ransack::Search.new(Chouette::StopArea) }
+
+ before :each do
+ 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_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_item(stop_areas, "show", -> (stop_area){ view.stop_area_referential_stop_area_path(stop_area_referential, stop_area) }) }
+ it { should_not have_link_for_each_item(stop_areas, "create", -> (stop_area){ view.new_stop_area_referential_stop_area_path(stop_area_referential) }) }
+ it { should have_the_right_number_of_links(stop_areas, 1) }
+ end
+
+ with_permission "stop_areas.update" do
+ it { should have_link_for_each_item(stop_areas, "show", -> (stop_area){ view.stop_area_referential_stop_area_path(stop_area_referential, stop_area) }) }
+ 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
+
+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