diff options
32 files changed, 432 insertions, 136 deletions
diff --git a/app/controllers/compliance_control_sets_controller.rb b/app/controllers/compliance_control_sets_controller.rb index f6002956b..cff67d5cb 100644 --- a/app/controllers/compliance_control_sets_controller.rb +++ b/app/controllers/compliance_control_sets_controller.rb @@ -17,8 +17,12 @@ class ComplianceControlSetsController < InheritedResources::Base def show show! do |format| format.html { + @q_controls_form = @compliance_control_set.compliance_controls.ransack(params[:q]) @compliance_control_set = @compliance_control_set.decorate - @compliance_controls_without_block = decorate_compliance_controls(@compliance_control_set.compliance_controls.where(compliance_control_block_id: nil)) + @compliance_controls = + decorate_compliance_controls( @q_controls_form.result) + .group_by(&:compliance_control_block) + @indirect_compliance_controls = @compliance_controls.delete nil } end end @@ -58,4 +62,4 @@ class ComplianceControlSetsController < InheritedResources::Base def compliance_control_set_params params.require(:compliance_control_set).permit(:name, :id) end -end
\ No newline at end of file +end diff --git a/app/controllers/stop_areas_controller.rb b/app/controllers/stop_areas_controller.rb index 0c9f3067a..1d6f88068 100644 --- a/app/controllers/stop_areas_controller.rb +++ b/app/controllers/stop_areas_controller.rb @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- class StopAreasController < InheritedResources::Base include ApplicationHelper diff --git a/app/helpers/compliance_control_blocks_helper.rb b/app/helpers/compliance_control_blocks_helper.rb index 09e22d6e9..311e6fb46 100644 --- a/app/helpers/compliance_control_blocks_helper.rb +++ b/app/helpers/compliance_control_blocks_helper.rb @@ -1,10 +1,10 @@ module ComplianceControlBlocksHelper def transport_mode(transport_mode, transport_submode) - if (transport_mode) && (transport_submode) != "" - transportMode = "[" + t("enumerize.transport_mode.#{transport_mode}") + "]" + "[" + t("enumerize.transport_submode.#{transport_submode}") + "]" + return "[Tous les modes de transport]" if transport_mode == "" + if transport_submode == "" + "[" + t("enumerize.transport_mode.#{transport_mode}") + "]" else - transportMode = "[Tous les modes de transport]" + "[" + t("enumerize.transport_mode.#{transport_mode}") + "]" + "[" + t("enumerize.transport_submode.#{transport_submode}") + "]" end - transportMode end -end
\ No newline at end of file +end diff --git a/app/helpers/compliance_controls_helper.rb b/app/helpers/compliance_controls_helper.rb new file mode 100644 index 000000000..ba0c538c9 --- /dev/null +++ b/app/helpers/compliance_controls_helper.rb @@ -0,0 +1,11 @@ +module ComplianceControlsHelper + def subclass_selection_list + ComplianceControl.subclass_patterns.map(&method(:make_subclass_selection_item)) + end + + + def make_subclass_selection_item(key_pattern) + key, pattern = key_pattern + [t("compliance_controls.filters.subclasses.#{key}"), "-#{pattern}-"] + end +end diff --git a/app/helpers/table_builder_helper.rb b/app/helpers/table_builder_helper.rb index 95f53a90d..37f01ce0d 100644 --- a/app/helpers/table_builder_helper.rb +++ b/app/helpers/table_builder_helper.rb @@ -83,17 +83,21 @@ module TableBuilderHelper cls: '', # A set of content, over the th line... - overhead: [] + overhead: [], + + # Possibility to override the result of collection.model + model: nil + ) content_tag :table, - thead(collection, columns, sortable, selectable, links.any?, overhead) + + thead(collection, columns, sortable, selectable, links.any?, overhead, model || collection.model) + tbody(collection, columns, selectable, links, overhead), class: cls end private - def thead(collection, columns, sortable, selectable, has_links, overhead) + def thead(collection, columns, sortable, selectable, has_links, overhead, model ) content_tag :thead do # Inserts overhead content if any specified over_head = '' @@ -121,7 +125,7 @@ module TableBuilderHelper hcont << content_tag(:th, build_column_header( column, sortable, - collection.model, + model, params, params[:sort], params[:direction] @@ -137,7 +141,7 @@ module TableBuilderHelper hcont << content_tag(:th, build_column_header( column, sortable, - collection.model, + model, params, params[:sort], params[:direction] @@ -147,7 +151,7 @@ module TableBuilderHelper hcont << content_tag(:th, build_column_header( column, sortable, - collection.model, + model, params, params[:sort], params[:direction] @@ -160,7 +164,7 @@ module TableBuilderHelper hcont << content_tag(:th, build_column_header( column, sortable, - collection.model, + model, params, params[:sort], params[:direction] @@ -299,14 +303,14 @@ module TableBuilderHelper def build_column_header( column, table_is_sortable, - collection_model, + model, params, sort_on, sort_direction ) if !table_is_sortable || !column.sortable - return column.header_label(collection_model) + return column.header_label(model) end direction = @@ -331,7 +335,7 @@ module TableBuilderHelper arrow_icons = content_tag :span, arrow_up + arrow_down, class: 'orderers' ( - column.header_label(collection_model) + + column.header_label(model) + arrow_icons ).html_safe end diff --git a/app/models/compliance_control.rb b/app/models/compliance_control.rb index 08efa7e9a..49fb6513f 100644 --- a/app/models/compliance_control.rb +++ b/app/models/compliance_control.rb @@ -1,29 +1,7 @@ class ComplianceControl < ActiveRecord::Base - extend Enumerize - belongs_to :compliance_control_set - belongs_to :compliance_control_block - - enumerize :criticity, in: %i(warning error), scope: true, default: :warning - hstore_accessor :control_attributes, {} - - validates :criticity, presence: true - validates :name, presence: true - validates :code, presence: true, uniqueness: { scope: :compliance_control_set } - validates :origin_code, presence: true - validates :compliance_control_set, presence: true - - validate def coherent_control_set - return true if compliance_control_block_id.nil? - ids = [compliance_control_block.compliance_control_set_id, compliance_control_set_id] - return true if ids.first == ids.last - names = ids.map{|id| ComplianceControlSet.find(id).name} - errors.add(:coherent_control_set, - I18n.t('compliance_controls.errors.incoherent_control_sets', - indirect_set_name: names.first, - direct_set_name: names.last)) - end class << self + def criticities; %i(warning error) end def default_code; "" end def dynamic_attributes hstore_metadata_for_control_attributes.keys @@ -33,6 +11,17 @@ class ComplianceControl < ActiveRecord::Base ComplianceControlPolicy end + def subclass_patterns + { + generic: 'Generic', + journey_pattern: 'JourneyPattern', + line: 'Line', + route: 'Route', + routing_constraint_zone: 'RoutingConstraint', + vehicle_journey: 'VehicleJourney' + } + end + def inherited(child) child.instance_eval do def model_name @@ -43,12 +32,37 @@ class ComplianceControl < ActiveRecord::Base end end - def initialize(attributes = {}) - super - self.name ||= I18n.t("activerecord.models.#{self.class.name.underscore}.one") - self.code ||= self.class.default_code - self.origin_code ||= self.class.default_code - end + extend Enumerize + belongs_to :compliance_control_set + belongs_to :compliance_control_block + + enumerize :criticity, in: criticities, scope: true, default: :warning + hstore_accessor :control_attributes, {} + + validates :criticity, presence: true + validates :name, presence: true + validates :code, presence: true, uniqueness: { scope: :compliance_control_set } + validates :origin_code, presence: true + validates :compliance_control_set, presence: true + + validate def coherent_control_set + return true if compliance_control_block_id.nil? + ids = [compliance_control_block.compliance_control_set_id, compliance_control_set_id] + return true if ids.first == ids.last + names = ids.map{|id| ComplianceControlSet.find(id).name} + errors.add(:coherent_control_set, + I18n.t('compliance_controls.errors.incoherent_control_sets', + indirect_set_name: names.first, + direct_set_name: names.last)) +end + + +def initialize(attributes = {}) + super + self.name ||= I18n.t("activerecord.models.#{self.class.name.underscore}.one") + self.code ||= self.class.default_code + self.origin_code ||= self.class.default_code +end end diff --git a/app/models/import.rb b/app/models/import.rb index e0aae6ef1..20e7f2d8a 100644 --- a/app/models/import.rb +++ b/app/models/import.rb @@ -16,9 +16,10 @@ class Import < ActiveRecord::Base extend Enumerize enumerize :status, in: %i(new pending successful warning failed running aborted canceled), scope: true, default: :new + validates :name, presence: true validates :file, presence: true validates_presence_of :workbench, :creator - validates_format_of :file, with: %r{\.zip\z}i, message: I18n.t('activerecord.errors.models.imports.wrong_file_extension') + validates_format_of :file, with: %r{\.zip\z}i, message: I18n.t('activerecord.errors.models.import.attributes.file.wrong_file_extension') before_create :initialize_fields diff --git a/app/views/compliance_control_sets/show.html.slim b/app/views/compliance_control_sets/show.html.slim index cf236feb8..294df6a53 100644 --- a/app/views/compliance_control_sets/show.html.slim +++ b/app/views/compliance_control_sets/show.html.slim @@ -24,54 +24,21 @@ .col-lg-6.col-md-6.col-sm-12.col-xs-12 = definition_list t('metadatas'), ComplianceControlSet.human_attribute_name(:name) => @compliance_control_set.name + - if params[:q].present? or @compliance_controls.any? + .row + .col-lg-12 + = render '/compliance_controls/filters' + .row .col-lg-12 h2 = transport_mode("", "") - .row - .col-lg-12 - .select_table - = table_builder_2 @compliance_controls_without_block, - [ \ - TableBuilderHelper::Column.new( \ - key: :code, \ - attribute: 'code' \ - ), \ - TableBuilderHelper::Column.new( \ - key: :name, \ - attribute: 'name', \ - link_to: lambda do |compliance_control| \ - compliance_control_set_compliance_control_path(@compliance_control_set, compliance_control) \ - end \ - ), \ - TableBuilderHelper::Column.new( \ - key: :criticity, \ - attribute: 'criticity' \ - ), \ - TableBuilderHelper::Column.new( \ - key: :comment, \ - attribute: 'comment' \ - ), \ - ], - sortable: true, - cls: 'table has-filter has-search' - - @compliance_control_set.compliance_control_blocks.each do |block| - .row - .col-lg-12 - h2 - = transport_mode(block.transport_mode, block.transport_submode) - .btn-group - .btn.dropdown-toggle{ data-toggle="dropdown" } - .span.fa.fa-cog - ul.dropdown-menu - li - = link_to t('compliance_control_sets.actions.edit'), edit_compliance_control_set_compliance_control_block_path(@compliance_control_set.id, block.id) - = link_to t('compliance_control_sets.actions.destroy'), compliance_control_set_compliance_control_block_path(@compliance_control_set.id, block.id), :method => :delete, :data => {:confirm => t('compliance_control_sets.actions.destroy_confirm')} + - if @indirect_compliance_controls.try(:any?) .row .col-lg-12 .select_table - = table_builder_2 ModelDecorator.decorate(block.compliance_controls, with: ComplianceControlDecorator), + = table_builder_2 @indirect_compliance_controls, [ \ TableBuilderHelper::Column.new( \ key: :code, \ @@ -94,7 +61,52 @@ ), \ ], sortable: true, - cls: 'table has-filter has-search' + cls: 'table has-filter has-search', + model: ComplianceControl + + - @compliance_controls.each do |block, compliance_controls| + + - if compliance_controls.try(:any?) + .row + .col-lg-12 + h2 + = transport_mode(block.transport_mode, block.transport_submode) + .btn-group + .btn.dropdown-toggle{ data-toggle="dropdown" } + .span.fa.fa-cog + ul.dropdown-menu + li + = link_to t('compliance_control_sets.actions.edit'), edit_compliance_control_set_compliance_control_block_path(@compliance_control_set.id, block.id) + = link_to t('compliance_control_sets.actions.destroy'), compliance_control_set_compliance_control_block_path(@compliance_control_set.id, block.id), :method => :delete, :data => {:confirm => t('compliance_control_sets.actions.destroy_confirm')} + .row + .col-lg-12 + .select_table + = table_builder_2 compliance_controls, + [ \ + TableBuilderHelper::Column.new( \ + key: :code, \ + attribute: 'code' \ + ), \ + TableBuilderHelper::Column.new( \ + key: :name, \ + attribute: 'name', \ + link_to: lambda do |compliance_control| \ + compliance_control_set_compliance_control_path(@compliance_control_set, compliance_control) \ + end \ + ), \ + TableBuilderHelper::Column.new( \ + key: :criticity, \ + attribute: 'criticity' \ + ), \ + TableBuilderHelper::Column.new( \ + key: :comment, \ + attribute: 'comment' \ + ), \ + ], + sortable: true, + cls: 'table has-filter has-search', + model: ComplianceControl + .select_toolbox ul li.st_action.with_text diff --git a/app/views/compliance_controls/_filters.html.slim b/app/views/compliance_controls/_filters.html.slim new file mode 100644 index 000000000..c729190a0 --- /dev/null +++ b/app/views/compliance_controls/_filters.html.slim @@ -0,0 +1,46 @@ += search_form_for @q_controls_form, + url: compliance_control_set_path(@compliance_control_set), + builder: SimpleForm::FormBuilder, + class: 'form form-filter' do |f| + + .ffg-row + .input-group.search_bar + = f.search_field :name_cont, + class: 'form-control', + placeholder: t('compliance_controls.filters.name') + span.input-group-btn + button.btn.btn-default type='submit' + span.fa.fa-search + + .ffg-row + .form-group.togglable#compliance_control_block-filter + = f.label t('activerecord.models.compliance_control_block.one'), required: false, class: 'control-label' + = f.input :compliance_control_block_id_eq_any, + collection: @compliance_control_set.compliance_control_blocks, + as: :check_boxes, + label: false, + label_method: lambda {|w| ("<span>#{transport_mode(w.transport_mode, w.transport_submode)}</span>").html_safe}, + required: false, + wrapper_html: {class: 'checkbox_list'} + .form-group.togglable#subclass-filter + = f.label t('compliance_controls.filters.subclass'), required: false, class: 'control-label' + = f.input :origin_code_cont_any, + collection: subclass_selection_list, + as: :check_boxes, + label: false, + label_method: lambda {|w| ("<span>#{w.first}</span>").html_safe}, + required: false, + wrapper_html: {class: 'checkbox_list'} + .form-group.togglable#severity-filter + = f.label t('compliance_controls.filters.criticity'), required: false, class: 'control-label' + = f.input :criticity_eq_any, + collection: ComplianceControl.criticities, + as: :check_boxes, + label: false, + label_method: lambda {|w| ("<span>#{w}</span>").html_safe}, + required: false, + wrapper_html: {class: 'checkbox_list'} + + .actions + = link_to t('actions.erase'), @compliance_control_set, class: 'btn btn-link' + = f.submit t('actions.filter'), class: 'btn btn-default', id: 'compliance_control_set_compliance_controls_filter_btn' diff --git a/app/views/layouts/navigation/_main_nav_left.html.slim b/app/views/layouts/navigation/_main_nav_left.html.slim index 062c9383c..837b9cb73 100644 --- a/app/views/layouts/navigation/_main_nav_left.html.slim +++ b/app/views/layouts/navigation/_main_nav_left.html.slim @@ -31,16 +31,17 @@ #miTwo.panel-collapse.collapse .list-group - = link_to workbench_path(current_offer_workbench), class: "list-group-item #{params[:controller] == 'workbenches' ? 'active' : ''}" do - 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 - 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 - = link_to compliance_control_sets_path, class: 'list-group-item' do - span Jeux de contrôle + - if current_user + = link_to workbench_path(current_offer_workbench), class: "list-group-item #{params[:controller] == 'workbenches' ? 'active' : ''}" do + 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 + 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 + = link_to compliance_control_sets_path, class: 'list-group-item' do + span Jeux de contrôle .menu-item.panel .panel-heading diff --git a/app/workers/compliance_control_set_copy_worker.rb b/app/workers/compliance_control_set_copy_worker.rb new file mode 100644 index 000000000..d18bb0c88 --- /dev/null +++ b/app/workers/compliance_control_set_copy_worker.rb @@ -0,0 +1,14 @@ +class ComplianceControlSetCopyWorker + include Sidekiq::Worker + + def perform(control_set_id, referential_id) + check_set = ComplianceControlSetCopier.new.copy(control_set_id, referential_id) + + begin + Net::HTTP.get(URI("#{Rails.configuration.iev_url}/boiv_iev/referentials/validator/new?id=#{check_set.id}")) + rescue Exception => e + logger.error "IEV server error : #{e.message}" + logger.error e.backtrace.inspect + end + end +end diff --git a/app/workers/workbench_import_worker.rb b/app/workers/workbench_import_worker.rb index 300fad9e2..de51efded 100644 --- a/app/workers/workbench_import_worker.rb +++ b/app/workers/workbench_import_worker.rb @@ -35,7 +35,7 @@ class WorkbenchImportWorker end def handle_corrupt_zip_file - @workbench_import.messages.create(criticity: :error, message_key: 'corrupt_zip_file', message_attributes: {import_name: @workbench_import.name}) + @workbench_import.messages.create(criticity: :error, message_key: 'corrupt_zip_file', message_attributes: {source_filename: @workbench_import.file.file.file}) end def upload zip_service @@ -55,8 +55,8 @@ class WorkbenchImportWorker criticity: :warning, message_key: 'inconsistent_zip_file', message_attributes: { - 'import_name' => @workbench_import.name, - 'spurious_dirs' => entry.spurious.join(', ') + 'source_filename' => @workbench_import.file.file.file, + 'spurious_dirs' => entry.spurious.join(', ') }) end end diff --git a/config/environments/test.rb b/config/environments/test.rb index b3312be4a..8bf94f5da 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -62,6 +62,9 @@ Rails.application.configure do # Reflex api url config.reflex_api_url = "https://195.46.215.128/ws/reflex/V1/service=getData" + # IEV url + config.iev_url = ENV.fetch('IEV_URL', 'http://localhost:8080') + config.rails_host = "http://www.example.com" # file to data for demo config.demo_data = "tmp/demo.zip" diff --git a/config/locales/compliance_controls.en.yml b/config/locales/compliance_controls.en.yml index 887bc2009..41971d9e9 100644 --- a/config/locales/compliance_controls.en.yml +++ b/config/locales/compliance_controls.en.yml @@ -2,6 +2,17 @@ en: compliance_controls: clone: prefix: 'Copy of' + filters: + criticity: Severity + name: "Search by a control's name or code" + subclass: Object + subclasses: + generic: 'Generic' + journey_pattern: 'JourneyPattern' + line: 'Line' + route: 'Route' + routing_constraint_zone: 'RoutingConstraint' + vehicle_journey: 'VehicleJourney' min_max_values: "the minimum (%{min}) is not supposed to be greater than the maximum (%{max})" errors: incoherent_control_sets: "Impossible to assign a control to a set (id: %{direct_set_name}) differing from the one of its group (id: %{indirect_set_name})" @@ -179,4 +190,4 @@ en: compliance_control_block: "Control Block" minimum: "Minimum" maximum: "Maximum" - target: "Target"
\ No newline at end of file + target: "Target" diff --git a/config/locales/compliance_controls.fr.yml b/config/locales/compliance_controls.fr.yml index 2feb201bf..3fa83a147 100644 --- a/config/locales/compliance_controls.fr.yml +++ b/config/locales/compliance_controls.fr.yml @@ -2,6 +2,17 @@ fr: compliance_controls: clone: prefix: 'Copie de' + filters: + criticity: Criticité + name: "Chercher le nom ou code d'un contrôl" + subclass: Objet + subclasses: + generic: 'Généric' + journey_pattern: 'JourneyPattern' + line: 'Ligne' + route: 'Itinéraire' + routing_constraint_zone: 'ITL' + vehicle_journey: 'Course' min_max_values: "la valeur de minimum (%{min}) ne doit pas être superieur à la valuer du maximum (%{max})" errors: incoherent_control_sets: "Le contrôle ne peut pas être associé à un jeu de contrôle (id: %{direct_set_name}) différent de celui de son groupe (id: %{indirect_set_name})" @@ -119,7 +130,7 @@ fr: activerecord: models: compliance_control: - one: "controle" + one: "contrôle" other: "contrôles" route_control/zdl_stop_area: one: "Deux arrêts d’une même ZDL ne peuvent pas se succéder dans un itinéraire" @@ -130,7 +141,7 @@ fr: route_control/duplicates: one: "Détection de double définition d'itinéraire" route_control/opposite_route_terminus: - one: "Vérification des terminus de l'itinéraire inverse" + one: "Vérification des terminus de l'itinéraire inverse" route_control/minimum_length: one: "Un itinéraire doit contenir au moins 2 arrêts" route_control/omnibus_journey_pattern: @@ -179,4 +190,4 @@ fr: compliance_control_block: "Groupe de contrôle" minimum: "Minimum" maximum: "Maximum" - target: "Cible"
\ No newline at end of file + target: "Cible" diff --git a/config/locales/import_messages.en.yml b/config/locales/import_messages.en.yml index 2048b9794..bf6b45020 100644 --- a/config/locales/import_messages.en.yml +++ b/config/locales/import_messages.en.yml @@ -1,8 +1,8 @@ en: import_messages: compliance_check_messages: - corrupt_zip_file: "The zip file of WorkbenchImport %{import_name} is corrupted and cannot be read" - inconsistent_zip_file: "The zip file of WorkbenchImport %{import_name} contains the following spurious directories %{spurious_dirs}, which are ignored" + corrupt_zip_file: "The zip file %{source_filename} is corrupted and cannot be read" + inconsistent_zip_file: "The zip file %{source_filename} contains unexpected directories: %{spurious_dirs}, which are ignored" referential_creation: "Le référentiel n'a pas pu être créé car un référentiel existe déjà sur les même périodes et lignes" 1_netexstif_2: "Le fichier %{source_filename} ne respecte pas la syntaxe XML ou la XSD NeTEx : erreur '%{error_value}' rencontré" 1_netexstif_5: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet %{source_label} d'identifiant %{source_objectid} a une date de mise à jour dans le futur" diff --git a/config/locales/import_messages.fr.yml b/config/locales/import_messages.fr.yml index 9f0af1faa..7d3bbf23b 100644 --- a/config/locales/import_messages.fr.yml +++ b/config/locales/import_messages.fr.yml @@ -1,8 +1,8 @@ fr: import_messages: compliance_check_messages: - corrupt_zip_file: "Le fichier zip du WorkbenchImport %{import_name} est corrompu, et ne peut être lu" - inconsistent_zip_file: "Le fichier zip du WorkbenchImport %{import_name} contient les repertoirs illegeaux %{spurious_dirs} qui seront ignorés" + corrupt_zip_file: "Le fichier zip %{source_filename} est corrompu, et ne peut être lu" + inconsistent_zip_file: "Le fichier zip %{source_filename} contient des repertoires non prévus : %{spurious_dirs} qui seront ignorés" referential_creation: "Le référentiel n'a pas pu être créé car un référentiel existe déjà sur les même périodes et lignes" 1_netexstif_2: "Le fichier %{source_filename} ne respecte pas la syntaxe XML ou la XSD NeTEx : erreur '%{error_value}' rencontré" 1_netexstif_5: "%{source_filename}-Ligne %{source_line_number}-Colonne %{source_column_number} : l'objet %{source_label} d'identifiant %{source_objectid} a une date de mise à jour dans le futur" diff --git a/config/locales/imports.en.yml b/config/locales/imports.en.yml index f3bcad9e9..10434dd19 100644 --- a/config/locales/imports.en.yml +++ b/config/locales/imports.en.yml @@ -55,8 +55,10 @@ en: other: "imports" errors: models: - imports: - wrong_file_extension: "The imported file must be a zip file" + import: + attributes: + file: + wrong_file_extension: "The imported file must be a zip file" attributes: import: resources: "File to import" diff --git a/config/locales/imports.fr.yml b/config/locales/imports.fr.yml index 6e74fa33c..099488a6b 100644 --- a/config/locales/imports.fr.yml +++ b/config/locales/imports.fr.yml @@ -55,8 +55,10 @@ fr: other: "imports" errors: models: - imports: - wrong_file_extension: "Le fichier importé doit être au format zip" + import: + attributes: + file: + wrong_file_extension: "Le fichier importé doit être au format zip" attributes: import: resources: "Fichier à importer" diff --git a/config/routes.rb b/config/routes.rb index 214b12584..30ba51358 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -74,6 +74,7 @@ ChouetteIhm::Application.routes.draw do resources :api_keys, :only => [:edit, :update, :new, :create, :destroy] resources :compliance_control_sets do + get :simple, on: :member get :clone, on: :member get :select_compliance_control_set resources :compliance_controls, except: :index do diff --git a/db/schema.rb b/db/schema.rb index a64a426de..dd9461c78 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -284,6 +284,22 @@ ActiveRecord::Schema.define(version: 20171016074044) do add_index "connection_links", ["objectid"], name: "connection_links_objectid_key", unique: true, using: :btree + create_table "delayed_jobs", id: :bigserial, force: :cascade do |t| + t.integer "priority", default: 0 + t.integer "attempts", default: 0 + t.text "handler" + t.text "last_error" + t.datetime "run_at" + t.datetime "locked_at" + t.datetime "failed_at" + t.string "locked_by", limit: 255 + t.string "queue", limit: 255 + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "delayed_jobs", ["priority", "run_at"], name: "delayed_jobs_priority", using: :btree + create_table "exports", id: :bigserial, force: :cascade do |t| t.integer "referential_id", limit: 8 t.string "status" @@ -405,12 +421,12 @@ ActiveRecord::Schema.define(version: 20171016074044) do t.datetime "started_at" t.datetime "ended_at" t.string "token_download" - t.string "type" + t.string "type", limit: 255 t.integer "parent_id", limit: 8 t.string "parent_type" + t.integer "current_step", default: 0 + t.integer "total_steps", default: 0 t.datetime "notified_parent_at" - t.integer "current_step", default: 0 - t.integer "total_steps", default: 0 t.string "creator" end @@ -562,6 +578,11 @@ ActiveRecord::Schema.define(version: 20171016074044) do add_index "networks", ["objectid"], name: "networks_objectid_key", unique: true, using: :btree add_index "networks", ["registration_number"], name: "networks_registration_number_key", using: :btree + create_table "object_id_factories", id: :bigserial, force: :cascade do |t| + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + create_table "organisations", id: :bigserial, force: :cascade do |t| t.string "name" t.datetime "created_at" @@ -750,7 +771,7 @@ ActiveRecord::Schema.define(version: 20171016074044) do create_table "stop_areas", id: :bigserial, force: :cascade do |t| t.integer "parent_id", limit: 8 - t.string "objectid", null: false + t.string "objectid", null: false t.integer "object_version", limit: 8 t.string "creator_id" t.string "name" @@ -759,8 +780,8 @@ ActiveRecord::Schema.define(version: 20171016074044) do t.string "registration_number" t.string "nearest_topic_name" t.integer "fare_code" - t.decimal "longitude", precision: 19, scale: 16 - t.decimal "latitude", precision: 19, scale: 16 + t.decimal "longitude", precision: 19, scale: 16 + t.decimal "latitude", precision: 19, scale: 16 t.string "long_lat_type" t.string "country_code" t.string "street_name" @@ -778,7 +799,7 @@ ActiveRecord::Schema.define(version: 20171016074044) do t.datetime "deleted_at" t.datetime "created_at" t.datetime "updated_at" - t.string "stif_type" + t.string "stif_type", limit: 255 end add_index "stop_areas", ["name"], name: "index_stop_areas_on_name", using: :btree @@ -849,18 +870,18 @@ ActiveRecord::Schema.define(version: 20171016074044) do add_index "time_table_periods", ["time_table_id"], name: "index_time_table_periods_on_time_table_id", using: :btree create_table "time_tables", id: :bigserial, force: :cascade do |t| - t.string "objectid", null: false - t.integer "object_version", limit: 8, default: 1 + t.string "objectid", null: false + t.integer "object_version", limit: 8, default: 1 t.string "creator_id" t.string "version" t.string "comment" - t.integer "int_day_types", default: 0 + t.integer "int_day_types", default: 0 t.date "start_date" t.date "end_date" t.integer "calendar_id", limit: 8 t.datetime "created_at" t.datetime "updated_at" - t.string "color" + t.string "color", limit: 255 t.integer "created_from_id" t.string "checksum" t.text "checksum_source" @@ -1007,9 +1028,13 @@ ActiveRecord::Schema.define(version: 20171016074044) do add_foreign_key "compliance_controls", "compliance_control_blocks" add_foreign_key "compliance_controls", "compliance_control_sets" add_foreign_key "group_of_lines_lines", "group_of_lines", name: "groupofline_group_fkey", on_delete: :cascade + add_foreign_key "journey_frequencies", "timebands", name: "journey_frequencies_timeband_id_fk", on_delete: :nullify add_foreign_key "journey_frequencies", "timebands", on_delete: :nullify + add_foreign_key "journey_frequencies", "vehicle_journeys", name: "journey_frequencies_vehicle_journey_id_fk", on_delete: :nullify add_foreign_key "journey_frequencies", "vehicle_journeys", on_delete: :nullify + add_foreign_key "journey_pattern_sections", "journey_patterns", name: "journey_pattern_sections_journey_pattern_id_fk", on_delete: :cascade add_foreign_key "journey_pattern_sections", "journey_patterns", on_delete: :cascade + add_foreign_key "journey_pattern_sections", "route_sections", name: "journey_pattern_sections_route_section_id_fk", on_delete: :cascade add_foreign_key "journey_pattern_sections", "route_sections", on_delete: :cascade add_foreign_key "journey_patterns", "routes", name: "jp_route_fkey", on_delete: :cascade add_foreign_key "journey_patterns", "stop_points", column: "arrival_stop_point_id", name: "arrival_point_fkey", on_delete: :nullify diff --git a/lib/compliance_control_set_copier.rb b/lib/compliance_control_set_copier.rb index 20518ee0e..58d40cdbf 100644 --- a/lib/compliance_control_set_copier.rb +++ b/lib/compliance_control_set_copier.rb @@ -11,6 +11,8 @@ class ComplianceControlSetCopier @referential_id = referential_id check_organisation_coherence! copy_set + + cck_set end diff --git a/spec/controllers/api/v1/imports_controller_spec.rb b/spec/controllers/api/v1/imports_controller_spec.rb index 266b25486..8077dd052 100644 --- a/spec/controllers/api/v1/imports_controller_spec.rb +++ b/spec/controllers/api/v1/imports_controller_spec.rb @@ -29,7 +29,7 @@ RSpec.describe Api::V1::ImportsController, type: :controller do it 'should be successful' do expect { - post :create, workbench_id: workbench.id, workbench_import: {file: file, creator: 'test'}, format: :json + post :create, workbench_id: workbench.id, workbench_import: {name: "test", file: file, creator: 'test'}, format: :json }.to change{WorkbenchImport.count}.by(1) expect(response).to be_success end diff --git a/spec/features/compliance_control_sets_spec.rb b/spec/features/compliance_control_sets_spec.rb new file mode 100644 index 000000000..500d4ce6f --- /dev/null +++ b/spec/features/compliance_control_sets_spec.rb @@ -0,0 +1,82 @@ +RSpec.describe "ComplianceControlSets", type: :feature do + + login_user + + # We setup a control_set with two blocks and one direct control (meaning that it is not attached to a block) + # Then we add one control to the first block and two controls to the second block + let( :control_set ){ create :compliance_control_set, organisation: organisation } + let( :controls ){ control_set.compliance_controls } + + let(:blox){ + 2.times.map{ | _ | create :compliance_control_block, compliance_control_set: control_set } + } + + before do + blox.first.update transport_mode: 'bus', transport_submode: 'bus' + blox.second.update transport_mode: 'train', transport_submode: 'train' + + make_control + make_control blox.first, severity: :error + make_control blox.second, times: 2 + end + + describe 'show' do + before do + visit compliance_control_set_path( control_set ) + end + + it 'we can see the controls inside their blocks' do + controls.each do | control | + expect( page ).to have_content(control.code) + end + end + + it 'we can apply a severity filter' do + controls.take(2).each do | control | + control.update criticity: 'error' + end + check('error') + click_on('Filtrer') + controls.each do | control | + if control.criticity == 'error' + expect( page ).to have_content(control.code) + else + expect( page ).not_to have_content(control.code) + end + end + end + + it 'we can apply a subclass filter' do + controls.first.update(origin_code: 'x-Route-y') + controls.second.update(origin_code: 'x-Line-y') + + within('#subclass-filter') do + check('Itinéraire') + check('Ligne') + end + click_on('Filtrer') + controls.each do | control | + if control.origin_code[/-Generic-/] + expect( page ).not_to have_content(control.code) + else + expect( page ).to have_content(control.code) + end + end + end + + end + + def make_control ccblock=nil, times: 1, severity: :warning + times.times do + make_one_control ccblock, severity + end + end + + def make_one_control ccblock, severity + create( :generic_attribute_control_min_max, + code: random_string, + compliance_control_block: ccblock, + compliance_control_set: control_set) + end + +end diff --git a/spec/features/connection_links_spec.rb b/spec/features/connection_links_spec.rb index 7272242fe..2f6283dcd 100644 --- a/spec/features/connection_links_spec.rb +++ b/spec/features/connection_links_spec.rb @@ -1,4 +1,4 @@ -RSpec.describe "ConnectionLinks", :type => :feature do +RSpec.describe "ConnectionLinks", type: :feature do login_user let!(:connection_links) { Array.new(2) { create(:connection_link) } } diff --git a/spec/lib/compliance_control_set_copier_spec.rb b/spec/lib/compliance_control_set_copier_spec.rb index a9e576cf7..0f15d86d0 100644 --- a/spec/lib/compliance_control_set_copier_spec.rb +++ b/spec/lib/compliance_control_set_copier_spec.rb @@ -99,6 +99,10 @@ RSpec.describe ComplianceControlSetCopier do expect( actual ).to eq( expected ) end + + it 'returns the newly-created ComplianceCheckSet' do + expect(subject.copy(cc_set.id, ref.id)).to eq(cck_set) + end end end diff --git a/spec/models/compliance_control_class_level_defaults/compliance_control_subclass_pattern_spec.rb b/spec/models/compliance_control_class_level_defaults/compliance_control_subclass_pattern_spec.rb new file mode 100644 index 000000000..868eca984 --- /dev/null +++ b/spec/models/compliance_control_class_level_defaults/compliance_control_subclass_pattern_spec.rb @@ -0,0 +1,17 @@ +RSpec.describe ComplianceControl do + let( :subject ){ described_class.subclass_patterns } + + context 'subclass_patterns' do + it 'are correctly defined' do + expect_it.to eq( + generic: 'Generic', + journey_pattern: 'JourneyPattern', + line: 'Line', + route: 'Route', + routing_constraint_zone: 'RoutingConstraint', + vehicle_journey: 'VehicleJourney' + ) + end + end + +end diff --git a/spec/models/compliance_control_spec.rb b/spec/models/compliance_control_spec.rb index db73dab21..4267459ea 100644 --- a/spec/models/compliance_control_spec.rb +++ b/spec/models/compliance_control_spec.rb @@ -4,10 +4,6 @@ RSpec.describe ComplianceControl, type: :model do let(:compliance_control) { build_stubbed :compliance_control } - it 'should have a valid factory' do - expect(compliance_control).to be_valid - end - it { should belong_to :compliance_control_set } it { should belong_to :compliance_control_block } diff --git a/spec/models/import_spec.rb b/spec/models/import_spec.rb index c06d05dab..7be05908a 100644 --- a/spec/models/import_spec.rb +++ b/spec/models/import_spec.rb @@ -10,7 +10,7 @@ RSpec.describe Import, type: :model do it { should validate_presence_of(:workbench) } it { should validate_presence_of(:creator) } - it { should allow_value('file.zip').for(:file).with_message(I18n.t('activerecord.errors.models.imports.wrong_file_extension')) } + it { should allow_value('file.zip').for(:file).with_message(I18n.t('activerecord.errors.models.import.attributes.file.wrong_file_extension')) } it { should_not allow_values('file.json', 'file.png', 'file.pdf').for(:file) } let(:workbench_import) { build_stubbed(:workbench_import) } diff --git a/spec/workers/compliance_control_set_copy_worker_spec.rb b/spec/workers/compliance_control_set_copy_worker_spec.rb new file mode 100644 index 000000000..0ff721e75 --- /dev/null +++ b/spec/workers/compliance_control_set_copy_worker_spec.rb @@ -0,0 +1,35 @@ +RSpec.describe ComplianceControlSetCopyWorker do + let(:control_set_id) { 55 } + let(:referential_id) { 99 } + let(:check_set) { double(ComplianceCheckSet, id: 888) } + let(:stub_validation_request) do + stub_request( + :get, + "#{Rails.configuration.iev_url}/boiv_iev/referentials/validator/new?id=#{check_set.id}" + ) + end + + before(:each) do + allow_any_instance_of( + ComplianceControlSetCopier + ).to receive(:copy).and_return(check_set) + + stub_validation_request + end + + it "calls ComplianceControlSetCopier" do + expect_any_instance_of( + ComplianceControlSetCopier + ).to receive(:copy) + .with(control_set_id, referential_id) + .and_return(check_set) + + ComplianceControlSetCopyWorker.new.perform(control_set_id, referential_id) + end + + it "calls the Java API to launch validation" do + ComplianceControlSetCopyWorker.new.perform(control_set_id, referential_id) + + expect(stub_validation_request).to have_been_requested + end +end diff --git a/spec/workers/workbench_import/workbench_import_with_corrupt_zip_spec.rb b/spec/workers/workbench_import/workbench_import_with_corrupt_zip_spec.rb index 5e34b208a..47626f5a1 100644 --- a/spec/workers/workbench_import/workbench_import_with_corrupt_zip_spec.rb +++ b/spec/workers/workbench_import/workbench_import_with_corrupt_zip_spec.rb @@ -1,6 +1,5 @@ RSpec.describe WorkbenchImportWorker do - shared_examples_for 'corrupt zipfile data' do subject { described_class.new } let( :workbench_import ){ create :workbench_import, status: :pending } @@ -23,7 +22,7 @@ RSpec.describe WorkbenchImportWorker do message = workbench_import.messages.last expect( message.criticity ).to eq('error') expect( message.message_key ).to eq('corrupt_zip_file') - expect( message.message_attributes ).to eq( 'import_name' => workbench_import.name ) + expect( message.message_attributes ).to eq( 'source_filename' => workbench_import.file.file.file ) end it 'does not change current step' do diff --git a/spec/workers/workbench_import/workbench_import_worker_spec.rb b/spec/workers/workbench_import/workbench_import_worker_spec.rb index deaa1e3a5..47ca2b4ff 100644 --- a/spec/workers/workbench_import/workbench_import_worker_spec.rb +++ b/spec/workers/workbench_import/workbench_import_worker_spec.rb @@ -115,8 +115,8 @@ RSpec.describe WorkbenchImportWorker, type: [:worker, :request] do let( :spurious ){ [spurious1, spurious2] } let( :messages ){ double('messages') } let( :message_attributes ){{criticity: :warning, message_key: 'inconsistent_zip_file'}} - let( :message1_attributes ){ message_attributes.merge(message_attributes: {'import_name' => import.name, 'spurious_dirs' => spurious1.join(', ')}) } - let( :message2_attributes ){ message_attributes.merge(message_attributes: {'import_name' => import.name, 'spurious_dirs' => spurious2.join(', ')}) } + let( :message1_attributes ){ message_attributes.merge(message_attributes: {'source_filename' => import.file.file.file, 'spurious_dirs' => spurious1.join(', ')}) } + let( :message2_attributes ){ message_attributes.merge(message_attributes: {'source_filename' => import.file.file.file, 'spurious_dirs' => spurious2.join(', ')}) } before do allow(import).to receive(:messages).and_return(messages) |
