diff options
178 files changed, 1566 insertions, 599 deletions
diff --git a/.gitignore b/.gitignore index acdb5e230..dd4d057ef 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,8 @@ /tmp *~ public/assets/ +public/javascripts/i18n.js +public/javascripts/translations.js # for vim users *.swp @@ -16,7 +16,7 @@ gem 'uglifier', '~> 2.7.2' gem 'coffee-rails', '~> 4.0.0' # Webpacker -gem 'webpacker', '3.0.2' +gem 'webpacker', '3.2.1' # Use jquery as the JavaScript library gem 'jquery-rails', '~> 3.1.4' # Update to v4 for Rails 4.2 @@ -103,6 +103,7 @@ gem 'will_paginate-bootstrap' gem 'gretel' gem 'country_select' gem 'flag-icons-rails' +gem 'i18n-js' # Format Output gem 'json' @@ -176,6 +177,7 @@ group :test do gem 'simplecov-rcov', :require => false gem 'htmlbeautifier' gem 'timecop' + gem 'rspec-snapshot' end group :test, :development, :dev do diff --git a/Gemfile.lock b/Gemfile.lock index 805ee460d..046167e69 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -269,8 +269,10 @@ GEM htmlbeautifier (1.3.1) httparty (0.14.0) multi_xml (>= 0.5.2) - i18n (0.9.3) + i18n (0.9.4) concurrent-ruby (~> 1.0) + i18n-js (3.0.4) + i18n (~> 0.6, >= 0.6.6) i18n-tasks (0.9.15) activesupport (>= 4.0.2) ast (>= 2.1.0) @@ -318,7 +320,7 @@ GEM mime-types-data (3.2016.0521) mimemagic (0.3.2) mini_portile2 (2.3.0) - minitest (5.11.2) + minitest (5.11.3) money (6.10.1) i18n (>= 0.6.4, < 1.0) multi_json (1.12.1) @@ -447,6 +449,10 @@ GEM roo (2.7.1) nokogiri (~> 1) rubyzip (~> 1.1, < 2.0.0) + rspec (3.5.0) + rspec-core (~> 3.5.0) + rspec-expectations (~> 3.5.0) + rspec-mocks (~> 3.5.0) rspec-core (3.5.4) rspec-support (~> 3.5.0) rspec-expectations (3.5.0) @@ -463,6 +469,8 @@ GEM rspec-expectations (~> 3.5.0) rspec-mocks (~> 3.5.0) rspec-support (~> 3.5.0) + rspec-snapshot (0.1.1) + rspec (> 3.0.0) rspec-support (3.5.0) ruby-filemagic (0.7.2) ruby-graphviz (1.2.3) @@ -553,7 +561,7 @@ GEM json (>= 1.8, < 3.0) parser (>= 2.3.0.7) rainbow (>= 1.99.1, < 3.0) - tzinfo (1.2.4) + tzinfo (1.2.5) thread_safe (~> 0.1) uglifier (2.7.2) execjs (>= 0.3.0) @@ -566,7 +574,7 @@ GEM addressable (>= 2.3.6) crack (>= 0.3.2) hashdiff - webpacker (3.0.2) + webpacker (3.2.1) activesupport (>= 4.2) rack-proxy (>= 0.6.1) railties (>= 4.2) @@ -638,6 +646,7 @@ DEPENDENCIES gretel has_array_of! htmlbeautifier + i18n-js i18n-tasks inherited_resources jbuilder (~> 2.0) @@ -681,6 +690,7 @@ DEPENDENCIES rgeo (~> 0.5.2) roo rspec-rails (~> 3.5.0) + rspec-snapshot rubyzip sass-rails (~> 4.0.3) sawyer (~> 0.6.0) @@ -703,7 +713,7 @@ DEPENDENCIES transpec uglifier (~> 2.7.2) webmock - webpacker (= 3.0.2) + webpacker (= 3.2.1) whenever! will_paginate will_paginate-bootstrap diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js index 4c5aff22f..6a79f7e8e 100644 --- a/app/assets/javascripts/application.js +++ b/app/assets/javascripts/application.js @@ -22,3 +22,6 @@ //= require_directory . // require('whatwg-fetch') // require('babel-polyfill') +//= require "i18n" +//= require "i18n/extended" +//= require "i18n/translations" diff --git a/app/assets/javascripts/i18n/extended.coffee b/app/assets/javascripts/i18n/extended.coffee new file mode 100644 index 000000000..aeb67bd09 --- /dev/null +++ b/app/assets/javascripts/i18n/extended.coffee @@ -0,0 +1,24 @@ +#= require i18n + +decorateI18n = (_i18n)-> + _i18n.tc = (key, opts={}) -> + out = _i18n.t(key, opts) + out += " " if _i18n.locale == "fr" + out + ":" + + _i18n.model_name = (model, opts={}) -> + last_key = if opts.plural then "other" else "one" + _i18n.t("activerecord.models.#{model}.#{last_key}") + + _i18n.attribute_name = (model, attribute, opts={}) -> + _i18n.t("activerecord.attributes.#{model}.#{attribute}") + + _i18n.enumerize = (enumerize, key, opts={}) -> + I18n.t("enumerize.#{enumerize}.#{key}") + + _i18n + +module?.exports = decorateI18n + +if I18n? + decorateI18n(I18n) diff --git a/app/assets/stylesheets/components/_tables.sass b/app/assets/stylesheets/components/_tables.sass index 35e1122f3..1e02ad586 100644 --- a/app/assets/stylesheets/components/_tables.sass +++ b/app/assets/stylesheets/components/_tables.sass @@ -9,7 +9,6 @@ font-weight: 700 border-bottom: 2px solid $darkgrey vertical-align: middle - > a position: relative display: block @@ -326,6 +325,26 @@ padding: 6px 8px border-bottom: 2px solid rgba($grey, 0.5) border-top: 1px solid rgba($grey, 0.5) + text-transform: capitalize + + .info-button + position: absolute + width: 20px + height: 20px + top: 0 + right: 0 + margin: 6px 8px + button + border: none + background: $blue + border-radius: 20px + width: 100% + height: 100% + font-size: 12px + line-height: 14px + color: white + outline: none + .td position: relative padding: 6px 8px diff --git a/app/controllers/autocomplete_stop_areas_controller.rb b/app/controllers/autocomplete_stop_areas_controller.rb index d82fa316a..79154a6e0 100644 --- a/app/controllers/autocomplete_stop_areas_controller.rb +++ b/app/controllers/autocomplete_stop_areas_controller.rb @@ -21,7 +21,7 @@ class AutocompleteStopAreasController < ChouetteController scope = StopAreaPolicy::Scope.new(current_user, scope).search_scope(search_scope) end args = [].tap{|arg| 4.times{arg << "%#{params[:q]}%"}} - @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 = scope.where("unaccent(stop_areas.name) ILIKE unaccent(?) OR unaccent(stop_areas.city_name) ILIKE unaccent(?) OR stop_areas.registration_number ILIKE ? OR stop_areas.objectid ILIKE ?", *args).limit(50) @stop_areas end diff --git a/app/controllers/calendars_controller.rb b/app/controllers/calendars_controller.rb index 5cc7912b7..75d4cbd09 100644 --- a/app/controllers/calendars_controller.rb +++ b/app/controllers/calendars_controller.rb @@ -8,14 +8,21 @@ class CalendarsController < ChouetteController respond_to :json, only: :show respond_to :js, only: :index + belongs_to :workgroup + def index index! do - @calendars = CalendarDecorator.decorate(@calendars) + @calendars = decorate_calendars(@calendars) end end def show - @year = params[:year] ? params[:year].to_i : Date.today.cwyear + show! do + @year = params[:year] ? params[:year].to_i : Date.today.cwyear + @calendar = @calendar.decorate(context: { + workgroup: workgroup + }) + end end def month @@ -45,6 +52,16 @@ class CalendarsController < ChouetteController end private + + def decorate_calendars(calendars) + CalendarDecorator.decorate( + calendars, + context: { + workgroup: workgroup + } + ) + end + def calendar_params permitted_params = [:id, :name, :short_name, :shared, periods_attributes: [:id, :begin, :end, :_destroy], date_values_attributes: [:id, :value, :_destroy]] permitted_params << :shared if policy(Calendar).share? @@ -60,25 +77,30 @@ class CalendarsController < ChouetteController end protected + + alias_method :workgroup, :parent + helper_method :workgroup + def resource - @calendar = Calendar.where('organisation_id = ? OR shared = true', current_organisation.id).find_by_id(params[:id]).decorate + @calendar ||= workgroup.calendars.where('(organisation_id = ? OR shared = ?)', current_organisation.id, true).find_by_id(params[:id]) end def build_resource super.tap do |calendar| + calendar.workgroup = workgroup calendar.organisation = current_organisation end end def collection - return @calendars if @calendars - scope = Calendar.where('organisation_id = ? OR shared = ?', current_organisation.id, true) - scope = shared_scope(scope) - @q = scope.ransack(params[:q]) - - calendars = @q.result - calendars = calendars.order(sort_column + ' ' + sort_direction) if sort_column && sort_direction - @calendars = calendars.paginate(page: params[:page]) + @calendars ||= begin + scope = workgroup.calendars.where('(organisation_id = ? OR shared = ?)', current_organisation.id, true) + scope = shared_scope(scope) + @q = scope.ransack(params[:q]) + calendars = @q.result + calendars = calendars.order(sort_column + ' ' + sort_direction) if sort_column && sort_direction + calendars = calendars.paginate(page: params[:page]) + end end def ransack_contains_date @@ -103,4 +125,4 @@ class CalendarsController < ChouetteController scope end -end +end
\ No newline at end of file diff --git a/app/controllers/compliance_control_sets_controller.rb b/app/controllers/compliance_control_sets_controller.rb index ae1d01feb..8f9251155 100644 --- a/app/controllers/compliance_control_sets_controller.rb +++ b/app/controllers/compliance_control_sets_controller.rb @@ -7,10 +7,8 @@ class ComplianceControlSetsController < ChouetteController def index index! do |format| - scope = self.ransack_period_range(scope: @compliance_control_sets, error_message: t('imports.filters.error_period_filter'), query: :where_updated_at_between) - @q_for_form = scope.ransack(params[:q]) format.html { - @compliance_control_sets = decorate_compliance_control_sets(@q_for_form.result.paginate(page: params[:page], per_page: 30)) + @compliance_control_sets = decorate_compliance_control_sets(@compliance_control_sets) } end end @@ -37,6 +35,14 @@ class ComplianceControlSetsController < ChouetteController private + def collection + scope = self.ransack_period_range(scope: ComplianceControlSet.all, error_message: t('imports.filters.error_period_filter'), query: :where_updated_at_between) + @q_for_form = scope.ransack(params[:q]) + compliance_control_sets = @q_for_form.result + compliance_control_sets = joins_with_associated_objects(compliance_control_sets).order(sort_column + ' ' + sort_direction) if sort_column && sort_direction + @compliance_control_sets = compliance_control_sets.paginate(page: params[:page], per_page: 30) + end + def decorate_compliance_control_sets(compliance_control_sets) ComplianceControlSetDecorator.decorate(compliance_control_sets) end @@ -58,4 +64,32 @@ class ComplianceControlSetsController < ChouetteController @direct_compliance_controls = compliance_controls.delete nil @blocks_to_compliance_controls_map = compliance_controls end + + def sort_column + case params[:sort] + when 'name' then 'lower(compliance_control_sets.name)' + when 'owner_jdc' then 'lower(organisations.name)' + when 'control_numbers' then 'COUNT(compliance_controls.id)' + else + ComplianceControlSet.column_names.include?(params[:sort]) ? params[:sort] : 'lower(compliance_control_sets.name)' + end + end + + def joins_with_associated_objects(collection) + + # dont know if this is the right way to do it but since we need to join table deoending of the params + # it was to avoid loading associated objects if we don't need them + case params[:sort] + when 'owner_jdc' + collection.joins("LEFT JOIN organisations ON compliance_control_sets.organisation_id = organisations.id") + when 'control_numbers' + collection.joins("LEFT JOIN compliance_controls ON compliance_controls.compliance_control_set_id = compliance_control_sets.id").group(:id) + else + collection + end + end + + def sort_direction + %w[asc desc].include?(params[:direction]) ? params[:direction] : 'asc' + end end diff --git a/app/controllers/snapshots_controller.rb b/app/controllers/snapshots_controller.rb new file mode 100644 index 000000000..e453b4965 --- /dev/null +++ b/app/controllers/snapshots_controller.rb @@ -0,0 +1,14 @@ +class SnapshotsController < ApplicationController + if Rails.env.development? || Rails.env.test? + layout :which_layout + def show + tpl = params[:snap] + tpl = tpl.gsub Rails.root.to_s, '' + render file: tpl + end + + def which_layout + "snapshots/#{params[:layout] || "default"}" + end + end +end diff --git a/app/controllers/statuses_controller.rb b/app/controllers/statuses_controller.rb new file mode 100644 index 000000000..e38a92982 --- /dev/null +++ b/app/controllers/statuses_controller.rb @@ -0,0 +1,20 @@ +class StatusesController < ChouetteController + respond_to :json + + def index + + status = { + referentials_blocked: Referential.blocked.count, + imports_blocked: Import.blocked.count, + compliance_check_sets_blocked: ComplianceCheckSet.blocked.count + } + status[:status] = global_status status + render json: status.to_json + end + + private + + def global_status status + status.values.all?(&:zero?) ? 'ok' : 'ko' + end +end diff --git a/app/decorators/calendar_decorator.rb b/app/decorators/calendar_decorator.rb index be1f9e3bf..4c6088e8e 100644 --- a/app/decorators/calendar_decorator.rb +++ b/app/decorators/calendar_decorator.rb @@ -1,6 +1,6 @@ class CalendarDecorator < AF83::Decorator decorates Calendar - + set_scope { context[:workgroup] } create_action_link with_instance_decorator do |instance_decorator| diff --git a/app/decorators/company_decorator.rb b/app/decorators/company_decorator.rb index aadce68bb..5580e0d4a 100644 --- a/app/decorators/company_decorator.rb +++ b/app/decorators/company_decorator.rb @@ -1,34 +1,21 @@ class CompanyDecorator < AF83::Decorator decorates Chouette::Company + set_scope { context[:referential] } + create_action_link do |l| l.content { h.t('companies.actions.new') } - l.href { [:new, context[:referential], :company] } end with_instance_decorator do |instance_decorator| - instance_decorator.show_action_link do |l| - l.href { [context[:referential], object] } - end + instance_decorator.show_action_link instance_decorator.edit_action_link do |l| l.content {|l| l.action == "show" ? h.t('actions.edit') : h.t('companies.actions.edit') } - l.href { - h.edit_line_referential_company_path( - context[:referential], - object - ) - } end instance_decorator.destroy_action_link do |l| l.content { h.destroy_link_content('companies.actions.destroy') } - l.href { - h.edit_line_referential_company_path( - context[:referential], - object - ) - } l.data {{ confirm: h.t('companies.actions.destroy_confirm') }} end end diff --git a/app/decorators/compliance_control_decorator.rb b/app/decorators/compliance_control_decorator.rb index c57a7ccc7..fd2dbd9ce 100644 --- a/app/decorators/compliance_control_decorator.rb +++ b/app/decorators/compliance_control_decorator.rb @@ -1,6 +1,8 @@ class ComplianceControlDecorator < AF83::Decorator decorates ComplianceControl + set_scope { object.compliance_control_set } + with_instance_decorator do |instance_decorator| instance_decorator.show_action_link do |l| l.content h.t('compliance_control_sets.actions.show') @@ -12,23 +14,9 @@ class ComplianceControlDecorator < AF83::Decorator end end - instance_decorator.edit_action_link do |l| - l.href do - h.edit_compliance_control_set_compliance_control_path( - object.compliance_control_set_id, - object.id - ) - end - end + instance_decorator.edit_action_link instance_decorator.destroy_action_link do |l| - l.content h.destroy_link_content - l.href do - h.compliance_control_set_compliance_control_path( - object.compliance_control_set.id, - object.id - ) - end l.data confirm: h.t('compliance_controls.actions.destroy_confirm') end end diff --git a/app/decorators/compliance_control_set_decorator.rb b/app/decorators/compliance_control_set_decorator.rb index 387822c67..b16a06886 100644 --- a/app/decorators/compliance_control_set_decorator.rb +++ b/app/decorators/compliance_control_set_decorator.rb @@ -6,6 +6,8 @@ class ComplianceControlSetDecorator < AF83::Decorator end with_instance_decorator do |instance_decorator| + instance_decorator.show_action_link + instance_decorator.edit_action_link do |l| l.content t('compliance_control_sets.actions.edit') end diff --git a/app/decorators/import_decorator.rb b/app/decorators/import_decorator.rb index c6b1f2349..1964365ae 100644 --- a/app/decorators/import_decorator.rb +++ b/app/decorators/import_decorator.rb @@ -1,6 +1,8 @@ class ImportDecorator < AF83::Decorator decorates Import + set_scope { context[:workbench] } + define_instance_method :import_status_css_class do cls ='' cls = 'overheaded-success' if object.status == 'successful' @@ -11,13 +13,10 @@ class ImportDecorator < AF83::Decorator create_action_link do |l| l.content t('imports.actions.new') - l.href { h.new_workbench_import_path(workbench_id: context[:workbench]) } end with_instance_decorator do |instance_decorator| - instance_decorator.show_action_link do |l| - l.href { h.workbench_import_path(context[:workbench], object) } - end + instance_decorator.show_action_link instance_decorator.action_link secondary: :show do |l| l.content t('imports.actions.download') diff --git a/app/decorators/line_decorator.rb b/app/decorators/line_decorator.rb index adeb89f70..0e7b6b9ae 100644 --- a/app/decorators/line_decorator.rb +++ b/app/decorators/line_decorator.rb @@ -1,9 +1,10 @@ class LineDecorator < AF83::Decorator decorates Chouette::Line + set_scope { context[:line_referential] } + create_action_link do |l| l.content t('lines.actions.new') - l.href { h.new_line_referential_line_path(context[:line_referential]) } end with_instance_decorator do |instance_decorator| @@ -14,18 +15,17 @@ class LineDecorator < AF83::Decorator instance_decorator.show_action_link do |l| l.content t('lines.actions.show') - l.href { [context[:line_referential], object] } end instance_decorator.action_link secondary: :show do |l| l.content t('lines.actions.show_network') - l.href { [context[:line_referential], object.network] } + l.href { [scope, object.network] } l.disabled { object.network.nil? } end instance_decorator.action_link secondary: :show do |l| l.content t('lines.actions.show_company') - l.href { [context[:line_referential], object.company] } + l.href { [scope, object.company] } l.disabled { object.company.nil? } end @@ -34,7 +34,6 @@ class LineDecorator < AF83::Decorator instance_decorator.with_condition can_edit_line do edit_action_link do |l| l.content {|l| l.primary? ? h.t('actions.edit') : h.t('lines.actions.edit') } - l.href { h.edit_line_referential_line_path(context[:line_referential], object.id) } end action_link on: :index, secondary: :index do |l| @@ -64,7 +63,6 @@ class LineDecorator < AF83::Decorator instance_decorator.destroy_action_link do |l| l.content { h.destroy_link_content('lines.actions.destroy') } - l.href { h.line_referential_line_path(context[:line_referential], object) } l.data confirm: h.t('lines.actions.destroy_confirm') l.add_class "delete-action" end diff --git a/app/decorators/network_decorator.rb b/app/decorators/network_decorator.rb index 90f0d0e82..ea0f73dc2 100644 --- a/app/decorators/network_decorator.rb +++ b/app/decorators/network_decorator.rb @@ -1,6 +1,7 @@ class NetworkDecorator < AF83::Decorator decorates Chouette::Network + set_scope { context[:line_referential] } # Action links require: # context: { # line_referential: , @@ -8,15 +9,10 @@ class NetworkDecorator < AF83::Decorator create_action_link do |l| l.content t('networks.actions.new') - l.href { h.new_line_referential_network_path(context[:line_referential]) } end with_instance_decorator do |instance_decorator| - instance_decorator.show_action_link do |l| - l.href do - h.line_referential_network_path(context[:line_referential], object) - end - end + instance_decorator.show_action_link instance_decorator.action_link secondary: true, policy: :edit do |l| l.content t('networks.actions.edit') @@ -30,12 +26,6 @@ class NetworkDecorator < AF83::Decorator instance_decorator.destroy_action_link do |l| l.content h.destroy_link_content('networks.actions.destroy') - l.href do - h.line_referential_network_path( - context[:line_referential], - object - ) - end l.data confirm: h.t('networks.actions.destroy_confirm') end end diff --git a/app/decorators/purchase_window_decorator.rb b/app/decorators/purchase_window_decorator.rb index 54b241173..9b58577b2 100644 --- a/app/decorators/purchase_window_decorator.rb +++ b/app/decorators/purchase_window_decorator.rb @@ -1,32 +1,20 @@ class PurchaseWindowDecorator < AF83::Decorator decorates Chouette::PurchaseWindow + set_scope { context[:referential] } + create_action_link do |l| l.content t('purchase_windows.actions.new') - l.href { h.new_referential_purchase_window_path(context[:referential]) } end with_instance_decorator do |instance_decorator| instance_decorator.show_action_link do |l| l.content t('purchase_windows.actions.show') - l.href do - h.referential_purchase_window_path( - context[:referential], - object - ) - end end - instance_decorator.edit_action_link do |l| - l.href do - h.edit_referential_purchase_window_path(context[:referential].id, object) - end - end + instance_decorator.edit_action_link instance_decorator.destroy_action_link do |l| - l.href do - h.referential_purchase_window_path(context[:referential].id, object) - end l.data confirm: h.t('purchase_windows.actions.destroy_confirm') end end diff --git a/app/decorators/referential_line_decorator.rb b/app/decorators/referential_line_decorator.rb index 8f884a8e0..3ac846d76 100644 --- a/app/decorators/referential_line_decorator.rb +++ b/app/decorators/referential_line_decorator.rb @@ -1,6 +1,8 @@ class ReferentialLineDecorator < AF83::Decorator decorates Chouette::Line + set_scope { context[:referential] } + # Action links require: # context: { # referential: , @@ -8,9 +10,7 @@ class ReferentialLineDecorator < AF83::Decorator # } with_instance_decorator do |instance_decorator| - instance_decorator.show_action_link do |l| - l.href { h.referential_line_path(context[:referential], object) } - end + instance_decorator.show_action_link instance_decorator.action_link secondary: true do |l| l.content Chouette::Line.human_attribute_name(:footnotes) @@ -21,7 +21,7 @@ class ReferentialLineDecorator < AF83::Decorator l.content h.t('routing_constraint_zones.index.title') l.href do h.referential_line_routing_constraint_zones_path( - context[:referential], + scope, object ) end @@ -37,7 +37,7 @@ class ReferentialLineDecorator < AF83::Decorator secondary: true ) do |l| l.content h.t('routes.actions.new') - l.href { h.new_referential_line_route_path(context[:referential], object) } + l.href { h.new_referential_line_route_path(scope, object) } end end end diff --git a/app/decorators/referential_network_decorator.rb b/app/decorators/referential_network_decorator.rb index ff3467188..c508452c0 100644 --- a/app/decorators/referential_network_decorator.rb +++ b/app/decorators/referential_network_decorator.rb @@ -1,6 +1,8 @@ class ReferentialNetworkDecorator < AF83::Decorator decorates Chouette::Network + set_scope { context[:referential] } + # Action links require: # context: { # referential: , @@ -8,33 +10,18 @@ class ReferentialNetworkDecorator < AF83::Decorator create_action_link do |l| l.content t('networks.actions.new') - l.href { h.new_referential_network_path(context[:referential]) } end with_instance_decorator do |instance_decorator| - instance_decorator.show_action_link do |l| - l.href { h.referential_network_path(context[:referential], object) } - end + instance_decorator.show_action_link instance_decorator.edit_action_link do |l| l.content t('networks.actions.edit') - l.href do - h.edit_referential_network_path( - context[:referential], - object - ) - end end instance_decorator.destroy_action_link do |l| l.content h.destroy_link_content('networks.actions.destroy') - l.href do - h.referential_network_path( - context[:referential], - object - ) - end l.data confirm: h.t('networks.actions.destroy_confirm') end end -end
\ No newline at end of file +end diff --git a/app/decorators/route_decorator.rb b/app/decorators/route_decorator.rb index f9870fbbe..fa6367924 100644 --- a/app/decorators/route_decorator.rb +++ b/app/decorators/route_decorator.rb @@ -7,26 +7,12 @@ class RouteDecorator < AF83::Decorator # line: # } + set_scope { [context[:referential], context[:line]] } + with_instance_decorator do |instance_decorator| - instance_decorator.show_action_link do |l| - l.href do - h.referential_line_route_path( - context[:referential], - context[:line], - object - ) - end - end + instance_decorator.show_action_link - instance_decorator.edit_action_link do |l| - l.href do - h.edit_referential_line_route_path( - context[:referential], - context[:line], - object - ) - end - end + instance_decorator.edit_action_link instance_decorator.action_link( if: ->() { object.stop_points.any? }, @@ -86,13 +72,6 @@ class RouteDecorator < AF83::Decorator end instance_decorator.destroy_action_link do |l| - l.href do - h.referential_line_route_path( - context[:referential], - context[:line], - object - ) - end l.data confirm: h.t('routes.actions.destroy_confirm') end end diff --git a/app/decorators/routing_constraint_zone_decorator.rb b/app/decorators/routing_constraint_zone_decorator.rb index 962625fa7..de73068be 100644 --- a/app/decorators/routing_constraint_zone_decorator.rb +++ b/app/decorators/routing_constraint_zone_decorator.rb @@ -1,6 +1,8 @@ class RoutingConstraintZoneDecorator < AF83::Decorator decorates Chouette::RoutingConstraintZone + set_scope { [context[:referential], context[:line]] } + # Action links require: # context: { # referential: , @@ -12,44 +14,13 @@ class RoutingConstraintZoneDecorator < AF83::Decorator h.policy(Chouette::RoutingConstraintZone).create? && context[:referential].organisation == h.current_organisation } - ) do |l| - l.href do - h.new_referential_line_routing_constraint_zone_path( - context[:referential], - context[:line] - ) - end - end + ) with_instance_decorator do |instance_decorator| - instance_decorator.show_action_link do |l| - l.href do - h.referential_line_routing_constraint_zone_path( - context[:referential], - context[:line], - object - ) - end - end - - instance_decorator.edit_action_link do |l| - l.href do - h.edit_referential_line_routing_constraint_zone_path( - context[:referential], - context[:line], - object - ) - end - end + instance_decorator.show_action_link + instance_decorator.edit_action_link instance_decorator.destroy_action_link do |l| - l.href do - h.referential_line_routing_constraint_zone_path( - context[:referential], - context[:line], - object - ) - end l.data confirm: h.t('routing_constraint_zones.actions.destroy_confirm') end end diff --git a/app/decorators/stop_area_decorator.rb b/app/decorators/stop_area_decorator.rb index 2e57da0e4..525681971 100644 --- a/app/decorators/stop_area_decorator.rb +++ b/app/decorators/stop_area_decorator.rb @@ -7,23 +7,11 @@ class StopAreaDecorator < AF83::Decorator end with_instance_decorator do |instance_decorator| - instance_decorator.show_action_link do |l| - l.href do - h.stop_area_referential_stop_area_path( - object.stop_area_referential, - object - ) - end - end + set_scope { object.stop_area_referential } + instance_decorator.show_action_link instance_decorator.edit_action_link do |l| l.content h.t('stop_areas.actions.edit') - l.href do - h.edit_stop_area_referential_stop_area_path( - object.stop_area_referential, - object - ) - end end instance_decorator.action_link policy: :deactivate, secondary: true do |l| @@ -54,12 +42,6 @@ class StopAreaDecorator < AF83::Decorator instance_decorator.destroy_action_link do |l| l.content h.destroy_link_content('stop_areas.actions.destroy') - l.href do - h.stop_area_referential_stop_area_path( - object.stop_area_referential, - object - ) - end l.data confirm: h.t('stop_areas.actions.destroy_confirm') end end diff --git a/app/decorators/time_table_decorator.rb b/app/decorators/time_table_decorator.rb index 95b1fd959..e4f9d7dbc 100644 --- a/app/decorators/time_table_decorator.rb +++ b/app/decorators/time_table_decorator.rb @@ -14,7 +14,7 @@ class TimeTableDecorator < AF83::Decorator l.href { [:edit, context[:referential], object] } end - instance_decorator.action_link if: ->{ object.calendar }, secondary: true do |l| + instance_decorator.action_link policy: :actualize, if: ->{ object.calendar }, secondary: true do |l| l.content t('actions.actualize') l.href do h.actualize_referential_time_table_path( diff --git a/app/helpers/table_builder_helper.rb b/app/helpers/table_builder_helper.rb index 9a255e757..2068dd23c 100644 --- a/app/helpers/table_builder_helper.rb +++ b/app/helpers/table_builder_helper.rb @@ -330,7 +330,7 @@ module TableBuilderHelper else menu = content_tag :ul, class: 'dropdown-menu' do ( - CustomLinks.new(item, pundit_user, links, referential).links + + CustomLinks.new(item, pundit_user, links, referential, workgroup).links + action_links.select { |link| link.is_a?(Link) } ).map do |link| gear_menu_link(link) @@ -395,7 +395,6 @@ module TableBuilderHelper klass << link.extra_class if link.extra_class klass << 'delete-action' if link.method == :delete klass << 'disabled' if link.disabled - content_tag( :li, link_to( @@ -414,4 +413,10 @@ module TableBuilderHelper # cases, avoid a `NoMethodError`. @__referential__ ||= try(:current_referential) end + + def workgroup + # Certain controllers don't define a `#current_referential`. In these + # cases, avoid a `NoMethodError`. + @__workgroup__ ||= try(:current_workgroup) + end end diff --git a/app/helpers/table_builder_helper/custom_links.rb b/app/helpers/table_builder_helper/custom_links.rb index b1bb11f10..e09078be0 100644 --- a/app/helpers/table_builder_helper/custom_links.rb +++ b/app/helpers/table_builder_helper/custom_links.rb @@ -8,13 +8,14 @@ module TableBuilderHelper unarchive: :put } - attr_reader :actions, :object, :user_context, :referential + attr_reader :actions, :object, :user_context, :referential, :workgroup - def initialize(object, user_context, actions, referential = nil) + def initialize(object, user_context, actions, referential = nil, workgroup = nil) @object = object @user_context = user_context @actions = actions @referential = referential + @workgroup = workgroup end def links @@ -34,7 +35,7 @@ module TableBuilderHelper polymorph_url << action end - polymorph_url += URL.polymorphic_url_parts(object, referential) + polymorph_url += URL.polymorphic_url_parts(object, referential, workgroup) end def method_for_action(action) diff --git a/app/helpers/table_builder_helper/url.rb b/app/helpers/table_builder_helper/url.rb index 28f1ade76..0e3dce0aa 100644 --- a/app/helpers/table_builder_helper/url.rb +++ b/app/helpers/table_builder_helper/url.rb @@ -1,6 +1,6 @@ module TableBuilderHelper class URL - def self.polymorphic_url_parts(item, referential) + def self.polymorphic_url_parts(item, referential, workgroup) polymorph_url = [] unless item.is_a?(Calendar) || item.is_a?(Referential) || item.is_a?(ComplianceControlSet) @@ -20,6 +20,7 @@ module TableBuilderHelper end end else + polymorph_url << item.workgroup if item.respond_to? :workgroup polymorph_url << item end diff --git a/app/javascript/routes/components/BSelect2.js b/app/javascript/routes/components/BSelect2.js index 158deaa17..035bce155 100644 --- a/app/javascript/routes/components/BSelect2.js +++ b/app/javascript/routes/components/BSelect2.js @@ -85,7 +85,7 @@ class BSelect2 extends Component{ onSelect={ this.props.onSelect } ref='newSelect' options={{ - placeholder: this.context.I18n.routes.edit.select2.placeholder, + placeholder: this.context.I18n.t("routes.edit.select2.placeholder"), allowClear: true, language: 'fr', /* Doesn't seem to work... :( */ theme: 'bootstrap', diff --git a/app/javascript/routes/components/OlMap.js b/app/javascript/routes/components/OlMap.js index 056bddbcb..4beb02872 100644 --- a/app/javascript/routes/components/OlMap.js +++ b/app/javascript/routes/components/OlMap.js @@ -115,40 +115,40 @@ export default class OlMap extends Component{ <strong>{this.props.value.olMap.json.name}</strong> </p> <p> - <strong>{this.context.I18n.routes.edit.stop_point_type} : </strong> + <strong>{this.context.I18n.t('routes.edit.map.stop_point_type')} : </strong> {this.props.value.olMap.json.area_type} </p> <p> - <strong>{this.context.I18n.routes.edit.short_name} : </strong> + <strong>{this.context.I18n.t('routes.edit.map.short_name')} : </strong> {this.props.value.olMap.json.short_name} </p> <p> - <strong>{this.context.I18n.id_reflex} : </strong> + <strong>{this.context.I18n.t('id_reflex')} : </strong> {this.props.value.olMap.json.user_objectid} </p> - <p><strong>{this.context.I18n.routes.edit.map.coordinates} : </strong></p> + <p><strong>{this.context.I18n.t('routes.edit.map.coordinates')} : </strong></p> <p style={{paddingLeft: 10, marginTop: 0}}> - <em>{this.context.I18n.routes.edit.map.proj}.: </em>WSG84<br/> - <em>{this.context.I18n.routes.edit.map.lat}.: </em>{this.props.value.olMap.json.latitude} <br/> - <em>{this.context.I18n.routes.edit.map.lon}.: </em>{this.props.value.olMap.json.longitude} + <em>{this.context.I18n.t('routes.edit.map.proj')}.: </em>WSG84<br/> + <em>{this.context.I18n.t('routes.edit.map.lat')}.: </em>{this.props.value.olMap.json.latitude} <br/> + <em>{this.context.I18n.t('routes.edit.map.lon')}.: </em>{this.props.value.olMap.json.longitude} </p> <p> - <strong>{this.context.I18n.routes.edit.map.postal_code} : </strong> + <strong>{this.context.I18n.t('routes.edit.map.postal_code')} : </strong> {this.props.value.olMap.json.zip_code} </p> <p> - <strong>{this.context.I18n.routes.edit.map.city} : </strong> + <strong>{this.context.I18n.t('routes.edit.map.city')} : </strong> {this.props.value.olMap.json.city_name} </p> <p> - <strong>{this.context.I18n.routes.edit.map.comment} : </strong> + <strong>{this.context.I18n.t('routes.edit.map.comment')} : </strong> {this.props.value.olMap.json.comment} </p> {(this.props.value.stoparea_id != this.props.value.olMap.json.stoparea_id) &&( <div className='btn btn-outline-primary btn-sm' onClick= {() => {this.props.onUpdateViaOlMap(this.props.index, this.props.value.olMap.json)}} - >{this.context.I18n.actions.select}</div> + >{this.context.I18n.t('actions.select')}</div> )} </div> <div className='map_content'> @@ -162,7 +162,7 @@ export default class OlMap extends Component{ } } -OlMap.PropTypes = { +OlMap.propTypes = { } OlMap.contextTypes = { diff --git a/app/javascript/routes/components/StopPoint.js b/app/javascript/routes/components/StopPoint.js index 2d47e802b..af51a6bb4 100644 --- a/app/javascript/routes/components/StopPoint.js +++ b/app/javascript/routes/components/StopPoint.js @@ -18,15 +18,15 @@ export default function StopPoint(props, {I18n}) { <div> <select className='form-control' value={props.value.for_boarding} id="for_boarding" onChange={props.onSelectChange}> - <option value="normal">{I18n.routes.edit.stop_point.boarding.normal}</option> - <option value="forbidden">{I18n.routes.edit.stop_point.boarding.forbidden}</option> + <option value="normal">{I18n.t('routes.edit.stop_point.boarding.normal')}</option> + <option value="forbidden">{I18n.t('routes.edit.stop_point.boarding.forbidden')}</option> </select> </div> <div> <select className='form-control' value={props.value.for_alighting} id="for_alighting" onChange={props.onSelectChange}> - <option value="normal">{I18n.routes.edit.stop_point.alighting.normal}</option> - <option value="forbidden">{I18n.routes.edit.stop_point.alighting.forbidden}</option> + <option value="normal">{I18n.t('routes.edit.stop_point.alighting.normal')}</option> + <option value="forbidden">{I18n.t('routes.edit.stop_point.alighting.forbidden')}</option> </select> </div> @@ -77,7 +77,7 @@ export default function StopPoint(props, {I18n}) { ) } -StopPoint.PropTypes = { +StopPoint.propTypes = { onToggleMap: PropTypes.func.isRequired, onToggleEdit: PropTypes.func.isRequired, onDeleteClick: PropTypes.func.isRequired, @@ -93,4 +93,4 @@ StopPoint.PropTypes = { StopPoint.contextTypes = { I18n: PropTypes.object -}
\ No newline at end of file +} diff --git a/app/javascript/routes/components/StopPointList.js b/app/javascript/routes/components/StopPointList.js index b39fa0c9c..b227abdea 100644 --- a/app/javascript/routes/components/StopPointList.js +++ b/app/javascript/routes/components/StopPointList.js @@ -10,22 +10,22 @@ export default function StopPointList({ stopPoints, onDeleteClick, onMoveUpClick <div className="wrapper"> <div style={{width: 100}}> <div className="form-group"> - <label className="control-label">{I18n.reflex_id}</label> + <label className="control-label">{I18n.t('simple_form.labels.stop_point.reflex_id')}</label> </div> </div> <div> <div className="form-group"> - <label className="control-label">{I18n.simple_form.labels.stop_point.name}</label> + <label className="control-label">{I18n.t('simple_form.labels.stop_point.name')}</label> </div> </div> <div> <div className="form-group"> - <label className="control-label">{I18n.simple_form.labels.stop_point.for_boarding}</label> + <label className="control-label">{I18n.t('simple_form.labels.stop_point.for_boarding')}</label> </div> </div> <div> <div className="form-group"> - <label className="control-label">{I18n.simple_form.labels.stop_point.for_alighting}</label> + <label className="control-label">{I18n.t('simple_form.labels.stop_point.for_alighting')}</label> </div> </div> <div className='actions-5'></div> diff --git a/app/javascript/time_tables/actions/index.js b/app/javascript/time_tables/actions/index.js index 4a36ec4e1..98b9eab4b 100644 --- a/app/javascript/time_tables/actions/index.js +++ b/app/javascript/time_tables/actions/index.js @@ -8,7 +8,7 @@ const I18n = clone(window, "I18n") const actions = { weekDays: (index) => { - return range(1, 8).map(n => I18n.time_tables.edit.metas.days[n]) + return range(1, 8).map(n => I18n.t('time_tables.edit.metas.days')[n]) }, strToArrayDayTypes: (str) =>{ return actions.weekDays().map(day => str.indexOf(day) !== -1) @@ -155,7 +155,7 @@ const actions = { type : 'CLOSE_MODAL' }), monthName(strDate) { - let monthList = range(1,13).map(n => I18n.calendars.months[n]) + let monthList = range(1,13).map(n => I18n.t('calendars.months.'+ n )) let date = new Date(strDate) return monthList[date.getUTCMonth()] }, @@ -225,7 +225,7 @@ const actions = { let period = periods[i] if (index !== i && !period.deleted) { if (new Date(period.period_start) <= end && new Date(period.period_end) >= start) { - error = I18n.time_tables.edit.error_submit.periods_overlaps + error = I18n.t('time_tables.edit.error_submit.periods_overlaps') break } } @@ -239,7 +239,7 @@ const actions = { for (let day of in_days) { if (start <= new Date(day.date) && end >= new Date(day.date)) { - error = I18n.time_tables.edit.error_submit.dates_overlaps + error = I18n.t('time_tables.edit.error_submit.dates_overlaps') break } } @@ -316,9 +316,9 @@ const actions = { errorModalMessage: (errorKey) => { switch (errorKey) { case "withoutPeriodsWithDaysTypes": - return I18n.time_tables.edit.error_modal.withoutPeriodsWithDaysTypes + return I18n.t('time_tables.edit.error_modal.withoutPeriodsWithDaysTypes') case "withPeriodsWithoutDayTypes": - return I18n.time_tables.edit.error_modal.withPeriodsWithoutDayTypes + return I18n.t('time_tables.edit.error_modal.withPeriodsWithoutDayTypes') default: return errorKey diff --git a/app/javascript/time_tables/components/ConfirmModal.js b/app/javascript/time_tables/components/ConfirmModal.js index 845e7ed1b..4e8583bc0 100644 --- a/app/javascript/time_tables/components/ConfirmModal.js +++ b/app/javascript/time_tables/components/ConfirmModal.js @@ -9,11 +9,11 @@ export default function ConfirmModal({dispatch, modal, onModalAccept, onModalCan <div className='modal-dialog'> <div className='modal-content'> <div className='modal-header'> - <h4 className='modal-title'>{I18n.time_tables.edit.confirm_modal.title}</h4> + <h4 className='modal-title'>{I18n.t('time_tables.edit.confirm_modal.title')}</h4> </div> <div className='modal-body'> <div className='mt-md mb-md'> - <p>{I18n.time_tables.edit.confirm_modal.message}</p> + <p>{I18n.t('time_tables.edit.confirm_modal.message')}</p> </div> </div> <div className='modal-footer'> @@ -23,7 +23,7 @@ export default function ConfirmModal({dispatch, modal, onModalAccept, onModalCan type='button' onClick={() => { onModalCancel(modal.confirmModal.callback) }} > - {I18n.cancel} + {I18n.t('cancel')} </button> <button className='btn btn-primary' @@ -31,7 +31,7 @@ export default function ConfirmModal({dispatch, modal, onModalAccept, onModalCan type='button' onClick={() => { onModalAccept(modal.confirmModal.callback, timetable, metas) }} > - {I18n.actions.submit} + {I18n.t('actions.submit')} </button> </div> </div> @@ -49,4 +49,4 @@ ConfirmModal.propTypes = { ConfirmModal.contextTypes = { I18n: PropTypes.object -}
\ No newline at end of file +} diff --git a/app/javascript/time_tables/components/ErrorModal.js b/app/javascript/time_tables/components/ErrorModal.js index 543177e54..8af12f1d1 100644 --- a/app/javascript/time_tables/components/ErrorModal.js +++ b/app/javascript/time_tables/components/ErrorModal.js @@ -10,7 +10,7 @@ export default function ErrorModal({dispatch, modal, onModalClose}, {I18n}) { <div className='modal-dialog'> <div className='modal-content'> <div className='modal-header'> - <h4 className='modal-title'>{I18n.time_tables.edit.error_modal.title}</h4> + <h4 className='modal-title'>{I18n.t('time_tables.edit.error_modal.title')}</h4> </div> <div className='modal-body'> <div className='mt-md mb-md'> @@ -24,7 +24,7 @@ export default function ErrorModal({dispatch, modal, onModalClose}, {I18n}) { type='button' onClick={() => { onModalClose() }} > - {I18n.back} + {I18n.t('back')} </button> </div> </div> @@ -41,4 +41,4 @@ ErrorModal.propTypes = { ErrorModal.contextTypes = { I18n: PropTypes.object -}
\ No newline at end of file +} diff --git a/app/javascript/time_tables/components/Metas.js b/app/javascript/time_tables/components/Metas.js index 3c6848d27..08a6e26fe 100644 --- a/app/javascript/time_tables/components/Metas.js +++ b/app/javascript/time_tables/components/Metas.js @@ -13,7 +13,7 @@ export default function Metas({metas, onUpdateDayTypes, onUpdateComment, onUpdat {/* comment (name) */} <div className="form-group"> <label htmlFor="" className="control-label col-sm-4 required"> - {I18n.time_tables.edit.metas.name} <abbr title="">*</abbr> + {I18n.t('time_tables.edit.metas.name')} <abbr title="">*</abbr> </label> <div className="col-sm-8"> <input @@ -28,7 +28,7 @@ export default function Metas({metas, onUpdateDayTypes, onUpdateComment, onUpdat {/* color */} {metas.color !== undefined && <div className="form-group"> - <label htmlFor="" className="control-label col-sm-4">{I18n.activerecord.attributes.time_table.color}</label> + <label htmlFor="" className="control-label col-sm-4">{I18n.attribute_name('time_table', 'color')}</label> <div className="col-sm-8"> <div className="dropdown color_selector"> <button @@ -73,7 +73,7 @@ export default function Metas({metas, onUpdateDayTypes, onUpdateComment, onUpdat {/* tags */} {metas.tags !== undefined && <div className="form-group"> - <label htmlFor="" className="control-label col-sm-4">{I18n.activerecord.attributes.time_table.tag_list}</label> + <label htmlFor="" className="control-label col-sm-4">{I18n.attribute_name('time_table', 'tag_list')}</label> <div className="col-sm-8"> <TagsSelect2 initialTags={metas.initial_tags} @@ -86,16 +86,16 @@ export default function Metas({metas, onUpdateDayTypes, onUpdateComment, onUpdat {/* calendar */} {metas.calendar !== null && <div className="form-group"> - <label htmlFor="" className="control-label col-sm-4">{I18n.activerecord.attributes.time_table.calendar}</label> + <label htmlFor="" className="control-label col-sm-4">{I18n.attribute_name('time_table', 'calendar')}</label> <div className="col-sm-8"> - <span>{metas.calendar ? metas.calendar.name : I18n.time_tables.edit.metas.no_calendar}</span> + <span>{metas.calendar ? metas.calendar.name : I18n.t('time_tables.edit.metas.no_calendar')}</span> </div> </div>} {/* day_types */} <div className="form-group"> <label htmlFor="" className="control-label col-sm-4"> - {I18n.time_tables.edit.metas.day_types} + {I18n.t('time_tables.edit.metas.day_types')} </label> <div className="col-sm-8"> <div className="form-group labelled-checkbox-group"> diff --git a/app/javascript/time_tables/components/PeriodForm.js b/app/javascript/time_tables/components/PeriodForm.js index 085654a88..d17a246f7 100644 --- a/app/javascript/time_tables/components/PeriodForm.js +++ b/app/javascript/time_tables/components/PeriodForm.js @@ -46,7 +46,7 @@ export default function PeriodForm({modal, timetable, metas, onOpenAddPeriodForm <div> <div className="form-group"> <label htmlFor="" className="control-label required"> - {I18n.time_tables.edit.period_form.begin} + {I18n.t('time_tables.edit.period_form.begin')} <abbr title="requis">*</abbr> </label> </div> @@ -54,7 +54,7 @@ export default function PeriodForm({modal, timetable, metas, onOpenAddPeriodForm <div> <div className="form-group"> <label htmlFor="" className="control-label required"> - {I18n.time_tables.edit.period_form.end} + {I18n.t('time_tables.edit.period_form.end')} <abbr title="requis">*</abbr> </label> </div> @@ -105,14 +105,14 @@ export default function PeriodForm({modal, timetable, metas, onOpenAddPeriodForm className='btn btn-link' onClick={onClosePeriodForm} > - {I18n.cancel} + {I18n.t('cancel')} </button> <button type='button' className='btn btn-outline-primary mr-sm' onClick={() => onValidatePeriodForm(modal.modalProps, timetable.time_table_periods, metas, filter(timetable.time_table_dates, ['in_out', true]))} > - {I18n.actions.submit} + {I18n.t('actions.submit')} </button> </div> </div> @@ -124,7 +124,7 @@ export default function PeriodForm({modal, timetable, metas, onOpenAddPeriodForm className='btn btn-outline-primary' onClick={onOpenAddPeriodForm} > - {I18n.time_tables.actions.add_period} + {I18n.t('time_tables.actions.add_period')} </button> </div> } @@ -132,7 +132,7 @@ export default function PeriodForm({modal, timetable, metas, onOpenAddPeriodForm </div> </div> </div> - ) + ) } PeriodForm.propTypes = { @@ -147,4 +147,4 @@ PeriodForm.propTypes = { PeriodForm.contextTypes = { I18n: PropTypes.object -}
\ No newline at end of file +} diff --git a/app/javascript/time_tables/components/TagsSelect2.js b/app/javascript/time_tables/components/TagsSelect2.js index dc3739d58..43cf59fdf 100644 --- a/app/javascript/time_tables/components/TagsSelect2.js +++ b/app/javascript/time_tables/components/TagsSelect2.js @@ -40,7 +40,7 @@ export default class TagsSelect2 extends Component { allowClear: true, theme: 'bootstrap', width: '100%', - placeholder: this.context.I18n.time_tables.edit.select2.tag.placeholder, + placeholder: this.context.I18n.t('time_tables.edit.select2.tag.placeholder'), ajax: { url: origin + path + '/tags.json', dataType: 'json', diff --git a/app/javascript/time_tables/components/Timetable.js b/app/javascript/time_tables/components/Timetable.js index c44f2a134..991f31435 100644 --- a/app/javascript/time_tables/components/Timetable.js +++ b/app/javascript/time_tables/components/Timetable.js @@ -31,11 +31,11 @@ export default class Timetable extends Component { <div className="table table-2entries mb-sm"> <div className="t2e-head w20"> <div className="th"> - <div className="strong">{this.context.I18n.time_tables.synthesis}</div> + <div className="strong">{this.context.I18n.t('time_tables.edit.synthesis')}</div> </div> - <div className="td"><span>{this.context.I18n.time_tables.edit.day_types}</span></div> - <div className="td"><span>{this.context.I18n.time_tables.edit.periods}</span></div> - <div className="td"><span>{this.context.I18n.time_tables.edit.exceptions}</span></div> + <div className="td"><span>{this.context.I18n.t('time_tables.edit.day_types')}</span></div> + <div className="td"><span>{this.context.I18n.t('time_tables.edit.periods')}</span></div> + <div className="td"><span>{this.context.I18n.t('time_tables.edit.exceptions')}</span></div> </div> <div className="t2e-item-list w80"> <div> diff --git a/app/javascript/vehicle_journeys/components/ConfirmModal.js b/app/javascript/vehicle_journeys/components/ConfirmModal.js index 3bfc852fb..75e8a3932 100644 --- a/app/javascript/vehicle_journeys/components/ConfirmModal.js +++ b/app/javascript/vehicle_journeys/components/ConfirmModal.js @@ -7,7 +7,7 @@ export default function ConfirmModal({dispatch, modal, onModalAccept, onModalCan <div className='modal-dialog'> <div className='modal-content'> <div className='modal-body'> - <p> Voulez-vous valider vos modifications avant de changer de page? </p> + <p> {I18n.t('vehicle_journeys.vehicle_journeys_matrix.modal_confirm')} </p> </div> <div className='modal-footer'> <button @@ -31,11 +31,11 @@ export default function ConfirmModal({dispatch, modal, onModalAccept, onModalCan </div> </div> ) -} +} ConfirmModal.propTypes = { vehicleJourneys: PropTypes.array.isRequired, modal: PropTypes.object.isRequired, onModalAccept: PropTypes.func.isRequired, onModalCancel: PropTypes.func.isRequired -}
\ No newline at end of file +} diff --git a/app/javascript/vehicle_journeys/components/Filters.js b/app/javascript/vehicle_journeys/components/Filters.js index 2bd912e3e..f8697c930 100644 --- a/app/javascript/vehicle_journeys/components/Filters.js +++ b/app/javascript/vehicle_journeys/components/Filters.js @@ -46,10 +46,10 @@ export default function Filters({filters, pagination, missions, onFilter, onRese <div className='ffg-row'> {/* Plage horaire */} <div className='form-group togglable'> - <label className='control-label'>Plage horaire au départ de la course</label> + <label className='control-label'>{I18n.t("vehicle_journeys.form.departure_range.label")}</label> <div className='filter_menu'> <div className='form-group time filter_menu-item'> - <label className='control-label time'>Début</label> + <label className='control-label time'>{I18n.t("vehicle_journeys.form.departure_range.start")}</label> <div className='form-inline'> <div className='input-group time'> <input @@ -73,7 +73,7 @@ export default function Filters({filters, pagination, missions, onFilter, onRese </div> </div> <div className='form-group time filter_menu-item'> - <label className='control-label time'>Fin</label> + <label className='control-label time'>{I18n.t("vehicle_journeys.form.departure_range.end")}</label> <div className='form-inline'> <div className='input-group time'> <input @@ -101,7 +101,7 @@ export default function Filters({filters, pagination, missions, onFilter, onRese {/* Switch avec/sans horaires */} <div className='form-group has_switch'> - <label className='control-label pull-left'>Afficher les courses sans horaires</label> + <label className='control-label pull-left'>{I18n.t("vehicle_journeys.form.show_journeys_without_schedule")}</label> <div className='form-group pull-left' style={{padding: 0}}> <div className='checkbox'> <label> @@ -110,8 +110,8 @@ export default function Filters({filters, pagination, missions, onFilter, onRese onChange={onToggleWithoutSchedule} checked={filters.query.withoutSchedule} ></input> - <span className='switch-label' data-checkedvalue='Non' data-uncheckedvalue='Oui'> - {filters.query.withoutSchedule ? 'Oui' : 'Non'} + <span className='switch-label' data-checkedvalue={I18n.t("no")} data-uncheckedvalue={I18n.t("yes")}> + {filters.query.withoutSchedule ? I18n.t("yes") : I18n.t("no")} </span> </label> </div> @@ -122,7 +122,7 @@ export default function Filters({filters, pagination, missions, onFilter, onRese <div className="ffg-row"> {/* Switch avec/sans calendrier */} <div className='form-group has_switch'> - <label className='control-label pull-left'>Afficher les courses avec calendrier</label> + <label className='control-label pull-left'>{I18n.t("vehicle_journeys.form.show_journeys_with_calendar")}</label> <div className='form-group pull-left' style={{padding: 0}}> <div className='checkbox'> <label> @@ -131,8 +131,8 @@ export default function Filters({filters, pagination, missions, onFilter, onRese onChange={onToggleWithoutTimeTable} checked={filters.query.withoutTimeTable} ></input> - <span className='switch-label' data-checkedvalue='Non' data-uncheckedvalue='Oui'> - {filters.query.withoutTimeTable ? 'Oui' : 'Non'} + <span className='switch-label' data-checkedvalue={I18n.t("no")} data-uncheckedvalue={I18n.t("yes")}> + {filters.query.withoutTimeTable ? I18n.t("yes") : I18n.t("no")} </span> </label> </div> diff --git a/app/javascript/vehicle_journeys/components/Navigate.js b/app/javascript/vehicle_journeys/components/Navigate.js index 0158b8392..24843babc 100644 --- a/app/javascript/vehicle_journeys/components/Navigate.js +++ b/app/javascript/vehicle_journeys/components/Navigate.js @@ -17,8 +17,7 @@ export default function Navigate({ dispatch, vehicleJourneys, pagination, status if(status.fetchSuccess == true) { return ( <div className="pagination"> - Liste des horaires {minVJ} à {maxVJ} sur {pagination.totalCount} - + {I18n.t("vehicle_journeys.vehicle_journeys_matrix.pagination", {minVJ, maxVJ, total:pagination.totalCount})} <form className='page_links' onSubmit={e => {e.preventDefault()}}> <button onClick={e => { @@ -53,4 +52,4 @@ Navigate.propTypes = { status: PropTypes.object.isRequired, pagination: PropTypes.object.isRequired, dispatch: PropTypes.func.isRequired -}
\ No newline at end of file +} diff --git a/app/javascript/vehicle_journeys/components/ToggleArrivals.js b/app/javascript/vehicle_journeys/components/ToggleArrivals.js index 9e7089be5..9a2b0097f 100644 --- a/app/javascript/vehicle_journeys/components/ToggleArrivals.js +++ b/app/javascript/vehicle_journeys/components/ToggleArrivals.js @@ -5,7 +5,7 @@ import PropTypes from 'prop-types' export default function ToggleArrivals({filters, onToggleArrivals}) { return ( <div className='has_switch form-group inline'> - <label htmlFor='toggleArrivals' className='control-label'>Afficher et éditer les horaires d'arrivée</label> + <label htmlFor='toggleArrivals' className='control-label'>{I18n.t('vehicle_journeys.form.show_arrival_time')}</label> <div className='form-group'> <div className='checkbox'> <label> diff --git a/app/javascript/vehicle_journeys/components/Tools.js b/app/javascript/vehicle_journeys/components/Tools.js index ee02e5a68..22ea44283 100644 --- a/app/javascript/vehicle_journeys/components/Tools.js +++ b/app/javascript/vehicle_journeys/components/Tools.js @@ -44,8 +44,8 @@ export default class Tools extends Component { <DeleteVehicleJourneys disabled={!this.hasPolicy("destroy") || !editMode}/> </ul> - <span className='info-msg'>{actions.getSelected(vehicleJourneys).length} course(s) sélectionnée(s)</span> - <button className='btn btn-xs btn-link pull-right' onClick={onCancelSelection}>Annuler la sélection</button> + <span className='info-msg'>{I18n.t('vehicle_journeys.vehicle_journeys_matrix.selected_journeys', {count: actions.getSelected(vehicleJourneys).length})}</span> + <button className='btn btn-xs btn-link pull-right' onClick={onCancelSelection}>{I18n.t('vehicle_journeys.vehicle_journeys_matrix.cancel_selection')}</button> </div> ) } diff --git a/app/javascript/vehicle_journeys/components/VehicleJourney.js b/app/javascript/vehicle_journeys/components/VehicleJourney.js index 99a458f50..4a9432231 100644 --- a/app/javascript/vehicle_journeys/components/VehicleJourney.js +++ b/app/javascript/vehicle_journeys/components/VehicleJourney.js @@ -23,7 +23,7 @@ export default class VehicleJourney extends Component { let ttURL = refURL + '/time_tables/' + tt.id return ( - <a href={ttURL} title='Voir le calendrier'><span className='fa fa-calendar' style={{ color: (tt.color ? tt.color : '#4B4B4B')}}></span></a> + <a href={ttURL} title={I18n.t('vehicle_journeys.vehicle_journeys_matrix.show_timetable')}><span className='fa fa-calendar' style={{ color: (tt.color ? tt.color : '#4B4B4B')}}></span></a> ) } @@ -32,7 +32,7 @@ export default class VehicleJourney extends Component { let ttURL = refURL + '/purchase_windows/' + tt.id return ( - <a href={ttURL} title='Voir le calendrier commercial'><span className='fa fa-calendar' style={{color: (tt.color ? tt.color : '')}}></span></a> + <a href={ttURL} title={I18n.t('vehicle_journeys.vehicle_journeys_matrix.show_purchase_window')}><span className='fa fa-calendar' style={{color: (tt.color ? tt.color : '')}}></span></a> ) } @@ -65,7 +65,7 @@ export default class VehicleJourney extends Component { } > <div className='strong mb-xs'>{this.props.value.short_id || '-'}</div> - <div>{this.props.value.published_journey_name && this.props.value.published_journey_name != "non renseigné" ? this.props.value.published_journey_name : '-'}</div> + <div>{this.props.value.published_journey_name && this.props.value.published_journey_name != I18n.t('undefined') ? this.props.value.published_journey_name : '-'}</div> <div>{this.props.value.journey_pattern.short_id || '-'}</div> <div>{this.props.value.company ? this.props.value.company.name : '-'}</div> <div> @@ -100,7 +100,7 @@ export default class VehicleJourney extends Component { <div key={i} className='td text-center'> <div className={'cellwrap' + (this.cityNameChecker(vj) ? ' headlined' : '')}> {this.props.filters.toggleArrivals && - <div data-headline='Arrivée à'> + <div data-headline={I18n.t("vehicle_journeys.form.arrival_at")}> <span className={((this.isDisabled(this.props.value.deletable, vj.dummy) || this.props.filters.policy['vehicle_journeys.update'] == false) ? 'disabled ' : '') + 'input-group time'}> <input type='number' @@ -131,7 +131,7 @@ export default class VehicleJourney extends Component { <span className='sb sb-chrono sb-lg text-warning' data-textinside={vj.delta}></span> } </div> - <div data-headline='Départ à'> + <div data-headline={I18n.t("vehicle_journeys.form.departure_at")}> <span className={((this.isDisabled(this.props.value.deletable, vj.dummy) || this.props.filters.policy['vehicle_journeys.update'] == false) ? 'disabled ' : '') + 'input-group time'}> <input type='number' diff --git a/app/javascript/vehicle_journeys/components/VehicleJourneys.js b/app/javascript/vehicle_journeys/components/VehicleJourneys.js index ae852b35a..01e07ee0c 100644 --- a/app/javascript/vehicle_journeys/components/VehicleJourneys.js +++ b/app/javascript/vehicle_journeys/components/VehicleJourneys.js @@ -106,14 +106,14 @@ export default class VehicleJourneys extends Component { <div className='col-lg-12'> {(this.props.status.fetchSuccess == false) && ( <div className='alert alert-danger mt-sm'> - <strong>Erreur : </strong> - la récupération des missions a rencontré un problème. Rechargez la page pour tenter de corriger le problème. + <strong>{I18n.tc("error")}</strong> + {I18n.t("vehicle_journeys.vehicle_journeys_matrix.fetching_error")} </div> )} { this.vehicleJourneysList().errors && this.vehicleJourneysList().errors.length && _.some(this.vehicleJourneysList(), 'errors') && ( <div className="alert alert-danger mt-sm"> - <strong>Erreur : </strong> + <strong>{I18n.tc("error")}</strong> {this.vehicleJourneysList().map((vj, index) => vj.errors && vj.errors.map((err, i) => { return ( @@ -129,12 +129,12 @@ export default class VehicleJourneys extends Component { <div className={'table table-2entries mt-sm mb-sm' + ((this.vehicleJourneysList().length > 0) ? '' : ' no_result')}> <div className='t2e-head w20'> <div className='th'> - <div className='strong mb-xs'>ID course</div> - <div>Nom course</div> - <div>ID mission</div> - <div>Transporteur</div> - <div>Calendriers</div> - { this.hasFeature('purchase_windows') && <div>Calendriers Commerciaux</div> } + <div className='strong mb-xs'>{I18n.attribute_name("vehicle_journey", "id")}</div> + <div>{I18n.attribute_name("vehicle_journey", "name")}</div> + <div>{I18n.attribute_name("vehicle_journey", "journey_pattern_id")}</div> + <div>{I18n.model_name("company")}</div> + <div>{I18n.model_name("time_table", "plural": true)}</div> + { this.hasFeature('purchase_windows') && <div>{I18n.model_name("purchase_window", "plural": true)}</div> } </div> {this.stopPoints().map((sp, i) =>{ return ( diff --git a/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js b/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js index f6a0e3c61..d3c01f154 100644 --- a/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js +++ b/app/javascript/vehicle_journeys/components/tools/EditVehicleJourney.js @@ -59,7 +59,7 @@ export default class EditVehicleJourney extends Component { <div className='modal-dialog'> <div className='modal-content'> <div className='modal-header'> - <h4 className='modal-title'>Informations</h4> + <h4 className='modal-title'>{I18n.t('vehicle_journeys.form.infos')}</h4> <span type="button" className="close modal-close" data-dismiss="modal">×</span> </div> @@ -69,7 +69,7 @@ export default class EditVehicleJourney extends Component { <div className='row'> <div className='col-lg-6 col-md-6 col-sm-6 col-xs-12'> <div className='form-group'> - <label className='control-label'>Nom de la course</label> + <label className='control-label'>{I18n.attribute_name('vehicle_journey', 'journey_name')}</label> <input type='text' ref='published_journey_name' @@ -82,7 +82,7 @@ export default class EditVehicleJourney extends Component { </div> <div className='col-lg-6 col-md-6 col-sm-6 col-xs-12'> <div className='form-group'> - <label className='control-label'>Mission</label> + <label className='control-label'>{I18n.attribute_name('vehicle_journey', 'journey_pattern')}</label> <input type='text' className='form-control' @@ -96,7 +96,7 @@ export default class EditVehicleJourney extends Component { <div className='row'> <div className='col-lg-6 col-md-6 col-sm-6 col-xs-12'> <div className='form-group'> - <label className='control-label'>Numéro de train</label> + <label className='control-label'>{I18n.attribute_name('vehicle_journey', 'company')}</label> <input type='text' ref='published_journey_identifier' @@ -109,7 +109,7 @@ export default class EditVehicleJourney extends Component { </div> <div className='col-lg-6 col-md-6 col-sm-6 col-xs-12'> <div className='form-group'> - <label className='control-label'>Transporteur</label> + <label className='control-label'>{I18n.attribute_name('vehicle_journey', 'company')}</label> <CompanySelect2 editModal={this.props.modal.type == "edit"} editMode={this.editMode()} @@ -124,29 +124,29 @@ export default class EditVehicleJourney extends Component { <div className='row'> <div className='col-lg-6 col-md-6 col-sm-6 col-xs-12'> <div className='form-group'> - <label className='control-label'>Mode de transport</label> + <label className='control-label'>{I18n.attribute_name('vehicle_journey', 'transport_mode')}</label> <input type='text' className='form-control' - value={window.I18n.fr.enumerize.transport_mode[this.props.modal.modalProps.vehicleJourney.transport_mode]} + value={I18n.enumerize('transport_mode', this.props.modal.modalProps.vehicleJourney.transport_mode)} disabled={true} /> </div> </div> <div className='col-lg-6 col-md-6 col-sm-6 col-xs-12'> <div className='form-group'> - <label className='control-label'>Sous mode de transport</label> + <label className='control-label'>{I18n.attribute_name('vehicle_journey', 'transport_submode')}</label> <input type='text' className='form-control' - value={window.I18n.fr.enumerize.transport_submode[this.props.modal.modalProps.vehicleJourney.transport_submode]} + value={I18n.enumerize('transport_submode', this.props.modal.modalProps.vehicleJourney.transport_submode)} disabled={true} /> </div> </div> </div> <div className='form-group'> - <label className='control-label'>Signature métier</label> + <label className='control-label'>{I18n.attribute_name('vehicle_journey', 'checksum')}</label> <input type='text' ref='checksum' diff --git a/app/javascript/vehicle_journeys/components/tools/VehicleJourneyInfoButton.js b/app/javascript/vehicle_journeys/components/tools/VehicleJourneyInfoButton.js index a63a1d701..538bbdbd6 100644 --- a/app/javascript/vehicle_journeys/components/tools/VehicleJourneyInfoButton.js +++ b/app/javascript/vehicle_journeys/components/tools/VehicleJourneyInfoButton.js @@ -10,7 +10,7 @@ export default class VehicleJourneyInfoButton extends Component { render() { return ( - <li className='st_action'> + <div className='info-button'> <button type='button' data-toggle='modal' @@ -19,7 +19,7 @@ export default class VehicleJourneyInfoButton extends Component { > <span className='fa fa-info'></span> </button> - </li> + </div> ) } } diff --git a/app/models/calendar.rb b/app/models/calendar.rb index 561a2e3f7..84b569ab4 100644 --- a/app/models/calendar.rb +++ b/app/models/calendar.rb @@ -10,8 +10,9 @@ class Calendar < ActiveRecord::Base has_paper_trail class_name: 'PublicVersion' belongs_to :organisation + belongs_to :workgroup - validates_presence_of :name, :short_name, :organisation + validates_presence_of :name, :short_name, :organisation, :workgroup validates_uniqueness_of :short_name has_many :time_tables diff --git a/app/models/compliance_check_set.rb b/app/models/compliance_check_set.rb index f4c44d26d..289fc134f 100644 --- a/app/models/compliance_check_set.rb +++ b/app/models/compliance_check_set.rb @@ -19,6 +19,20 @@ class ComplianceCheckSet < ActiveRecord::Base where('created_at BETWEEN :begin AND :end', begin: period_range.begin, end: period_range.end) end + scope :blocked, -> { where('created_at < ? AND status = ?', 4.hours.ago, 'running') } + + def self.finished_statuses + %w(successful failed warning aborted canceled) + end + + def self.abort_old + where( + 'created_at < ? AND status NOT IN (?)', + 4.hours.ago, + finished_statuses + ).update_all(status: 'aborted') + end + def notify_parent if parent # parent.child_change diff --git a/app/models/concerns/min_max_values_validation.rb b/app/models/concerns/min_max_values_validation.rb index 9b2e0d548..eff779d81 100644 --- a/app/models/concerns/min_max_values_validation.rb +++ b/app/models/concerns/min_max_values_validation.rb @@ -2,6 +2,7 @@ module MinMaxValuesValidation extend ActiveSupport::Concern included do + validates_presence_of :minimum, :maximum validate :min_max_values_validation end diff --git a/app/models/concerns/timetable_support.rb b/app/models/concerns/timetable_support.rb index d2bc99d51..5242abc33 100644 --- a/app/models/concerns/timetable_support.rb +++ b/app/models/concerns/timetable_support.rb @@ -100,6 +100,7 @@ module TimetableSupport period.period_start = Date.parse(item['period_start']) period.period_end = Date.parse(item['period_end']) + period.save if period.is_a?(ActiveRecord::Base) && period.changed? item['id'] = period.id diff --git a/app/models/import.rb b/app/models/import.rb index 049a65f40..29aadcd56 100644 --- a/app/models/import.rb +++ b/app/models/import.rb @@ -13,6 +13,8 @@ class Import < ActiveRecord::Base where('started_at BETWEEN :begin AND :end', begin: period_range.begin, end: period_range.end) end + scope :blocked, -> { where('created_at < ? AND status = ?', 4.hours.ago, 'running') } + extend Enumerize enumerize :status, in: %w(new pending successful warning failed running aborted canceled), scope: true, default: :new @@ -42,6 +44,14 @@ class Import < ActiveRecord::Base %w(successful failed warning aborted canceled) end + def self.abort_old + where( + 'created_at < ? AND status NOT IN (?)', + 4.hours.ago, + finished_statuses + ).update_all(status: 'aborted') + end + def notify_parent parent.child_change update(notified_parent_at: DateTime.now) diff --git a/app/models/referential.rb b/app/models/referential.rb index baaa354da..509e0412f 100644 --- a/app/models/referential.rb +++ b/app/models/referential.rb @@ -62,6 +62,7 @@ class Referential < ActiveRecord::Base scope :order_by_validity_period, ->(dir) { joins(:metadatas).order("unnest(periodes) #{dir}") } scope :order_by_lines, ->(dir) { joins(:metadatas).group("referentials.id").order("sum(array_length(referential_metadata.line_ids,1)) #{dir}") } scope :not_in_referential_suite, -> { where referential_suite_id: nil } + scope :blocked, -> { where('ready = ? AND created_at < ?', false, 4.hours.ago) } def save_with_table_lock_timeout(options = {}) save_without_table_lock_timeout(options) @@ -153,10 +154,6 @@ class Referential < ActiveRecord::Base end end - def stop_areas - Chouette::StopArea.all - end - def access_points Chouette::AccessPoint.all end diff --git a/app/models/vehicle_journey_control/delta.rb b/app/models/vehicle_journey_control/delta.rb index f061b9fdd..737b7d78c 100644 --- a/app/models/vehicle_journey_control/delta.rb +++ b/app/models/vehicle_journey_control/delta.rb @@ -4,6 +4,7 @@ module VehicleJourneyControl store_accessor :control_attributes, :maximum validates_numericality_of :maximum, allow_nil: true, greater_than_or_equal_to: 0 + validates_presence_of :maximum def self.default_code; "3-VehicleJourney-3" end end diff --git a/app/models/vehicle_journey_control/waiting_time.rb b/app/models/vehicle_journey_control/waiting_time.rb index f2666cb72..89a18a5d9 100644 --- a/app/models/vehicle_journey_control/waiting_time.rb +++ b/app/models/vehicle_journey_control/waiting_time.rb @@ -3,6 +3,7 @@ module VehicleJourneyControl store_accessor :control_attributes, :maximum validates_numericality_of :maximum, allow_nil: true, greater_than_or_equal_to: 0 + validates_presence_of :maximum def self.default_code; "3-VehicleJourney-1" end end diff --git a/app/models/workgroup.rb b/app/models/workgroup.rb index 3d761e81f..3af20ae23 100644 --- a/app/models/workgroup.rb +++ b/app/models/workgroup.rb @@ -3,6 +3,7 @@ class Workgroup < ActiveRecord::Base belongs_to :stop_area_referential has_many :workbenches + has_many :calendars has_many :organisations, through: :workbenches has_many :referentials, through: :workbenches diff --git a/app/services/parent_import_notifier.rb b/app/services/parent_import_notifier.rb deleted file mode 100644 index 47e6755e4..000000000 --- a/app/services/parent_import_notifier.rb +++ /dev/null @@ -1,15 +0,0 @@ -class ParentImportNotifier - def self.notify_when_finished(imports = nil) - imports ||= imports_pending_notification - imports.each(&:notify_parent) - end - - def self.imports_pending_notification - Import - .where( - notified_parent_at: nil, - status: Import.finished_statuses - ) - .where.not(parent: nil) - end -end diff --git a/app/services/parent_notifier.rb b/app/services/parent_notifier.rb new file mode 100644 index 000000000..653c98aff --- /dev/null +++ b/app/services/parent_notifier.rb @@ -0,0 +1,19 @@ +class ParentNotifier + def initialize(klass) + @klass = klass + end + + def notify_when_finished(collection = nil) + collection ||= objects_pending_notification + collection.each(&:notify_parent) + end + + def objects_pending_notification + @klass + .where( + notified_parent_at: nil, + status: @klass.finished_statuses + ) + .where.not(parent: nil) + end +end diff --git a/app/views/calendar_mailer/created.html.slim b/app/views/calendar_mailer/created.html.slim index 37b2a86ea..bee071150 100644 --- a/app/views/calendar_mailer/created.html.slim +++ b/app/views/calendar_mailer/created.html.slim @@ -1,4 +1,4 @@ -div = t('mailers.calendar_mailer.created.body', cal_name: @calendar.name, cal_index_url: calendars_url) +div = t('mailers.calendar_mailer.created.body', cal_name: @calendar.name, cal_index_url: workgroup_calendars_url(@calendar.workgroup)) table style="border-collapse:collapse;font-family:'Open Sans', Arial, sans serif;width:550px;margin:0px auto;color:#333333;" @@ -16,7 +16,7 @@ table style="border-collapse:collapse;font-family:'Open Sans', Arial, sans serif = t('mailers.calendar_mailer.updated.subject') p style="font-size:14px;margin:0px 0px 10px 0px;" - = t('mailers.calendar_mailer.created.body', cal_name: @calendar.name, cal_index_url: calendars_url).html_safe + = t('mailers.calendar_mailer.created.body', cal_name: @calendar.name, cal_index_url: workgroup_calendars_url(@calendar.workgroup)).html_safe tr td style="text-align:center;padding:20px 0 0 0;border-top:1px solid #007fbb;" diff --git a/app/views/calendar_mailer/updated.html.slim b/app/views/calendar_mailer/updated.html.slim index bf128439a..0bdc2e7db 100644 --- a/app/views/calendar_mailer/updated.html.slim +++ b/app/views/calendar_mailer/updated.html.slim @@ -14,7 +14,7 @@ table style="border-collapse:collapse;font-family:'Open Sans', Arial, sans serif = t('mailers.calendar_mailer.updated.subject') p style="font-size:14px;margin:0px 0px 10px 0px;" - = t('mailers.calendar_mailer.updated.body', cal_name: @calendar.name, cal_index_url: calendars_url).html_safe + = t('mailers.calendar_mailer.updated.body', cal_name: @calendar.name, cal_index_url: workgroup_calendars_url(@calendar.workgroup)).html_safe tr td style="text-align:center;padding:20px 0 0 0;border-top:1px solid #007fbb;" diff --git a/app/views/calendars/_filters.html.slim b/app/views/calendars/_filters.html.slim index d9c936b64..8bfe1974e 100644 --- a/app/views/calendars/_filters.html.slim +++ b/app/views/calendars/_filters.html.slim @@ -1,4 +1,4 @@ -= search_form_for @q, url: calendars_path, builder: SimpleForm::FormBuilder, html: { method: :get, class: 'form form-filter' } do |f| += search_form_for @q, url: workgroup_calendars_path(@workgroup), builder: SimpleForm::FormBuilder, html: { method: :get, class: 'form form-filter' } do |f| .ffg-row .input-group.search_bar class=filter_item_class(params[:q], :name_or_short_name_cont) = f.search_field :name_or_short_name_cont, class: 'form-control', placeholder: 'Indiquez un nom/nom court de calendrier...' @@ -18,5 +18,5 @@ = f.input :contains_date, as: :date, label: false, wrapper_html: { class: 'date smart_date' }, class: 'form-control', include_blank: true .actions - = link_to 'Effacer', calendars_path, class: 'btn btn-link' + = link_to 'Effacer', workgroup_calendars_path(@workgroup), class: 'btn btn-link' = f.submit 'Filtrer', id: 'calendar_filter_btn', class: 'btn btn-default' diff --git a/app/views/calendars/_form_advanced.html.slim b/app/views/calendars/_form_advanced.html.slim index b4154166b..e796e2e36 100644 --- a/app/views/calendars/_form_advanced.html.slim +++ b/app/views/calendars/_form_advanced.html.slim @@ -2,7 +2,7 @@ = javascript_tag do | window.actionType = "#{raw params[:action]}"; - | window.I18n = #{(I18n.backend.send(:translations)[I18n.locale].to_json).html_safe}; + // | window.I18n = #{(I18n.backend.send(:translations)[I18n.locale].to_json).html_safe}; | window.timetablesUrl = "#{calendar_url(@calendar).html_safe}"; = javascript_pack_tag 'calendars/edit.js' diff --git a/app/views/calendars/_form_simple.html.slim b/app/views/calendars/_form_simple.html.slim index 2f469ada7..ba18c765b 100644 --- a/app/views/calendars/_form_simple.html.slim +++ b/app/views/calendars/_form_simple.html.slim @@ -1,6 +1,6 @@ .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 @calendar, html: { class: 'form-horizontal', id: 'calendar_form' }, wrapper: :horizontal_form do |f| + = simple_form_for [@workgroup, @calendar], html: { class: 'form-horizontal', id: 'calendar_form' }, wrapper: :horizontal_form do |f| .row .col-lg-12 = f.input :name diff --git a/app/views/calendars/edit.html.slim b/app/views/calendars/edit.html.slim index e64790daf..79ab1f5d0 100644 --- a/app/views/calendars/edit.html.slim +++ b/app/views/calendars/edit.html.slim @@ -1,4 +1,4 @@ -- breadcrumb :calendar, @calendar +- breadcrumb :calendar, @workgroup, @calendar - page_header_content_for @calendar .page_content .container-fluid diff --git a/app/views/calendars/index.html.slim b/app/views/calendars/index.html.slim index 92c24be5b..0b58c0c72 100644 --- a/app/views/calendars/index.html.slim +++ b/app/views/calendars/index.html.slim @@ -1,4 +1,4 @@ -- breadcrumb :calendars +- breadcrumb :calendars, workgroup .page_content .container-fluid @@ -16,7 +16,7 @@ key: :name, \ attribute: 'name', \ link_to: lambda do |calendar| \ - calendar_path(calendar) \ + workgroup_calendar_path(workgroup, calendar) \ end \ ), \ TableBuilderHelper::Column.new( \ diff --git a/app/views/calendars/new.html.slim b/app/views/calendars/new.html.slim index b3840b705..5657a0c55 100644 --- a/app/views/calendars/new.html.slim +++ b/app/views/calendars/new.html.slim @@ -1,4 +1,4 @@ -- breadcrumb :calendars +- breadcrumb :calendars, @workgroup .page_content .container-fluid = render 'form_simple' diff --git a/app/views/calendars/show.html.slim b/app/views/calendars/show.html.slim index ec53be0ef..cec4f66a5 100644 --- a/app/views/calendars/show.html.slim +++ b/app/views/calendars/show.html.slim @@ -1,4 +1,4 @@ -- breadcrumb :calendar, @calendar +- breadcrumb :calendar, @workgroup, @calendar - page_header_content_for @calendar .page_content diff --git a/app/views/compliance_check_sets/index.html.slim b/app/views/compliance_check_sets/index.html.slim index ead467174..31ad31e5b 100644 --- a/app/views/compliance_check_sets/index.html.slim +++ b/app/views/compliance_check_sets/index.html.slim @@ -23,9 +23,9 @@ ), \ TableBuilderHelper::Column.new( \ key: :associated_object, \ - attribute: Proc.new{|n| n.referential.name}, \ + attribute: Proc.new{|n| n.referential.present? ? n.referential.name : ''}, \ link_to: lambda do |compliance_check_set| \ - referential_path(compliance_check_set.referential_id) \ + compliance_check_set.referential.present? ? referential_path(compliance_check_set.referential_id) : '#' \ end \ ), \ TableBuilderHelper::Column.new( \ diff --git a/app/views/dashboards/_dashboard.html.slim b/app/views/dashboards/_dashboard.html.slim index 075b94ddc..58cfcc542 100644 --- a/app/views/dashboards/_dashboard.html.slim +++ b/app/views/dashboards/_dashboard.html.slim @@ -22,13 +22,13 @@ .panel.panel-default .panel-heading h3.panel-title.with_actions - = link_to I18n.t("activerecord.models.calendar", count: @dashboard.current_organisation.calendars.size), calendars_path + = link_to I18n.t("activerecord.models.calendar", count: @dashboard.current_organisation.calendars.size), workgroup_calendars_path(current_workgroup) div - = link_to '', calendars_path, class: ' fa fa-chevron-right pull-right' + = link_to '', workgroup_calendars_path(current_workgroup), class: ' fa fa-chevron-right pull-right' - if @dashboard.current_organisation.calendars.present? .list-group - @dashboard.current_organisation.calendars.order("updated_at desc").limit(5).each do |calendar| - = link_to calendar.name, calendar_path(calendar), class: 'list-group-item' + = link_to calendar.name, workgroup_calendars_path(current_workgroup, calendar), class: 'list-group-item' - else .panel-body em.small.text-muted diff --git a/app/views/errors/forbidden.html.slim b/app/views/errors/forbidden.html.slim index 23ea67eff..8c35b46a8 100644 --- a/app/views/errors/forbidden.html.slim +++ b/app/views/errors/forbidden.html.slim @@ -9,7 +9,7 @@ p strong = "Désolé, la page demandée la page n'est pas accessible avec votre profil utilisateur." - p = "Vous pouvez néanmoins continuer à utiliser l'application IBOO." + p = "Vous pouvez néanmoins continuer à utiliser l'application." - else p diff --git a/app/views/errors/server_error.html.slim b/app/views/errors/server_error.html.slim index 189a48760..529ad73e8 100644 --- a/app/views/errors/server_error.html.slim +++ b/app/views/errors/server_error.html.slim @@ -9,7 +9,7 @@ p strong = "Désolé, une erreur est survenue." - p = "Vous pouvez néanmoins continuer à utiliser l'application IBOO." + p = "Vous pouvez néanmoins continuer à utiliser l'application." - else p diff --git a/app/views/layouts/application.html.slim b/app/views/layouts/application.html.slim index 34b373295..3921c8701 100644 --- a/app/views/layouts/application.html.slim +++ b/app/views/layouts/application.html.slim @@ -13,6 +13,8 @@ html lang=I18n.locale = javascript_pack_tag 'application' = javascript_include_tag 'application' + = javascript_tag do + | I18n.locale = '#{I18n.locale}' body = render 'layouts/navigation/main_nav' diff --git a/app/views/layouts/navigation/_main_nav_left_content_stif.html.slim b/app/views/layouts/navigation/_main_nav_left_content_stif.html.slim index 3963d4cd4..1b7293d21 100644 --- a/app/views/layouts/navigation/_main_nav_left_content_stif.html.slim +++ b/app/views/layouts/navigation/_main_nav_left_content_stif.html.slim @@ -29,7 +29,7 @@ span Jeux de données = link_to workbench_imports_path(current_offer_workbench), class: "list-group-item #{(params[:controller] == 'imports') ? 'active' : ''}" do span Import - = link_to calendars_path, class: 'list-group-item' do + = link_to workgroup_calendars_path(current_workgroup), class: 'list-group-item' do span Modèles de calendrier = link_to workbench_compliance_check_sets_path(current_offer_workbench), class: 'list-group-item' do span Rapport de contrôle diff --git a/app/views/layouts/snapshots/actions_links.html.slim b/app/views/layouts/snapshots/actions_links.html.slim new file mode 100644 index 000000000..f1fa55e87 --- /dev/null +++ b/app/views/layouts/snapshots/actions_links.html.slim @@ -0,0 +1,21 @@ +doctype html +html lang=I18n.locale + head + meta charset="utf-8" + meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" + + = csrf_meta_tag + + title = t('brandname') + + = stylesheet_link_tag 'base' + = stylesheet_link_tag 'application' + + = javascript_pack_tag 'application' + = javascript_include_tag 'application' + + body + = render 'layouts/navigation/main_nav' + = render 'layouts/flash_messages', flash: flash + div.page_header + = yield diff --git a/app/views/layouts/snapshots/default.html.slim b/app/views/layouts/snapshots/default.html.slim new file mode 100644 index 000000000..9e4565dcb --- /dev/null +++ b/app/views/layouts/snapshots/default.html.slim @@ -0,0 +1,19 @@ +doctype html +html lang=I18n.locale + head + meta charset="utf-8" + meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" + + = csrf_meta_tag + + title = t('brandname') + + = stylesheet_link_tag 'base' + = stylesheet_link_tag 'application' + + = javascript_pack_tag 'application' + = javascript_include_tag 'application' + + body + = yield + diff --git a/app/views/routes/_form.html.slim b/app/views/routes/_form.html.slim index 29e5be3d2..81f719437 100644 --- a/app/views/routes/_form.html.slim +++ b/app/views/routes/_form.html.slim @@ -27,7 +27,7 @@ // Get JSON data for route stop points = javascript_tag do | window.itinerary_stop = "#{URI.escape(route_json_for_edit(@route))}"; - | window.I18n = #{(I18n.backend.send(:translations)[I18n.locale].to_json).html_safe}; + // | window.I18n = #{(I18n.backend.send(:translations)[I18n.locale].to_json).html_safe}; / StopPoints Reactux component = javascript_pack_tag 'routes/edit.js' diff --git a/app/views/stif/dashboards/_dashboard.html.slim b/app/views/stif/dashboards/_dashboard.html.slim index 64e7d4f96..c28696a94 100644 --- a/app/views/stif/dashboards/_dashboard.html.slim +++ b/app/views/stif/dashboards/_dashboard.html.slim @@ -60,12 +60,12 @@ span.badge.ml-xs = @dashboard.calendars.count if @dashboard.calendars.present? div - = link_to '', calendars_path, class: ' fa fa-chevron-right pull-right', title: t('.see') + = link_to '', workgroup_calendars_path(current_workgroup), class: ' fa fa-chevron-right pull-right', title: t('.see') - if @dashboard.calendars.present? .list-group - @dashboard.calendars.first(5).each_with_index do |calendar, i| - = link_to calendar.name, calendar_path(calendar), class: 'list-group-item' if i < 6 + = link_to calendar.name, workgroup_calendar_path(current_workgroup, calendar), class: 'list-group-item' if i < 6 - else .panel-body diff --git a/app/views/time_tables/_form.html.slim b/app/views/time_tables/_form.html.slim index d06fdf444..007044e65 100644 --- a/app/views/time_tables/_form.html.slim +++ b/app/views/time_tables/_form.html.slim @@ -5,7 +5,7 @@ = form.input :comment, :input_html => { :title => t("formtastic.titles#{format_restriction_for_locales(@referential)}.time_table.comment")} - if @time_table.new_record? && !@time_table.created_from - = form.input :calendar_id, as: :select, input_html: { class: 'tt_target', style: "width: 100%", data: { 'select2-ajax': 'true', 'select2ed-placeholder': 'Indiquez un modèle de calendrier...', term: 'name_cont', url: autocomplete_calendars_path}} + = form.input :calendar_id, as: :select, input_html: { class: 'tt_target', style: "width: 100%", data: { 'select2-ajax': 'true', 'select2ed-placeholder': 'Indiquez un modèle de calendrier...', term: 'name_cont', url: autocomplete_workgroup_calendars_path(current_workgroup)}} - if @time_table.created_from = form.input :created_from, disabled: true, input_html: { value: @time_table.created_from.comment } diff --git a/app/views/time_tables/edit.html.slim b/app/views/time_tables/edit.html.slim index e1c566ff4..d8cffb1b0 100644 --- a/app/views/time_tables/edit.html.slim +++ b/app/views/time_tables/edit.html.slim @@ -8,6 +8,6 @@ = javascript_tag do | window.actionType = "#{raw params[:action]}"; - | window.I18n = #{(I18n.backend.send(:translations)[I18n.locale].to_json).html_safe}; + // | window.I18n = #{(I18n.backend.send(:translations)[I18n.locale].to_json).html_safe}; = javascript_pack_tag 'time_tables/edit.js' diff --git a/app/views/time_tables/index.html.slim b/app/views/time_tables/index.html.slim index f58fbb5ea..6913712a0 100644 --- a/app/views/time_tables/index.html.slim +++ b/app/views/time_tables/index.html.slim @@ -61,6 +61,6 @@ = replacement_msg t('time_tables.search_no_results') = javascript_tag do - | window.I18n = #{(I18n.backend.send(:translations).to_json).html_safe}; + // | window.I18n = #{(I18n.backend.send(:translations).to_json).html_safe}; = javascript_pack_tag 'date_filters' diff --git a/app/views/vehicle_journeys/index.html.slim b/app/views/vehicle_journeys/index.html.slim index caa8450a0..d53d8b50c 100644 --- a/app/views/vehicle_journeys/index.html.slim +++ b/app/views/vehicle_journeys/index.html.slim @@ -29,7 +29,7 @@ | window.features = #{raw @features}; | window.all_missions = #{(@all_missions.to_json).html_safe}; | window.custom_fields = #{(@custom_fields.to_json).html_safe}; - | window.I18n = #{(I18n.backend.send(:translations).to_json).html_safe}; + // | window.I18n = #{(I18n.backend.send(:translations).to_json).html_safe}; - if has_feature?(:vehicle_journeys_return_route) = javascript_tag do diff --git a/app/views/vehicle_journeys/show.rabl b/app/views/vehicle_journeys/show.rabl index dca0866b3..546c851a4 100644 --- a/app/views/vehicle_journeys/show.rabl +++ b/app/views/vehicle_journeys/show.rabl @@ -39,10 +39,8 @@ child :footnotes, :object_root => false do |footnotes| end child(:vehicle_journey_at_stops_matrix, :object_root => false) do |vehicle_stops| + attributes :id, :connecting_service_id, :boarding_alighting_possibility node do |vehicle_stop| - [:id, :connecting_service_id, :boarding_alighting_possibility].map do |att| - node(att) { vehicle_stop.send(att) ? vehicle_stop.send(att) : nil } - end node(:dummy) { vehicle_stop.dummy } node(:area_kind) { vehicle_stop.stop_point.stop_area.kind } diff --git a/app/views/workbenches/show.html.slim b/app/views/workbenches/show.html.slim index a162ca334..aae34c51b 100644 --- a/app/views/workbenches/show.html.slim +++ b/app/views/workbenches/show.html.slim @@ -72,6 +72,6 @@ = replacement_msg t('referentials.search_no_results') = javascript_tag do - | window.I18n = #{(I18n.backend.send(:translations).to_json).html_safe}; + // | window.I18n = #{(I18n.backend.send(:translations).to_json).html_safe}; = javascript_pack_tag 'date_filters' diff --git a/config/breadcrumbs.rb b/config/breadcrumbs.rb index 6da96d73a..2772895fe 100644 --- a/config/breadcrumbs.rb +++ b/config/breadcrumbs.rb @@ -202,13 +202,13 @@ crumb :purchase_window do |referential, purchase_window| parent :purchase_windows, referential end -crumb :calendars do - link I18n.t('calendars.index.title'), calendars_path +crumb :calendars do |workgroup| + link I18n.t('calendars.index.title'), workgroup_calendars_path(workgroup) end -crumb :calendar do |calendar| - link breadcrumb_name(calendar), calendar_path(calendar) - parent :calendars +crumb :calendar do |workgroup, calendar| + link breadcrumb_name(calendar), workgroup_calendar_path(workgroup, calendar) + parent :calendars, workgroup end crumb :referential_line do |referential, line| diff --git a/config/deploy.rb b/config/deploy.rb index 9be023adc..136c60196 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -79,6 +79,7 @@ namespace :deploy do end after 'deploy:update_code', 'deploy:symlink_shared' before 'deploy:assets:precompile', 'deploy:symlink_shared' + after 'deploy:assets:precompile', "deploy:i18n_js_export" desc "Make group writable all deployed files" task :group_writable do @@ -92,8 +93,13 @@ namespace :deploy do end after "deploy:restart", "deploy:sidekiq_restart" + desc "Run i18n:js:export" + task :i18n_js_export do + run "cd #{release_path} && RAILS_ENV=#{rails_env} #{rake} i18n:js:export" + end + desc "Run db:seed" task :seed do - run "cd #{current_path} && #{rake} db:seed RAILS_ENV=#{rails_env}" + run "cd #{current_path} && RAILS_ENV=#{rails_env} #{rake} db:seed" end end diff --git a/config/environments/development.rb b/config/environments/development.rb index 1d2fee44f..446e72190 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -95,6 +95,7 @@ Rails.application.configure do config.i18n.available_locales = [:fr, :en] config.middleware.insert_after(ActionDispatch::Static, Rack::LiveReload) if ENV['LIVERELOAD'] + config.middleware.use I18n::JS::Middleware config.development_toolbar = false if ENV['TOOLBAR'] && File.exists?("config/development_toolbar.rb") config.development_toolbar = OpenStruct.new diff --git a/config/locales/en.yml b/config/locales/en.yml index e59960f95..8af8067db 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -3,6 +3,7 @@ en: "false": "No" "unknown": "Unknown" + time: formats: hour: "%Hh%M" @@ -61,3 +62,7 @@ en: reflex_data: 'Reflex datas' objectid: 'ID' brandname: IBOO + error: "Error" + undefined: 'undefined' + "yes": yes + "no": no diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 175b71ebc..e1f52ff55 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -61,3 +61,7 @@ fr: reflex_data: 'Données Reflex' objectid: 'ID' brandname: IBOO + error: "Erreur" + undefined: 'non renseigné' + "yes": oui + "no": non diff --git a/config/locales/journey_patterns.en.yml b/config/locales/journey_patterns.en.yml index e5248c29c..9d9bc21e2 100644 --- a/config/locales/journey_patterns.en.yml +++ b/config/locales/journey_patterns.en.yml @@ -6,6 +6,7 @@ en: vehicle_journeys_count: "Vehicle journeys: %{count}" vehicle_journey_at_stops: "Vehicle journey at stops" actions: + index: "Journey patterns" new: "Add a new journey_pattern" edit: "Edit this journey pattern" destroy: "Remove this journey pattern" diff --git a/config/locales/stop_points.en.yml b/config/locales/stop_points.en.yml index d22d85731..72e138270 100644 --- a/config/locales/stop_points.en.yml +++ b/config/locales/stop_points.en.yml @@ -55,3 +55,4 @@ en: name: Stop Point for_boarding: "Pickup" for_alighting: "Drop off" + reflex_id: ID diff --git a/config/locales/stop_points.fr.yml b/config/locales/stop_points.fr.yml index d3c873442..71be684f6 100644 --- a/config/locales/stop_points.fr.yml +++ b/config/locales/stop_points.fr.yml @@ -52,6 +52,7 @@ fr: simple_form: labels: stop_point: - name: Arrêt + name: Arrêt for_boarding: "Montée" for_alighting: "Descente" + reflex_id: ID diff --git a/config/locales/vehicle_journeys.en.yml b/config/locales/vehicle_journeys.en.yml index abb1da530..0c8a75b0c 100644 --- a/config/locales/vehicle_journeys.en.yml +++ b/config/locales/vehicle_journeys.en.yml @@ -1,7 +1,14 @@ en: vehicle_journeys: vehicle_journeys_matrix: + cancel_selection: "Cancel Selection" + fetching_error: "There has been a problem fetching the data. Please reload the page to try again." line_routes: "Line's routes" + modal_confirm: 'Do you want to save mofications before moving on to the next page ?' + pagination: "Schedules %{minVJ} to %{maxVJ} over %{total}" + selected_journeys: "%{count} selected journeys" + show_purchase_window: 'Show the purchase window' + show_timetable: 'Show calendar' vehicle_journey: title_stopless: "Vehicle journey %{name}" title: "Vehicle journey leaving from %{stop} at %{time}" @@ -25,44 +32,54 @@ en: title_stopless: "Update vehicle journey %{name}" title: "Update vehicle journey %{name} leaving from %{stop} at %{time}" form: - stop_title: "Stop" - departure: "Departure" + arrival_at: "Arrival at" arrival: "Arrival" - to_arrivals: "Copy departures to arrivals" - to_departures: "Copy arrivals to departures" - time_tables: "Associated calendars to vehicle journey" - slide: "Shift" - slide_title: "Shift all vehicle passing times" + departure_at: "Departure at" + departure: "Departure" + departure_range: + label: Journey departure range + start: Start + end: End + infos: Informations set: "Set" - to: "at" - slide_departure: "departure time at first stop" + show_arrival_time: "Show and edit arrival times" + show_journeys_with_calendar: "Show journeys with calendar" + show_journeys_without_schedule: "Show journeys without schedule" slide_arrival: "arrival time at first stop" - submit_timed: "Create vehicle journey" + slide_departure: "departure time at first stop" + slide_title: "Shift all vehicle passing times" + slide: "Shift" + stop_title: "Stop" + submit_frequency_edit: "Edit frequency vehicle journey" submit_frequency: "Create frequency vehicle journey" submit_timed_edit: "Edit vehicle journey" - submit_frequency_edit: "Edit frequency vehicle journey" + submit_timed: "Create vehicle journey" + time_tables: "Associated calendars to vehicle journey" + to_arrivals: "Copy departures to arrivals" + to_departures: "Copy arrivals to departures" + to: "at" timeless: title: "Timeless vehicle journeys" vehicle_journeys: "Vehicle journeys with times at stop" vehicles_list: "Vehicle journeys list" show: - title: "Vehicle Journey %{vehicle journey}" - stop_title: "Stop" - departure: "Departure" arrival: "Arrival" - time_tables: "Calendars list" bounding: "From %{start} to %{end}" - translation_form: "Vehicle journey translations" + departure: "Departure" journey_frequencies: "Timeband" + stop_title: "Stop" + time_tables: "Calendars list" + title: "Vehicle Journey %{vehicle journey}" + translation_form: "Vehicle journey translations" index: - title: "Vehicle journeys on route %{route}" - vehicle_journeys: "Departure's times" - selection: "Filter on" - selection_all: "All" + advanced_search: "Advanced Search" select_journey_patterns: "Select journey pattern" select_time_tables: "Enter a timetable" + selection_all: "All" + selection: "Filter on" time_range: "Departure time threshold" - advanced_search: "Advanced Search" + title: "Vehicle journeys on route %{route}" + vehicle_journeys: "Departure's times" time_filter: time_range_filter: "Filter" sidebar: @@ -78,40 +95,47 @@ en: other: "vehicle journeys" attributes: vehicle_journey: - line: "Line" - route: "Route" - journey_pattern: "Journey Pattern" - time_tables: "Calendars" - time_slot: "Time Slot" - company: "Company" - number: "Number" + accessible: "Accessible" + arrival_time: "Arrival" + checksum: "Checksum" comment: "Comments" - status_value: "Status Value" - transport_mode: "Transport Mode" - mobility_restricted_suitability: "PRM accessibility" + company: "Company" + created_at: Created at + creator_id: "Created by" + departure_time: "Departure" + facility: "Facility" flexible_service: "On demond transportation" - unspecified_mrs: "Not specified" - accessible: "Accessible" + footnote_ids: "Footnotes" + id: "Journey ID" + journey_frequency_ids: "Timeband" + journey_name: "Name of the journey" + journey_pattern_id: "Pattern ID" + journey_pattern: "Journey Pattern" + line: "Line" + mobility_restricted_suitability: "PRM accessibility" + name: "Journey Name" not_accessible: "Not accessible" - unspecified_fs: "Not specified" + number: "Number" + object_version: "Version" + objectid: "Neptune identifier" on_demand_fs: "On demand service" - regular_fs: "Regular service" - published_journey_name: "Published Name" published_journey_identifier: "Published Identifier" - facility: "Facility" - vehicle_type_identifier: "Vehicle Type Identifier" + published_journey_name: "Published Name" + purchase_window: "Purchase availability" + regular_fs: "Regular service" + route: "Route" + status_value: "Status Value" + time_slot: "Time Slot" time_table_ids: "Calendar list" - vehicle_journey_at_stop_ids: "Time list" - journey_frequency_ids: "Timeband" - objectid: "Neptune identifier" - object_version: "Version" - created_at: Created at + time_tables: "Calendars" + train_number: "Train number" + transport_mode: "Transport Mode" + transport_submode: "Transport Submode" + unspecified_fs: "Not specified" + unspecified_mrs: "Not specified" updated_at: Updated at - creator_id: "Created by" - footnote_ids: "Footnotes" - departure_time: "Departure" - arrival_time: "Arrival" - purchase_window: "Purchase availability" + vehicle_journey_at_stop_ids: "Time list" + vehicle_type_identifier: "Vehicle Type Identifier" errors: models: vehicle_journey: diff --git a/config/locales/vehicle_journeys.fr.yml b/config/locales/vehicle_journeys.fr.yml index ca8475812..1034a3fba 100644 --- a/config/locales/vehicle_journeys.fr.yml +++ b/config/locales/vehicle_journeys.fr.yml @@ -1,7 +1,14 @@ fr: vehicle_journeys: vehicle_journeys_matrix: + cancel_selection: "Annuler la sélection" + fetching_error: "La récupération des missions a rencontré un problème. Rechargez la page pour tenter de corriger le problème." line_routes: "Séquences d'arrêts de la ligne" + modal_confirm: 'Voulez-vous valider vos modifications avant de changer de page?' + pagination: "Liste des horaires %{minVJ} à %{maxVJ} sur %{total}" + selected_journeys: "%{count} course(s) sélectionnée(s)" + show_purchase_window: 'Voir le calendrier commercial' + show_timetable: 'Voir le calendrier' vehicle_journey: title_stopless: "Course %{name}" title: "Course partant de %{stop} à %{time}" @@ -25,44 +32,55 @@ fr: title_stopless: "Editer la course %{name}" title: "Editer la course partant de %{stop} à %{time}" form: - stop_title: "Arrêt" - departure: "Départ" + arrival_at: "Arrivée à" arrival: "Arrivée" - to_arrivals: "Copie départs vers arrivées" - to_departures: "Copie arrivées vers départs" - time_tables: "Calendriers associés à la course" - slide: "Décaler" - slide_title: "Décaler l'ensemble des horaires de course" + departure_at: "Départ à" + departure: "Départ" + departure_range: + label: Plage horaire au départ de la course + start: Début + end: Fin + infos: Informations set: "Fixer" - to: "à" - slide_departure: "horaire de départ au 1° arrêt à" + show_arrival_time: "Afficher et éditer les horaires d'arrivée" + show_journeys_with_calendar: "Afficher les courses avec calendrier" + show_journeys_without_schedule: "Afficher les courses sans horaires" slide_arrival: "horaire d'arrivée au 1° arrêt à" - submit_timed: "Créer course" + slide_departure: "horaire de départ au 1° arrêt à" + slide_title: "Décaler l'ensemble des horaires de course" + slide: "Décaler" + stop_title: "Arrêt" + submit_frequency_edit: "Editer course en fréquence" submit_frequency: "Créer course en fréquence" submit_timed_edit: "Editer course" - submit_frequency_edit: "Editer course en fréquence" + submit_timed: "Créer course" + time_tables: "Calendriers associés à la course" + to_arrivals: "Copie départs vers arrivées" + to_arrivals: "Copie départs vers arrivées" + to_departures: "Copie arrivées vers départs" + to: "à" timeless: title: "Courses sans horaire" vehicle_journeys: "Courses ayant des horaires" vehicles_list: "Liste des courses" show: - title: "Course au départ de %{stop} à %{time} sur la séquence %{route}" - stop_title: "Arrêt" - departure: "Départ" arrival: "Arrivée" - time_tables: "Liste des calendriers" bounding: "De %{start} à %{end}" - translation_form: "Cloner la course" + departure: "Départ" journey_frequencies: "Créneau horaire" + stop_title: "Arrêt" + time_tables: "Liste des calendriers" + title: "Course au départ de %{stop} à %{time} sur la séquence %{route}" + translation_form: "Cloner la course" index: - title: "Horaires de '%{route}'" - vehicle_journeys: "Horaires de départ aux arrêts" - selection: "Filtrer sur" - selection_all: "Tous" + advanced_search: "Recherche avancée" select_journey_patterns: "Sélectionner une mission" select_time_tables: "Saisir un calendrier" + selection_all: "Tous" + selection: "Filtrer sur" time_range: "Seuil horaire au départ" - advanced_search: "Recherche avancée" + title: "Horaires de '%{route}'" + vehicle_journeys: "Horaires de départ aux arrêts" time_filter: time_range_filter: "Filtrer" sidebar: @@ -78,40 +96,47 @@ fr: other: "courses" attributes: vehicle_journey: - line: "Ligne" - route: "Séquence d'arrêt" - journey_pattern: "Mission" - time_tables: "Calendriers" - time_slot: "Fréquence" - company: "Transporteur" - number: "Numéro" + accessible: "Accessible" + arrival_time: "Arrivée" + checksum: "Signature métier" comment: "Commentaires" - status_value: "Etat de trafic" - transport_mode: "Mode de transport" - mobility_restricted_suitability: "Accessibilité PMR" + company: "Transporteur" + created_at: "Créé le" + creator_id: "Créé par" + departure_time: "Départ" + facility: "Equipement" flexible_service: "Transport à la demande" - unspecified_mrs: "Non spécifié" - accessible: "Accessible" + footnote_ids: "Notes de bas de page" + id: "ID Course" + journey_frequency_ids: "Créneau horaire" + journey_name: "Nom de la course" + journey_pattern_id: "ID Mission" + journey_pattern: "Mission" + line: "Ligne" + mobility_restricted_suitability: "Accessibilité PMR" + name: "Nom Course" not_accessible: "Non accessible" - unspecified_fs: "Non spécifié" + number: "Numéro" + object_version: "Version" + objectid: "Identifiant Neptune" on_demand_fs: "Service à la demande" - regular_fs: "Service régulier" - published_journey_name: "Nom public" published_journey_identifier: "Identifiant public" - facility: "Equipement" - vehicle_type_identifier: "Type d'identifiant du véhicule" + published_journey_name: "Nom public" + purchase_window: "Disponibilité commerciale" + regular_fs: "Service régulier" + route: "Itinéraire" + status_value: "Etat de trafic" + time_slot: "Fréquence" time_table_ids: "Liste des calendriers" - vehicle_journey_at_stop_ids: "Liste des horaires" - journey_frequency_ids: "Créneau horaire" - objectid: "Identifiant Neptune" - object_version: "Version" - created_at: "Créé le" + time_tables: "Calendriers" + train_number: "Numéro de train" + transport_mode: "Mode de transport" + transport_submode: "Sous-mode de transport" + unspecified_fs: "Non spécifié" + unspecified_mrs: "Non spécifié" updated_at: "Edité le" - creator_id: "Créé par" - footnote_ids: "Notes de bas de page" - departure_time: "Départ" - arrival_time: "Arrivée" - purchase_window: "Disponibilité commerciale" + vehicle_journey_at_stop_ids: "Liste des horaires" + vehicle_type_identifier: "Type d'identifiant du véhicule" errors: models: vehicle_journey: diff --git a/config/routes.rb b/config/routes.rb index fc2807ab1..0b657b028 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -111,11 +111,13 @@ ChouetteIhm::Application.routes.draw do resources :companies resources :networks end - - resources :calendars do - get :autocomplete, on: :collection, controller: 'autocomplete_calendars' - member do - get 'month', defaults: { format: :json } + + resources :workgroups do + resources :calendars do + get :autocomplete, on: :collection, controller: 'autocomplete_calendars' + member do + get 'month', defaults: { format: :json } + end end end @@ -239,6 +241,10 @@ ChouetteIhm::Application.routes.draw do root :to => "dashboards#show" + if Rails.env.development? || Rails.env.test? + get "/snap" => "snapshots#show" + end + get '/help/(*slug)' => 'help#show' if Rails.application.config.development_toolbar @@ -250,4 +256,6 @@ ChouetteIhm::Application.routes.draw do match '/422', to: 'errors#server_error', via: :all, as: 'unprocessable_entity' match '/500', to: 'errors#server_error', via: :all, as: 'server_error' + match '/status', to: 'statuses#index', via: :get + end diff --git a/config/schedule.rb b/config/schedule.rb index 08488c255..0d2a24f31 100644 --- a/config/schedule.rb +++ b/config/schedule.rb @@ -40,9 +40,15 @@ every :day, :at => '4:00 am' do end every 5.minutes do + rake "import:netex_abort_old" rake "import:notify_parent" end +every 5.minutes do + rake "compliance_check_sets:abort_old" + rake "compliance_check_sets:notify_parent" +end + every 1.minute do command "/bin/echo HeartBeat" end diff --git a/config/webpack/environment.js b/config/webpack/environment.js index 688bcbe8e..743cf66a8 100644 --- a/config/webpack/environment.js +++ b/config/webpack/environment.js @@ -14,7 +14,7 @@ let cleanOptions = { }; -environment.plugins.set( +environment.plugins.append( 'CleanWebpack', new CleanWebpackPlugin(pathsToClean, cleanOptions) ) diff --git a/config/webpack/production.js b/config/webpack/production.js index 7703f8452..82478b156 100644 --- a/config/webpack/production.js +++ b/config/webpack/production.js @@ -2,7 +2,7 @@ const environment = require('./environment') const webpack = require('webpack') const UglifyJsPlugin = require('uglify-js') -environment.plugins.set( +environment.plugins.append( 'UglifyJs', new webpack.optimize.UglifyJsPlugin({ compress: { diff --git a/config/webpack/staging.js b/config/webpack/staging.js index 7703f8452..82478b156 100644 --- a/config/webpack/staging.js +++ b/config/webpack/staging.js @@ -2,7 +2,7 @@ const environment = require('./environment') const webpack = require('webpack') const UglifyJsPlugin = require('uglify-js') -environment.plugins.set( +environment.plugins.append( 'UglifyJs', new webpack.optimize.UglifyJsPlugin({ compress: { diff --git a/db/migrate/20180123174450_add_workgroup_id_to_calendars.rb b/db/migrate/20180123174450_add_workgroup_id_to_calendars.rb new file mode 100644 index 000000000..64ad1a752 --- /dev/null +++ b/db/migrate/20180123174450_add_workgroup_id_to_calendars.rb @@ -0,0 +1,6 @@ +class AddWorkgroupIdToCalendars < ActiveRecord::Migration + def change + add_column :calendars, :workgroup_id, :integer, limit: 8 + add_index :calendars, :workgroup_id + end +end diff --git a/db/schema.rb b/db/schema.rb index cd4d42005..596682ce8 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -90,12 +90,14 @@ ActiveRecord::Schema.define(version: 20180202170009) do t.integer "organisation_id", limit: 8 t.datetime "created_at" t.datetime "updated_at" + t.integer "workgroup_id", limit: 8 t.integer "int_day_types" t.date "excluded_dates", array: true end add_index "calendars", ["organisation_id"], name: "index_calendars_on_organisation_id", using: :btree add_index "calendars", ["short_name"], name: "index_calendars_on_short_name", unique: true, using: :btree + add_index "calendars", ["workgroup_id"], name: "index_calendars_on_workgroup_id", using: :btree create_table "clean_up_results", id: :bigserial, force: :cascade do |t| t.string "message_key" @@ -418,9 +420,9 @@ ActiveRecord::Schema.define(version: 20180202170009) do t.string "type" t.integer "parent_id", limit: 8 t.string "parent_type" - t.datetime "notified_parent_at" t.integer "current_step", default: 0 t.integer "total_steps", default: 0 + t.datetime "notified_parent_at" t.string "creator" end diff --git a/lib/af83/decorator.rb b/lib/af83/decorator.rb index f990555fe..71cf1170d 100644 --- a/lib/af83/decorator.rb +++ b/lib/af83/decorator.rb @@ -2,40 +2,49 @@ class AF83::Decorator < ModelDecorator include AF83::Decorator::EnhancedDecorator extend AF83::Decorator::EnhancedDecorator::ClassMethods - def self.decorates klass - instance_decorator.decorates klass - end + class << self + def decorates klass + instance_decorator.decorates klass + end - def self.instance_decorator - @instance_decorator ||= begin - klass = Class.new(AF83::Decorator::InstanceDecorator) - klass.delegate_all - klass + def instance_decorator + @instance_decorator ||= begin + klass = Class.new(AF83::Decorator::InstanceDecorator) + klass.delegate_all + klass + end end - end - def self.with_instance_decorator - @_with_instance_decorator = true - yield instance_decorator - @_with_instance_decorator = false - end + def with_instance_decorator + @_with_instance_decorator = true + yield instance_decorator + @_with_instance_decorator = false + end + + def decorate object, options = {} + if object.is_a?(ActiveRecord::Base) + return instance_decorator.decorate object, options + else + self.new object, options.update(with: instance_decorator) + end + end - def self.decorate object, options = {} - if object.is_a?(ActiveRecord::Base) - return instance_decorator.decorate object, options - else - self.new object, options.update(with: instance_decorator) + def define_instance_method method_name, &block + instance_decorator.send(:define_method, method_name, &block) end - end - def self.define_instance_method method_name, &block - instance_decorator.send(:define_method, method_name, &block) - end + # Defines a class method on the decorated object's class. These + # can be called like `object.class.my_method`. + def define_instance_class_method method_name, &block + instance_decorator.send(:define_singleton_method, method_name, &block) + end + + def set_scope_with_instance_decorator value=nil, &block + set_scope_without_instance_decorator value, &block + instance_decorator.set_scope value, &block + end - # Defines a class method on the decorated object's class. These - # can be called like `object.class.my_method`. - def self.define_instance_class_method method_name, &block - instance_decorator.send(:define_singleton_method, method_name, &block) + alias_method_chain :set_scope, :instance_decorator end class ActionLinks diff --git a/lib/af83/decorator/enhanced_decorator.rb b/lib/af83/decorator/enhanced_decorator.rb index 904d1b2da..fff8bb8b3 100644 --- a/lib/af83/decorator/enhanced_decorator.rb +++ b/lib/af83/decorator/enhanced_decorator.rb @@ -25,7 +25,7 @@ module AF83::Decorator::EnhancedDecorator policy: :create, before_block: -> (l){ l.content { h.t('actions.add') } - l.href { [:new, object.klass.name.underscore.singularize] } + l.href { [:new, scope, object.klass.model_name.singular] } } } action_link opts.update(args), &block @@ -37,7 +37,7 @@ module AF83::Decorator::EnhancedDecorator primary: :index, before_block: -> (l){ l.content { h.t('actions.show') } - l.href { [object] } + l.href { [scope, object] } } } action_link opts.update(args), &block @@ -49,7 +49,7 @@ module AF83::Decorator::EnhancedDecorator policy: :edit, before_block: -> (l){ l.content { h.t('actions.edit') } - l.href { [:edit, object] } + l.href { [:edit, scope, object] } } } action_link opts.update(args), &block @@ -62,7 +62,7 @@ module AF83::Decorator::EnhancedDecorator secondary: :show, before_block: -> (l){ l.content { h.destroy_link_content } - l.href { [object] } + l.href { [scope, object] } l.method :delete l.data {{ confirm: h.t('actions.destroy_confirm') }} } @@ -70,6 +70,14 @@ module AF83::Decorator::EnhancedDecorator action_link opts.update(args), &block end + def set_scope value=nil, &block + @scope = value || block + end + + def scope + @scope + end + def t key eval "-> (l){ h.t('#{key}') }" end @@ -142,4 +150,10 @@ module AF83::Decorator::EnhancedDecorator def check_feature feature h.has_feature? feature end + + def scope + scope = self.class.scope + scope = instance_exec &scope if scope.is_a? Proc + scope + end end diff --git a/lib/af83/decorator/link.rb b/lib/af83/decorator/link.rb index 7d2896e6a..ee09f80dc 100644 --- a/lib/af83/decorator/link.rb +++ b/lib/af83/decorator/link.rb @@ -30,7 +30,8 @@ class AF83::Decorator::Link @options[name] = block elsif args.size == 0 out = @options[name] - out = context.instance_exec(self, &out) if out.is_a?(Proc) + out = context.instance_exec(self, &out) if out.is_a?(Proc) + out = out.flatten.compact if name.to_s == "href" && out.is_a?(Array) out else # we can use l.foo("bar") or l.foo = "bar" @@ -129,7 +130,9 @@ class AF83::Decorator::Link out[:method] = link_method out[:class] = extra_class out.delete(:link_class) + out.delete(:link_method) out[:class] += " disabled" if disabled + out[:class].strip! out[:disabled] = !!disabled out end diff --git a/lib/stif/dashboard.rb b/lib/stif/dashboard.rb index b6b6b8284..46c635091 100644 --- a/lib/stif/dashboard.rb +++ b/lib/stif/dashboard.rb @@ -4,12 +4,16 @@ module Stif @workbench ||= current_organisation.workbenches.find_by(name: "Gestion de l'offre") end + def workgroup + workbench.workgroup + end + def referentials @referentials ||= self.workbench.all_referentials end def calendars - @calendars ||= Calendar.where('organisation_id = ? OR shared = ?', current_organisation.id, true) + @calendars ||= Calendar.where('(organisation_id = ? OR shared = ?) AND workgroup_id = ?', current_organisation.id, true, workgroup.id) end end end diff --git a/lib/tasks/ci.rake b/lib/tasks/ci.rake index 13d7b8d73..89f9aa9c8 100644 --- a/lib/tasks/ci.rake +++ b/lib/tasks/ci.rake @@ -31,19 +31,22 @@ namespace :ci do sh "bundle exec bundle-audit check --update" end - task :spec => ["ci:assets","spec"] - task :assets do sh "RAILS_ENV=test bundle exec rake assets:precompile" end - task :jest => "ci:assets" do - sh "yarn --no-progress install" # Hack to force install jest after webpack - sh "node_modules/.bin/jest" unless ["CHOUETTE_JEST_DISABLED"] + task :i18n_js_export do + sh "RAILS_ENV=test bundle exec rake i18n:js:export" + end + + task :jest do + sh "node_modules/.bin/jest" unless ENV["CHOUETTE_JEST_DISABLED"] end desc "Deploy after CI" task :deploy do + return if ENV["CHOUETTE_DEPLOY_DISABLED"] + if deploy_env sh "cap #{deploy_env} deploy:migrations" else @@ -59,4 +62,4 @@ namespace :ci do end desc "Run continuous integration tasks (spec, ...)" -task :ci => ["ci:setup", "ci:spec", "ci:jest", "cucumber", "ci:check_security", "ci:deploy", "ci:clean"] +task :ci => ["ci:setup", "ci:assets", "ci:i18n_js_export", "spec", "ci:jest", "cucumber", "ci:check_security", "ci:deploy", "ci:clean"] diff --git a/lib/tasks/compliance_check_sets.rb b/lib/tasks/compliance_check_sets.rb new file mode 100644 index 000000000..c53c7f9ed --- /dev/null +++ b/lib/tasks/compliance_check_sets.rb @@ -0,0 +1,11 @@ +namespace :compliance_check_sets do + desc "Notify parent check sets when children finish" + task notify_parent: :environment do + ParentNotifier.new(ComplianceCheckSet).notify_when_finished + end + + desc "Mark old unfinished check sets as 'aborted'" + task abort_old: :environment do + ComplianceCheckSet.abort_old + end +end diff --git a/lib/tasks/imports.rake b/lib/tasks/imports.rake index 6bc84acc8..02e32fd3d 100644 --- a/lib/tasks/imports.rake +++ b/lib/tasks/imports.rake @@ -1,6 +1,11 @@ namespace :import do desc "Notify parent imports when children finish" task notify_parent: :environment do - ParentImportNotifier.notify_when_finished + ParentNotifier.new(Import).notify_when_finished + end + + desc "Mark old unfinished Netex imports as 'aborted'" + task netex_abort_old: :environment do + NetexImport.abort_old end end diff --git a/package.json b/package.json index e80f5231e..1a63eeac3 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "redux-logger": "3.0.6", "redux-promise": "0.5.3", "redux-thunk": "2.2.0", + "uglify-js": "3.3.2", "whatwg-fetch": "2.0.3" }, "license": "MIT", @@ -41,7 +42,6 @@ "react-addons-test-utils": "15.6.2", "react-test-renderer": "^16.2.0", "sinon": "4.1.3", - "uglify-js": "3.3.2", "webpack-dev-server": "2.9.7" }, "jest": { @@ -49,6 +49,10 @@ "roots": [ "<rootDir>/spec/javascript" ], + "transform": { + "^.+\\.coffee$": "<rootDir>/spec/javascript/preprocessor.js", + "^.+\\.jsx?$": "babel-jest" + }, "testEnvironment": "jest-environment-jsdom-global", "setupFiles": [ "<rootDir>/spec/javascript/spec_helper.js", diff --git a/spec/controllers/api/v1/stop_area_controller_spec.rb b/spec/controllers/api/v1/stop_area_controller_spec.rb index eb0c87661..1ad71a95a 100644 --- a/spec/controllers/api/v1/stop_area_controller_spec.rb +++ b/spec/controllers/api/v1/stop_area_controller_spec.rb @@ -18,16 +18,15 @@ describe Api::V1::StopAreasController, :type => :controller do end end describe "GET #index, :q => { :name_cont => 'aa'}" do - let!(:sa1) { create(:stop_area, :name => "aaa") } - let!(:sa2) { create(:stop_area, :name => "aab") } - let!(:sa3) { create(:stop_area, :name => "abb") } + let!(:sa1) { create(:stop_area, :name => "aaa", stop_area_referential: referential.stop_area_referential) } + let!(:sa2) { create(:stop_area, :name => "aab", stop_area_referential: referential.stop_area_referential) } + let!(:sa3) { create(:stop_area, :name => "abb", stop_area_referential: referential.stop_area_referential) } before :each do config_formatted_request_with_authorization( "application/json") - get :index, :q => { :name_cont => "aa"} + get :index, :q => { :name_cont => "aa"} end it "should assign expected stop_areas" do expect(assigns[:stop_areas].map(&:name).sort).to eq([ sa1.name, sa2.name]) end end end - diff --git a/spec/controllers/autocomplete_stop_areas_controller_spec.rb b/spec/controllers/autocomplete_stop_areas_controller_spec.rb index 2af471361..e0d1cd714 100644 --- a/spec/controllers/autocomplete_stop_areas_controller_spec.rb +++ b/spec/controllers/autocomplete_stop_areas_controller_spec.rb @@ -4,9 +4,11 @@ RSpec.describe AutocompleteStopAreasController, type: :controller do login_user let(:referential) { Referential.first } - let!(:stop_area) { create :stop_area, name: 'écolà militaire' } - let!(:zdep_stop_area) { create :stop_area, area_type: "zdep" } - let!(:not_zdep_stop_area) { create :stop_area, area_type: "lda" } + let(:other_referential) { create :referential } + let!(:stop_area) { create :stop_area, name: 'écolà militaire', referential: referential } + let!(:other_referential_stop_area) { create :stop_area, name: 'écolà militaire', referential: other_referential } + let!(:zdep_stop_area) { create :stop_area, area_type: "zdep", referential: referential } + let!(:not_zdep_stop_area) { create :stop_area, area_type: "lda", referential: referential } describe 'GET #index' do it 'should be successful' do @@ -14,6 +16,12 @@ RSpec.describe AutocompleteStopAreasController, type: :controller do expect(response).to be_success end + it "should filter stop areas based on referential" do + get :index, referential_id: referential.id + expect(assigns(:stop_areas)).to include(stop_area) + expect(assigns(:stop_areas)).to_not include(other_referential_stop_area) + end + context 'search by name' do it 'should be successful' do get :index, referential_id: referential.id, q: 'écolà', :format => :json diff --git a/spec/controllers/statuses_controller_spec.rb b/spec/controllers/statuses_controller_spec.rb new file mode 100644 index 000000000..8a6db8e28 --- /dev/null +++ b/spec/controllers/statuses_controller_spec.rb @@ -0,0 +1,50 @@ +RSpec.describe StatusesController, :type => :controller do + + describe "GET index" do + login_user + render_views + + + let(:request){ get :index} + let(:parsed_response){ JSON.parse response.body } + it "should be ok" do + request + expect(response).to have_http_status 200 + expect(parsed_response["status"]).to eq "ok" + end + context "without blocked object" do + before do + create :referential + create :import + create :compliance_check_set + request + end + + it "should be ok" do + expect(response).to have_http_status 200 + expect(parsed_response["status"]).to eq "ok" + expect(parsed_response["referentials_blocked"]).to eq 0 + expect(parsed_response["imports_blocked"]).to eq 0 + expect(parsed_response["imports_blocked"]).to eq 0 + end + end + + context "with a blocked object" do + before do + create :referential, created_at: 5.hours.ago, ready: false + create :import + create :compliance_check_set + request + end + + it "should be ko" do + expect(Referential.blocked.count).to eq 1 + expect(response).to have_http_status 200 + expect(parsed_response["status"]).to eq "ko" + expect(parsed_response["referentials_blocked"]).to eq 1 + expect(parsed_response["imports_blocked"]).to eq 0 + expect(parsed_response["imports_blocked"]).to eq 0 + end + end + end +end diff --git a/spec/controllers/vehicle_journeys_controller_spec.rb b/spec/controllers/vehicle_journeys_controller_spec.rb index 416450c21..300684532 100644 --- a/spec/controllers/vehicle_journeys_controller_spec.rb +++ b/spec/controllers/vehicle_journeys_controller_spec.rb @@ -26,4 +26,28 @@ RSpec.describe VehicleJourneysController, :type => :controller do end end + describe "GET index" do + login_user + render_views + + context "in JSON" do + let(:vehicle_journey){ create :vehicle_journey } + let(:route){ vehicle_journey.route } + let(:line){ route.line } + let!(:request){ get :index, referential_id: referential.id, line_id: line.id, route_id: route.id, format: :json} + let(:parsed_response){ JSON.parse response.body } + it "should have all the attributes" do + expect(response).to have_http_status 200 + vehicle_journey = parsed_response["vehicle_journeys"].first + vehicle_journey_at_stops_matrix = vehicle_journey["vehicle_journey_at_stops"] + vehicle_journey_at_stops_matrix.each do |received_vjas| + expect(received_vjas).to have_key("id") + vjas = Chouette::VehicleJourneyAtStop.find received_vjas["id"] + [:connecting_service_id, :boarding_alighting_possibility].each do |att| + expect(received_vjas[att]).to eq vjas.send(att) + end + end + end + end + end end diff --git a/spec/factories/calendars.rb b/spec/factories/calendars.rb index 5f3188bee..d9fd242d1 100644 --- a/spec/factories/calendars.rb +++ b/spec/factories/calendars.rb @@ -6,6 +6,7 @@ FactoryGirl.define do sequence(:dates) { |n| [ Date.yesterday - n, Date.yesterday - 2*n ] } shared false organisation + workgroup end sequence :date_range do |n| diff --git a/spec/factories/chouette_stop_areas.rb b/spec/factories/chouette_stop_areas.rb index 9b4764781..dab135ca6 100644 --- a/spec/factories/chouette_stop_areas.rb +++ b/spec/factories/chouette_stop_areas.rb @@ -10,6 +10,14 @@ FactoryGirl.define do association :stop_area_referential + transient do + referential nil + end + + before(:create) do |stop_area, evaluator| + stop_area.stop_area_referential = evaluator.referential.stop_area_referential if evaluator.referential + end + trait :deactivated do deleted_at { 1.hour.ago } end diff --git a/spec/factories/compliance_controls/vehicle_journey_control_factories.rb b/spec/factories/compliance_controls/vehicle_journey_control_factories.rb index e8f68cbdf..86a335aba 100644 --- a/spec/factories/compliance_controls/vehicle_journey_control_factories.rb +++ b/spec/factories/compliance_controls/vehicle_journey_control_factories.rb @@ -1,10 +1,12 @@ FactoryGirl.define do factory :vehicle_journey_control_wating_time, class: 'VehicleJourneyControl::WaitingTime' do + maximum 10 association :compliance_control_set end factory :vehicle_journey_control_delta, class: 'VehicleJourneyControl::Delta' do + maximum 10 association :compliance_control_set end diff --git a/spec/features/access_points_spec.rb b/spec/features/access_points_spec.rb index c16039d67..890906de7 100644 --- a/spec/features/access_points_spec.rb +++ b/spec/features/access_points_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' describe "Access points", :type => :feature do login_user - let!(:stop_area) { create(:stop_area) } + let!(:stop_area) { create(:stop_area, stop_area_referential: referential.stop_area_referential) } let!(:access_points) { Array.new(2) { create(:access_point, :stop_area => stop_area) } } subject { access_points.first } diff --git a/spec/features/calendars_permissions_spec.rb b/spec/features/calendars_permissions_spec.rb index 9b47ab2bb..4857592d5 100644 --- a/spec/features/calendars_permissions_spec.rb +++ b/spec/features/calendars_permissions_spec.rb @@ -2,6 +2,7 @@ RSpec.describe 'Calendars', type: :feature do login_user let(:calendar) { create :calendar, organisation_id: 1 } + let(:workgroup) { calendar.workgroup } describe 'permissions' do before do @@ -13,7 +14,7 @@ RSpec.describe 'Calendars', type: :feature do end context 'on show view' do - let( :path ){ calendar_path(calendar) } + let( :path ){ workgroup_calendar_path(workgroup, calendar) } context 'if present → ' do let( :permission ){ true } @@ -33,7 +34,7 @@ RSpec.describe 'Calendars', type: :feature do end context 'on edit view' do - let( :path ){ edit_calendar_path(calendar) } + let( :path ){ edit_workgroup_calendar_path(workgroup, calendar) } context 'if present → ' do let( :permission ){ true } @@ -51,7 +52,7 @@ RSpec.describe 'Calendars', type: :feature do end context 'on index view' do - let( :path ){ calendars_path } + let( :path ){ workgroup_calendars_path(workgroup) } context 'if present → ' do let( :permission ){ true } diff --git a/spec/features/referential_stop_areas_spec.rb b/spec/features/referential_stop_areas_spec.rb index 0dc7951a7..5e70857e7 100644 --- a/spec/features/referential_stop_areas_spec.rb +++ b/spec/features/referential_stop_areas_spec.rb @@ -5,7 +5,7 @@ describe 'ReferentialStopAreas', type: :feature do login_user let(:referential) { Referential.first } - let(:stop_area_referential) { create :stop_area_referential } + let(:stop_area_referential) { referential.stop_area_referential } let!(:stop_areas) { Array.new(2) { create :stop_area, stop_area_referential: stop_area_referential } } describe 'index' do diff --git a/spec/javascript/preprocessor.js b/spec/javascript/preprocessor.js new file mode 100644 index 000000000..a2de8e4be --- /dev/null +++ b/spec/javascript/preprocessor.js @@ -0,0 +1,15 @@ +'use strict'; + +var coffee = require('coffeescript'); + +module.exports = { + process: function(src, filename) { + if (coffee.helpers.isCoffee(filename)) { + return coffee.compile(src, { + 'bare': false, + 'inlineMap': true + }) + } + return src; + } +}; diff --git a/spec/javascript/vehicle_journeys/components/VehicleJourneys_spec.js b/spec/javascript/vehicle_journeys/components/VehicleJourneys_spec.js index 87151c64b..2a84cb9ca 100644 --- a/spec/javascript/vehicle_journeys/components/VehicleJourneys_spec.js +++ b/spec/javascript/vehicle_journeys/components/VehicleJourneys_spec.js @@ -1,6 +1,13 @@ import React, { Component } from 'react' import VehicleJourneys from '../../../../app/javascript/vehicle_journeys/components/VehicleJourneys' import renderer from 'react-test-renderer' +import fs from 'fs' + +import I18n from '../../../../public/javascripts/i18n' +import decorateI18n from '../../../../app/assets/javascripts/i18n/extended.coffee' +window.I18n = decorateI18n(I18n) +I18n.locale = "fr" +eval(fs.readFileSync('./public/javascripts/translations.js')+'') describe('stopPointHeader', () => { set('features', () => { diff --git a/spec/javascript/vehicle_journeys/components/__snapshots__/VehicleJourneys_spec.js.snap b/spec/javascript/vehicle_journeys/components/__snapshots__/VehicleJourneys_spec.js.snap index 703f727d7..cdd34cbbd 100644 --- a/spec/javascript/vehicle_journeys/components/__snapshots__/VehicleJourneys_spec.js.snap +++ b/spec/javascript/vehicle_journeys/components/__snapshots__/VehicleJourneys_spec.js.snap @@ -19,19 +19,19 @@ exports[`stopPointHeader should display the city name 1`] = ` <div className="strong mb-xs" > - ID course + ID Course </div> <div> - Nom course + Nom Course </div> <div> - ID mission + ID Mission </div> <div> - Transporteur + transporteur </div> <div> - Calendriers + calendrier </div> </div> <div @@ -109,19 +109,19 @@ exports[`stopPointHeader with the "long_distance_routes" feature should display <div className="strong mb-xs" > - ID course + ID Course </div> <div> - Nom course + Nom Course </div> <div> - ID mission + ID Mission </div> <div> - Transporteur + transporteur </div> <div> - Calendriers + calendrier </div> </div> <div diff --git a/spec/mailers/calendar_mailer_spec.rb b/spec/mailers/calendar_mailer_spec.rb index 9a2076f64..00d73a58b 100644 --- a/spec/mailers/calendar_mailer_spec.rb +++ b/spec/mailers/calendar_mailer_spec.rb @@ -20,7 +20,7 @@ RSpec.describe CalendarMailer, type: :mailer do end it 'should have correct body' do - key = I18n.t("mailers.calendar_mailer.#{type}.body", cal_name: calendar.name, cal_index_url: calendars_url) + key = I18n.t("mailers.calendar_mailer.#{type}.body", cal_name: calendar.name, cal_index_url: workgroup_calendars_url(calendar.workgroup)) expect(email).to have_body_text /#{key}/ end end diff --git a/spec/models/calendar_spec.rb b/spec/models/calendar_spec.rb index 3cffd0f8a..a5c0a7471 100644 --- a/spec/models/calendar_spec.rb +++ b/spec/models/calendar_spec.rb @@ -36,7 +36,7 @@ RSpec.describe Calendar, :type => :model do end it 'validates that dates and date_ranges do not overlap but allow for days not in the list' do - expect(build(:calendar, dates: [Date.today.beginning_of_week], date_ranges: [Date.today.beginning_of_week..Date.today], int_day_types: Calendar::THURSDAY)).to be_valid + expect(build(:calendar, dates: [Date.today.beginning_of_week - 1.week], date_ranges: [(Date.today.beginning_of_week - 1.week)..Date.today], int_day_types: Calendar::THURSDAY)).to be_valid end it 'validates that there are no duplicates in dates' do diff --git a/spec/models/compliance_check_spec.rb b/spec/models/compliance_check_spec.rb index f83d78c29..ffa59245c 100644 --- a/spec/models/compliance_check_spec.rb +++ b/spec/models/compliance_check_spec.rb @@ -15,4 +15,36 @@ RSpec.describe ComplianceCheck, type: :model do it { should validate_presence_of :name } it { should validate_presence_of :code } it { should validate_presence_of :origin_code } + + describe ".abort_old" do + it "changes check sets older than 4 hours to aborted" do + Timecop.freeze(Time.now) do + old_check_set = create( + :compliance_check_set, + status: 'pending', + created_at: 4.hours.ago - 1.minute + ) + current_check_set = create(:compliance_check_set, status: 'pending') + + ComplianceCheckSet.abort_old + + expect(current_check_set.reload.status).to eq('pending') + expect(old_check_set.reload.status).to eq('aborted') + end + end + + it "doesn't work on check sets with a `finished_status`" do + Timecop.freeze(Time.now) do + check_set = create( + :compliance_check_set, + status: 'successful', + created_at: 4.hours.ago - 1.minute + ) + + ComplianceCheckSet.abort_old + + expect(check_set.reload.status).to eq('successful') + end + end + end end diff --git a/spec/models/import_spec.rb b/spec/models/import_spec.rb index ffb2360c2..8b85f151b 100644 --- a/spec/models/import_spec.rb +++ b/spec/models/import_spec.rb @@ -29,6 +29,58 @@ RSpec.describe Import, type: :model do ) end + describe ".abort_old" do + it "changes imports older than 4 hours to aborted" do + Timecop.freeze(Time.now) do + old_import = create( + :workbench_import, + status: 'pending', + created_at: 4.hours.ago - 1.minute + ) + current_import = create(:workbench_import, status: 'pending') + + Import.abort_old + + expect(current_import.reload.status).to eq('pending') + expect(old_import.reload.status).to eq('aborted') + end + end + + it "doesn't work on imports with a `finished_status`" do + Timecop.freeze(Time.now) do + import = create( + :workbench_import, + status: 'successful', + created_at: 4.hours.ago - 1.minute + ) + + Import.abort_old + + expect(import.reload.status).to eq('successful') + end + end + + it "only works on the caller type" do + Timecop.freeze(Time.now) do + workbench_import = create( + :workbench_import, + status: 'pending', + created_at: 4.hours.ago - 1.minute + ) + netex_import = create( + :netex_import, + status: 'pending', + created_at: 4.hours.ago - 1.minute + ) + + NetexImport.abort_old + + expect(workbench_import.reload.status).to eq('pending') + expect(netex_import.reload.status).to eq('aborted') + end + end + end + describe "#destroy" do it "must destroy all child imports" do netex_import = create(:netex_import) diff --git a/spec/services/parent_import_notifier_spec.rb b/spec/services/parent_notifier_spec.rb index 3ab505f88..ecf508fcd 100644 --- a/spec/services/parent_import_notifier_spec.rb +++ b/spec/services/parent_notifier_spec.rb @@ -1,4 +1,4 @@ -RSpec.describe ParentImportNotifier do +RSpec.describe ParentNotifier do let(:workbench_import) { create(:workbench_import) } describe ".notify_when_finished" do @@ -20,7 +20,7 @@ RSpec.describe ParentImportNotifier do expect(netex_import).to receive(:notify_parent) end - ParentImportNotifier.notify_when_finished(netex_imports) + ParentNotifier.new(Import).notify_when_finished(netex_imports) end it "doesn't call #notify_parent if its `notified_parent_at` is set" do @@ -33,11 +33,11 @@ RSpec.describe ParentImportNotifier do expect(netex_import).not_to receive(:notify_parent) - ParentImportNotifier.notify_when_finished + ParentNotifier.new(Import).notify_when_finished end end - describe ".imports_pending_notification" do + describe ".objects_pending_notification" do it "includes imports with a parent and `notified_parent_at` unset" do netex_import = create( :netex_import, @@ -47,7 +47,7 @@ RSpec.describe ParentImportNotifier do ) expect( - ParentImportNotifier.imports_pending_notification + ParentNotifier.new(Import).objects_pending_notification ).to eq([netex_import]) end @@ -55,7 +55,7 @@ RSpec.describe ParentImportNotifier do create(:import, parent: nil) expect( - ParentImportNotifier.imports_pending_notification + ParentNotifier.new(Import).objects_pending_notification ).to be_empty end @@ -70,7 +70,7 @@ RSpec.describe ParentImportNotifier do end expect( - ParentImportNotifier.imports_pending_notification + ParentNotifier.new(Import).objects_pending_notification ).to be_empty end @@ -83,7 +83,7 @@ RSpec.describe ParentImportNotifier do ) expect( - ParentImportNotifier.imports_pending_notification + ParentNotifier.new(Import).objects_pending_notification ).to be_empty end end diff --git a/spec/support/integration_spec_helper.rb b/spec/support/integration_spec_helper.rb index 36306559d..7ba7e9f92 100644 --- a/spec/support/integration_spec_helper.rb +++ b/spec/support/integration_spec_helper.rb @@ -3,7 +3,11 @@ module IntegrationSpecHelper def paginate_collection klass, decorator, page=1, context={} collection = klass.page(page) if decorator - collection = ModelDecorator.decorate(collection, with: decorator, context: context) + if decorator < AF83::Decorator + collection = decorator.decorate(collection, context: context) + else + collection = ModelDecorator.decorate(collection, with: decorator, context: context) + end end collection end @@ -24,6 +28,13 @@ module IntegrationSpecHelper context('', &block) if block_given? end end + + def with_feature feature, &block + context "with feature #{feature}" do + let(:features){ [feature] } + context('', &block) if block_given? + end + end end def self.included into @@ -48,7 +59,7 @@ RSpec::Matchers.define :have_link_for_each_item do |collection, name, opts| end description { "have #{name} link for each item" } failure_message do - "expected view to have #{name} link for each item, failed with selector: \"#{@selector}\"" + "expected view to have one #{name} link for each item, failed with selector: \"#{@selector}\"" end end diff --git a/spec/support/pundit/pundit_view_policy.rb b/spec/support/pundit/pundit_view_policy.rb index 91be0624c..63970de02 100644 --- a/spec/support/pundit/pundit_view_policy.rb +++ b/spec/support/pundit/pundit_view_policy.rb @@ -2,13 +2,18 @@ module Pundit module PunditViewPolicy 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(:current_referential){ referential || build_stubbed(:referential, organisation: organisation) } + into.let(:current_user){ create :user, permissions: permissions, organisation: organisation } into.let(:pundit_user){ UserContext.new(current_user, referential: current_referential) } + into.let(:current_offer_workbench) { create :workbench, organisation: organisation} into.before do allow(view).to receive(:pundit_user) { pundit_user } - + allow(view).to receive(:current_user) { current_user } + allow(view).to receive(:current_organisation).and_return(organisation) + allow(view).to receive(:current_offer_workbench).and_return(current_offer_workbench) + allow(view).to receive(:current_workgroup).and_return(current_offer_workbench.workgroup) + allow(view).to receive(:has_feature?){ |f| features.include?(f)} + allow(view).to receive(:user_signed_in?).and_return true allow(view).to receive(:policy) do |instance| ::Pundit.policy pundit_user, instance end diff --git a/spec/support/referential.rb b/spec/support/referential.rb index 497ff47a8..9acdce73a 100644 --- a/spec/support/referential.rb +++ b/spec/support/referential.rb @@ -11,8 +11,8 @@ module ReferentialHelper def self.included(base) base.class_eval do extend ClassMethods - alias_method :referential, :first_referential - alias_method :organisation, :first_organisation + base.let(:referential){ first_referential } + base.let(:organisation){ first_organisation } end end diff --git a/spec/support/snapshot_support.rb b/spec/support/snapshot_support.rb new file mode 100644 index 000000000..b1ade5288 --- /dev/null +++ b/spec/support/snapshot_support.rb @@ -0,0 +1,60 @@ +module SnaphostSpecHelper + + module Methods + def set_invariant expr, val=nil + val ||= expr + chain = expr.split(".") + method = chain.pop + + before(:each) do + allow(eval(chain.join('.'))).to receive(method){ val } + end + end + end + + def self.included into + into.extend Methods + end +end + +RSpec.configure do |config| + config.include SnaphostSpecHelper, type: :view +end + + +RSpec::Matchers.define :match_actions_links_snapshot do |name| + match do |actual| + @content = Capybara::Node::Simple.new(rendered).find('.page_header').native.inner_html + expect(@content).to match_snapshot(name) + end + + failure_message do |actual| + out = ["Snapshots did not match."] + snap_path = File.dirname(method_missing(:class).metadata[:file_path]) + "/__snapshots__/#{name}.snap" + temp_path = Pathname.new "#{Rails.root}/tmp/__snapshots__/#{name}.failed.snap" + FileUtils.mkdir_p temp_path.dirname + tmp = File.new temp_path, "w" + tmp.write @content + tmp.close() + expected = File.read snap_path + out << "Expected: #{expected}" + out << "Actual: #{@content}" + out << "\n\n --- DIFF ---" + out << differ.diff_as_string(@content, expected) + out << "\n\n --- Previews : ---" + out << "Expected: \n" + snapshot_url(snap: snap_path, layout: :actions_links) + out << " \nActual: \n" + snapshot_url(snap: tmp.path, layout: :actions_links) + out.join("\n") + end + + def snapshot_url snap:, layout: + "http://localhost:3000/snap/?snap=#{URI.encode(snap.to_s)}&layout=#{URI.encode(layout.to_s)}" + end + + def differ + RSpec::Support::Differ.new( + :object_preparer => lambda { |object| RSpec::Matchers::Composable.surface_descriptions_in(object) }, + :color => RSpec::Matchers.configuration.color? + ) + end +end diff --git a/spec/views/companies/__snapshots__/companies/index.snap b/spec/views/companies/__snapshots__/companies/index.snap new file mode 100644 index 000000000..2c5c23400 --- /dev/null +++ b/spec/views/companies/__snapshots__/companies/index.snap @@ -0,0 +1,4 @@ +<div class="container-fluid"><div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"></div></div> +</div></div>
\ No newline at end of file diff --git a/spec/views/companies/__snapshots__/companies/index_create.snap b/spec/views/companies/__snapshots__/companies/index_create.snap new file mode 100644 index 000000000..df36d5f49 --- /dev/null +++ b/spec/views/companies/__snapshots__/companies/index_create.snap @@ -0,0 +1,4 @@ +<div class="container-fluid"><div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><a class="btn btn-default" href="/line_referentials/99/companies/new">Ajouter un transporteur</a></div></div> +</div></div>
\ No newline at end of file diff --git a/spec/views/companies/__snapshots__/companies/index_destroy.snap b/spec/views/companies/__snapshots__/companies/index_destroy.snap new file mode 100644 index 000000000..2c5c23400 --- /dev/null +++ b/spec/views/companies/__snapshots__/companies/index_destroy.snap @@ -0,0 +1,4 @@ +<div class="container-fluid"><div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"></div></div> +</div></div>
\ No newline at end of file diff --git a/spec/views/companies/__snapshots__/companies/index_update.snap b/spec/views/companies/__snapshots__/companies/index_update.snap new file mode 100644 index 000000000..2c5c23400 --- /dev/null +++ b/spec/views/companies/__snapshots__/companies/index_update.snap @@ -0,0 +1,4 @@ +<div class="container-fluid"><div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"></div></div> +</div></div>
\ No newline at end of file diff --git a/spec/views/companies/__snapshots__/companies/show.snap b/spec/views/companies/__snapshots__/companies/show.snap new file mode 100644 index 000000000..8fe847427 --- /dev/null +++ b/spec/views/companies/__snapshots__/companies/show.snap @@ -0,0 +1,4 @@ +<div class="container-fluid"><div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>Transporteur Company Name</h1></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 23/01/2018 <br> Par web service</div></div></div> +</div></div>
\ No newline at end of file diff --git a/spec/views/companies/__snapshots__/companies/show_create.snap b/spec/views/companies/__snapshots__/companies/show_create.snap new file mode 100644 index 000000000..8fe847427 --- /dev/null +++ b/spec/views/companies/__snapshots__/companies/show_create.snap @@ -0,0 +1,4 @@ +<div class="container-fluid"><div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>Transporteur Company Name</h1></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 23/01/2018 <br> Par web service</div></div></div> +</div></div>
\ No newline at end of file diff --git a/spec/views/companies/__snapshots__/companies/show_destroy.snap b/spec/views/companies/__snapshots__/companies/show_destroy.snap new file mode 100644 index 000000000..5d574e460 --- /dev/null +++ b/spec/views/companies/__snapshots__/companies/show_destroy.snap @@ -0,0 +1,7 @@ +<div class="container-fluid"> +<div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>Transporteur Company Name</h1></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 23/01/2018 <br> Par web service</div></div></div> +</div> +<div class="row mb-sm"><div class="col-lg-12 text-right"><a data-confirm="Etes vous sûr de supprimer ce transporteur ?" class="btn btn-primary" rel="nofollow" data-method="delete" href="/line_referentials/99/companies/909"><span class="fa fa-trash mr-xs"></span>Supprimer ce transporteur</a></div></div> +</div>
\ No newline at end of file diff --git a/spec/views/companies/__snapshots__/companies/show_update.snap b/spec/views/companies/__snapshots__/companies/show_update.snap new file mode 100644 index 000000000..c2fbd3297 --- /dev/null +++ b/spec/views/companies/__snapshots__/companies/show_update.snap @@ -0,0 +1,7 @@ +<div class="container-fluid"><div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>Transporteur Company Name</h1></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"> +<div class="small last-update">Dernière mise à jour le 23/01/2018 <br> Par web service</div> +<a class="btn btn-default" href="/line_referentials/99/companies/909/edit">Editer ce transporteur</a> +</div></div> +</div></div>
\ No newline at end of file diff --git a/spec/views/companies/index.html.erb_spec.rb b/spec/views/companies/index.html.erb_spec.rb index 9db689ba6..8ed5f2c21 100644 --- a/spec/views/companies/index.html.erb_spec.rb +++ b/spec/views/companies/index.html.erb_spec.rb @@ -3,7 +3,10 @@ require 'spec_helper' RSpec.describe "/companies/index", :type => :view do let!(:line_referential) { assign :line_referential, create(:line_referential) } - let!(:companies) { assign :companies, CompanyDecorator.decorate_collection(Array.new(2) { create(:company, line_referential: line_referential) }.paginate) } + let(:context){{referential: line_referential}} + let!(:companies) do + assign :companies, build_paginated_collection(:company, CompanyDecorator, line_referential: line_referential, context: context) + end let!(:search) { assign :q, Ransack::Search.new(Chouette::Company) } # Fixme #1795 @@ -22,4 +25,28 @@ RSpec.describe "/companies/index", :type => :view do # expect(view.content_for(:sidebar)).to have_selector(".actions a[href='#{new_line_referential_company_path(line_referential)}']") # end + before(:each) do + allow(view).to receive(:collection).and_return(companies) + allow(view).to receive(:decorated_collection).and_return(companies) + allow(view).to receive(:current_referential).and_return(line_referential) + controller.request.path_parameters[:line_referential_id] = line_referential.id + allow(view).to receive(:params).and_return({action: :index}) + end + + describe "action links" do + set_invariant "line_referential.id", "99" + + before(:each){ + render template: "companies/index", layout: "layouts/application" + } + + it { should match_actions_links_snapshot "companies/index" } + + %w(create update destroy).each do |p| + with_permission "companies.#{p}" do + it { should match_actions_links_snapshot "companies/index_#{p}" } + end + end + end + end diff --git a/spec/views/companies/show.html.erb_spec.rb b/spec/views/companies/show.html.erb_spec.rb index aeb93aebb..b127bdf44 100644 --- a/spec/views/companies/show.html.erb_spec.rb +++ b/spec/views/companies/show.html.erb_spec.rb @@ -2,11 +2,38 @@ require 'spec_helper' describe "/companies/show", :type => :view do - let!(:company) { assign(:company, create(:company)) } + let!(:company) { c = create(:company); assign(:company, c.decorate(context: {referential: c.line_referential})) } let!(:line_referential) { assign :line_referential, company.line_referential } # it "should display a map with class 'company'" do # render # expect(rendered).to have_selector("#map", :class => 'company') # end + + before(:each) do + allow(view).to receive(:current_referential).and_return(line_referential) + allow(view).to receive(:resource).and_return(company) + controller.request.path_parameters[:line_referential_id] = line_referential.id + controller.request.path_parameters[:id] = company.id + allow(view).to receive(:params).and_return({action: :show}) + end + + describe "action links" do + set_invariant "line_referential.id", "99" + set_invariant "company.object.id", "909" + set_invariant "company.object.name", "Company Name" + set_invariant "company.object.updated_at", "2018/01/23".to_time + + before(:each){ + render template: "companies/show", layout: "layouts/application" + } + + it { should match_actions_links_snapshot "companies/show" } + + %w(create update destroy).each do |p| + with_permission "companies.#{p}" do + it { should match_actions_links_snapshot "companies/show_#{p}" } + end + end + end end diff --git a/spec/views/lines/__snapshots__/lines/index.snap b/spec/views/lines/__snapshots__/lines/index.snap new file mode 100644 index 000000000..2c5c23400 --- /dev/null +++ b/spec/views/lines/__snapshots__/lines/index.snap @@ -0,0 +1,4 @@ +<div class="container-fluid"><div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"></div></div> +</div></div>
\ No newline at end of file diff --git a/spec/views/lines/__snapshots__/lines/index_create.snap b/spec/views/lines/__snapshots__/lines/index_create.snap new file mode 100644 index 000000000..4e4f54e7f --- /dev/null +++ b/spec/views/lines/__snapshots__/lines/index_create.snap @@ -0,0 +1,4 @@ +<div class="container-fluid"><div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><a class="btn btn-default" href="/line_referentials/99/lines/new">Ajouter une ligne</a></div></div> +</div></div>
\ No newline at end of file diff --git a/spec/views/lines/__snapshots__/lines/index_destroy.snap b/spec/views/lines/__snapshots__/lines/index_destroy.snap new file mode 100644 index 000000000..2c5c23400 --- /dev/null +++ b/spec/views/lines/__snapshots__/lines/index_destroy.snap @@ -0,0 +1,4 @@ +<div class="container-fluid"><div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"></div></div> +</div></div>
\ No newline at end of file diff --git a/spec/views/lines/__snapshots__/lines/index_update.snap b/spec/views/lines/__snapshots__/lines/index_update.snap new file mode 100644 index 000000000..2c5c23400 --- /dev/null +++ b/spec/views/lines/__snapshots__/lines/index_update.snap @@ -0,0 +1,4 @@ +<div class="container-fluid"><div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"></div></div> +</div></div>
\ No newline at end of file diff --git a/spec/views/lines/__snapshots__/lines/show.snap b/spec/views/lines/__snapshots__/lines/show.snap new file mode 100644 index 000000000..30eb6786e --- /dev/null +++ b/spec/views/lines/__snapshots__/lines/show.snap @@ -0,0 +1,9 @@ +<div class="container-fluid"> +<div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>Ligne Name</h1></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 23/01/2018 <br> Par web service</div></div></div> +</div> +<div class="row mb-sm"><div class="col-lg-12 text-right"> +<a class="btn btn-primary" href="/line_referentials/99/networks/99">Voir le réseau</a><a class="btn btn-primary" href="/line_referentials/99/companies/99">Voir le transporteur principal</a> +</div></div> +</div>
\ No newline at end of file diff --git a/spec/views/lines/__snapshots__/lines/show_create.snap b/spec/views/lines/__snapshots__/lines/show_create.snap new file mode 100644 index 000000000..30eb6786e --- /dev/null +++ b/spec/views/lines/__snapshots__/lines/show_create.snap @@ -0,0 +1,9 @@ +<div class="container-fluid"> +<div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>Ligne Name</h1></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 23/01/2018 <br> Par web service</div></div></div> +</div> +<div class="row mb-sm"><div class="col-lg-12 text-right"> +<a class="btn btn-primary" href="/line_referentials/99/networks/99">Voir le réseau</a><a class="btn btn-primary" href="/line_referentials/99/companies/99">Voir le transporteur principal</a> +</div></div> +</div>
\ No newline at end of file diff --git a/spec/views/lines/__snapshots__/lines/show_destroy.snap b/spec/views/lines/__snapshots__/lines/show_destroy.snap new file mode 100644 index 000000000..8ed08a90d --- /dev/null +++ b/spec/views/lines/__snapshots__/lines/show_destroy.snap @@ -0,0 +1,9 @@ +<div class="container-fluid"> +<div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>Ligne Name</h1></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 23/01/2018 <br> Par web service</div></div></div> +</div> +<div class="row mb-sm"><div class="col-lg-12 text-right"> +<a class="btn btn-primary" href="/line_referentials/99/networks/99">Voir le réseau</a><a class="btn btn-primary" href="/line_referentials/99/companies/99">Voir le transporteur principal</a><a data-confirm="Etes vous sûr de supprimer cette ligne ?" class="btn btn-primary" rel="nofollow" data-method="delete" href="/line_referentials/99/lines/99"><span class="fa fa-trash mr-xs"></span>Supprimer cette ligne</a> +</div></div> +</div>
\ No newline at end of file diff --git a/spec/views/lines/__snapshots__/lines/show_update.snap b/spec/views/lines/__snapshots__/lines/show_update.snap new file mode 100644 index 000000000..30eb6786e --- /dev/null +++ b/spec/views/lines/__snapshots__/lines/show_update.snap @@ -0,0 +1,9 @@ +<div class="container-fluid"> +<div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>Ligne Name</h1></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 23/01/2018 <br> Par web service</div></div></div> +</div> +<div class="row mb-sm"><div class="col-lg-12 text-right"> +<a class="btn btn-primary" href="/line_referentials/99/networks/99">Voir le réseau</a><a class="btn btn-primary" href="/line_referentials/99/companies/99">Voir le transporteur principal</a> +</div></div> +</div>
\ No newline at end of file diff --git a/spec/views/lines/index.html.slim_spec.rb b/spec/views/lines/index.html.slim_spec.rb index fb436c545..20e1783e3 100644 --- a/spec/views/lines/index.html.slim_spec.rb +++ b/spec/views/lines/index.html.slim_spec.rb @@ -13,11 +13,12 @@ describe "/lines/index", :type => :view do let(:lines) do assign :lines, build_paginated_collection(:line, LineDecorator, line_referential: line_referential, context: context) end - let!(:q) { assign :q, Ransack::Search.new(Chouette::Line) } + let!(:q) { assign :q, Ransack::Search.new(Chouette::Line) } before :each do deactivated_line allow(view).to receive(:collection).and_return(lines) + allow(view).to receive(:decorated_collection).and_return(lines) allow(view).to receive(:current_referential).and_return(line_referential) allow(view).to receive(:params).and_return({action: :index}) controller.request.path_parameters[:line_referential_id] = line_referential.id @@ -25,49 +26,68 @@ describe "/lines/index", :type => :view do render end - common_items = ->{ - it { should have_link_for_each_item(lines, "show", -> (line){ view.line_referential_line_path(line_referential, line) }) } - it { should have_link_for_each_item(lines, "network", -> (line){ view.line_referential_network_path(line_referential, line.network) }) } - it { should have_link_for_each_item(lines, "company", -> (line){ view.line_referential_company_path(line_referential, line.company) }) } - } + describe "action links" do + set_invariant "line_referential.id", "99" + set_invariant "line_referential.name", "Name" - common_items.call() - it { should have_the_right_number_of_links(lines, 3) } + before(:each){ + render template: "lines/index", layout: "layouts/application" + } - with_permission "lines.change_status" do - common_items.call() - it { should have_link_for_each_item(lines, "deactivate", -> (line){ view.deactivate_line_referential_line_path(line_referential, line) }) } - it { should have_the_right_number_of_links(lines, 4) } + it { should match_actions_links_snapshot "lines/index" } + + %w(create update destroy).each do |p| + with_permission "lines.#{p}" do + it { should match_actions_links_snapshot "lines/index_#{p}" } + end + end end - with_permission "lines.destroy" do - common_items.call() - it { - should have_link_for_each_item(lines, "destroy", { - href: ->(line){ view.line_referential_line_path(line_referential, line)}, - method: :delete - }) + context "links" do + common_items = ->{ + it { should have_link_for_each_item(lines, "show", -> (line){ view.line_referential_line_path(line_referential, line) }) } + it { should have_link_for_each_item(lines, "network", -> (line){ view.line_referential_network_path(line_referential, line.network) }) } + it { should have_link_for_each_item(lines, "company", -> (line){ view.line_referential_company_path(line_referential, line.company) }) } } - it { should have_the_right_number_of_links(lines, 4) } - end - context "with a deactivated item" do + common_items.call() + it { should have_the_right_number_of_links(lines, 3) } + with_permission "lines.change_status" do - let(:deactivated_line){ create :line, deactivated: true } + common_items.call() + it { should have_link_for_each_item(lines, "deactivate", -> (line){ view.deactivate_line_referential_line_path(line_referential, line) }) } + it { should have_the_right_number_of_links(lines, 4) } + end + with_permission "lines.destroy" do common_items.call() - it "should display an activate link for the deactivated one" do - lines.each do |line| - if line == deactivated_line - href = view.activate_line_referential_line_path(line_referential, line) - else - href = view.deactivate_line_referential_line_path(line_referential, line) + it { + should have_link_for_each_item(lines, "destroy", { + href: ->(line){ view.line_referential_line_path(line_referential, line)}, + method: :delete + }) + } + it { should have_the_right_number_of_links(lines, 4) } + end + + context "with a deactivated item" do + with_permission "lines.change_status" do + let(:deactivated_line){ create :line, deactivated: true } + + common_items.call() + it "should display an activate link for the deactivated one" do + lines.each do |line| + if line == deactivated_line + href = view.activate_line_referential_line_path(line_referential, line) + else + href = view.deactivate_line_referential_line_path(line_referential, line) + end + selector = "tr.#{TableBuilderHelper.item_row_class_name(lines)}-#{line.id} .actions a[href='#{href}']" + expect(rendered).to have_selector(selector, count: 1) end - selector = "tr.#{TableBuilderHelper.item_row_class_name(lines)}-#{line.id} .actions a[href='#{href}']" - expect(rendered).to have_selector(selector, count: 1) end + it { should have_the_right_number_of_links(lines, 4) } end - it { should have_the_right_number_of_links(lines, 4) } end end end diff --git a/spec/views/lines/show.html.erb_spec.rb b/spec/views/lines/show.html.erb_spec.rb index 9649d9c8e..effdcd014 100644 --- a/spec/views/lines/show.html.erb_spec.rb +++ b/spec/views/lines/show.html.erb_spec.rb @@ -15,6 +15,30 @@ describe "/lines/show", :type => :view do let!(:map) { assign(:map, double(:to_html => '<div id="map"/>'.html_safe)) } before do - allow(view).to receive_messages(current_organisation: referential.organisation) + allow(view).to receive_messages(current_organisation: referential.organisation, resource: line) + controller.request.path_parameters[:line_referential_id] = line_referential.id + controller.request.path_parameters[:id] = line.id + allow(view).to receive(:params).and_return({action: :show}) + end + + describe "action links" do + set_invariant "line_referential.id", "99" + set_invariant "line.object.id", "99" + set_invariant "line.object.name", "Name" + set_invariant "line.company.id", "99" + set_invariant "line.network.id", "99" + set_invariant "line.updated_at", "2018/01/23".to_time + + before(:each){ + render template: "lines/show", layout: "layouts/application" + } + + it { should match_actions_links_snapshot "lines/show" } + + %w(create update destroy).each do |p| + with_permission "lines.#{p}" do + it { should match_actions_links_snapshot "lines/show_#{p}" } + end + end end end diff --git a/spec/views/networks/__snapshots__/networks/index.snap b/spec/views/networks/__snapshots__/networks/index.snap new file mode 100644 index 000000000..2c5c23400 --- /dev/null +++ b/spec/views/networks/__snapshots__/networks/index.snap @@ -0,0 +1,4 @@ +<div class="container-fluid"><div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"></div></div> +</div></div>
\ No newline at end of file diff --git a/spec/views/networks/__snapshots__/networks/index_create.snap b/spec/views/networks/__snapshots__/networks/index_create.snap new file mode 100644 index 000000000..afd4aa41b --- /dev/null +++ b/spec/views/networks/__snapshots__/networks/index_create.snap @@ -0,0 +1,4 @@ +<div class="container-fluid"><div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><a class="btn btn-default" href="/line_referentials/99/networks/new">Ajouter un réseau</a></div></div> +</div></div>
\ No newline at end of file diff --git a/spec/views/networks/__snapshots__/networks/index_destroy.snap b/spec/views/networks/__snapshots__/networks/index_destroy.snap new file mode 100644 index 000000000..2c5c23400 --- /dev/null +++ b/spec/views/networks/__snapshots__/networks/index_destroy.snap @@ -0,0 +1,4 @@ +<div class="container-fluid"><div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"></div></div> +</div></div>
\ No newline at end of file diff --git a/spec/views/networks/__snapshots__/networks/index_update.snap b/spec/views/networks/__snapshots__/networks/index_update.snap new file mode 100644 index 000000000..2c5c23400 --- /dev/null +++ b/spec/views/networks/__snapshots__/networks/index_update.snap @@ -0,0 +1,4 @@ +<div class="container-fluid"><div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"></div></div> +</div></div>
\ No newline at end of file diff --git a/spec/views/networks/__snapshots__/networks/show.snap b/spec/views/networks/__snapshots__/networks/show.snap new file mode 100644 index 000000000..8f2992065 --- /dev/null +++ b/spec/views/networks/__snapshots__/networks/show.snap @@ -0,0 +1,4 @@ +<div class="container-fluid"><div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>Réseau Name</h1></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 23/01/2018 <br> Par web service</div></div></div> +</div></div>
\ No newline at end of file diff --git a/spec/views/networks/__snapshots__/networks/show_create.snap b/spec/views/networks/__snapshots__/networks/show_create.snap new file mode 100644 index 000000000..8f2992065 --- /dev/null +++ b/spec/views/networks/__snapshots__/networks/show_create.snap @@ -0,0 +1,4 @@ +<div class="container-fluid"><div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>Réseau Name</h1></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 23/01/2018 <br> Par web service</div></div></div> +</div></div>
\ No newline at end of file diff --git a/spec/views/networks/__snapshots__/networks/show_destroy.snap b/spec/views/networks/__snapshots__/networks/show_destroy.snap new file mode 100644 index 000000000..c525c05b7 --- /dev/null +++ b/spec/views/networks/__snapshots__/networks/show_destroy.snap @@ -0,0 +1,7 @@ +<div class="container-fluid"> +<div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>Réseau Name</h1></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 23/01/2018 <br> Par web service</div></div></div> +</div> +<div class="row mb-sm"><div class="col-lg-12 text-right"><a data-confirm="Etes vous sûr de supprimer ce réseau ?" class="btn btn-primary" rel="nofollow" data-method="delete" href="/line_referentials/99/networks/909"><span class="fa fa-trash mr-xs"></span>Supprimer ce réseau</a></div></div> +</div>
\ No newline at end of file diff --git a/spec/views/networks/__snapshots__/networks/show_update.snap b/spec/views/networks/__snapshots__/networks/show_update.snap new file mode 100644 index 000000000..35f8ee9ac --- /dev/null +++ b/spec/views/networks/__snapshots__/networks/show_update.snap @@ -0,0 +1,7 @@ +<div class="container-fluid"> +<div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>Réseau Name</h1></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 23/01/2018 <br> Par web service</div></div></div> +</div> +<div class="row mb-sm"><div class="col-lg-12 text-right"><a class="btn btn-primary" href="/line_referentials/99/networks/909/edit">Editer ce réseau</a></div></div> +</div>
\ No newline at end of file diff --git a/spec/views/networks/index.html.erb_spec.rb b/spec/views/networks/index.html.erb_spec.rb index d2dde7f87..80e755163 100644 --- a/spec/views/networks/index.html.erb_spec.rb +++ b/spec/views/networks/index.html.erb_spec.rb @@ -3,7 +3,11 @@ require 'spec_helper' describe "/networks/index", :type => :view do let!(:line_referential) { assign :line_referential, create(:line_referential) } - let!(:networks) { assign :networks, Array.new(2){ create(:network, line_referential: line_referential) }.paginate } + let(:context){{line_referential: line_referential}} + let!(:networks) do + assign :networks, build_paginated_collection(:network, NetworkDecorator, line_referential: line_referential, context: context) + end + let!(:search) { assign :q, Ransack::Search.new(Chouette::Network) } # it "should render a show link for each group" do @@ -18,5 +22,27 @@ describe "/networks/index", :type => :view do # render # expect(view.content_for(:sidebar)).to have_selector("a[href='#{new_line_referential_network_path(line_referential)}']") # end + before(:each) do + allow(view).to receive(:collection).and_return(networks) + allow(view).to receive(:decorated_collection).and_return(networks) + allow(view).to receive(:current_referential).and_return(line_referential) + controller.request.path_parameters[:line_referential_id] = line_referential.id + allow(view).to receive(:params).and_return({action: :index}) + end + + describe "action links" do + set_invariant "line_referential.id", "99" + + before(:each){ + render template: "networks/index", layout: "layouts/application" + } + + it { should match_actions_links_snapshot "networks/index" } + %w(create update destroy).each do |p| + with_permission "networks.#{p}" do + it { should match_actions_links_snapshot "networks/index_#{p}" } + end + end + end end diff --git a/spec/views/networks/show.html.erb_spec.rb b/spec/views/networks/show.html.erb_spec.rb index 3926ead14..998e8ac44 100644 --- a/spec/views/networks/show.html.erb_spec.rb +++ b/spec/views/networks/show.html.erb_spec.rb @@ -11,8 +11,30 @@ describe "/networks/show", :type => :view do let!(:map) { assign(:map, double(:to_html => '<div id="map"/>'.html_safe)) } let!(:line_referential) { assign :line_referential, network.line_referential } - # it "should display a map with class 'network'" do - # render - # expect(rendered).to have_selector("#map") - # end + before(:each) do + allow(view).to receive(:current_referential).and_return(line_referential) + allow(view).to receive(:resource).and_return(network) + controller.request.path_parameters[:line_referential_id] = line_referential.id + controller.request.path_parameters[:id] = network.id + allow(view).to receive(:params).and_return({action: :show}) + end + + describe "action links" do + set_invariant "line_referential.id", "99" + set_invariant "network.object.id", "909" + set_invariant "network.object.updated_at", "2018/01/23".to_time + set_invariant "network.object.name", "Name" + + before(:each){ + render template: "networks/show", layout: "layouts/application" + } + + it { should match_actions_links_snapshot "networks/show" } + + %w(create update destroy).each do |p| + with_permission "networks.#{p}" do + it { should match_actions_links_snapshot "networks/show_#{p}" } + end + end + end end diff --git a/spec/views/referentials/__snapshots__/referentials/show.snap b/spec/views/referentials/__snapshots__/referentials/show.snap new file mode 100644 index 000000000..83531ac0e --- /dev/null +++ b/spec/views/referentials/__snapshots__/referentials/show.snap @@ -0,0 +1,9 @@ +<div class="container-fluid"> +<div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 01/01/2000</div></div></div> +</div> +<div class="row mb-sm"><div class="col-lg-12 text-right"> +<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a> +</div></div> +</div>
\ No newline at end of file diff --git a/spec/views/referentials/__snapshots__/referentials/show_create.snap b/spec/views/referentials/__snapshots__/referentials/show_create.snap new file mode 100644 index 000000000..e5d309b96 --- /dev/null +++ b/spec/views/referentials/__snapshots__/referentials/show_create.snap @@ -0,0 +1,9 @@ +<div class="container-fluid"> +<div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 01/01/2000</div></div></div> +</div> +<div class="row mb-sm"><div class="col-lg-12 text-right"> +<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a><a class="btn btn-primary" href="/referentials/new?from=99">Dupliquer</a><a class="btn btn-primary" href="/referentials/99/select_compliance_control_set">Valider</a> +</div></div> +</div>
\ No newline at end of file diff --git a/spec/views/referentials/__snapshots__/referentials/show_destroy.snap b/spec/views/referentials/__snapshots__/referentials/show_destroy.snap new file mode 100644 index 000000000..d90198391 --- /dev/null +++ b/spec/views/referentials/__snapshots__/referentials/show_destroy.snap @@ -0,0 +1,9 @@ +<div class="container-fluid"> +<div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 01/01/2000</div></div></div> +</div> +<div class="row mb-sm"><div class="col-lg-12 text-right"> +<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a><a data-confirm="Etes vous sûr de vouloir supprimer ce jeu de données ?" class="btn btn-primary" rel="nofollow" data-method="delete" href="/referentials/99"><span class="fa fa-trash mr-xs"></span>Supprimer</a> +</div></div> +</div>
\ No newline at end of file diff --git a/spec/views/referentials/__snapshots__/referentials/show_purchase_windows.snap b/spec/views/referentials/__snapshots__/referentials/show_purchase_windows.snap new file mode 100644 index 000000000..83531ac0e --- /dev/null +++ b/spec/views/referentials/__snapshots__/referentials/show_purchase_windows.snap @@ -0,0 +1,9 @@ +<div class="container-fluid"> +<div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 01/01/2000</div></div></div> +</div> +<div class="row mb-sm"><div class="col-lg-12 text-right"> +<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a> +</div></div> +</div>
\ No newline at end of file diff --git a/spec/views/referentials/__snapshots__/referentials/show_purchase_windows_create.snap b/spec/views/referentials/__snapshots__/referentials/show_purchase_windows_create.snap new file mode 100644 index 000000000..e5d309b96 --- /dev/null +++ b/spec/views/referentials/__snapshots__/referentials/show_purchase_windows_create.snap @@ -0,0 +1,9 @@ +<div class="container-fluid"> +<div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 01/01/2000</div></div></div> +</div> +<div class="row mb-sm"><div class="col-lg-12 text-right"> +<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a><a class="btn btn-primary" href="/referentials/new?from=99">Dupliquer</a><a class="btn btn-primary" href="/referentials/99/select_compliance_control_set">Valider</a> +</div></div> +</div>
\ No newline at end of file diff --git a/spec/views/referentials/__snapshots__/referentials/show_purchase_windows_destroy.snap b/spec/views/referentials/__snapshots__/referentials/show_purchase_windows_destroy.snap new file mode 100644 index 000000000..d90198391 --- /dev/null +++ b/spec/views/referentials/__snapshots__/referentials/show_purchase_windows_destroy.snap @@ -0,0 +1,9 @@ +<div class="container-fluid"> +<div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 01/01/2000</div></div></div> +</div> +<div class="row mb-sm"><div class="col-lg-12 text-right"> +<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a><a data-confirm="Etes vous sûr de vouloir supprimer ce jeu de données ?" class="btn btn-primary" rel="nofollow" data-method="delete" href="/referentials/99"><span class="fa fa-trash mr-xs"></span>Supprimer</a> +</div></div> +</div>
\ No newline at end of file diff --git a/spec/views/referentials/__snapshots__/referentials/show_purchase_windows_update.snap b/spec/views/referentials/__snapshots__/referentials/show_purchase_windows_update.snap new file mode 100644 index 000000000..32d46beda --- /dev/null +++ b/spec/views/referentials/__snapshots__/referentials/show_purchase_windows_update.snap @@ -0,0 +1,12 @@ +<div class="container-fluid"> +<div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"> +<div class="small last-update">Dernière mise à jour le 01/01/2000</div> +<a class="btn btn-default" href="/referentials/99/edit">Editer</a> +</div></div> +</div> +<div class="row mb-sm"><div class="col-lg-12 text-right"> +<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a><a class="btn btn-primary" rel="nofollow" data-method="put" href="/referentials/99/archive">Conserver</a><button type="button" data-toggle="modal" data-target="#purgeModal" class="btn btn-primary">Purger</button> +</div></div> +</div>
\ No newline at end of file diff --git a/spec/views/referentials/__snapshots__/referentials/show_readonly.snap b/spec/views/referentials/__snapshots__/referentials/show_readonly.snap new file mode 100644 index 000000000..83531ac0e --- /dev/null +++ b/spec/views/referentials/__snapshots__/referentials/show_readonly.snap @@ -0,0 +1,9 @@ +<div class="container-fluid"> +<div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 01/01/2000</div></div></div> +</div> +<div class="row mb-sm"><div class="col-lg-12 text-right"> +<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a> +</div></div> +</div>
\ No newline at end of file diff --git a/spec/views/referentials/__snapshots__/referentials/show_readonly_create.snap b/spec/views/referentials/__snapshots__/referentials/show_readonly_create.snap new file mode 100644 index 000000000..82a77521a --- /dev/null +++ b/spec/views/referentials/__snapshots__/referentials/show_readonly_create.snap @@ -0,0 +1,9 @@ +<div class="container-fluid"> +<div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 01/01/2000</div></div></div> +</div> +<div class="row mb-sm"><div class="col-lg-12 text-right"> +<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a><a class="btn btn-primary" href="/referentials/new?from=99">Dupliquer</a> +</div></div> +</div>
\ No newline at end of file diff --git a/spec/views/referentials/__snapshots__/referentials/show_readonly_destroy.snap b/spec/views/referentials/__snapshots__/referentials/show_readonly_destroy.snap new file mode 100644 index 000000000..83531ac0e --- /dev/null +++ b/spec/views/referentials/__snapshots__/referentials/show_readonly_destroy.snap @@ -0,0 +1,9 @@ +<div class="container-fluid"> +<div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 01/01/2000</div></div></div> +</div> +<div class="row mb-sm"><div class="col-lg-12 text-right"> +<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a> +</div></div> +</div>
\ No newline at end of file diff --git a/spec/views/referentials/__snapshots__/referentials/show_readonly_update.snap b/spec/views/referentials/__snapshots__/referentials/show_readonly_update.snap new file mode 100644 index 000000000..83531ac0e --- /dev/null +++ b/spec/views/referentials/__snapshots__/referentials/show_readonly_update.snap @@ -0,0 +1,9 @@ +<div class="container-fluid"> +<div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 01/01/2000</div></div></div> +</div> +<div class="row mb-sm"><div class="col-lg-12 text-right"> +<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a> +</div></div> +</div>
\ No newline at end of file diff --git a/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys.snap b/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys.snap new file mode 100644 index 000000000..83531ac0e --- /dev/null +++ b/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys.snap @@ -0,0 +1,9 @@ +<div class="container-fluid"> +<div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 01/01/2000</div></div></div> +</div> +<div class="row mb-sm"><div class="col-lg-12 text-right"> +<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a> +</div></div> +</div>
\ No newline at end of file diff --git a/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_create.snap b/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_create.snap new file mode 100644 index 000000000..e5d309b96 --- /dev/null +++ b/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_create.snap @@ -0,0 +1,9 @@ +<div class="container-fluid"> +<div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 01/01/2000</div></div></div> +</div> +<div class="row mb-sm"><div class="col-lg-12 text-right"> +<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a><a class="btn btn-primary" href="/referentials/new?from=99">Dupliquer</a><a class="btn btn-primary" href="/referentials/99/select_compliance_control_set">Valider</a> +</div></div> +</div>
\ No newline at end of file diff --git a/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_destroy.snap b/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_destroy.snap new file mode 100644 index 000000000..d90198391 --- /dev/null +++ b/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_destroy.snap @@ -0,0 +1,9 @@ +<div class="container-fluid"> +<div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"><div class="small last-update">Dernière mise à jour le 01/01/2000</div></div></div> +</div> +<div class="row mb-sm"><div class="col-lg-12 text-right"> +<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a><a data-confirm="Etes vous sûr de vouloir supprimer ce jeu de données ?" class="btn btn-primary" rel="nofollow" data-method="delete" href="/referentials/99"><span class="fa fa-trash mr-xs"></span>Supprimer</a> +</div></div> +</div>
\ No newline at end of file diff --git a/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_update.snap b/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_update.snap new file mode 100644 index 000000000..32d46beda --- /dev/null +++ b/spec/views/referentials/__snapshots__/referentials/show_referential_vehicle_journeys_update.snap @@ -0,0 +1,12 @@ +<div class="container-fluid"> +<div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"> +<div class="small last-update">Dernière mise à jour le 01/01/2000</div> +<a class="btn btn-default" href="/referentials/99/edit">Editer</a> +</div></div> +</div> +<div class="row mb-sm"><div class="col-lg-12 text-right"> +<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a><a class="btn btn-primary" rel="nofollow" data-method="put" href="/referentials/99/archive">Conserver</a><button type="button" data-toggle="modal" data-target="#purgeModal" class="btn btn-primary">Purger</button> +</div></div> +</div>
\ No newline at end of file diff --git a/spec/views/referentials/__snapshots__/referentials/show_update.snap b/spec/views/referentials/__snapshots__/referentials/show_update.snap new file mode 100644 index 000000000..32d46beda --- /dev/null +++ b/spec/views/referentials/__snapshots__/referentials/show_update.snap @@ -0,0 +1,12 @@ +<div class="container-fluid"> +<div class="row"> +<div class="col-lg-9 col-md-8 col-sm-7 col-xs-7"><div class="page-title"><h1>referential_full_name</h1></div></div> +<div class="col-lg-3 col-md-4 col-sm-5 col-xs-5 text-right"><div class="page-action"> +<div class="small last-update">Dernière mise à jour le 01/01/2000</div> +<a class="btn btn-default" href="/referentials/99/edit">Editer</a> +</div></div> +</div> +<div class="row mb-sm"><div class="col-lg-12 text-right"> +<a class="btn btn-primary" href="/referentials/99/vehicle_journeys">Courses</a><a class="btn btn-primary" href="/referentials/99/purchase_windows">Calendriers commerciaux</a><a class="btn btn-primary" href="/referentials/99/time_tables">Calendriers</a><a class="btn btn-primary" rel="nofollow" data-method="put" href="/referentials/99/archive">Conserver</a><button type="button" data-toggle="modal" data-target="#purgeModal" class="btn btn-primary">Purger</button> +</div></div> +</div>
\ No newline at end of file diff --git a/spec/views/referentials/show.html.erb_spec.rb b/spec/views/referentials/show.html.erb_spec.rb index 4a2afe2ca..ea3bc1fe1 100644 --- a/spec/views/referentials/show.html.erb_spec.rb +++ b/spec/views/referentials/show.html.erb_spec.rb @@ -1,22 +1,23 @@ require 'spec_helper' describe "referentials/show", type: :view do - let!(:referential) do - referential = create(:referential) + referential = create(:referential, organisation: organisation) assign :referential, referential.decorate(context: { current_organisation: referential.organisation }) end let(:permissions){ [] } let(:current_organisation) { organisation } - let(:current_offer_workbench) { create :workbench, organisation: current_organisation} + let(:current_offer_workbench) { create :workbench, organisation: organisation} + let(:current_workgroup) { current_offer_workbench.workgroup } let(:readonly){ false } before :each do assign :reflines, [] allow(view).to receive(:current_offer_workbench).and_return(current_offer_workbench) allow(view).to receive(:current_organisation).and_return(current_organisation) + allow(view).to receive(:current_workgroup).and_return(current_workgroup) allow(view).to receive(:current_user).and_return(current_user) allow(view).to receive(:resource).and_return(referential) @@ -26,24 +27,47 @@ describe "referentials/show", type: :view do allow(view).to receive(:params).and_return({action: :show}) allow(referential).to receive(:referential_read_only?){ readonly } - render template: "referentials/show", layout: "layouts/application" - end - - it "should not present edit button" do - expect(rendered).to_not have_selector("a[href=\"#{view.edit_referential_path(referential)}\"]") end - with_permission "referentials.update" do - it "should present edit button" do - expect(rendered).to have_selector("a[href=\"#{view.edit_referential_path(referential)}\"]") - end + describe "action links" do + set_invariant "referential.object.full_name", "referential_full_name" + set_invariant "referential.object.updated_at", "01/01/2000 00:00".to_time + set_invariant "referential.object.id", "99" + before(:each){ + render template: "referentials/show", layout: "layouts/application" + } context "with a readonly referential" do let(:readonly){ true } - it "should not present edit button" do - expect(rendered).to_not have_selector("a[href=\"#{view.edit_referential_path(referential)}\"]") + it { should match_actions_links_snapshot "referentials/show_readonly" } + + %w(create destroy update).each do |p| + with_permission "referentials.#{p}" do + it { should match_actions_links_snapshot "referentials/show_readonly_#{p}" } + end end end - end + context "with a non-readonly referential" do + it { should match_actions_links_snapshot "referentials/show" } + + %w(create destroy update).each do |p| + with_permission "referentials.#{p}" do + it { should match_actions_links_snapshot "referentials/show_#{p}" } + end + end + end + + %w(purchase_windows referential_vehicle_journeys).each do |f| + with_feature f do + it { should match_actions_links_snapshot "referentials/show_#{f}" } + + %w(create update destroy).each do |p| + with_permission "referentials.#{p}" do + it { should match_actions_links_snapshot "referentials/show_#{f}_#{p}" } + end + end + end + end + end end |
