From cb8c37b2902c07a1869ce991ce3f382eea25c812 Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 16 Oct 2017 10:28:18 +0200 Subject: Hotfix correction --- .../genric_attribute_validation/min_max_validation_spec.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spec/models/compliance_control_validations/genric_attribute_validation/min_max_validation_spec.rb b/spec/models/compliance_control_validations/genric_attribute_validation/min_max_validation_spec.rb index 276d09a92..4d30d61e3 100644 --- a/spec/models/compliance_control_validations/genric_attribute_validation/min_max_validation_spec.rb +++ b/spec/models/compliance_control_validations/genric_attribute_validation/min_max_validation_spec.rb @@ -1,8 +1,8 @@ -# RSpec.describe GenericAttributeControl::MinMax do +RSpec.describe GenericAttributeControl::MinMax do -# let( :factory ){ :generic_attribute_control_min_max } -# subject{ build factory } + let( :factory ){ :generic_attribute_control_min_max } + subject{ build factory } -# it_behaves_like 'has min_max_values' + it_behaves_like 'has min_max_values' -# end +end -- cgit v1.2.3 From 3d69e36539cee8796f9da2a981ba3c6b5e535e9f Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 16 Oct 2017 12:39:14 +0200 Subject: migrated --- db/schema.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/db/schema.rb b/db/schema.rb index 181c83402..a64a426de 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -408,9 +408,9 @@ ActiveRecord::Schema.define(version: 20171016074044) 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 -- cgit v1.2.3 From aaa5d31971ebf2b429efea3c869a8e132f9d0836 Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 16 Oct 2017 21:50:56 +0200 Subject: Refs: #4727@3h; Specing and implementing lib function to clone ComplianceControlSet --- config/locales/compliance_control_blocks.en.yml | 4 +- config/locales/compliance_control_blocks.fr.yml | 4 +- config/locales/compliance_control_sets.en.yml | 2 + config/locales/compliance_control_sets.fr.yml | 2 + config/locales/compliance_controls.en.yml | 2 + config/locales/compliance_controls.fr.yml | 2 + lib/compliance_control_set_cloner.rb | 89 +++++++++++++++ spec/lib/compliance_control_set_cloner_spec.rb | 142 ++++++++++++++++++++++++ 8 files changed, 245 insertions(+), 2 deletions(-) create mode 100644 lib/compliance_control_set_cloner.rb create mode 100644 spec/lib/compliance_control_set_cloner_spec.rb diff --git a/config/locales/compliance_control_blocks.en.yml b/config/locales/compliance_control_blocks.en.yml index a37b41db5..fbface6b2 100644 --- a/config/locales/compliance_control_blocks.en.yml +++ b/config/locales/compliance_control_blocks.en.yml @@ -10,9 +10,11 @@ fr: transport_mode: Transport mode sub_transport_mode: Transport submode compliance_control_blocks: + clone: + prefix: 'Copy of' actions: destroy_confirm: Are you sure you want to destroy this block ? new: title: Create a control block edit: - title: "Edit the control block : %{compliance_control_block}" \ No newline at end of file + title: "Edit the control block : %{compliance_control_block}" diff --git a/config/locales/compliance_control_blocks.fr.yml b/config/locales/compliance_control_blocks.fr.yml index f93cafa54..66df008be 100644 --- a/config/locales/compliance_control_blocks.fr.yml +++ b/config/locales/compliance_control_blocks.fr.yml @@ -10,9 +10,11 @@ fr: transport_mode: Mode de transport transport_submode: Sous-mode de transport compliance_control_blocks: + clone: + prefix: 'Copie de' actions: destroy_confirm: Etes vous sûr de supprimer ce bloc ? new: title: Créer un groupe de contrôle(s) edit: - title: "Editer le groupe de contrôle : %{compliance_control_block}" \ No newline at end of file + title: "Editer le groupe de contrôle : %{compliance_control_block}" diff --git a/config/locales/compliance_control_sets.en.yml b/config/locales/compliance_control_sets.en.yml index 83b14642c..f72342894 100644 --- a/config/locales/compliance_control_sets.en.yml +++ b/config/locales/compliance_control_sets.en.yml @@ -1,5 +1,7 @@ en: compliance_control_sets: + clone: + prefix: 'Copie de' index: title: Compliance control set new: New compliance control set diff --git a/config/locales/compliance_control_sets.fr.yml b/config/locales/compliance_control_sets.fr.yml index 37851d7c4..c31eb9423 100644 --- a/config/locales/compliance_control_sets.fr.yml +++ b/config/locales/compliance_control_sets.fr.yml @@ -1,5 +1,7 @@ fr: compliance_control_sets: + clone: + prefix: 'Copy of' index: title: "Liste des jeux de contrôles" edit: diff --git a/config/locales/compliance_controls.en.yml b/config/locales/compliance_controls.en.yml index 3063c35a4..887bc2009 100644 --- a/config/locales/compliance_controls.en.yml +++ b/config/locales/compliance_controls.en.yml @@ -1,5 +1,7 @@ en: compliance_controls: + clone: + prefix: 'Copy of' 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})" diff --git a/config/locales/compliance_controls.fr.yml b/config/locales/compliance_controls.fr.yml index 2038b9eb7..2feb201bf 100644 --- a/config/locales/compliance_controls.fr.yml +++ b/config/locales/compliance_controls.fr.yml @@ -1,5 +1,7 @@ fr: compliance_controls: + clone: + prefix: 'Copie de' 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})" diff --git a/lib/compliance_control_set_cloner.rb b/lib/compliance_control_set_cloner.rb new file mode 100644 index 000000000..50c757a9f --- /dev/null +++ b/lib/compliance_control_set_cloner.rb @@ -0,0 +1,89 @@ +class ComplianceControlSetCloner + + # Naming Convention: As we are in a domain with quite long names we + # abbreviate compliance_control to cc and + # compliance_check to cck iff used as prefixes. + + attr_reader :source_set_id + + def copy source_set_id + @source_set_id = source_set_id + copy_set + end + + + private + + # Workers + # ------- + + # Copy Set: + def copy_set + # Force lazy creation of target_set, just in case source_set is _empty_. + target_set + copy_controls + copy_blocks + end + + # Copy Blocks: + def copy_block source_block + target_set.compliance_control_blocks.create( + name: name_of_copy(:compliance_control_blocks, source_block.name), + condition_attributes: source_block.condition_attributes).tap do | target_block | + relink_checks_to_block source_block, target_block + end + end + def copy_blocks + source_set.compliance_control_blocks.order(:id).each(&method(:copy_block)) + end + def relink_checks_to_block source_block, target_block + source_block + .compliance_controls + .order(:id) + .each do | source_control | + control_id_map[source_control.id] + .update(compliance_control_block_id: target_block.id) + end + end + + # Copy Controls: + def copy_controls + source_set.compliance_controls.order(:id).each(&method(:copy_control)) + end + def copy_control(compliance_control) + target_set.compliance_controls.create( + code: compliance_control.code, + comment: compliance_control.comment, + control_attributes: compliance_control.control_attributes, + criticity: compliance_control.criticity, + name: name_of_copy(:compliance_controls, compliance_control.name), + origin_code: compliance_control.origin_code, + type: compliance_control.type + ).tap do | control | + control_id_map.update compliance_control.id => control + end + end + + def name_of_copy resource, name + [I18n.t("#{resource}.clone.prefix"), name].join(' ') + end + + # Lazy Values + # ----------- + def source_set + @__source_set__ ||= ComplianceControlSet.find(source_set_id) + end + def target_set + @__target_set__ ||= ComplianceControlSet.create!( + organisation: source_set.organisation, + name: name_of_copy(:compliance_control_sets, source_set.name) + ) + end + def control_id_map + # Map: compliance_control_id -> compliance_control (origin_id -> copied object) + @__control_id_to_check__ ||= Hash.new + end + def referential + @__referential__ ||= Referential.find(referential_id) + end +end diff --git a/spec/lib/compliance_control_set_cloner_spec.rb b/spec/lib/compliance_control_set_cloner_spec.rb new file mode 100644 index 000000000..5313c15de --- /dev/null +++ b/spec/lib/compliance_control_set_cloner_spec.rb @@ -0,0 +1,142 @@ +RSpec.describe ComplianceControlSetCloner do + + subject{ described_class.new } + + let( :source_set ){ create :compliance_control_set } + let( :set_prefix ){ I18n.t('compliance_control_sets.clone.prefix') } + let( :block_prefix ){ I18n.t('compliance_control_blocks.clone.prefix') } + let( :control_prefix ){ I18n.t('compliance_controls.clone.prefix') } + + + context 'Copying empty set' do + + context 'correct organisation' do + + # + # + # + # + # + # + # + # +-------------------+ + # +---------------------+----------------| Control (direct0) | + # | | +-------------------+ + # | | + # | | +-------------------+ + # +---------------------)------------+---| Control (direct1) | + # | | | +-------------------+ + # | | | + # | | | +-------------------+ + # +---------------------)------------)---| Control (direct2) | + # | | | +-------------------+ + # | | | + # | | | + # | | | + # v v | + # +------------+ +--------------+ | +---------------------+ + # | ControlSet |<----+----| ControlBlock |<-)--| Control (indirect0) | + # +------------+ | +--------------+ | +---------------------+ + # | | + # | +--------------+<-+ +---------------------+ + # |<---| ControlBlock |<----| Control (indirect1) | + # | +--------------+ +---------------------+ + # | + # | +--------------+ +---------------------+ + # +----| ControlBlock |<----| Control (indirect2) | + # +--------------+ +---------------------+ + + context 'Directed Acyclic Graph is copied correctly' do + let(:source_blox){ + 3.times.map{ |_| create :compliance_control_block, compliance_control_set: source_set } + } + let(:direct_ccs){ + 3.times.map{ |n| create :compliance_control, compliance_control_set: source_set, name: "direct #{n.succ}", code: "direct-#{n.succ}" } + } + # Needed to check we do not dulicate a node (compliance_control) twice + let(:indirect_ccs){ + # Create 1 child for each block and also associate first of the direct ccs to the first block + # seconf of the direct css to the second block + source_blox.take(2).zip(direct_ccs.take(2)).each do | source_block, cc | + cc.update compliance_control_block_id: source_block.id + end + source_blox.each_with_index.map{ | source_block, n | + create(:compliance_control, compliance_control_set: source_set, compliance_control_block: source_block, name: "indirect #{n.succ}", code: "indirect-#{n.succ}") + } + } + let( :sources ){ source_set.compliance_controls.order(:id) } + + let( :target_set ){ ComplianceControlSet.last } + let( :target_blox ){ ComplianceControlBlock.last 3 } + let( :targets ){ target_set.compliance_controls.order(:id) } + + before do + direct_ccs + indirect_ccs + end + it 'correctly creates a set for a complete DAG' do + # Slowness of tests constrains us to create a minimum of objects in the DB, + # hence only one example :( + # + # Execute copy and keep count + counts = object_counts + subject.copy(source_set.id) + delta = count_diff counts, object_counts + + # Check correctly copied set + expect(target_set.organisation).to eq(source_set.organisation) + expect(target_set.name).to eq( [set_prefix, source_set.name].join(' ') ) + + # Check correctly copied controls + targets.zip(sources).each do | target, source | + expect( target.code ).to eq(source.code ) + expect( target.comment ).to eq(source.comment ) + expect( target.compliance_control_set ).to eq( target_set ) + expect( target.control_attributes ).to eq(source.control_attributes) + expect( target.criticity ).to eq(source.criticity ) + expect( target.name ).to eq([control_prefix, source.name].join(' ')) + expect( target.origin_code ).to eq(source.origin_code ) + expect( target.type ).to eq(source.type) + end + # Check correctly copied blocks + target_blox.zip(source_blox).each do | target_block, source_block | + expect( target_block.compliance_control_set ).to eq(target_set) + expect( target_block.name ).to eq( [block_prefix, source_block.name].join(' ') ) + expect( target_block.condition_attributes ).to eq( source_block.condition_attributes ) + end + + # Check correct block associations + # See diagram above to understand the meaning of this: + # - The first two controls have been assigned to the first two blocks accordingly + # - The third has no block + # - The last three controls have been created from the three blocks in order + expected_block_ids = target_blox.take(2).map(&:id) + [ nil ] + target_blox.map(&:id) + expect( targets.pluck(:compliance_control_block_id) ).to eq( expected_block_ids ) + + # Check overall counts (no additional creations) + expect( delta ).to eq(counts) + end + end + + end + + def object_counts + { + source_set_count: ComplianceControlSet.count, + cc_block_count: ComplianceControlBlock.count, + cc_count: ComplianceControl.count, + cck_set_count: ComplianceCheckSet.count, + cck_block_count: ComplianceCheckBlock.count, + cck_count: ComplianceCheck.count + } + end + + def count_diff count1, count2 + count1.inject({}){ |h, (k,v)| + h.merge( k => count2[k] - v ) + } + end + + end + +end -- cgit v1.2.3 From 8fffc6dd27175b20cc18c246a10151bc98bba4ee Mon Sep 17 00:00:00 2001 From: Robert Date: Tue, 17 Oct 2017 10:32:33 +0200 Subject: Refs: #4727@2h; Debugged test setup to comply to new validation --- lib/compliance_control_set_cloner.rb | 1 + spec/lib/compliance_control_set_cloner_spec.rb | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/compliance_control_set_cloner.rb b/lib/compliance_control_set_cloner.rb index 50c757a9f..3856ce25e 100644 --- a/lib/compliance_control_set_cloner.rb +++ b/lib/compliance_control_set_cloner.rb @@ -58,6 +58,7 @@ class ComplianceControlSetCloner criticity: compliance_control.criticity, name: name_of_copy(:compliance_controls, compliance_control.name), origin_code: compliance_control.origin_code, + target: compliance_control.target, type: compliance_control.type ).tap do | control | control_id_map.update compliance_control.id => control diff --git a/spec/lib/compliance_control_set_cloner_spec.rb b/spec/lib/compliance_control_set_cloner_spec.rb index 5313c15de..ca359536a 100644 --- a/spec/lib/compliance_control_set_cloner_spec.rb +++ b/spec/lib/compliance_control_set_cloner_spec.rb @@ -51,7 +51,7 @@ RSpec.describe ComplianceControlSetCloner do 3.times.map{ |_| create :compliance_control_block, compliance_control_set: source_set } } let(:direct_ccs){ - 3.times.map{ |n| create :compliance_control, compliance_control_set: source_set, name: "direct #{n.succ}", code: "direct-#{n.succ}" } + 3.times.map{ |n| create :generic_attribute_control_min_max, compliance_control_set: source_set, name: "direct #{n.succ}", code: "direct-#{n.succ}" } } # Needed to check we do not dulicate a node (compliance_control) twice let(:indirect_ccs){ @@ -61,7 +61,7 @@ RSpec.describe ComplianceControlSetCloner do cc.update compliance_control_block_id: source_block.id end source_blox.each_with_index.map{ | source_block, n | - create(:compliance_control, compliance_control_set: source_set, compliance_control_block: source_block, name: "indirect #{n.succ}", code: "indirect-#{n.succ}") + create(:generic_attribute_control_min_max, compliance_control_set: source_set, compliance_control_block: source_block, name: "indirect #{n.succ}", code: "indirect-#{n.succ}") } } let( :sources ){ source_set.compliance_controls.order(:id) } -- cgit v1.2.3 From bacb624a9d0415337dfab6418de240cd2afa7305 Mon Sep 17 00:00:00 2001 From: Robert Date: Tue, 17 Oct 2017 10:50:41 +0200 Subject: Fixes: #4727@0.5h; Worker speced and implemented --- app/workers/compliance_control_set_cloning_worker.rb | 8 ++++++++ spec/workers/clean_up_worker_spec.rb | 1 - spec/workers/compliance_control_set_cloning_worker_spec.rb | 14 ++++++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 app/workers/compliance_control_set_cloning_worker.rb create mode 100644 spec/workers/compliance_control_set_cloning_worker_spec.rb diff --git a/app/workers/compliance_control_set_cloning_worker.rb b/app/workers/compliance_control_set_cloning_worker.rb new file mode 100644 index 000000000..6194a06ad --- /dev/null +++ b/app/workers/compliance_control_set_cloning_worker.rb @@ -0,0 +1,8 @@ +class ComplianceControlSetCloningWorker + include Sidekiq::Worker + + def perform id + ComplianceControlSetCloner.new.copy id + end + +end diff --git a/spec/workers/clean_up_worker_spec.rb b/spec/workers/clean_up_worker_spec.rb index e85768fa3..fd767db00 100644 --- a/spec/workers/clean_up_worker_spec.rb +++ b/spec/workers/clean_up_worker_spec.rb @@ -1,4 +1,3 @@ -require 'rails_helper' RSpec.describe CleanUpWorker, type: :worker do pending "add some examples to (or delete) #{__FILE__}" end diff --git a/spec/workers/compliance_control_set_cloning_worker_spec.rb b/spec/workers/compliance_control_set_cloning_worker_spec.rb new file mode 100644 index 000000000..dee3e6dd5 --- /dev/null +++ b/spec/workers/compliance_control_set_cloning_worker_spec.rb @@ -0,0 +1,14 @@ +RSpec.describe ComplianceControlSetCloningWorker do + + + it 'is a worker' do + expect( described_class.new ).to be_a(Sidekiq::Worker) + end + + it 'delegates perform to the correct lib call' do + id = random_int + expect_any_instance_of(ComplianceControlSetCloner).to receive(:copy).with(id) + described_class.new.perform(id) + end + +end -- cgit v1.2.3 From 0b744d48fdc84445f593114fe61baaafca4e17f4 Mon Sep 17 00:00:00 2001 From: Robert Date: Tue, 17 Oct 2017 12:28:35 +0200 Subject: Fixes: #4727@0.1h; Added organisation to clone for and rebased master --- app/workers/compliance_control_set_cloning_worker.rb | 4 ++-- lib/compliance_control_set_cloner.rb | 12 ++++++++---- spec/lib/compliance_control_set_cloner_spec.rb | 6 ++++-- spec/workers/compliance_control_set_cloning_worker_spec.rb | 7 ++++--- 4 files changed, 18 insertions(+), 11 deletions(-) diff --git a/app/workers/compliance_control_set_cloning_worker.rb b/app/workers/compliance_control_set_cloning_worker.rb index 6194a06ad..9cbe5c81a 100644 --- a/app/workers/compliance_control_set_cloning_worker.rb +++ b/app/workers/compliance_control_set_cloning_worker.rb @@ -1,8 +1,8 @@ class ComplianceControlSetCloningWorker include Sidekiq::Worker - def perform id - ComplianceControlSetCloner.new.copy id + def perform id, organisation_id + ComplianceControlSetCloner.new.copy id, organisation_id end end diff --git a/lib/compliance_control_set_cloner.rb b/lib/compliance_control_set_cloner.rb index 3856ce25e..1cf58a38d 100644 --- a/lib/compliance_control_set_cloner.rb +++ b/lib/compliance_control_set_cloner.rb @@ -4,10 +4,11 @@ class ComplianceControlSetCloner # abbreviate compliance_control to cc and # compliance_check to cck iff used as prefixes. - attr_reader :source_set_id - - def copy source_set_id + attr_reader :organisation_id, :source_set_id + + def copy source_set_id, organisation_id @source_set_id = source_set_id + @organisation_id = organisation_id copy_set end @@ -71,12 +72,15 @@ class ComplianceControlSetCloner # Lazy Values # ----------- + def organisation + @__organisation__ ||= Organisation.find(organisation_id) + end def source_set @__source_set__ ||= ComplianceControlSet.find(source_set_id) end def target_set @__target_set__ ||= ComplianceControlSet.create!( - organisation: source_set.organisation, + organisation: organisation, name: name_of_copy(:compliance_control_sets, source_set.name) ) end diff --git a/spec/lib/compliance_control_set_cloner_spec.rb b/spec/lib/compliance_control_set_cloner_spec.rb index ca359536a..4305ec70b 100644 --- a/spec/lib/compliance_control_set_cloner_spec.rb +++ b/spec/lib/compliance_control_set_cloner_spec.rb @@ -2,6 +2,8 @@ RSpec.describe ComplianceControlSetCloner do subject{ described_class.new } + let( :new_organisation ){ create :organisation } + let( :source_set ){ create :compliance_control_set } let( :set_prefix ){ I18n.t('compliance_control_sets.clone.prefix') } let( :block_prefix ){ I18n.t('compliance_control_blocks.clone.prefix') } @@ -80,11 +82,11 @@ RSpec.describe ComplianceControlSetCloner do # # Execute copy and keep count counts = object_counts - subject.copy(source_set.id) + subject.copy(source_set.id, new_organisation.id) delta = count_diff counts, object_counts # Check correctly copied set - expect(target_set.organisation).to eq(source_set.organisation) + expect(target_set.organisation).to eq(new_organisation) expect(target_set.name).to eq( [set_prefix, source_set.name].join(' ') ) # Check correctly copied controls diff --git a/spec/workers/compliance_control_set_cloning_worker_spec.rb b/spec/workers/compliance_control_set_cloning_worker_spec.rb index dee3e6dd5..3a2332f62 100644 --- a/spec/workers/compliance_control_set_cloning_worker_spec.rb +++ b/spec/workers/compliance_control_set_cloning_worker_spec.rb @@ -6,9 +6,10 @@ RSpec.describe ComplianceControlSetCloningWorker do end it 'delegates perform to the correct lib call' do - id = random_int - expect_any_instance_of(ComplianceControlSetCloner).to receive(:copy).with(id) - described_class.new.perform(id) + id = double('id') + organisation_id = double('organisation_id') + expect_any_instance_of(ComplianceControlSetCloner).to receive(:copy).with(id, organisation_id) + described_class.new.perform(id, organisation_id) end end -- cgit v1.2.3 From 4bb7669f00b7e6e622f966a11b4c727938838f22 Mon Sep 17 00:00:00 2001 From: Xinhui Date: Tue, 17 Oct 2017 14:54:41 +0200 Subject: Fix time_tables#index tags form should display searched tags on submit Refs #4711 --- app/controllers/time_tables_controller.rb | 1 - app/views/time_tables/_filter.html.slim | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/app/controllers/time_tables_controller.rb b/app/controllers/time_tables_controller.rb index 2d24d5aa6..af74f635f 100644 --- a/app/controllers/time_tables_controller.rb +++ b/app/controllers/time_tables_controller.rb @@ -130,7 +130,6 @@ class TimeTablesController < ChouetteController scope = select_time_tables if params[:q] && params[:q]["tag_search"] tags = params[:q]["tag_search"].reject {|c| c.empty?} - params[:q].delete("tag_search") scope = select_time_tables.tagged_with(tags, :any => true) if tags.any? end scope = self.ransack_period_range(scope: scope, error_message: t('referentials.errors.validity_period'), query: :overlapping) diff --git a/app/views/time_tables/_filter.html.slim b/app/views/time_tables/_filter.html.slim index 2672f7dfc..11e9987c4 100644 --- a/app/views/time_tables/_filter.html.slim +++ b/app/views/time_tables/_filter.html.slim @@ -9,7 +9,7 @@ .ffg-row .form-group = f.label Chouette::TimeTable.human_attribute_name(:tag_search), required: false, class: 'control-label' - = f.input :tag_search, as: :tags, collection: Chouette::TimeTable.tags_on(:tags).pluck(:name), label: false, input_html: { 'data-select2ed': 'true', 'data-select2ed-placeholder': 'Indiquez une étiquette...' }, wrapper_html: { class: 'select2ed'}, include_blank: false + = f.input :tag_search, as: :tags, collection: Chouette::TimeTable.tags_on(:tags).pluck(:name), label: false, input_html: { 'data-select2ed': 'true', 'data-select2ed-placeholder': 'Indiquez une étiquette...' }, wrapper_html: { class: 'select2ed'}, include_blank: false, selected: params[:q] ? params[:q]['tag_search'] : nil .form-group.togglable = f.label Chouette::TimeTable.human_attribute_name(:bounding_dates), required: false, class: 'control-label' -- cgit v1.2.3 From c1ed07eadc07e878ad09feecb529c26623189878 Mon Sep 17 00:00:00 2001 From: Robert Date: Tue, 17 Oct 2017 15:25:44 +0200 Subject: updated INSTALL.md for Webpack --- INSTALL.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/INSTALL.md b/INSTALL.md index bd4a3f330..1da342e39 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -19,6 +19,19 @@ Go into your local repro and install the gems bundle +## Node and Yarn + +Yarn needs a node version ≥ 6, if you use Node Version Manager [NVM](https://github.com/creationix/nvm) you can rely on the content of `.nvmrc`. + +Otherwise please make sure to use a compatible version, still best to use the same as indicated by `.nvrmc`. + +Then install yarn (`brew install yarn` does nicely on macOS). + +## Webpack + +... is managed by the webpacker gem, thusly at latest + before starting your server and tests, setup webpacker with `bundle exec rake webpacker:install`. + ### Installation Caveats #### Node Related Issue, libv8 -- cgit v1.2.3 From 5559c8639f977b2ee946d3f982da1bbf0643a5a4 Mon Sep 17 00:00:00 2001 From: Guillaume Date: Tue, 17 Oct 2017 15:30:30 +0200 Subject: add new picto for header compliance_control_sets, compliance_controls, compliance_control_blocks Refs #4729 --- app/views/compliance_control_blocks/edit.html.slim | 2 +- app/views/compliance_control_blocks/new.html.slim | 2 +- app/views/compliance_control_sets/edit.html.slim | 2 +- app/views/compliance_control_sets/index.html.slim | 2 +- app/views/compliance_control_sets/new.html.slim | 2 +- app/views/compliance_control_sets/show.html.slim | 2 +- app/views/compliance_controls/edit.html.slim | 2 +- app/views/compliance_controls/new.html.slim | 2 +- app/views/compliance_controls/select_type.html.slim | 2 +- app/views/compliance_controls/show.html.slim | 6 ++++-- 10 files changed, 13 insertions(+), 11 deletions(-) diff --git a/app/views/compliance_control_blocks/edit.html.slim b/app/views/compliance_control_blocks/edit.html.slim index 0ac507ece..637bb7311 100644 --- a/app/views/compliance_control_blocks/edit.html.slim +++ b/app/views/compliance_control_blocks/edit.html.slim @@ -1,5 +1,5 @@ / PageHeader -= pageheader 'modele-calendrier', += pageheader 'jeux-de-controle', t('compliance_control_blocks.edit.title', compliance_control_block: @compliance_control_block.id) diff --git a/app/views/compliance_control_blocks/new.html.slim b/app/views/compliance_control_blocks/new.html.slim index 654a0dc7f..49404c552 100644 --- a/app/views/compliance_control_blocks/new.html.slim +++ b/app/views/compliance_control_blocks/new.html.slim @@ -1,5 +1,5 @@ / PageHeader -= pageheader 'modele-calendrier', += pageheader 'jeux-de-controle', t('compliance_control_blocks.new.title') diff --git a/app/views/compliance_control_sets/edit.html.slim b/app/views/compliance_control_sets/edit.html.slim index 934bd81b0..649154b91 100644 --- a/app/views/compliance_control_sets/edit.html.slim +++ b/app/views/compliance_control_sets/edit.html.slim @@ -1,5 +1,5 @@ / PageHeader -= pageheader 'modele-calendrier', += pageheader 'jeux-de-controle', t('compliance_control_sets.edit.title', name: @compliance_control_set.name) / PageContent diff --git a/app/views/compliance_control_sets/index.html.slim b/app/views/compliance_control_sets/index.html.slim index 68173fee9..1120ed186 100644 --- a/app/views/compliance_control_sets/index.html.slim +++ b/app/views/compliance_control_sets/index.html.slim @@ -1,5 +1,5 @@ / PageHeader -- header_params = ['jeux-de-donnees', +- header_params = ['jeux-de-controle', t('compliance_control_sets.index.title'), ''] - header_params << link_to(t('compliance_control_sets.actions.new'), new_compliance_control_set_path, class: 'btn btn-default') if policy(Calendar).create? diff --git a/app/views/compliance_control_sets/new.html.slim b/app/views/compliance_control_sets/new.html.slim index d6be41ee8..35654b4d6 100644 --- a/app/views/compliance_control_sets/new.html.slim +++ b/app/views/compliance_control_sets/new.html.slim @@ -1,5 +1,5 @@ / PageHeader -= pageheader 'modele-calendrier', += pageheader 'jeux-de-controle', t('compliance_control_sets.index.new') diff --git a/app/views/compliance_control_sets/show.html.slim b/app/views/compliance_control_sets/show.html.slim index b6e203a9e..7767bd0d9 100644 --- a/app/views/compliance_control_sets/show.html.slim +++ b/app/views/compliance_control_sets/show.html.slim @@ -1,5 +1,5 @@ / PageHeader -= pageheader 'jeux-de-donnees', += pageheader 'jeux-de-controle', t('compliance_control_sets.show.title', name: @compliance_control_set.name), 'Lorem ipsum dolor sit amet' diff --git a/app/views/compliance_controls/edit.html.slim b/app/views/compliance_controls/edit.html.slim index d7497c0e2..1d478e845 100644 --- a/app/views/compliance_controls/edit.html.slim +++ b/app/views/compliance_controls/edit.html.slim @@ -1,4 +1,4 @@ -= pageheader 'compliance-control', += pageheader 'jeux-de-controle', t('compliance_controls.edit.title') diff --git a/app/views/compliance_controls/new.html.slim b/app/views/compliance_controls/new.html.slim index 962f70ecc..181f49a15 100644 --- a/app/views/compliance_controls/new.html.slim +++ b/app/views/compliance_controls/new.html.slim @@ -1,5 +1,5 @@ / PageHeader -- header_params = ['jeux-de-donnees', +- header_params = ['jeux-de-controle', t('compliance_controls.new.title'), ''] = pageheader(*header_params) do diff --git a/app/views/compliance_controls/select_type.html.slim b/app/views/compliance_controls/select_type.html.slim index c6e3b0427..98cc5a943 100644 --- a/app/views/compliance_controls/select_type.html.slim +++ b/app/views/compliance_controls/select_type.html.slim @@ -1,5 +1,5 @@ / PageHeader -- header_params = ['jeux-de-donnees', +- header_params = ['jeux-de-controle', t('compliance_controls.select_type.title'), ''] = pageheader(*header_params) do diff --git a/app/views/compliance_controls/show.html.slim b/app/views/compliance_controls/show.html.slim index 8232dbe28..7f11b1041 100644 --- a/app/views/compliance_controls/show.html.slim +++ b/app/views/compliance_controls/show.html.slim @@ -1,7 +1,9 @@ / PageHeader -= pageheader 'jeux-de-donnees', +- header_params = ['jeux-de-controle', t('compliance_controls.show.title'), - '' + ''] += pageheader(*header_params) do + / PageContent .page_content .container-fluid -- cgit v1.2.3 From 40c1942fedfa6932c94be42d169e4977674c0cfa Mon Sep 17 00:00:00 2001 From: Xinhui Date: Tue, 17 Oct 2017 16:47:53 +0200 Subject: Compliance Control set min level of criticity Refs #4730 --- app/models/compliance_control.rb | 1 - app/models/generic_attribute_control/min_max.rb | 1 - app/models/generic_attribute_control/pattern.rb | 1 - app/models/generic_attribute_control/uniqueness.rb | 1 - app/models/route_control/minimum_length.rb | 1 + app/models/route_control/opposite_route.rb | 1 + app/models/vehicle_journey_control/time_table.rb | 1 + app/models/vehicle_journey_control/vehicle_journey_at_stops.rb | 1 + 8 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/models/compliance_control.rb b/app/models/compliance_control.rb index baf491e8a..08efa7e9a 100644 --- a/app/models/compliance_control.rb +++ b/app/models/compliance_control.rb @@ -24,7 +24,6 @@ class ComplianceControl < ActiveRecord::Base end class << self - def default_criticity; :warning end def default_code; "" end def dynamic_attributes hstore_metadata_for_control_attributes.keys diff --git a/app/models/generic_attribute_control/min_max.rb b/app/models/generic_attribute_control/min_max.rb index a83ab64ab..ab6f546a7 100644 --- a/app/models/generic_attribute_control/min_max.rb +++ b/app/models/generic_attribute_control/min_max.rb @@ -9,7 +9,6 @@ module GenericAttributeControl class << self def attribute_type; :integer end - def default_criticity; :warning end def default_code; "3-Generic-2" end end end diff --git a/app/models/generic_attribute_control/pattern.rb b/app/models/generic_attribute_control/pattern.rb index 027d6948e..3a4a55d5c 100644 --- a/app/models/generic_attribute_control/pattern.rb +++ b/app/models/generic_attribute_control/pattern.rb @@ -7,7 +7,6 @@ module GenericAttributeControl class << self def attribute_type; :string end - def default_criticity; :warning end def default_code; "3-Generic-1" end end end diff --git a/app/models/generic_attribute_control/uniqueness.rb b/app/models/generic_attribute_control/uniqueness.rb index 36a270d74..f707c944b 100644 --- a/app/models/generic_attribute_control/uniqueness.rb +++ b/app/models/generic_attribute_control/uniqueness.rb @@ -6,7 +6,6 @@ module GenericAttributeControl class << self def attribute_type; :string end - def default_criticity; :warning end def default_code; "3-Generic-3" end end end diff --git a/app/models/route_control/minimum_length.rb b/app/models/route_control/minimum_length.rb index 56becfb2b..d378f3870 100644 --- a/app/models/route_control/minimum_length.rb +++ b/app/models/route_control/minimum_length.rb @@ -1,5 +1,6 @@ module RouteControl class MinimumLength < ComplianceControl + enumerize :criticity, in: %i(error), scope: true def self.default_code; "3-Route-6" end end diff --git a/app/models/route_control/opposite_route.rb b/app/models/route_control/opposite_route.rb index 0148087ca..88548f756 100644 --- a/app/models/route_control/opposite_route.rb +++ b/app/models/route_control/opposite_route.rb @@ -1,5 +1,6 @@ module RouteControl class OppositeRoute < ComplianceControl + enumerize :criticity, in: %i(error), scope: true def self.default_code; "3-Route-2" end end diff --git a/app/models/vehicle_journey_control/time_table.rb b/app/models/vehicle_journey_control/time_table.rb index 617ead12b..c286e193d 100644 --- a/app/models/vehicle_journey_control/time_table.rb +++ b/app/models/vehicle_journey_control/time_table.rb @@ -1,5 +1,6 @@ module VehicleJourneyControl class TimeTable < ComplianceControl + enumerize :criticity, in: %i(error), scope: true def self.default_code; "3-VehicleJourney-4" end end diff --git a/app/models/vehicle_journey_control/vehicle_journey_at_stops.rb b/app/models/vehicle_journey_control/vehicle_journey_at_stops.rb index 47ee26f82..737c26038 100644 --- a/app/models/vehicle_journey_control/vehicle_journey_at_stops.rb +++ b/app/models/vehicle_journey_control/vehicle_journey_at_stops.rb @@ -1,5 +1,6 @@ module VehicleJourneyControl class VehicleJourneyAtStops < ComplianceControl + enumerize :criticity, in: %i(error), scope: true def self.default_code; "3-VehicleJourney-5" end end -- cgit v1.2.3 From 8f16ba911810f93c5a651e6fb9c355953e41d53c Mon Sep 17 00:00:00 2001 From: Guillaume Date: Wed, 18 Oct 2017 14:19:47 +0200 Subject: add clone method in compliance_control_sets_controller, add duplicate button to IHM and flash message Refs #4741 --- app/controllers/compliance_control_sets_controller.rb | 11 +++++++++-- app/decorators/compliance_control_set_decorator.rb | 7 +++++++ config/locales/compliance_control_sets.en.yml | 2 ++ config/locales/compliance_control_sets.fr.yml | 2 ++ config/routes.rb | 1 + 5 files changed, 21 insertions(+), 2 deletions(-) diff --git a/app/controllers/compliance_control_sets_controller.rb b/app/controllers/compliance_control_sets_controller.rb index 9de90c21c..1f578f781 100644 --- a/app/controllers/compliance_control_sets_controller.rb +++ b/app/controllers/compliance_control_sets_controller.rb @@ -23,12 +23,19 @@ class ComplianceControlSetsController < BreadcrumbController end end - protected - def begin_of_association_chain current_organisation end + def clone + ComplianceControlSetCloner.new.copy(params[:id], current_organisation) + flash[:notice] = I18n.t("compliance_control_sets.errors.operation_in_progress") + redirect_to(compliance_control_sets_path) + end + + protected + + private def decorate_compliance_control_sets(compliance_control_sets) diff --git a/app/decorators/compliance_control_set_decorator.rb b/app/decorators/compliance_control_set_decorator.rb index f4aa607e1..7515316ce 100644 --- a/app/decorators/compliance_control_set_decorator.rb +++ b/app/decorators/compliance_control_set_decorator.rb @@ -4,6 +4,13 @@ class ComplianceControlSetDecorator < Draper::Decorator def action_links links = [] + # if policy.clone? + links << Link.new( + content: h.t('actions.clone'), + href: h.clone_compliance_control_set_path(object.id) + ) + # end + # if h.policy(object).destroy? links << Link.new( content: h.destroy_link_content, diff --git a/config/locales/compliance_control_sets.en.yml b/config/locales/compliance_control_sets.en.yml index f72342894..7e5381786 100644 --- a/config/locales/compliance_control_sets.en.yml +++ b/config/locales/compliance_control_sets.en.yml @@ -2,6 +2,8 @@ en: compliance_control_sets: clone: prefix: 'Copie de' + errors: + operation_in_progress: "The clone operation is in progress. Please wait and refresh the page in a few moments" index: title: Compliance control set new: New compliance control set diff --git a/config/locales/compliance_control_sets.fr.yml b/config/locales/compliance_control_sets.fr.yml index c31eb9423..ff559b945 100644 --- a/config/locales/compliance_control_sets.fr.yml +++ b/config/locales/compliance_control_sets.fr.yml @@ -2,6 +2,8 @@ fr: compliance_control_sets: clone: prefix: 'Copy of' + errors: + operation_in_progress: "L'opération de clone est en cours. Veuillez patienter et raffraichir la page dans quelques instants" index: title: "Liste des jeux de contrôles" edit: diff --git a/config/routes.rb b/config/routes.rb index b9e318f91..b105e77d6 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 :clone, on: :member resources :compliance_controls, except: :index do get :select_type, on: :collection end -- cgit v1.2.3 From 9c0f538419b66d4c2b34312b7c047f1d5041ad3c Mon Sep 17 00:00:00 2001 From: Xinhui Date: Wed, 18 Oct 2017 15:02:07 +0200 Subject: Fix spec validation failed on contriance control sti subclasses --- app/models/route_control/minimum_length.rb | 2 +- app/models/route_control/opposite_route.rb | 2 +- app/models/vehicle_journey_control/time_table.rb | 2 +- app/models/vehicle_journey_control/vehicle_journey_at_stops.rb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/models/route_control/minimum_length.rb b/app/models/route_control/minimum_length.rb index d378f3870..7aee4da21 100644 --- a/app/models/route_control/minimum_length.rb +++ b/app/models/route_control/minimum_length.rb @@ -1,6 +1,6 @@ module RouteControl class MinimumLength < ComplianceControl - enumerize :criticity, in: %i(error), scope: true + enumerize :criticity, in: %i(error), scope: true, default: :error def self.default_code; "3-Route-6" end end diff --git a/app/models/route_control/opposite_route.rb b/app/models/route_control/opposite_route.rb index 88548f756..3921bb0a2 100644 --- a/app/models/route_control/opposite_route.rb +++ b/app/models/route_control/opposite_route.rb @@ -1,6 +1,6 @@ module RouteControl class OppositeRoute < ComplianceControl - enumerize :criticity, in: %i(error), scope: true + enumerize :criticity, in: %i(error), scope: true, default: :error def self.default_code; "3-Route-2" end end diff --git a/app/models/vehicle_journey_control/time_table.rb b/app/models/vehicle_journey_control/time_table.rb index c286e193d..1e3166693 100644 --- a/app/models/vehicle_journey_control/time_table.rb +++ b/app/models/vehicle_journey_control/time_table.rb @@ -1,6 +1,6 @@ module VehicleJourneyControl class TimeTable < ComplianceControl - enumerize :criticity, in: %i(error), scope: true + enumerize :criticity, in: %i(error), scope: true, default: :error def self.default_code; "3-VehicleJourney-4" end end diff --git a/app/models/vehicle_journey_control/vehicle_journey_at_stops.rb b/app/models/vehicle_journey_control/vehicle_journey_at_stops.rb index 737c26038..392e7764f 100644 --- a/app/models/vehicle_journey_control/vehicle_journey_at_stops.rb +++ b/app/models/vehicle_journey_control/vehicle_journey_at_stops.rb @@ -1,6 +1,6 @@ module VehicleJourneyControl class VehicleJourneyAtStops < ComplianceControl - enumerize :criticity, in: %i(error), scope: true + enumerize :criticity, in: %i(error), scope: true, default: :error def self.default_code; "3-VehicleJourney-5" end end -- cgit v1.2.3 From 87c14225229ae775d3af8c4ec2eef810788598e0 Mon Sep 17 00:00:00 2001 From: Guillaume Date: Wed, 18 Oct 2017 16:53:07 +0200 Subject: add edit button on IHM show for edit compliance_controls Refs #4729 --- app/views/compliance_controls/show.html.slim | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/views/compliance_controls/show.html.slim b/app/views/compliance_controls/show.html.slim index 7f11b1041..12a28cd4b 100644 --- a/app/views/compliance_controls/show.html.slim +++ b/app/views/compliance_controls/show.html.slim @@ -1,8 +1,8 @@ / PageHeader -- header_params = ['jeux-de-controle', += pageheader 'jeux-de-controle', t('compliance_controls.show.title'), - ''] -= pageheader(*header_params) do + '', + link_to(t('actions.edit'), edit_compliance_control_set_compliance_control_path(params[:compliance_control_set_id], params[:id]), class: 'btn btn-default') do / PageContent .page_content -- cgit v1.2.3 From a72da010bc7b1d46a5a64ba715ac0926f7ba6748 Mon Sep 17 00:00:00 2001 From: Guillaume Date: Thu, 19 Oct 2017 10:14:09 +0200 Subject: move begin_of_association_chain to protected method Refs #4741 --- app/controllers/compliance_control_sets_controller.rb | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/app/controllers/compliance_control_sets_controller.rb b/app/controllers/compliance_control_sets_controller.rb index 1f578f781..1243c742b 100644 --- a/app/controllers/compliance_control_sets_controller.rb +++ b/app/controllers/compliance_control_sets_controller.rb @@ -23,10 +23,6 @@ class ComplianceControlSetsController < BreadcrumbController end end - def begin_of_association_chain - current_organisation - end - def clone ComplianceControlSetCloner.new.copy(params[:id], current_organisation) flash[:notice] = I18n.t("compliance_control_sets.errors.operation_in_progress") @@ -35,6 +31,9 @@ class ComplianceControlSetsController < BreadcrumbController protected + def begin_of_association_chain + current_organisation + end private @@ -55,4 +54,4 @@ class ComplianceControlSetsController < BreadcrumbController def compliance_control_set_params params.require(:compliance_control_set).permit(:name, :id) end -end +end \ No newline at end of file -- cgit v1.2.3 From 86122f091fc58cccaa882e1d76368730f16d30da Mon Sep 17 00:00:00 2001 From: Guillaume Date: Thu, 19 Oct 2017 15:28:18 +0200 Subject: modify UI for bottom buttons actions on compliance_control_sets#show, add new locales Refs #4752 --- app/assets/stylesheets/components/_tables.sass | 10 ++++++++++ app/views/compliance_control_sets/show.html.slim | 10 +++++++--- config/locales/compliance_control_sets.en.yml | 3 ++- config/locales/compliance_control_sets.fr.yml | 3 ++- 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/app/assets/stylesheets/components/_tables.sass b/app/assets/stylesheets/components/_tables.sass index 8fe7be374..178ec2f36 100644 --- a/app/assets/stylesheets/components/_tables.sass +++ b/app/assets/stylesheets/components/_tables.sass @@ -247,6 +247,16 @@ width: 35px height: 35px margin: 5px + &.with_text + width: initial + > a, > button + border-radius: 4% + text-decoration: none + span + &.fa + padding-left: 10px + span + padding: 0 10px 0 0 > a, > button display: block diff --git a/app/views/compliance_control_sets/show.html.slim b/app/views/compliance_control_sets/show.html.slim index 7767bd0d9..f45b0227a 100644 --- a/app/views/compliance_control_sets/show.html.slim +++ b/app/views/compliance_control_sets/show.html.slim @@ -96,9 +96,13 @@ cls: 'table has-filter has-search' .select_toolbox ul - li.st_action + li.st_action.with_text = link_to select_type_compliance_control_set_compliance_controls_path(@compliance_control_set.id) span.fa.fa-plus - li.st_action + span + = t('compliance_control_sets.actions.add_compliance_control') + li.st_action.with_text = link_to new_compliance_control_set_compliance_control_block_path(@compliance_control_set.id) - span.fa.fa-plus-square + span.fa.fa-plus + span + = t('compliance_control_sets.actions.add_compliance_control_block') diff --git a/config/locales/compliance_control_sets.en.yml b/config/locales/compliance_control_sets.en.yml index f72342894..34f25e1e1 100644 --- a/config/locales/compliance_control_sets.en.yml +++ b/config/locales/compliance_control_sets.en.yml @@ -13,7 +13,8 @@ en: edit: Edit show: Show destroy: Destroy - add_compliance_control: Add a compliance control + add_compliance_control: Compliance Control + add_compliance_control_block: Compliance Control Block destroy_confirm: Are you sur ? filters: name: 'Enter name ...' diff --git a/config/locales/compliance_control_sets.fr.yml b/config/locales/compliance_control_sets.fr.yml index c31eb9423..83be7da2b 100644 --- a/config/locales/compliance_control_sets.fr.yml +++ b/config/locales/compliance_control_sets.fr.yml @@ -15,7 +15,8 @@ fr: edit: Editer show: Consulter destroy: Supprimer - add_compliance_control: Ajouter un JDC + add_compliance_control: Contrôle + add_compliance_control_block: Groupe de contrôles loaded: Charger le contrôle destroy_confirm: Etes vous sûr de supprimer ce jeux de contrôle ? filters: -- cgit v1.2.3 From aba7a66a6baf07b38e346caf05ae5606804d2976 Mon Sep 17 00:00:00 2001 From: Guillaume Date: Thu, 19 Oct 2017 15:38:12 +0200 Subject: prefer current_organisation.id for organisation_id param in copy method in ComplianceControlSetCloner class --- app/controllers/compliance_control_sets_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/compliance_control_sets_controller.rb b/app/controllers/compliance_control_sets_controller.rb index 1243c742b..e5c2e19dd 100644 --- a/app/controllers/compliance_control_sets_controller.rb +++ b/app/controllers/compliance_control_sets_controller.rb @@ -24,7 +24,7 @@ class ComplianceControlSetsController < BreadcrumbController end def clone - ComplianceControlSetCloner.new.copy(params[:id], current_organisation) + ComplianceControlSetCloner.new.copy(params[:id], current_organisation.id) flash[:notice] = I18n.t("compliance_control_sets.errors.operation_in_progress") redirect_to(compliance_control_sets_path) end -- cgit v1.2.3 From 34e17a46d1564aafb05a4fb7e123188df58bc297 Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 23 Oct 2017 11:41:49 +0200 Subject: Hotfix ComplianceControlSet.clone --- lib/compliance_control_set_cloner.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/compliance_control_set_cloner.rb b/lib/compliance_control_set_cloner.rb index 1cf58a38d..12e1eccb5 100644 --- a/lib/compliance_control_set_cloner.rb +++ b/lib/compliance_control_set_cloner.rb @@ -59,7 +59,6 @@ class ComplianceControlSetCloner criticity: compliance_control.criticity, name: name_of_copy(:compliance_controls, compliance_control.name), origin_code: compliance_control.origin_code, - target: compliance_control.target, type: compliance_control.type ).tap do | control | control_id_map.update compliance_control.id => control -- cgit v1.2.3 From 4e3fefe39274424c14c12cd93016fdf495e7cc08 Mon Sep 17 00:00:00 2001 From: cedricnjanga Date: Mon, 23 Oct 2017 17:07:14 +0200 Subject: Refs #4762 Add file extension checking before importing (standard app and api) --- app/controllers/api/v1/imports_controller.rb | 7 ++++++- app/controllers/imports_controller.rb | 7 +++++++ app/models/import.rb | 6 ++++++ app/views/imports/_form.html.slim | 2 +- config/locales/imports.en.yml | 4 ++++ config/locales/imports.fr.yml | 4 ++++ 6 files changed, 28 insertions(+), 2 deletions(-) diff --git a/app/controllers/api/v1/imports_controller.rb b/app/controllers/api/v1/imports_controller.rb index 6050418d8..197e23337 100644 --- a/app/controllers/api/v1/imports_controller.rb +++ b/app/controllers/api/v1/imports_controller.rb @@ -5,7 +5,12 @@ class Api::V1::ImportsController < Api::V1::IbooController def create args = workbench_import_params.merge(creator: 'Webservice') @import = parent.workbench_imports.create(args) - create! + if @import.valid? + create! + else + binding.pry + render json: { status: "error", messages: @import.errors.full_messages } + end end private diff --git a/app/controllers/imports_controller.rb b/app/controllers/imports_controller.rb index 3c52dc935..66dccc243 100644 --- a/app/controllers/imports_controller.rb +++ b/app/controllers/imports_controller.rb @@ -38,6 +38,13 @@ class ImportsController < BreadcrumbController end end + def create + create! do |success, failure| + success.html { redirect_to workbench_imports_path } + failure.html { flash.now[:error] = @import.errors[:wrong_file_extension][0] if @import.file.file; render :new } + end + end + def download if params[:token] == resource.token_download send_file resource.file.path diff --git a/app/models/import.rb b/app/models/import.rb index 64f713914..72d9f2ce6 100644 --- a/app/models/import.rb +++ b/app/models/import.rb @@ -19,6 +19,12 @@ class Import < ActiveRecord::Base validates :file, presence: true validates_presence_of :workbench, :creator + validate def file_extension_must_be_zip + if self.file.file + errors.add(:wrong_file_extension, I18n.t('activerecord.errors.models.imports.wrong_file_extension')) unless self.file.file.extension == "zip" + end + end + before_create :initialize_fields def self.model_name diff --git a/app/views/imports/_form.html.slim b/app/views/imports/_form.html.slim index 0fbf578be..95d97c534 100644 --- a/app/views/imports/_form.html.slim +++ b/app/views/imports/_form.html.slim @@ -9,6 +9,6 @@ .form-group = form.label :file, t('activerecord.attributes.import.resources'), class: 'control-label col-sm-4 col-xs-5' .col-sm-8.col-xs-7 - = form.input_field :file, label: false, class: 'form-control' + = form.input :file, label: false, class: 'form-control' = form.button :submit, t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'wb_import_form' diff --git a/config/locales/imports.en.yml b/config/locales/imports.en.yml index 9bf877c86..f3bcad9e9 100644 --- a/config/locales/imports.en.yml +++ b/config/locales/imports.en.yml @@ -53,6 +53,10 @@ en: zero: "import" one: "NeTEx import" other: "imports" + errors: + models: + imports: + 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 6998c89d2..6e74fa33c 100644 --- a/config/locales/imports.fr.yml +++ b/config/locales/imports.fr.yml @@ -53,6 +53,10 @@ fr: zero: "import" one: "import NeTEx" other: "imports" + errors: + models: + imports: + wrong_file_extension: "Le fichier importé doit être au format zip" attributes: import: resources: "Fichier à importer" -- cgit v1.2.3 From d0668e45ec978e6b5f7f3f98ffe5ebabd9e701d6 Mon Sep 17 00:00:00 2001 From: Guillaume Date: Mon, 23 Oct 2017 17:16:04 +0200 Subject: fix redirect on compliance_control delete --- app/controllers/compliance_controls_controller.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/compliance_controls_controller.rb b/app/controllers/compliance_controls_controller.rb index e51d1eb74..b0545e120 100644 --- a/app/controllers/compliance_controls_controller.rb +++ b/app/controllers/compliance_controls_controller.rb @@ -1,6 +1,7 @@ class ComplianceControlsController < BreadcrumbController defaults resource_class: ComplianceControl belongs_to :compliance_control_set + actions :all, :except => [:show, :index] def select_type @sti_subclasses = ComplianceControl.subclasses -- cgit v1.2.3 From 5e5d06c815ea0b67c4e970011470dd7ac4a42431 Mon Sep 17 00:00:00 2001 From: Luc Donnet Date: Tue, 24 Oct 2017 12:40:04 +0200 Subject: Make erd patch for multi relationships and add merge png in output --- Gemfile.lock | 5 +++-- config/initializers/relationship.rb | 15 +++++++++++++++ lib/tasks/erd.rake | 4 ++-- 3 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 config/initializers/relationship.rb diff --git a/Gemfile.lock b/Gemfile.lock index da7c4f3c1..3acc27613 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -256,7 +256,8 @@ GEM htmlbeautifier (1.3.1) httparty (0.14.0) multi_xml (>= 0.5.2) - i18n (0.8.6) + i18n (0.9.0) + concurrent-ruby (~> 1.0) i18n-tasks (0.9.15) activesupport (>= 4.0.2) ast (>= 2.1.0) @@ -380,7 +381,7 @@ GEM activesupport (>= 4.2.0.beta, < 5.0) nokogiri (~> 1.6) rails-deprecated_sanitizer (>= 1.0.1) - rails-erd (1.5.0) + rails-erd (1.5.2) activerecord (>= 3.2) activesupport (>= 3.2) choice (~> 0.2.0) diff --git a/config/initializers/relationship.rb b/config/initializers/relationship.rb new file mode 100644 index 000000000..6f3fc29be --- /dev/null +++ b/config/initializers/relationship.rb @@ -0,0 +1,15 @@ +require 'rails_erd/domain/relationship' + +module RailsERD + class Domain + class Relationship + class << self + private + + def association_identity(association) + Set[association_owner(association), association_target(association)] + end + end + end + end +end diff --git a/lib/tasks/erd.rake b/lib/tasks/erd.rake index 6b79967de..e2665374e 100644 --- a/lib/tasks/erd.rake +++ b/lib/tasks/erd.rake @@ -7,9 +7,9 @@ namespace :generate do sh "bundle exec rake erd only='Organisation,StopAreaReferential,StopAreaReferentialSync,StopAreaReferentialSyncMessage,StopAreaReferentialMembership,LineReferential,LineReferentialSync,LineReferentialSyncMessage,LineReferentialMembership' filename='referentiels_externes' title='Référentiels externes'" sh "bundle exec rake erd only='NetexImport,Import,WorkbenchImport,ImportResource,ImportMessage' filename='import' title='Import'" sh "bundle exec rake erd only='ComplianceControlSet,ComplianceControlBlock,ComplianceControl,ComplianceCheckSet,ComplianceCheckBlock,ComplianceCheck,ComplianceCheckResource,ComplianceCheckMessage' filename='validation' title='Validation'" + sh "bundle exec rake erd only='Organisation,Workbench,ReferentialSuite,Referential' filename='merge' title='Merge'" #sh "bundle exec rake erd only='VehicleJourney,VehicleJourneyExport' filename='export' title='Export'" - #sh "bundle exec rake erd only='' filename='intégration' title='Integration'" - #sh "bundle exec rake erd only='' filename='fusion' title='Fusion'" + #sh "bundle exec rake erd only='' filename='integration' title='Integration'" #sh "bundle exec rake erd only='' filename='publication' title='Publication'" end -- cgit v1.2.3 From fd7ccf86e4a8e3cbc514d01afd19beb03ffae8e8 Mon Sep 17 00:00:00 2001 From: Luc Donnet Date: Tue, 24 Oct 2017 12:47:07 +0200 Subject: Add hack to use erd patch only for RAILS_ENV=development only --- config/initializers/relationship.rb | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/config/initializers/relationship.rb b/config/initializers/relationship.rb index 6f3fc29be..492aa627f 100644 --- a/config/initializers/relationship.rb +++ b/config/initializers/relationship.rb @@ -1,13 +1,15 @@ -require 'rails_erd/domain/relationship' +if Rails.env.development? + require 'rails_erd/domain/relationship' -module RailsERD - class Domain - class Relationship - class << self - private + module RailsERD + class Domain + class Relationship + class << self + private - def association_identity(association) - Set[association_owner(association), association_target(association)] + def association_identity(association) + Set[association_owner(association), association_target(association)] + end end end end -- cgit v1.2.3 From 7160d39c6f785e7db247aa97efda257c38f629f8 Mon Sep 17 00:00:00 2001 From: Luc Donnet Date: Tue, 24 Oct 2017 14:00:07 +0200 Subject: Fix spec/controllers/compliance_controls_controller_spec.rb redirect route for POST UPDATE --- spec/controllers/compliance_controls_controller_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/controllers/compliance_controls_controller_spec.rb b/spec/controllers/compliance_controls_controller_spec.rb index 34b27530d..61e94025d 100644 --- a/spec/controllers/compliance_controls_controller_spec.rb +++ b/spec/controllers/compliance_controls_controller_spec.rb @@ -44,7 +44,7 @@ RSpec.describe ComplianceControlsController, type: :controller do describe 'POST #update' do it 'should be successful' do post :update, compliance_control_set_id: compliance_control_set.id, id: compliance_control.id, compliance_control: compliance_control.as_json.merge(type: 'GenericAttributeControl::MinMax') - expect(response).to redirect_to compliance_control_set_compliance_control_path(compliance_control_set, compliance_control) + expect(response).to redirect_to compliance_control_set_path(compliance_control_set) end end -- cgit v1.2.3 From efe056fb645f0380e594f57ad058409194f3becd Mon Sep 17 00:00:00 2001 From: Robert Date: Tue, 24 Oct 2017 15:16:59 +0200 Subject: Hotfix for dyslexic en-fr traductions (compliance_control_stes.*.yml) --- app/controllers/compliance_controls_controller.rb | 1 - config/locales/compliance_control_sets.en.yml | 2 +- config/locales/compliance_control_sets.fr.yml | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/controllers/compliance_controls_controller.rb b/app/controllers/compliance_controls_controller.rb index b0545e120..0a9c7d52b 100644 --- a/app/controllers/compliance_controls_controller.rb +++ b/app/controllers/compliance_controls_controller.rb @@ -16,7 +16,6 @@ class ComplianceControlsController < BreadcrumbController end def create - puts build_resource.inspect create! do |success, failure| success.html { redirect_to compliance_control_set_path(parent) } failure.html { render( :action => 'new' ) } diff --git a/config/locales/compliance_control_sets.en.yml b/config/locales/compliance_control_sets.en.yml index ed7ccad5e..7361edacf 100644 --- a/config/locales/compliance_control_sets.en.yml +++ b/config/locales/compliance_control_sets.en.yml @@ -1,7 +1,7 @@ en: compliance_control_sets: clone: - prefix: 'Copie de' + prefix: 'Copy of' errors: operation_in_progress: "The clone operation is in progress. Please wait and refresh the page in a few moments" index: diff --git a/config/locales/compliance_control_sets.fr.yml b/config/locales/compliance_control_sets.fr.yml index d952567bf..19f6f08ee 100644 --- a/config/locales/compliance_control_sets.fr.yml +++ b/config/locales/compliance_control_sets.fr.yml @@ -1,7 +1,7 @@ fr: compliance_control_sets: clone: - prefix: 'Copy of' + prefix: 'Copie de' errors: operation_in_progress: "L'opération de clone est en cours. Veuillez patienter et raffraichir la page dans quelques instants" index: -- cgit v1.2.3 From 302ed0f642c755b6f96def25eda25e2d2dae8891 Mon Sep 17 00:00:00 2001 From: Robert Date: Thu, 19 Oct 2017 15:27:30 +0200 Subject: Refs: #4633@3h: - Discussing Spec - Speced and implemented the corrupt zipfile part Next: - Spec incorrect directory structure part - Implement incorrect directory structure part --- app/workers/workbench_import_worker.rb | 8 +++- spec/support/random.rb | 6 +++ .../workbench_import_with_corrupt_zip_spec.rb | 44 ++++++++++++++++++++++ spec/workers/workbench_import_worker_spec.rb | 5 +-- 4 files changed, 59 insertions(+), 4 deletions(-) create mode 100644 spec/workers/workbench_import_with_corrupt_zip_spec.rb diff --git a/app/workers/workbench_import_worker.rb b/app/workers/workbench_import_worker.rb index 994493944..b89ba19d8 100644 --- a/app/workers/workbench_import_worker.rb +++ b/app/workers/workbench_import_worker.rb @@ -14,11 +14,13 @@ class WorkbenchImportWorker zip_service = ZipService.new(downloaded) upload zip_service @workbench_import.update(ended_at: Time.now) + rescue Zip::Error + handle_corrupt_zip_file end def download logger.info "HTTP GET #{import_url}" - @zipfile_data = HTTPService.get_resource( + HTTPService.get_resource( host: import_host, path: import_path, params: {token: @workbench_import.token_download}).body @@ -32,6 +34,10 @@ class WorkbenchImportWorker params: params(eg_file, eg_name)) end + def handle_corrupt_zip_file + @workbench_import.messages.create(criticity: :error) + end + def upload zip_service entry_group_streams = zip_service.subdirs @workbench_import.update total_steps: entry_group_streams.size diff --git a/spec/support/random.rb b/spec/support/random.rb index 59e1a1475..1d5d62ec8 100644 --- a/spec/support/random.rb +++ b/spec/support/random.rb @@ -22,6 +22,12 @@ module Support def random_string SecureRandom.urlsafe_base64 end + + def very_random(veryness=3, joiner: '-') + raise ArgumentError, 'not very random' unless veryness > 1 + 3.times.map{ SecureRandom.uuid }.join(joiner) + end + end end diff --git a/spec/workers/workbench_import_with_corrupt_zip_spec.rb b/spec/workers/workbench_import_with_corrupt_zip_spec.rb new file mode 100644 index 000000000..344943ad7 --- /dev/null +++ b/spec/workers/workbench_import_with_corrupt_zip_spec.rb @@ -0,0 +1,44 @@ +RSpec.describe WorkbenchImportWorker do + + + shared_examples_for 'corrupt zipfile data' do + subject { described_class.new } + let( :workbench_import ){ create :workbench_import, status: :pending } + + before do + # Let us make sure that the name Enterprise will never be forgotten by history, + # ahem, I meant, that nothing is uploaded, by forbidding any message to be sent + # to HTTPService + expect_it.to receive(:download).and_return(downloaded) + end + + it 'does not upload' do + stub_const 'HTTPService', double('HTTPService') + subject.perform(workbench_import.id) + end + + it 'does create a message' do + expect{ subject.perform(workbench_import.id) }.to change{ workbench_import.messages.count }.by(1) + expect( workbench_import.messages.last.criticity ).to eq('error') + end + + it 'does not change current step' do + expect{ subject.perform(workbench_import.id) }.not_to change{ workbench_import.current_step } + end + + it "sets the workbench_import.status to failed" do + subject.perform(workbench_import.id) + expect( workbench_import.reload.status ).to eq('failed') + end + end + + context 'empty zip file' do + let( :downloaded ){ '' } + it_should_behave_like 'corrupt zipfile data' + end + + context 'corrupt data' do + let( :downloaded ){ very_random } + it_should_behave_like 'corrupt zipfile data' + end +end diff --git a/spec/workers/workbench_import_worker_spec.rb b/spec/workers/workbench_import_worker_spec.rb index a349b3433..726dd7f8d 100644 --- a/spec/workers/workbench_import_worker_spec.rb +++ b/spec/workers/workbench_import_worker_spec.rb @@ -5,7 +5,7 @@ RSpec.describe WorkbenchImportWorker, type: [:worker, :request] do let( :workbench ){ import.workbench } let( :referential ){ import.referential } - let( :api_key ){ build_stubbed :api_key, referential: referential, token: "#{referential.id}-#{SecureRandom.hex}" } + let( :api_key ){ build_stubbed :api_key, referential: referential, token: "#{referential.id}-#{random_hex}" } # http://www.example.com/workbenches/:workbench_id/imports/:id/download let( :host ){ Rails.configuration.rails_host } @@ -13,8 +13,7 @@ RSpec.describe WorkbenchImportWorker, type: [:worker, :request] do let( :downloaded_zip ){ double("downloaded zip") } let( :download_zip_response ){ OpenStruct.new( body: downloaded_zip ) } - let( :download_token ){ SecureRandom.urlsafe_base64 } - + let( :download_token ){ random_string } let( :upload_path ) { api_v1_netex_imports_path(format: :json) } -- cgit v1.2.3 From 7f3b2aa1a1c4a2e051e1b2d3d3b57ab646b01a44 Mon Sep 17 00:00:00 2001 From: Robert Date: Thu, 19 Oct 2017 18:22:44 +0200 Subject: Refs: #4633@0.5h; Speced and implemented ZipService to return additional directories in the entry's `spurious` field. --- app/services/zip_service.rb | 18 ++++-- spec/fixtures/OFFRE_WITH_EXTRA.zip | Bin 0 -> 5586 bytes spec/services/zip_service/regression_4273_spec.rb | 59 ------------------- spec/services/zip_service_spec.rb | 68 ++++++++++++++++++++++ 4 files changed, 82 insertions(+), 63 deletions(-) create mode 100644 spec/fixtures/OFFRE_WITH_EXTRA.zip delete mode 100644 spec/services/zip_service/regression_4273_spec.rb create mode 100644 spec/services/zip_service_spec.rb diff --git a/app/services/zip_service.rb b/app/services/zip_service.rb index cab301b01..7a4bdad1b 100644 --- a/app/services/zip_service.rb +++ b/app/services/zip_service.rb @@ -1,10 +1,9 @@ class ZipService - # TODO: Remove me before merge https://github.com/rubyzip/rubyzip - class Subdir < Struct.new(:name, :stream) + class Subdir < Struct.new(:name, :stream, :spurious) end - attr_reader :current_key, :current_output, :yielder + attr_reader :current_key, :current_output, :current_spurious, :yielder def initialize data @zip_data = StringIO.new(data) @@ -36,6 +35,7 @@ class ZipService end def add_to_current_output entry + return if is_spurious! entry.name current_output.put_next_entry entry.name write_to_current_output entry.get_input_stream end @@ -51,7 +51,8 @@ class ZipService @yielder << Subdir.new( current_key, # Second part of the solution, yield the closed stream - current_output.close_buffer) + current_output.close_buffer, + current_spurious) end end @@ -59,10 +60,19 @@ class ZipService @current_key = entry_key # First piece of the solution, use internal way to create a Zip::OutputStream @current_output = Zip::OutputStream.new(StringIO.new(''), true, nil) + @current_spurious = [] end def entry_key entry # last dir name File.dirname.split("/").last entry.name.split('/', -1)[-2] end + + def is_spurious! entry_name + segments = entry_name.split('/', 3) + return false if segments.size < 3 + + current_spurious << segments.second + return true + end end diff --git a/spec/fixtures/OFFRE_WITH_EXTRA.zip b/spec/fixtures/OFFRE_WITH_EXTRA.zip new file mode 100644 index 000000000..97ea3f513 Binary files /dev/null and b/spec/fixtures/OFFRE_WITH_EXTRA.zip differ diff --git a/spec/services/zip_service/regression_4273_spec.rb b/spec/services/zip_service/regression_4273_spec.rb deleted file mode 100644 index 4fe0f6539..000000000 --- a/spec/services/zip_service/regression_4273_spec.rb +++ /dev/null @@ -1,59 +0,0 @@ -RSpec.describe ZipService do - describe 'Regression Issue # 4273 https://projects.af83.io/issues/4273' do - let( :zip_service ){ described_class } - let( :unzipper ){ zip_service.new(zip_data) } - let( :zip_data ){ File.read zip_file } - - context 'real test data' do - let( :subdir_names ){ %w } - let( :expected_chksums ){ - checksum_trees( subdir_names.map{ |sn| subdir_file(sn, prefix: 'source_') } ) - } - - let( :zip_file ){ fixtures_path 'OFFRE_TRANSDEV_2017030112251.zip' } - # - # Remove potential test artefacts - before do - subdir_names.each do | subdir_name | - File.unlink( subdir_file subdir_name, suffix: '.zip' ) rescue nil - Dir.unlink( subdir_file subdir_name ) rescue nil - end - end - - it "yields the correct content" do - subdir_contents = {} - # Write ZipService Streams to files and inflate them to file system - unzipper.subdirs.each do | subdir | - File.open(subdir_file( subdir.name, suffix: '.zip' ), 'wb'){ |f| f.write subdir.stream.string } - unzip_subdir subdir - end - # Represent the inflated file_system as a checksum tree - actual_checksums = - checksum_trees( subdir_names.map{ |sn| subdir_file(sn, prefix: 'target/') } ) - expect( actual_checksums ).to eq( expected_chksums ) - end - - end - - end - - def checksum_trees *dirs - dirs.flatten.inject({},&method(:checksum_tree)) - end - def checksum_tree repr, dir - Dir.glob("#{dir}/**/*").each do |file| - if !File.directory?(file) - repr.merge!( File.basename(file) => %x{cksum #{file}}.split.first ){ |_, ov, nv| Array(ov) << nv } - end - end - repr - end - - def subdir_file( subdir, prefix: 'target_', suffix: '' ) - fixtures_path("#{prefix}#{subdir}#{suffix}") - end - - def unzip_subdir subdir - %x{unzip -oqq #{subdir_file subdir.name, suffix: '.zip'} -d #{fixture_path}/target} - end -end diff --git a/spec/services/zip_service_spec.rb b/spec/services/zip_service_spec.rb new file mode 100644 index 000000000..98cb9026d --- /dev/null +++ b/spec/services/zip_service_spec.rb @@ -0,0 +1,68 @@ +RSpec.describe ZipService do + + let( :zip_service ){ described_class } + let( :unzipper ){ zip_service.new(zip_data) } + let( :zip_data ){ File.read zip_file } + + + context 'correct test data' do + before do + subdir_names.each do | subdir_name | + File.unlink( subdir_file subdir_name, suffix: '.zip' ) rescue nil + Dir.unlink( subdir_file subdir_name ) rescue nil + end + end + let( :subdir_names ){ %w } + let( :expected_chksums ){ + checksum_trees( subdir_names.map{ |sn| subdir_file(sn, prefix: 'source_') } ) + } + + let( :zip_file ){ fixtures_path 'OFFRE_TRANSDEV_2017030112251.zip' } + # + # Remove potential test artefacts + + it 'yields the correct content' do + # Write ZipService Streams to files and inflate them to file system + unzipper.subdirs.each do | subdir | + expect( subdir.spurious ).to be_empty + File.open(subdir_file( subdir.name, suffix: '.zip' ), 'wb'){ |f| f.write subdir.stream.string } + unzip_subdir subdir + end + # Represent the inflated file_system as a checksum tree + actual_checksums = + checksum_trees( subdir_names.map{ |sn| subdir_file(sn, prefix: 'target/') } ) + expect( actual_checksums ).to eq( expected_chksums ) + end + + end + + context 'test data with spurious directories' do + let( :zip_file ){ fixtures_path 'OFFRE_WITH_EXTRA.zip' } + + it 'returns the extra dir in the spurious field of the entry' do + expect( unzipper.subdirs.first.spurious ).to eq(%w{EXTRA}) + end + end + + + def checksum_trees *dirs + dirs.flatten.inject({},&method(:checksum_tree)) + end + def checksum_tree repr, dir + Dir.glob("#{dir}/**/*").each do |file| + if !File.directory?(file) + repr.merge!( File.basename(file) => %x{cksum #{file}}.split.first ){ |_, ov, nv| Array(ov) << nv } + end + end + repr + end + + def subdir_file( subdir, prefix: 'target_', suffix: '' ) + fixtures_path("#{prefix}#{subdir}#{suffix}") + end + + def unzip_subdir subdir + %x{unzip -oqq #{subdir_file subdir.name, suffix: '.zip'} -d #{fixture_path}/target} + end +end + -- cgit v1.2.3 From d351eab8ceea2bc7609e800e62bfb90c000cff5c Mon Sep 17 00:00:00 2001 From: Robert Date: Thu, 19 Oct 2017 20:45:50 +0200 Subject: Refs: #4633@0.5h; WorkbenchImportWorker implements message creation for spurious directories - Speced and implemented Missing: - Exact message parameters (change key from xxx, how to add names of spurious directories) --- app/workers/workbench_import_worker.rb | 18 ++- spec/support/random.rb | 2 +- .../workbench_import_with_corrupt_zip_spec.rb | 44 ++++++ .../workbench_import_worker_spec.rb | 166 +++++++++++++++++++++ .../workbench_import_with_corrupt_zip_spec.rb | 44 ------ spec/workers/workbench_import_worker_spec.rb | 131 ---------------- 6 files changed, 224 insertions(+), 181 deletions(-) create mode 100644 spec/workers/workbench_import/workbench_import_with_corrupt_zip_spec.rb create mode 100644 spec/workers/workbench_import/workbench_import_worker_spec.rb delete mode 100644 spec/workers/workbench_import_with_corrupt_zip_spec.rb delete mode 100644 spec/workers/workbench_import_worker_spec.rb diff --git a/app/workers/workbench_import_worker.rb b/app/workers/workbench_import_worker.rb index b89ba19d8..ef95cad51 100644 --- a/app/workers/workbench_import_worker.rb +++ b/app/workers/workbench_import_worker.rb @@ -48,11 +48,19 @@ class WorkbenchImportWorker raise end - def upload_entry_group entry_pair, element_count - @workbench_import.update( current_step: element_count.succ ) - # status = retry_service.execute(&upload_entry_group_proc(entry_pair)) - eg_name = entry_pair.name - eg_stream = entry_pair.stream + def update_object_state entry, count + @workbench_import.update( current_step: count ) + # TODO: Determine the other attributes of the message, especially how to add the names + # of the spurious dirs entry.spurious + unless entry.spurious.empty? + @workbench_import.messages.create(criticity: :warning, message_key: 'xxx') + end + end + def upload_entry_group entry, element_count + update_object_state entry, element_count.succ + # status = retry_service.execute(&upload_entry_group_proc(entry)) + eg_name = entry.name + eg_stream = entry.stream FileUtils.mkdir_p(Rails.root.join('tmp', 'imports')) diff --git a/spec/support/random.rb b/spec/support/random.rb index 1d5d62ec8..0ebc2ee5e 100644 --- a/spec/support/random.rb +++ b/spec/support/random.rb @@ -25,7 +25,7 @@ module Support def very_random(veryness=3, joiner: '-') raise ArgumentError, 'not very random' unless veryness > 1 - 3.times.map{ SecureRandom.uuid }.join(joiner) + veryness.times.map{ SecureRandom.uuid }.join(joiner) 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 new file mode 100644 index 000000000..344943ad7 --- /dev/null +++ b/spec/workers/workbench_import/workbench_import_with_corrupt_zip_spec.rb @@ -0,0 +1,44 @@ +RSpec.describe WorkbenchImportWorker do + + + shared_examples_for 'corrupt zipfile data' do + subject { described_class.new } + let( :workbench_import ){ create :workbench_import, status: :pending } + + before do + # Let us make sure that the name Enterprise will never be forgotten by history, + # ahem, I meant, that nothing is uploaded, by forbidding any message to be sent + # to HTTPService + expect_it.to receive(:download).and_return(downloaded) + end + + it 'does not upload' do + stub_const 'HTTPService', double('HTTPService') + subject.perform(workbench_import.id) + end + + it 'does create a message' do + expect{ subject.perform(workbench_import.id) }.to change{ workbench_import.messages.count }.by(1) + expect( workbench_import.messages.last.criticity ).to eq('error') + end + + it 'does not change current step' do + expect{ subject.perform(workbench_import.id) }.not_to change{ workbench_import.current_step } + end + + it "sets the workbench_import.status to failed" do + subject.perform(workbench_import.id) + expect( workbench_import.reload.status ).to eq('failed') + end + end + + context 'empty zip file' do + let( :downloaded ){ '' } + it_should_behave_like 'corrupt zipfile data' + end + + context 'corrupt data' do + let( :downloaded ){ very_random } + it_should_behave_like 'corrupt zipfile data' + end +end diff --git a/spec/workers/workbench_import/workbench_import_worker_spec.rb b/spec/workers/workbench_import/workbench_import_worker_spec.rb new file mode 100644 index 000000000..17cb7e16b --- /dev/null +++ b/spec/workers/workbench_import/workbench_import_worker_spec.rb @@ -0,0 +1,166 @@ +RSpec.describe WorkbenchImportWorker, type: [:worker, :request] do + + let( :worker ) { described_class.new } + let( :import ){ build_stubbed :import, token_download: download_token, file: zip_file } + + let( :workbench ){ import.workbench } + let( :referential ){ import.referential } + let( :api_key ){ build_stubbed :api_key, referential: referential, token: "#{referential.id}-#{random_hex}" } + + # http://www.example.com/workbenches/:workbench_id/imports/:id/download + let( :host ){ Rails.configuration.rails_host } + let( :path ){ download_workbench_import_path(workbench, import) } + + let( :downloaded_zip ){ double("downloaded zip") } + let( :download_zip_response ){ OpenStruct.new( body: downloaded_zip ) } + let( :download_token ){ random_string } + + let( :upload_path ) { api_v1_netex_imports_path(format: :json) } + + let( :spurious ){ [[], [], []] } + let( :subdirs ) do + entry_count.times.map do |i| + ZipService::Subdir.new( + "subdir #{i}", + double("subdir #{i}", rewind: 0, read: ''), + spurious[i] + ) + end + end + + let( :zip_service ){ double("zip service") } + let( :zip_file ){ open_fixture('multiple_references_import.zip') } + + let( :post_response_ok ){ double(status: 201, body: "{}") } + + before do + Timecop.freeze(Time.now) + + # Silence Logger + allow_any_instance_of(Logger).to receive(:info) + allow_any_instance_of(Logger).to receive(:warn) + + # That should be `build_stubbed's` job, no? + allow(Import).to receive(:find).with(import.id).and_return(import) + + allow(Api::V1::ApiKey).to receive(:from).and_return(api_key) + allow(ZipService).to receive(:new).with(downloaded_zip).and_return zip_service + expect(zip_service).to receive(:subdirs).and_return(subdirs) + expect( import ).to receive(:update).with( + status: 'running', + started_at: Time.now + ) + end + + after do + Timecop.return + end + + + context 'multireferential zipfile, no errors' do + let( :entry_count ){ 2 } + + it 'downloads a zip file, cuts it, and uploads all pieces' do + + expect(HTTPService).to receive(:get_resource) + .with(host: host, path: path, params: {token: download_token}) + .and_return( download_zip_response ) + + subdirs.each do |subdir| + mock_post subdir, post_response_ok + end + + expect( import ).to receive(:update).with(total_steps: 2) + expect( import ).to receive(:update).with(current_step: 1) + expect( import ).to receive(:update).with(current_step: 2) + expect( import ).to receive(:update).with(ended_at: Time.now) + + worker.perform import.id + + end + end + + context 'multireferential zipfile with error' do + let( :entry_count ){ 3 } + let( :post_response_failure ){ double(status: 406, body: {error: 'What was you thinking'}) } + + it 'downloads a zip file, cuts it, and uploads some pieces' do + expect(HTTPService).to receive(:get_resource) + .with(host: host, path: path, params: {token: download_token}) + .and_return( download_zip_response ) + + # First subdir succeeds + subdirs[0..0].each do |subdir| + mock_post subdir, post_response_ok + end + + # Second subdir fails (M I S E R A B L Y) + subdirs[1..1].each do |subdir| + mock_post subdir, post_response_failure + end + + expect( import ).to receive(:update).with(total_steps: 3) + expect( import ).to receive(:update).with(current_step: 1) + expect( import ).to receive(:update).with(current_step: 2) + expect( import ).to receive(:update).with(current_step: 3, status: 'failed') + + expect { worker.perform import.id }.to raise_error(StopIteration) + end + end + + context 'multireferential zipfile with spurious directories' do + let( :entry_count ){ 2 } + let( :spurious1 ){ [random_string] } + let( :spurious2 ){ [random_string, random_string] } + let( :spurious ){ [spurious1, spurious2] } + let( :messages ){ double('messages') } + + before do + allow(import).to receive(:messages).and_return(messages) + end + + it 'downloads a zip file, cuts it, and uploads all pieces and adds messages' do + + expect(HTTPService).to receive(:get_resource) + .with(host: host, path: path, params: {token: download_token}) + .and_return( download_zip_response ) + + subdirs.each do |subdir| + mock_post subdir, post_response_ok + end + + expect( import ).to receive(:update).with(total_steps: 2) + expect( import ).to receive(:update).with(current_step: 1) + expect( messages ).to receive(:create).with(criticity: :warning, message_key: 'xxx') + expect( import ).to receive(:update).with(current_step: 2) + expect( messages ).to receive(:create).with(criticity: :warning, message_key: 'xxx') + expect( import ).to receive(:update).with(ended_at: Time.now) + + worker.perform import.id + + end + + end + + def mock_post subdir, response + allow(HTTPService).to receive(:upload) + expect( HTTPService ).to receive(:post_resource) + .with( + host: host, + path: upload_path, + params: { + netex_import: { + parent_id: import.id, + parent_type: import.class.name, + workbench_id: workbench.id, + name: subdir.name, + file: HTTPService.upload( + subdir.stream, + 'application/zip', + "#{subdir.name}.zip" + ) + } + } + ).and_return(response) + end +end diff --git a/spec/workers/workbench_import_with_corrupt_zip_spec.rb b/spec/workers/workbench_import_with_corrupt_zip_spec.rb deleted file mode 100644 index 344943ad7..000000000 --- a/spec/workers/workbench_import_with_corrupt_zip_spec.rb +++ /dev/null @@ -1,44 +0,0 @@ -RSpec.describe WorkbenchImportWorker do - - - shared_examples_for 'corrupt zipfile data' do - subject { described_class.new } - let( :workbench_import ){ create :workbench_import, status: :pending } - - before do - # Let us make sure that the name Enterprise will never be forgotten by history, - # ahem, I meant, that nothing is uploaded, by forbidding any message to be sent - # to HTTPService - expect_it.to receive(:download).and_return(downloaded) - end - - it 'does not upload' do - stub_const 'HTTPService', double('HTTPService') - subject.perform(workbench_import.id) - end - - it 'does create a message' do - expect{ subject.perform(workbench_import.id) }.to change{ workbench_import.messages.count }.by(1) - expect( workbench_import.messages.last.criticity ).to eq('error') - end - - it 'does not change current step' do - expect{ subject.perform(workbench_import.id) }.not_to change{ workbench_import.current_step } - end - - it "sets the workbench_import.status to failed" do - subject.perform(workbench_import.id) - expect( workbench_import.reload.status ).to eq('failed') - end - end - - context 'empty zip file' do - let( :downloaded ){ '' } - it_should_behave_like 'corrupt zipfile data' - end - - context 'corrupt data' do - let( :downloaded ){ very_random } - it_should_behave_like 'corrupt zipfile data' - end -end diff --git a/spec/workers/workbench_import_worker_spec.rb b/spec/workers/workbench_import_worker_spec.rb deleted file mode 100644 index 726dd7f8d..000000000 --- a/spec/workers/workbench_import_worker_spec.rb +++ /dev/null @@ -1,131 +0,0 @@ -RSpec.describe WorkbenchImportWorker, type: [:worker, :request] do - - let( :worker ) { described_class.new } - let( :import ){ build_stubbed :import, token_download: download_token, file: zip_file } - - let( :workbench ){ import.workbench } - let( :referential ){ import.referential } - let( :api_key ){ build_stubbed :api_key, referential: referential, token: "#{referential.id}-#{random_hex}" } - - # http://www.example.com/workbenches/:workbench_id/imports/:id/download - let( :host ){ Rails.configuration.rails_host } - let( :path ){ download_workbench_import_path(workbench, import) } - - let( :downloaded_zip ){ double("downloaded zip") } - let( :download_zip_response ){ OpenStruct.new( body: downloaded_zip ) } - let( :download_token ){ random_string } - - let( :upload_path ) { api_v1_netex_imports_path(format: :json) } - - let( :subdirs ) do - entry_count.times.map do |i| - ZipService::Subdir.new( - "subdir #{i}", - double("subdir #{i}", rewind: 0, read: '') - ) - end - end - - let( :zip_service ){ double("zip service") } - let( :zip_file ){ open_fixture('multiple_references_import.zip') } - - let( :post_response_ok ){ double(status: 201, body: "{}") } - - before do - Timecop.freeze(Time.now) - - # Silence Logger - allow_any_instance_of(Logger).to receive(:info) - allow_any_instance_of(Logger).to receive(:warn) - - # That should be `build_stubbed's` job, no? - allow(Import).to receive(:find).with(import.id).and_return(import) - - allow(Api::V1::ApiKey).to receive(:from).and_return(api_key) - allow(ZipService).to receive(:new).with(downloaded_zip).and_return zip_service - expect(zip_service).to receive(:subdirs).and_return(subdirs) - expect( import ).to receive(:update).with( - status: 'running', - started_at: Time.now - ) - end - - after do - Timecop.return - end - - - context 'multireferential zipfile, no errors' do - let( :entry_count ){ 2 } - - it 'downloads a zip file, cuts it, and uploads all pieces' do - - expect(HTTPService).to receive(:get_resource) - .with(host: host, path: path, params: {token: download_token}) - .and_return( download_zip_response ) - - subdirs.each do |subdir| - mock_post subdir, post_response_ok - end - - expect( import ).to receive(:update).with(total_steps: 2) - expect( import ).to receive(:update).with(current_step: 1) - expect( import ).to receive(:update).with(current_step: 2) - expect( import ).to receive(:update).with(ended_at: Time.now) - - worker.perform import.id - - end - end - - context 'multireferential zipfile with error' do - let( :entry_count ){ 3 } - let( :post_response_failure ){ double(status: 406, body: {error: 'What was you thinking'}) } - - it 'downloads a zip file, cuts it, and uploads some pieces' do - expect(HTTPService).to receive(:get_resource) - .with(host: host, path: path, params: {token: download_token}) - .and_return( download_zip_response ) - - # First subdir succeeds - subdirs[0..0].each do |subdir| - mock_post subdir, post_response_ok - end - - # Second subdir fails (M I S E R A B L Y) - subdirs[1..1].each do |subdir| - mock_post subdir, post_response_failure - end - - expect( import ).to receive(:update).with(total_steps: 3) - expect( import ).to receive(:update).with(current_step: 1) - expect( import ).to receive(:update).with(current_step: 2) - expect( import ).to receive(:update).with(current_step: 3, status: 'failed') - - expect { worker.perform import.id }.to raise_error(StopIteration) - - end - end - - def mock_post subdir, response - allow(HTTPService).to receive(:upload) - expect( HTTPService ).to receive(:post_resource) - .with( - host: host, - path: upload_path, - params: { - netex_import: { - parent_id: import.id, - parent_type: import.class.name, - workbench_id: workbench.id, - name: subdir.name, - file: HTTPService.upload( - subdir.stream, - 'application/zip', - "#{subdir.name}.zip" - ) - } - } - ).and_return(response) - end -end -- cgit v1.2.3 From ddd885d2acec8a39a82dfb34e7810b52c8f01c94 Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 23 Oct 2017 13:12:13 +0200 Subject: Refs: #4633@1h; Implenting correct message for corrupt zip file --- app/workers/workbench_import_worker.rb | 2 +- config/locales/import_messages.en.yml | 1 + config/locales/import_messages.fr.yml | 1 + .../workbench_import/workbench_import_with_corrupt_zip_spec.rb | 8 ++++++-- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/app/workers/workbench_import_worker.rb b/app/workers/workbench_import_worker.rb index ef95cad51..b28e96acc 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) + @workbench_import.messages.create(criticity: :error, message_key: 'corrupt_zip_file', message_attributes: {import_name: @workbench_import.name}) end def upload zip_service diff --git a/config/locales/import_messages.en.yml b/config/locales/import_messages.en.yml index 4009d7c77..a1a133527 100644 --- a/config/locales/import_messages.en.yml +++ b/config/locales/import_messages.en.yml @@ -1,6 +1,7 @@ en: import_messages: compliance_check_messages: + corrupt_zip_file: "The zip file of WorkbenchImport %{import_name} is corrupted and cannot be read" 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 085299bb4..f77c32b34 100644 --- a/config/locales/import_messages.fr.yml +++ b/config/locales/import_messages.fr.yml @@ -1,6 +1,7 @@ fr: import_messages: compliance_check_messages: + corrupt_zip_file: "Le fichier zip du WorkbenchImport %{import_name} est corrompu, et ne peut être lu" 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/spec/workers/workbench_import/workbench_import_with_corrupt_zip_spec.rb b/spec/workers/workbench_import/workbench_import_with_corrupt_zip_spec.rb index 344943ad7..5e34b208a 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 @@ -18,8 +18,12 @@ RSpec.describe WorkbenchImportWorker do end it 'does create a message' do - expect{ subject.perform(workbench_import.id) }.to change{ workbench_import.messages.count }.by(1) - expect( workbench_import.messages.last.criticity ).to eq('error') + expect{ subject.perform(workbench_import.id) }.to change{ workbench_import.messages.count }.by(1) + + 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 ) end it 'does not change current step' do -- cgit v1.2.3 From f88df773cb31c9967430af0c3cd7bd9df46e46e0 Mon Sep 17 00:00:00 2001 From: Robert Date: Mon, 23 Oct 2017 13:30:57 +0200 Subject: Fixes: #4633@0.5h; Implenting correct message for inconsistent zip file --- app/workers/workbench_import_worker.rb | 11 ++++++++--- config/locales/import_messages.en.yml | 1 + spec/workers/workbench_import/workbench_import_worker_spec.rb | 7 +++++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/app/workers/workbench_import_worker.rb b/app/workers/workbench_import_worker.rb index b28e96acc..80f458e1c 100644 --- a/app/workers/workbench_import_worker.rb +++ b/app/workers/workbench_import_worker.rb @@ -50,12 +50,17 @@ class WorkbenchImportWorker def update_object_state entry, count @workbench_import.update( current_step: count ) - # TODO: Determine the other attributes of the message, especially how to add the names - # of the spurious dirs entry.spurious unless entry.spurious.empty? - @workbench_import.messages.create(criticity: :warning, message_key: 'xxx') + @workbench_import.messages.create( + criticity: :warning, + message_key: 'inconsistent_zip_file', + message_attributes: { + 'import_name' => @workbench_import.name, + 'spurious_dirs' => entry.spurious.inspect + }) end end + def upload_entry_group entry, element_count update_object_state entry, element_count.succ # status = retry_service.execute(&upload_entry_group_proc(entry)) diff --git a/config/locales/import_messages.en.yml b/config/locales/import_messages.en.yml index a1a133527..528ab3477 100644 --- a/config/locales/import_messages.en.yml +++ b/config/locales/import_messages.en.yml @@ -2,6 +2,7 @@ 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" 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/spec/workers/workbench_import/workbench_import_worker_spec.rb b/spec/workers/workbench_import/workbench_import_worker_spec.rb index 17cb7e16b..9f860a6b3 100644 --- a/spec/workers/workbench_import/workbench_import_worker_spec.rb +++ b/spec/workers/workbench_import/workbench_import_worker_spec.rb @@ -114,6 +114,9 @@ RSpec.describe WorkbenchImportWorker, type: [:worker, :request] do let( :spurious2 ){ [random_string, random_string] } 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.inspect}) } + let( :message2_attributes ){ message_attributes.merge(message_attributes: {'import_name' => import.name, 'spurious_dirs' => spurious2.inspect}) } before do allow(import).to receive(:messages).and_return(messages) @@ -131,9 +134,9 @@ RSpec.describe WorkbenchImportWorker, type: [:worker, :request] do expect( import ).to receive(:update).with(total_steps: 2) expect( import ).to receive(:update).with(current_step: 1) - expect( messages ).to receive(:create).with(criticity: :warning, message_key: 'xxx') + expect( messages ).to receive(:create).with(message1_attributes) expect( import ).to receive(:update).with(current_step: 2) - expect( messages ).to receive(:create).with(criticity: :warning, message_key: 'xxx') + expect( messages ).to receive(:create).with(message2_attributes) expect( import ).to receive(:update).with(ended_at: Time.now) worker.perform import.id -- cgit v1.2.3 From 489d2b19f4039daa14799122901f6e27b6c0dba5 Mon Sep 17 00:00:00 2001 From: cedricnjanga Date: Tue, 24 Oct 2017 15:50:43 +0200 Subject: Simplify extension file validation --- app/controllers/api/v1/imports_controller.rb | 1 - app/controllers/imports_controller.rb | 7 ------- app/models/import.rb | 7 +------ 3 files changed, 1 insertion(+), 14 deletions(-) diff --git a/app/controllers/api/v1/imports_controller.rb b/app/controllers/api/v1/imports_controller.rb index 197e23337..3d7f4ca79 100644 --- a/app/controllers/api/v1/imports_controller.rb +++ b/app/controllers/api/v1/imports_controller.rb @@ -8,7 +8,6 @@ class Api::V1::ImportsController < Api::V1::IbooController if @import.valid? create! else - binding.pry render json: { status: "error", messages: @import.errors.full_messages } end end diff --git a/app/controllers/imports_controller.rb b/app/controllers/imports_controller.rb index 66dccc243..3c52dc935 100644 --- a/app/controllers/imports_controller.rb +++ b/app/controllers/imports_controller.rb @@ -38,13 +38,6 @@ class ImportsController < BreadcrumbController end end - def create - create! do |success, failure| - success.html { redirect_to workbench_imports_path } - failure.html { flash.now[:error] = @import.errors[:wrong_file_extension][0] if @import.file.file; render :new } - end - end - def download if params[:token] == resource.token_download send_file resource.file.path diff --git a/app/models/import.rb b/app/models/import.rb index 72d9f2ce6..4ff8326ab 100644 --- a/app/models/import.rb +++ b/app/models/import.rb @@ -18,12 +18,7 @@ class Import < ActiveRecord::Base validates :file, presence: true validates_presence_of :workbench, :creator - - validate def file_extension_must_be_zip - if self.file.file - errors.add(:wrong_file_extension, I18n.t('activerecord.errors.models.imports.wrong_file_extension')) unless self.file.file.extension == "zip" - end - end + validates_format_of :file, with: %r{\.zip\z}i, message: I18n.t('activerecord.errors.models.imports.wrong_file_extension') before_create :initialize_fields -- cgit v1.2.3 From 671d58819a33c6b15c6241859ee039031842f065 Mon Sep 17 00:00:00 2001 From: Robert Date: Tue, 24 Oct 2017 15:38:42 +0200 Subject: Fixes: #4633;@0.5h; CR changes --- INSTALL.md | 5 ----- app/workers/workbench_import_worker.rb | 2 +- config/locales/import_messages.fr.yml | 1 + 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index 1da342e39..6e497b580 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -27,11 +27,6 @@ Otherwise please make sure to use a compatible version, still best to use the sa Then install yarn (`brew install yarn` does nicely on macOS). -## Webpack - -... is managed by the webpacker gem, thusly at latest - before starting your server and tests, setup webpacker with `bundle exec rake webpacker:install`. - ### Installation Caveats #### Node Related Issue, libv8 diff --git a/app/workers/workbench_import_worker.rb b/app/workers/workbench_import_worker.rb index 80f458e1c..300fad9e2 100644 --- a/app/workers/workbench_import_worker.rb +++ b/app/workers/workbench_import_worker.rb @@ -56,7 +56,7 @@ class WorkbenchImportWorker message_key: 'inconsistent_zip_file', message_attributes: { 'import_name' => @workbench_import.name, - 'spurious_dirs' => entry.spurious.inspect + 'spurious_dirs' => entry.spurious.join(', ') }) end end diff --git a/config/locales/import_messages.fr.yml b/config/locales/import_messages.fr.yml index f77c32b34..15de6eed8 100644 --- a/config/locales/import_messages.fr.yml +++ b/config/locales/import_messages.fr.yml @@ -2,6 +2,7 @@ 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" 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" -- cgit v1.2.3 From f4aa0048c144e4d382184213f76ace9f4109577d Mon Sep 17 00:00:00 2001 From: cedricnjanga Date: Tue, 24 Oct 2017 17:27:54 +0200 Subject: Fix error on build due to missing translation --- spec/factories/imports.rb | 16 ++++++++++++++++ spec/factories/netex_imports.rb | 2 +- spec/factories/workbench_imports.rb | 2 +- spec/models/import_spec.rb | 3 +++ 4 files changed, 21 insertions(+), 2 deletions(-) diff --git a/spec/factories/imports.rb b/spec/factories/imports.rb index 2c53106c3..e9986b074 100644 --- a/spec/factories/imports.rb +++ b/spec/factories/imports.rb @@ -1,5 +1,21 @@ FactoryGirl.define do factory :import do + sequence(:name) { |n| "Import #{n}" } + current_step_id "MyString" + current_step_progress 1.5 + association :workbench + association :referential + file {File.open(File.join(Rails.root, 'spec', 'fixtures', 'OFFRE_TRANSDEV_2017030112251.zip'))} + status :new + started_at nil + ended_at nil + creator 'rspec' + + after(:build) do |import| + import.class.skip_callback(:create, :before, :initialize_fields) + end + + factory :badimport do sequence(:name) { |n| "Import #{n}" } current_step_id "MyString" current_step_progress 1.5 diff --git a/spec/factories/netex_imports.rb b/spec/factories/netex_imports.rb index 057e47730..9e9d836e4 100644 --- a/spec/factories/netex_imports.rb +++ b/spec/factories/netex_imports.rb @@ -1,5 +1,5 @@ FactoryGirl.define do factory :netex_import, class: NetexImport, parent: :import do - file { File.open(Rails.root.join('spec', 'fixtures', 'terminated_job.json')) } + file { File.open(Rails.root.join('spec', 'fixtures', 'OFFRE_TRANSDEV_2017030112251.zip')) } end end diff --git a/spec/factories/workbench_imports.rb b/spec/factories/workbench_imports.rb index 5cdcfd15f..466bfe688 100644 --- a/spec/factories/workbench_imports.rb +++ b/spec/factories/workbench_imports.rb @@ -1,5 +1,5 @@ FactoryGirl.define do factory :workbench_import, class: WorkbenchImport, parent: :import do - file { File.open(Rails.root.join('spec', 'fixtures', 'terminated_job.json')) } + file { File.open(Rails.root.join('spec', 'fixtures', 'OFFRE_TRANSDEV_2017030112251.zip')) } end end diff --git a/spec/models/import_spec.rb b/spec/models/import_spec.rb index cd5a30982..c06d05dab 100644 --- a/spec/models/import_spec.rb +++ b/spec/models/import_spec.rb @@ -10,6 +10,9 @@ 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_not allow_values('file.json', 'file.png', 'file.pdf').for(:file) } + let(:workbench_import) { build_stubbed(:workbench_import) } let(:workbench_import_with_completed_steps) do workbench_import = build_stubbed( -- cgit v1.2.3 From 2568e7f7553c82adb0bed1521ef9f013df9df87e Mon Sep 17 00:00:00 2001 From: cedricnjanga Date: Tue, 24 Oct 2017 17:37:18 +0200 Subject: Fix typo in import factory --- spec/factories/imports.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/factories/imports.rb b/spec/factories/imports.rb index e9986b074..e07447b60 100644 --- a/spec/factories/imports.rb +++ b/spec/factories/imports.rb @@ -14,8 +14,9 @@ FactoryGirl.define do after(:build) do |import| import.class.skip_callback(:create, :before, :initialize_fields) end + end - factory :badimport do + factory :bad_import do sequence(:name) { |n| "Import #{n}" } current_step_id "MyString" current_step_progress 1.5 -- cgit v1.2.3