From c1efd1d00bb3e11077b864ccd9dc4d757d7974cd Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 25 Sep 2015 14:09:55 +0100 Subject: [PATCH 001/365] moved test-unit out of test group --- Gemfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Gemfile b/Gemfile index 410aeecbc0..805715ef84 100644 --- a/Gemfile +++ b/Gemfile @@ -144,7 +144,6 @@ gem 'geoip' gem 'clerk' gem 'paper_trail', '~> 4.0.0.beta' - gem 'rails-secrets' gem 'dotenv-rails' From 6db7a48a13fedda76c1f2db9a3c1e2ac93bdb3dc Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Tue, 6 Jan 2015 10:48:37 +0100 Subject: [PATCH 002/365] First implementation of the new name wizard. Working with accepted names --- .../new_name_controller.rb | 92 +++++++++++++++++++ .../admin/nomenclature_changes_helper.rb | 15 +++ app/models/nomenclature_change/new_name.rb | 59 ++++++++++++ .../new_name/constructor.rb | 12 +++ .../nomenclature_change/new_name/processor.rb | 18 ++++ app/models/nomenclature_change/output.rb | 14 +-- .../admin/nomenclature_changes/index.html.erb | 9 +- .../new_name/accepted_names.html.erb | 19 ++++ .../new_name/author_year.html.erb | 19 ++++ .../new_name/hybrid_parents.html.erb | 22 +++++ .../new_name/name_status.html.erb | 19 ++++ .../new_name/parent.html.erb | 21 +++++ .../new_name/rank.html.erb | 20 ++++ .../new_name/scientific_name.html.erb | 19 ++++ .../new_name/summary.html.erb | 3 + .../new_name/taxonomy.html.erb | 19 ++++ config/routes.rb | 1 + ...onomy_id_to_nomenclature_change_outputs.rb | 5 + 18 files changed, 379 insertions(+), 7 deletions(-) create mode 100644 app/controllers/admin/nomenclature_changes/new_name_controller.rb create mode 100644 app/models/nomenclature_change/new_name.rb create mode 100644 app/models/nomenclature_change/new_name/constructor.rb create mode 100644 app/models/nomenclature_change/new_name/processor.rb create mode 100644 app/views/admin/nomenclature_changes/new_name/accepted_names.html.erb create mode 100644 app/views/admin/nomenclature_changes/new_name/author_year.html.erb create mode 100644 app/views/admin/nomenclature_changes/new_name/hybrid_parents.html.erb create mode 100644 app/views/admin/nomenclature_changes/new_name/name_status.html.erb create mode 100644 app/views/admin/nomenclature_changes/new_name/parent.html.erb create mode 100644 app/views/admin/nomenclature_changes/new_name/rank.html.erb create mode 100644 app/views/admin/nomenclature_changes/new_name/scientific_name.html.erb create mode 100644 app/views/admin/nomenclature_changes/new_name/summary.html.erb create mode 100644 app/views/admin/nomenclature_changes/new_name/taxonomy.html.erb create mode 100644 db/migrate/20150105101526_add_taxonomy_id_to_nomenclature_change_outputs.rb diff --git a/app/controllers/admin/nomenclature_changes/new_name_controller.rb b/app/controllers/admin/nomenclature_changes/new_name_controller.rb new file mode 100644 index 0000000000..0db968d435 --- /dev/null +++ b/app/controllers/admin/nomenclature_changes/new_name_controller.rb @@ -0,0 +1,92 @@ +class Admin::NomenclatureChanges::NewNameController < Admin::NomenclatureChanges::BuildController + + steps *NomenclatureChange::NewName::STEPS + + def show + builder = NomenclatureChange::NewName::Constructor.new(@nomenclature_change) + case step + when :name_status + builder.build_output + when :parent + set_new_name_taxonomy + skip_or_previous_step if @nomenclature_change.output.new_name_status != 'A' + when :accepted_names + set_new_name_taxonomy + skip_or_previous_step if ['A','H','N'].include?(@nomenclature_change.output.new_name_status) + when :hybrid_parents + set_new_name_taxonomy + hybrid_skip_or_previous_step if @nomenclature_change.output.new_name_status != 'H' + when :summary + processor = NomenclatureChange::NewName::Processor.new(@nomenclature_change) + @summary = processor.summary + end + render_wizard + end + + def update + @nomenclature_change.assign_attributes( + (params[:nomenclature_change_new_name] || {}).merge({ + :status => (step == steps.last ? NomenclatureChange::SUBMITTED : step.to_s) + }) + ) + + case step + when :parent + set_new_name_taxonomy + end + + success = @nomenclature_change.valid? + + render_wizard @nomenclature_change + end + + private + def klass + NomenclatureChange::NewName + end + + def init_new_name nomenclature_change + #output = nomenclature_change.build_output + #tc = @nomenclature_change.output.build_new_taxon_concept + nomenclature_change.assign_attributes({"output_attributes" => + { + "taxon_concept_id"=>"", + "new_parent_id"=>"2036", + "new_scientific_name"=>"lumpus#{@nomenclature_change.id}", + "new_author_year"=>"Ferdinando, 2014", + "new_rank_id"=>8, + "new_name_status"=>"A" + } + }) + end + + def output_attributes + {"output_attributes" => + { + "taxon_concept_id"=>"", + "new_parent_id"=>"2036", + "new_scientific_name"=>"lumpus#{@nomenclature_change.id}", + "new_author_year"=>"Ferdinando, 2014", + "new_rank_id"=>8, + "new_name_status"=>"A" + }.merge(params[:nomenclature_change_new_name][:output_attributes]) + } + end + + def set_new_name_taxonomy + @taxonomy = Taxonomy.find(@nomenclature_change.output.taxonomy_id) + end + + def hybrid_skip_or_previous_step + if params[:back] + if @nomenclature_change.output.new_name_status != 'A' + jump_to(:rank) + else + jump_to(previous_step) + end + else + skip_step + end + end + +end diff --git a/app/helpers/admin/nomenclature_changes_helper.rb b/app/helpers/admin/nomenclature_changes_helper.rb index 038db2ed41..cb849fed10 100644 --- a/app/helpers/admin/nomenclature_changes_helper.rb +++ b/app/helpers/admin/nomenclature_changes_helper.rb @@ -320,4 +320,19 @@ def name_reassignment_label(reassignment) end end + def select_taxonomy + select("taxonomy","taxonomy_id", Taxonomy.all.collect {|t| [t.name, t.id]}) + end + + def select_rank + select("rank", "rank_id", ranks_collection) + end + + def ranks_collection + Rank.all.collect {|r| [r.name, r.id]} + end + + def taxon_concepts_collection + TaxonConcept.where(:taxonomy_id => 1).collect {|t| [t.full_name, t.id]} + end end diff --git a/app/models/nomenclature_change/new_name.rb b/app/models/nomenclature_change/new_name.rb new file mode 100644 index 0000000000..a80938048b --- /dev/null +++ b/app/models/nomenclature_change/new_name.rb @@ -0,0 +1,59 @@ +# event_id :integer +# type :string(255) not null +# status :string(255) not null +# created_by_id :integer not null +# updated_by_id :integer not null +# created_at :datetime not null +# updated_at :datetime not null + +class NomenclatureChange::NewName < NomenclatureChange + build_steps(:name_status, :taxonomy, :rank, :parent, :hybrid_parents, + :scientific_name, :author_year, :accepted_names, + :summary) + attr_accessible :output_attributes + + has_one :output, :inverse_of => :nomenclature_change, + :class_name => NomenclatureChange::Output, + :foreign_key => :nomenclature_change_id, + :dependent => :destroy + + accepts_nested_attributes_for :output, :allow_destroy => true + + validates :status, inclusion: { + in: self.status_dict, + message: "%{value} is not a valid status" + } + validate :required_different_name, if: :scientific_name_step? + validate :parent_at_immediately_higher_rank, if: :parent_step? + + def scientific_name_step? + status == 'scientific_name' + end + + def parent_step? + status == 'parent' + end + + def required_different_name + if output.present? + if output.new_full_name.nil? + errors.add(:outputs, "Scientific name is required") + return false + elsif output.taxon_name_already_existing? && + !output.new_full_name.nil? + errors.add(:outputs, "Name already existing") + return false + end + end + end + + def parent_at_immediately_higher_rank + return true if (output.new_parent.rank.name == 'KINGDOM' && output.new_parent.full_name == 'Plantae' && output.new_rank.name == 'ORDER') + unless output.new_parent.rank.taxonomic_position >= output.new_rank.parent_rank_lower_bound && + output.new_parent.rank.taxonomic_position < output.new_rank.taxonomic_position + errors.add(:new_parent_id, "must be at immediately higher rank") + return false + end + end + +end \ No newline at end of file diff --git a/app/models/nomenclature_change/new_name/constructor.rb b/app/models/nomenclature_change/new_name/constructor.rb new file mode 100644 index 0000000000..caf2c611e6 --- /dev/null +++ b/app/models/nomenclature_change/new_name/constructor.rb @@ -0,0 +1,12 @@ +class NomenclatureChange::NewName::Constructor + include NomenclatureChange::ConstructorHelpers + + def initialize(nomenclature_change) + @nomenclature_change = nomenclature_change + end + + def build_output + @nomenclature_change.build_output if @nomenclature_change.output.nil? + end + +end \ No newline at end of file diff --git a/app/models/nomenclature_change/new_name/processor.rb b/app/models/nomenclature_change/new_name/processor.rb new file mode 100644 index 0000000000..c2230f8b6d --- /dev/null +++ b/app/models/nomenclature_change/new_name/processor.rb @@ -0,0 +1,18 @@ +class NomenclatureChange::NewName::Processor < NomenclatureChange::Processor + + def summary + "Summary" + end + + private + + def prepare_chain + chain = [] + chain << NomenclatureChange::OutputTaxonConceptProcessor.new(@output) + end + + def initialize_inputs_and_outputs + @output = @nc.output + end + +end \ No newline at end of file diff --git a/app/models/nomenclature_change/output.rb b/app/models/nomenclature_change/output.rb index ef06871efe..cff925a21e 100644 --- a/app/models/nomenclature_change/output.rb +++ b/app/models/nomenclature_change/output.rb @@ -33,8 +33,8 @@ class NomenclatureChange::Output < ActiveRecord::Base track_who_does_it attr_accessible :nomenclature_change_id, :taxon_concept_id, - :new_taxon_concept_id, :new_scientific_name, :new_author_year, - :new_name_status, :new_parent_id, :new_rank_id, + :new_taxon_concept_id, :rank_id, :new_scientific_name, :new_author_year, + :new_name_status, :new_parent_id, :new_rank_id, :taxonomy_id, :note_en, :note_es, :note_fr, :internal_note, :is_primary_output, :parent_reassignments_attributes, :name_reassignments_attributes, :distribution_reassignments_attributes, :legislation_reassignments_attributes @@ -70,11 +70,11 @@ class NomenclatureChange::Output < ActiveRecord::Base belongs_to :new_rank, :class_name => Rank, :foreign_key => :new_rank_id validates :nomenclature_change, :presence => true validates :new_scientific_name, :presence => true, - :if => Proc.new { |c| c.taxon_concept_id.blank? } + :if => Proc.new { |c| c.taxon_concept_id.blank? && !c.nomenclature_change.is_a?(NomenclatureChange::NewName) } validates :new_parent_id, :presence => true, - :if => Proc.new { |c| c.taxon_concept_id.blank? } + :if => Proc.new { |c| c.taxon_concept_id.blank? && !c.nomenclature_change.is_a?(NomenclatureChange::NewName) } validate :validate_tmp_taxon_concept, - :if => Proc.new { |c| c.will_create_taxon? || c.will_update_taxon? } + :if => Proc.new { |c| (c.will_create_taxon? || c.will_update_taxon?) && !c.nomenclature_change.is_a?(NomenclatureChange::NewName) } before_validation :populate_taxon_concept_fields, :if => Proc.new { |c| (c.new_record? || c.taxon_concept_id_changed?) && c.taxon_concept } @@ -130,7 +130,9 @@ def tmp_taxon_concept :name_status => (new_name_status.present? ? new_name_status : name_status) } if will_create_taxon? - taxonomy = Taxonomy.find_by_name(Taxonomy::CITES_EU) + taxonomy = (taxonomy_id.present? ? Taxonomy.find(taxonomy_id) : + Taxonomy.find_by_name(Taxonomy::CITES_EU) + ) TaxonConcept.new( taxon_concept_attrs.merge({ :taxonomy_id => taxonomy.id, diff --git a/app/views/admin/nomenclature_changes/index.html.erb b/app/views/admin/nomenclature_changes/index.html.erb index 10bd329959..1ecc45524e 100644 --- a/app/views/admin/nomenclature_changes/index.html.erb +++ b/app/views/admin/nomenclature_changes/index.html.erb @@ -6,7 +6,14 @@

- + diff --git a/app/views/admin/nomenclature_changes/new_name/accepted_names.html.erb b/app/views/admin/nomenclature_changes/new_name/accepted_names.html.erb new file mode 100644 index 0000000000..f4a1bbc6d0 --- /dev/null +++ b/app/views/admin/nomenclature_changes/new_name/accepted_names.html.erb @@ -0,0 +1,19 @@ +

New name: accepted names

+

+ + Assign accepted names +

+<%= nomenclature_change_form do |f| %> +
+ <%= f.fields_for :output do |ff| %> + +
+ + <%= ff.select :taxon_relationship_ids, + options_for_select(taxon_concepts_collection,''), + {}, {:class => 'simple-taxon-concept', :multiple => ''} + %> +
+ <% end %> +
+<% end %> \ No newline at end of file diff --git a/app/views/admin/nomenclature_changes/new_name/author_year.html.erb b/app/views/admin/nomenclature_changes/new_name/author_year.html.erb new file mode 100644 index 0000000000..a928478003 --- /dev/null +++ b/app/views/admin/nomenclature_changes/new_name/author_year.html.erb @@ -0,0 +1,19 @@ +

New name: author-year

+

+ + Assign author-year +

+<%= nomenclature_change_form do |f| %> + +
+ <%= f.fields_for :output do |ff| %> + +
+ <%= ff.text_field :new_author_year, { + :class => 'new-author-year' + } %> +
+ <% end %> +
+ +<% end %> \ No newline at end of file diff --git a/app/views/admin/nomenclature_changes/new_name/hybrid_parents.html.erb b/app/views/admin/nomenclature_changes/new_name/hybrid_parents.html.erb new file mode 100644 index 0000000000..079bb16435 --- /dev/null +++ b/app/views/admin/nomenclature_changes/new_name/hybrid_parents.html.erb @@ -0,0 +1,22 @@ +

New name: hybrid parents

+

+ + Assign hybrid parents +

+<%= nomenclature_change_form do |f| %> +
+ <%= f.fields_for :output do |ff| %> + +
+ + <%= ff.text_field :new_parent_id, { + :class => 'taxon-concept parent-taxon', + :'data-name' => ff.object.new_parent.try(:full_name), + :'data-name-status' => ff.object.new_parent.try(:name_status), + :'data-name-status-filter' => ['A'].to_json, + :'data-taxonomy-id' => @taxonomy.id + } %> +
+ <% end %> +
+<% end %> \ No newline at end of file diff --git a/app/views/admin/nomenclature_changes/new_name/name_status.html.erb b/app/views/admin/nomenclature_changes/new_name/name_status.html.erb new file mode 100644 index 0000000000..b9e6ade55c --- /dev/null +++ b/app/views/admin/nomenclature_changes/new_name/name_status.html.erb @@ -0,0 +1,19 @@ +

New name: name status

+

+ + Assign name status +

+<%= nomenclature_change_form do |f| %> +
+ <%= f.fields_for :output do |ff| %> + +
+ <%= ff.select :new_name_status, + options_for_select(['A', 'N', 'S', 'T', 'H'], + ff.object.new_name_status), + {} + %> +
+ <% end %> +
+<% end %> \ No newline at end of file diff --git a/app/views/admin/nomenclature_changes/new_name/parent.html.erb b/app/views/admin/nomenclature_changes/new_name/parent.html.erb new file mode 100644 index 0000000000..20b54fba77 --- /dev/null +++ b/app/views/admin/nomenclature_changes/new_name/parent.html.erb @@ -0,0 +1,21 @@ +

New name: parent

+

+ + Assign parent +

+<%= nomenclature_change_form do |f| %> +
+ <%= f.fields_for :output do |ff| %> + +
+ <%= ff.text_field :new_parent_id, { + :class => 'taxon-concept parent-taxon', + :'data-name' => ff.object.new_parent.try(:full_name), + :'data-name-status' => ff.object.new_parent.try(:name_status), + :'data-name-status-filter' => ['A'].to_json, + :'data-taxonomy-id' => @taxonomy.id + } %> +
+ <% end %> +
+<% end %> \ No newline at end of file diff --git a/app/views/admin/nomenclature_changes/new_name/rank.html.erb b/app/views/admin/nomenclature_changes/new_name/rank.html.erb new file mode 100644 index 0000000000..9da910d332 --- /dev/null +++ b/app/views/admin/nomenclature_changes/new_name/rank.html.erb @@ -0,0 +1,20 @@ +

New name: rank

+

+ + Assign rank +

+<%= nomenclature_change_form do |f| %> +
+ <%= f.fields_for :output do |ff| %> + +
+ <%= ff.select :new_rank_id, + options_for_select(ranks_collection, + ff.object.new_rank_id), + {} + %> +
+ <% end %> +
+ +<% end %> \ No newline at end of file diff --git a/app/views/admin/nomenclature_changes/new_name/scientific_name.html.erb b/app/views/admin/nomenclature_changes/new_name/scientific_name.html.erb new file mode 100644 index 0000000000..96e6084e2c --- /dev/null +++ b/app/views/admin/nomenclature_changes/new_name/scientific_name.html.erb @@ -0,0 +1,19 @@ +

New name: scientific name

+

+ + Assign scientific name +

+<%= nomenclature_change_form do |f| %> + +
+ <%= f.fields_for :output do |ff| %> + +
+ <%= ff.text_field :new_scientific_name, { + :class => 'new-scientific-name' + } %> +
+ <% end %> +
+ +<% end %> \ No newline at end of file diff --git a/app/views/admin/nomenclature_changes/new_name/summary.html.erb b/app/views/admin/nomenclature_changes/new_name/summary.html.erb new file mode 100644 index 0000000000..51cee6b80a --- /dev/null +++ b/app/views/admin/nomenclature_changes/new_name/summary.html.erb @@ -0,0 +1,3 @@ +

New name: summary

+ +<%= render partial: 'admin/nomenclature_changes/build/summary' %> diff --git a/app/views/admin/nomenclature_changes/new_name/taxonomy.html.erb b/app/views/admin/nomenclature_changes/new_name/taxonomy.html.erb new file mode 100644 index 0000000000..5052fb012c --- /dev/null +++ b/app/views/admin/nomenclature_changes/new_name/taxonomy.html.erb @@ -0,0 +1,19 @@ +

New name: taxonomy

+

+ + Assign taxonomy +

+<%= nomenclature_change_form do |f| %> +
+ <%= f.fields_for :output do |ff| %> + +
+ <%= ff.select :taxonomy_id, + options_for_select([["CITES_EU",1],["CMS",2]], + ff.object.taxonomy_id), + {} + %> +
+ <% end %> +
+<% end %> \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index e6118ec4c4..19e644bfe5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -156,6 +156,7 @@ resources :status_to_synonym, controller: 'nomenclature_changes/status_to_synonym' resources :status_swap, controller: 'nomenclature_changes/status_swap' + resources :new_name, controller: 'nomenclature_changes/new_name' end match 'exports' => 'exports#index' match 'exports/download' => 'exports#download' diff --git a/db/migrate/20150105101526_add_taxonomy_id_to_nomenclature_change_outputs.rb b/db/migrate/20150105101526_add_taxonomy_id_to_nomenclature_change_outputs.rb new file mode 100644 index 0000000000..d5b2b43cbf --- /dev/null +++ b/db/migrate/20150105101526_add_taxonomy_id_to_nomenclature_change_outputs.rb @@ -0,0 +1,5 @@ +class AddTaxonomyIdToNomenclatureChangeOutputs < ActiveRecord::Migration + def change + add_column :nomenclature_change_outputs, :taxonomy_id, :integer + end +end From f53979c15e2bdf170e2d88eef9f5bc54a6955b71 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Wed, 30 Sep 2015 11:52:05 +0100 Subject: [PATCH 003/365] Renamed old migration --- ...50929175554_add_taxonomy_id_to_nomenclature_change_outputs.rb} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename db/migrate/{20150105101526_add_taxonomy_id_to_nomenclature_change_outputs.rb => 20150929175554_add_taxonomy_id_to_nomenclature_change_outputs.rb} (100%) diff --git a/db/migrate/20150105101526_add_taxonomy_id_to_nomenclature_change_outputs.rb b/db/migrate/20150929175554_add_taxonomy_id_to_nomenclature_change_outputs.rb similarity index 100% rename from db/migrate/20150105101526_add_taxonomy_id_to_nomenclature_change_outputs.rb rename to db/migrate/20150929175554_add_taxonomy_id_to_nomenclature_change_outputs.rb From 1afd6483a44ca82fe0df4bbb38987234caa2826f Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 2 Oct 2015 00:12:57 +0100 Subject: [PATCH 004/365] fixes full reassignment of common names, CITES quotas & suspensions --- .../nomenclature_change/full_reassignment.rb | 17 +++- .../reassignment_processor.rb | 2 + app/models/trade_restriction.rb | 3 +- .../full_reassignment_spec.rb | 78 +++++++++++++++++++ 4 files changed, 95 insertions(+), 5 deletions(-) create mode 100644 spec/models/nomenclature_change/full_reassignment_spec.rb diff --git a/app/models/nomenclature_change/full_reassignment.rb b/app/models/nomenclature_change/full_reassignment.rb index 1c9d816f9a..583727e64e 100644 --- a/app/models/nomenclature_change/full_reassignment.rb +++ b/app/models/nomenclature_change/full_reassignment.rb @@ -6,43 +6,52 @@ def initialize(old_taxon_concept, new_taxon_concept) end def process + Rails.logger.debug "FULL REASSIGNMENT #{@old_taxon_concept.full_name} to #{@new_taxon_concept.full_name}" update_attrs = { taxon_concept_id: @new_taxon_concept.id } # distributions + Rails.logger.debug "FULL REASSIGNMENT Distributions (#{@old_taxon_concept.distributions.count})" @old_taxon_concept.distributions.each do |d| d.update_attributes(update_attrs) end # references + Rails.logger.debug "FULL REASSIGNMENT References (#{@old_taxon_concept.taxon_concept_references.count})" @old_taxon_concept.taxon_concept_references.each do |tcr| tcr.update_attributes(update_attrs) end # listing changes + Rails.logger.debug "FULL REASSIGNMENT Listing Changes (#{@old_taxon_concept.listing_changes.count})" @old_taxon_concept.listing_changes.each do |lc| lc.update_attributes(update_attrs) end # EU opinions + Rails.logger.debug "FULL REASSIGNMENT EU Opinions (#{@old_taxon_concept.eu_opinions.count})" @old_taxon_concept.eu_opinions.each do |ed| ed.update_attributes(update_attrs) end # EU suspensions + Rails.logger.debug "FULL REASSIGNMENT EU Suspensions (#{@old_taxon_concept.eu_suspensions.count})" @old_taxon_concept.eu_suspensions.each do |ed| ed.update_attributes(update_attrs) end # CITES quotas - @old_taxon_concept.quotas do |tr| + Rails.logger.debug "FULL REASSIGNMENT CITES Quotas (#{@old_taxon_concept.quotas.count})" + @old_taxon_concept.quotas.each do |tr| tr.update_attributes(update_attrs) end # CITES suspensions - @old_taxon_concept.cites_suspensions do |tr| + Rails.logger.debug "FULL REASSIGNMENT CITES Suspensions (#{@old_taxon_concept.cites_suspensions.count})" + @old_taxon_concept.cites_suspensions.each do |tr| tr.update_attributes(update_attrs) end # common names - @old_taxon_concept.taxon_commons do |tc| + Rails.logger.debug "FULL REASSIGNMENT Common names (#{@old_taxon_concept.taxon_commons.count})" + @old_taxon_concept.taxon_commons.each do |tc| tc.update_attributes(update_attrs) end # shipments - Rails.logger.debug "Updating shipments where taxon concept = #{@old_taxon_concept.full_name} to have taxon concept = #{@new_taxon_concept.full_name}" + Rails.logger.debug "FULL REASSIGNMENT Shipments" Trade::Shipment.update_all( update_attrs, {taxon_concept_id: @old_taxon_concept.id} diff --git a/app/models/nomenclature_change/reassignment_processor.rb b/app/models/nomenclature_change/reassignment_processor.rb index 5902a4e47b..6c7554a83c 100644 --- a/app/models/nomenclature_change/reassignment_processor.rb +++ b/app/models/nomenclature_change/reassignment_processor.rb @@ -85,6 +85,7 @@ def conflicting_listing_change_reassignment?(reassignment, reassignable) end def post_process(reassigned_object, object_before_reassignment) + Rails.logger.warn("Resassignment post processing BEGIN") if reassigned_object.is_a?(TaxonConcept) resolver = NomenclatureChange::TaxonomicTreeNameResolver.new(reassigned_object) resolver.process @@ -92,6 +93,7 @@ def post_process(reassigned_object, object_before_reassignment) resolver = NomenclatureChange::TradeShipmentsResolver.new(reassigned_object, object_before_reassignment) resolver.process end + Rails.logger.warn("Resassignment post processing END") end end diff --git a/app/models/trade_restriction.rb b/app/models/trade_restriction.rb index 76694baf4e..80b47ab7e6 100644 --- a/app/models/trade_restriction.rb +++ b/app/models/trade_restriction.rb @@ -38,7 +38,8 @@ class TradeRestriction < ActiveRecord::Base :notes, :publication_date, :purpose_ids, :quota, :type, :source_ids, :start_date, :term_ids, :unit_id, :internal_notes, :nomenclature_note_en, :nomenclature_note_es, :nomenclature_note_fr, - :created_by_id, :updated_by_id, :url + :created_by_id, :updated_by_id, :url, + :taxon_concept_id belongs_to :taxon_concept belongs_to :m_taxon_concept, :foreign_key => :taxon_concept_id diff --git a/spec/models/nomenclature_change/full_reassignment_spec.rb b/spec/models/nomenclature_change/full_reassignment_spec.rb new file mode 100644 index 0000000000..e24cd9253b --- /dev/null +++ b/spec/models/nomenclature_change/full_reassignment_spec.rb @@ -0,0 +1,78 @@ +require 'spec_helper' + +describe NomenclatureChange::FullReassignment do + + describe 'process' do + let(:old_tc){ create_cites_eu_species } + let(:new_tc){ create_cites_eu_species } + subject { NomenclatureChange::FullReassignment.new(old_tc, new_tc) } + + context 'when distributions present' do + before(:each) do + create(:distribution, taxon_concept: old_tc) + subject.process + end + specify{ expect(new_tc.distributions.count).to eq(1) } + end + + context 'when references present' do + before(:each) do + create(:taxon_concept_reference, taxon_concept: old_tc) + subject.process + end + specify{ expect(new_tc.taxon_concept_references.count).to eq(1) } + end + + context 'when listing changes present' do + before(:each) do + create_cites_I_addition(taxon_concept: old_tc) + subject.process + end + specify{ expect(new_tc.listing_changes.count).to eq(1) } + end + + context 'when EU Opinions present' do + before(:each) do + create(:eu_opinion, taxon_concept: old_tc) + subject.process + end + specify{ expect(new_tc.eu_opinions.count).to eq(1) } + end + + context 'when EU Suspensions present' do + before(:each) do + create(:eu_suspension, taxon_concept: old_tc) + subject.process + end + specify{ expect(new_tc.eu_suspensions.count).to eq(1) } + end + + context 'when CITES Quotas present' do + before(:each) do + create(:quota, taxon_concept: old_tc, geo_entity: create(:geo_entity)) + subject.process + end + specify{ expect(new_tc.quotas.count).to eq(1) } + end + + context 'when CITES Suspensions present' do + before(:each) do + create(:cites_suspension, taxon_concept: old_tc, + start_notification: create(:cites_suspension_notification, :designation => cites) + ) + subject.process + end + specify{ expect(new_tc.cites_suspensions.count).to eq(1) } + end + + context 'when common names present' do + before(:each) do + create(:taxon_common, taxon_concept: old_tc) + subject.process + end + specify{ expect(new_tc.taxon_commons.count).to eq(1) } + end + + end + +end From 8642c7156e016d9afdaea9a28ec6d017a1b388eb Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 2 Oct 2015 15:48:25 +0100 Subject: [PATCH 005/365] move the auto-reassignments construction step to an earlier stage of the process to ensure reassignments are processed correctly and summaries of reassignments are accurate --- .../status_change/processor_helpers.rb | 2 +- .../nomenclature_change/status_change_helpers.rb | 2 -- app/models/nomenclature_change/status_swap.rb | 10 +++++++--- app/models/nomenclature_change/status_to_accepted.rb | 1 + app/models/nomenclature_change/status_to_synonym.rb | 1 + 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/app/models/nomenclature_change/status_change/processor_helpers.rb b/app/models/nomenclature_change/status_change/processor_helpers.rb index 7961c02ae1..3eb99d4dab 100644 --- a/app/models/nomenclature_change/status_change/processor_helpers.rb +++ b/app/models/nomenclature_change/status_change/processor_helpers.rb @@ -5,7 +5,7 @@ def reassignment_processor(output) # if input is not one of outputs, that means it only acts as a template # for associations and reassignment processor should copy rather than - # transfer associations + # transfer associations; if it is one of the outputs it is probably a swap transfer = [@primary_output, @secondary_output].compact.map(&:taxon_concept).include?( @input.taxon_concept ) diff --git a/app/models/nomenclature_change/status_change_helpers.rb b/app/models/nomenclature_change/status_change_helpers.rb index 3164822b70..fb0f2cd8ff 100644 --- a/app/models/nomenclature_change/status_change_helpers.rb +++ b/app/models/nomenclature_change/status_change_helpers.rb @@ -24,8 +24,6 @@ def self.included(base) accepts_nested_attributes_for :secondary_output, :allow_destroy => true validate :required_primary_output, if: :primary_output_or_submitting? - - before_save :build_auto_reassignments, if: :summary? end end diff --git a/app/models/nomenclature_change/status_swap.rb b/app/models/nomenclature_change/status_swap.rb index feaff45764..4fe3b304b4 100644 --- a/app/models/nomenclature_change/status_swap.rb +++ b/app/models/nomenclature_change/status_swap.rb @@ -29,13 +29,17 @@ class NomenclatureChange::StatusSwap < NomenclatureChange message: "%{value} is not a valid status" } before_save :build_input_for_swap, if: :swap? + before_save :build_auto_reassignments, if: :legislation? def build_input_for_swap # In case the primary output is an S name turning A # as part of status swap with another A name - # this other name becomes an input of the nomenclature change, so that - # reassignments can be put in place between this input and - # the primary output + # the secondary output becomes a pseudo-input for reassignments + # to the primary output. + # In case the primary output is an A name turning S + # as part of status swap with anoter S name + # the primary output becomes a pseudo-input for reassignments + # to the secondary output. if needs_to_receive_associations? && ( input.nil? || input.taxon_concept_id.blank?) build_input(taxon_concept_id: secondary_output.taxon_concept_id) diff --git a/app/models/nomenclature_change/status_to_accepted.rb b/app/models/nomenclature_change/status_to_accepted.rb index 3c3882d8a0..4b0a82e784 100644 --- a/app/models/nomenclature_change/status_to_accepted.rb +++ b/app/models/nomenclature_change/status_to_accepted.rb @@ -25,6 +25,7 @@ class NomenclatureChange::StatusToAccepted < NomenclatureChange before_validation :set_output_name_status, if: :primary_output_or_submitting? before_validation :set_output_rank_id, if: :primary_output_or_submitting? before_validation :set_output_parent_id, if: :primary_output_or_submitting? + before_save :build_auto_reassignments, if: :parent? def set_output_name_status primary_output && primary_output.new_name_status = 'A' diff --git a/app/models/nomenclature_change/status_to_synonym.rb b/app/models/nomenclature_change/status_to_synonym.rb index 2a44ec978e..e2739f9f42 100644 --- a/app/models/nomenclature_change/status_to_synonym.rb +++ b/app/models/nomenclature_change/status_to_synonym.rb @@ -30,6 +30,7 @@ class NomenclatureChange::StatusToSynonym < NomenclatureChange } validate :required_secondary_output, if: :relay_or_submitting? before_save :build_input_for_relay, if: :relay? + before_save :build_auto_reassignments, if: :legislation? before_validation :ensure_new_name_status, if: :primary_output? def ensure_new_name_status From e4c5e63c384634d9c4349f3dff509f2ae7d4e0c2 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Thu, 1 Oct 2015 12:12:53 +0100 Subject: [PATCH 006/365] Working creation of a new synonym --- .../nomenclature_changes/new_name_controller.rb | 4 +++- app/models/nomenclature_change/new_name.rb | 6 +++++- app/models/nomenclature_change/output.rb | 15 ++++++++++++--- .../new_name/accepted_names.html.erb | 14 ++++++++------ ...94410_add_output_fields_for_new_name_wizard.rb | 7 +++++++ 5 files changed, 35 insertions(+), 11 deletions(-) create mode 100644 db/migrate/20151001094410_add_output_fields_for_new_name_wizard.rb diff --git a/app/controllers/admin/nomenclature_changes/new_name_controller.rb b/app/controllers/admin/nomenclature_changes/new_name_controller.rb index 0db968d435..3bbd83b16f 100644 --- a/app/controllers/admin/nomenclature_changes/new_name_controller.rb +++ b/app/controllers/admin/nomenclature_changes/new_name_controller.rb @@ -8,8 +8,10 @@ def show when :name_status builder.build_output when :parent + #for synonyms not setting the parent will lead to a failure of the new_full_name method for output set_new_name_taxonomy - skip_or_previous_step if @nomenclature_change.output.new_name_status != 'A' + #skip_or_previous_step if @nomenclature_change.output.new_name_status != 'A' + skip_or_previous_step unless ['A','N'].include?(@nomenclature_change.output.new_name_status) when :accepted_names set_new_name_taxonomy skip_or_previous_step if ['A','H','N'].include?(@nomenclature_change.output.new_name_status) diff --git a/app/models/nomenclature_change/new_name.rb b/app/models/nomenclature_change/new_name.rb index a80938048b..cb7b3eae59 100644 --- a/app/models/nomenclature_change/new_name.rb +++ b/app/models/nomenclature_change/new_name.rb @@ -47,6 +47,10 @@ def required_different_name end end + def new_output_parent + nil + end + def parent_at_immediately_higher_rank return true if (output.new_parent.rank.name == 'KINGDOM' && output.new_parent.full_name == 'Plantae' && output.new_rank.name == 'ORDER') unless output.new_parent.rank.taxonomic_position >= output.new_rank.parent_rank_lower_bound && @@ -56,4 +60,4 @@ def parent_at_immediately_higher_rank end end -end \ No newline at end of file +end diff --git a/app/models/nomenclature_change/output.rb b/app/models/nomenclature_change/output.rb index cff925a21e..8908f91f9a 100644 --- a/app/models/nomenclature_change/output.rb +++ b/app/models/nomenclature_change/output.rb @@ -34,7 +34,7 @@ class NomenclatureChange::Output < ActiveRecord::Base track_who_does_it attr_accessible :nomenclature_change_id, :taxon_concept_id, :new_taxon_concept_id, :rank_id, :new_scientific_name, :new_author_year, - :new_name_status, :new_parent_id, :new_rank_id, :taxonomy_id, + :new_name_status, :new_parent_id, :new_rank_id, :taxonomy_id, :accepted_taxon_id, :note_en, :note_es, :note_fr, :internal_note, :is_primary_output, :parent_reassignments_attributes, :name_reassignments_attributes, :distribution_reassignments_attributes, :legislation_reassignments_attributes @@ -67,6 +67,7 @@ class NomenclatureChange::Output < ActiveRecord::Base :class_name => NomenclatureChange::ReassignmentTarget, :foreign_key => :nomenclature_change_output_id, :dependent => :destroy belongs_to :new_parent, :class_name => TaxonConcept, :foreign_key => :new_parent_id + belongs_to :accepted_taxon, :class_name => TaxonConcept, :foreign_key => :accepted_taxon_id belongs_to :new_rank, :class_name => Rank, :foreign_key => :new_rank_id validates :nomenclature_change, :presence => true validates :new_scientific_name, :presence => true, @@ -136,9 +137,9 @@ def tmp_taxon_concept TaxonConcept.new( taxon_concept_attrs.merge({ :taxonomy_id => taxonomy.id, - :full_name => display_full_name + :full_name => display_full_name, }) - ) + ).tap{ |tc| add_synonym_relationship(tc, accepted_taxon_id) } elsif will_update_taxon? taxon_concept.assign_attributes(taxon_concept_attrs) taxon_concept @@ -147,6 +148,14 @@ def tmp_taxon_concept end end + def add_synonym_relationship(tc, accepted_taxon_id) + tc.inverse_taxon_relationships.build( + :taxon_concept_id => accepted_taxon_id, + :taxon_relationship_type_id => TaxonRelationshipType. + find_by_name(TaxonRelationshipType::HAS_SYNONYM).id + ) if accepted_taxon_id + end + def validate_tmp_taxon_concept @tmp_taxon_concept = tmp_taxon_concept return true if @tmp_taxon_concept.valid? diff --git a/app/views/admin/nomenclature_changes/new_name/accepted_names.html.erb b/app/views/admin/nomenclature_changes/new_name/accepted_names.html.erb index f4a1bbc6d0..b48facd2a7 100644 --- a/app/views/admin/nomenclature_changes/new_name/accepted_names.html.erb +++ b/app/views/admin/nomenclature_changes/new_name/accepted_names.html.erb @@ -8,12 +8,14 @@ <%= f.fields_for :output do |ff| %>
- - <%= ff.select :taxon_relationship_ids, - options_for_select(taxon_concepts_collection,''), - {}, {:class => 'simple-taxon-concept', :multiple => ''} - %> + <%= ff.text_field :accepted_taxon_id, { + :class => 'taxon-concept', + :'data-name' => ff.object.accepted_taxon.try(:full_name), + :'data-name-status' => ff.object.accepted_taxon.try(:name_status), + :'data-name-status-filter' => ['A'].to_json, + :'data-taxonomy-id' => @taxonomy.id + } %>
<% end %> -<% end %> \ No newline at end of file +<% end %> diff --git a/db/migrate/20151001094410_add_output_fields_for_new_name_wizard.rb b/db/migrate/20151001094410_add_output_fields_for_new_name_wizard.rb new file mode 100644 index 0000000000..b45a32d34c --- /dev/null +++ b/db/migrate/20151001094410_add_output_fields_for_new_name_wizard.rb @@ -0,0 +1,7 @@ +class AddOutputFieldsForNewNameWizard < ActiveRecord::Migration + def change + add_column :nomenclature_change_outputs, :accepted_taxon_id, :integer + add_column :nomenclature_change_outputs, :hybrid_parent_id, :integer + add_column :nomenclature_change_outputs, :other_hybrid_parent_id, :integer + end +end From 3d9e149774637b70d6eef05647f0575f0a93057d Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Thu, 1 Oct 2015 12:45:43 +0100 Subject: [PATCH 007/365] New name hybrids working --- app/models/nomenclature_change/output.rb | 16 +++++--- .../new_name/hybrid_parents.html.erb | 39 ++++++++++++------- 2 files changed, 35 insertions(+), 20 deletions(-) diff --git a/app/models/nomenclature_change/output.rb b/app/models/nomenclature_change/output.rb index 8908f91f9a..f15a007d79 100644 --- a/app/models/nomenclature_change/output.rb +++ b/app/models/nomenclature_change/output.rb @@ -37,7 +37,7 @@ class NomenclatureChange::Output < ActiveRecord::Base :new_name_status, :new_parent_id, :new_rank_id, :taxonomy_id, :accepted_taxon_id, :note_en, :note_es, :note_fr, :internal_note, :is_primary_output, :parent_reassignments_attributes, :name_reassignments_attributes, - :distribution_reassignments_attributes, :legislation_reassignments_attributes + :distribution_reassignments_attributes, :legislation_reassignments_attributes, :hybrid_parent_id, :other_hybrid_parent_id belongs_to :nomenclature_change belongs_to :taxon_concept belongs_to :parent, :class_name => TaxonConcept, :foreign_key => :parent_id @@ -139,7 +139,11 @@ def tmp_taxon_concept :taxonomy_id => taxonomy.id, :full_name => display_full_name, }) - ).tap{ |tc| add_synonym_relationship(tc, accepted_taxon_id) } + ).tap do |tc| + add_taxon_relationship(tc, accepted_taxon_id, "HAS_SYNONYM") + add_taxon_relationship(tc, hybrid_parent_id, "HAS_HYBRID") + add_taxon_relationship(tc, other_hybrid_parent_id, "HAS_HYBRID") + end elsif will_update_taxon? taxon_concept.assign_attributes(taxon_concept_attrs) taxon_concept @@ -148,12 +152,12 @@ def tmp_taxon_concept end end - def add_synonym_relationship(tc, accepted_taxon_id) + def add_taxon_relationship(tc, other_taxon_id, rel_type) tc.inverse_taxon_relationships.build( - :taxon_concept_id => accepted_taxon_id, + :taxon_concept_id => other_taxon_id, :taxon_relationship_type_id => TaxonRelationshipType. - find_by_name(TaxonRelationshipType::HAS_SYNONYM).id - ) if accepted_taxon_id + find_by_name(TaxonRelationshipType.const_get(rel_type)).id + ) if other_taxon_id end def validate_tmp_taxon_concept diff --git a/app/views/admin/nomenclature_changes/new_name/hybrid_parents.html.erb b/app/views/admin/nomenclature_changes/new_name/hybrid_parents.html.erb index 079bb16435..0cc4bd71f2 100644 --- a/app/views/admin/nomenclature_changes/new_name/hybrid_parents.html.erb +++ b/app/views/admin/nomenclature_changes/new_name/hybrid_parents.html.erb @@ -4,19 +4,30 @@ Assign hybrid parents

<%= nomenclature_change_form do |f| %> -
- <%= f.fields_for :output do |ff| %> - + <%= f.fields_for :output do |ff| %> +
+
- - <%= ff.text_field :new_parent_id, { - :class => 'taxon-concept parent-taxon', - :'data-name' => ff.object.new_parent.try(:full_name), - :'data-name-status' => ff.object.new_parent.try(:name_status), - :'data-name-status-filter' => ['A'].to_json, - :'data-taxonomy-id' => @taxonomy.id - } %> + <%= ff.text_field :hybrid_parent_id, { + :class => 'taxon-concept', + :'data-name' => ff.object.new_parent.try(:full_name), + :'data-name-status' => ff.object.new_parent.try(:name_status), + :'data-name-status-filter' => ['A'].to_json, + :'data-taxonomy-id' => @taxonomy.id + } %>
- <% end %> -
-<% end %> \ No newline at end of file +
+
+ +
+ <%= ff.text_field :other_hybrid_parent_id, { + :class => 'taxon-concept', + :'data-name' => ff.object.new_parent.try(:full_name), + :'data-name-status' => ff.object.new_parent.try(:name_status), + :'data-name-status-filter' => ['A'].to_json, + :'data-taxonomy-id' => @taxonomy.id + } %> +
+
+ <% end %> +<% end %> From 866c308ff5e51142a2105e529cb06b5764b6c362 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Thu, 1 Oct 2015 13:26:05 +0100 Subject: [PATCH 008/365] Removed new taxon concept button and related modal windows --- app/helpers/taxon_concept_helper.rb | 22 +------------------ app/views/admin/taxon_concepts/index.html.erb | 4 ---- 2 files changed, 1 insertion(+), 25 deletions(-) diff --git a/app/helpers/taxon_concept_helper.rb b/app/helpers/taxon_concept_helper.rb index 1f01e32fab..e93e12c574 100644 --- a/app/helpers/taxon_concept_helper.rb +++ b/app/helpers/taxon_concept_helper.rb @@ -8,27 +8,7 @@ def admin_taxon_concept_title else controller_name.titleize end - ) + (content_tag(:div, :class => 'action-buttons') do - admin_add_new_taxon_concept_multi - end) - end - end - - def admin_add_new_taxon_concept_multi - content_tag(:div, :class => 'btn-group', :style => 'float:right') do - link_to(' Add new Taxon Concept'.html_safe, '#', :class => 'btn') + - link_to(''.html_safe, '#', :class => 'btn dropdown-toggle', :"data-toggle" => 'dropdown') + - content_tag(:ul, :class => 'dropdown-menu') do - content_tag(:li) do - link_to('Accepted name', '#new-taxon_concept', :"data-toggle" => 'modal') - end + - content_tag(:li) do - link_to('Synonym', '#new-taxon_concept_synonym', :"data-toggle" => 'modal') - end + - content_tag(:li) do - link_to('Hybrid', '#new-taxon_concept_hybrid', :"data-toggle" => 'modal') - end - end + ) end end diff --git a/app/views/admin/taxon_concepts/index.html.erb b/app/views/admin/taxon_concepts/index.html.erb index 2202b92c03..b9cbba2c8e 100644 --- a/app/views/admin/taxon_concepts/index.html.erb +++ b/app/views/admin/taxon_concepts/index.html.erb @@ -1,9 +1,5 @@ <%= admin_taxon_concept_title %> -<%= admin_new_modal %> -<%= admin_new_synonym_modal %> -<%= admin_new_hybrid_modal %> - <%= render :partial => 'search' %> <%= admin_table %> From 7b382b8ee48e961d1bf4c8321ca3dda108f13186 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Fri, 2 Oct 2015 14:02:37 +0100 Subject: [PATCH 009/365] Mutiple selection of accepted names for synonym --- .../admin/nomenclature_changes.js.coffee | 1 + app/models/nomenclature_change/output.rb | 31 +++++++++++++++---- .../new_name/accepted_names.html.erb | 7 +++-- ...0_add_output_fields_for_new_name_wizard.rb | 2 +- 4 files changed, 31 insertions(+), 10 deletions(-) diff --git a/app/assets/javascripts/admin/nomenclature_changes.js.coffee b/app/assets/javascripts/admin/nomenclature_changes.js.coffee index d7276b1112..233c552fab 100644 --- a/app/assets/javascripts/admin/nomenclature_changes.js.coffee +++ b/app/assets/javascripts/admin/nomenclature_changes.js.coffee @@ -28,6 +28,7 @@ $(document).ready -> results: formatted_taxon_concepts } $('.taxon-concept').select2(defaultTaxonSelect2Options) + $('.taxon-concept-multiple').select2($.extend(defaultTaxonSelect2Options,{multiple: true})) $('.taxon-concept').on('change', (event) -> return false unless event.val $.when($.ajax( '/admin/taxon_concepts/' + event.val + '.json' ) ).then(( data, textStatus, jqXHR ) => diff --git a/app/models/nomenclature_change/output.rb b/app/models/nomenclature_change/output.rb index f15a007d79..eeb966c8e7 100644 --- a/app/models/nomenclature_change/output.rb +++ b/app/models/nomenclature_change/output.rb @@ -31,10 +31,11 @@ # Outputs may be new taxon concepts, created as a result of the nomenclature # change. class NomenclatureChange::Output < ActiveRecord::Base + include PgArrayParser track_who_does_it attr_accessible :nomenclature_change_id, :taxon_concept_id, :new_taxon_concept_id, :rank_id, :new_scientific_name, :new_author_year, - :new_name_status, :new_parent_id, :new_rank_id, :taxonomy_id, :accepted_taxon_id, + :new_name_status, :new_parent_id, :new_rank_id, :taxonomy_id, :accepted_taxon_ids, :note_en, :note_es, :note_fr, :internal_note, :is_primary_output, :parent_reassignments_attributes, :name_reassignments_attributes, :distribution_reassignments_attributes, :legislation_reassignments_attributes, :hybrid_parent_id, :other_hybrid_parent_id @@ -79,6 +80,14 @@ class NomenclatureChange::Output < ActiveRecord::Base before_validation :populate_taxon_concept_fields, :if => Proc.new { |c| (c.new_record? || c.taxon_concept_id_changed?) && c.taxon_concept } + def accepted_taxon_ids + parse_pg_array(read_attribute(:accepted_taxon_ids)||"").compact + end + + def accepted_taxon_ids=(ary) + write_attribute(:accepted_taxon_ids, "{#{ary && ary.join(',')}}") + end + def populate_taxon_concept_fields self.parent_id = taxon_concept.parent_id_changed? ? taxon_concept.parent_id_was : taxon_concept.parent_id self.rank_id = taxon_concept.rank_id_changed? ? taxon_concept.rank_id_was : taxon_concept.rank_id @@ -140,9 +149,9 @@ def tmp_taxon_concept :full_name => display_full_name, }) ).tap do |tc| - add_taxon_relationship(tc, accepted_taxon_id, "HAS_SYNONYM") - add_taxon_relationship(tc, hybrid_parent_id, "HAS_HYBRID") - add_taxon_relationship(tc, other_hybrid_parent_id, "HAS_HYBRID") + add_taxon_synonym(tc, accepted_taxon_ids) + add_taxon_hybrid(tc, hybrid_parent_id) + add_taxon_hybrid(tc, other_hybrid_parent_id) end elsif will_update_taxon? taxon_concept.assign_attributes(taxon_concept_attrs) @@ -152,11 +161,21 @@ def tmp_taxon_concept end end - def add_taxon_relationship(tc, other_taxon_id, rel_type) + def add_taxon_synonym(tc, accepted_taxon_ids) + accepted_taxon_ids.each do |accepted_taxon_id| + tc.inverse_taxon_relationships.build( + :taxon_concept_id => accepted_taxon_id, + :taxon_relationship_type_id => TaxonRelationshipType. + find_by_name(TaxonRelationshipType::HAS_SYNONYM).id + ) + end + end + + def add_taxon_hybrid(tc, other_taxon_id) tc.inverse_taxon_relationships.build( :taxon_concept_id => other_taxon_id, :taxon_relationship_type_id => TaxonRelationshipType. - find_by_name(TaxonRelationshipType.const_get(rel_type)).id + find_by_name(TaxonRelationshipType::HAS_HYBRID).id ) if other_taxon_id end diff --git a/app/views/admin/nomenclature_changes/new_name/accepted_names.html.erb b/app/views/admin/nomenclature_changes/new_name/accepted_names.html.erb index b48facd2a7..12d05bea87 100644 --- a/app/views/admin/nomenclature_changes/new_name/accepted_names.html.erb +++ b/app/views/admin/nomenclature_changes/new_name/accepted_names.html.erb @@ -8,12 +8,13 @@ <%= f.fields_for :output do |ff| %>
- <%= ff.text_field :accepted_taxon_id, { - :class => 'taxon-concept', + <%= ff.text_field :accepted_taxon_ids, { + :class => 'taxon-concept-multiple', :'data-name' => ff.object.accepted_taxon.try(:full_name), :'data-name-status' => ff.object.accepted_taxon.try(:name_status), :'data-name-status-filter' => ['A'].to_json, - :'data-taxonomy-id' => @taxonomy.id + :'data-taxonomy-id' => @taxonomy.id, + :multiple => 'multiple' } %>
<% end %> diff --git a/db/migrate/20151001094410_add_output_fields_for_new_name_wizard.rb b/db/migrate/20151001094410_add_output_fields_for_new_name_wizard.rb index b45a32d34c..d0c235a86d 100644 --- a/db/migrate/20151001094410_add_output_fields_for_new_name_wizard.rb +++ b/db/migrate/20151001094410_add_output_fields_for_new_name_wizard.rb @@ -1,6 +1,6 @@ class AddOutputFieldsForNewNameWizard < ActiveRecord::Migration def change - add_column :nomenclature_change_outputs, :accepted_taxon_id, :integer + add_column :nomenclature_change_outputs, :accepted_taxon_ids, "INTEGER[]" add_column :nomenclature_change_outputs, :hybrid_parent_id, :integer add_column :nomenclature_change_outputs, :other_hybrid_parent_id, :integer end From 10a17057f7ea8feaf42ae2a679bc58edb928db5b Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Fri, 2 Oct 2015 14:03:01 +0100 Subject: [PATCH 010/365] Fixed wizard navigation --- .../new_name_controller.rb | 34 ++++++++++++++----- app/models/nomenclature_change/new_name.rb | 4 +-- 2 files changed, 27 insertions(+), 11 deletions(-) diff --git a/app/controllers/admin/nomenclature_changes/new_name_controller.rb b/app/controllers/admin/nomenclature_changes/new_name_controller.rb index 3bbd83b16f..ed64cee9f9 100644 --- a/app/controllers/admin/nomenclature_changes/new_name_controller.rb +++ b/app/controllers/admin/nomenclature_changes/new_name_controller.rb @@ -2,22 +2,22 @@ class Admin::NomenclatureChanges::NewNameController < Admin::NomenclatureChanges steps *NomenclatureChange::NewName::STEPS + before_filter :set_name_status, only: [:show] + def show builder = NomenclatureChange::NewName::Constructor.new(@nomenclature_change) case step when :name_status builder.build_output when :parent - #for synonyms not setting the parent will lead to a failure of the new_full_name method for output set_new_name_taxonomy - #skip_or_previous_step if @nomenclature_change.output.new_name_status != 'A' - skip_or_previous_step unless ['A','N'].include?(@nomenclature_change.output.new_name_status) + skip_or_previous_step unless ['A','N'].include?(@name_status) when :accepted_names set_new_name_taxonomy - skip_or_previous_step if ['A','H','N'].include?(@nomenclature_change.output.new_name_status) + skip_or_previous_step if ['A','H','N'].include?(@name_status) when :hybrid_parents set_new_name_taxonomy - hybrid_skip_or_previous_step if @nomenclature_change.output.new_name_status != 'H' + skip_or_previous_step if @name_status != 'H' when :summary processor = NomenclatureChange::NewName::Processor.new(@nomenclature_change) @summary = processor.summary @@ -33,6 +33,11 @@ def update ) case step + when :rank + case @nomenclature_change.output.new_name_status + when 'S' then jump_to(:accepted_names) + when 'H' then jump_to(:hybrid_parents) + end when :parent set_new_name_taxonomy end @@ -47,6 +52,14 @@ def klass NomenclatureChange::NewName end + def set_name_status + @name_status = '' + if @nomenclature_change.output and + [:parent, :accepted_names, :hybrid_parents].include?(step) + @name_status = @nomenclature_change.output.new_name_status + end + end + def init_new_name nomenclature_change #output = nomenclature_change.build_output #tc = @nomenclature_change.output.build_new_taxon_concept @@ -79,12 +92,15 @@ def set_new_name_taxonomy @taxonomy = Taxonomy.find(@nomenclature_change.output.taxonomy_id) end - def hybrid_skip_or_previous_step + def skip_or_previous_step if params[:back] - if @nomenclature_change.output.new_name_status != 'A' + if step == :accepted_names || step == :parent jump_to(:rank) - else - jump_to(previous_step) + elsif step == :hybrid_parents + case @nomenclature_change.output.new_name_status + when 'A' then jump_to(:parent) + when 'S' then jump_to(:accepted_names) + end end else skip_step diff --git a/app/models/nomenclature_change/new_name.rb b/app/models/nomenclature_change/new_name.rb index cb7b3eae59..55ba11cde2 100644 --- a/app/models/nomenclature_change/new_name.rb +++ b/app/models/nomenclature_change/new_name.rb @@ -7,8 +7,8 @@ # updated_at :datetime not null class NomenclatureChange::NewName < NomenclatureChange - build_steps(:name_status, :taxonomy, :rank, :parent, :hybrid_parents, - :scientific_name, :author_year, :accepted_names, + build_steps(:name_status, :taxonomy, :rank, :parent, :accepted_names, + :hybrid_parents, :scientific_name, :author_year, :summary) attr_accessible :output_attributes From fa947975304122ba88d80678ec606a295ad97069 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Fri, 2 Oct 2015 14:03:34 +0100 Subject: [PATCH 011/365] Added some tests for new_name controller --- .../new_name_controller_spec.rb | 160 ++++++++++++++++++ spec/factories/nomenclature_changes.rb | 3 + 2 files changed, 163 insertions(+) create mode 100644 spec/controllers/admin/nomenclature_changes/new_name_controller_spec.rb diff --git a/spec/controllers/admin/nomenclature_changes/new_name_controller_spec.rb b/spec/controllers/admin/nomenclature_changes/new_name_controller_spec.rb new file mode 100644 index 0000000000..4b0c8e3903 --- /dev/null +++ b/spec/controllers/admin/nomenclature_changes/new_name_controller_spec.rb @@ -0,0 +1,160 @@ +require 'spec_helper' + +describe Admin::NomenclatureChanges::NewNameController do + login_admin + + describe 'GET show' do + before(:each) do + @new_name = create(:nomenclature_change_new_name) + end + context :name_status do + it 'renders the name_status template' do + get :show, id: :name_status, nomenclature_change_id: @new_name.id + response.should render_template('name_status') + end + end + context :taxonomy do + it 'renders the taxonomy template' do + get :show, id: :taxonomy, nomenclature_change_id: @new_name.id + response.should render_template('taxonomy') + end + end + context :rank do + it 'renders the taxonomy template' do + get :show, id: :rank, nomenclature_change_id: @new_name.id + response.should render_template('rank') + end + end + context 'when is an accepted name' do + before(:each) do + @taxonomy = create(:taxonomy, name: "CITES_EU") + create(:nomenclature_change_output, + nomenclature_change: @new_name, + new_name_status: 'A', + taxonomy_id: @taxonomy.id + ) + end + it 'renders the parent template' do + get :show, id: :parent, nomenclature_change_id: @new_name.id + response.should render_template('parent') + end + end + context 'when is a synonym' do + before(:each) do + @taxonomy = create(:taxonomy, name: "CITES_EU") + create(:nomenclature_change_output, + nomenclature_change: @new_name, + new_name_status: 'S', + taxonomy_id: @taxonomy.id + ) + end + it 'renders the accepted_names template' do + get :show, id: :accepted_names, nomenclature_change_id: @new_name.id + response.should render_template('accepted_names') + end + end + context 'when is an hybrid' do + before(:each) do + @taxonomy = create(:taxonomy, name: "CITES_EU") + create(:nomenclature_change_output, + nomenclature_change: @new_name, + new_name_status: 'H', + taxonomy_id: @taxonomy.id + ) + end + it 'renders the hybrid_parents template' do + get :show, id: :hybrid_parents, nomenclature_change_id: @new_name.id + response.should render_template('hybrid_parents') + end + end + context :scientific_name do + it 'renders the scientific name template' do + get :show, id: :scientific_name, nomenclature_change_id: @new_name.id + response.should render_template('scientific_name') + end + end + context :summary do + it 'renders the summary template' do + get :show, id: :summary, nomenclature_change_id: @new_name.id + response.should render_template('summary') + end + end + end + + describe 'POST create' do + it 'redirects to new_name wizard' do + post :create, nomenclature_change_id: 'new' + response.should redirect_to(admin_nomenclature_change_new_name_url( + nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'name_status' + )) + end + end + + describe 'PUT update' do + before(:each) do + @new_name = create(:nomenclature_change_new_name) + @taxonomy = create(:taxonomy, name: "CITES_EU") + @rank = create(:rank, name: "SUBSPECIES") + end + context 'when successful' do + it 'redirects to next step' do + put :update, nomenclature_change_new_name: { + output_attributes: { new_name_status: 'A' }, + }, nomenclature_change_id: @new_name.id, id: 'name_status' + response.should redirect_to(admin_nomenclature_change_new_name_url( + nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'taxonomy' + )) + end + end + context 'when unsuccessful' do + it 're-renders step' do + put :update, nomenclature_change_new_name: { + output_attributes: { new_scientific_name: nil } + }, nomenclature_change_id: @new_name.id, id: 'scientific_name' + response.should render_template('scientific_name') + end + end + context 'when is accepted name' do + it 'redirects to parent step' do + put :update, nomenclature_change_new_name: { + output_attributes: { + new_name_status: 'A', + taxonomy_id: @taxonomy.id, + rank_id: @rank.id + }, + }, nomenclature_change_id: @new_name.id, id: 'rank' + response.should redirect_to(admin_nomenclature_change_new_name_url( + nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'parent' + )) + end + end + context 'when is synonym' do + it 'redirects to accepted names step' do + put :update, nomenclature_change_new_name: { + output_attributes: { + new_name_status: 'S', + taxonomy_id: @taxonomy.id, + rank_id: @rank.id + }, + }, nomenclature_change_id: @new_name.id, id: 'rank' + response.should redirect_to(admin_nomenclature_change_new_name_url( + nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'accepted_names' + )) + end + end + context 'when is synonym' do + it 'redirects to hybrid parents step' do + put :update, nomenclature_change_new_name: { + output_attributes: { + new_name_status: 'H', + taxonomy_id: @taxonomy.id, + rank_id: @rank.id + }, + }, nomenclature_change_id: @new_name.id, id: 'rank' + response.should redirect_to(admin_nomenclature_change_new_name_url( + nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'hybrid_parents' + )) + end + end + end +end diff --git a/spec/factories/nomenclature_changes.rb b/spec/factories/nomenclature_changes.rb index 8fb57fb7e5..5d5466be43 100644 --- a/spec/factories/nomenclature_changes.rb +++ b/spec/factories/nomenclature_changes.rb @@ -20,6 +20,9 @@ factory :nomenclature_change_status_to_synonym, class: NomenclatureChange::StatusToSynonym do type 'NomenclatureChange::StatusToSynonym' end + factory :nomenclature_change_new_name, class: NomenclatureChange::NewName do + type 'NomenclatureChange::NewName' + end end factory :nomenclature_change_input, class: NomenclatureChange::Input, From 07539e108fe232d89b656614438c183d7971a7da Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Fri, 2 Oct 2015 14:39:05 +0100 Subject: [PATCH 012/365] Added nomenclature notes step --- app/models/nomenclature_change/new_name.rb | 2 +- .../nomenclature_change/new_name/constructor.rb | 3 +-- .../new_name/nomenclature_notes.html.erb | 12 ++++++++++++ 3 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 app/views/admin/nomenclature_changes/new_name/nomenclature_notes.html.erb diff --git a/app/models/nomenclature_change/new_name.rb b/app/models/nomenclature_change/new_name.rb index 55ba11cde2..61a4f7ae6e 100644 --- a/app/models/nomenclature_change/new_name.rb +++ b/app/models/nomenclature_change/new_name.rb @@ -9,7 +9,7 @@ class NomenclatureChange::NewName < NomenclatureChange build_steps(:name_status, :taxonomy, :rank, :parent, :accepted_names, :hybrid_parents, :scientific_name, :author_year, - :summary) + :nomenclature_notes, :summary) attr_accessible :output_attributes has_one :output, :inverse_of => :nomenclature_change, diff --git a/app/models/nomenclature_change/new_name/constructor.rb b/app/models/nomenclature_change/new_name/constructor.rb index caf2c611e6..7c7afbd996 100644 --- a/app/models/nomenclature_change/new_name/constructor.rb +++ b/app/models/nomenclature_change/new_name/constructor.rb @@ -8,5 +8,4 @@ def initialize(nomenclature_change) def build_output @nomenclature_change.build_output if @nomenclature_change.output.nil? end - -end \ No newline at end of file +end diff --git a/app/views/admin/nomenclature_changes/new_name/nomenclature_notes.html.erb b/app/views/admin/nomenclature_changes/new_name/nomenclature_notes.html.erb new file mode 100644 index 0000000000..eccd2314d4 --- /dev/null +++ b/app/views/admin/nomenclature_changes/new_name/nomenclature_notes.html.erb @@ -0,0 +1,12 @@ +

New name: nomenclature change notes

+<%= nomenclature_change_form do |f| %> + <%= f.fields_for :output do |ff| %> +
+
+ <%= render partial: 'admin/nomenclature_changes/build/nomenclature_notes', + locals: {ff: ff} + %> +
+
+ <% end %> +<% end %> From 5f389773ffc638e7af7bf627032c9f923b44f134 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Fri, 2 Oct 2015 15:11:56 +0100 Subject: [PATCH 013/365] Added validation for hybrids --- .../nomenclature_changes/new_name_controller.rb | 2 +- app/models/nomenclature_change/new_name.rb | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/app/controllers/admin/nomenclature_changes/new_name_controller.rb b/app/controllers/admin/nomenclature_changes/new_name_controller.rb index ed64cee9f9..5daf8ba3d6 100644 --- a/app/controllers/admin/nomenclature_changes/new_name_controller.rb +++ b/app/controllers/admin/nomenclature_changes/new_name_controller.rb @@ -38,7 +38,7 @@ def update when 'S' then jump_to(:accepted_names) when 'H' then jump_to(:hybrid_parents) end - when :parent + when :parent, :hybrid_parents set_new_name_taxonomy end diff --git a/app/models/nomenclature_change/new_name.rb b/app/models/nomenclature_change/new_name.rb index 61a4f7ae6e..4fcf640bd5 100644 --- a/app/models/nomenclature_change/new_name.rb +++ b/app/models/nomenclature_change/new_name.rb @@ -25,6 +25,7 @@ class NomenclatureChange::NewName < NomenclatureChange } validate :required_different_name, if: :scientific_name_step? validate :parent_at_immediately_higher_rank, if: :parent_step? + validate :required_hybrids, if: :hybrid_parents_step? def scientific_name_step? status == 'scientific_name' @@ -34,6 +35,19 @@ def parent_step? status == 'parent' end + def hybrid_parents_step? + status == 'hybrid_parents' + end + + def required_hybrids + if output.present? + unless output.hybrid_parent_id && output.other_hybrid_parent_id + errors.add(:outputs, "Hybrid parents are required") + return false; + end + end + end + def required_different_name if output.present? if output.new_full_name.nil? From d5fa7edb9b82114062bd3321b9a72dbaee4cd423 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Fri, 2 Oct 2015 15:18:38 +0100 Subject: [PATCH 014/365] Fix hybrid parents step to fetch taxon names --- app/models/nomenclature_change/output.rb | 3 ++- .../nomenclature_changes/new_name/hybrid_parents.html.erb | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/models/nomenclature_change/output.rb b/app/models/nomenclature_change/output.rb index eeb966c8e7..95ed077dda 100644 --- a/app/models/nomenclature_change/output.rb +++ b/app/models/nomenclature_change/output.rb @@ -68,8 +68,9 @@ class NomenclatureChange::Output < ActiveRecord::Base :class_name => NomenclatureChange::ReassignmentTarget, :foreign_key => :nomenclature_change_output_id, :dependent => :destroy belongs_to :new_parent, :class_name => TaxonConcept, :foreign_key => :new_parent_id - belongs_to :accepted_taxon, :class_name => TaxonConcept, :foreign_key => :accepted_taxon_id belongs_to :new_rank, :class_name => Rank, :foreign_key => :new_rank_id + belongs_to :hybrid_parent, :class_name => TaxonConcept, :foreign_key => :hybrid_parent_id + belongs_to :other_hybrid_parent, :class_name => TaxonConcept, :foreign_key => :other_hybrid_parent_id validates :nomenclature_change, :presence => true validates :new_scientific_name, :presence => true, :if => Proc.new { |c| c.taxon_concept_id.blank? && !c.nomenclature_change.is_a?(NomenclatureChange::NewName) } diff --git a/app/views/admin/nomenclature_changes/new_name/hybrid_parents.html.erb b/app/views/admin/nomenclature_changes/new_name/hybrid_parents.html.erb index 0cc4bd71f2..1d906524ac 100644 --- a/app/views/admin/nomenclature_changes/new_name/hybrid_parents.html.erb +++ b/app/views/admin/nomenclature_changes/new_name/hybrid_parents.html.erb @@ -10,8 +10,8 @@
<%= ff.text_field :hybrid_parent_id, { :class => 'taxon-concept', - :'data-name' => ff.object.new_parent.try(:full_name), - :'data-name-status' => ff.object.new_parent.try(:name_status), + :'data-name' => ff.object.hybrid_parent.try(:full_name), + :'data-name-status' => ff.object.hybrid_parent.try(:name_status), :'data-name-status-filter' => ['A'].to_json, :'data-taxonomy-id' => @taxonomy.id } %> @@ -22,8 +22,8 @@
<%= ff.text_field :other_hybrid_parent_id, { :class => 'taxon-concept', - :'data-name' => ff.object.new_parent.try(:full_name), - :'data-name-status' => ff.object.new_parent.try(:name_status), + :'data-name' => ff.object.other_hybrid_parent.try(:full_name), + :'data-name-status' => ff.object.other_hybrid_parent.try(:name_status), :'data-name-status-filter' => ['A'].to_json, :'data-taxonomy-id' => @taxonomy.id } %> From 832f212c48cc41dddd8a69203c1066fe55972e17 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Sun, 4 Oct 2015 17:31:27 +0100 Subject: [PATCH 015/365] Fixed repopulation of accepted names when previous step --- .../admin/nomenclature_changes.js.coffee | 19 +++++++++++++++++-- app/models/nomenclature_change/output.rb | 10 ++++++++++ .../new_name/accepted_names.html.erb | 4 ++-- .../new_name/parent.html.erb | 2 +- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/app/assets/javascripts/admin/nomenclature_changes.js.coffee b/app/assets/javascripts/admin/nomenclature_changes.js.coffee index 233c552fab..d456ed2154 100644 --- a/app/assets/javascripts/admin/nomenclature_changes.js.coffee +++ b/app/assets/javascripts/admin/nomenclature_changes.js.coffee @@ -8,7 +8,7 @@ $(document).ready -> initSelection: (element, callback) => id = $(element).val() if (id != null && id != '') - callback({id: id, text: $(element).attr('data-name') + ' ' + $(element).attr('data-name-status')}) + callback({id: id, text: $(element).data('name') + ' ' + $(element).data('name-status')}) ajax: url: '/admin/taxon_concepts/autocomplete' @@ -27,8 +27,23 @@ $(document).ready -> text: tc.full_name + ' ' + tc.name_status results: formatted_taxon_concepts } + multiTaxonSelect2Options = { + multiple: true, + initSelection: (element, callback) => + id = $(element).val() + $(element).attr('value','') + if (id != null && id != '') + ids = id.substr(1,id.length-2).split(',') + names = $(element).data('name') + name_status = $(element).data('name-status') + result = [] + for id, i in ids + result.push({id: id, text: names[i] + ' ' + name_status}) + callback(result) + } + $('.taxon-concept').select2(defaultTaxonSelect2Options) - $('.taxon-concept-multiple').select2($.extend(defaultTaxonSelect2Options,{multiple: true})) + $('.taxon-concept-multiple').select2($.extend(defaultTaxonSelect2Options,multiTaxonSelect2Options)) $('.taxon-concept').on('change', (event) -> return false unless event.val $.when($.ajax( '/admin/taxon_concepts/' + event.val + '.json' ) ).then(( data, textStatus, jqXHR ) => diff --git a/app/models/nomenclature_change/output.rb b/app/models/nomenclature_change/output.rb index 95ed077dda..d2a9c56bf9 100644 --- a/app/models/nomenclature_change/output.rb +++ b/app/models/nomenclature_change/output.rb @@ -89,6 +89,16 @@ def accepted_taxon_ids=(ary) write_attribute(:accepted_taxon_ids, "{#{ary && ary.join(',')}}") end + def fetch_accepted_taxons_full_name + if accepted_taxon_ids.present? + ActiveRecord::Base.connection.execute( + <<-SQL + SELECT tc.full_name FROM taxon_concepts tc WHERE tc.id = ANY (ARRAY#{accepted_taxon_ids.map(&:to_i)}) + SQL + ).map{ |row| row['full_name']}.to_s + end + end + def populate_taxon_concept_fields self.parent_id = taxon_concept.parent_id_changed? ? taxon_concept.parent_id_was : taxon_concept.parent_id self.rank_id = taxon_concept.rank_id_changed? ? taxon_concept.rank_id_was : taxon_concept.rank_id diff --git a/app/views/admin/nomenclature_changes/new_name/accepted_names.html.erb b/app/views/admin/nomenclature_changes/new_name/accepted_names.html.erb index 12d05bea87..346c84a12c 100644 --- a/app/views/admin/nomenclature_changes/new_name/accepted_names.html.erb +++ b/app/views/admin/nomenclature_changes/new_name/accepted_names.html.erb @@ -10,8 +10,8 @@
<%= ff.text_field :accepted_taxon_ids, { :class => 'taxon-concept-multiple', - :'data-name' => ff.object.accepted_taxon.try(:full_name), - :'data-name-status' => ff.object.accepted_taxon.try(:name_status), + :'data-name' => ff.object.fetch_accepted_taxons_full_name, + :'data-name-status' => 'A', :'data-name-status-filter' => ['A'].to_json, :'data-taxonomy-id' => @taxonomy.id, :multiple => 'multiple' diff --git a/app/views/admin/nomenclature_changes/new_name/parent.html.erb b/app/views/admin/nomenclature_changes/new_name/parent.html.erb index 20b54fba77..5e9e5d8623 100644 --- a/app/views/admin/nomenclature_changes/new_name/parent.html.erb +++ b/app/views/admin/nomenclature_changes/new_name/parent.html.erb @@ -18,4 +18,4 @@
<% end %>
-<% end %> \ No newline at end of file +<% end %> From 5792115dc99b3110eef372dd2a5464ab0818b106 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Sun, 4 Oct 2015 17:53:16 +0100 Subject: [PATCH 016/365] Removed unnecessary code --- .../new_name_controller.rb | 28 ------------------- 1 file changed, 28 deletions(-) diff --git a/app/controllers/admin/nomenclature_changes/new_name_controller.rb b/app/controllers/admin/nomenclature_changes/new_name_controller.rb index 5daf8ba3d6..5b4e4b1899 100644 --- a/app/controllers/admin/nomenclature_changes/new_name_controller.rb +++ b/app/controllers/admin/nomenclature_changes/new_name_controller.rb @@ -60,34 +60,6 @@ def set_name_status end end - def init_new_name nomenclature_change - #output = nomenclature_change.build_output - #tc = @nomenclature_change.output.build_new_taxon_concept - nomenclature_change.assign_attributes({"output_attributes" => - { - "taxon_concept_id"=>"", - "new_parent_id"=>"2036", - "new_scientific_name"=>"lumpus#{@nomenclature_change.id}", - "new_author_year"=>"Ferdinando, 2014", - "new_rank_id"=>8, - "new_name_status"=>"A" - } - }) - end - - def output_attributes - {"output_attributes" => - { - "taxon_concept_id"=>"", - "new_parent_id"=>"2036", - "new_scientific_name"=>"lumpus#{@nomenclature_change.id}", - "new_author_year"=>"Ferdinando, 2014", - "new_rank_id"=>8, - "new_name_status"=>"A" - }.merge(params[:nomenclature_change_new_name][:output_attributes]) - } - end - def set_new_name_taxonomy @taxonomy = Taxonomy.find(@nomenclature_change.output.taxonomy_id) end From 0a5fdb09901443d96f1cfff0dab1946e65c4583f Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Mon, 5 Oct 2015 10:06:14 +0100 Subject: [PATCH 017/365] Added summary --- app/models/nomenclature_change/new_name/processor.rb | 6 ++++-- .../nomenclature_change/output_taxon_concept_processor.rb | 7 +++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/app/models/nomenclature_change/new_name/processor.rb b/app/models/nomenclature_change/new_name/processor.rb index c2230f8b6d..5b110d4f4d 100644 --- a/app/models/nomenclature_change/new_name/processor.rb +++ b/app/models/nomenclature_change/new_name/processor.rb @@ -1,7 +1,9 @@ class NomenclatureChange::NewName::Processor < NomenclatureChange::Processor def summary - "Summary" + result = [] + @subprocessors.each{ |processor| result << processor.summary } + result.flatten(1) end private @@ -15,4 +17,4 @@ def initialize_inputs_and_outputs @output = @nc.output end -end \ No newline at end of file +end diff --git a/app/models/nomenclature_change/output_taxon_concept_processor.rb b/app/models/nomenclature_change/output_taxon_concept_processor.rb index 8f3dc5c09a..2edab2ea45 100644 --- a/app/models/nomenclature_change/output_taxon_concept_processor.rb +++ b/app/models/nomenclature_change/output_taxon_concept_processor.rb @@ -30,6 +30,13 @@ def summary name_status = @output.new_name_status || @output.taxon_concept.try(:name_status) if @output.taxon_concept.blank? res << "New #{rank_name} #{full_name} (#{name_status}) will be created" + if @output.nomenclature_change.type == "NomenclatureChange::NewName" + case name_status + when 'A' then res << "Parent: #{@output.new_parent.full_name}" + when 'S' then res << "Accepted names: #{@output.fetch_accepted_taxons_full_name.join(',')}" + when 'H' then res << "Parents: #{@output.hybrid_parent.full_name},#{@output.other_hybrid_parent.full_name}" + end + end elsif @output.will_create_taxon? res << "New #{rank_name} #{full_name} (#{name_status}) will be created, based on #{@output.taxon_concept.full_name}" if ['A', 'N', 'H'].include? @output.taxon_concept.name_status From ab115bb2109991694ec8dea016c1bdfeae7b09f2 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Mon, 5 Oct 2015 10:20:30 +0100 Subject: [PATCH 018/365] Fixed summary test --- .../nomenclature_changes/new_name_controller_spec.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/spec/controllers/admin/nomenclature_changes/new_name_controller_spec.rb b/spec/controllers/admin/nomenclature_changes/new_name_controller_spec.rb index 4b0c8e3903..2fe06e1718 100644 --- a/spec/controllers/admin/nomenclature_changes/new_name_controller_spec.rb +++ b/spec/controllers/admin/nomenclature_changes/new_name_controller_spec.rb @@ -74,6 +74,14 @@ end end context :summary do + before(:each) do + @taxonomy = create(:taxonomy, name: "CITES_EU") + create(:nomenclature_change_output, + nomenclature_change: @new_name, + new_name_status: 'S', + taxonomy_id: @taxonomy.id + ) + end it 'renders the summary template' do get :show, id: :summary, nomenclature_change_id: @new_name.id response.should render_template('summary') From 424881f30c9e39e690ed97b9c3c65d7ec3baba33 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Mon, 5 Oct 2015 10:21:46 +0100 Subject: [PATCH 019/365] Minor changes including reduction of name statuses to just A,S,H --- app/assets/javascripts/admin/nomenclature_changes.js.coffee | 1 + app/models/nomenclature_change/output.rb | 2 +- .../nomenclature_changes/new_name/accepted_names.html.erb | 2 +- .../admin/nomenclature_changes/new_name/name_status.html.erb | 4 ++-- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/admin/nomenclature_changes.js.coffee b/app/assets/javascripts/admin/nomenclature_changes.js.coffee index d456ed2154..3510b873b7 100644 --- a/app/assets/javascripts/admin/nomenclature_changes.js.coffee +++ b/app/assets/javascripts/admin/nomenclature_changes.js.coffee @@ -31,6 +31,7 @@ $(document).ready -> multiple: true, initSelection: (element, callback) => id = $(element).val() + # Reset value attribute to let Select2 work properly when submitting the values again $(element).attr('value','') if (id != null && id != '') ids = id.substr(1,id.length-2).split(',') diff --git a/app/models/nomenclature_change/output.rb b/app/models/nomenclature_change/output.rb index d2a9c56bf9..86408be157 100644 --- a/app/models/nomenclature_change/output.rb +++ b/app/models/nomenclature_change/output.rb @@ -95,7 +95,7 @@ def fetch_accepted_taxons_full_name <<-SQL SELECT tc.full_name FROM taxon_concepts tc WHERE tc.id = ANY (ARRAY#{accepted_taxon_ids.map(&:to_i)}) SQL - ).map{ |row| row['full_name']}.to_s + ).map{ |row| row['full_name']} end end diff --git a/app/views/admin/nomenclature_changes/new_name/accepted_names.html.erb b/app/views/admin/nomenclature_changes/new_name/accepted_names.html.erb index 346c84a12c..209a789344 100644 --- a/app/views/admin/nomenclature_changes/new_name/accepted_names.html.erb +++ b/app/views/admin/nomenclature_changes/new_name/accepted_names.html.erb @@ -10,7 +10,7 @@
<%= ff.text_field :accepted_taxon_ids, { :class => 'taxon-concept-multiple', - :'data-name' => ff.object.fetch_accepted_taxons_full_name, + :'data-name' => ff.object.fetch_accepted_taxons_full_name.to_s, :'data-name-status' => 'A', :'data-name-status-filter' => ['A'].to_json, :'data-taxonomy-id' => @taxonomy.id, diff --git a/app/views/admin/nomenclature_changes/new_name/name_status.html.erb b/app/views/admin/nomenclature_changes/new_name/name_status.html.erb index b9e6ade55c..3745cccc8a 100644 --- a/app/views/admin/nomenclature_changes/new_name/name_status.html.erb +++ b/app/views/admin/nomenclature_changes/new_name/name_status.html.erb @@ -9,11 +9,11 @@
<%= ff.select :new_name_status, - options_for_select(['A', 'N', 'S', 'T', 'H'], + options_for_select(['A', 'S', 'H'], ff.object.new_name_status), {} %>
<% end %>
-<% end %> \ No newline at end of file +<% end %> From e0e567fc88766b1ee06fb3036dd2e4c28ef3a0d6 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Mon, 5 Oct 2015 11:45:13 +0100 Subject: [PATCH 020/365] Added validation for the accepted_names step --- .../admin/nomenclature_changes.js.coffee | 4 ++-- .../nomenclature_changes/new_name_controller.rb | 2 +- app/models/nomenclature_change/new_name.rb | 14 ++++++++++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/admin/nomenclature_changes.js.coffee b/app/assets/javascripts/admin/nomenclature_changes.js.coffee index 3510b873b7..0a8ce9f2d0 100644 --- a/app/assets/javascripts/admin/nomenclature_changes.js.coffee +++ b/app/assets/javascripts/admin/nomenclature_changes.js.coffee @@ -30,11 +30,11 @@ $(document).ready -> multiTaxonSelect2Options = { multiple: true, initSelection: (element, callback) => - id = $(element).val() + id = $(element).val().match(/{(.*)}/)[1] # Reset value attribute to let Select2 work properly when submitting the values again $(element).attr('value','') if (id != null && id != '') - ids = id.substr(1,id.length-2).split(',') + ids = id.split(',') names = $(element).data('name') name_status = $(element).data('name-status') result = [] diff --git a/app/controllers/admin/nomenclature_changes/new_name_controller.rb b/app/controllers/admin/nomenclature_changes/new_name_controller.rb index 5b4e4b1899..113710448c 100644 --- a/app/controllers/admin/nomenclature_changes/new_name_controller.rb +++ b/app/controllers/admin/nomenclature_changes/new_name_controller.rb @@ -38,7 +38,7 @@ def update when 'S' then jump_to(:accepted_names) when 'H' then jump_to(:hybrid_parents) end - when :parent, :hybrid_parents + when :parent, :accepted_names, :hybrid_parents set_new_name_taxonomy end diff --git a/app/models/nomenclature_change/new_name.rb b/app/models/nomenclature_change/new_name.rb index 4fcf640bd5..e209e5d0be 100644 --- a/app/models/nomenclature_change/new_name.rb +++ b/app/models/nomenclature_change/new_name.rb @@ -25,6 +25,7 @@ class NomenclatureChange::NewName < NomenclatureChange } validate :required_different_name, if: :scientific_name_step? validate :parent_at_immediately_higher_rank, if: :parent_step? + validate :required_accepted_names, if: :accepted_names_step? validate :required_hybrids, if: :hybrid_parents_step? def scientific_name_step? @@ -35,10 +36,23 @@ def parent_step? status == 'parent' end + def accepted_names_step? + status == 'accepted_names' + end + def hybrid_parents_step? status == 'hybrid_parents' end + def required_accepted_names + if output.present? + unless output.accepted_taxon_ids.present? + errors.add(:outputs, "at least an accepted name is required") + return false + end + end + end + def required_hybrids if output.present? unless output.hybrid_parent_id && output.other_hybrid_parent_id From ea74160c8ef7c4a3f89f8ee70759ad8d7661a146 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Mon, 5 Oct 2015 14:32:45 +0100 Subject: [PATCH 021/365] Added hint for scientific_name --- app/helpers/admin/nomenclature_changes_helper.rb | 7 +++++++ .../nomenclature_changes/new_name/scientific_name.html.erb | 5 ++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/app/helpers/admin/nomenclature_changes_helper.rb b/app/helpers/admin/nomenclature_changes_helper.rb index cb849fed10..c33e564b05 100644 --- a/app/helpers/admin/nomenclature_changes_helper.rb +++ b/app/helpers/admin/nomenclature_changes_helper.rb @@ -335,4 +335,11 @@ def ranks_collection def taxon_concepts_collection TaxonConcept.where(:taxonomy_id => 1).collect {|t| [t.full_name, t.id]} end + + def new_name_scientific_name_hint + case @nomenclature_change.output.new_name_status + when 'A' then "e.g. 'africana' for Loxodonta africana" + when 'S','H' then "e.g. Loxodonta africana" + end + end end diff --git a/app/views/admin/nomenclature_changes/new_name/scientific_name.html.erb b/app/views/admin/nomenclature_changes/new_name/scientific_name.html.erb index 96e6084e2c..69e04a4849 100644 --- a/app/views/admin/nomenclature_changes/new_name/scientific_name.html.erb +++ b/app/views/admin/nomenclature_changes/new_name/scientific_name.html.erb @@ -12,8 +12,11 @@ <%= ff.text_field :new_scientific_name, { :class => 'new-scientific-name' } %> +
<% end %> -<% end %> \ No newline at end of file +<% end %> From 6290669c788b13c3549972434980cf17a44583b3 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Mon, 5 Oct 2015 15:10:16 +0100 Subject: [PATCH 022/365] Fixed show page for NewName --- .../admin/nomenclature_changes_helper.rb | 20 ++++++++++++++----- .../output_taxon_concept_processor.rb | 2 +- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/app/helpers/admin/nomenclature_changes_helper.rb b/app/helpers/admin/nomenclature_changes_helper.rb index c33e564b05..6baafce08d 100644 --- a/app/helpers/admin/nomenclature_changes_helper.rb +++ b/app/helpers/admin/nomenclature_changes_helper.rb @@ -169,12 +169,17 @@ def nomenclature_change_header when @nc.is_a?(NomenclatureChange::StatusToAccepted) content_tag(:h1, "NomenclatureChange #{@nc.id} - STATUS TO ACCEPTED", nil) + content_tag(:div, @nc.primary_output.note_en.html_safe, class: 'well well-small') + when @nc.is_a?(NomenclatureChange::NewName) + content_tag(:h1, "NomenclatureChange #{@nc.id} - NEW NAME", nil) + + content_tag(:div, @nc.output.note_en.html_safe, class: 'well well-small') end end def generate_input_content if @nc.is_a?(NomenclatureChange::Lump) lump_inputs_tags + lump_inputs_content + elsif @nc.is_a?(NomenclatureChange::NewName) + '' else split_input_tag + split_input_content end @@ -184,7 +189,7 @@ def generate_output_content if @nc.is_a?(NomenclatureChange::Lump) lump_output_tag + lump_output_content else - split_outputs_tags + split_outputs_content + outputs_tags + outputs_content end end @@ -256,8 +261,8 @@ def split_input_content end end - def split_outputs_tags - outputs = select_outputs + def outputs_tags + outputs = Array.wrap(select_outputs) content_tag(:ul, class: 'nav nav-tabs') do outputs.each_with_index do |output, idx| tc = output.new_taxon_concept || output.taxon_concept @@ -266,8 +271,8 @@ def split_outputs_tags end end - def split_outputs_content - outputs = select_outputs + def outputs_content + outputs = Array.wrap(select_outputs) content_tag(:div, class: 'tab-content') do outputs.each_with_index do |output, idx| tc = output.new_taxon_concept || output.taxon_concept @@ -286,6 +291,9 @@ def inner_content(input_or_output,tc) content_tag(:p, content_tag(:i, link_to(tc.full_name, admin_taxon_concept_names_path(tc)), nil) ) + + if input_or_output.nomenclature_change.is_a?(NomenclatureChange::NewName) + content_tag(:p, "Name status: #{input_or_output.new_name_status}") + end + content_tag(:p, "Author: #{tc.author_year || tc.new_author_year}") + content_tag(:p, "Internal note: #{input_or_output.internal_note}") end @@ -293,6 +301,8 @@ def inner_content(input_or_output,tc) def select_outputs if @nc.is_a?(NomenclatureChange::Split) @nc.outputs + elsif @nc.is_a?(NomenclatureChange::NewName) + @nc.output else [@nc.primary_output, @nc.secondary_output].compact end diff --git a/app/models/nomenclature_change/output_taxon_concept_processor.rb b/app/models/nomenclature_change/output_taxon_concept_processor.rb index 2edab2ea45..80f179d037 100644 --- a/app/models/nomenclature_change/output_taxon_concept_processor.rb +++ b/app/models/nomenclature_change/output_taxon_concept_processor.rb @@ -30,7 +30,7 @@ def summary name_status = @output.new_name_status || @output.taxon_concept.try(:name_status) if @output.taxon_concept.blank? res << "New #{rank_name} #{full_name} (#{name_status}) will be created" - if @output.nomenclature_change.type == "NomenclatureChange::NewName" + if @output.nomenclature_change.is_a?(NomenclatureChange::NewName) case name_status when 'A' then res << "Parent: #{@output.new_parent.full_name}" when 'S' then res << "Accepted names: #{@output.fetch_accepted_taxons_full_name.join(',')}" From 3cf83524e08e26d3330464066d0960065c7b348f Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Mon, 5 Oct 2015 16:08:58 +0100 Subject: [PATCH 023/365] Fixed several nomenclature_changes show pages --- .../admin/nomenclature_changes_helper.rb | 6 +-- ...53_add_empty_string_as_default_to_notes.rb | 46 +++++++++++++++++++ 2 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 db/migrate/20151005141953_add_empty_string_as_default_to_notes.rb diff --git a/app/helpers/admin/nomenclature_changes_helper.rb b/app/helpers/admin/nomenclature_changes_helper.rb index 6baafce08d..3a02e77a1c 100644 --- a/app/helpers/admin/nomenclature_changes_helper.rb +++ b/app/helpers/admin/nomenclature_changes_helper.rb @@ -180,7 +180,7 @@ def generate_input_content lump_inputs_tags + lump_inputs_content elsif @nc.is_a?(NomenclatureChange::NewName) '' - else + elsif @nc.input split_input_tag + split_input_content end end @@ -291,8 +291,8 @@ def inner_content(input_or_output,tc) content_tag(:p, content_tag(:i, link_to(tc.full_name, admin_taxon_concept_names_path(tc)), nil) ) + - if input_or_output.nomenclature_change.is_a?(NomenclatureChange::NewName) - content_tag(:p, "Name status: #{input_or_output.new_name_status}") + if input_or_output.is_a?(NomenclatureChange::Output) + content_tag(:p, "Name status: #{input_or_output.new_name_status || input_or_output.name_status}") end + content_tag(:p, "Author: #{tc.author_year || tc.new_author_year}") + content_tag(:p, "Internal note: #{input_or_output.internal_note}") diff --git a/db/migrate/20151005141953_add_empty_string_as_default_to_notes.rb b/db/migrate/20151005141953_add_empty_string_as_default_to_notes.rb new file mode 100644 index 0000000000..c40bf2d63f --- /dev/null +++ b/db/migrate/20151005141953_add_empty_string_as_default_to_notes.rb @@ -0,0 +1,46 @@ +class AddEmptyStringAsDefaultToNotes < ActiveRecord::Migration + def change + [:en, :es, :fr].each do |lng| + change_column :nomenclature_change_outputs, :"note_#{lng}", :text, default: '' + change_column :nomenclature_change_inputs, :"note_#{lng}", :text, default: '' + end + change_column :nomenclature_change_outputs, :internal_note, :text, default: '' + change_column :nomenclature_change_inputs, :internal_note, :text, default: '' + + ActiveRecord::Base.connection.execute( + <<-SQL + UPDATE nomenclature_change_outputs + SET note_en='' + WHERE note_en IS NULL; + + UPDATE nomenclature_change_outputs + SET note_es='' + WHERE note_es IS NULL; + + UPDATE nomenclature_change_outputs + SET note_fr='' + WHERE note_fr IS NULL; + + UPDATE nomenclature_change_outputs + SET internal_note='' + WHERE internal_note IS NULL; + + UPDATE nomenclature_change_inputs + SET note_en='' + WHERE note_en IS NULL; + + UPDATE nomenclature_change_inputs + SET note_es='' + WHERE note_es IS NULL; + + UPDATE nomenclature_change_inputs + SET note_fr='' + WHERE note_fr IS NULL; + + UPDATE nomenclature_change_inputs + SET internal_note='' + WHERE internal_note IS NULL; + SQL + ) + end +end From c9c2e2d69c0fc92fe0c90f37cf1473482a15c47c Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Mon, 5 Oct 2015 16:34:37 +0100 Subject: [PATCH 024/365] Minor code improvement --- .../admin/nomenclature_changes/new_name_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/admin/nomenclature_changes/new_name_controller.rb b/app/controllers/admin/nomenclature_changes/new_name_controller.rb index 113710448c..43925fac44 100644 --- a/app/controllers/admin/nomenclature_changes/new_name_controller.rb +++ b/app/controllers/admin/nomenclature_changes/new_name_controller.rb @@ -11,10 +11,10 @@ def show builder.build_output when :parent set_new_name_taxonomy - skip_or_previous_step unless ['A','N'].include?(@name_status) + skip_or_previous_step if @name_status != 'A' when :accepted_names set_new_name_taxonomy - skip_or_previous_step if ['A','H','N'].include?(@name_status) + skip_or_previous_step if @name_status != 'S' when :hybrid_parents set_new_name_taxonomy skip_or_previous_step if @name_status != 'H' From f73db3c6173c65e8fd46c16c4f68e08857c1e7ac Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 6 Oct 2015 09:42:46 +0100 Subject: [PATCH 025/365] fixes #84099622 - populate public note with year of the event where available --- .../nomenclature_change/constructor_helpers.rb | 10 ++++++++++ app/models/nomenclature_change/lump/constructor.rb | 5 +++-- app/models/nomenclature_change/split/constructor.rb | 5 +++-- .../status_change/constructor_helpers.rb | 3 ++- .../nomenclature_change/status_swap/constructor.rb | 1 + config/locales/nomenclature_change_notes.yml | 13 +++++++------ 6 files changed, 26 insertions(+), 11 deletions(-) diff --git a/app/models/nomenclature_change/constructor_helpers.rb b/app/models/nomenclature_change/constructor_helpers.rb index f8ec512c71..a55c5def4a 100644 --- a/app/models/nomenclature_change/constructor_helpers.rb +++ b/app/models/nomenclature_change/constructor_helpers.rb @@ -196,6 +196,16 @@ def following_taxonomic_changes(event, lng) end end + def in_year(event, lng) + I18n.with_locale(lng) do + I18n.translate( + 'in_year', + year: event && event.effective_at.try(:year) || Date.today.year, + default: 'Translation missing' + ) + end + end + def multi_lingual_legislation_note(note_type) result = {} [:en, :es, :fr].each do |lng| diff --git a/app/models/nomenclature_change/lump/constructor.rb b/app/models/nomenclature_change/lump/constructor.rb index 0fce2f130a..f195b9014f 100644 --- a/app/models/nomenclature_change/lump/constructor.rb +++ b/app/models/nomenclature_change/lump/constructor.rb @@ -59,7 +59,6 @@ def input_lumped_into(input, output, lng) 'lump.input_lumped_into', input_taxon: input_html, output_taxon: output_html, - year: Date.today.year, default: 'Translation missing' ) end @@ -75,7 +74,6 @@ def output_lumped_from(output, inputs, lng) 'lump.output_lumped_from', output_taxon: output_html, input_taxa: inputs_html, - year: Date.today.year, default: 'Translation missing' ) end @@ -86,6 +84,7 @@ def multi_lingual_input_note(input, output, event) [:en, :es, :fr].each do |lng| note = '

' note << input_lumped_into(input, output, lng) + note << in_year(event, lng) note << following_taxonomic_changes(event, lng) if event note << '.

' result[lng] = note @@ -98,6 +97,7 @@ def multi_lingual_output_note(output, inputs, event) [:en, :es, :fr].each do |lng| note = '

' note << output_lumped_from(output, @nomenclature_change.inputs, lng) + note << in_year(event, lng) note << following_taxonomic_changes(event, lng) if event note << '.

' result[lng] = note @@ -130,6 +130,7 @@ def legislation_note(lng) output_html = taxon_concept_html(output.display_full_name, output.display_rank_name) note = '

' note << yield(input_html, output_html) + note << in_year(@nomenclature_change.event, lng) if @nomenclature_change.event note << following_taxonomic_changes(@nomenclature_change.event, lng) end diff --git a/app/models/nomenclature_change/split/constructor.rb b/app/models/nomenclature_change/split/constructor.rb index d939042723..be3352243d 100644 --- a/app/models/nomenclature_change/split/constructor.rb +++ b/app/models/nomenclature_change/split/constructor.rb @@ -89,7 +89,6 @@ def input_split_into(input, outputs, lng) 'split.input_split_into', output_taxa: outputs_html, input_taxon: input_html, - year: Date.today.year, default: 'Translation missing' ) end @@ -115,7 +114,6 @@ def output_split_from(output, input, lng) 'split.output_split_from', output_taxon: output_html, input_taxon: input_html, - year: Date.today.year, default: 'Translation missing' ) end @@ -126,6 +124,7 @@ def multi_lingual_input_note(input, outputs, event) [:en, :es, :fr].each do |lng| note = '

' note << input_split_into(input, @nomenclature_change.outputs, lng) + note << in_year(event, lng) note << following_taxonomic_changes(event, lng) if event note << '.

' result[lng] = note @@ -138,6 +137,7 @@ def multi_lingual_output_note(output, input, event) [:en, :es, :fr].each do |lng| note = '

' note << output_split_from(output, input, lng) + note << in_year(event, lng) note << following_taxonomic_changes(event, lng) if event note << '.

' result[lng] = note @@ -170,6 +170,7 @@ def legislation_note(lng) output_html = taxon_concept_html('[[output]]', input.taxon_concept.rank.name) note = '

' note << yield(input_html, output_html) + note << in_year(@nomenclature_change.event, lng) if @nomenclature_change.event note << following_taxonomic_changes(@nomenclature_change.event, lng) end diff --git a/app/models/nomenclature_change/status_change/constructor_helpers.rb b/app/models/nomenclature_change/status_change/constructor_helpers.rb index 01fff8c489..8f0b60fcb6 100644 --- a/app/models/nomenclature_change/status_change/constructor_helpers.rb +++ b/app/models/nomenclature_change/status_change/constructor_helpers.rb @@ -85,7 +85,6 @@ def status_change_note(locale_key, output, lng) output_taxon: output_html, old_status: output.taxon_concept.name_status, new_status: output.new_name_status, - year: Date.today.year, default: 'Translation missing' ) end @@ -110,6 +109,7 @@ def multi_lingual_public_output_note(output, event) def public_output_note(output, event, lng) note = '

' note << status_elevated_to_accepted_name(output, lng) + note << in_year(event, lng) note << following_taxonomic_changes(event, lng) if event note << '.

' note @@ -118,6 +118,7 @@ def public_output_note(output, event, lng) def private_output_note(output, event, lng) note = '

' note << status_change_from_to(output, lng) + note << in_year(event, lng) note << following_taxonomic_changes(event, lng) if event note << '.

' note diff --git a/app/models/nomenclature_change/status_swap/constructor.rb b/app/models/nomenclature_change/status_swap/constructor.rb index 9dc4f5eeae..9cde8d6dbe 100644 --- a/app/models/nomenclature_change/status_swap/constructor.rb +++ b/app/models/nomenclature_change/status_swap/constructor.rb @@ -45,6 +45,7 @@ def legislation_note(lng) input = taxon_concept_html(input.taxon_concept.full_name, input.taxon_concept.rank.name) note = '

' note << yield(input, output) + note << in_year(@event, lng) if @event note << following_taxonomic_changes(@event, lng) end diff --git a/config/locales/nomenclature_change_notes.yml b/config/locales/nomenclature_change_notes.yml index ae3ae37535..db3b8be80c 100644 --- a/config/locales/nomenclature_change_notes.yml +++ b/config/locales/nomenclature_change_notes.yml @@ -1,22 +1,23 @@ en: following_taxonomic_changes: ', following taxonomic changes adopted at %{event}' + in_year: ' in %{year}' split: - output_split_from: '%{output_taxon} was split from %{input_taxon} in %{year}' - input_split_into: '%{input_taxon} was split into %{output_taxa} in %{year}' + output_split_from: '%{output_taxon} was split from %{input_taxon}' + input_split_into: '%{input_taxon} was split into %{output_taxa}' listing_change: 'Originally listed as %{input_taxon}, from which %{output_taxon} was split' suspension: 'Suspension originally formed for %{input_taxon}, from which %{output_taxon} was split' opinion: 'Opinion originally formed for %{input_taxon}, from which %{output_taxon} was split' quota: 'Quota originally published for %{input_taxon}, from which %{output_taxon} was split' lump: - input_lumped_into: '%{input_taxon} was lumped into %{output_taxon} in %{year}' - output_lumped_from: '%{output_taxon} was lumped from %{input_taxa} in %{year}' + input_lumped_into: '%{input_taxon} was lumped into %{output_taxon}' + output_lumped_from: '%{output_taxon} was lumped from %{input_taxa}' listing_change: 'Originally listed as %{input_taxon}, which was lumped into %{output_taxon}' suspension: 'Suspension originally formed for %{input_taxon}, which was lumped into %{output_taxon}' opinion: 'Opinion originally formed for %{input_taxon}, which was lumped into %{output_taxon}' quota: 'Quota originally formed for %{input_taxon}, which was lumped into %{output_taxon}' status_change: - status_elevated_to_accepted_name: '%{output_taxon} was elevated to an accepted name in %{year}' - status_change_from_to: '%{output_taxon} status change from %{old_status} to %{new_status} in %{year}' + status_elevated_to_accepted_name: '%{output_taxon} was elevated to an accepted name' + status_change_from_to: '%{output_taxon} status change from %{old_status} to %{new_status}' listing_change: 'Originally listed as %{input_taxon}, which became a synonym of %{output_taxon}' suspension: 'Suspension originally formed for %{input_taxon}, which became a synonym of %{output_taxon}' opinion: 'Opinion originally formed for %{input_taxon}, which became a synonym of %{output_taxon}' From 76c5b25ec43a6836555b04e96cde89e69561f21b Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 5 Oct 2015 17:03:19 +0100 Subject: [PATCH 026/365] possibly fixes legislation reassignments --- app/models/nomenclature_change/constructor_helpers.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/nomenclature_change/constructor_helpers.rb b/app/models/nomenclature_change/constructor_helpers.rb index a55c5def4a..9466e2626c 100644 --- a/app/models/nomenclature_change/constructor_helpers.rb +++ b/app/models/nomenclature_change/constructor_helpers.rb @@ -121,8 +121,8 @@ def _build_legislation_reassignments(input, outputs) input.legislation_reassignments.each do |reassignment| if input.is_a?(NomenclatureChange::Input) _build_multiple_targets(reassignment, outputs) - #input.reassignments << reassignment end + input.reassignments << reassignment end end From 5daca61aa786676db1c9390dd9d4828f6b1859cc Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Tue, 6 Oct 2015 15:21:35 +0100 Subject: [PATCH 027/365] Added default text to notes as well as event selection --- .../new_name_controller.rb | 9 +++-- .../new_name/constructor.rb | 35 +++++++++++++++++++ .../new_name/name_status.html.erb | 1 + config/locales/nomenclature_change_notes.yml | 4 ++- 4 files changed, 46 insertions(+), 3 deletions(-) diff --git a/app/controllers/admin/nomenclature_changes/new_name_controller.rb b/app/controllers/admin/nomenclature_changes/new_name_controller.rb index 43925fac44..98ad9fd063 100644 --- a/app/controllers/admin/nomenclature_changes/new_name_controller.rb +++ b/app/controllers/admin/nomenclature_changes/new_name_controller.rb @@ -8,6 +8,7 @@ def show builder = NomenclatureChange::NewName::Constructor.new(@nomenclature_change) case step when :name_status + set_events builder.build_output when :parent set_new_name_taxonomy @@ -18,6 +19,8 @@ def show when :hybrid_parents set_new_name_taxonomy skip_or_previous_step if @name_status != 'H' + when :nomenclature_notes + builder.build_output_notes when :summary processor = NomenclatureChange::NewName::Processor.new(@nomenclature_change) @summary = processor.summary @@ -32,7 +35,11 @@ def update }) ) + success = @nomenclature_change.valid? + case step + when :name_status + set_events unless success when :rank case @nomenclature_change.output.new_name_status when 'S' then jump_to(:accepted_names) @@ -41,8 +48,6 @@ def update when :parent, :accepted_names, :hybrid_parents set_new_name_taxonomy end - - success = @nomenclature_change.valid? render_wizard @nomenclature_change end diff --git a/app/models/nomenclature_change/new_name/constructor.rb b/app/models/nomenclature_change/new_name/constructor.rb index 7c7afbd996..7f0a69954b 100644 --- a/app/models/nomenclature_change/new_name/constructor.rb +++ b/app/models/nomenclature_change/new_name/constructor.rb @@ -8,4 +8,39 @@ def initialize(nomenclature_change) def build_output @nomenclature_change.build_output if @nomenclature_change.output.nil? end + + def multi_lingual_output_note(output, event) + result = {} + [:en, :es, :fr].each do |lng| + note = '

' + note << new_name_note(output, lng) + note << following_taxonomic_changes(event, lng) if event + note << '.

' + result[lng] = note + end + result + end + + def build_output_notes + output = @nomenclature_change.output + event = @nomenclature_change.event + if output.note_en.blank? + note = multi_lingual_output_note(output, event) + output.note_en = note[:en] + output.note_es = note[:es] + output.note_fr = note[:fr] + end + end + + def new_name_note(output, lng) + output_html = taxon_concept_html(output.display_full_name, output.display_rank_name) + I18n.with_locale(lng) do + I18n.translate( + 'new_name.new_name_note', + output_taxon: output_html, + year: Date.current.year, + default: 'Translation missing' + ) + end + end end diff --git a/app/views/admin/nomenclature_changes/new_name/name_status.html.erb b/app/views/admin/nomenclature_changes/new_name/name_status.html.erb index 3745cccc8a..4466b59c48 100644 --- a/app/views/admin/nomenclature_changes/new_name/name_status.html.erb +++ b/app/views/admin/nomenclature_changes/new_name/name_status.html.erb @@ -4,6 +4,7 @@ Assign name status

<%= nomenclature_change_form do |f| %> + <%= render 'admin/nomenclature_changes/build/event_selector', :f => f %>
<%= f.fields_for :output do |ff| %> diff --git a/config/locales/nomenclature_change_notes.yml b/config/locales/nomenclature_change_notes.yml index db3b8be80c..10a9a5e2c0 100644 --- a/config/locales/nomenclature_change_notes.yml +++ b/config/locales/nomenclature_change_notes.yml @@ -1,6 +1,8 @@ en: following_taxonomic_changes: ', following taxonomic changes adopted at %{event}' in_year: ' in %{year}' + new_name: + new_name_note: '%{output_taxon} was added to the database in %{year}' split: output_split_from: '%{output_taxon} was split from %{input_taxon}' input_split_into: '%{input_taxon} was split into %{output_taxa}' @@ -21,4 +23,4 @@ en: listing_change: 'Originally listed as %{input_taxon}, which became a synonym of %{output_taxon}' suspension: 'Suspension originally formed for %{input_taxon}, which became a synonym of %{output_taxon}' opinion: 'Opinion originally formed for %{input_taxon}, which became a synonym of %{output_taxon}' - quota: 'Quota originally published for %{input_taxon}, which became a synonym of %{output_taxon}' \ No newline at end of file + quota: 'Quota originally published for %{input_taxon}, which became a synonym of %{output_taxon}' From 3f1dbb67d4b00970042ec5c774b0f80be3a09d98 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Tue, 6 Oct 2015 16:59:35 +0100 Subject: [PATCH 028/365] Added tags to nomenclature_notes step for new name wizard --- .../nomenclature_changes/new_name_controller.rb | 5 +++++ app/helpers/admin_helper.rb | 2 +- app/models/nomenclature_change/output.rb | 12 +++++++++++- .../new_name/nomenclature_notes.html.erb | 16 +++++++++++++--- ...dd_tag_list_to_nomenclature_changes_output.rb | 5 +++++ 5 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 db/migrate/20151006153403_add_tag_list_to_nomenclature_changes_output.rb diff --git a/app/controllers/admin/nomenclature_changes/new_name_controller.rb b/app/controllers/admin/nomenclature_changes/new_name_controller.rb index 98ad9fd063..f1e41fd95f 100644 --- a/app/controllers/admin/nomenclature_changes/new_name_controller.rb +++ b/app/controllers/admin/nomenclature_changes/new_name_controller.rb @@ -21,6 +21,7 @@ def show skip_or_previous_step if @name_status != 'H' when :nomenclature_notes builder.build_output_notes + load_tags when :summary processor = NomenclatureChange::NewName::Processor.new(@nomenclature_change) @summary = processor.summary @@ -84,4 +85,8 @@ def skip_or_previous_step end end + def load_tags + @tags = PresetTag.where(:model => PresetTag::TYPES[:TaxonConcept]) + end + end diff --git a/app/helpers/admin_helper.rb b/app/helpers/admin_helper.rb index b6963c4cea..fd073b54e0 100644 --- a/app/helpers/admin_helper.rb +++ b/app/helpers/admin_helper.rb @@ -70,7 +70,7 @@ def true_false_icon(bool_value) end def tag_list(tags_ary) - tags_ary.map{ |t| content_tag(:span, :class => 'myMinTag'){t} }.join.html_safe + tags_ary.map{ |t| content_tag(:span, :class => 'myMinTag'){t} }.join(', ').html_safe end def error_messages_for(resource) diff --git a/app/models/nomenclature_change/output.rb b/app/models/nomenclature_change/output.rb index 86408be157..767ff07331 100644 --- a/app/models/nomenclature_change/output.rb +++ b/app/models/nomenclature_change/output.rb @@ -38,7 +38,8 @@ class NomenclatureChange::Output < ActiveRecord::Base :new_name_status, :new_parent_id, :new_rank_id, :taxonomy_id, :accepted_taxon_ids, :note_en, :note_es, :note_fr, :internal_note, :is_primary_output, :parent_reassignments_attributes, :name_reassignments_attributes, - :distribution_reassignments_attributes, :legislation_reassignments_attributes, :hybrid_parent_id, :other_hybrid_parent_id + :distribution_reassignments_attributes, :legislation_reassignments_attributes, :hybrid_parent_id, :other_hybrid_parent_id, :tag_list + belongs_to :nomenclature_change belongs_to :taxon_concept belongs_to :parent, :class_name => TaxonConcept, :foreign_key => :parent_id @@ -89,6 +90,14 @@ def accepted_taxon_ids=(ary) write_attribute(:accepted_taxon_ids, "{#{ary && ary.join(',')}}") end + def tag_list + parse_pg_array(read_attribute(:tag_list)||"").compact + end + + def tag_list=(ary) + write_attribute(:tag_list, "{#{ary && ary.join(',')}}") + end + def fetch_accepted_taxons_full_name if accepted_taxon_ids.present? ActiveRecord::Base.connection.execute( @@ -158,6 +167,7 @@ def tmp_taxon_concept taxon_concept_attrs.merge({ :taxonomy_id => taxonomy.id, :full_name => display_full_name, + :tag_list => tag_list }) ).tap do |tc| add_taxon_synonym(tc, accepted_taxon_ids) diff --git a/app/views/admin/nomenclature_changes/new_name/nomenclature_notes.html.erb b/app/views/admin/nomenclature_changes/new_name/nomenclature_notes.html.erb index eccd2314d4..631b16b740 100644 --- a/app/views/admin/nomenclature_changes/new_name/nomenclature_notes.html.erb +++ b/app/views/admin/nomenclature_changes/new_name/nomenclature_notes.html.erb @@ -2,11 +2,21 @@ <%= nomenclature_change_form do |f| %> <%= f.fields_for :output do |ff| %>
+
- <%= render partial: 'admin/nomenclature_changes/build/nomenclature_notes', - locals: {ff: ff} + <%= ff.select :tag_list, + options_from_collection_for_select( + @tags, + :name, + :name, + ff.object.tag_list + ), {}, + { :multiple => true, :class => 'tags', :style => "width: 220px"} %> +
-
+ <%= render partial: 'admin/nomenclature_changes/build/nomenclature_notes', + locals: {ff: ff} + %> <% end %> <% end %> diff --git a/db/migrate/20151006153403_add_tag_list_to_nomenclature_changes_output.rb b/db/migrate/20151006153403_add_tag_list_to_nomenclature_changes_output.rb new file mode 100644 index 0000000000..34ddf51578 --- /dev/null +++ b/db/migrate/20151006153403_add_tag_list_to_nomenclature_changes_output.rb @@ -0,0 +1,5 @@ +class AddTagListToNomenclatureChangesOutput < ActiveRecord::Migration + def change + add_column :nomenclature_change_outputs, :tag_list, :text, array: true, default: [] + end +end From 1729310e37ab6f44dda1aabd2792cee52bfb2057 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Tue, 6 Oct 2015 17:07:59 +0100 Subject: [PATCH 029/365] Fixed smoke tests when deploying --- lib/capistrano/tasks/smoke_test.rake | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/capistrano/tasks/smoke_test.rake b/lib/capistrano/tasks/smoke_test.rake index add151972d..d1f76bd19e 100644 --- a/lib/capistrano/tasks/smoke_test.rake +++ b/lib/capistrano/tasks/smoke_test.rake @@ -1,3 +1,5 @@ +require 'net/http' + namespace :smoke_test do task :test_endpoints do From 643097baf3cb77c94f1014baad5d5e898cd320b5 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 8 Oct 2015 09:12:46 +0100 Subject: [PATCH 030/365] fix exception when no author_year present (A->S) --- app/helpers/admin/nomenclature_changes_helper.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/helpers/admin/nomenclature_changes_helper.rb b/app/helpers/admin/nomenclature_changes_helper.rb index 3a02e77a1c..1096167a60 100644 --- a/app/helpers/admin/nomenclature_changes_helper.rb +++ b/app/helpers/admin/nomenclature_changes_helper.rb @@ -288,13 +288,14 @@ def outputs_content end def inner_content(input_or_output,tc) + is_output = input_or_output.is_a?(NomenclatureChange::Output) content_tag(:p, content_tag(:i, link_to(tc.full_name, admin_taxon_concept_names_path(tc)), nil) ) + - if input_or_output.is_a?(NomenclatureChange::Output) + if is_output content_tag(:p, "Name status: #{input_or_output.new_name_status || input_or_output.name_status}") end + - content_tag(:p, "Author: #{tc.author_year || tc.new_author_year}") + + content_tag(:p, "Author: #{tc.author_year || is_output && input_or_output.new_author_year}") + content_tag(:p, "Internal note: #{input_or_output.internal_note}") end From c2c4910dafb4e03dddeb72185b76eba66900b1ed Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 8 Oct 2015 11:19:31 +0100 Subject: [PATCH 031/365] changed deploy branch --- config/deploy/staging.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/deploy/staging.rb b/config/deploy/staging.rb index 34f27b87da..8923725796 100644 --- a/config/deploy/staging.rb +++ b/config/deploy/staging.rb @@ -1,5 +1,5 @@ set :stage, :staging -set :branch, "master" +set :branch, "nomenclature_changes" server "sapi-staging.linode.unep-wcmc.org", user: "wcmc", roles: %w{app web db} From 1bd4a734db57df0757f3a679fdf9183c452c03ff Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Thu, 8 Oct 2015 16:10:32 +0100 Subject: [PATCH 032/365] If note is nil then use empty string as default --- app/models/m_taxon_concept.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/m_taxon_concept.rb b/app/models/m_taxon_concept.rb index 31f4a58749..02dc524f33 100644 --- a/app/models/m_taxon_concept.rb +++ b/app/models/m_taxon_concept.rb @@ -244,7 +244,7 @@ def recently_changed ["hash_full_note_#{lng.downcase}", "full_note_#{lng.downcase}", "short_note_#{lng.downcase}"].each do |method_name| define_method(method_name) do current_cites_additions.map do |lc| - note = lc.send(method_name) + note = lc.send(method_name) || '' note && "Appendix #{lc.species_listing_name}:" + (note || '') + (" #{lc.nomenclature_note}" || '') end.join("\n") end From 72736cef59ef28eda607377ce34341de3f8562bb Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Thu, 8 Oct 2015 23:42:42 +0100 Subject: [PATCH 033/365] Replace joins with includes to fix readonly exception --- app/models/listing_change.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/listing_change.rb b/app/models/listing_change.rb index be2d651be3..e444a943d9 100644 --- a/app/models/listing_change.rb +++ b/app/models/listing_change.rb @@ -137,14 +137,14 @@ def duplicates(comparison_attributes_override = {}) ) ) if party_listing_distribution - relation = relation.joins(:party_listing_distribution).where( + relation = relation.includes(:party_listing_distribution).where( party_listing_distribution.comparison_conditions( party_listing_distribution.comparison_attributes.except(:listing_change_id) ) ) end if annotation - relation = relation.joins(:annotation).where( + relation = relation.includes(:annotation).where( annotation.comparison_conditions ) end From c816cf18c399d776bbc9e1f6a4f32e0d2eb7044d Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Sun, 11 Oct 2015 18:17:38 +0100 Subject: [PATCH 034/365] Name changes cascade if rank in range of Genus-Variety --- .../admin/taxon_concepts_controller.rb | 5 ++++ app/models/taxon_concept.rb | 7 ++++++ app/workers/update_taxonomy_worker.rb | 25 +++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 app/workers/update_taxonomy_worker.rb diff --git a/app/controllers/admin/taxon_concepts_controller.rb b/app/controllers/admin/taxon_concepts_controller.rb index efb1323587..a04392ae63 100644 --- a/app/controllers/admin/taxon_concepts_controller.rb +++ b/app/controllers/admin/taxon_concepts_controller.rb @@ -48,8 +48,12 @@ def create end def update + @taxon_concept = TaxonConcept.find(params[:id]) + rebuild_taxonomy = + @taxon_concept.rebuild_taxonomy?(params[:taxon_concept][:full_name]) update! do |success, failure| success.js { + UpdateTaxonomyWorker.perform_async if rebuild_taxonomy render 'update' } failure.js { @@ -59,6 +63,7 @@ def update render 'new' } success.html { + UpdateTaxonomyWorker.perform_async if rebuild_taxonomy redirect_to edit_admin_taxon_concept_url(@taxon_concept), :notice => 'Operation successful' } diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index 1fc483a45f..17fec10732 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -327,6 +327,12 @@ def expected_full_name(parent) end end + def rebuild_taxonomy?(new_full_name) + new_full_name and new_full_name != full_name and + Rank.in_range(Rank::VARIETY, Rank::GENUS).include?(rank.name) + end + + private def dependent_objects_map @@ -506,4 +512,5 @@ def ensure_taxonomic_position true end + end diff --git a/app/workers/update_taxonomy_worker.rb b/app/workers/update_taxonomy_worker.rb new file mode 100644 index 0000000000..32d1ae2dd5 --- /dev/null +++ b/app/workers/update_taxonomy_worker.rb @@ -0,0 +1,25 @@ +class UpdateTaxonomyWorker + include Sidekiq::Worker + + def perform + puts "Procedure: taxonomy" + ActiveRecord::Base.connection.execute( + "SELECT * FROM rebuild_taxonomy()" + ) + + changed_cnt = TaxonConcept.where('touched_at IS NOT NULL AND touched_at > updated_at').count + + if changed_cnt > 0 + # increment cache iterators if anything changed + Species::Search.increment_cache_iterator + Species::TaxonConceptPrefixMatcher.increment_cache_iterator + Checklist::Checklist.increment_cache_iterator + + TaxonConcept.update_all( + 'updated_at = touched_at', + 'touched_at IS NOT NULL AND touched_at > updated_at' + ) + end + + end +end From 68d55231412ce183c4004ad24847b8a3c89ec296 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Mon, 12 Oct 2015 10:45:02 +0100 Subject: [PATCH 035/365] Improve rebuild_taxonomy code --- app/controllers/admin/taxon_concepts_controller.rb | 2 +- app/models/taxon_concept.rb | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/controllers/admin/taxon_concepts_controller.rb b/app/controllers/admin/taxon_concepts_controller.rb index a04392ae63..29db859fa6 100644 --- a/app/controllers/admin/taxon_concepts_controller.rb +++ b/app/controllers/admin/taxon_concepts_controller.rb @@ -50,7 +50,7 @@ def create def update @taxon_concept = TaxonConcept.find(params[:id]) rebuild_taxonomy = - @taxon_concept.rebuild_taxonomy?(params[:taxon_concept][:full_name]) + @taxon_concept.rebuild_taxonomy?(params) update! do |success, failure| success.js { UpdateTaxonomyWorker.perform_async if rebuild_taxonomy diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index 17fec10732..90327e2d83 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -327,7 +327,8 @@ def expected_full_name(parent) end end - def rebuild_taxonomy?(new_full_name) + def rebuild_taxonomy?(params) + new_full_name = params[:taxon_concept] ? params[:taxon_concept][:full_name] : '' new_full_name and new_full_name != full_name and Rank.in_range(Rank::VARIETY, Rank::GENUS).include?(rank.name) end From dbed76cac8fc2326a1ab5a5851b227d5d0085976 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Mon, 12 Oct 2015 12:36:50 +0100 Subject: [PATCH 036/365] Moved init function into superclass to be used by all its subclasses --- .../admin/admin_in_place_editor.js.coffee | 80 +++++++++---------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/app/assets/javascripts/admin/admin_in_place_editor.js.coffee b/app/assets/javascripts/admin/admin_in_place_editor.js.coffee index 8a8ddc2383..2880d855a4 100644 --- a/app/assets/javascripts/admin/admin_in_place_editor.js.coffee +++ b/app/assets/javascripts/admin/admin_in_place_editor.js.coffee @@ -47,6 +47,46 @@ class AdminEditor $(alert).insertBefore($('h1')) + initTaxonConceptTypeaheads: () -> + + $('input.typeahead').each (idx) -> + formId = $(@).closest('form').attr('id') + + if formId? + matches = formId.match('^(.+_)?(new|edit)_(.+)$') + prefix = matches[3] + prefix = matches[1] + prefix unless matches[1] == undefined + + taxonomyEl = $('#' + prefix + '_taxonomy_id') + rankEl = $('#' + prefix + '_rank_id') + + #initialize this typeahead + $(@).typeahead + source: (query, process) => + $.get('/admin/taxon_concepts/autocomplete', + { + search_params: { + scientific_name: query, + taxonomy: { + id: taxonomyEl && taxonomyEl.val() || $(@).attr('data-taxonomy-id') + }, + rank: { + id: rankEl && rankEl.val() || $(@).attr('data-rank-id'), + scope: $(@).attr('data-rank-scope') + } + } + limit: 25 + }, (data) => + labels = [] + $.each(data, (i, item) => + label = item.full_name + ' ' + item.rank_name + labels.push(label) + ) + return process(labels) + ) + $().add(taxonomyEl).add(rankEl).change () => + $(@).val(null) + initSearchTypeahead: () -> $('.search-typeahead').typeahead source: (query, process) -> @@ -168,46 +208,6 @@ class TaxonConceptsEditor extends AdminEditor @initTaxonConceptTypeaheads() $('.distributions-list > a').popover({}); - initTaxonConceptTypeaheads: () -> - - $('input.typeahead').each (idx) -> - formId = $(@).closest('form').attr('id') - - if formId? - matches = formId.match('^(.+_)?(new|edit)_(.+)$') - prefix = matches[3] - prefix = matches[1] + prefix unless matches[1] == undefined - - taxonomyEl = $('#' + prefix + '_taxonomy_id') - rankEl = $('#' + prefix + '_rank_id') - - #initialize this typeahead - $(@).typeahead - source: (query, process) => - $.get('/admin/taxon_concepts/autocomplete', - { - search_params: { - scientific_name: query, - taxonomy: { - id: taxonomyEl && taxonomyEl.val() || $(@).attr('data-taxonomy-id') - }, - rank: { - id: rankEl && rankEl.val() || $(@).attr('data-rank-id'), - scope: $(@).attr('data-rank-scope') - } - } - limit: 25 - }, (data) => - labels = [] - $.each(data, (i, item) => - label = item.full_name + ' ' + item.rank_name - labels.push(label) - ) - return process(labels) - ) - $().add(taxonomyEl).add(rankEl).change () => - $(@).val(null) - alertSuccess: (txt) -> $('.alert').remove() From f6b8cf50b0759cdea3a8d336e8cbedbe7633ae97 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Mon, 12 Oct 2015 14:02:18 +0100 Subject: [PATCH 037/365] Fix split's interface outputs ordering --- app/assets/stylesheets/admin/layout.scss | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/app/assets/stylesheets/admin/layout.scss b/app/assets/stylesheets/admin/layout.scss index 39cb29b6ab..aa95b261b1 100644 --- a/app/assets/stylesheets/admin/layout.scss +++ b/app/assets/stylesheets/admin/layout.scss @@ -73,19 +73,15 @@ form.documents { width: 50%; } -ol { +form ol { counter-reset: listCounter; list-style-type: none; -} - -ol li { - counter-increment: listCounter; -} - -ol li:before { - content: "Taxon " counter(listCounter) "."; + .fields > li { counter-increment: listCounter; } + .fields > li:before { + content: "Taxon " counter(listCounter) "."; + } } .new-scientific-name-eg { display: inline-block; -} \ No newline at end of file +} From da59a09f8688c732e0334cf7a273058c8738c082 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 15 Oct 2015 14:22:29 +0100 Subject: [PATCH 038/365] fixed transfer of distribution references --- .../reassignment_transfer_processor.rb | 42 +++++++++++++++++++ ...bution_reassignments_processor_examples.rb | 8 +++- 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/app/models/nomenclature_change/reassignment_transfer_processor.rb b/app/models/nomenclature_change/reassignment_transfer_processor.rb index 39374951fa..c72d0b9c03 100644 --- a/app/models/nomenclature_change/reassignment_transfer_processor.rb +++ b/app/models/nomenclature_change/reassignment_transfer_processor.rb @@ -6,6 +6,7 @@ def process_reassignment(reassignment, reassignable) if reassigned_object reassigned_object.save(validate: false) post_process(reassigned_object, object_before_reassignment) + transfer_associations(reassigned_object, reassignable) end reassigned_object end @@ -48,4 +49,45 @@ def summary_line to #{@output.display_full_name}" end + protected + + def transfer_associations(reassigned_object, reassignable) + return if reassigned_object.id == reassignable.id + if reassigned_object.is_a?(Distribution) + # that means the distribution is a duplicate and was not transferred + # but it might have some distribution references and taggings + transfer_distribution_references(reassigned_object, reassignable) + transfer_distribution_taggings(reassigned_object, reassignable) + end + # destroy the original object + reassignable.delete + end + + def transfer_distribution_references(reassigned_object, reassignable) + return if reassignable.distribution_references.count == 0 + distribution_references_to_transfer = reassignable.distribution_references + if reassigned_object.distribution_references.count > 0 + distribution_references_to_transfer = distribution_references_to_transfer. + where( + 'reference_id NOT IN (?)', + reassigned_object.distribution_references.select(:reference_id) + .map(&:reference_id) + ) + end + distribution_references_to_transfer.update_all(distribution_id: reassigned_object.id) + end + + def transfer_distribution_taggings(reassigned_object, reassignable) + return if reassignable.taggings.count == 0 + taggings_to_transfer = reassignable.taggings + if reassigned_object.taggings.count > 0 + taggings_to_transfer = taggings_to_transfer. + where( + 'tag_id NOT IN (?)', + reassigned_object.taggings.select(:tag_id).map(&:tag_id) + ) + end + taggings_to_transfer.update_all(taggable_id: reassigned_object.id) + end + end diff --git a/spec/models/nomenclature_change/shared/distribution_reassignments_processor_examples.rb b/spec/models/nomenclature_change/shared/distribution_reassignments_processor_examples.rb index 920e0d06b0..fa7ac4e14e 100644 --- a/spec/models/nomenclature_change/shared/distribution_reassignments_processor_examples.rb +++ b/spec/models/nomenclature_change/shared/distribution_reassignments_processor_examples.rb @@ -19,6 +19,12 @@ ) } before(:each) do + original_d = create( + :distribution, + taxon_concept: output_species1, + geo_entity: poland + ) + original_d.distribution_references.create(reference_id: create(:reference).id) create(:preset_tag, model: 'Distribution', name: 'extinct') d = create( :distribution, @@ -33,5 +39,5 @@ specify{ expect(output_species1.distributions.count).to eq(2) } specify{ expect(output_species1.distributions.find_by_geo_entity_id(poland.id)).not_to be_nil } specify{ expect(output_species1.distributions.find_by_geo_entity_id(poland.id).tag_list).to eq(['extinct']) } - specify{ expect(output_species1.distributions.find_by_geo_entity_id(poland.id).distribution_references.count).to eq(1) } + specify{ expect(output_species1.distributions.find_by_geo_entity_id(poland.id).distribution_references.count).to eq(2) } end From fe695dc778c5d753cbae8ce2af1c284c6bf03c59 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 15 Oct 2015 14:24:46 +0100 Subject: [PATCH 039/365] fixed typo in debug output --- app/models/nomenclature_change/reassignment_processor.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/nomenclature_change/reassignment_processor.rb b/app/models/nomenclature_change/reassignment_processor.rb index 6c7554a83c..1562aea902 100644 --- a/app/models/nomenclature_change/reassignment_processor.rb +++ b/app/models/nomenclature_change/reassignment_processor.rb @@ -85,7 +85,7 @@ def conflicting_listing_change_reassignment?(reassignment, reassignable) end def post_process(reassigned_object, object_before_reassignment) - Rails.logger.warn("Resassignment post processing BEGIN") + Rails.logger.warn("Reassignment post processing BEGIN") if reassigned_object.is_a?(TaxonConcept) resolver = NomenclatureChange::TaxonomicTreeNameResolver.new(reassigned_object) resolver.process @@ -93,7 +93,7 @@ def post_process(reassigned_object, object_before_reassignment) resolver = NomenclatureChange::TradeShipmentsResolver.new(reassigned_object, object_before_reassignment) resolver.process end - Rails.logger.warn("Resassignment post processing END") + Rails.logger.warn("Reassignment post processing END") end end From bf5fba0b29eaa3b92e5fdd1c4d8ac820f7be7de1 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 15 Oct 2015 22:24:46 +0100 Subject: [PATCH 040/365] ensure dependencies are destroyed --- .../reassignment_transfer_processor.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/models/nomenclature_change/reassignment_transfer_processor.rb b/app/models/nomenclature_change/reassignment_transfer_processor.rb index c72d0b9c03..ac90a8c4ad 100644 --- a/app/models/nomenclature_change/reassignment_transfer_processor.rb +++ b/app/models/nomenclature_change/reassignment_transfer_processor.rb @@ -59,8 +59,14 @@ def transfer_associations(reassigned_object, reassignable) transfer_distribution_references(reassigned_object, reassignable) transfer_distribution_taggings(reassigned_object, reassignable) end + if reassigned_object.is_a?(ListingChange) + transfer_party_listing_distribution(reassigned_object, reassignable) + transfer_listing_distributions(reassigned_object, reassignable) + transfer_taxonomic_exclusions(reassigned_object, reassignable) + transfer_geographic_exclusions(reassigned_object, reassignable) + end # destroy the original object - reassignable.delete + reassignable.destroy end def transfer_distribution_references(reassigned_object, reassignable) From 6add68c81ac98a37fbc691e2dfc070f19a000783 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 15 Oct 2015 22:25:13 +0100 Subject: [PATCH 041/365] fixed transfer of listing distributions --- .../reassignment_transfer_processor.rb | 40 +++++++++++++++++++ ...lation_reassignments_processor_examples.rb | 21 +++++++++- 2 files changed, 59 insertions(+), 2 deletions(-) diff --git a/app/models/nomenclature_change/reassignment_transfer_processor.rb b/app/models/nomenclature_change/reassignment_transfer_processor.rb index ac90a8c4ad..53fc4786bb 100644 --- a/app/models/nomenclature_change/reassignment_transfer_processor.rb +++ b/app/models/nomenclature_change/reassignment_transfer_processor.rb @@ -96,4 +96,44 @@ def transfer_distribution_taggings(reassigned_object, reassignable) taggings_to_transfer.update_all(taggable_id: reassigned_object.id) end + def transfer_party_listing_distribution(reassigned_object, reassignable) + return if reassigned_object.party_listing_distribution + return if !reassignable.party_listing_distribution + reassignable.party_listing_distribution.update_attribute(:listing_change_id, reassigned_object.id) + end + + def transfer_listing_distributions(reassigned_object, reassignable) + return if reassignable.listing_distributions.count == 0 + listing_distributions_to_transfer = reassignable.listing_distributions + + if reassigned_object.listing_distributions.count > 0 + listing_distributions_to_transfer = listing_distributions_to_transfer. + where( + 'geo_entity_id NOT IN (?)', + reassigned_object.listing_distributions.select(:geo_entity_id) + .map(&:geo_entity_id) + ) + end + listing_distributions_to_transfer.update_all(listing_change_id: reassigned_object.id) + end + + + def transfer_taxonomic_exclusions(reassigned_object, reassignable) + return if reassignable.taxonomic_exclusions.count == 0 + taxonomic_exclusions_to_transfer = reassignable.taxonomic_exclusions + if reassigned_object.taxonomic_exclusions.count > 0 + taxonomic_exclusions_to_transfer = taxonomic_exclusions_to_transfer. + where( + 'taxon_concept_id NOT IN (?)', + reassigned_object.taxonomic_exclusions.select(:taxon_concept_id). + map(&:taxon_concept_id) + ) + end + taxonomic_exclusions_to_transfer.update_all(parent_id: reassigned_object.id) + end + + def transfer_geographic_exclusions(reassigned_object, reassignable) + reassignable.geographic_exclusions.update_all(parent_id: reassigned_object.id) + end + end diff --git a/spec/models/nomenclature_change/shared/legislation_reassignments_processor_examples.rb b/spec/models/nomenclature_change/shared/legislation_reassignments_processor_examples.rb index a6aed65b1d..4cbad93acc 100644 --- a/spec/models/nomenclature_change/shared/legislation_reassignments_processor_examples.rb +++ b/spec/models/nomenclature_change/shared/legislation_reassignments_processor_examples.rb @@ -15,6 +15,23 @@ } before(:each) do lc1_annotation = create(:annotation) + original_lc1 = create_cites_III_addition( + taxon_concept: output_species1, + annotation: lc1_annotation, + effective_at: '2013-01-01' + ) + create( + :listing_distribution, + geo_entity: poland, + listing_change: original_lc1, + is_party: true + ) + create( + :listing_distribution, + geo_entity: portugal, + listing_change: original_lc1, + is_party: false + ) lc1 = create_cites_III_addition( taxon_concept: input_species, annotation: lc1_annotation, @@ -99,8 +116,8 @@ expect( output_species1.listing_changes. find_by_effective_at_and_change_type_id('2013-01-01', cites_addition.id). - listing_distributions - ).to_not be_empty + listing_distributions.count + ).to eq(2) } specify{ expect( From b22316b83be3948e9eb2dacf6f023c7f0c439a07 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 15 Oct 2015 22:38:59 +0100 Subject: [PATCH 042/365] clear downloads cache after processing --- app/models/nomenclature_change/processor.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/models/nomenclature_change/processor.rb b/app/models/nomenclature_change/processor.rb index b967dece97..a0899d926b 100644 --- a/app/models/nomenclature_change/processor.rb +++ b/app/models/nomenclature_change/processor.rb @@ -11,6 +11,7 @@ def run Rails.logger.warn("[#{@nc.type}] BEGIN") @subprocessors.each{ |processor| processor.run } Rails.logger.warn("[#{@nc.type}] END") + DownloadsCache.clear end def summary From fdab5d18e95b4cb960aa89fd57ff3cd7bffea71a Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 12 Oct 2015 15:00:43 +0100 Subject: [PATCH 043/365] removed unused taxon concept create action --- .../admin/taxon_concepts_controller.rb | 16 ---------------- config/routes.rb | 2 +- .../admin/taxon_concepts_controller_spec.rb | 13 ------------- 3 files changed, 1 insertion(+), 30 deletions(-) diff --git a/app/controllers/admin/taxon_concepts_controller.rb b/app/controllers/admin/taxon_concepts_controller.rb index 29db859fa6..9a4ca5b665 100644 --- a/app/controllers/admin/taxon_concepts_controller.rb +++ b/app/controllers/admin/taxon_concepts_controller.rb @@ -31,22 +31,6 @@ def edit end end - def create - create! do |success, failure| - @taxonomies = Taxonomy.order(:name) - @ranks = Rank.order(:taxonomic_position) - success.js { render('create') } - failure.js { - if @taxon_concept.is_synonym? - @synonym = @taxon_concept - render('new_synonym') - else - render('new') - end - } - end - end - def update @taxon_concept = TaxonConcept.find(params[:id]) rebuild_taxonomy = diff --git a/config/routes.rb b/config/routes.rb index 19e644bfe5..c5fba8855d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -118,7 +118,7 @@ resources :ahoy_visits, :only => [:index, :show] resources :ahoy_events, :only => [:index, :show] - resources :taxon_concepts do + resources :taxon_concepts, only: [:index, :edit, :update, :show, :destroy] do get :autocomplete, :on => :collection resources :children, :only => [:index] resources :taxon_relationships, :only => [:index, :create, :destroy] diff --git a/spec/controllers/admin/taxon_concepts_controller_spec.rb b/spec/controllers/admin/taxon_concepts_controller_spec.rb index 962f38078e..bfc8a03805 100644 --- a/spec/controllers/admin/taxon_concepts_controller_spec.rb +++ b/spec/controllers/admin/taxon_concepts_controller_spec.rb @@ -33,19 +33,6 @@ end end - describe "XHR POST create" do - let(:taxon_concept_attributes){ build_tc_attributes(:taxon_concept) } - it "renders create when successful" do - xhr :post, :create, - taxon_concept: taxon_concept_attributes - response.should render_template("create") - end - it "renders new when not successful" do - xhr :post, :create, taxon_concept: {} - response.should render_template("new") - end - end - describe "XHR PUT update" do let(:taxon_concept){ create(:taxon_concept) } context "when JSON" do From 61d68a8ebaa432706177eb7120662a2fd4b67c58 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 12 Oct 2015 16:57:08 +0100 Subject: [PATCH 044/365] removed unused new synonym form (the "not nested" one, formerly available on the home page) --- app/helpers/taxon_concept_helper.rb | 8 ++--- app/views/admin/names/index.html.erb | 2 +- .../taxon_concepts/_synonym_form.html.erb | 34 ------------------- .../admin/taxon_concepts/new_synonym.js.erb | 4 --- 4 files changed, 5 insertions(+), 43 deletions(-) delete mode 100644 app/views/admin/taxon_concepts/_synonym_form.html.erb delete mode 100644 app/views/admin/taxon_concepts/new_synonym.js.erb diff --git a/app/helpers/taxon_concept_helper.rb b/app/helpers/taxon_concept_helper.rb index e93e12c574..7d8168f6c3 100644 --- a/app/helpers/taxon_concept_helper.rb +++ b/app/helpers/taxon_concept_helper.rb @@ -45,11 +45,11 @@ def admin_add_new_hybrid_button ) end - def admin_new_synonym_modal(nested = false) + def admin_new_synonym_modal admin_new_modal( - :resource => 'taxon_concept_synonym', - :title => 'Add new Synonym' - ){ nested ? '' : render('synonym_form') } + resource: 'taxon_concept_synonym', + title: 'Add new Synonym' + ){ '' } end def admin_new_trade_name_modal(nested = false) diff --git a/app/views/admin/names/index.html.erb b/app/views/admin/names/index.html.erb index 8036c68d9d..14b7311672 100644 --- a/app/views/admin/names/index.html.erb +++ b/app/views/admin/names/index.html.erb @@ -3,7 +3,7 @@

Synonyms

<%= admin_add_new_synonym_button %> - <%= admin_new_synonym_modal(true) %> + <%= admin_new_synonym_modal %>
<% if @taxon_concept.has_synonyms? %> diff --git a/app/views/admin/taxon_concepts/_synonym_form.html.erb b/app/views/admin/taxon_concepts/_synonym_form.html.erb deleted file mode 100644 index 743d744acd..0000000000 --- a/app/views/admin/taxon_concepts/_synonym_form.html.erb +++ /dev/null @@ -1,34 +0,0 @@ -<%= form_for [:admin, @synonym], :remote => true, :namespace => 'synonym' do |f| %> - <%= error_messages_for(@synonym) %> - <%= f.hidden_field :name_status %> - -
- - <%= f.select :taxonomy_id, - options_from_collection_for_select( - @taxonomies, :id, :name, @synonym && @synonym.taxonomy_id - ) - %> -
-
- - <%= f.select :rank_id, - options_from_collection_for_select( - @ranks, :id, :name, - @synonym && @synonym.rank_id - ) - %> -
-
- - <%= f.text_field :accepted_scientific_name, :class => 'typeahead' %> -
-
- - <%= f.text_field :full_name %> -
-
- - <%= f.text_field :author_year %> -
-<% end %> diff --git a/app/views/admin/taxon_concepts/new_synonym.js.erb b/app/views/admin/taxon_concepts/new_synonym.js.erb deleted file mode 100644 index e85a9b24c3..0000000000 --- a/app/views/admin/taxon_concepts/new_synonym.js.erb +++ /dev/null @@ -1,4 +0,0 @@ -$('#admin-new-taxon_concept_synonym-form').html( - "<%= escape_javascript(render('synonym_form')) %>"); -$('#new-taxon_concept_synonym').modal('show'); -window.adminEditor.initTaxonConceptTypeaheads(); \ No newline at end of file From 6875359243839064884270a5d702846dd1d2947a Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 12 Oct 2015 17:15:53 +0100 Subject: [PATCH 045/365] changed the new synonym modal to allow selecting an existing synonym --- .../admin/nomenclature_changes.js.coffee | 8 ++--- .../synonym_relationships/_form.html.erb | 35 ++++++++----------- .../admin/synonym_relationships/new.js.erb | 1 + 3 files changed, 19 insertions(+), 25 deletions(-) diff --git a/app/assets/javascripts/admin/nomenclature_changes.js.coffee b/app/assets/javascripts/admin/nomenclature_changes.js.coffee index 0a8ce9f2d0..9470027d46 100644 --- a/app/assets/javascripts/admin/nomenclature_changes.js.coffee +++ b/app/assets/javascripts/admin/nomenclature_changes.js.coffee @@ -1,5 +1,5 @@ $(document).ready -> - defaultTaxonSelect2Options = { + window.defaultTaxonSelect2Options = { placeholder: 'Start typing scientific name' width: '300px' minimumInputLength: 3 @@ -43,8 +43,8 @@ $(document).ready -> callback(result) } - $('.taxon-concept').select2(defaultTaxonSelect2Options) - $('.taxon-concept-multiple').select2($.extend(defaultTaxonSelect2Options,multiTaxonSelect2Options)) + $('.taxon-concept').select2(window.defaultTaxonSelect2Options) + $('.taxon-concept-multiple').select2($.extend(window.defaultTaxonSelect2Options,multiTaxonSelect2Options)) $('.taxon-concept').on('change', (event) -> return false unless event.val $.when($.ajax( '/admin/taxon_concepts/' + event.val + '.json' ) ).then(( data, textStatus, jqXHR ) => @@ -82,7 +82,7 @@ $(document).ready -> # it's a jQuery object already taxonField = field.find('.taxon-concept') # and activate select2 - taxonField.select2(defaultTaxonSelect2Options) + taxonField.select2(window.defaultTaxonSelect2Options) ) simpleTaxonSelect2Options = { diff --git a/app/views/admin/synonym_relationships/_form.html.erb b/app/views/admin/synonym_relationships/_form.html.erb index 23540c0336..67bfbf7570 100644 --- a/app/views/admin/synonym_relationships/_form.html.erb +++ b/app/views/admin/synonym_relationships/_form.html.erb @@ -6,26 +6,19 @@ <%= form_for [:admin, @taxon_concept, @synonym_relationship], :url => form_url, :remote => true do |f| %> <%= error_messages_for(@synonym_relationship) %> <%= f.hidden_field :taxon_relationship_type_id %> - <%= f.fields_for :other_taxon_concept do |ff| %> - <%= ff.hidden_field :name_status %> - <%= ff.hidden_field :taxonomy_id %> -
- - <%= ff.select :rank_id, - options_from_collection_for_select( - @ranks, :id, :name, - @synonym_relationship && @synonym_relationship.other_taxon_concept && - @synonym_relationship.other_taxon_concept.rank_id - ) - %> +
+ +
+ <%= f.text_field :other_taxon_concept_id, { + :class => 'taxon-concept clear-others', + :'data-name' => @synonym_relationship.other_taxon_concept.try(:full_name), + :'data-name-status' => @synonym_relationship.other_taxon_concept.try(:name_status), + :'data-name-status-filter' => ['S'], + :'data-taxonomy-id' => @taxon_concept.taxonomy_id + } %>
-
- - <%= ff.text_field :full_name %> -
-
- - <%= ff.text_field :author_year %> -
- <% end %> +
+

+ <%= link_to 'Create a new synonym', admin_nomenclature_changes_path %> +

<% end %> diff --git a/app/views/admin/synonym_relationships/new.js.erb b/app/views/admin/synonym_relationships/new.js.erb index f8f76fdbeb..8443208178 100644 --- a/app/views/admin/synonym_relationships/new.js.erb +++ b/app/views/admin/synonym_relationships/new.js.erb @@ -1,2 +1,3 @@ $('#admin-new-taxon_concept_synonym-form').html("<%= escape_javascript(render('form')) %>"); $('#new-taxon_concept_synonym').modal('show'); +$('.taxon-concept').select2(window.defaultTaxonSelect2Options); From 9f98ff012844205c501c3486cd69484167e3eddb Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 12 Oct 2015 17:23:11 +0100 Subject: [PATCH 046/365] changed the new trade name modal to allow selecting an existing synonym --- app/helpers/taxon_concept_helper.rb | 4 +-- app/views/admin/names/index.html.erb | 2 +- .../trade_name_relationships/_form.html.erb | 32 +++++++------------ .../admin/trade_name_relationships/new.js.erb | 1 + 4 files changed, 15 insertions(+), 24 deletions(-) diff --git a/app/helpers/taxon_concept_helper.rb b/app/helpers/taxon_concept_helper.rb index 7d8168f6c3..2175b4c3ba 100644 --- a/app/helpers/taxon_concept_helper.rb +++ b/app/helpers/taxon_concept_helper.rb @@ -52,11 +52,11 @@ def admin_new_synonym_modal ){ '' } end - def admin_new_trade_name_modal(nested = false) + def admin_new_trade_name_modal admin_new_modal( :resource => 'taxon_concept_trade_name', :title => 'Add new Trade name' - ){ nested ? '' : render('trade_name_form') } + ){ '' } end def admin_add_new_distribution_button diff --git a/app/views/admin/names/index.html.erb b/app/views/admin/names/index.html.erb index 14b7311672..ef3f92df42 100644 --- a/app/views/admin/names/index.html.erb +++ b/app/views/admin/names/index.html.erb @@ -16,7 +16,7 @@

Trade names

<%= admin_add_new_trade_name_button %> - <%= admin_new_trade_name_modal(true) %> + <%= admin_new_trade_name_modal %>
<% if @taxon_concept.has_trade_names? %> diff --git a/app/views/admin/trade_name_relationships/_form.html.erb b/app/views/admin/trade_name_relationships/_form.html.erb index f63bbf6de5..7b34e9e9ca 100644 --- a/app/views/admin/trade_name_relationships/_form.html.erb +++ b/app/views/admin/trade_name_relationships/_form.html.erb @@ -6,26 +6,16 @@ <%= form_for [:admin, @taxon_concept, @trade_name_relationship], :url => form_url, :remote => true do |f| %> <%= error_messages_for(@trade_name_relationship) %> <%= f.hidden_field :taxon_relationship_type_id %> - <%= f.fields_for :other_taxon_concept do |ff| %> - <%= ff.hidden_field :name_status %> - <%= ff.hidden_field :taxonomy_id %> -
- - <%= ff.select :rank_id, - options_from_collection_for_select( - @ranks, :id, :name, - @trade_name_relationship && @trade_name_relationship.other_taxon_concept && - @trade_name_relationship.other_taxon_concept.rank_id - ) - %> +
+ +
+ <%= f.text_field :other_taxon_concept_id, { + :class => 'taxon-concept clear-others', + :'data-name' => @trade_name_relationship.other_taxon_concept.try(:full_name), + :'data-name-status' => @trade_name_relationship.other_taxon_concept.try(:name_status), + :'data-name-status-filter' => ['T'], + :'data-taxonomy-id' => @taxon_concept.taxonomy_id + } %>
-
- - <%= ff.text_field :full_name %> -
-
- - <%= ff.text_field :author_year %> -
- <% end %> +
<% end %> diff --git a/app/views/admin/trade_name_relationships/new.js.erb b/app/views/admin/trade_name_relationships/new.js.erb index b412d99195..45bf14bc96 100644 --- a/app/views/admin/trade_name_relationships/new.js.erb +++ b/app/views/admin/trade_name_relationships/new.js.erb @@ -1,2 +1,3 @@ $('#admin-new-taxon_concept_trade_name-form').html("<%= escape_javascript(render('form')) %>"); $('#new-taxon_concept_trade_name').modal('show'); +$('.taxon-concept').select2(window.defaultTaxonSelect2Options); From f41caa5b024a1e3f7d6b434a79c0e05a7ab250a1 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 13 Oct 2015 11:39:14 +0100 Subject: [PATCH 047/365] removed potentially obsolete script --- app/views/admin/taxon_concepts/create_synonym.js.erb | 4 ---- 1 file changed, 4 deletions(-) delete mode 100644 app/views/admin/taxon_concepts/create_synonym.js.erb diff --git a/app/views/admin/taxon_concepts/create_synonym.js.erb b/app/views/admin/taxon_concepts/create_synonym.js.erb deleted file mode 100644 index 5fceb22b04..0000000000 --- a/app/views/admin/taxon_concepts/create_synonym.js.erb +++ /dev/null @@ -1,4 +0,0 @@ -$('.modal').modal('hide'); -$('#synonyms-list').html("<%= escape_javascript(render('synonym_list')) %>"); -window.adminEditor.initEditors(); -window.adminEditor.alertSuccess("Operation successful"); From 6362ab06a0a6375a822d5baeabe69a7b920685ea Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 13 Oct 2015 11:41:28 +0100 Subject: [PATCH 048/365] fixes edit modal windows for synonyms & trade names --- app/assets/javascripts/admin/nomenclature_changes.js.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/assets/javascripts/admin/nomenclature_changes.js.coffee b/app/assets/javascripts/admin/nomenclature_changes.js.coffee index 9470027d46..111a0b6658 100644 --- a/app/assets/javascripts/admin/nomenclature_changes.js.coffee +++ b/app/assets/javascripts/admin/nomenclature_changes.js.coffee @@ -44,7 +44,7 @@ $(document).ready -> } $('.taxon-concept').select2(window.defaultTaxonSelect2Options) - $('.taxon-concept-multiple').select2($.extend(window.defaultTaxonSelect2Options,multiTaxonSelect2Options)) + $('.taxon-concept-multiple').select2($.extend({}, window.defaultTaxonSelect2Options, multiTaxonSelect2Options)) $('.taxon-concept').on('change', (event) -> return false unless event.val $.when($.ajax( '/admin/taxon_concepts/' + event.val + '.json' ) ).then(( data, textStatus, jqXHR ) => From d8417ac500d502b4c7d38e5e88bfc46f3d5f5b77 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 13 Oct 2015 11:44:43 +0100 Subject: [PATCH 049/365] changed the new hybrid modal to allow selecting an existing hybrid --- app/helpers/taxon_concept_helper.rb | 4 +- .../admin/hybrid_relationships/_form.html.erb | 54 +++++-------------- .../admin/hybrid_relationships/new.js.erb | 9 +--- app/views/admin/names/index.html.erb | 2 +- .../taxon_concepts/_hybrid_form.html.erb | 54 ------------------- .../admin/taxon_concepts/new_hybrid.js.erb | 4 -- 6 files changed, 19 insertions(+), 108 deletions(-) delete mode 100644 app/views/admin/taxon_concepts/_hybrid_form.html.erb delete mode 100644 app/views/admin/taxon_concepts/new_hybrid.js.erb diff --git a/app/helpers/taxon_concept_helper.rb b/app/helpers/taxon_concept_helper.rb index 2175b4c3ba..656809cdd6 100644 --- a/app/helpers/taxon_concept_helper.rb +++ b/app/helpers/taxon_concept_helper.rb @@ -96,11 +96,11 @@ def admin_edit_distribution_modal(nested = false) ){ nested ? '' : render('admin/distributions/form') } end - def admin_new_hybrid_modal(nested = false) + def admin_new_hybrid_modal admin_new_modal( :resource => 'taxon_concept_hybrid', :title => 'Add new Hybrid' - ){ nested ? '' : render('hybrid_form') } + ){ '' } end def admin_add_new_reference_button diff --git a/app/views/admin/hybrid_relationships/_form.html.erb b/app/views/admin/hybrid_relationships/_form.html.erb index 7acaa6f1a6..5664fb494d 100644 --- a/app/views/admin/hybrid_relationships/_form.html.erb +++ b/app/views/admin/hybrid_relationships/_form.html.erb @@ -6,45 +6,19 @@ <%= form_for [:admin, @taxon_concept, @hybrid_relationship], :url => form_url, :remote => true do |f| %> <%= error_messages_for(@hybrid_relationship) %> <%= f.hidden_field :taxon_relationship_type_id %> - <%= f.fields_for :other_taxon_concept do |ff| %> - <%= ff.hidden_field :name_status %> - <%= ff.hidden_field :taxonomy_id %> -
- - <%= ff.select :rank_id, - options_from_collection_for_select( - @ranks, :id, :name, - @hybrid_relationship && @hybrid_relationship.other_taxon_concept && - @hybrid_relationship.other_taxon_concept.rank_id - ) - %> +
+ +
+ <%= f.text_field :other_taxon_concept_id, { + :class => 'taxon-concept', + :'data-name' => @hybrid_relationship.other_taxon_concept.try(:full_name), + :'data-name-status' => @hybrid_relationship.other_taxon_concept.try(:name_status), + :'data-name-status-filter' => ['H'], + :'data-taxonomy-id' => @taxon_concept.taxonomy_id + } %>
-
- - <%= ff.text_field :other_hybrid_parent_scientific_name, - :class => 'typeahead', "data-rank-scope" => 'ancestors', - "data-taxonomy-id" => @taxon_concept.taxonomy_id - %> -
-
- - <%= ff.text_field :full_name %> -
-
- - <%= ff.select :tag_list, - options_from_collection_for_select( - @tags, - :name, - :name, - @taxon_concept.tag_list - ), {}, - { :multiple => true, :class => 'tags', :style => "width: 220px"} - %> -
-
- - <%= ff.text_field :author_year %> -
- <% end %> +
+

+ <%= link_to 'Create a new hybrid', admin_nomenclature_changes_path %> +

<% end %> diff --git a/app/views/admin/hybrid_relationships/new.js.erb b/app/views/admin/hybrid_relationships/new.js.erb index 3a10e2da7c..f7bf1a9dd7 100644 --- a/app/views/admin/hybrid_relationships/new.js.erb +++ b/app/views/admin/hybrid_relationships/new.js.erb @@ -1,8 +1,3 @@ -// $().html is asynchronous, inexplicably, so we render the form to a jQuery object -// first and init the tag box before passing to .html() -var form = $("<%= escape_javascript(render('form')) %>"); -form.find('.tags').select2(); - -$('#admin-new-taxon_concept_hybrid-form').html(form); +$('#admin-new-taxon_concept_hybrid-form').html("<%= escape_javascript(render('form')) %>"); $('#new-taxon_concept_hybrid').modal('show'); -window.adminEditor.initTaxonConceptTypeaheads(); +$('.taxon-concept').select2(window.defaultTaxonSelect2Options); diff --git a/app/views/admin/names/index.html.erb b/app/views/admin/names/index.html.erb index ef3f92df42..393c22adf5 100644 --- a/app/views/admin/names/index.html.erb +++ b/app/views/admin/names/index.html.erb @@ -43,7 +43,7 @@

Hybrids

<%= admin_add_new_hybrid_button %> - <%= admin_new_hybrid_modal(true) %> + <%= admin_new_hybrid_modal %>
<% if @taxon_concept.has_hybrids? %> diff --git a/app/views/admin/taxon_concepts/_hybrid_form.html.erb b/app/views/admin/taxon_concepts/_hybrid_form.html.erb deleted file mode 100644 index d2e632e01a..0000000000 --- a/app/views/admin/taxon_concepts/_hybrid_form.html.erb +++ /dev/null @@ -1,54 +0,0 @@ -<%= form_for [:admin, @hybrid], :remote => true, :namespace => 'hybrid' do |f| %> - <%= error_messages_for(@hybrid) %> - <%= f.hidden_field :name_status %> - -
- - <%= f.select :taxonomy_id, - options_from_collection_for_select( - @taxonomies, :id, :name, @hybrid && @hybrid.taxonomy_id - ) - %> -
-
- - <%= f.select :rank_id, - options_from_collection_for_select( - @ranks, :id, :name, - @hybrid && @hybrid.rank_id - ) - %> -
-
- - <%= f.text_field :hybrid_parent_scientific_name, :class => 'typeahead', - "data-rank-scope" => 'ancestors' - %> -
-
- - <%= f.text_field :other_hybrid_parent_scientific_name, :class => 'typeahead', - "data-rank-scope" => 'ancestors' - %> -
-
- - <%= f.text_field :full_name %> -
-
- - <%= f.select :tag_list, - options_from_collection_for_select( - @tags, - :name, - :name, - @taxon_concept.tag_list - ), {}, - { :multiple => true, :class => 'tags', :style => "width: 220px"} - %> -
-
- - <%= f.text_field :author_year %> -
-<% end %> diff --git a/app/views/admin/taxon_concepts/new_hybrid.js.erb b/app/views/admin/taxon_concepts/new_hybrid.js.erb deleted file mode 100644 index feff054727..0000000000 --- a/app/views/admin/taxon_concepts/new_hybrid.js.erb +++ /dev/null @@ -1,4 +0,0 @@ -$('#admin-new-taxon_concept_hybrid-form').html( - "<%= escape_javascript(render('hybrid_form')) %>"); -$('#new-taxon_concept_hybrid').modal('show'); -window.adminEditor.initTaxonConceptTypeaheads(); \ No newline at end of file From 19aaa353c92e80e1ea36b4dc260f06581947bb98 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 13 Oct 2015 12:56:02 +0100 Subject: [PATCH 050/365] removed obsolete initialisation --- app/views/admin/hybrid_relationships/create.js.erb | 1 - app/views/admin/synonym_relationships/create.js.erb | 1 - app/views/admin/trade_name_relationships/create.js.erb | 1 - 3 files changed, 3 deletions(-) diff --git a/app/views/admin/hybrid_relationships/create.js.erb b/app/views/admin/hybrid_relationships/create.js.erb index fc0d86f0ba..ccb7f0f7ce 100644 --- a/app/views/admin/hybrid_relationships/create.js.erb +++ b/app/views/admin/hybrid_relationships/create.js.erb @@ -1,4 +1,3 @@ $('.modal').modal('hide'); $('#hybrids-list').html("<%= escape_javascript(render('list')) %>"); -window.adminEditor.initEditors(); window.adminEditor.alertSuccess("Operation successful"); diff --git a/app/views/admin/synonym_relationships/create.js.erb b/app/views/admin/synonym_relationships/create.js.erb index a4cc901a56..96b64a99b9 100644 --- a/app/views/admin/synonym_relationships/create.js.erb +++ b/app/views/admin/synonym_relationships/create.js.erb @@ -1,4 +1,3 @@ $('.modal').modal('hide'); $('#synonyms-list').html("<%= escape_javascript(render('list')) %>"); -window.adminEditor.initEditors(); window.adminEditor.alertSuccess("Operation successful"); diff --git a/app/views/admin/trade_name_relationships/create.js.erb b/app/views/admin/trade_name_relationships/create.js.erb index 0450c11c48..2cea289101 100644 --- a/app/views/admin/trade_name_relationships/create.js.erb +++ b/app/views/admin/trade_name_relationships/create.js.erb @@ -1,4 +1,3 @@ $('.modal').modal('hide'); $('#trade_names-list').html("<%= escape_javascript(render('list')) %>"); -window.adminEditor.initEditors(); window.adminEditor.alertSuccess("Operation successful"); From 4471882515177574dd5b50a0571fa4c9db959289 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 13 Oct 2015 12:56:36 +0100 Subject: [PATCH 051/365] removed obsolete class name --- app/views/admin/synonym_relationships/_form.html.erb | 2 +- app/views/admin/trade_name_relationships/_form.html.erb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/admin/synonym_relationships/_form.html.erb b/app/views/admin/synonym_relationships/_form.html.erb index 67bfbf7570..fea36ebd02 100644 --- a/app/views/admin/synonym_relationships/_form.html.erb +++ b/app/views/admin/synonym_relationships/_form.html.erb @@ -10,7 +10,7 @@
<%= f.text_field :other_taxon_concept_id, { - :class => 'taxon-concept clear-others', + :class => 'taxon-concept', :'data-name' => @synonym_relationship.other_taxon_concept.try(:full_name), :'data-name-status' => @synonym_relationship.other_taxon_concept.try(:name_status), :'data-name-status-filter' => ['S'], diff --git a/app/views/admin/trade_name_relationships/_form.html.erb b/app/views/admin/trade_name_relationships/_form.html.erb index 7b34e9e9ca..98e2740779 100644 --- a/app/views/admin/trade_name_relationships/_form.html.erb +++ b/app/views/admin/trade_name_relationships/_form.html.erb @@ -10,7 +10,7 @@
<%= f.text_field :other_taxon_concept_id, { - :class => 'taxon-concept clear-others', + :class => 'taxon-concept', :'data-name' => @trade_name_relationship.other_taxon_concept.try(:full_name), :'data-name-status' => @trade_name_relationship.other_taxon_concept.try(:name_status), :'data-name-status-filter' => ['T'], From 368b747bf91afbb01104b932ff7fb35bd5f56330 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 13 Oct 2015 14:24:21 +0100 Subject: [PATCH 052/365] removed obsolete loading code --- .../admin/hybrid_relationships_controller.rb | 15 ------------ .../admin/synonym_relationships_controller.rb | 24 ------------------- .../trade_name_relationships_controller.rb | 24 ------------------- 3 files changed, 63 deletions(-) diff --git a/app/controllers/admin/hybrid_relationships_controller.rb b/app/controllers/admin/hybrid_relationships_controller.rb index 183ab30cb2..32b62d3d0e 100644 --- a/app/controllers/admin/hybrid_relationships_controller.rb +++ b/app/controllers/admin/hybrid_relationships_controller.rb @@ -7,19 +7,10 @@ class Admin::HybridRelationshipsController < Admin::TaxonConceptAssociatedTypesC authorize_resource :class => false def new - @taxonomies = Taxonomy.order(:name) - @ranks = Rank.order(:taxonomic_position) - @tags = TaxonConcept.tag_counts_on('tags') new! do |format| @hybrid_relationship = TaxonRelationship.new( :taxon_relationship_type_id => @hybrid_relationship_type.id ) - @hybrid_relationship.build_other_taxon_concept( - :taxonomy_id => @taxon_concept.taxonomy_id, - :rank_id => @taxon_concept.rank_id, - :name_status => 'H' - ) - @hybrid_relationship.other_taxon_concept.build_taxon_name end end @@ -33,18 +24,12 @@ def create render 'create' } failure.js { - @taxonomies = Taxonomy.order(:name) - @ranks = Rank.order(:taxonomic_position) - @tags = TaxonConcept.tag_counts_on('tags') render 'new' } end end def edit - @taxonomies = Taxonomy.order(:name) - @ranks = Rank.order(:taxonomic_position) - @tags = TaxonConcept.tag_counts_on('tags') edit! do |format| format.js { render 'new' } end diff --git a/app/controllers/admin/synonym_relationships_controller.rb b/app/controllers/admin/synonym_relationships_controller.rb index 9a57d8a5bc..584e2ef024 100644 --- a/app/controllers/admin/synonym_relationships_controller.rb +++ b/app/controllers/admin/synonym_relationships_controller.rb @@ -6,16 +6,9 @@ class Admin::SynonymRelationshipsController < Admin::TaxonConceptAssociatedTypes def new new! do |format| - load_taxonomies_and_ranks @synonym_relationship = TaxonRelationship.new( :taxon_relationship_type_id => @synonym_relationship_type.id ) - @synonym_relationship.build_other_taxon_concept( - :taxonomy_id => @taxon_concept.taxonomy_id, - :rank_id => @taxon_concept.rank_id, - :name_status => 'S' - ) - @synonym_relationship.other_taxon_concept.build_taxon_name end end @@ -29,16 +22,6 @@ def create render 'create' } failure.js { - @synonym_relationship.build_other_taxon_concept( - :taxonomy_id => @taxon_concept.taxonomy_id, - :rank_id => @taxon_concept.rank_id, - :name_status => 'S', - :full_name => params[:taxon_relationship][:other_taxon_concept_attributes][:full_name], - :author_year => params[:taxon_relationship][:other_taxon_concept_attributes][:author_year] - - ) - @synonym_relationship.other_taxon_concept.build_taxon_name - load_taxonomies_and_ranks render 'new' } end @@ -46,7 +29,6 @@ def create def edit edit! do |format| - load_taxonomies_and_ranks format.js { render 'new' } end end @@ -61,7 +43,6 @@ def update render 'create' } failure.js { - load_taxonomies_and_ranks render 'new' } end @@ -77,11 +58,6 @@ def destroy protected - def load_taxonomies_and_ranks - @taxonomies = Taxonomy.order(:name) - @ranks = Rank.order(:taxonomic_position) - end - def load_synonym_relationship_type @synonym_relationship_type = TaxonRelationshipType. find_by_name(TaxonRelationshipType::HAS_SYNONYM) diff --git a/app/controllers/admin/trade_name_relationships_controller.rb b/app/controllers/admin/trade_name_relationships_controller.rb index c5c056cd8c..ca4b918182 100644 --- a/app/controllers/admin/trade_name_relationships_controller.rb +++ b/app/controllers/admin/trade_name_relationships_controller.rb @@ -6,16 +6,9 @@ class Admin::TradeNameRelationshipsController < Admin::TaxonConceptAssociatedTyp def new new! do |format| - load_taxonomies_and_ranks @trade_name_relationship = TaxonRelationship.new( :taxon_relationship_type_id => @trade_name_relationship_type.id ) - @trade_name_relationship.build_other_taxon_concept( - :taxonomy_id => @taxon_concept.taxonomy_id, - :rank_id => @taxon_concept.rank_id, - :name_status => 'T' - ) - @trade_name_relationship.other_taxon_concept.build_taxon_name end end @@ -29,16 +22,6 @@ def create render 'create' } failure.js { - @trade_name_relationship.build_other_taxon_concept( - :taxonomy_id => @taxon_concept.taxonomy_id, - :rank_id => @taxon_concept.rank_id, - :name_status => 'T', - :full_name => params[:taxon_relationship][:other_taxon_concept_attributes][:full_name], - :author_year => params[:taxon_relationship][:other_taxon_concept_attributes][:author_year] - - ) - @trade_name_relationship.other_taxon_concept.build_taxon_name - load_taxonomies_and_ranks render 'new' } end @@ -46,7 +29,6 @@ def create def edit edit! do |format| - load_taxonomies_and_ranks format.js { render 'new' } end end @@ -61,7 +43,6 @@ def update render 'create' } failure.js { - load_taxonomies_and_ranks render 'new' } end @@ -77,11 +58,6 @@ def destroy protected - def load_taxonomies_and_ranks - @taxonomies = Taxonomy.order(:name) - @ranks = Rank.order(:taxonomic_position) - end - def load_trade_name_relationship_type @trade_name_relationship_type = TaxonRelationshipType. find_by_name(TaxonRelationshipType::HAS_TRADE_NAME) From ca8ff61b77fcd531bb4429abd421f7effd921e8f Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 13 Oct 2015 14:25:12 +0100 Subject: [PATCH 053/365] added inverse relationships with input for reassignment subclasses --- app/models/nomenclature_change/distribution_reassignment.rb | 3 +++ app/models/nomenclature_change/legislation_reassignment.rb | 3 +++ app/models/nomenclature_change/name_reassignment.rb | 3 +++ app/models/nomenclature_change/parent_reassignment.rb | 3 +++ 4 files changed, 12 insertions(+) diff --git a/app/models/nomenclature_change/distribution_reassignment.rb b/app/models/nomenclature_change/distribution_reassignment.rb index ba00e4914f..734e02269c 100644 --- a/app/models/nomenclature_change/distribution_reassignment.rb +++ b/app/models/nomenclature_change/distribution_reassignment.rb @@ -19,4 +19,7 @@ # Reassignable is a distribution that is assigned to a new taxon concept class NomenclatureChange::DistributionReassignment < NomenclatureChange::Reassignment + belongs_to :input, class_name: NomenclatureChange::Input, + inverse_of: :distribution_reassignments, + foreign_key: :nomenclature_change_input_id end diff --git a/app/models/nomenclature_change/legislation_reassignment.rb b/app/models/nomenclature_change/legislation_reassignment.rb index 2dde0ca608..4aa71b049b 100644 --- a/app/models/nomenclature_change/legislation_reassignment.rb +++ b/app/models/nomenclature_change/legislation_reassignment.rb @@ -19,4 +19,7 @@ # Reassignable is legislation that is assigned to a new taxon concept class NomenclatureChange::LegislationReassignment < NomenclatureChange::Reassignment + belongs_to :input, class_name: NomenclatureChange::Input, + inverse_of: :legislation_reassignments, + foreign_key: :nomenclature_change_input_id end diff --git a/app/models/nomenclature_change/name_reassignment.rb b/app/models/nomenclature_change/name_reassignment.rb index 14b7ff878e..1eea7e8a51 100644 --- a/app/models/nomenclature_change/name_reassignment.rb +++ b/app/models/nomenclature_change/name_reassignment.rb @@ -19,4 +19,7 @@ # Reassignable is a taxon relationship that is assigned to a new taxon concept class NomenclatureChange::NameReassignment < NomenclatureChange::Reassignment + belongs_to :input, class_name: NomenclatureChange::Input, + inverse_of: :name_reassignments, + foreign_key: :nomenclature_change_input_id end diff --git a/app/models/nomenclature_change/parent_reassignment.rb b/app/models/nomenclature_change/parent_reassignment.rb index 37536f5a1c..5ba0a43180 100644 --- a/app/models/nomenclature_change/parent_reassignment.rb +++ b/app/models/nomenclature_change/parent_reassignment.rb @@ -23,5 +23,8 @@ class NomenclatureChange::ParentReassignment < NomenclatureChange::Reassignment has_one :reassignment_target, :inverse_of => :reassignment, :class_name => NomenclatureChange::ReassignmentTarget, :foreign_key => :nomenclature_change_reassignment_id + belongs_to :input, class_name: NomenclatureChange::Input, + inverse_of: :parent_reassignments, + foreign_key: :nomenclature_change_input_id accepts_nested_attributes_for :reassignment_target, :allow_destroy => true end From 4850b95551445cbaf6e8607c419e389f45a08b6e Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Wed, 14 Oct 2015 11:24:32 +0100 Subject: [PATCH 054/365] removed the ability to create S, H, T taxa via nested attributes in TaxonRelationship --- app/models/taxon_relationship.rb | 8 ++- .../hybrid_relationships_controller_spec.rb | 10 ++- .../synonym_relationships_controller_spec.rb | 10 ++- ...ade_names_relationships_controller_spec.rb | 10 ++- spec/models/hybrid_relationship_spec.rb | 61 ++++++------------- spec/models/synonym_relationship_spec.rb | 58 ++++++------------ spec/models/taxon_concept/hybrids_spec.rb | 39 +++++------- spec/models/taxon_concept/synonyms_spec.rb | 43 +++++-------- spec/models/taxon_concept/trade_names_spec.rb | 43 +++++-------- 9 files changed, 95 insertions(+), 187 deletions(-) diff --git a/app/models/taxon_relationship.rb b/app/models/taxon_relationship.rb index 8cf789ece0..c09b8e6226 100644 --- a/app/models/taxon_relationship.rb +++ b/app/models/taxon_relationship.rb @@ -29,11 +29,13 @@ class TaxonRelationship < ActiveRecord::Base before_destroy :destroy_opposite, :if => Proc.new { self.is_bidirectional? && self.has_opposite? } after_create :create_opposite, :if => Proc.new { self.is_bidirectional? && !self.has_opposite? } after_save :update_higher_taxa_for_hybrid_child - validates :taxon_concept_id, :uniqueness => { :scope => [:taxon_relationship_type_id, :other_taxon_concept_id], :message => 'This relationship already exists, choose another taxa.' } + validates :taxon_concept_id, uniqueness: { + scope: [:taxon_relationship_type_id, :other_taxon_concept_id], + message: 'This relationship already exists, choose another taxon.' + } + validates :other_taxon_concept_id, presence: true validate :intertaxonomic_relationship_uniqueness, :if => "taxon_relationship_type.is_intertaxonomic?" - accepts_nested_attributes_for :other_taxon_concept - def update_higher_taxa_for_hybrid_child if other_taxon_concept && taxon_relationship_type && taxon_relationship_type.name == TaxonRelationshipType::HAS_HYBRID diff --git a/spec/controllers/admin/hybrid_relationships_controller_spec.rb b/spec/controllers/admin/hybrid_relationships_controller_spec.rb index 1ab39f704a..f74a564fed 100644 --- a/spec/controllers/admin/hybrid_relationships_controller_spec.rb +++ b/spec/controllers/admin/hybrid_relationships_controller_spec.rb @@ -29,8 +29,7 @@ xhr :post, :create, :taxon_concept_id => taxon_concept.id, :taxon_relationship => { - :other_taxon_concept_attributes => - build_tc_attributes(:taxon_concept, :name_status => 'H') + other_taxon_concept_id: hybrid.id } response.should render_template("create") end @@ -38,7 +37,7 @@ xhr :post, :create, :taxon_concept_id => taxon_concept.id, :taxon_relationship => { - :other_taxon_concept_attributes => {} + other_taxon_concept_id: nil } response.should render_template("new") end @@ -63,8 +62,7 @@ :taxon_concept_id => taxon_concept.id, :id => hybrid_relationship.id, :taxon_relationship => { - :other_taxon_concept_attributes => - build_tc_attributes(:taxon_concept, :name_status => 'H') + other_taxon_concept_id: hybrid.id } response.should be_success end @@ -73,7 +71,7 @@ :taxon_concept_id => taxon_concept.id, :id => hybrid_relationship.id, :taxon_relationship => { - :other_taxon_concept_attributes => { } + other_taxon_concept_id: nil } JSON.parse(response.body).should include('errors') end diff --git a/spec/controllers/admin/synonym_relationships_controller_spec.rb b/spec/controllers/admin/synonym_relationships_controller_spec.rb index eb0f75e600..8aa3fc614a 100644 --- a/spec/controllers/admin/synonym_relationships_controller_spec.rb +++ b/spec/controllers/admin/synonym_relationships_controller_spec.rb @@ -29,8 +29,7 @@ xhr :post, :create, :taxon_concept_id => taxon_concept.id, :taxon_relationship => { - :other_taxon_concept_attributes => - build_tc_attributes(:taxon_concept, :name_status => 'S') + other_taxon_concept_id: synonym.id } response.should render_template("create") end @@ -38,7 +37,7 @@ xhr :post, :create, :taxon_concept_id => taxon_concept.id, :taxon_relationship => { - :other_taxon_concept_attributes => {} + other_taxon_concept_id: nil } response.should render_template("new") end @@ -63,8 +62,7 @@ :taxon_concept_id => taxon_concept.id, :id => synonym_relationship.id, :taxon_relationship => { - :other_taxon_concept_attributes => - build_tc_attributes(:taxon_concept, :name_status => 'S') + other_taxon_concept_id: synonym.id } response.should be_success end @@ -73,7 +71,7 @@ :taxon_concept_id => taxon_concept.id, :id => synonym_relationship.id, :taxon_relationship => { - :other_taxon_concept_attributes => { } + other_taxon_concept_id: nil } JSON.parse(response.body).should include('errors') end diff --git a/spec/controllers/admin/trade_names_relationships_controller_spec.rb b/spec/controllers/admin/trade_names_relationships_controller_spec.rb index 86d6364d63..6d84d788b3 100644 --- a/spec/controllers/admin/trade_names_relationships_controller_spec.rb +++ b/spec/controllers/admin/trade_names_relationships_controller_spec.rb @@ -29,8 +29,7 @@ xhr :post, :create, :taxon_concept_id => taxon_concept.id, :taxon_relationship => { - :other_taxon_concept_attributes => - build_tc_attributes(:taxon_concept, :name_status => 'T') + other_taxon_concept_id: trade_name.id } response.should render_template("create") end @@ -38,7 +37,7 @@ xhr :post, :create, :taxon_concept_id => taxon_concept.id, :taxon_relationship => { - :other_taxon_concept_attributes => {} + other_taxon_concept_id: nil } response.should render_template("new") end @@ -63,8 +62,7 @@ :taxon_concept_id => taxon_concept.id, :id => trade_name_relationship.id, :taxon_relationship => { - :other_taxon_concept_attributes => - build_tc_attributes(:taxon_concept, :name_status => 'T') + other_taxon_concept_id: trade_name.id } response.should be_success end @@ -73,7 +71,7 @@ :taxon_concept_id => taxon_concept.id, :id => trade_name_relationship.id, :taxon_relationship => { - :other_taxon_concept_attributes => { } + other_taxon_concept_id: nil } JSON.parse(response.body).should include('errors') end diff --git a/spec/models/hybrid_relationship_spec.rb b/spec/models/hybrid_relationship_spec.rb index 793fa3d942..c3059872ec 100644 --- a/spec/models/hybrid_relationship_spec.rb +++ b/spec/models/hybrid_relationship_spec.rb @@ -19,68 +19,45 @@ :taxon_name => create(:taxon_name, :scientific_name => 'lolcatus') ) } - let(:hybrid_attributes){ - build_tc_attributes( - :taxon_concept, - :taxonomy => cites_eu, - :rank => species_rank, - :name_status => 'H', - :author_year => 'Hemulen 2013', - :full_name => 'Lolcatus lolatus x lolcatus' + + let(:hybrid){ + create_cites_eu_species( + name_status: 'H', + author_year: 'Hemulen 2013', + full_name: 'Lolcatus lolatus x lolcatus' ) } - let(:another_hybrid_attributes){ - build_tc_attributes( - :taxon_concept, - :taxonomy => cites_eu, - :rank => species_rank, - :name_status => 'H', - :author_year => 'Hemulen 2013', - :full_name => 'Lolcatus lolcatus x ?' + let(:another_hybrid){ + create_cites_eu_species( + name_status: 'H', + author_year: 'Hemulen 2013', + full_name: 'Lolcatus lolcatus x ?' ) } let(:hybrid_rel){ build( :taxon_relationship, - :taxon_relationship_type => hybrid_relationship_type, - :taxon_concept_id => tc.id, - :other_taxon_concept_id => nil, - :other_taxon_concept_attributes => hybrid_attributes + taxon_relationship_type: hybrid_relationship_type, + taxon_concept_id: tc.id, + other_taxon_concept_id: hybrid.id ) } let(:another_hybrid_rel){ build( :taxon_relationship, - :taxon_relationship_type => hybrid_relationship_type, - :taxon_concept_id => another_tc.id, - :other_taxon_concept_id => nil, - :other_taxon_concept_attributes => hybrid_attributes + taxon_relationship_type: hybrid_relationship_type, + taxon_concept_id: another_tc.id, + other_taxon_concept_id: hybrid.id ) } specify { hybrid_rel.save tc.hybrids.map(&:full_name).should include('Lolcatus lolatus x lolcatus') } - specify{ - lambda do - hybrid_rel.save - end.should change(TaxonConcept, :count).by(1) - } - specify{ - lambda do - hybrid_rel.save - another_hybrid_rel.save - end.should change(TaxonConcept, :count).by(1) - } - specify{ - hybrid_rel.save - another_hybrid_rel.save - another_tc.hybrids.map(&:full_name).should include('Lolcatus lolatus x lolcatus') - } - specify{ + specify{ hybrid_rel.save another_hybrid_rel.save - hybrid_rel.other_taxon_concept_attributes = another_hybrid_attributes + hybrid_rel.other_taxon_concept = another_hybrid hybrid_rel.save tc.hybrids.map(&:full_name).should include('Lolcatus lolcatus x ?') another_tc.hybrids.map(&:full_name).should include('Lolcatus lolatus x lolcatus') diff --git a/spec/models/synonym_relationship_spec.rb b/spec/models/synonym_relationship_spec.rb index cb997b2269..791ed410e1 100644 --- a/spec/models/synonym_relationship_spec.rb +++ b/spec/models/synonym_relationship_spec.rb @@ -19,68 +19,44 @@ :taxon_name => create(:taxon_name, :scientific_name => 'lolcatus') ) } - let(:synonym_attributes){ - build_tc_attributes( - :taxon_concept, - :taxonomy => cites_eu, - :rank => species_rank, - :name_status => 'S', - :author_year => 'Hemulen 2013', - :full_name => 'Lolcatus lolus' + let(:synonym){ + create_cites_eu_species( + name_status: 'S', + author_year: 'Hemulen 2013', + full_name: 'Lolcatus lolus' ) } - let(:another_synonym_attributes){ - build_tc_attributes( - :taxon_concept, - :taxonomy => cites_eu, - :rank => species_rank, - :name_status => 'S', - :author_year => 'Hemulen 2013', - :full_name => 'Lolcatus lolatus' + let(:another_synonym){ + create_cites_eu_species( + name_status: 'S', + author_year: 'Hemulen 2013', + full_name: 'Lolcatus lolatus' ) } let(:synonymy_rel){ build( :taxon_relationship, - :taxon_relationship_type => synonym_relationship_type, - :taxon_concept_id => tc.id, - :other_taxon_concept_id => nil, - :other_taxon_concept_attributes => synonym_attributes + taxon_relationship_type: synonym_relationship_type, + taxon_concept_id: tc.id, + other_taxon_concept_id: synonym.id ) } let(:another_synonymy_rel){ build( :taxon_relationship, - :taxon_relationship_type => synonym_relationship_type, - :taxon_concept_id => another_tc.id, - :other_taxon_concept_id => nil, - :other_taxon_concept_attributes => synonym_attributes + taxon_relationship_type: synonym_relationship_type, + taxon_concept_id: another_tc.id, + other_taxon_concept_id: synonym.id ) } specify { synonymy_rel.save tc.synonyms.map(&:full_name).should include('Lolcatus lolus') } - specify{ - lambda do - synonymy_rel.save - end.should change(TaxonConcept, :count).by(1) - } - specify{ - lambda do - synonymy_rel.save - another_synonymy_rel.save - end.should change(TaxonConcept, :count).by(1) - } - specify{ - synonymy_rel.save - another_synonymy_rel.save - another_tc.synonyms.map(&:full_name).should include('Lolcatus lolus') - } specify{ synonymy_rel.save another_synonymy_rel.save - synonymy_rel.other_taxon_concept_attributes = another_synonym_attributes + synonymy_rel.other_taxon_concept = another_synonym synonymy_rel.save tc.synonyms.map(&:full_name).should include('Lolcatus lolatus') another_tc.synonyms.map(&:full_name).should include('Lolcatus lolus') diff --git a/spec/models/taxon_concept/hybrids_spec.rb b/spec/models/taxon_concept/hybrids_spec.rb index 542645b5f7..b3ba808532 100644 --- a/spec/models/taxon_concept/hybrids_spec.rb +++ b/spec/models/taxon_concept/hybrids_spec.rb @@ -14,35 +14,30 @@ :taxon_name => create(:taxon_name, :scientific_name => 'lolatus') ) } - let!(:another_tc){ + let(:hybrid){ create_cites_eu_species( - :parent_id => parent.id, - :taxon_name => create(:taxon_name, :scientific_name => 'lolcatus') + name_status: 'H', + author_year: 'Taxonomus 2013', + taxon_name: create(:taxon_name, :scientific_name => 'Lolcatus lolcatus x lolatus') ) } - let(:hybrid){ - build_cites_eu_species( - :name_status => 'H', - :author_year => 'Taxonomus 2013', - :hybrid_parent_scientific_name => tc.full_name, - :other_hybrid_parent_scientific_name => another_tc.full_name, - :full_name => 'Lolcatus lolcatus x lolatus' + let!(:hybrid_rel){ + create(:taxon_relationship, + taxon_relationship_type: hybrid_relationship_type, + taxon_concept_id: tc.id, + other_taxon_concept_id: hybrid.id ) } context "when new" do specify { - lambda do - hybrid.save - end.should change(TaxonConcept, :count).by(1) - } - pending { - hybrid.save tc.has_hybrids?.should be_true } specify { - hybrid.save hybrid.is_hybrid?.should be_true } + specify { + hybrid.full_name.should == 'Lolcatus lolcatus x lolatus' + } end context "when duplicate" do let(:duplicate){ @@ -50,9 +45,8 @@ } specify { lambda do - hybrid.save duplicate.save - end.should change(TaxonConcept, :count).by(1) + end.should change(TaxonConcept, :count).by(0) } end context "when duplicate but author name different" do @@ -63,13 +57,8 @@ } specify { lambda do - hybrid.save duplicate.save - end.should change(TaxonConcept, :count).by(2) - } - specify { - hybrid.save - hybrid.full_name.should == 'Lolcatus lolcatus x lolatus' + end.should change(TaxonConcept, :count).by(1) } end end diff --git a/spec/models/taxon_concept/synonyms_spec.rb b/spec/models/taxon_concept/synonyms_spec.rb index 74d0c9f22e..4e9d6f7348 100644 --- a/spec/models/taxon_concept/synonyms_spec.rb +++ b/spec/models/taxon_concept/synonyms_spec.rb @@ -15,32 +15,29 @@ ) } let(:synonym){ - build_cites_eu_species( + create_cites_eu_species( :name_status => 'S', :author_year => 'Taxonomus 2013', - :accepted_scientific_name => tc.full_name, - :full_name => 'Lolcatus lolus' + taxon_name: create(:taxon_name, scientific_name: 'Lolcatus lolus') + ) + } + let!(:synonym_rel){ + create(:taxon_relationship, + taxon_relationship_type: synonym_relationship_type, + taxon_concept_id: tc.id, + other_taxon_concept_id: synonym.id ) } context "when new" do specify { - lambda do - synonym.save - end.should change(TaxonConcept, :count).by(1) - } - pending { - lambda do - synonym.save - end.should change(TaxonRelationship, :count).by(1) - } - pending { - synonym.save tc.has_synonyms?.should be_true } specify { - synonym.save synonym.is_synonym?.should be_true } + specify { + synonym.full_name.should == 'Lolcatus lolus' + } end context "when duplicate" do let(:duplicate){ @@ -48,15 +45,8 @@ } specify { lambda do - synonym.save - duplicate.save - end.should change(TaxonConcept, :count).by(1) - } - pending { - lambda do - synonym.save duplicate.save - end.should change(TaxonRelationship, :count).by(2) + end.should change(TaxonConcept, :count).by(0) } end context "when duplicate but author name different" do @@ -67,13 +57,8 @@ } specify { lambda do - synonym.save duplicate.save - end.should change(TaxonConcept, :count).by(2) - } - specify { - synonym.save - synonym.full_name.should == 'Lolcatus lolus' + end.should change(TaxonConcept, :count).by(1) } end context "when has accepted parent" do diff --git a/spec/models/taxon_concept/trade_names_spec.rb b/spec/models/taxon_concept/trade_names_spec.rb index 366278368e..5be55ade8c 100644 --- a/spec/models/taxon_concept/trade_names_spec.rb +++ b/spec/models/taxon_concept/trade_names_spec.rb @@ -15,32 +15,29 @@ ) } let(:trade_name){ - build_cites_eu_species( + create_cites_eu_species( :name_status => 'T', :author_year => 'Taxonomus 2014', - :accepted_scientific_name => tc.full_name, - :full_name => 'Lolcatus lolus' + taxon_name: create(:taxon_name, scientific_name: 'Lolcatus lolus') + ) + } + let!(:trade_name_rel){ + create(:taxon_relationship, + taxon_relationship_type: trade_name_relationship_type, + taxon_concept_id: tc.id, + other_taxon_concept_id: trade_name.id ) } context "when new" do specify { - lambda do - trade_name.save - end.should change(TaxonConcept, :count).by(1) - } - pending { - lambda do - trade_name.save - end.should change(TaxonRelationship, :count).by(1) - } - pending { - trade_name.save tc.has_trade_names?.should be_true } specify { - trade_name.save trade_name.is_trade_name?.should be_true } + specify { + trade_name.full_name.should == 'Lolcatus lolus' + } end context "when duplicate" do let(:duplicate){ @@ -48,15 +45,8 @@ } specify { lambda do - trade_name.save - duplicate.save - end.should change(TaxonConcept, :count).by(1) - } - pending { - lambda do - trade_name.save duplicate.save - end.should change(TaxonRelationship, :count).by(2) + end.should change(TaxonConcept, :count).by(0) } end context "when duplicate but author name different" do @@ -67,13 +57,8 @@ } specify { lambda do - trade_name.save duplicate.save - end.should change(TaxonConcept, :count).by(2) - } - specify { - trade_name.save - trade_name.full_name.should == 'Lolcatus lolus' + end.should change(TaxonConcept, :count).by(1) } end context "when has accepted parent" do From 532b3ce07173c0d40f7ba9073f923812c2f757e9 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Wed, 14 Oct 2015 11:54:22 +0100 Subject: [PATCH 055/365] specs for taxon_relationships#destroy --- .../taxon_relationships_controller_spec.rb | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/spec/controllers/admin/taxon_relationships_controller_spec.rb b/spec/controllers/admin/taxon_relationships_controller_spec.rb index c3754e0e23..811fe85c7b 100644 --- a/spec/controllers/admin/taxon_relationships_controller_spec.rb +++ b/spec/controllers/admin/taxon_relationships_controller_spec.rb @@ -42,4 +42,65 @@ end end + describe 'DELETE destroy' do + context"when relationship is bidirectional" do + let(:taxon_concept){ + create_cites_eu_species + } + let(:other_taxon_concept){ + create_cms_species + } + let!(:rel){ + create(:taxon_relationship, + taxon_relationship_type: equal_relationship_type, + taxon_concept_id: taxon_concept.id, + other_taxon_concept_id: other_taxon_concept.id + ) + } + context "destroys relationship for taxon concept" do + specify { + lambda do + delete :destroy, taxon_concept_id: taxon_concept.id, id: rel.id + end.should change(TaxonRelationship, :count).by(-2) + } + end + context "destroys relationship for other taxon concept" do + specify { + lambda do + delete :destroy, taxon_concept_id: other_taxon_concept.id, id: rel.id + end.should change(TaxonRelationship, :count).by(-2) + } + end + end + context"when relationship is not bidirectional" do + let(:taxon_concept){ + create_cites_eu_species + } + let(:other_taxon_concept){ + create_cites_eu_species(name_status: 'S') + } + let!(:rel){ + create(:taxon_relationship, + taxon_relationship_type: synonym_relationship_type, + taxon_concept_id: taxon_concept.id, + other_taxon_concept_id: other_taxon_concept.id + ) + } + context "destroys relationship for taxon concept" do + specify { + lambda do + delete :destroy, taxon_concept_id: taxon_concept.id, id: rel.id + end.should change(TaxonRelationship, :count).by(-1) + } + end + context "destroys relationship for other taxon concept" do + specify { + lambda do + delete :destroy, taxon_concept_id: other_taxon_concept.id, id: rel.id + end.should change(TaxonRelationship, :count).by(-1) + } + end + end + end + end From 78b0deb2c4d63baf4251764246e039a8669da862 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Wed, 14 Oct 2015 11:56:02 +0100 Subject: [PATCH 056/365] removed obsolete check --- app/models/taxon_relationship.rb | 34 +------------------------------- 1 file changed, 1 insertion(+), 33 deletions(-) diff --git a/app/models/taxon_relationship.rb b/app/models/taxon_relationship.rb index c09b8e6226..1bdab03261 100644 --- a/app/models/taxon_relationship.rb +++ b/app/models/taxon_relationship.rb @@ -15,7 +15,7 @@ class TaxonRelationship < ActiveRecord::Base track_who_does_it attr_accessible :taxon_concept_id, :other_taxon_concept_id, :taxon_relationship_type_id, - :other_taxon_concept_attributes, :created_by_id, :updated_by_id + :created_by_id, :updated_by_id belongs_to :taxon_relationship_type belongs_to :taxon_concept belongs_to :other_taxon_concept, :class_name => 'TaxonConcept', @@ -25,7 +25,6 @@ class TaxonRelationship < ActiveRecord::Base delegate :is_bidirectional?, :to => :taxon_relationship_type - before_validation :check_other_taxon_concept_exists before_destroy :destroy_opposite, :if => Proc.new { self.is_bidirectional? && self.has_opposite? } after_create :create_opposite, :if => Proc.new { self.is_bidirectional? && !self.has_opposite? } after_save :update_higher_taxa_for_hybrid_child @@ -58,37 +57,6 @@ def has_opposite? private - def check_other_taxon_concept_exists - return true unless other_taxon_concept - required_name_status = case taxon_relationship_type.name - when TaxonRelationshipType::HAS_SYNONYM - 'S' - when TaxonRelationshipType::HAS_TRADE_NAME - 'T' - when TaxonRelationshipType::HAS_HYBRID - 'H' - else - 'A' - end - existing_tc = TaxonConcept. - where(:taxonomy_id => other_taxon_concept.taxonomy_id). - where(:rank_id => other_taxon_concept.rank_id). - where(:full_name => other_taxon_concept.full_name). - where( - if other_taxon_concept.author_year.blank? - 'SQUISH_NULL(author_year) IS NULL' - else - {:author_year => other_taxon_concept.author_year} - end - ). - where(:name_status => required_name_status).first - if existing_tc - self.other_taxon_concept = existing_tc - self.other_taxon_concept_id = existing_tc.id - end - true - end - def create_opposite TaxonRelationship.create( :taxon_concept_id => self.other_taxon_concept_id, From c58ba34e3ef03ce3494319e6190a4082dfaeaae6 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Wed, 14 Oct 2015 12:44:28 +0100 Subject: [PATCH 057/365] removed obsolete before_validation callbacks --- app/models/taxon_concept.rb | 49 +------------------------------------ 1 file changed, 1 insertion(+), 48 deletions(-) diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index 90327e2d83..9d11f16618 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -190,14 +190,7 @@ class TaxonConcept < ActiveRecord::Base :if => lambda { |tc| tc.full_name } before_validation :check_parent_taxon_concept_exists, :if => lambda { |tc| tc.parent_scientific_name } - before_validation :check_hybrid_parent_taxon_concept_exists, - :if => lambda { |tc| tc.is_hybrid? && tc.hybrid_parent_scientific_name } - before_validation :check_other_hybrid_parent_taxon_concept_exists, - :if => lambda { |tc| tc.is_hybrid? && tc.other_hybrid_parent_scientific_name } - before_validation :check_accepted_taxon_concept_exists, - :if => lambda { |tc| tc.is_synonym? && tc.accepted_scientific_name } - before_validation :check_accepted_taxon_concept_for_trade_name_exists, - :if => lambda { |tc| tc.is_trade_name? && tc.accepted_scientific_name } + before_validation :ensure_taxonomic_position translates :nomenclature_note @@ -420,46 +413,6 @@ def check_taxon_name_exists true end - def check_hybrid_parent_taxon_concept_exists - check_associated_taxon_concept_exists(:hybrid_parent_scientific_name) do |tc| - inverse_taxon_relationships.build( - :taxon_concept_id => tc.id, - :taxon_relationship_type_id => TaxonRelationshipType. - find_by_name(TaxonRelationshipType::HAS_HYBRID).id - ) - end - end - - def check_other_hybrid_parent_taxon_concept_exists - check_associated_taxon_concept_exists(:other_hybrid_parent_scientific_name) do |tc| - inverse_taxon_relationships.build( - :taxon_concept_id => tc.id, - :taxon_relationship_type_id => TaxonRelationshipType. - find_by_name(TaxonRelationshipType::HAS_HYBRID).id - ) - end - end - - def check_accepted_taxon_concept_exists - check_associated_taxon_concept_exists(:accepted_scientific_name) do |tc| - inverse_taxon_relationships.build( - :taxon_concept_id => tc.id, - :taxon_relationship_type_id => TaxonRelationshipType. - find_by_name(TaxonRelationshipType::HAS_SYNONYM).id - ) - end - end - - def check_accepted_taxon_concept_for_trade_name_exists - check_associated_taxon_concept_exists(:accepted_scientific_name) do |tc| - inverse_taxon_relationships.build( - :taxon_concept_id => tc.id, - :taxon_relationship_type_id => TaxonRelationshipType. - find_by_name(TaxonRelationshipType::HAS_TRADE_NAME).id - ) - end - end - def check_parent_taxon_concept_exists check_associated_taxon_concept_exists(:parent_scientific_name) do |tc| self.parent_id = tc.id From 01dabdfd6123cdf9a3e50d0bf71ec8260b270391 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Wed, 14 Oct 2015 19:52:49 +0100 Subject: [PATCH 058/365] Initialise select2 in the edit modal window --- app/assets/javascripts/admin/admin_in_place_editor.js.coffee | 3 +++ app/views/admin/taxon_concepts/new.js.erb | 1 + 2 files changed, 4 insertions(+) diff --git a/app/assets/javascripts/admin/admin_in_place_editor.js.coffee b/app/assets/javascripts/admin/admin_in_place_editor.js.coffee index 2880d855a4..f36d84ac36 100644 --- a/app/assets/javascripts/admin/admin_in_place_editor.js.coffee +++ b/app/assets/javascripts/admin/admin_in_place_editor.js.coffee @@ -196,6 +196,9 @@ class AdminInPlaceEditor extends AdminEditor 'option', 'emptytext', 'not current' ) + initSelect2Inputs: () -> + $('.taxon-concept-multiple').select2($.extend(window.defaultTaxonSelect2Options,window.multiTaxonSelect2Options)) + class TaxonConceptsEditor extends AdminEditor init: () -> super diff --git a/app/views/admin/taxon_concepts/new.js.erb b/app/views/admin/taxon_concepts/new.js.erb index 8c3854c60a..e580c3a837 100644 --- a/app/views/admin/taxon_concepts/new.js.erb +++ b/app/views/admin/taxon_concepts/new.js.erb @@ -4,3 +4,4 @@ form.find('.tags').select2(); $('#admin-new-<%= controller_name.singularize %>-form').html(form); $('#new-<%= controller_name.singularize %>').modal('show'); window.adminEditor.initTaxonConceptTypeaheads(); +window.adminEditor.initSelect2Inputs(); From e1fdeb549063a22bce0d19363f1cdd5e5e602464 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Wed, 14 Oct 2015 19:53:17 +0100 Subject: [PATCH 059/365] Select2 to work properly anywhere --- .../javascripts/admin/nomenclature_changes.js.coffee | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/admin/nomenclature_changes.js.coffee b/app/assets/javascripts/admin/nomenclature_changes.js.coffee index 111a0b6658..4a8b5df674 100644 --- a/app/assets/javascripts/admin/nomenclature_changes.js.coffee +++ b/app/assets/javascripts/admin/nomenclature_changes.js.coffee @@ -27,10 +27,10 @@ $(document).ready -> text: tc.full_name + ' ' + tc.name_status results: formatted_taxon_concepts } - multiTaxonSelect2Options = { + window.multiTaxonSelect2Options = { multiple: true, initSelection: (element, callback) => - id = $(element).val().match(/{(.*)}/)[1] + id = $(element).val().match(/({|\[)(.*)(}|\])/)[2] # Reset value attribute to let Select2 work properly when submitting the values again $(element).attr('value','') if (id != null && id != '') @@ -39,12 +39,12 @@ $(document).ready -> name_status = $(element).data('name-status') result = [] for id, i in ids - result.push({id: id, text: names[i] + ' ' + name_status}) + result.push({id: id.trim(), text: names[i] + ' ' + name_status}) callback(result) } $('.taxon-concept').select2(window.defaultTaxonSelect2Options) - $('.taxon-concept-multiple').select2($.extend({}, window.defaultTaxonSelect2Options, multiTaxonSelect2Options)) + $('.taxon-concept-multiple').select2($.extend({}, window.defaultTaxonSelect2Options, window.multiTaxonSelect2Options)) $('.taxon-concept').on('change', (event) -> return false unless event.val $.when($.ajax( '/admin/taxon_concepts/' + event.val + '.json' ) ).then(( data, textStatus, jqXHR ) => From 21d6caa601b3c101ef6d8fe1690aa9b1761895c2 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Wed, 14 Oct 2015 19:54:37 +0100 Subject: [PATCH 060/365] Rebuild relationship when editing accepted names in modal --- .../admin/taxon_concepts_controller.rb | 5 ++- app/models/nomenclature_change/output.rb | 10 ----- app/models/taxon_concept.rb | 44 ++++++++++++++++++- 3 files changed, 46 insertions(+), 13 deletions(-) diff --git a/app/controllers/admin/taxon_concepts_controller.rb b/app/controllers/admin/taxon_concepts_controller.rb index 9a4ca5b665..9ebc6b76a5 100644 --- a/app/controllers/admin/taxon_concepts_controller.rb +++ b/app/controllers/admin/taxon_concepts_controller.rb @@ -33,10 +33,10 @@ def edit def update @taxon_concept = TaxonConcept.find(params[:id]) - rebuild_taxonomy = - @taxon_concept.rebuild_taxonomy?(params) + rebuild_taxonomy = @taxon_concept.rebuild_taxonomy?(params) update! do |success, failure| success.js { + @taxon_concept.rebuild_relationships(params) UpdateTaxonomyWorker.perform_async if rebuild_taxonomy render 'update' } @@ -47,6 +47,7 @@ def update render 'new' } success.html { + @taxon_concept.rebuild_relationships(params) UpdateTaxonomyWorker.perform_async if rebuild_taxonomy redirect_to edit_admin_taxon_concept_url(@taxon_concept), :notice => 'Operation successful' diff --git a/app/models/nomenclature_change/output.rb b/app/models/nomenclature_change/output.rb index 767ff07331..c5c1a76d22 100644 --- a/app/models/nomenclature_change/output.rb +++ b/app/models/nomenclature_change/output.rb @@ -98,16 +98,6 @@ def tag_list=(ary) write_attribute(:tag_list, "{#{ary && ary.join(',')}}") end - def fetch_accepted_taxons_full_name - if accepted_taxon_ids.present? - ActiveRecord::Base.connection.execute( - <<-SQL - SELECT tc.full_name FROM taxon_concepts tc WHERE tc.id = ANY (ARRAY#{accepted_taxon_ids.map(&:to_i)}) - SQL - ).map{ |row| row['full_name']} - end - end - def populate_taxon_concept_fields self.parent_id = taxon_concept.parent_id_changed? ? taxon_concept.parent_id_was : taxon_concept.parent_id self.rank_id = taxon_concept.rank_id_changed? ? taxon_concept.rank_id_was : taxon_concept.rank_id diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index 9d11f16618..bf059a0ab0 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -47,7 +47,7 @@ class TaxonConcept < ActiveRecord::Base :legacy_id, :legacy_type, :full_name, :name_status, :accepted_scientific_name, :parent_scientific_name, :hybrid_parent_scientific_name, :other_hybrid_parent_scientific_name, - :tag_list, :legacy_trade_code, + :tag_list, :legacy_trade_code, :accepted_name_ids, :nomenclature_note_en, :nomenclature_note_es, :nomenclature_note_fr, :created_by_id, :updated_by_id, :dependents_updated_at @@ -218,6 +218,16 @@ class TaxonConcept < ActiveRecord::Base ) } + def self.fetch_taxons_full_name(taxon_ids) + if taxon_ids.present? + ActiveRecord::Base.connection.execute( + <<-SQL + SELECT tc.full_name FROM taxon_concepts tc WHERE tc.id = ANY (ARRAY#{taxon_ids.map(&:to_i)}) + SQL + ).map{ |row| row['full_name']} + end + end + def has_comments? general_comment.try(:note).try(:present?) || nomenclature_comment.try(:note).try(:present?) || @@ -326,6 +336,38 @@ def rebuild_taxonomy?(params) Rank.in_range(Rank::VARIETY, Rank::GENUS).include?(rank.name) end + def rebuild_relationships(params) + all_accepted_name_ids = + params[:taxon_concept][:accepted_name_ids].first.split(',').map(&:to_i) + new_accepted_name_ids = all_accepted_name_ids - accepted_name_ids + removed_accepted_name_ids = accepted_name_ids - all_accepted_name_ids + new_accepted_names = TaxonConcept.where(id: new_accepted_name_ids) + removed_accepted_names = TaxonConcept.where(id: removed_accepted_name_ids) + rel_type = + if name_status == 'S' + TaxonRelationshipType. + find_by_name(TaxonRelationshipType::HAS_SYNONYM) + elsif name_status == 'T' + TaxonRelationshipType. + find_by_name(TaxonRelationshipType::HAS_TRADE_NAME) + end + + removed_accepted_names.each do |accepted_name| + accepted_name.taxon_relationships. + where('other_taxon_concept_id = ? AND rel_type = ?', id, rel_type). + first.destroy + end + + new_accepted_names.each do |accepted_name| + Rails.logger.debug "Creating #{rel_type.name} inverse relationship with #{accepted_name.full_name}" + accepted_name.taxon_relationships << TaxonRelationship.new( + :taxon_relationship_type_id => rel_type.id, + :other_taxon_concept_id => id + ) + accepted_name.save + end + end + private From 8a2d3b21a277e8d471d48570e28bff20dc6b59d9 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Wed, 14 Oct 2015 19:55:19 +0100 Subject: [PATCH 061/365] Fix function call --- .../admin/nomenclature_changes/new_name/accepted_names.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/nomenclature_changes/new_name/accepted_names.html.erb b/app/views/admin/nomenclature_changes/new_name/accepted_names.html.erb index 209a789344..4821be22d5 100644 --- a/app/views/admin/nomenclature_changes/new_name/accepted_names.html.erb +++ b/app/views/admin/nomenclature_changes/new_name/accepted_names.html.erb @@ -10,7 +10,7 @@
<%= ff.text_field :accepted_taxon_ids, { :class => 'taxon-concept-multiple', - :'data-name' => ff.object.fetch_accepted_taxons_full_name.to_s, + :'data-name' => TaxonConcept.fetch_taxons_full_name(ff.object.accepted_taxon_ids).to_s, :'data-name-status' => 'A', :'data-name-status-filter' => ['A'].to_json, :'data-taxonomy-id' => @taxonomy.id, From 1de36ce36f79373920c1974626d466a486ca2c82 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Wed, 14 Oct 2015 19:56:03 +0100 Subject: [PATCH 062/365] Add the correct input form in edit modal --- app/helpers/admin/taxon_concepts_helper.rb | 25 +++++++++++++++++++ app/views/admin/taxon_concepts/_form.html.erb | 9 +------ 2 files changed, 26 insertions(+), 8 deletions(-) create mode 100644 app/helpers/admin/taxon_concepts_helper.rb diff --git a/app/helpers/admin/taxon_concepts_helper.rb b/app/helpers/admin/taxon_concepts_helper.rb new file mode 100644 index 0000000000..448a54f3ad --- /dev/null +++ b/app/helpers/admin/taxon_concepts_helper.rb @@ -0,0 +1,25 @@ +module Admin::TaxonConceptsHelper + + def dynamic_form_fields f, name_status + if ['A', 'N'].include? name_status + content_tag(:div, class: 'control-group') do + concat content_tag(:label, 'Parent') + concat f.text_field(:parent_scientific_name, + class: 'typeahead', + 'data-rank-scope' => 'parent') + end + elsif ['S', 'T'].include? name_status + content_tag(:div, class: 'control-group') do + concat content_tag(:label, 'Accepted names') + concat f.text_field(:accepted_name_ids, { + :class => 'taxon-concept-multiple', + :'data-name' => TaxonConcept.fetch_taxons_full_name(f.object.accepted_name_ids).to_s, + :'data-name-status' => 'A', + :'data-name-status-filter' => ['A'].to_json, + :'data-taxonomy-id' => f.object.taxonomy_id, + :multiple => 'multiple' + }) + end + end + end +end diff --git a/app/views/admin/taxon_concepts/_form.html.erb b/app/views/admin/taxon_concepts/_form.html.erb index 2041778111..aeeeb65666 100644 --- a/app/views/admin/taxon_concepts/_form.html.erb +++ b/app/views/admin/taxon_concepts/_form.html.erb @@ -14,14 +14,7 @@ options_from_collection_for_select(@ranks, :id, :name, @taxon_concept && @taxon_concept.rank_id) %>
- <% if ['A', 'N'].include? @taxon_concept.name_status %> -
- - <%= f.text_field :parent_scientific_name, :class => 'typeahead', - "data-rank-scope" => 'parent' - %> -
- <% end %> + <%= dynamic_form_fields(f, @taxon_concept.name_status) %>
<%= f.text_field :full_name %> From 47b2940289232071d7fab966eb231b1b37991814 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Wed, 14 Oct 2015 23:48:52 +0100 Subject: [PATCH 063/365] Code improvement --- .../admin/taxon_concepts_controller.rb | 4 ++-- app/models/taxon_concept.rb | 23 ++++++++++++------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/app/controllers/admin/taxon_concepts_controller.rb b/app/controllers/admin/taxon_concepts_controller.rb index 9ebc6b76a5..0e15d45685 100644 --- a/app/controllers/admin/taxon_concepts_controller.rb +++ b/app/controllers/admin/taxon_concepts_controller.rb @@ -36,7 +36,7 @@ def update rebuild_taxonomy = @taxon_concept.rebuild_taxonomy?(params) update! do |success, failure| success.js { - @taxon_concept.rebuild_relationships(params) + @taxon_concept.rebuild_relationships(params[:taxon_concept]) UpdateTaxonomyWorker.perform_async if rebuild_taxonomy render 'update' } @@ -47,7 +47,7 @@ def update render 'new' } success.html { - @taxon_concept.rebuild_relationships(params) + @taxon_concept.rebuild_relationships(params[:taxon_concept]) UpdateTaxonomyWorker.perform_async if rebuild_taxonomy redirect_to edit_admin_taxon_concept_url(@taxon_concept), :notice => 'Operation successful' diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index bf059a0ab0..3f4a0e2063 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -337,12 +337,7 @@ def rebuild_taxonomy?(params) end def rebuild_relationships(params) - all_accepted_name_ids = - params[:taxon_concept][:accepted_name_ids].first.split(',').map(&:to_i) - new_accepted_name_ids = all_accepted_name_ids - accepted_name_ids - removed_accepted_name_ids = accepted_name_ids - all_accepted_name_ids - new_accepted_names = TaxonConcept.where(id: new_accepted_name_ids) - removed_accepted_names = TaxonConcept.where(id: removed_accepted_name_ids) + new_accepted_taxa, removed_accepted_taxa = init_accepted_taxa(params) rel_type = if name_status == 'S' TaxonRelationshipType. @@ -352,13 +347,13 @@ def rebuild_relationships(params) find_by_name(TaxonRelationshipType::HAS_TRADE_NAME) end - removed_accepted_names.each do |accepted_name| + removed_accepted_taxa.each do |accepted_name| accepted_name.taxon_relationships. where('other_taxon_concept_id = ? AND rel_type = ?', id, rel_type). first.destroy end - new_accepted_names.each do |accepted_name| + new_accepted_taxa.each do |accepted_name| Rails.logger.debug "Creating #{rel_type.name} inverse relationship with #{accepted_name.full_name}" accepted_name.taxon_relationships << TaxonRelationship.new( :taxon_relationship_type_id => rel_type.id, @@ -371,6 +366,18 @@ def rebuild_relationships(params) private + def init_accepted_taxa(params) + all_accepted_name_ids = + params ? params[:accepted_name_ids].first.split(',').map(&:to_i) : [] + new_accepted_name_ids = all_accepted_name_ids - accepted_name_ids + removed_accepted_name_ids = accepted_name_ids - all_accepted_name_ids + + [ + TaxonConcept.where(id: new_accepted_name_ids), + TaxonConcept.where(id: removed_accepted_name_ids) + ] + end + def dependent_objects_map { 'children' => children, From 71eef5e76cdc025e5692822ef0f4d6cde9044297 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Wed, 14 Oct 2015 13:59:32 +0100 Subject: [PATCH 064/365] fixes some of the class loading issues by prviding class_name as string rather than as constant --- app/models/distribution.rb | 4 ++ app/models/nomenclature_change/input.rb | 50 +++++++++++-------- .../reassignment_helpers.rb | 10 ++-- .../reassignment_target.rb | 5 +- app/models/taxon_concept.rb | 5 +- app/models/taxon_relationship.rb | 6 ++- 6 files changed, 51 insertions(+), 29 deletions(-) diff --git a/app/models/distribution.rb b/app/models/distribution.rb index 9c7d922e52..f26d3554ed 100644 --- a/app/models/distribution.rb +++ b/app/models/distribution.rb @@ -22,6 +22,10 @@ class Distribution < ActiveRecord::Base belongs_to :taxon_concept has_many :distribution_references, :dependent => :destroy has_many :references, :through => :distribution_references + has_many :distribution_reassignments, + class_name: 'NomenclatureChange::DistributionReassignment', + as: :reassignable, + dependent: :destroy accepts_nested_attributes_for :references, :allow_destroy => true validates :taxon_concept_id, :uniqueness => { :scope => :geo_entity_id, :message => 'already has this distribution' } diff --git a/app/models/nomenclature_change/input.rb b/app/models/nomenclature_change/input.rb index eceefb3f34..8a2be92f4e 100644 --- a/app/models/nomenclature_change/input.rb +++ b/app/models/nomenclature_change/input.rb @@ -27,26 +27,36 @@ class NomenclatureChange::Input < ActiveRecord::Base :legislation_reassignments_attributes belongs_to :nomenclature_change belongs_to :taxon_concept - has_many :reassignments, :inverse_of => :input, - :class_name => NomenclatureChange::Reassignment, - :foreign_key => :nomenclature_change_input_id, :dependent => :destroy, - :autosave => true - has_many :parent_reassignments, :inverse_of => :input, - :class_name => NomenclatureChange::ParentReassignment, - :foreign_key => :nomenclature_change_input_id, :dependent => :destroy, - :autosave => true - has_many :name_reassignments, :inverse_of => :input, - :class_name => NomenclatureChange::NameReassignment, - :foreign_key => :nomenclature_change_input_id, :dependent => :destroy, - :autosave => true - has_many :distribution_reassignments, :inverse_of => :input, - :class_name => NomenclatureChange::DistributionReassignment, - :foreign_key => :nomenclature_change_input_id, :dependent => :destroy, - :autosave => true - has_many :legislation_reassignments, :inverse_of => :input, - :class_name => NomenclatureChange::LegislationReassignment, - :foreign_key => :nomenclature_change_input_id, :dependent => :destroy, - :autosave => true + has_many :reassignments, + inverse_of: :input, + class_name: 'NomenclatureChange::Reassignment', + foreign_key: :nomenclature_change_input_id, + dependent: :destroy, + autosave: true + has_many :parent_reassignments, + inverse_of: :input, + class_name: 'NomenclatureChange::ParentReassignment', + foreign_key: :nomenclature_change_input_id, + dependent: :destroy, + autosave: true + has_many :name_reassignments, + inverse_of: :input, + class_name: 'NomenclatureChange::NameReassignment', + foreign_key: :nomenclature_change_input_id, + dependent: :destroy, + autosave: true + has_many :distribution_reassignments, + inverse_of: :input, + class_name: 'NomenclatureChange::DistributionReassignment', + foreign_key: :nomenclature_change_input_id, + dependent: :destroy, + autosave: true + has_many :legislation_reassignments, + inverse_of: :input, + class_name: 'NomenclatureChange::LegislationReassignment', + foreign_key: :nomenclature_change_input_id, + dependent: :destroy, + autosave: true validates :nomenclature_change, :presence => true validates :taxon_concept, :presence => true accepts_nested_attributes_for :parent_reassignments, :allow_destroy => true diff --git a/app/models/nomenclature_change/reassignment_helpers.rb b/app/models/nomenclature_change/reassignment_helpers.rb index 80c569df44..4d59ceda80 100644 --- a/app/models/nomenclature_change/reassignment_helpers.rb +++ b/app/models/nomenclature_change/reassignment_helpers.rb @@ -7,10 +7,12 @@ def self.included(base) :nomenclature_change_input_id, :nomenclature_change_output_id, :note_en, :note_es, :note_fr, :internal_note, :output_ids belongs_to :reassignable, :polymorphic => true - has_many :reassignment_targets, :inverse_of => :reassignment, - :class_name => NomenclatureChange::ReassignmentTarget, - :foreign_key => :nomenclature_change_reassignment_id, - :dependent => :destroy, :autosave => true + has_many :reassignment_targets, + inverse_of: :reassignment, + class_name: 'NomenclatureChange::ReassignmentTarget', + foreign_key: :nomenclature_change_reassignment_id, + dependent: :destroy, + autosave: true has_many :outputs, :through => :reassignment_targets validates :reassignable_type, :presence => true diff --git a/app/models/nomenclature_change/reassignment_target.rb b/app/models/nomenclature_change/reassignment_target.rb index 71d3ef8965..8afc362e18 100644 --- a/app/models/nomenclature_change/reassignment_target.rb +++ b/app/models/nomenclature_change/reassignment_target.rb @@ -17,8 +17,9 @@ class NomenclatureChange::ReassignmentTarget < ActiveRecord::Base :nomenclature_change_reassignment_id, :note belongs_to :output, :class_name => NomenclatureChange::Output, :foreign_key => :nomenclature_change_output_id - belongs_to :reassignment, :class_name => NomenclatureChange::Reassignment, - :foreign_key => :nomenclature_change_reassignment_id + belongs_to :reassignment, + class_name: 'NomenclatureChange::Reassignment', + foreign_key: :nomenclature_change_reassignment_id validates :reassignment, :presence => true validates :output, :presence => true diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index 3f4a0e2063..5986525b0b 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -158,7 +158,10 @@ class TaxonConcept < ActiveRecord::Base conditions: {comment_type: 'Nomenclature'} has_one :distribution_comment, class_name: 'Comment', as: 'commentable', conditions: {comment_type: 'Distribution'} - has_many :nomenclature_change_reassignments, :as => :reassignable + has_many :parent_reassignments, + class_name: 'NomenclatureChange::ParentReassignment', + as: :reassignable, + dependent: :destroy has_many :nomenclature_change_inputs, class_name: 'NomenclatureChange::Input' has_many :nomenclature_change_outputs, class_name: 'NomenclatureChange::Output' has_many :nomenclature_change_outputs_as_new, class_name: 'NomenclatureChange::Output', diff --git a/app/models/taxon_relationship.rb b/app/models/taxon_relationship.rb index 1bdab03261..db744ed470 100644 --- a/app/models/taxon_relationship.rb +++ b/app/models/taxon_relationship.rb @@ -20,8 +20,10 @@ class TaxonRelationship < ActiveRecord::Base belongs_to :taxon_concept belongs_to :other_taxon_concept, :class_name => 'TaxonConcept', :foreign_key => :other_taxon_concept_id - has_many :name_reassignments, :class_name => 'NomenclatureChange::NameReassignment', - as: :reassignable, dependent: :destroy + has_many :name_reassignments, + class_name: 'NomenclatureChange::NameReassignment', + as: :reassignable, + dependent: :destroy delegate :is_bidirectional?, :to => :taxon_relationship_type From 9b11ff3507ea7b616b0df6c4c3a20f4e207b0145 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 15 Oct 2015 08:09:36 +0100 Subject: [PATCH 065/365] fixed redirect after deleting a hybrid relationship --- app/controllers/admin/hybrid_relationships_controller.rb | 8 ++++++++ .../admin/hybrid_relationships_controller_spec.rb | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/controllers/admin/hybrid_relationships_controller.rb b/app/controllers/admin/hybrid_relationships_controller.rb index 32b62d3d0e..0f269f47c6 100644 --- a/app/controllers/admin/hybrid_relationships_controller.rb +++ b/app/controllers/admin/hybrid_relationships_controller.rb @@ -48,6 +48,14 @@ def update end end + def destroy + destroy! do |success| + success.html { + redirect_to admin_taxon_concept_names_path(@taxon_concept) + } + end + end + protected def load_hybrid_relationship_type diff --git a/spec/controllers/admin/hybrid_relationships_controller_spec.rb b/spec/controllers/admin/hybrid_relationships_controller_spec.rb index f74a564fed..be3af920a0 100644 --- a/spec/controllers/admin/hybrid_relationships_controller_spec.rb +++ b/spec/controllers/admin/hybrid_relationships_controller_spec.rb @@ -83,7 +83,7 @@ :taxon_concept_id => taxon_concept.id, :id => hybrid_relationship.id response.should redirect_to( - edit_admin_taxon_concept_url(hybrid_relationship.taxon_concept) + admin_taxon_concept_names_url(hybrid_relationship.taxon_concept) ) end end From f6bcb55857a1275cd92f5c834952bbee03933eaa Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 15 Oct 2015 08:14:24 +0100 Subject: [PATCH 066/365] fixed relationship update specs --- .../admin/hybrid_relationships_controller_spec.rb | 8 ++++---- .../admin/synonym_relationships_controller_spec.rb | 8 ++++---- .../admin/trade_names_relationships_controller_spec.rb | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/spec/controllers/admin/hybrid_relationships_controller_spec.rb b/spec/controllers/admin/hybrid_relationships_controller_spec.rb index be3af920a0..175a37e38e 100644 --- a/spec/controllers/admin/hybrid_relationships_controller_spec.rb +++ b/spec/controllers/admin/hybrid_relationships_controller_spec.rb @@ -58,22 +58,22 @@ describe "XHR PUT update" do it "responds with 200 when successful" do - xhr :put, :update, :format => 'json', + xhr :put, :update, :format => 'js', :taxon_concept_id => taxon_concept.id, :id => hybrid_relationship.id, :taxon_relationship => { other_taxon_concept_id: hybrid.id } - response.should be_success + response.should render_template("create") end it "responds with json when not successful" do - xhr :put, :update, :format => 'json', + xhr :put, :update, :format => 'js', :taxon_concept_id => taxon_concept.id, :id => hybrid_relationship.id, :taxon_relationship => { other_taxon_concept_id: nil } - JSON.parse(response.body).should include('errors') + response.should render_template('new') end end diff --git a/spec/controllers/admin/synonym_relationships_controller_spec.rb b/spec/controllers/admin/synonym_relationships_controller_spec.rb index 8aa3fc614a..f00203f585 100644 --- a/spec/controllers/admin/synonym_relationships_controller_spec.rb +++ b/spec/controllers/admin/synonym_relationships_controller_spec.rb @@ -58,22 +58,22 @@ describe "XHR PUT update" do it "responds with 200 when successful" do - xhr :put, :update, :format => 'json', + xhr :put, :update, :format => 'js', :taxon_concept_id => taxon_concept.id, :id => synonym_relationship.id, :taxon_relationship => { other_taxon_concept_id: synonym.id } - response.should be_success + response.should render_template('create') end it "responds with json when not successful" do - xhr :put, :update, :format => 'json', + xhr :put, :update, :format => 'js', :taxon_concept_id => taxon_concept.id, :id => synonym_relationship.id, :taxon_relationship => { other_taxon_concept_id: nil } - JSON.parse(response.body).should include('errors') + response.should render_template('new') end end diff --git a/spec/controllers/admin/trade_names_relationships_controller_spec.rb b/spec/controllers/admin/trade_names_relationships_controller_spec.rb index 6d84d788b3..992960a332 100644 --- a/spec/controllers/admin/trade_names_relationships_controller_spec.rb +++ b/spec/controllers/admin/trade_names_relationships_controller_spec.rb @@ -58,22 +58,22 @@ describe "XHR PUT update" do it "responds with 200 when successful" do - xhr :put, :update, :format => 'json', + xhr :put, :update, :format => 'js', :taxon_concept_id => taxon_concept.id, :id => trade_name_relationship.id, :taxon_relationship => { other_taxon_concept_id: trade_name.id } - response.should be_success + response.should render_template("create") end it "responds with json when not successful" do - xhr :put, :update, :format => 'json', + xhr :put, :update, :format => 'js', :taxon_concept_id => taxon_concept.id, :id => trade_name_relationship.id, :taxon_relationship => { other_taxon_concept_id: nil } - JSON.parse(response.body).should include('errors') + response.should render_template('new') end end From 1c480477d959236324abfa92e5a923d5276ab0dc Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 15 Oct 2015 08:44:28 +0100 Subject: [PATCH 067/365] spec for updating taxonomy --- spec/models/taxon_concept/validation_spec.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/spec/models/taxon_concept/validation_spec.rb b/spec/models/taxon_concept/validation_spec.rb index 379fd44223..d83c305b35 100644 --- a/spec/models/taxon_concept/validation_spec.rb +++ b/spec/models/taxon_concept/validation_spec.rb @@ -125,4 +125,9 @@ specify { tc2.should have(1).error_on(:full_name) } end end + context "update" do + let(:tc){ create_cites_eu_species } + let!(:tc_child) { create_cites_eu_subspecies(parent_id: tc.id) } + specify { tc.taxonomy = cms; tc.should have(1).error_on(:taxonomy_id) } + end end \ No newline at end of file From 9a2a9296f185dec957f5cba82d40d7b3b9d574b3 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 15 Oct 2015 09:22:12 +0100 Subject: [PATCH 068/365] removed obsolete accessors --- app/models/taxon_concept.rb | 5 +---- spec/factories.rb | 3 --- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index 5986525b0b..a5b61d58d0 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -45,15 +45,12 @@ class TaxonConcept < ActiveRecord::Base attr_accessible :parent_id, :taxonomy_id, :rank_id, :parent_id, :author_year, :taxon_name_id, :taxonomic_position, :legacy_id, :legacy_type, :full_name, :name_status, - :accepted_scientific_name, :parent_scientific_name, - :hybrid_parent_scientific_name, :other_hybrid_parent_scientific_name, + :parent_scientific_name, :tag_list, :legacy_trade_code, :accepted_name_ids, :nomenclature_note_en, :nomenclature_note_es, :nomenclature_note_fr, :created_by_id, :updated_by_id, :dependents_updated_at attr_writer :parent_scientific_name - attr_accessor :accepted_scientific_name, :hybrid_parent_scientific_name, - :other_hybrid_parent_scientific_name acts_as_taggable diff --git a/spec/factories.rb b/spec/factories.rb index 6ab9b63dab..df4fcd0407 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -73,9 +73,6 @@ data {} listing {} parent_scientific_name '' - accepted_scientific_name '' - hybrid_parent_scientific_name '' - other_hybrid_parent_scientific_name '' end factory :cites_suspension do From a9c06cb674927c528ff5c3ca5e9a6c186cc1e2ae Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 15 Oct 2015 09:22:24 +0100 Subject: [PATCH 069/365] added missing specs --- spec/models/taxon_concept/hybrids_spec.rb | 3 +++ spec/models/taxon_concept/synonyms_spec.rb | 3 +++ spec/models/taxon_concept/trade_names_spec.rb | 3 +++ 3 files changed, 9 insertions(+) diff --git a/spec/models/taxon_concept/hybrids_spec.rb b/spec/models/taxon_concept/hybrids_spec.rb index b3ba808532..035ea1b6f5 100644 --- a/spec/models/taxon_concept/hybrids_spec.rb +++ b/spec/models/taxon_concept/hybrids_spec.rb @@ -35,6 +35,9 @@ specify { hybrid.is_hybrid?.should be_true } + specify{ + hybrid.has_hybrid_parents?.should be_true + } specify { hybrid.full_name.should == 'Lolcatus lolcatus x lolatus' } diff --git a/spec/models/taxon_concept/synonyms_spec.rb b/spec/models/taxon_concept/synonyms_spec.rb index 4e9d6f7348..9555719ce7 100644 --- a/spec/models/taxon_concept/synonyms_spec.rb +++ b/spec/models/taxon_concept/synonyms_spec.rb @@ -35,6 +35,9 @@ specify { synonym.is_synonym?.should be_true } + specify{ + synonym.has_accepted_names?.should be_true + } specify { synonym.full_name.should == 'Lolcatus lolus' } diff --git a/spec/models/taxon_concept/trade_names_spec.rb b/spec/models/taxon_concept/trade_names_spec.rb index 5be55ade8c..374740aba2 100644 --- a/spec/models/taxon_concept/trade_names_spec.rb +++ b/spec/models/taxon_concept/trade_names_spec.rb @@ -35,6 +35,9 @@ specify { trade_name.is_trade_name?.should be_true } + specify{ + trade_name.has_accepted_names_for_trade_name?.should be_true + } specify { trade_name.full_name.should == 'Lolcatus lolus' } From e6f2c4330677d0b723250c52480c2f704b5b75c7 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Thu, 15 Oct 2015 11:47:30 +0100 Subject: [PATCH 070/365] Fix bug related to wrong order between taxon id and name --- .../javascripts/admin/nomenclature_changes.js.coffee | 6 ++++-- app/models/taxon_concept.rb | 7 ++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/admin/nomenclature_changes.js.coffee b/app/assets/javascripts/admin/nomenclature_changes.js.coffee index 4a8b5df674..e547e53b44 100644 --- a/app/assets/javascripts/admin/nomenclature_changes.js.coffee +++ b/app/assets/javascripts/admin/nomenclature_changes.js.coffee @@ -34,12 +34,14 @@ $(document).ready -> # Reset value attribute to let Select2 work properly when submitting the values again $(element).attr('value','') if (id != null && id != '') - ids = id.split(',') + ids = id.split(',').map( (id) -> + parseInt(id.trim()) + ).sort( (a, b) -> a - b) names = $(element).data('name') name_status = $(element).data('name-status') result = [] for id, i in ids - result.push({id: id.trim(), text: names[i] + ' ' + name_status}) + result.push({id: id, text: names[i] + ' ' + name_status}) callback(result) } diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index a5b61d58d0..865b817fb8 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -222,7 +222,10 @@ def self.fetch_taxons_full_name(taxon_ids) if taxon_ids.present? ActiveRecord::Base.connection.execute( <<-SQL - SELECT tc.full_name FROM taxon_concepts tc WHERE tc.id = ANY (ARRAY#{taxon_ids.map(&:to_i)}) + SELECT tc.full_name + FROM taxon_concepts tc + WHERE tc.id = ANY (ARRAY#{taxon_ids.map(&:to_i)}) + ORDER BY tc.id SQL ).map{ |row| row['full_name']} end @@ -336,6 +339,8 @@ def rebuild_taxonomy?(params) Rank.in_range(Rank::VARIETY, Rank::GENUS).include?(rank.name) end + #TODO + # save changes button won't work once already submitted def rebuild_relationships(params) new_accepted_taxa, removed_accepted_taxa = init_accepted_taxa(params) rel_type = From a7b40b665dbdd337c6609d8f898457cbc127ba75 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Thu, 15 Oct 2015 13:53:52 +0100 Subject: [PATCH 071/365] Fix accepted names for trade names --- app/helpers/admin/taxon_concepts_helper.rb | 6 ++++-- app/models/taxon_concept.rb | 12 ++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/app/helpers/admin/taxon_concepts_helper.rb b/app/helpers/admin/taxon_concepts_helper.rb index 448a54f3ad..59b18dbfb8 100644 --- a/app/helpers/admin/taxon_concepts_helper.rb +++ b/app/helpers/admin/taxon_concepts_helper.rb @@ -9,11 +9,13 @@ def dynamic_form_fields f, name_status 'data-rank-scope' => 'parent') end elsif ['S', 'T'].include? name_status + name_ids = + name_status == 'S' ? :accepted_name_ids : :accepted_names_for_trade_name_ids content_tag(:div, class: 'control-group') do concat content_tag(:label, 'Accepted names') - concat f.text_field(:accepted_name_ids, { + concat f.text_field(name_ids, { :class => 'taxon-concept-multiple', - :'data-name' => TaxonConcept.fetch_taxons_full_name(f.object.accepted_name_ids).to_s, + :'data-name' => TaxonConcept.fetch_taxons_full_name(f.object.send(name_ids)).to_s, :'data-name-status' => 'A', :'data-name-status-filter' => ['A'].to_json, :'data-taxonomy-id' => f.object.taxonomy_id, diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index 865b817fb8..1357c1302a 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -46,7 +46,8 @@ class TaxonConcept < ActiveRecord::Base :parent_id, :author_year, :taxon_name_id, :taxonomic_position, :legacy_id, :legacy_type, :full_name, :name_status, :parent_scientific_name, - :tag_list, :legacy_trade_code, :accepted_name_ids, + :tag_list, :legacy_trade_code, + :accepted_name_ids, :accepted_names_for_trade_name_ids, :nomenclature_note_en, :nomenclature_note_es, :nomenclature_note_fr, :created_by_id, :updated_by_id, :dependents_updated_at @@ -372,8 +373,15 @@ def rebuild_relationships(params) private def init_accepted_taxa(params) + name_ids = + case name_status + when 'S' then :accepted_name_ids + when 'T' then :accepted_names_for_trade_name_ids + else return [] + end + all_accepted_name_ids = - params ? params[:accepted_name_ids].first.split(',').map(&:to_i) : [] + params ? params[name_ids].first.split(',').map(&:to_i) : [] new_accepted_name_ids = all_accepted_name_ids - accepted_name_ids removed_accepted_name_ids = accepted_name_ids - all_accepted_name_ids From de9de1d2828698c2d45524a3babd266da51a509e Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Thu, 15 Oct 2015 14:01:13 +0100 Subject: [PATCH 072/365] Bug fix to return array of empty arrays --- app/models/taxon_concept.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index 1357c1302a..01e29e0898 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -377,7 +377,7 @@ def init_accepted_taxa(params) case name_status when 'S' then :accepted_name_ids when 'T' then :accepted_names_for_trade_name_ids - else return [] + else return [[],[]] end all_accepted_name_ids = From 0fec322ee3e53128b84fc7f236a5c6efb4a8414e Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Fri, 16 Oct 2015 16:03:06 +0100 Subject: [PATCH 073/365] Initialise taxon concept single selection with select2 --- app/assets/javascripts/admin/admin_in_place_editor.js.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/admin/admin_in_place_editor.js.coffee b/app/assets/javascripts/admin/admin_in_place_editor.js.coffee index f36d84ac36..f42baad525 100644 --- a/app/assets/javascripts/admin/admin_in_place_editor.js.coffee +++ b/app/assets/javascripts/admin/admin_in_place_editor.js.coffee @@ -197,7 +197,8 @@ class AdminInPlaceEditor extends AdminEditor ) initSelect2Inputs: () -> - $('.taxon-concept-multiple').select2($.extend(window.defaultTaxonSelect2Options,window.multiTaxonSelect2Options)) + $('.taxon-concept').select2(window.defaultTaxonSelect2Options) + $('.taxon-concept-multiple').select2($.extend({}, window.defaultTaxonSelect2Options,window.multiTaxonSelect2Options)) class TaxonConceptsEditor extends AdminEditor init: () -> From 5ab1491a60882ef8d770d08aabccf2d5876c944e Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Fri, 16 Oct 2015 16:04:02 +0100 Subject: [PATCH 074/365] Dynamically generate tc edit form --- .../admin/taxon_concepts_controller.rb | 20 +++++++++++++++++-- app/views/admin/taxon_concepts/_form.html.erb | 2 +- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/app/controllers/admin/taxon_concepts_controller.rb b/app/controllers/admin/taxon_concepts_controller.rb index 0e15d45685..d604c75ada 100644 --- a/app/controllers/admin/taxon_concepts_controller.rb +++ b/app/controllers/admin/taxon_concepts_controller.rb @@ -2,6 +2,7 @@ class Admin::TaxonConceptsController < Admin::StandardAuthorizationController respond_to :json layout :determine_layout before_filter :sanitize_search_params, :only => [:index, :autocomplete] + before_filter :sanitize_update_params, :only => [:update] before_filter :load_tags, :only => [:index, :edit, :create] def index @@ -36,7 +37,7 @@ def update rebuild_taxonomy = @taxon_concept.rebuild_taxonomy?(params) update! do |success, failure| success.js { - @taxon_concept.rebuild_relationships(params[:taxon_concept]) + @taxon_concept.rebuild_relationships(@taxa_ids) UpdateTaxonomyWorker.perform_async if rebuild_taxonomy render 'update' } @@ -47,7 +48,7 @@ def update render 'new' } success.html { - @taxon_concept.rebuild_relationships(params[:taxon_concept]) + @taxon_concept.rebuild_relationships(@taxa_ids) UpdateTaxonomyWorker.perform_async if rebuild_taxonomy redirect_to edit_admin_taxon_concept_url(@taxon_concept), :notice => 'Operation successful' @@ -90,6 +91,21 @@ def sanitize_search_params }) end + def sanitize_update_params + name_status = params[:taxon_concept][:name_status] + if params[:taxon_concept] + name_ids = + case name_status + when 'S' then :accepted_name_ids + when 'T' then :accepted_names_for_trade_name_ids + when 'H' then :hybrid_parent_ids + else return [] + end + @taxa_ids = + params[:taxon_concept].delete(name_ids).first.split(',').map(&:to_i) + end + end + def load_tags @tags = PresetTag.where(:model => PresetTag::TYPES[:TaxonConcept]) end diff --git a/app/views/admin/taxon_concepts/_form.html.erb b/app/views/admin/taxon_concepts/_form.html.erb index aeeeb65666..abcaac9ffc 100644 --- a/app/views/admin/taxon_concepts/_form.html.erb +++ b/app/views/admin/taxon_concepts/_form.html.erb @@ -14,7 +14,7 @@ options_from_collection_for_select(@ranks, :id, :name, @taxon_concept && @taxon_concept.rank_id) %>
- <%= dynamic_form_fields(f, @taxon_concept.name_status) %> + <%= name_status_related_fields(f, @taxon_concept.name_status) %>
<%= f.text_field :full_name %> From 1c07fa22ef06de5f804109fcc26afe86193e1fce Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Fri, 16 Oct 2015 16:05:02 +0100 Subject: [PATCH 075/365] Generate tc form, forgotten file --- app/helpers/admin/taxon_concepts_helper.rb | 80 ++++++++++++++++------ 1 file changed, 58 insertions(+), 22 deletions(-) diff --git a/app/helpers/admin/taxon_concepts_helper.rb b/app/helpers/admin/taxon_concepts_helper.rb index 59b18dbfb8..996667fb8a 100644 --- a/app/helpers/admin/taxon_concepts_helper.rb +++ b/app/helpers/admin/taxon_concepts_helper.rb @@ -1,27 +1,63 @@ module Admin::TaxonConceptsHelper - def dynamic_form_fields f, name_status - if ['A', 'N'].include? name_status - content_tag(:div, class: 'control-group') do - concat content_tag(:label, 'Parent') - concat f.text_field(:parent_scientific_name, - class: 'typeahead', - 'data-rank-scope' => 'parent') - end - elsif ['S', 'T'].include? name_status - name_ids = - name_status == 'S' ? :accepted_name_ids : :accepted_names_for_trade_name_ids - content_tag(:div, class: 'control-group') do - concat content_tag(:label, 'Accepted names') - concat f.text_field(name_ids, { - :class => 'taxon-concept-multiple', - :'data-name' => TaxonConcept.fetch_taxons_full_name(f.object.send(name_ids)).to_s, - :'data-name-status' => 'A', - :'data-name-status-filter' => ['A'].to_json, - :'data-taxonomy-id' => f.object.taxonomy_id, - :multiple => 'multiple' - }) - end + DEFAULT_OPTS = { + klass: 'taxon-concept-multiple', + multiple: 'multiple', + data_name_status: 'A' + } + def fields_opts f, name_status + case name_status + when 'A', 'N' + DEFAULT_OPTS.merge({ + label: 'Parent', + klass: 'taxon-concept parent-taxon', + field_name: :parent_id, + data_name: f.object.parent.try(:full_name), + data_name_status: f.object.parent.try(:name_status), + multiple: '' + }) + when 'S' + DEFAULT_OPTS.merge({ + label: "Accepted names", + field_name: :accepted_name_ids, + data_name: TaxonConcept.fetch_taxons_full_name( + f.object.accepted_name_ids + ).to_s, + }) + when 'T' + DEFAULT_OPTS.merge({ + label: "Accepted names", + field_name: :accepted_names_for_trade_name_ids, + data_name: TaxonConcept.fetch_taxons_full_name( + f.object.accepted_names_for_trade_name_ids + ).to_s, + }) + when 'H' + DEFAULT_OPTS.merge({ + label: 'Parents', + field_name: :hybrid_parent_ids, + data_name: TaxonConcept.fetch_taxons_full_name( + f.object.hybrid_parent_ids + ).to_s, + }) + end + end + + def name_status_related_fields f, name_status + generate_input_form(f, fields_opts(f, name_status)) + end + + def generate_input_form(f, opts={}) + content_tag(:div, class: 'control-group') do + concat content_tag(:label, opts[:label]) + concat f.text_field(opts[:field_name], { + :class => opts[:klass], + :'data-name' => opts[:data_name], + :'data-name-status' => 'A', + :'data-name-status-filter' => ['A'].to_json, + :'data-taxonomy-id' => f.object.taxonomy_id, + opts[:multiple] => opts[:multiple] + }) end end end From c2dd7c1fcf27faf36231b164b8bd3be8f1624fae Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Fri, 16 Oct 2015 17:19:36 +0100 Subject: [PATCH 076/365] code improvement --- .../admin/taxon_concepts_controller.rb | 10 +-- app/models/taxon_concept.rb | 65 +++++++++---------- 2 files changed, 38 insertions(+), 37 deletions(-) diff --git a/app/controllers/admin/taxon_concepts_controller.rb b/app/controllers/admin/taxon_concepts_controller.rb index d604c75ada..bdcf177e81 100644 --- a/app/controllers/admin/taxon_concepts_controller.rb +++ b/app/controllers/admin/taxon_concepts_controller.rb @@ -2,7 +2,6 @@ class Admin::TaxonConceptsController < Admin::StandardAuthorizationController respond_to :json layout :determine_layout before_filter :sanitize_search_params, :only => [:index, :autocomplete] - before_filter :sanitize_update_params, :only => [:update] before_filter :load_tags, :only => [:index, :edit, :create] def index @@ -34,10 +33,11 @@ def edit def update @taxon_concept = TaxonConcept.find(params[:id]) + taxa_ids = sanitize_update_params rebuild_taxonomy = @taxon_concept.rebuild_taxonomy?(params) update! do |success, failure| success.js { - @taxon_concept.rebuild_relationships(@taxa_ids) + @taxon_concept.rebuild_relationships(taxa_ids) if taxa_ids.present? UpdateTaxonomyWorker.perform_async if rebuild_taxonomy render 'update' } @@ -48,7 +48,7 @@ def update render 'new' } success.html { - @taxon_concept.rebuild_relationships(@taxa_ids) + @taxon_concept.rebuild_relationships(taxa_ids) if taxa_ids.present? UpdateTaxonomyWorker.perform_async if rebuild_taxonomy redirect_to edit_admin_taxon_concept_url(@taxon_concept), :notice => 'Operation successful' @@ -93,6 +93,7 @@ def sanitize_search_params def sanitize_update_params name_status = params[:taxon_concept][:name_status] + taxa_ids = [] if params[:taxon_concept] name_ids = case name_status @@ -101,9 +102,10 @@ def sanitize_update_params when 'H' then :hybrid_parent_ids else return [] end - @taxa_ids = + taxa_ids = params[:taxon_concept].delete(name_ids).first.split(',').map(&:to_i) end + taxa_ids end def load_tags diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index 01e29e0898..dfe702ddd7 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -46,13 +46,12 @@ class TaxonConcept < ActiveRecord::Base :parent_id, :author_year, :taxon_name_id, :taxonomic_position, :legacy_id, :legacy_type, :full_name, :name_status, :parent_scientific_name, - :tag_list, :legacy_trade_code, + :tag_list, :legacy_trade_code, :hybrid_parent_ids, :accepted_name_ids, :accepted_names_for_trade_name_ids, :nomenclature_note_en, :nomenclature_note_es, :nomenclature_note_fr, :created_by_id, :updated_by_id, :dependents_updated_at attr_writer :parent_scientific_name - acts_as_taggable serialize :data, ActiveRecord::Coders::Hstore @@ -340,54 +339,55 @@ def rebuild_taxonomy?(params) Rank.in_range(Rank::VARIETY, Rank::GENUS).include?(rank.name) end - #TODO - # save changes button won't work once already submitted - def rebuild_relationships(params) - new_accepted_taxa, removed_accepted_taxa = init_accepted_taxa(params) - rel_type = - if name_status == 'S' - TaxonRelationshipType. - find_by_name(TaxonRelationshipType::HAS_SYNONYM) - elsif name_status == 'T' - TaxonRelationshipType. - find_by_name(TaxonRelationshipType::HAS_TRADE_NAME) - end + def rebuild_relationships(taxa_ids) + if ['S', 'T', 'H'].include? name_status + new_taxa, removed_taxa = init_accepted_taxa(taxa_ids) + rel_type = + case name_status + when 'S' + TaxonRelationshipType.find_by_name(TaxonRelationshipType::HAS_SYNONYM) + when 'T' + TaxonRelationshipType.find_by_name(TaxonRelationshipType::HAS_TRADE_NAME) + when 'H' + TaxonRelationshipType.find_by_name(TaxonRelationshipType::HAS_HYBRID) + end + add_remove_relationships(new_taxa, removed_taxa, rel_type) + end + end + + private - removed_accepted_taxa.each do |accepted_name| - accepted_name.taxon_relationships. - where('other_taxon_concept_id = ? AND rel_type = ?', id, rel_type). + def add_remove_relationships(new_taxa, removed_taxa, rel_type) + removed_taxa.each do |taxon_concept| + taxon_concept.taxon_relationships. + where('other_taxon_concept_id = ? AND + taxon_relationship_type_id = ?', id, rel_type.id). first.destroy end - new_accepted_taxa.each do |accepted_name| - Rails.logger.debug "Creating #{rel_type.name} inverse relationship with #{accepted_name.full_name}" - accepted_name.taxon_relationships << TaxonRelationship.new( + new_taxa.each do |taxon_concept| + taxon_concept.taxon_relationships << TaxonRelationship.new( :taxon_relationship_type_id => rel_type.id, :other_taxon_concept_id => id ) - accepted_name.save end end - - private - - def init_accepted_taxa(params) + def init_accepted_taxa(all_taxa_ids) name_ids = case name_status when 'S' then :accepted_name_ids when 'T' then :accepted_names_for_trade_name_ids + when 'H' then :hybrid_parent_ids else return [[],[]] end - - all_accepted_name_ids = - params ? params[name_ids].first.split(',').map(&:to_i) : [] - new_accepted_name_ids = all_accepted_name_ids - accepted_name_ids - removed_accepted_name_ids = accepted_name_ids - all_accepted_name_ids + current_name_ids = send(name_ids) + new_taxa_ids = all_taxa_ids - current_name_ids + removed_taxa_ids = current_name_ids - all_taxa_ids [ - TaxonConcept.where(id: new_accepted_name_ids), - TaxonConcept.where(id: removed_accepted_name_ids) + TaxonConcept.where(id: new_taxa_ids), + TaxonConcept.where(id: removed_taxa_ids) ] end @@ -528,5 +528,4 @@ def ensure_taxonomic_position true end - end From 422f5427db00c1a72a01b6d9f0daf0119b8e3322 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Sun, 18 Oct 2015 15:31:51 +0200 Subject: [PATCH 077/365] Fix test exception --- app/controllers/admin/taxon_concepts_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/admin/taxon_concepts_controller.rb b/app/controllers/admin/taxon_concepts_controller.rb index bdcf177e81..efc0b8b0e5 100644 --- a/app/controllers/admin/taxon_concepts_controller.rb +++ b/app/controllers/admin/taxon_concepts_controller.rb @@ -92,7 +92,7 @@ def sanitize_search_params end def sanitize_update_params - name_status = params[:taxon_concept][:name_status] + name_status = params[:taxon_concept] ? params[:taxon_concept][:name_status] : '' taxa_ids = [] if params[:taxon_concept] name_ids = From 741cc01fa61189a4bf7181e6e06cf25023171aca Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Sun, 18 Oct 2015 15:32:09 +0200 Subject: [PATCH 078/365] Limit hybrids selection to 2 --- app/assets/javascripts/admin/admin_in_place_editor.js.coffee | 1 + app/assets/javascripts/admin/nomenclature_changes.js.coffee | 5 +++++ app/helpers/admin/taxon_concepts_helper.rb | 1 + 3 files changed, 7 insertions(+) diff --git a/app/assets/javascripts/admin/admin_in_place_editor.js.coffee b/app/assets/javascripts/admin/admin_in_place_editor.js.coffee index f42baad525..4b587a8361 100644 --- a/app/assets/javascripts/admin/admin_in_place_editor.js.coffee +++ b/app/assets/javascripts/admin/admin_in_place_editor.js.coffee @@ -199,6 +199,7 @@ class AdminInPlaceEditor extends AdminEditor initSelect2Inputs: () -> $('.taxon-concept').select2(window.defaultTaxonSelect2Options) $('.taxon-concept-multiple').select2($.extend({}, window.defaultTaxonSelect2Options,window.multiTaxonSelect2Options)) + $('.hybrids-selection').select2($.extend({}, window.defaultTaxonSelect2Options, window.multiTaxonSelect2Options, window.hybridsSelect2Options)) class TaxonConceptsEditor extends AdminEditor init: () -> diff --git a/app/assets/javascripts/admin/nomenclature_changes.js.coffee b/app/assets/javascripts/admin/nomenclature_changes.js.coffee index e547e53b44..04b256ea1a 100644 --- a/app/assets/javascripts/admin/nomenclature_changes.js.coffee +++ b/app/assets/javascripts/admin/nomenclature_changes.js.coffee @@ -44,6 +44,11 @@ $(document).ready -> result.push({id: id, text: names[i] + ' ' + name_status}) callback(result) } + window.hybridsSelect2Options = { + maximumSelectionSize: 2, + formatSelectionTooBig: (limit) -> + return 'You can only select ' + limit + ' items' + } $('.taxon-concept').select2(window.defaultTaxonSelect2Options) $('.taxon-concept-multiple').select2($.extend({}, window.defaultTaxonSelect2Options, window.multiTaxonSelect2Options)) diff --git a/app/helpers/admin/taxon_concepts_helper.rb b/app/helpers/admin/taxon_concepts_helper.rb index 996667fb8a..4f61a7f2e2 100644 --- a/app/helpers/admin/taxon_concepts_helper.rb +++ b/app/helpers/admin/taxon_concepts_helper.rb @@ -34,6 +34,7 @@ def fields_opts f, name_status }) when 'H' DEFAULT_OPTS.merge({ + klass: 'hybrids-selection', label: 'Parents', field_name: :hybrid_parent_ids, data_name: TaxonConcept.fetch_taxons_full_name( From 3b348c12e0bfbdf43daaca66eb35e0e110097fdd Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 21 Jan 2016 22:21:41 +0000 Subject: [PATCH 079/365] redis config in rails secrets --- config/secrets.yml.example | 1 - config/secrets.yml.travis | 1 - 2 files changed, 2 deletions(-) diff --git a/config/secrets.yml.example b/config/secrets.yml.example index c69a172f7c..22b224d43c 100644 --- a/config/secrets.yml.example +++ b/config/secrets.yml.example @@ -1,7 +1,6 @@ common: &defaults secret_key_base: 'e09049f49c23855f0d6b52c864796e27708bbd61d37920fc01b9641e4310ed901ca77a0a827c6384509f17e81c8c68c7446658a70bc4780eae740803d045323b' redis: - namespace: 'SAPI' url: 'redis://127.0.0.1:6379/1' development: diff --git a/config/secrets.yml.travis b/config/secrets.yml.travis index c69a172f7c..22b224d43c 100644 --- a/config/secrets.yml.travis +++ b/config/secrets.yml.travis @@ -1,7 +1,6 @@ common: &defaults secret_key_base: 'e09049f49c23855f0d6b52c864796e27708bbd61d37920fc01b9641e4310ed901ca77a0a827c6384509f17e81c8c68c7446658a70bc4780eae740803d045323b' redis: - namespace: 'SAPI' url: 'redis://127.0.0.1:6379/1' development: From cdd921c2cb4eccf38e9fae58f1dcefc54f2b9cd2 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 21 Jan 2016 22:38:13 +0000 Subject: [PATCH 080/365] added dogapi gem for recording capistrano deployments --- Capfile | 4 ++++ Gemfile | 1 + Gemfile.lock | 2 ++ vendor/cache/dogapi-1.21.0.gem | Bin 0 -> 35840 bytes 4 files changed, 7 insertions(+) create mode 100644 vendor/cache/dogapi-1.21.0.gem diff --git a/Capfile b/Capfile index 59f216cf1d..55f7162a8d 100644 --- a/Capfile +++ b/Capfile @@ -2,6 +2,10 @@ require 'dotenv' Dotenv.load +# DataDog deployment events +require "capistrano/datadog" +set :datadog_api_key, "5a2b3ffdb12de3ae0f25b12610457dbb" + # Load DSL and set up stages require 'capistrano/setup' diff --git a/Gemfile b/Gemfile index 805715ef84..9815b9e800 100644 --- a/Gemfile +++ b/Gemfile @@ -107,6 +107,7 @@ group :development do gem 'webrick', '1.3.1' gem 'jslint_on_rails' gem 'git_pretty_accept' + gem 'dogapi', '>= 1.3.0' end group :test, :development do diff --git a/Gemfile.lock b/Gemfile.lock index b9867a8df1..6a016d18ff 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -165,6 +165,8 @@ GEM warden (~> 1.2.3) diff-lcs (1.1.3) docile (1.1.5) + dogapi (1.21.0) + multi_json domain_name (0.5.20160216) unf (>= 0.0.5, < 1.0.0) dotenv (2.0.1) diff --git a/vendor/cache/dogapi-1.21.0.gem b/vendor/cache/dogapi-1.21.0.gem new file mode 100644 index 0000000000000000000000000000000000000000..d62821a3d973af712406c07cc8e05125251c3122 GIT binary patch literal 35840 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 literal 0 HcmV?d00001 From e6155b8f991b646af1e5def066e425d4c2697914 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 18 Feb 2016 14:09:02 +0000 Subject: [PATCH 081/365] Revert "added dogapi gem for recording capistrano deployments" This reverts commit 8f6003d896ecf92f3d2ee921ac1e63878c9e22e6. --- Capfile | 4 ---- Gemfile | 1 - Gemfile.lock | 2 -- vendor/cache/dogapi-1.21.0.gem | Bin 35840 -> 0 bytes 4 files changed, 7 deletions(-) delete mode 100644 vendor/cache/dogapi-1.21.0.gem diff --git a/Capfile b/Capfile index 55f7162a8d..59f216cf1d 100644 --- a/Capfile +++ b/Capfile @@ -2,10 +2,6 @@ require 'dotenv' Dotenv.load -# DataDog deployment events -require "capistrano/datadog" -set :datadog_api_key, "5a2b3ffdb12de3ae0f25b12610457dbb" - # Load DSL and set up stages require 'capistrano/setup' diff --git a/Gemfile b/Gemfile index 9815b9e800..805715ef84 100644 --- a/Gemfile +++ b/Gemfile @@ -107,7 +107,6 @@ group :development do gem 'webrick', '1.3.1' gem 'jslint_on_rails' gem 'git_pretty_accept' - gem 'dogapi', '>= 1.3.0' end group :test, :development do diff --git a/Gemfile.lock b/Gemfile.lock index 6a016d18ff..b9867a8df1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -165,8 +165,6 @@ GEM warden (~> 1.2.3) diff-lcs (1.1.3) docile (1.1.5) - dogapi (1.21.0) - multi_json domain_name (0.5.20160216) unf (>= 0.0.5, < 1.0.0) dotenv (2.0.1) diff --git a/vendor/cache/dogapi-1.21.0.gem b/vendor/cache/dogapi-1.21.0.gem deleted file mode 100644 index d62821a3d973af712406c07cc8e05125251c3122..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35840 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 From f55a71a6dcf1c11b8a7f2228c75928c081c0b57c Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Wed, 9 Mar 2016 13:46:51 +0000 Subject: [PATCH 082/365] Fix undefined fetch_accepted_taxons_full_name --- app/models/nomenclature_change/output.rb | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/app/models/nomenclature_change/output.rb b/app/models/nomenclature_change/output.rb index c5c1a76d22..93d4cfbdfe 100644 --- a/app/models/nomenclature_change/output.rb +++ b/app/models/nomenclature_change/output.rb @@ -125,6 +125,19 @@ def display_rank_name try(:new_rank).try(:name) || taxon_concept.try(:rank).try(:name) end + def fetch_accepted_taxons_full_name + if accepted_taxon_ids.present? + ActiveRecord::Base.connection.execute( + <<-SQL + SELECT tc.full_name + FROM taxon_concepts tc + WHERE tc.id = ANY (ARRAY#{accepted_taxon_ids.map(&:to_i)}) + ORDER BY tc.id + SQL + ).map{ |row| row['full_name']} + end + end + # Returns true when the new taxon has a different name from old one def will_create_taxon? taxon_concept.nil? || From 652858f4ebcfc68acc4b7ac78ff082d2fdd36d96 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 15 Mar 2016 11:04:01 +0000 Subject: [PATCH 083/365] skip parent rank validation unless accepted name --- app/models/taxon_concept.rb | 3 ++- spec/models/nomenclature_change/output_spec.rb | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index dfe702ddd7..85c543bc76 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -168,7 +168,8 @@ class TaxonConcept < ActiveRecord::Base validates :rank_id, :presence => true validates :name_status, :presence => true validate :parent_in_same_taxonomy, :if => lambda { |tc| tc.parent } - validate :parent_at_immediately_higher_rank, :if => lambda { |tc| tc.parent } + validate :parent_at_immediately_higher_rank, + :if => lambda { |tc| tc.parent && tc.name_status == 'A' } validate :parent_name_compatible, :if => lambda { |tc| tc.parent && tc.rank && tc.full_name && ( ['A', 'N'].include?(tc.name_status) || tc.name_status.blank? diff --git a/spec/models/nomenclature_change/output_spec.rb b/spec/models/nomenclature_change/output_spec.rb index e83db62b9e..1891b99c93 100644 --- a/spec/models/nomenclature_change/output_spec.rb +++ b/spec/models/nomenclature_change/output_spec.rb @@ -60,10 +60,10 @@ :new_scientific_name => 'xxx', :new_parent_id => create_cites_eu_species.id, :new_rank_id => species_rank.id, - :new_name_status => nil + :new_name_status => 'A' ) } - specify { expect(output).to have(2).errors_on(:new_parent_id) } + specify { expect(output).to have(1).error_on(:new_parent_id) } end context "when taxon concept specified" do let(:tc){ create_cites_eu_species } From c17077b73646805cf03e5407fff9c362b79bbac1 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 15 Mar 2016 12:10:13 +0000 Subject: [PATCH 084/365] removed ability to select A species to be turned into synonyms --- app/views/admin/nomenclature_changes/index.html.erb | 2 +- .../status_to_synonym/primary_output.html.erb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/admin/nomenclature_changes/index.html.erb b/app/views/admin/nomenclature_changes/index.html.erb index 1ecc45524e..b8797d931d 100644 --- a/app/views/admin/nomenclature_changes/index.html.erb +++ b/app/views/admin/nomenclature_changes/index.html.erb @@ -38,7 +38,7 @@ <% end %> -
+
+ <%= link_to admin_nomenclature_change_new_name_index_path( + :nomenclature_change_id => :new), + :method => :post do + %> + + <% end %> + Create a new name
Change the name status to synonym (e.g. A -> S, N -> S, T -> S)Change the name status to synonym (e.g. N -> S, T -> S)
diff --git a/app/views/admin/nomenclature_changes/status_to_synonym/primary_output.html.erb b/app/views/admin/nomenclature_changes/status_to_synonym/primary_output.html.erb index 20a2eb247c..6aae4d8279 100644 --- a/app/views/admin/nomenclature_changes/status_to_synonym/primary_output.html.erb +++ b/app/views/admin/nomenclature_changes/status_to_synonym/primary_output.html.erb @@ -9,7 +9,7 @@ :class => 'taxon-concept status-change', :'data-name' => ff.object.taxon_concept.try(:full_name), :'data-name-status' => ff.object.taxon_concept.try(:name_status), - :'data-name-status-filter' => ['A', 'N', 'T'].to_json, + :'data-name-status-filter' => ['N', 'T'].to_json, :'data-taxonomy-id' => @taxonomy.id } %> From 65592459e6364b652bd5bc0abb8fb9062cc32ee4 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 15 Mar 2016 12:11:21 +0000 Subject: [PATCH 085/365] amended model and specs to reflect removal of A -> S scenario --- .../nomenclature_change/status_to_synonym.rb | 10 +++---- .../status_to_synonym_controller_spec.rb | 30 ++++--------------- .../shared/status_change_definitions.rb | 14 +++++++-- .../status_swap/constructor_spec.rb | 2 +- .../status_swap/processor_spec.rb | 2 +- .../status_to_synonym/constructor_spec.rb | 7 +++-- .../output_taxon_concept_processor_spec.rb | 4 ++- .../status_to_synonym/processor_spec.rb | 5 ++-- 8 files changed, 34 insertions(+), 40 deletions(-) diff --git a/app/models/nomenclature_change/status_to_synonym.rb b/app/models/nomenclature_change/status_to_synonym.rb index e2739f9f42..d8534e4422 100644 --- a/app/models/nomenclature_change/status_to_synonym.rb +++ b/app/models/nomenclature_change/status_to_synonym.rb @@ -13,8 +13,8 @@ # # A status change to S needs to have at least one output and at most two -# The cases where there are 2 are as follows: -# 1. accepted taxon t1 (input) downgraded to synonym t1 (output1), +# The case where there are 2 is as follows: +# N taxon t1 (input) downgraded to synonym t1 (output1), # with any associations transferred to accepted taxon t2 (output2) # As a rule of thumb, if there are 2 outputs that means there are reassignments @@ -38,7 +38,7 @@ def ensure_new_name_status end # we only need two outputs if we need a target for reassignments - # (which happens when one of the outputs is an A / N name turning S) + # (which happens when one of the outputs is an N name turning S) def required_secondary_output if (needs_to_relay_associations? || requires_accepted_name_assignment?) && secondary_output.nil? @@ -49,7 +49,7 @@ def required_secondary_output end def build_input_for_relay - # In case the primary output is an A / N name turning S + # In case the primary output is a N name turning S # this same name becomes an input of the nomenclature change, so that # reassignments can be put in place between this input and # the secondary output @@ -63,7 +63,7 @@ def needs_to_receive_associations? end def needs_to_relay_associations? - ['A', 'N'].include?(primary_output.try(:name_status)) + primary_output.try(:name_status) == 'N' end def requires_accepted_name_assignment? diff --git a/spec/controllers/admin/nomenclature_changes/status_to_synonym_controller_spec.rb b/spec/controllers/admin/nomenclature_changes/status_to_synonym_controller_spec.rb index b3301c6579..4c498fc664 100644 --- a/spec/controllers/admin/nomenclature_changes/status_to_synonym_controller_spec.rb +++ b/spec/controllers/admin/nomenclature_changes/status_to_synonym_controller_spec.rb @@ -3,6 +3,7 @@ describe Admin::NomenclatureChanges::StatusToSynonymController do login_admin include_context 'status_change_definitions' + let(:input_species){ create_cites_eu_species(name_status: 'N') } describe 'GET show' do context :primary_output do @@ -16,38 +17,17 @@ end context :relay do before(:each) do - @status_change = a_to_s_with_primary_output + @status_change = n_to_s_with_primary_output end it 'renders the relay template' do get :show, id: :relay, nomenclature_change_id: @status_change.id response.should render_template('relay') end end - context :reassignments do - before(:each) do - @status_change = a_to_s_with_input_and_secondary_output - end - context "when legislation present" do - before(:each) do - create_cites_I_addition(taxon_concept: input_species) - end - it 'renders the legislation template' do - get :show, id: :legislation, nomenclature_change_id: @status_change.id - response.should render_template('legislation') - end - end - context "when no legislation" do - it 'redirects to next step' do - get :show, id: :legislation, nomenclature_change_id: @status_change.id - response.should redirect_to(admin_nomenclature_change_status_to_synonym_url( - nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'summary' - )) - end - end - end + context :summary do before(:each) do - @status_change = a_to_s_with_input_and_secondary_output + @status_change = n_to_s_with_input_and_secondary_output end it 'renders the summary template' do get :show, id: :summary, nomenclature_change_id: @status_change.id @@ -73,7 +53,7 @@ it 'redirects to next step' do put :update, nomenclature_change_status_to_synonym: { primary_output_attributes: { - taxon_concept_id: create_cites_eu_species.id, + taxon_concept_id: create_cites_eu_species(name_status: 'N').id, new_name_status: 'S' } }, nomenclature_change_id: @status_change.id, id: 'primary_output' diff --git a/spec/models/nomenclature_change/shared/status_change_definitions.rb b/spec/models/nomenclature_change/shared/status_change_definitions.rb index e5449f53ac..9206028b89 100644 --- a/spec/models/nomenclature_change/shared/status_change_definitions.rb +++ b/spec/models/nomenclature_change/shared/status_change_definitions.rb @@ -19,7 +19,7 @@ ) tc } - let(:a_to_s_with_primary_output){ + let(:n_to_s_with_primary_output){ create(:nomenclature_change_status_to_synonym, primary_output_attributes: { is_primary_output: true, @@ -53,7 +53,7 @@ status: NomenclatureChange::StatusToSynonym::RELAY ).reload } - let(:a_to_s_with_input_and_secondary_output){ + let(:n_to_s_with_input_and_secondary_output){ create(:nomenclature_change_status_to_synonym, primary_output_attributes: { is_primary_output: true, @@ -68,6 +68,16 @@ status: NomenclatureChange::StatusToSynonym::RELAY ).reload } + let(:a_to_s_with_swap_with_primary_output){ + create(:nomenclature_change_status_swap, + primary_output_attributes: { + is_primary_output: true, + taxon_concept_id: accepted_name.id, + new_name_status: 'S' + }, + status: NomenclatureChange::StatusSwap::PRIMARY_OUTPUT + ).reload + } let(:a_to_s_with_swap){ create(:nomenclature_change_status_swap, primary_output_attributes: { diff --git a/spec/models/nomenclature_change/status_swap/constructor_spec.rb b/spec/models/nomenclature_change/status_swap/constructor_spec.rb index c178a76d94..2e2eff332e 100644 --- a/spec/models/nomenclature_change/status_swap/constructor_spec.rb +++ b/spec/models/nomenclature_change/status_swap/constructor_spec.rb @@ -21,7 +21,7 @@ describe :build_secondary_output do context :downgrade do - let(:status_change){ a_to_s_with_primary_output } + let(:status_change){ a_to_s_with_swap_with_primary_output } before(:each) do @old_output = status_change.secondary_output constructor.build_secondary_output diff --git a/spec/models/nomenclature_change/status_swap/processor_spec.rb b/spec/models/nomenclature_change/status_swap/processor_spec.rb index 6a8afa7ba8..6bfa418b85 100644 --- a/spec/models/nomenclature_change/status_swap/processor_spec.rb +++ b/spec/models/nomenclature_change/status_swap/processor_spec.rb @@ -53,7 +53,7 @@ describe :summary do - let(:status_change){ a_to_s_with_input_and_secondary_output } + let(:status_change){ a_to_s_with_swap } specify { expect(processor.summary).to be_kind_of(Array) } end end diff --git a/spec/models/nomenclature_change/status_to_synonym/constructor_spec.rb b/spec/models/nomenclature_change/status_to_synonym/constructor_spec.rb index 123bbaa393..196c05ec3f 100644 --- a/spec/models/nomenclature_change/status_to_synonym/constructor_spec.rb +++ b/spec/models/nomenclature_change/status_to_synonym/constructor_spec.rb @@ -4,9 +4,10 @@ include_context 'status_change_definitions' let(:constructor){ NomenclatureChange::StatusToSynonym::Constructor.new(status_change) } + let(:input_species){ create_cites_eu_species(name_status: 'N') } describe :build_input do - let(:status_change){ a_to_s_with_primary_output } + let(:status_change){ n_to_s_with_primary_output } before(:each) do @old_input = status_change.input constructor.build_input @@ -15,7 +16,7 @@ specify{ expect(status_change.input).not_to be_nil } end context "when previously input in place" do - let(:status_change){ a_to_s_with_input_and_secondary_output } + let(:status_change){ n_to_s_with_input_and_secondary_output } specify{ expect(status_change.input).to eq(@old_input) } end end @@ -29,7 +30,7 @@ constructor.build_output_notes end - let(:status_change){ a_to_s_with_input_and_secondary_output } + let(:status_change){ n_to_s_with_input_and_secondary_output } context "when previously no notes in place" do specify{ expect(primary_output.internal_note).not_to be_blank } specify{ expect(secondary_output.note_en).to be_blank } diff --git a/spec/models/nomenclature_change/status_to_synonym/output_taxon_concept_processor_spec.rb b/spec/models/nomenclature_change/status_to_synonym/output_taxon_concept_processor_spec.rb index 4270785797..f90cc99964 100644 --- a/spec/models/nomenclature_change/status_to_synonym/output_taxon_concept_processor_spec.rb +++ b/spec/models/nomenclature_change/status_to_synonym/output_taxon_concept_processor_spec.rb @@ -4,6 +4,8 @@ include_context 'status_change_definitions' before(:each){ synonym_relationship_type } + let(:input_species){ create_cites_eu_species(name_status: 'N') } + describe :run do let(:processor){ NomenclatureChange::OutputTaxonConceptProcessor.new(primary_output) @@ -12,7 +14,7 @@ processor.run end context "when output is existing taxon" do - let(:primary_output){ a_to_s_with_input_and_secondary_output.primary_output } + let(:primary_output){ n_to_s_with_input_and_secondary_output.primary_output } specify{ expect(primary_output.new_taxon_concept).to be_nil } end end diff --git a/spec/models/nomenclature_change/status_to_synonym/processor_spec.rb b/spec/models/nomenclature_change/status_to_synonym/processor_spec.rb index 46959df760..bb3e8828fc 100644 --- a/spec/models/nomenclature_change/status_to_synonym/processor_spec.rb +++ b/spec/models/nomenclature_change/status_to_synonym/processor_spec.rb @@ -5,12 +5,13 @@ before(:each){ synonym_relationship_type } let(:processor){ NomenclatureChange::StatusToSynonym::Processor.new(status_change) } + let(:input_species){ create_cites_eu_species(name_status: 'N') } let(:primary_output_taxon_concept){ status_change.primary_output.taxon_concept } let(:secondary_output_taxon_concept){ status_change.secondary_output.taxon_concept } describe :run do - context "from accepted name" do - let(:status_change){ a_to_s_with_input_and_secondary_output } + context "from N name" do + let(:status_change){ n_to_s_with_input_and_secondary_output } before(:each){ @shipment = create(:shipment, taxon_concept: primary_output_taxon_concept, From 7a2d1c070f73816804eff838c21b8255b7516a81 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 15 Mar 2016 12:12:35 +0000 Subject: [PATCH 086/365] added primary output validations for changing into synonym --- .../nomenclature_change/status_to_synonym.rb | 18 +++++++++ .../status_to_synonym_spec.rb | 40 +++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 spec/models/nomenclature_change/status_to_synonym_spec.rb diff --git a/app/models/nomenclature_change/status_to_synonym.rb b/app/models/nomenclature_change/status_to_synonym.rb index d8534e4422..ba53f594a1 100644 --- a/app/models/nomenclature_change/status_to_synonym.rb +++ b/app/models/nomenclature_change/status_to_synonym.rb @@ -28,6 +28,8 @@ class NomenclatureChange::StatusToSynonym < NomenclatureChange in: self.status_dict, message: "%{value} is not a valid status" } + validate :required_primary_output, if: :primary_output_or_submitting? + validate :required_primary_output_name_status, if: :primary_output_or_submitting? validate :required_secondary_output, if: :relay_or_submitting? before_save :build_input_for_relay, if: :relay? before_save :build_auto_reassignments, if: :legislation? @@ -37,6 +39,22 @@ def ensure_new_name_status primary_output && primary_output.new_name_status = 'S' end + def required_primary_output + if primary_output.nil? + errors.add(:primary_output, "Must have a primary output") + return false + end + true + end + + def required_primary_output_name_status + if primary_output && !['N', 'T'].include?(primary_output.name_status) + errors.add(:primary_output, "Must be N or T taxon") + return false + end + true + end + # we only need two outputs if we need a target for reassignments # (which happens when one of the outputs is an N name turning S) def required_secondary_output diff --git a/spec/models/nomenclature_change/status_to_synonym_spec.rb b/spec/models/nomenclature_change/status_to_synonym_spec.rb new file mode 100644 index 0000000000..0ab3ec8c4d --- /dev/null +++ b/spec/models/nomenclature_change/status_to_synonym_spec.rb @@ -0,0 +1,40 @@ +# == Schema Information +# +# Table name: nomenclature_changes +# +# id :integer not null, primary key +# event_id :integer +# type :string(255) not null +# status :string(255) not null +# created_by_id :integer not null +# updated_by_id :integer not null +# created_at :datetime not null +# updated_at :datetime not null +# + +require 'spec_helper' + +describe NomenclatureChange::StatusToSynonym do + describe :validate do + context "when required primary output missing" do + context "when primary_output" do + let(:status_change){ + build( + :nomenclature_change_status_to_synonym, + :status => NomenclatureChange::StatusToSynonym::PRIMARY_OUTPUT + ) + } + specify { expect(status_change).to have(1).error_on(:primary_output) } + end + context "when submitting" do + let(:status_change){ + build( + :nomenclature_change_status_to_synonym, + :status => NomenclatureChange::StatusToSynonym::SUBMITTED + ) + } + specify { expect(status_change).to have(1).error_on(:primary_output) } + end + end + end +end From e9eb2044f1620db05922a6bcf75b7c8e9753c8d4 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 15 Mar 2016 12:31:41 +0000 Subject: [PATCH 087/365] added spec for secondary output validation --- .../status_to_synonym_spec.rb | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/spec/models/nomenclature_change/status_to_synonym_spec.rb b/spec/models/nomenclature_change/status_to_synonym_spec.rb index 0ab3ec8c4d..c89cd2c520 100644 --- a/spec/models/nomenclature_change/status_to_synonym_spec.rb +++ b/spec/models/nomenclature_change/status_to_synonym_spec.rb @@ -36,5 +36,27 @@ specify { expect(status_change).to have(1).error_on(:primary_output) } end end + context "when required secondary output missing" do + context "when relay" do + let(:status_change){ + build( + :nomenclature_change_status_to_synonym, + :primary_output_attributes => { taxon_concept_id: create_cites_eu_species(name_status: 'N').id }, + :status => NomenclatureChange::StatusToSynonym::RELAY + ) + } + specify { expect(status_change).to have(1).error_on(:secondary_output) } + end + context "when submitting" do + let(:status_change){ + build( + :nomenclature_change_status_to_synonym, + :primary_output_attributes => { taxon_concept_id: create_cites_eu_species(name_status: 'N').id }, + :status => NomenclatureChange::StatusToSynonym::SUBMITTED + ) + } + specify { expect(status_change).to have(1).error_on(:secondary_output) } + end + end end end From 0c44cc9f34ad169fc4447554c36924ff3ea0a039 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 15 Mar 2016 13:01:42 +0000 Subject: [PATCH 088/365] removed validation as it is duplicated in the included module --- app/models/nomenclature_change/status_to_synonym.rb | 9 --------- 1 file changed, 9 deletions(-) diff --git a/app/models/nomenclature_change/status_to_synonym.rb b/app/models/nomenclature_change/status_to_synonym.rb index ba53f594a1..edec324b33 100644 --- a/app/models/nomenclature_change/status_to_synonym.rb +++ b/app/models/nomenclature_change/status_to_synonym.rb @@ -28,7 +28,6 @@ class NomenclatureChange::StatusToSynonym < NomenclatureChange in: self.status_dict, message: "%{value} is not a valid status" } - validate :required_primary_output, if: :primary_output_or_submitting? validate :required_primary_output_name_status, if: :primary_output_or_submitting? validate :required_secondary_output, if: :relay_or_submitting? before_save :build_input_for_relay, if: :relay? @@ -39,14 +38,6 @@ def ensure_new_name_status primary_output && primary_output.new_name_status = 'S' end - def required_primary_output - if primary_output.nil? - errors.add(:primary_output, "Must have a primary output") - return false - end - true - end - def required_primary_output_name_status if primary_output && !['N', 'T'].include?(primary_output.name_status) errors.add(:primary_output, "Must be N or T taxon") From f1721fce145e1c5434b63c48cf82258415900993 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 15 Mar 2016 13:03:18 +0000 Subject: [PATCH 089/365] modernised syntax --- .../nomenclature_change/status_to_synonym_spec.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/spec/models/nomenclature_change/status_to_synonym_spec.rb b/spec/models/nomenclature_change/status_to_synonym_spec.rb index c89cd2c520..50ff35b9cb 100644 --- a/spec/models/nomenclature_change/status_to_synonym_spec.rb +++ b/spec/models/nomenclature_change/status_to_synonym_spec.rb @@ -21,7 +21,7 @@ let(:status_change){ build( :nomenclature_change_status_to_synonym, - :status => NomenclatureChange::StatusToSynonym::PRIMARY_OUTPUT + status: NomenclatureChange::StatusToSynonym::PRIMARY_OUTPUT ) } specify { expect(status_change).to have(1).error_on(:primary_output) } @@ -30,7 +30,7 @@ let(:status_change){ build( :nomenclature_change_status_to_synonym, - :status => NomenclatureChange::StatusToSynonym::SUBMITTED + status: NomenclatureChange::StatusToSynonym::SUBMITTED ) } specify { expect(status_change).to have(1).error_on(:primary_output) } @@ -41,8 +41,8 @@ let(:status_change){ build( :nomenclature_change_status_to_synonym, - :primary_output_attributes => { taxon_concept_id: create_cites_eu_species(name_status: 'N').id }, - :status => NomenclatureChange::StatusToSynonym::RELAY + primary_output_attributes: { taxon_concept_id: create_cites_eu_species(name_status: 'N').id }, + status: NomenclatureChange::StatusToSynonym::RELAY ) } specify { expect(status_change).to have(1).error_on(:secondary_output) } @@ -51,8 +51,8 @@ let(:status_change){ build( :nomenclature_change_status_to_synonym, - :primary_output_attributes => { taxon_concept_id: create_cites_eu_species(name_status: 'N').id }, - :status => NomenclatureChange::StatusToSynonym::SUBMITTED + primary_output_attributes: { taxon_concept_id: create_cites_eu_species(name_status: 'N').id }, + status: NomenclatureChange::StatusToSynonym::SUBMITTED ) } specify { expect(status_change).to have(1).error_on(:secondary_output) } From 4d53d366450f888514a168f3809e88e5b6d74bf9 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 15 Mar 2016 13:13:39 +0000 Subject: [PATCH 090/365] added spec for primary output name status validation --- .../status_to_synonym_spec.rb | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/spec/models/nomenclature_change/status_to_synonym_spec.rb b/spec/models/nomenclature_change/status_to_synonym_spec.rb index 50ff35b9cb..10231bcdd9 100644 --- a/spec/models/nomenclature_change/status_to_synonym_spec.rb +++ b/spec/models/nomenclature_change/status_to_synonym_spec.rb @@ -36,6 +36,34 @@ specify { expect(status_change).to have(1).error_on(:primary_output) } end end + context "when primary output has invalid name status" do + context "when primary_output" do + let(:status_change){ + build( + :nomenclature_change_status_to_synonym, + :primary_output_attributes => { + taxon_concept_id: create_cites_eu_species(name_status: 'A').id + }, + status: NomenclatureChange::StatusToAccepted::PRIMARY_OUTPUT + ) + } + specify { expect(status_change).to have(1).error_on(:primary_output) } + end + end + context "when primary output has valid name status" do + context "when primary_output" do + let(:status_change){ + build( + :nomenclature_change_status_to_synonym, + :primary_output_attributes => { + taxon_concept_id: create_cites_eu_species(name_status: 'N').id + }, + status: NomenclatureChange::StatusToAccepted::PRIMARY_OUTPUT + ) + } + specify { expect(status_change).to have(0).errors_on(:primary_output) } + end + end context "when required secondary output missing" do context "when relay" do let(:status_change){ From 5b194ff3b234fd88e39f1a295e0a19cf2f92aa95 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Wed, 16 Mar 2016 11:56:25 +0000 Subject: [PATCH 091/365] Add new taxon concept button back along with some synonym functionalities --- .../admin/taxon_concepts_controller.rb | 18 +++++++++- app/helpers/taxon_concept_helper.rb | 26 ++++++++++++-- app/models/taxon_concept.rb | 3 +- app/views/admin/names/index.html.erb | 2 +- .../taxon_concepts/_synonym_form.html.erb | 34 +++++++++++++++++++ app/views/admin/taxon_concepts/index.html.erb | 4 +++ .../admin/taxon_concepts/new_synonym.js.erb | 4 +++ config/routes.rb | 2 +- .../admin/taxon_concepts_controller_spec.rb | 13 +++++++ 9 files changed, 99 insertions(+), 7 deletions(-) create mode 100644 app/views/admin/taxon_concepts/_synonym_form.html.erb create mode 100644 app/views/admin/taxon_concepts/new_synonym.js.erb diff --git a/app/controllers/admin/taxon_concepts_controller.rb b/app/controllers/admin/taxon_concepts_controller.rb index efc0b8b0e5..37c526a3d6 100644 --- a/app/controllers/admin/taxon_concepts_controller.rb +++ b/app/controllers/admin/taxon_concepts_controller.rb @@ -31,6 +31,22 @@ def edit end end + def create + create! do |success, failure| + @taxonomies = Taxonomy.order(:name) + @ranks = Rank.order(:taxonomic_position) + success.js { render('create') } + failure.js { + if @taxon_concept.is_synonym? + @synonym = @taxon_concept + render('new_synonym') + else + render('new') + end + } + end + end + def update @taxon_concept = TaxonConcept.find(params[:id]) taxa_ids = sanitize_update_params @@ -85,7 +101,7 @@ def determine_layout def sanitize_search_params @search_params = SearchParams.new( - params[:search_params] || + params[:search_params] || { :taxonomy => { :id => Taxonomy. where(:name => Taxonomy::CITES_EU).limit(1).select(:id).first.id } }) diff --git a/app/helpers/taxon_concept_helper.rb b/app/helpers/taxon_concept_helper.rb index 656809cdd6..6a59a21d0b 100644 --- a/app/helpers/taxon_concept_helper.rb +++ b/app/helpers/taxon_concept_helper.rb @@ -8,7 +8,27 @@ def admin_taxon_concept_title else controller_name.titleize end - ) + ) + (content_tag(:div, class: 'action-buttons') do + admin_add_new_taxon_concept_multi + end) + end + end + + def admin_add_new_taxon_concept_multi + content_tag(:div, :class => 'btn-group', :style => 'float:right') do + link_to(' Add new Taxon Concept'.html_safe, '#', :class => 'btn') + + link_to(''.html_safe, '#', :class => 'btn dropdown-toggle', :"data-toggle" => 'dropdown') + + content_tag(:ul, :class => 'dropdown-menu') do + content_tag(:li) do + link_to('Accepted name', '#new-taxon_concept', :"data-toggle" => 'modal') + end + + content_tag(:li) do + link_to('Synonym', '#new-taxon_concept_synonym', :"data-toggle" => 'modal') + end + + content_tag(:li) do + link_to('Hybrid', '#new-taxon_concept_hybrid', :"data-toggle" => 'modal') + end + end end end @@ -45,11 +65,11 @@ def admin_add_new_hybrid_button ) end - def admin_new_synonym_modal + def admin_new_synonym_modal(nested = false) admin_new_modal( resource: 'taxon_concept_synonym', title: 'Add new Synonym' - ){ '' } + ){ nested ? '' : render('synonym_form') } end def admin_new_trade_name_modal diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index 85c543bc76..bee6ca5b78 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -45,13 +45,14 @@ class TaxonConcept < ActiveRecord::Base attr_accessible :parent_id, :taxonomy_id, :rank_id, :parent_id, :author_year, :taxon_name_id, :taxonomic_position, :legacy_id, :legacy_type, :full_name, :name_status, - :parent_scientific_name, + :parent_scientific_name, :accepted_scientific_name, :tag_list, :legacy_trade_code, :hybrid_parent_ids, :accepted_name_ids, :accepted_names_for_trade_name_ids, :nomenclature_note_en, :nomenclature_note_es, :nomenclature_note_fr, :created_by_id, :updated_by_id, :dependents_updated_at attr_writer :parent_scientific_name + attr_accessor :accepted_scientific_name acts_as_taggable serialize :data, ActiveRecord::Coders::Hstore diff --git a/app/views/admin/names/index.html.erb b/app/views/admin/names/index.html.erb index 393c22adf5..9e22c33c81 100644 --- a/app/views/admin/names/index.html.erb +++ b/app/views/admin/names/index.html.erb @@ -3,7 +3,7 @@

Synonyms

<%= admin_add_new_synonym_button %> - <%= admin_new_synonym_modal %> + <%= admin_new_synonym_modal(true) %>
<% if @taxon_concept.has_synonyms? %> diff --git a/app/views/admin/taxon_concepts/_synonym_form.html.erb b/app/views/admin/taxon_concepts/_synonym_form.html.erb new file mode 100644 index 0000000000..743d744acd --- /dev/null +++ b/app/views/admin/taxon_concepts/_synonym_form.html.erb @@ -0,0 +1,34 @@ +<%= form_for [:admin, @synonym], :remote => true, :namespace => 'synonym' do |f| %> + <%= error_messages_for(@synonym) %> + <%= f.hidden_field :name_status %> + +
+ + <%= f.select :taxonomy_id, + options_from_collection_for_select( + @taxonomies, :id, :name, @synonym && @synonym.taxonomy_id + ) + %> +
+
+ + <%= f.select :rank_id, + options_from_collection_for_select( + @ranks, :id, :name, + @synonym && @synonym.rank_id + ) + %> +
+
+ + <%= f.text_field :accepted_scientific_name, :class => 'typeahead' %> +
+
+ + <%= f.text_field :full_name %> +
+
+ + <%= f.text_field :author_year %> +
+<% end %> diff --git a/app/views/admin/taxon_concepts/index.html.erb b/app/views/admin/taxon_concepts/index.html.erb index b9cbba2c8e..2202b92c03 100644 --- a/app/views/admin/taxon_concepts/index.html.erb +++ b/app/views/admin/taxon_concepts/index.html.erb @@ -1,5 +1,9 @@ <%= admin_taxon_concept_title %> +<%= admin_new_modal %> +<%= admin_new_synonym_modal %> +<%= admin_new_hybrid_modal %> + <%= render :partial => 'search' %> <%= admin_table %> diff --git a/app/views/admin/taxon_concepts/new_synonym.js.erb b/app/views/admin/taxon_concepts/new_synonym.js.erb new file mode 100644 index 0000000000..464cd28d72 --- /dev/null +++ b/app/views/admin/taxon_concepts/new_synonym.js.erb @@ -0,0 +1,4 @@ +$('#admin-new-taxon_concept_synonym-form').html( + "<%= escape_javascript(render('synonym_form')) %>"); +$('#new-taxon_concept_synonym').modal('show'); +window.adminEditor.initTaxonConceptTypeaheads(); diff --git a/config/routes.rb b/config/routes.rb index c5fba8855d..19e644bfe5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -118,7 +118,7 @@ resources :ahoy_visits, :only => [:index, :show] resources :ahoy_events, :only => [:index, :show] - resources :taxon_concepts, only: [:index, :edit, :update, :show, :destroy] do + resources :taxon_concepts do get :autocomplete, :on => :collection resources :children, :only => [:index] resources :taxon_relationships, :only => [:index, :create, :destroy] diff --git a/spec/controllers/admin/taxon_concepts_controller_spec.rb b/spec/controllers/admin/taxon_concepts_controller_spec.rb index bfc8a03805..962f38078e 100644 --- a/spec/controllers/admin/taxon_concepts_controller_spec.rb +++ b/spec/controllers/admin/taxon_concepts_controller_spec.rb @@ -33,6 +33,19 @@ end end + describe "XHR POST create" do + let(:taxon_concept_attributes){ build_tc_attributes(:taxon_concept) } + it "renders create when successful" do + xhr :post, :create, + taxon_concept: taxon_concept_attributes + response.should render_template("create") + end + it "renders new when not successful" do + xhr :post, :create, taxon_concept: {} + response.should render_template("new") + end + end + describe "XHR PUT update" do let(:taxon_concept){ create(:taxon_concept) } context "when JSON" do From bb51b76c2231d43fbe9df5bebb668d6ba207fb62 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Wed, 16 Mar 2016 15:58:13 +0000 Subject: [PATCH 092/365] Create sysonym bringing back inverse relationship check --- app/models/taxon_concept.rb | 12 ++++++++++++ app/models/taxon_relationship.rb | 1 - 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index bee6ca5b78..1ef7b0fcf3 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -192,6 +192,8 @@ class TaxonConcept < ActiveRecord::Base :if => lambda { |tc| tc.full_name } before_validation :check_parent_taxon_concept_exists, :if => lambda { |tc| tc.parent_scientific_name } + before_validation :check_accepted_taxon_concept_exists, + :if => lambda { |tc| tc.is_synonym? && tc.accepted_scientific_name } before_validation :ensure_taxonomic_position @@ -477,6 +479,16 @@ def check_taxon_name_exists true end + def check_accepted_taxon_concept_exists + check_associated_taxon_concept_exists(:accepted_scientific_name) do |tc| + inverse_taxon_relationships.build( + taxon_concept_id: tc.id, + taxon_relationship_type_id: TaxonRelationshipType. + find_by_name(TaxonRelationshipType::HAS_SYNONYM).id + ) + end + end + def check_parent_taxon_concept_exists check_associated_taxon_concept_exists(:parent_scientific_name) do |tc| self.parent_id = tc.id diff --git a/app/models/taxon_relationship.rb b/app/models/taxon_relationship.rb index db744ed470..c2d0240d8e 100644 --- a/app/models/taxon_relationship.rb +++ b/app/models/taxon_relationship.rb @@ -34,7 +34,6 @@ class TaxonRelationship < ActiveRecord::Base scope: [:taxon_relationship_type_id, :other_taxon_concept_id], message: 'This relationship already exists, choose another taxon.' } - validates :other_taxon_concept_id, presence: true validate :intertaxonomic_relationship_uniqueness, :if => "taxon_relationship_type.is_intertaxonomic?" def update_higher_taxa_for_hybrid_child From bf3374cb08491b18fe3916ef19cda0b2f5e9d40c Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Wed, 16 Mar 2016 16:35:22 +0000 Subject: [PATCH 093/365] added parent presence validation and fixed all the specs that got upset --- app/models/taxon_concept.rb | 2 + .../admin/ranks_controller_spec.rb | 4 +- .../admin/taxon_concepts_controller_spec.rb | 4 +- spec/factories.rb | 18 +-- spec/factories/ranks.rb | 106 ++++++++++++++++++ spec/factories/taxon_concepts.rb | 22 ++++ spec/models/listing_change_spec.rb | 36 +----- spec/models/nomenclature_change/lump_spec.rb | 2 +- .../models/nomenclature_change/output_spec.rb | 2 +- .../shared/split_definitions.rb | 9 +- .../shared/status_change_definitions.rb | 21 +++- .../split/processor_spec.rb | 12 +- spec/models/nomenclature_change/split_spec.rb | 4 +- .../status_swap/processor_spec.rb | 1 + .../status_to_accepted/processor_spec.rb | 28 ++++- spec/models/rank_spec.rb | 20 ++-- .../orphaned_taxon_concepts_export_spec.rb | 3 +- spec/models/taxon_concept/validation_spec.rb | 5 +- .../taxon_concept_prefix_matcher_spec.rb | 37 +++--- spec/support/sapi_helpers.rb | 94 +++------------- 20 files changed, 251 insertions(+), 179 deletions(-) create mode 100644 spec/factories/ranks.rb create mode 100644 spec/factories/taxon_concepts.rb diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index 1ef7b0fcf3..91ca8ab396 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -168,6 +168,8 @@ class TaxonConcept < ActiveRecord::Base validates :taxonomy_id, :presence => true validates :rank_id, :presence => true validates :name_status, :presence => true + validates :parent_id, presence: true, + if: lambda { |tc| tc.name_status == 'A' && tc.rank.try(:name) != 'KINGDOM' } validate :parent_in_same_taxonomy, :if => lambda { |tc| tc.parent } validate :parent_at_immediately_higher_rank, :if => lambda { |tc| tc.parent && tc.name_status == 'A' } diff --git a/spec/controllers/admin/ranks_controller_spec.rb b/spec/controllers/admin/ranks_controller_spec.rb index b2d821954f..d484aea019 100644 --- a/spec/controllers/admin/ranks_controller_spec.rb +++ b/spec/controllers/admin/ranks_controller_spec.rb @@ -5,8 +5,8 @@ describe "GET index" do it "assigns @ranks sorted by taxonomic position" do - rank2 = create(:rank, :taxonomic_position => '2') - rank1 = create(:rank, :taxonomic_position => '1') + rank2 = create(:rank, name: Rank::PHYLUM, taxonomic_position: '2') + rank1 = create(:rank, name: Rank::KINGDOM, taxonomic_position: '1') get :index assigns(:ranks).should eq([rank1, rank2]) end diff --git a/spec/controllers/admin/taxon_concepts_controller_spec.rb b/spec/controllers/admin/taxon_concepts_controller_spec.rb index 962f38078e..3161cb4ab3 100644 --- a/spec/controllers/admin/taxon_concepts_controller_spec.rb +++ b/spec/controllers/admin/taxon_concepts_controller_spec.rb @@ -111,7 +111,7 @@ describe "XHR GET JSON autocomplete" do let!(:taxon_concept){ - create(:taxon_concept, + create_cites_eu_genus( :taxon_name => create(:taxon_name, :scientific_name => 'AAA') ) } @@ -119,7 +119,7 @@ xhr :get, :autocomplete, :format => 'json', :search_params => {:scientific_name => 'AAA'} response.body.should have_json_size(1) - parse_json(response.body, "0/full_name").should == 'AAA' + parse_json(response.body, "0/full_name").should == 'Aaa' end end diff --git a/spec/factories.rb b/spec/factories.rb index df4fcd0407..b3a8c3a9e8 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -1,4 +1,5 @@ #Encoding: utf-8 + FactoryGirl.define do factory :user do @@ -58,23 +59,6 @@ sequence(:scientific_name) {|n| "Lupus#{n}"} end - factory :rank do - sequence(:name) {|n| "rank#{n}"} - display_name_en { name } - taxonomic_position '1' - end - - factory :taxon_concept, :aliases => [:other_taxon_concept] do - taxonomy - rank - taxon_name - taxonomic_position '1' - name_status 'A' - data {} - listing {} - parent_scientific_name '' - end - factory :cites_suspension do taxon_concept start_notification diff --git a/spec/factories/ranks.rb b/spec/factories/ranks.rb new file mode 100644 index 0000000000..33107c5bd0 --- /dev/null +++ b/spec/factories/ranks.rb @@ -0,0 +1,106 @@ + # def find_or_create_rank(name) + # send("#{name.downcase}_rank") + # end + + # def kingdom_rank + # Rank.find_by_name(Rank::KINGDOM) || Rank.new(attributes_for_kingdom) + # end + + # def phylum_rank + # Rank.find_by_name(Rank::PHYLUM) || Rank.new(attributes_for_phylum) + # end + + # def class_rank + # Rank.find_by_name(Rank::CLASS) || Rank.new(attributes_for_class) + # end + + # def order_rank + # Rank.find_by_name(Rank::ORDER) || Rank.new(attributes_for_order) + # end + + # def family_rank + # Rank.find_by_name(Rank::FAMILY) || Rank.new(attributes_for_family) + # end + + # def subfamily_rank + # Rank.find_by_name(Rank::SUBFAMILY) || Rank.new(attributes_for_subfamily) + # end + + # def genus_rank + # Rank.find_by_name(Rank::GENUS) || Rank.new(attributes_for_genus) + # end + + # def species_rank + # Rank.find_by_name(Rank::SPECIES) || Rank.new(attributes_for_species) + # end + + # def subspecies_rank + # Rank.find_by_name(Rank::SUBSPECIES) || Rank.new(attributes_for_subspecies) + # end + + # def variety_rank + # Rank.find_by_name(Rank::VARIETY) || Rank.new(attributes_for_variety) + # end + + def attributes_for_rank(name) + send("attributes_for_#{name.downcase}") + end + + def attributes_for_kingdom + { name: Rank::KINGDOM, taxonomic_position: '1', fixed_order: true } + end + + def attributes_for_phylum + { name: Rank::PHYLUM, taxonomic_position: '2', fixed_order: true } + end + + def attributes_for_class + { name: Rank::CLASS, taxonomic_position: '3', fixed_order: true } + end + + def attributes_for_order + { name: Rank::ORDER, taxonomic_position: '4', fixed_order: false } + end + + def attributes_for_family + { name: Rank::FAMILY, taxonomic_position: '5', fixed_order: false } + end + + def attributes_for_subfamily + { name: Rank::SUBFAMILY, taxonomic_position: '5.1', fixed_order: false } + end + + def attributes_for_genus + { name: Rank::GENUS, taxonomic_position: '6', fixed_order: false } + end + + def attributes_for_species + { name: Rank::SPECIES, taxonomic_position: '7', fixed_order: false } + end + + def attributes_for_subspecies + { name: Rank::SUBSPECIES, taxonomic_position: '7.1', fixed_order: false } + end + + def attributes_for_variety + { name: Rank::VARIETY, taxonomic_position: '7.2', fixed_order: false } + end + +FactoryGirl.define do + factory :rank do + name { [ + Rank::KINGDOM, + Rank::PHYLUM, + Rank::CLASS, + Rank::ORDER, + Rank::FAMILY, + Rank::SUBFAMILY, + Rank::GENUS, + Rank::SPECIES, + Rank::SUBSPECIES, + Rank::VARIETY + ].sample } + display_name_en { |r| r.name } + initialize_with { Rank.find_by_name(name) || new(attributes_for_rank(name)) } + end +end diff --git a/spec/factories/taxon_concepts.rb b/spec/factories/taxon_concepts.rb new file mode 100644 index 0000000000..3fec4abbc6 --- /dev/null +++ b/spec/factories/taxon_concepts.rb @@ -0,0 +1,22 @@ +FactoryGirl.define do + factory :taxon_concept, :aliases => [:other_taxon_concept] do + taxonomy + rank + taxon_name + taxonomic_position '1' + name_status 'A' + data {} + listing {} + parent_scientific_name '' + before(:create){ |tc| + if tc.parent.nil? && tc.name_status == 'A' && tc.rank.try(:name) != 'KINGDOM' + tc.parent = create( + :taxon_concept, + taxonomy: tc.taxonomy, + name_status: 'A', + rank: create(:rank, name: tc.rank.parent_rank_name) # this should not produce duplicates + ) + end + } + end +end diff --git a/spec/models/listing_change_spec.rb b/spec/models/listing_change_spec.rb index b1dbffc1e6..73a724c6cf 100644 --- a/spec/models/listing_change_spec.rb +++ b/spec/models/listing_change_spec.rb @@ -45,41 +45,13 @@ specify{ listing_change.exclusions.size == 0 } end context "inclusion taxon concept is lower rank" do - let(:rank1){ create(:rank, :taxonomic_position => '1')} - let(:rank2){ create(:rank, :taxonomic_position => '1.2')} - let(:inclusion){ - create( - :taxon_concept, - :rank => rank2, - :taxon_name => create(:taxon_name, :scientific_name => 'Abc') - ) - } - let(:taxon_concept){ create(:taxon_concept, :rank => rank1) } - let(:listing_change){ - build( - :listing_change, - :taxon_concept => taxon_concept, - :inclusion_taxon_concept_id => inclusion.id - ) - } - specify{listing_change.should have(1).error_on(:inclusion_taxon_concept_id)} - end - context "inclusion taxon concept is lower rank" do - let(:rank1){ create(:rank, :taxonomic_position => '1')} - let(:rank2){ create(:rank, :taxonomic_position => '1.2')} - let(:inclusion){ - create( - :taxon_concept, - :rank => rank2, - :taxon_name => create(:taxon_name, :scientific_name => 'Abc') - ) - } - let(:taxon_concept){ create(:taxon_concept, :rank => rank1) } + let(:inclusion){ create_cites_eu_subspecies } + let(:taxon_concept){ create_cites_eu_species } let(:listing_change){ build( :listing_change, - :taxon_concept => taxon_concept, - :inclusion_taxon_concept_id => inclusion.id + taxon_concept: taxon_concept, + inclusion_taxon_concept_id: inclusion.id ) } specify{listing_change.should have(1).error_on(:inclusion_taxon_concept_id)} diff --git a/spec/models/nomenclature_change/lump_spec.rb b/spec/models/nomenclature_change/lump_spec.rb index 77c689c32f..7450cf19af 100644 --- a/spec/models/nomenclature_change/lump_spec.rb +++ b/spec/models/nomenclature_change/lump_spec.rb @@ -71,7 +71,7 @@ }, :output_attributes => { :taxon_concept_id => create_cites_eu_species.id, - :new_rank_id => species_rank.id + :new_rank_id => create(:rank, name: Rank::SPECIES).id } ) } diff --git a/spec/models/nomenclature_change/output_spec.rb b/spec/models/nomenclature_change/output_spec.rb index 1891b99c93..ad4beeafd7 100644 --- a/spec/models/nomenclature_change/output_spec.rb +++ b/spec/models/nomenclature_change/output_spec.rb @@ -59,7 +59,7 @@ :nomenclature_change_output, :taxon_concept_id => nil, :new_scientific_name => 'xxx', :new_parent_id => create_cites_eu_species.id, - :new_rank_id => species_rank.id, + :new_rank_id => create(:rank, name: Rank::SPECIES).id, :new_name_status => 'A' ) } diff --git a/spec/models/nomenclature_change/shared/split_definitions.rb b/spec/models/nomenclature_change/shared/split_definitions.rb index 189fb149b6..1e2e6ae5db 100644 --- a/spec/models/nomenclature_change/shared/split_definitions.rb +++ b/spec/models/nomenclature_change/shared/split_definitions.rb @@ -61,7 +61,7 @@ 1 => { new_scientific_name: 'fatalus', new_parent_id: errorus_genus.id, - new_rank_id: species_rank.id, + new_rank_id: create(:rank, name: Rank::SPECIES).id, new_name_status: 'A' } }, @@ -73,7 +73,10 @@ input_attributes: {taxon_concept_id: input_species.id}, outputs_attributes: { 0 => { taxon_concept_id: output_species1.id }, - 1 => { taxon_concept_id: output_species2.id, new_name_status: 'A' } + 1 => { taxon_concept_id: output_species2.id, + new_name_status: 'A', + new_parent_id: genus2.id + } }, status: NomenclatureChange::Split::OUTPUTS ) @@ -87,7 +90,7 @@ taxon_concept_id: output_subspecies2.id, new_scientific_name: 'lolcatus', new_parent_id: errorus_genus.id, - new_rank_id: species_rank.id, + new_rank_id: create(:rank, name: Rank::SPECIES).id, new_name_status: 'A' } }, diff --git a/spec/models/nomenclature_change/shared/status_change_definitions.rb b/spec/models/nomenclature_change/shared/status_change_definitions.rb index 9206028b89..42e31041a6 100644 --- a/spec/models/nomenclature_change/shared/status_change_definitions.rb +++ b/spec/models/nomenclature_change/shared/status_change_definitions.rb @@ -11,7 +11,9 @@ tc } let(:input_synonym){ - tc = create_cites_eu_species(name_status: 'S') + tc = create_cites_eu_species(name_status: 'S', + taxon_name: create(:taxon_name, scientific_name: 'Confundus totalus') + ) create(:taxon_relationship, taxon_concept: accepted_name, other_taxon_concept: tc, @@ -19,6 +21,11 @@ ) tc } + let(:input_synonym_genus){ + create_cites_eu_genus( + taxon_name: create(:taxon_name, scientific_name: 'Confundus') + ) + } let(:n_to_s_with_primary_output){ create(:nomenclature_change_status_to_synonym, primary_output_attributes: { @@ -34,7 +41,8 @@ primary_output_attributes: { is_primary_output: true, taxon_concept_id: input_synonym.id, - new_name_status: 'A' + new_name_status: 'A', + new_parent_id: input_synonym_genus.id }, status: NomenclatureChange::StatusToAccepted::PRIMARY_OUTPUT ).reload @@ -89,7 +97,8 @@ secondary_output_attributes: { is_primary_output: false, taxon_concept_id: input_synonym.id, - new_name_status: 'A' + new_name_status: 'A', + new_parent_id: input_synonym_genus.id }, status: NomenclatureChange::StatusSwap::SWAP ).reload @@ -99,7 +108,8 @@ primary_output_attributes: { is_primary_output: true, taxon_concept_id: input_synonym.id, - new_name_status: 'A' + new_name_status: 'A', + new_parent_id: input_synonym_genus.id }, status: NomenclatureChange::StatusToAccepted::PRIMARY_OUTPUT ).reload @@ -109,7 +119,8 @@ primary_output_attributes: { is_primary_output: true, taxon_concept_id: input_synonym.id, - new_name_status: 'A' + new_name_status: 'A', + new_parent_id: input_synonym_genus.id }, input_attributes: { taxon_concept_id: input_species.id }, secondary_output_attributes: { diff --git a/spec/models/nomenclature_change/split/processor_spec.rb b/spec/models/nomenclature_change/split/processor_spec.rb index ad0d1c6036..07b6614014 100644 --- a/spec/models/nomenclature_change/split/processor_spec.rb +++ b/spec/models/nomenclature_change/split/processor_spec.rb @@ -39,7 +39,17 @@ end end context "when output is existing taxon with new status" do - let(:output_species2){ create_cites_eu_species(:name_status => 'S') } + let(:output_species2){ + create_cites_eu_species( + name_status: 'S', + taxon_name: create(:taxon_name, scientific_name: 'Notio mirabilis') + ) + } + let(:genus2){ + create_cites_eu_genus( + taxon_name: create(:taxon_name, scientific_name: 'Notio') + ) + } let!(:split){ split_with_input_and_outputs_status_change } specify { expect{ processor.run }.not_to change(TaxonConcept, :count) } specify { expect{ processor.run }.not_to change(output_species1, :full_name) } diff --git a/spec/models/nomenclature_change/split_spec.rb b/spec/models/nomenclature_change/split_spec.rb index 61394616cd..b226ef1a4c 100644 --- a/spec/models/nomenclature_change/split_spec.rb +++ b/spec/models/nomenclature_change/split_spec.rb @@ -60,11 +60,11 @@ :outputs_attributes => { 0 => { :taxon_concept_id => create_cites_eu_subspecies.id, - :new_rank_id => subspecies_rank.id + :new_rank_id => create(:rank, name: Rank::SUBSPECIES).id }, 1 => { :taxon_concept_id => create_cites_eu_subspecies.id, - :new_rank_id => subspecies_rank.id + :new_rank_id => create(:rank, name: Rank::SUBSPECIES).id } } ) diff --git a/spec/models/nomenclature_change/status_swap/processor_spec.rb b/spec/models/nomenclature_change/status_swap/processor_spec.rb index 6bfa418b85..4d75d95e5a 100644 --- a/spec/models/nomenclature_change/status_swap/processor_spec.rb +++ b/spec/models/nomenclature_change/status_swap/processor_spec.rb @@ -15,6 +15,7 @@ tc } + before(:each){ synonym_relationship_type } let(:processor){ NomenclatureChange::StatusSwap::Processor.new(status_change) } let(:primary_output_taxon_concept){ status_change.primary_output.taxon_concept } diff --git a/spec/models/nomenclature_change/status_to_accepted/processor_spec.rb b/spec/models/nomenclature_change/status_to_accepted/processor_spec.rb index 0cdbf52d2e..7dfafaa742 100644 --- a/spec/models/nomenclature_change/status_to_accepted/processor_spec.rb +++ b/spec/models/nomenclature_change/status_to_accepted/processor_spec.rb @@ -6,7 +6,10 @@ let(:accepted_name){ create_cites_eu_species } let(:trade_name){ - tc = create_cites_eu_species(name_status: 'T') + tc = create_cites_eu_species( + name_status: 'T', + taxon_name: create(:taxon_name, scientific_name: 'Lolcatus nonsensus') + ) create(:taxon_relationship, taxon_concept: accepted_name, other_taxon_concept: tc, @@ -14,9 +17,16 @@ ) tc } - + let(:trade_name_genus){ + create_cites_eu_genus( + taxon_name: create(:taxon_name, scientific_name: 'Lolcatus') + ) + } let(:synonym){ - tc = create_cites_eu_species(name_status: 'S') + tc = create_cites_eu_species( + name_status: 'S', + taxon_name: create(:taxon_name, scientific_name: 'Foobarus ridiculus') + ) create(:taxon_relationship, taxon_concept: accepted_name, other_taxon_concept: tc, @@ -24,7 +34,11 @@ ) tc } - + let(:synonym_genus){ + create_cites_eu_genus( + taxon_name: create(:taxon_name, scientific_name: 'Foobarus') + ) + } before(:each){ synonym_relationship_type } let(:processor){ NomenclatureChange::StatusToAccepted::Processor.new(status_change) } let(:primary_output_taxon_concept){ status_change.primary_output.taxon_concept } @@ -38,7 +52,8 @@ primary_output_attributes: { is_primary_output: true, taxon_concept_id: synonym.id, - new_name_status: 'A' + new_name_status: 'A', + new_parent_id: synonym_genus.id }, input_attributes: { taxon_concept_id: input_species.id }, status: NomenclatureChange::StatusToAccepted::PRIMARY_OUTPUT @@ -65,7 +80,8 @@ primary_output_attributes: { is_primary_output: true, taxon_concept_id: trade_name.id, - new_name_status: 'A' + new_name_status: 'A', + new_parent_id: trade_name_genus.id }, input_attributes: { taxon_concept_id: input_species.id }, status: NomenclatureChange::StatusToAccepted::PRIMARY_OUTPUT diff --git a/spec/models/rank_spec.rb b/spec/models/rank_spec.rb index 915ae4e3dc..a3718a0b4d 100644 --- a/spec/models/rank_spec.rb +++ b/spec/models/rank_spec.rb @@ -18,32 +18,36 @@ describe Rank do describe :parent_rank_lower_bound do context "obligatory rank" do - let(:rank) { create(:rank, :name => 'Kingdom', :taxonomic_position => '1') } - specify {rank.parent_rank_lower_bound.should == '0'} + let(:rank) { create(:rank, name: Rank::KINGDOM) } + specify { rank.parent_rank_lower_bound.should == '0'} end context "optional rank" do - let(:rank) { create(:rank, :name => 'Infrakingdom', :taxonomic_position => '1.1.1') } - specify {rank.parent_rank_lower_bound.should == '1.1'} + let(:rank) { create(:rank, name: Rank::SUBFAMILY) } + specify { rank.parent_rank_lower_bound.should == '5' } end end describe :create do context "when taxonomic position malformed" do - let(:rank){ build(:rank, :name => 'Phylum', :taxonomic_position => '1.a.b') } + let(:rank){ build(:rank, name: Rank::PHYLUM, taxonomic_position: '1.a.b') } specify { rank.should have(1).error_on(:taxonomic_position) } end end describe :destroy do context "when no dependent objects attached" do - let(:rank){ create(:rank, :name => 'Phylum', :taxonomic_position => '1.1') } + let(:rank){ + r = create(:rank, name: Rank::PHYLUM, taxonomic_position: '1.1') + r.update_attribute(:name, 'SUPER PHYLUM') + r + } specify { rank.destroy.should be_true } end context "when dependent objects attached" do - let(:rank){ create(:rank, :name => 'Phylum', :taxonomic_position => '1.1') } + let(:rank){ create(:rank, name: Rank::PHYLUM, taxonomic_position: '1.1') } let!(:taxon_concept){ create(:taxon_concept, :rank => rank) } specify { rank.destroy.should be_false } end context "when protected name" do - let(:rank){ create(:rank, :name => 'PHYLUM', :taxonomic_position => '1.1') } + let(:rank){ create(:rank, name: Rank::PHYLUM, taxonomic_position: '1.1') } specify { rank.destroy.should be_false } end end diff --git a/spec/models/species/orphaned_taxon_concepts_export_spec.rb b/spec/models/species/orphaned_taxon_concepts_export_spec.rb index 9c4881a366..5643104881 100644 --- a/spec/models/species/orphaned_taxon_concepts_export_spec.rb +++ b/spec/models/species/orphaned_taxon_concepts_export_spec.rb @@ -15,7 +15,8 @@ end context "when results" do before(:each){ - create(:taxon_concept) + tc = create(:taxon_concept) + tc.update_attribute(:parent_id, nil) #skipping validations FileUtils.mkpath( File.expand_path("spec/public/downloads/orphaned_taxon_concepts") ) diff --git a/spec/models/taxon_concept/validation_spec.rb b/spec/models/taxon_concept/validation_spec.rb index d83c305b35..4be668ca28 100644 --- a/spec/models/taxon_concept/validation_spec.rb +++ b/spec/models/taxon_concept/validation_spec.rb @@ -112,13 +112,16 @@ specify { tc.should have(1).error_on(:taxonomic_position) } end context "when full name is already given" do + let(:tc_parent){ create_cites_eu_species } let!(:tc1) { create_cites_eu_subspecies( + parent: tc_parent, taxon_name: create(:taxon_name, scientific_name: 'duplicatus'), ) } - let!(:tc2) { + let(:tc2) { build_cites_eu_subspecies( + parent: tc_parent, taxon_name: build(:taxon_name, scientific_name: 'duplicatus'), ) } diff --git a/spec/models/taxon_concept_prefix_matcher_spec.rb b/spec/models/taxon_concept_prefix_matcher_spec.rb index 5d2c41f1be..a98524ab66 100644 --- a/spec/models/taxon_concept_prefix_matcher_spec.rb +++ b/spec/models/taxon_concept_prefix_matcher_spec.rb @@ -1,38 +1,35 @@ require 'spec_helper' describe TaxonConceptPrefixMatcher do - let(:taxonomy){ create(:taxonomy) } - let!(:rank1){ create(:rank, :taxonomic_position => '1') } - let!(:rank2){ create(:rank, :taxonomic_position => '2') } - let!(:rank3){ create(:rank, :taxonomic_position => '2.1') } - let!(:rank4){ create(:rank, :taxonomic_position => '3') } + let(:taxonomy){ cites_eu } let!(:taxon_concept1){ - create(:taxon_concept, :rank => rank1, :taxonomy => taxonomy, - :taxon_name => create(:taxon_name, :scientific_name => 'Aaa') + create_cites_eu_order( + taxon_name: create(:taxon_name, scientific_name: 'Aaa') ) } let!(:taxon_concept2){ - create(:taxon_concept, :rank => rank2, :taxonomy => taxonomy, - :taxon_name => create(:taxon_name, :scientific_name => 'Aac'), - :parent => taxon_concept1 + create_cites_eu_family( + taxon_name: create(:taxon_name, scientific_name: 'Aac'), + parent: taxon_concept1 ) } let!(:taxon_concept3){ - create(:taxon_concept, :rank => rank3, :taxonomy => taxonomy, - :taxon_name => create(:taxon_name, :scientific_name => 'Aab') + create_cites_eu_subfamily( + taxon_name: create(:taxon_name, scientific_name: 'Aab'), + parent: taxon_concept2 ) } let!(:taxon_concept4){ - create(:taxon_concept, :rank => rank4, :taxonomy => taxonomy, - :taxon_name => create(:taxon_name, :scientific_name => 'Abb'), - :parent => taxon_concept2 + create_cites_eu_genus( + taxon_name: create(:taxon_name, scientific_name: 'Abb'), + parent: taxon_concept3 ) } let!(:hybrid){ - tmp = create(:taxon_concept, :taxonomy => taxonomy, - :taxon_name => create(:taxon_name, :scientific_name => 'Abc'), - :name_status => 'H' + tmp = create_cites_eu_genus( + taxon_name: create(:taxon_name, scientific_name: 'Abc'), + name_status: 'H' ) create( :taxon_relationship, @@ -102,7 +99,7 @@ } specify{ ancestor_matcher.taxon_concepts.map(&:full_name).should == - ['Aaa', 'Aac'] } + ['Aaa', 'Aab', 'Aac'] } let(:descendant_matcher_params){ SearchParams.new( @@ -116,7 +113,7 @@ } specify{ descendant_matcher.taxon_concepts.map(&:full_name).should == - ['Abb'] } + ['Aab', 'Abb'] } end end diff --git a/spec/support/sapi_helpers.rb b/spec/support/sapi_helpers.rb index 729ac6b06c..9f887b0444 100644 --- a/spec/support/sapi_helpers.rb +++ b/spec/support/sapi_helpers.rb @@ -134,66 +134,6 @@ end end - let(:kingdom_rank){ - create( - :rank, - :name => Rank::KINGDOM, :taxonomic_position => '1', :fixed_order => true - ) - } - let(:phylum_rank){ - create( - :rank, - :name => Rank::PHYLUM, :taxonomic_position => '2', :fixed_order => true - ) - } - let(:class_rank){ - create( - :rank, - :name => Rank::CLASS, :taxonomic_position => '3', :fixed_order => true - ) - } - let(:order_rank){ - create( - :rank, - :name => Rank::ORDER, :taxonomic_position => '4', :fixed_order => false - ) - } - let(:family_rank){ - create( - :rank, - :name => Rank::FAMILY, :taxonomic_position => '5', :fixed_order => false - ) - } - let(:subfamily_rank){ - create( - :rank, - :name => Rank::SUBFAMILY, :taxonomic_position => '5.1', :fixed_order => false - ) - } - let(:genus_rank){ - create( - :rank, - :name => Rank::GENUS, :taxonomic_position => '6', :fixed_order => false - ) - } - let(:species_rank){ - create( - :rank, - :name => Rank::SPECIES, :taxonomic_position => '7', :fixed_order => false - ) - } - let(:subspecies_rank){ - create( - :rank, - :name => Rank::SUBSPECIES, :taxonomic_position => '7.1', :fixed_order => false - ) - } - let(:variety){ - create( - :rank, - :name => Rank::VARIETY, :taxonomic_position => '7.2', :fixed_order => false - ) - } let(:cites_eu_animalia){ create_cites_eu_kingdom( :taxonomic_position => '1', @@ -324,52 +264,52 @@ def create_cites_eu_plant_species(options = {}) ) end - %w(kingdom phylum class order family subfamily genus species subspecies variety).each do |rank| - define_method "create_#{rank}" do |options = {}| + %w(KINGDOM PHYLUM CLASS ORDER FAMILY SUBFAMILY GENUS SPECIES SUBSPECIES VARIETY).each do |rank| + define_method "create_#{rank.downcase}" do |options = {}| create( :taxon_concept, - options.merge({:rank => send("#{rank}_rank")}) + options.merge({rank: create(:rank, name: rank)}) ) end - define_method "build_#{rank}" do |options = {}| + define_method "build_#{rank.downcase}" do |options = {}| build( :taxon_concept, - options.merge({:rank => send("#{rank}_rank")}) + options.merge({rank: create(:rank, name: rank)}) ) end - define_method "create_cites_eu_#{rank}" do |options = {}| + define_method "create_cites_eu_#{rank.downcase}" do |options = {}| create( :taxon_concept, options.merge({ - :rank => send("#{rank}_rank"), - :taxonomy => cites_eu + rank: create(:rank, name: rank), + taxonomy: cites_eu }) ) end - define_method "build_cites_eu_#{rank}" do |options = {}| + define_method "build_cites_eu_#{rank.downcase}" do |options = {}| build( :taxon_concept, options.merge({ - :rank => send("#{rank}_rank"), - :taxonomy => cites_eu + rank: create(:rank, name: rank), + taxonomy: cites_eu }) ) end - define_method "create_cms_#{rank}" do |options = {}| + define_method "create_cms_#{rank.downcase}" do |options = {}| create( :taxon_concept, options.merge({ - :rank => send("#{rank}_rank"), - :taxonomy => cms + rank: create(:rank, name: rank), + taxonomy: cms }) ) end - define_method "build_cms_#{rank}" do |options = {}| + define_method "build_cms_#{rank.downcase}" do |options = {}| build( :taxon_concept, options.merge({ - :rank => send("#{rank}_rank"), - :taxonomy => cms + rank: create(:rank, name: rank), + taxonomy: cms }) ) end From cf4b8aec216334e3d49ed1dde33bb96efe3c2818 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Wed, 16 Mar 2016 17:00:55 +0000 Subject: [PATCH 094/365] removed commented code and fixed indentation --- spec/factories/ranks.rb | 110 ++++++++++++---------------------------- 1 file changed, 33 insertions(+), 77 deletions(-) diff --git a/spec/factories/ranks.rb b/spec/factories/ranks.rb index 33107c5bd0..c39e0c8a96 100644 --- a/spec/factories/ranks.rb +++ b/spec/factories/ranks.rb @@ -1,90 +1,46 @@ - # def find_or_create_rank(name) - # send("#{name.downcase}_rank") - # end - - # def kingdom_rank - # Rank.find_by_name(Rank::KINGDOM) || Rank.new(attributes_for_kingdom) - # end - - # def phylum_rank - # Rank.find_by_name(Rank::PHYLUM) || Rank.new(attributes_for_phylum) - # end - - # def class_rank - # Rank.find_by_name(Rank::CLASS) || Rank.new(attributes_for_class) - # end - - # def order_rank - # Rank.find_by_name(Rank::ORDER) || Rank.new(attributes_for_order) - # end - - # def family_rank - # Rank.find_by_name(Rank::FAMILY) || Rank.new(attributes_for_family) - # end - - # def subfamily_rank - # Rank.find_by_name(Rank::SUBFAMILY) || Rank.new(attributes_for_subfamily) - # end - - # def genus_rank - # Rank.find_by_name(Rank::GENUS) || Rank.new(attributes_for_genus) - # end - - # def species_rank - # Rank.find_by_name(Rank::SPECIES) || Rank.new(attributes_for_species) - # end - - # def subspecies_rank - # Rank.find_by_name(Rank::SUBSPECIES) || Rank.new(attributes_for_subspecies) - # end - - # def variety_rank - # Rank.find_by_name(Rank::VARIETY) || Rank.new(attributes_for_variety) - # end - - def attributes_for_rank(name) - send("attributes_for_#{name.downcase}") - end +def attributes_for_rank(name) + send("attributes_for_#{name.downcase}") +end - def attributes_for_kingdom - { name: Rank::KINGDOM, taxonomic_position: '1', fixed_order: true } - end +def attributes_for_kingdom + { name: Rank::KINGDOM, taxonomic_position: '1', fixed_order: true } +end - def attributes_for_phylum - { name: Rank::PHYLUM, taxonomic_position: '2', fixed_order: true } - end +def attributes_for_phylum + { name: Rank::PHYLUM, taxonomic_position: '2', fixed_order: true } +end - def attributes_for_class - { name: Rank::CLASS, taxonomic_position: '3', fixed_order: true } - end +def attributes_for_class + { name: Rank::CLASS, taxonomic_position: '3', fixed_order: true } +end - def attributes_for_order - { name: Rank::ORDER, taxonomic_position: '4', fixed_order: false } - end +def attributes_for_order + { name: Rank::ORDER, taxonomic_position: '4', fixed_order: false } +end - def attributes_for_family - { name: Rank::FAMILY, taxonomic_position: '5', fixed_order: false } - end +def attributes_for_family + { name: Rank::FAMILY, taxonomic_position: '5', fixed_order: false } +end - def attributes_for_subfamily - { name: Rank::SUBFAMILY, taxonomic_position: '5.1', fixed_order: false } - end +def attributes_for_subfamily + { name: Rank::SUBFAMILY, taxonomic_position: '5.1', fixed_order: false } +end - def attributes_for_genus - { name: Rank::GENUS, taxonomic_position: '6', fixed_order: false } - end +def attributes_for_genus + { name: Rank::GENUS, taxonomic_position: '6', fixed_order: false } +end - def attributes_for_species - { name: Rank::SPECIES, taxonomic_position: '7', fixed_order: false } - end +def attributes_for_species + { name: Rank::SPECIES, taxonomic_position: '7', fixed_order: false } +end - def attributes_for_subspecies - { name: Rank::SUBSPECIES, taxonomic_position: '7.1', fixed_order: false } - end +def attributes_for_subspecies + { name: Rank::SUBSPECIES, taxonomic_position: '7.1', fixed_order: false } +end - def attributes_for_variety - { name: Rank::VARIETY, taxonomic_position: '7.2', fixed_order: false } - end +def attributes_for_variety + { name: Rank::VARIETY, taxonomic_position: '7.2', fixed_order: false } +end FactoryGirl.define do factory :rank do From 03df91def3cef1d445a4e1e380c1b800c82dca08 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Wed, 16 Mar 2016 18:27:36 +0000 Subject: [PATCH 095/365] Keep other_taxon_concept validation without breaking functionalities --- app/models/taxon_concept.rb | 8 +++++--- app/models/taxon_relationship.rb | 1 + 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index 91ca8ab396..d403a32e8d 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -194,13 +194,14 @@ class TaxonConcept < ActiveRecord::Base :if => lambda { |tc| tc.full_name } before_validation :check_parent_taxon_concept_exists, :if => lambda { |tc| tc.parent_scientific_name } - before_validation :check_accepted_taxon_concept_exists, - :if => lambda { |tc| tc.is_synonym? && tc.accepted_scientific_name } before_validation :ensure_taxonomic_position translates :nomenclature_note + after_save :check_accepted_taxon_concept_exists, + :if => lambda { |tc| tc.is_synonym? && tc.accepted_scientific_name } + scope :at_parent_ranks, lambda{ |rank| joins_sql = <<-SQL INNER JOIN ranks ON ranks.id = taxon_concepts.rank_id @@ -483,8 +484,9 @@ def check_taxon_name_exists def check_accepted_taxon_concept_exists check_associated_taxon_concept_exists(:accepted_scientific_name) do |tc| - inverse_taxon_relationships.build( + inverse_taxon_relationships.create( taxon_concept_id: tc.id, + other_taxon_concept_id: self.id, taxon_relationship_type_id: TaxonRelationshipType. find_by_name(TaxonRelationshipType::HAS_SYNONYM).id ) diff --git a/app/models/taxon_relationship.rb b/app/models/taxon_relationship.rb index c2d0240d8e..db744ed470 100644 --- a/app/models/taxon_relationship.rb +++ b/app/models/taxon_relationship.rb @@ -34,6 +34,7 @@ class TaxonRelationship < ActiveRecord::Base scope: [:taxon_relationship_type_id, :other_taxon_concept_id], message: 'This relationship already exists, choose another taxon.' } + validates :other_taxon_concept_id, presence: true validate :intertaxonomic_relationship_uniqueness, :if => "taxon_relationship_type.is_intertaxonomic?" def update_higher_taxa_for_hybrid_child From 54bf045f9eff26e9da4b5b59d62c65abd00a0896 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Thu, 17 Mar 2016 09:35:59 +0000 Subject: [PATCH 096/365] Add new hybrid --- app/helpers/taxon_concept_helper.rb | 4 +- app/models/taxon_concept.rb | 32 ++++++++++- app/views/admin/names/index.html.erb | 2 +- .../taxon_concepts/_hybrid_form.html.erb | 54 +++++++++++++++++++ .../admin/taxon_concepts/new_hybrid.js.erb | 4 ++ 5 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 app/views/admin/taxon_concepts/_hybrid_form.html.erb create mode 100644 app/views/admin/taxon_concepts/new_hybrid.js.erb diff --git a/app/helpers/taxon_concept_helper.rb b/app/helpers/taxon_concept_helper.rb index 6a59a21d0b..5bc80f79f7 100644 --- a/app/helpers/taxon_concept_helper.rb +++ b/app/helpers/taxon_concept_helper.rb @@ -116,11 +116,11 @@ def admin_edit_distribution_modal(nested = false) ){ nested ? '' : render('admin/distributions/form') } end - def admin_new_hybrid_modal + def admin_new_hybrid_modal(nested = false) admin_new_modal( :resource => 'taxon_concept_hybrid', :title => 'Add new Hybrid' - ){ '' } + ){ nested ? '' : render('hybrid_form') } end def admin_add_new_reference_button diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index d403a32e8d..895377a03e 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -46,13 +46,15 @@ class TaxonConcept < ActiveRecord::Base :parent_id, :author_year, :taxon_name_id, :taxonomic_position, :legacy_id, :legacy_type, :full_name, :name_status, :parent_scientific_name, :accepted_scientific_name, + :hybrid_parent_scientific_name, :other_hybrid_parent_scientific_name, :tag_list, :legacy_trade_code, :hybrid_parent_ids, :accepted_name_ids, :accepted_names_for_trade_name_ids, :nomenclature_note_en, :nomenclature_note_es, :nomenclature_note_fr, :created_by_id, :updated_by_id, :dependents_updated_at attr_writer :parent_scientific_name - attr_accessor :accepted_scientific_name + attr_accessor :accepted_scientific_name, :hybrid_parent_scientific_name, + :other_hybrid_parent_scientific_name acts_as_taggable serialize :data, ActiveRecord::Coders::Hstore @@ -202,6 +204,12 @@ class TaxonConcept < ActiveRecord::Base after_save :check_accepted_taxon_concept_exists, :if => lambda { |tc| tc.is_synonym? && tc.accepted_scientific_name } + after_save :check_hybrid_parent_taxon_concept_exists, + :if => lambda { |tc| tc.is_hybrid? && tc.hybrid_parent_scientific_name } + + after_save :check_other_hybrid_parent_taxon_concept_exists, + :if => lambda { |tc| tc.is_hybrid? && tc.other_hybrid_parent_scientific_name } + scope :at_parent_ranks, lambda{ |rank| joins_sql = <<-SQL INNER JOIN ranks ON ranks.id = taxon_concepts.rank_id @@ -482,6 +490,28 @@ def check_taxon_name_exists true end + def check_hybrid_parent_taxon_concept_exists + check_associated_taxon_concept_exists(:hybrid_parent_scientific_name) do |tc| + inverse_taxon_relationships.create( + :taxon_concept_id => tc.id, + :other_taxon_concept_id => self.id, + :taxon_relationship_type_id => TaxonRelationshipType. + find_by_name(TaxonRelationshipType::HAS_HYBRID).id + ) + end + end + + def check_other_hybrid_parent_taxon_concept_exists + check_associated_taxon_concept_exists(:other_hybrid_parent_scientific_name) do |tc| + inverse_taxon_relationships.create( + :taxon_concept_id => tc.id, + :other_taxon_concept_id => self.id, + :taxon_relationship_type_id => TaxonRelationshipType. + find_by_name(TaxonRelationshipType::HAS_HYBRID).id + ) + end + end + def check_accepted_taxon_concept_exists check_associated_taxon_concept_exists(:accepted_scientific_name) do |tc| inverse_taxon_relationships.create( diff --git a/app/views/admin/names/index.html.erb b/app/views/admin/names/index.html.erb index 9e22c33c81..20b3238839 100644 --- a/app/views/admin/names/index.html.erb +++ b/app/views/admin/names/index.html.erb @@ -43,7 +43,7 @@

Hybrids

<%= admin_add_new_hybrid_button %> - <%= admin_new_hybrid_modal %> + <%= admin_new_hybrid_modal(true) %>
<% if @taxon_concept.has_hybrids? %> diff --git a/app/views/admin/taxon_concepts/_hybrid_form.html.erb b/app/views/admin/taxon_concepts/_hybrid_form.html.erb new file mode 100644 index 0000000000..d2e632e01a --- /dev/null +++ b/app/views/admin/taxon_concepts/_hybrid_form.html.erb @@ -0,0 +1,54 @@ +<%= form_for [:admin, @hybrid], :remote => true, :namespace => 'hybrid' do |f| %> + <%= error_messages_for(@hybrid) %> + <%= f.hidden_field :name_status %> + +
+ + <%= f.select :taxonomy_id, + options_from_collection_for_select( + @taxonomies, :id, :name, @hybrid && @hybrid.taxonomy_id + ) + %> +
+
+ + <%= f.select :rank_id, + options_from_collection_for_select( + @ranks, :id, :name, + @hybrid && @hybrid.rank_id + ) + %> +
+
+ + <%= f.text_field :hybrid_parent_scientific_name, :class => 'typeahead', + "data-rank-scope" => 'ancestors' + %> +
+
+ + <%= f.text_field :other_hybrid_parent_scientific_name, :class => 'typeahead', + "data-rank-scope" => 'ancestors' + %> +
+
+ + <%= f.text_field :full_name %> +
+
+ + <%= f.select :tag_list, + options_from_collection_for_select( + @tags, + :name, + :name, + @taxon_concept.tag_list + ), {}, + { :multiple => true, :class => 'tags', :style => "width: 220px"} + %> +
+
+ + <%= f.text_field :author_year %> +
+<% end %> diff --git a/app/views/admin/taxon_concepts/new_hybrid.js.erb b/app/views/admin/taxon_concepts/new_hybrid.js.erb new file mode 100644 index 0000000000..83c918f58e --- /dev/null +++ b/app/views/admin/taxon_concepts/new_hybrid.js.erb @@ -0,0 +1,4 @@ +$('#admin-new-taxon_concept_hybrid-form').html( + "<%= escape_javascript(render('hybrid_form')) %>"); +$('#new-taxon_concept_hybrid').modal('show'); +window.adminEditor.initTaxonConceptTypeaheads(); From 7b58df36eac3169ba17e221f6b286e4ace044773 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 17 Mar 2016 10:54:26 +0000 Subject: [PATCH 097/365] remove ability to select N / T taxa as split / lump outputs --- app/views/admin/nomenclature_changes/lump/outputs.html.erb | 2 +- app/views/admin/nomenclature_changes/split/outputs.html.erb | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/views/admin/nomenclature_changes/lump/outputs.html.erb b/app/views/admin/nomenclature_changes/lump/outputs.html.erb index 946110cfdd..10c5cbb18c 100644 --- a/app/views/admin/nomenclature_changes/lump/outputs.html.erb +++ b/app/views/admin/nomenclature_changes/lump/outputs.html.erb @@ -22,7 +22,7 @@ :'data-name' => ff.object.taxon_concept.try(:full_name), :'data-name-status' => ff.object.taxon_concept.try(:name_status), :'data-taxonomy-id' => @taxonomy.id, - :'data-name-status-filter' => ['A', 'N', 'S', 'T'].to_json + :'data-name-status-filter' => ['A', 'S'].to_json } %>
diff --git a/app/views/admin/nomenclature_changes/split/outputs.html.erb b/app/views/admin/nomenclature_changes/split/outputs.html.erb index dde329a1c5..8b1a4538ad 100644 --- a/app/views/admin/nomenclature_changes/split/outputs.html.erb +++ b/app/views/admin/nomenclature_changes/split/outputs.html.erb @@ -17,7 +17,7 @@ :'data-name' => ff.object.taxon_concept.try(:full_name), :'data-taxonomy-id' => @taxonomy.id, :'data-name-status' => ff.object.taxon_concept.try(:name_status), - :'data-name-status-filter' => ['A', 'N', 'S', 'T'].to_json + :'data-name-status-filter' => ['A', 'S'].to_json } %>
@@ -25,7 +25,6 @@
- <%= ff.text_field :new_parent_id, { :class => 'taxon-concept parent-taxon', :'data-name' => ff.object.new_parent.try(:full_name), From a07bef7fd8227dc08b8f1a0d74d6c21b7dccfd71 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 17 Mar 2016 10:56:14 +0000 Subject: [PATCH 098/365] corrected the default expected parent name for S / T outputs --- app/models/nomenclature_change/output.rb | 16 +++++- .../models/nomenclature_change/output_spec.rb | 55 +++++++++++++++++++ 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/app/models/nomenclature_change/output.rb b/app/models/nomenclature_change/output.rb index 93d4cfbdfe..28d466ea6f 100644 --- a/app/models/nomenclature_change/output.rb +++ b/app/models/nomenclature_change/output.rb @@ -230,16 +230,26 @@ def taxon_name_already_existing? return !TaxonConcept.where("lower(full_name) = ?", display_full_name.downcase).empty? end + def expected_parent_name + if rank.name == Rank::SPECIES + display_full_name.split[0] + elsif [Rank::SUBSPECIES, Rank::VARIETY].include?(rank.name) + display_full_name.split[0..1].join (' ') + else + nil + end + end + def default_parent - if name_status == 'T' && - Rank.in_range(Rank::VARIETY, Rank::SPECIES).include?(rank.name) + if ['S', 'T'].include? name_status && + parent_full_name = expected_parent_name TaxonConcept.where( taxonomy_id: Taxonomy.find_by_name(Taxonomy::CITES_EU).try(:id), rank_id: Rank.find_by_name(rank.parent_rank_name).try(:id), name_status: 'A' ).where( 'UPPER(SQUISH_NULL(full_name)) = UPPER(?)', - display_full_name.split.first + parent_full_name ).first else new_parent diff --git a/spec/models/nomenclature_change/output_spec.rb b/spec/models/nomenclature_change/output_spec.rb index ad4beeafd7..667586f7fa 100644 --- a/spec/models/nomenclature_change/output_spec.rb +++ b/spec/models/nomenclature_change/output_spec.rb @@ -77,4 +77,59 @@ specify{ expect(output.name_status).to eq(tc.name_status) } end end + describe :expected_parent_name do + let(:output){ + create(:nomenclature_change_output, :taxon_concept_id => tc.id) + } + let(:canis_genus){ + create_cites_eu_genus( + taxon_name: create(:taxon_name, scientific_name: 'Canis') + ) + } + let(:canis_species){ + create_cites_eu_species( + taxon_name: create(:taxon_name, scientific_name: 'lupus'), + parent: canis_genus + ) + } + let(:canis_subspecies){ + create_cites_eu_subspecies( + taxon_name: create(:taxon_name, scientific_name: 'dingo'), + parent: canis_species + ) + } + let(:magnolia_genus){ + create_cites_eu_genus( + taxon_name: create(:taxon_name, scientific_name: 'Magnolia') + ) + } + let(:magnolia_species){ + create_cites_eu_species( + taxon_name: create(:taxon_name, scientific_name: 'liliifera'), + parent: magnolia_genus + ) + } + let(:magnolia_variety){ + create_cites_eu_variety( + taxon_name: create(:taxon_name, scientific_name: 'var. obovata'), + parent: magnolia_species + ) + } + context "when genus" do + let(:tc){ canis_genus } + specify { expect(output.expected_parent_name).to be_nil } + end + context "when species" do + let(:tc){ canis_species } + specify { expect(output.expected_parent_name).to eq('Canis') } + end + context "when subspecies" do + let(:tc){ canis_subspecies } + specify { expect(output.expected_parent_name).to eq('Canis lupus') } + end + context "when variety" do + let(:tc){ magnolia_variety } + specify { expect(output.expected_parent_name).to eq('Magnolia liliifera') } + end + end end From 8b1254155e26aff2ca65ed3d7366d78dc60f06c2 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 17 Mar 2016 10:58:09 +0000 Subject: [PATCH 099/365] removed parent step and merged parent selection into primary_output step --- .../status_to_accepted_controller.rb | 5 ---- .../nomenclature_change/status_to_accepted.rb | 7 +----- .../build/_new_parent.html.erb | 12 ++++++++++ .../status_to_accepted/parent.html.erb | 19 --------------- .../primary_output.html.erb | 23 ++++++++++--------- .../status_to_accepted_controller_spec.rb | 11 +-------- 6 files changed, 26 insertions(+), 51 deletions(-) create mode 100644 app/views/admin/nomenclature_changes/build/_new_parent.html.erb delete mode 100644 app/views/admin/nomenclature_changes/status_to_accepted/parent.html.erb diff --git a/app/controllers/admin/nomenclature_changes/status_to_accepted_controller.rb b/app/controllers/admin/nomenclature_changes/status_to_accepted_controller.rb index 4612ba0505..f6ded4bb61 100644 --- a/app/controllers/admin/nomenclature_changes/status_to_accepted_controller.rb +++ b/app/controllers/admin/nomenclature_changes/status_to_accepted_controller.rb @@ -9,9 +9,6 @@ def show set_events set_taxonomy builder.build_primary_output - when :parent - skip_or_previous_step unless @nomenclature_change.needs_to_set_parent? - set_taxonomy when :summary processor = klass::Processor.new(@nomenclature_change) @summary = processor.summary @@ -32,8 +29,6 @@ def update set_events set_taxonomy end - when :parent - set_taxonomy unless success end render_wizard @nomenclature_change end diff --git a/app/models/nomenclature_change/status_to_accepted.rb b/app/models/nomenclature_change/status_to_accepted.rb index 4b0a82e784..9f6c45e30b 100644 --- a/app/models/nomenclature_change/status_to_accepted.rb +++ b/app/models/nomenclature_change/status_to_accepted.rb @@ -16,7 +16,7 @@ class NomenclatureChange::StatusToAccepted < NomenclatureChange include NomenclatureChange::StatusChangeHelpers build_steps( - :primary_output, :parent, :summary + :primary_output, :summary ) validates :status, inclusion: { in: self.status_dict, @@ -25,7 +25,6 @@ class NomenclatureChange::StatusToAccepted < NomenclatureChange before_validation :set_output_name_status, if: :primary_output_or_submitting? before_validation :set_output_rank_id, if: :primary_output_or_submitting? before_validation :set_output_parent_id, if: :primary_output_or_submitting? - before_save :build_auto_reassignments, if: :parent? def set_output_name_status primary_output && primary_output.new_name_status = 'A' @@ -54,8 +53,4 @@ def needs_to_set_parent? ['S', 'T'].include? primary_output.try(:name_status) end - def build_auto_reassignments - true - end - end diff --git a/app/views/admin/nomenclature_changes/build/_new_parent.html.erb b/app/views/admin/nomenclature_changes/build/_new_parent.html.erb new file mode 100644 index 0000000000..b807b88787 --- /dev/null +++ b/app/views/admin/nomenclature_changes/build/_new_parent.html.erb @@ -0,0 +1,12 @@ +
+ +
+ <%= ff.text_field :new_parent_id, { + :class => 'taxon-concept parent-taxon', + :'data-name' => ff.object.new_parent.try(:full_name), + :'data-name-status' => ff.object.new_parent.try(:name_status), + :'data-name-status-filter' => ['A'].to_json, + :'data-taxonomy-id' => @taxonomy.id + } %> +
+
diff --git a/app/views/admin/nomenclature_changes/status_to_accepted/parent.html.erb b/app/views/admin/nomenclature_changes/status_to_accepted/parent.html.erb deleted file mode 100644 index 3fc4aaee13..0000000000 --- a/app/views/admin/nomenclature_changes/status_to_accepted/parent.html.erb +++ /dev/null @@ -1,19 +0,0 @@ -

New status change to accepted name

-<%= status_change_blurb %> -<%= nomenclature_change_form do |f| %> - <%= f.fields_for :primary_output do |ff| %> -
- -
- - <%= ff.text_field :new_parent_id, { - :class => 'taxon-concept', - :'data-name' => ff.object.new_parent.try(:full_name), - :'data-name-status' => ff.object.new_parent.try(:name_status), - :'data-name-status-filter' => ['A'].to_json, - :'data-taxonomy-id' => @taxonomy.id - } %> -
-
- <% end %> -<% end %> diff --git a/app/views/admin/nomenclature_changes/status_to_accepted/primary_output.html.erb b/app/views/admin/nomenclature_changes/status_to_accepted/primary_output.html.erb index 89b17ccef7..8124ffa488 100644 --- a/app/views/admin/nomenclature_changes/status_to_accepted/primary_output.html.erb +++ b/app/views/admin/nomenclature_changes/status_to_accepted/primary_output.html.erb @@ -2,17 +2,18 @@ <%= nomenclature_change_form do |f| %> <%= render 'admin/nomenclature_changes/build/event_selector', :f => f %> <%= f.fields_for :primary_output do |ff| %> -
- -
- <%= ff.text_field :taxon_concept_id, { - :class => 'taxon-concept status-change', - :'data-name' => ff.object.taxon_concept.try(:full_name), - :'data-name-status' => ff.object.taxon_concept.try(:name_status), - :'data-name-status-filter' => ['N', 'S', 'T'].to_json, - :'data-taxonomy-id' => @taxonomy.id - } %> +
+ +
+ <%= ff.text_field :taxon_concept_id, { + :class => 'taxon-concept status-change', + :'data-name' => ff.object.taxon_concept.try(:full_name), + :'data-name-status' => ff.object.taxon_concept.try(:name_status), + :'data-name-status-filter' => ['N', 'S', 'T'].to_json, + :'data-taxonomy-id' => @taxonomy.id + } %> +
-
+ <%= render 'admin/nomenclature_changes/build/new_parent', :ff => ff %> <% end %> <% end %> \ No newline at end of file diff --git a/spec/controllers/admin/nomenclature_changes/status_to_accepted_controller_spec.rb b/spec/controllers/admin/nomenclature_changes/status_to_accepted_controller_spec.rb index 06c7148870..eaee5a3eac 100644 --- a/spec/controllers/admin/nomenclature_changes/status_to_accepted_controller_spec.rb +++ b/spec/controllers/admin/nomenclature_changes/status_to_accepted_controller_spec.rb @@ -14,15 +14,6 @@ response.should render_template('primary_output') end end - context :parent do - before(:each) do - @status_change = s_to_a_with_input - end - it 'renders the parent template' do - get :show, id: :parent, nomenclature_change_id: @status_change.id - response.should render_template('parent') - end - end context :summary do before(:each) do @status_change = s_to_a_with_input @@ -56,7 +47,7 @@ } }, nomenclature_change_id: @status_change.id, id: 'primary_output' response.should redirect_to(admin_nomenclature_change_status_to_accepted_url( - nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'parent' + nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'summary' )) end end From a9e2a3f3c1c1662e980034bd70248250ea989918 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Thu, 17 Mar 2016 11:25:17 +0000 Subject: [PATCH 100/365] Add N name option in Add new Taxon Concept button --- .../admin/taxon_concepts_controller.rb | 8 ++-- app/helpers/taxon_concept_helper.rb | 10 +++++ .../taxon_concepts/_n_name_form.html.erb | 44 +++++++++++++++++++ app/views/admin/taxon_concepts/index.html.erb | 1 + 4 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 app/views/admin/taxon_concepts/_n_name_form.html.erb diff --git a/app/controllers/admin/taxon_concepts_controller.rb b/app/controllers/admin/taxon_concepts_controller.rb index 37c526a3d6..6ea28b8686 100644 --- a/app/controllers/admin/taxon_concepts_controller.rb +++ b/app/controllers/admin/taxon_concepts_controller.rb @@ -7,12 +7,14 @@ class Admin::TaxonConceptsController < Admin::StandardAuthorizationController def index @taxonomies = Taxonomy.order(:name) @ranks = Rank.order(:taxonomic_position) - @taxon_concept = TaxonConcept.new(:name_status => 'A') + @taxon_concept = TaxonConcept.new(name_status: 'A') @taxon_concept.build_taxon_name - @synonym = TaxonConcept.new(:name_status => 'S') + @synonym = TaxonConcept.new(name_status: 'S') @synonym.build_taxon_name - @hybrid = TaxonConcept.new(:name_status => 'H') + @hybrid = TaxonConcept.new(name_status: 'H') @hybrid.build_taxon_name + @n_name = TaxonConcept.new(name_status: 'N') + @n_name.build_taxon_name @taxon_concepts = TaxonConceptMatcher.new(@search_params).taxon_concepts. includes([:rank, :taxonomy, :taxon_name, :parent]). order("taxon_concepts.taxonomic_position").page(params[:page]) diff --git a/app/helpers/taxon_concept_helper.rb b/app/helpers/taxon_concept_helper.rb index 5bc80f79f7..0c5d32c0c6 100644 --- a/app/helpers/taxon_concept_helper.rb +++ b/app/helpers/taxon_concept_helper.rb @@ -27,6 +27,9 @@ def admin_add_new_taxon_concept_multi end + content_tag(:li) do link_to('Hybrid', '#new-taxon_concept_hybrid', :"data-toggle" => 'modal') + end + + content_tag(:li) do + link_to('N name', '#new-taxon_concept_n_name', :"data-toggle" => 'modal') end end end @@ -123,6 +126,13 @@ def admin_new_hybrid_modal(nested = false) ){ nested ? '' : render('hybrid_form') } end + def admin_new_n_name_modal + admin_new_modal( + resource: 'taxon_concept_n_name', + title: 'Add new N name' + ){ render('n_name_form') } + end + def admin_add_new_reference_button admin_add_new_button( :resource => 'taxon_concept_reference', diff --git a/app/views/admin/taxon_concepts/_n_name_form.html.erb b/app/views/admin/taxon_concepts/_n_name_form.html.erb new file mode 100644 index 0000000000..59ffac79ee --- /dev/null +++ b/app/views/admin/taxon_concepts/_n_name_form.html.erb @@ -0,0 +1,44 @@ +<%= form_for [:admin, @n_name], :remote => true do |f| %> + + <%= error_messages_for(@taxon_concept) %> + <%= f.hidden_field :name_status %> +
+ + <%= f.select :taxonomy_id, + options_from_collection_for_select(@taxonomies, :id, :name, @taxon_concept && @taxon_concept.taxonomy_id) + %> +
+
+ + <%= f.select :rank_id, + options_from_collection_for_select(@ranks, :id, :name, @taxon_concept && @taxon_concept.rank_id) + %> +
+ <%= name_status_related_fields(f, @taxon_concept.name_status) %> +
+ + <%= f.text_field :full_name %> +
+
+ + <%= f.select :tag_list, + options_from_collection_for_select( + @tags, + :name, + :name, + @taxon_concept.tag_list + ), {}, + { :multiple => true, :class => 'tags', :style => "width: 220px"} + %> +
+
+ + <%= f.text_field :author_year %> +
+ <%= render :partial => 'admin/shared/nomenclature_notes_form', + locals: { + f: f, + locale_columns: TaxonConcept.locale_columns(:nomenclature_note) + } + %> +<% end %> diff --git a/app/views/admin/taxon_concepts/index.html.erb b/app/views/admin/taxon_concepts/index.html.erb index 2202b92c03..e5a61fdbce 100644 --- a/app/views/admin/taxon_concepts/index.html.erb +++ b/app/views/admin/taxon_concepts/index.html.erb @@ -3,6 +3,7 @@ <%= admin_new_modal %> <%= admin_new_synonym_modal %> <%= admin_new_hybrid_modal %> +<%= admin_new_n_name_modal %> <%= render :partial => 'search' %> From b8659ebc5b98a7e3d95ce54ec5df544c1cf5f969 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Thu, 17 Mar 2016 12:13:35 +0000 Subject: [PATCH 101/365] N name to get full scientific name from form --- app/models/taxon_concept.rb | 10 +++++++--- app/views/admin/taxon_concepts/_n_name_form.html.erb | 10 +++++----- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index 895377a03e..f45806a9eb 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -272,6 +272,10 @@ def has_accepted_names? inverse_synonym_relationships.limit(1).count > 0 end + def is_accepted_name? + name_status == 'A' + end + def is_synonym? name_status == 'S' end @@ -473,10 +477,10 @@ def parent_at_immediately_higher_rank def check_taxon_name_exists self.full_name = TaxonConcept.sanitize_full_name(full_name) - scientific_name = if is_synonym? || is_trade_name? || is_hybrid? - full_name - else + scientific_name = if is_accepted_name? TaxonName.sanitize_scientific_name(self.full_name) + else + full_name end tn = taxon_name && TaxonName.where(["UPPER(scientific_name) = UPPER(?)", scientific_name]).first diff --git a/app/views/admin/taxon_concepts/_n_name_form.html.erb b/app/views/admin/taxon_concepts/_n_name_form.html.erb index 59ffac79ee..684f21cf4e 100644 --- a/app/views/admin/taxon_concepts/_n_name_form.html.erb +++ b/app/views/admin/taxon_concepts/_n_name_form.html.erb @@ -1,20 +1,20 @@ <%= form_for [:admin, @n_name], :remote => true do |f| %> - <%= error_messages_for(@taxon_concept) %> + <%= error_messages_for(@n_name) %> <%= f.hidden_field :name_status %>
<%= f.select :taxonomy_id, - options_from_collection_for_select(@taxonomies, :id, :name, @taxon_concept && @taxon_concept.taxonomy_id) + options_from_collection_for_select(@taxonomies, :id, :name, @n_name && @n_name.taxonomy_id) %>
<%= f.select :rank_id, - options_from_collection_for_select(@ranks, :id, :name, @taxon_concept && @taxon_concept.rank_id) + options_from_collection_for_select(@ranks, :id, :name, @n_name && @n_name.rank_id) %>
- <%= name_status_related_fields(f, @taxon_concept.name_status) %> + <%= name_status_related_fields(f, @n_name.name_status) %>
<%= f.text_field :full_name %> @@ -26,7 +26,7 @@ @tags, :name, :name, - @taxon_concept.tag_list + @n_name.tag_list ), {}, { :multiple => true, :class => 'tags', :style => "width: 220px"} %> From 6b7b613b1bea3a3e7c4e870d9f5636bc1eea9dc5 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 17 Mar 2016 13:58:09 +0000 Subject: [PATCH 102/365] removed ability to have N taxa as lump inputs --- app/views/admin/nomenclature_changes/lump/inputs.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/admin/nomenclature_changes/lump/inputs.html.erb b/app/views/admin/nomenclature_changes/lump/inputs.html.erb index 62186cde46..a281e2a9be 100644 --- a/app/views/admin/nomenclature_changes/lump/inputs.html.erb +++ b/app/views/admin/nomenclature_changes/lump/inputs.html.erb @@ -11,7 +11,7 @@ :class => 'taxon-concept', :'data-name' => ff.object.taxon_concept.try(:full_name), :'data-name-status' => ff.object.taxon_concept.try(:name_status), - :'data-name-status-filter' => ['A', 'N'].to_json, + :'data-name-status-filter' => ['A'].to_json, :'data-taxonomy-id' => @taxonomy.id } %> <%= ff.link_to_remove 'Remove input' %> From f61920eced2a251bfdf86fbf3ecef5c7d16b72d6 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 17 Mar 2016 14:06:17 +0000 Subject: [PATCH 103/365] added parent selector to split, lump and swap outputs forms --- .../build/_new_parent.html.erb | 2 +- .../nomenclature_changes/lump/outputs.html.erb | 15 +-------------- .../nomenclature_changes/split/outputs.html.erb | 13 +------------ .../status_swap/primary_output.html.erb | 1 + 4 files changed, 4 insertions(+), 27 deletions(-) diff --git a/app/views/admin/nomenclature_changes/build/_new_parent.html.erb b/app/views/admin/nomenclature_changes/build/_new_parent.html.erb index b807b88787..aa3cac264e 100644 --- a/app/views/admin/nomenclature_changes/build/_new_parent.html.erb +++ b/app/views/admin/nomenclature_changes/build/_new_parent.html.erb @@ -2,7 +2,7 @@
<%= ff.text_field :new_parent_id, { - :class => 'taxon-concept parent-taxon', + class: 'taxon-concept parent-taxon', :'data-name' => ff.object.new_parent.try(:full_name), :'data-name-status' => ff.object.new_parent.try(:name_status), :'data-name-status-filter' => ['A'].to_json, diff --git a/app/views/admin/nomenclature_changes/lump/outputs.html.erb b/app/views/admin/nomenclature_changes/lump/outputs.html.erb index 10c5cbb18c..086f44f9fc 100644 --- a/app/views/admin/nomenclature_changes/lump/outputs.html.erb +++ b/app/views/admin/nomenclature_changes/lump/outputs.html.erb @@ -26,21 +26,8 @@ } %>
- + <%= render 'admin/nomenclature_changes/build/new_parent', :ff => ff %>
-
- -
- - <%= ff.text_field :new_parent_id, { - :class => 'taxon-concept parent-taxon', - :'data-name' => ff.object.new_parent.try(:full_name), - :'data-name-status' => ff.object.new_parent.try(:name_status), - :'data-name-status-filter' => ['A'].to_json, - :'data-taxonomy-id' => @taxonomy.id - } %> -
-
diff --git a/app/views/admin/nomenclature_changes/split/outputs.html.erb b/app/views/admin/nomenclature_changes/split/outputs.html.erb index 8b1a4538ad..d32ba7a2dd 100644 --- a/app/views/admin/nomenclature_changes/split/outputs.html.erb +++ b/app/views/admin/nomenclature_changes/split/outputs.html.erb @@ -21,19 +21,8 @@ } %>
+ <%= render 'admin/nomenclature_changes/build/new_parent', :ff => ff %>
-
- -
- <%= ff.text_field :new_parent_id, { - :class => 'taxon-concept parent-taxon', - :'data-name' => ff.object.new_parent.try(:full_name), - :'data-name-status' => ff.object.new_parent.try(:name_status), - :'data-name-status-filter' => ['A'].to_json, - :'data-taxonomy-id' => @taxonomy.id - } %> -
-
diff --git a/app/views/admin/nomenclature_changes/status_swap/primary_output.html.erb b/app/views/admin/nomenclature_changes/status_swap/primary_output.html.erb index 5f2cc29a01..d0162f8517 100644 --- a/app/views/admin/nomenclature_changes/status_swap/primary_output.html.erb +++ b/app/views/admin/nomenclature_changes/status_swap/primary_output.html.erb @@ -21,6 +21,7 @@ ff.object.new_name_status) %>
+ <%= render 'admin/nomenclature_changes/build/new_parent', :ff => ff %> <% end %> <% end %> \ No newline at end of file From 98afd54660d803984ce98351a7553029008d6459 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 17 Mar 2016 14:08:32 +0000 Subject: [PATCH 104/365] simplified handling of output type radio buttons --- .../admin/nomenclature_changes.js.coffee | 26 +++++++++---------- .../admin/nomenclature_changes_helper.rb | 21 ++++++++++++--- app/models/nomenclature_change/output.rb | 5 +++- 3 files changed, 34 insertions(+), 18 deletions(-) diff --git a/app/assets/javascripts/admin/nomenclature_changes.js.coffee b/app/assets/javascripts/admin/nomenclature_changes.js.coffee index 04b256ea1a..84f24fa4a2 100644 --- a/app/assets/javascripts/admin/nomenclature_changes.js.coffee +++ b/app/assets/javascripts/admin/nomenclature_changes.js.coffee @@ -126,11 +126,11 @@ $(document).ready -> $('form').on('click', '.output-radio', (e) -> value = $(this).val() switch value - when "New taxon" + when "new_taxon" NewTaxonForm(this) - when "Existing taxon" + when "existing_taxon" ExistingTaxonForm(this) - when "Existing subspecies" + when "existing_subspecies" UpgradedTaxonForm(this) ) @@ -145,6 +145,9 @@ $(document).ready -> input_taxon.show() input_taxon.closest('.control-group').find('label').show() + ShowUpgradeInfo = (obj) -> + $(obj).closest('.fields').find('.upgrade-info').first().show() + HideUpgradeInfo = (obj) -> upgrade_info = $(obj).closest('.fields').find('.upgrade-info') upgrade_info.first().hide() @@ -153,7 +156,7 @@ $(document).ready -> NewTaxonForm = (obj) -> HideInputTaxon(obj) - $(obj).closest('.fields').find('.upgrade-info').first().show() + ShowUpgradeInfo(obj) ExistingTaxonForm = (obj) -> ShowInputTaxon(obj) @@ -161,25 +164,20 @@ $(document).ready -> UpgradedTaxonForm = (obj) -> ShowInputTaxon(obj) - $(obj).closest('.fields').find('.upgrade-info').first().show() + ShowUpgradeInfo(obj) DefaultExistingTaxon = (obj) -> - $(obj).find('.output-radio[value="Existing taxon"]').attr("checked","checked") + $(obj).find('.output-radio[value="existing_taxon"]').attr("checked","checked") ExistingTaxonForm(obj) OutputsDefaultConfiguration = -> $('.fields').each (index) -> - taxon_concept = $(this).find('input.input-taxon') - parent = $(this).find('input.parent-taxon') - - if typeof taxon_concept.attr("data-name") == 'undefined' - $(this).find('.output-radio[value="New taxon"]').attr("checked","checked") + outputType = $(this).find('input[type=radio]:checked') + if outputType.val() == 'new_taxon' NewTaxonForm(this) - else if typeof parent.attr("data-name") == 'undefined' - $(this).find('.output-radio[value="Existing taxon"]').attr("checked","checked") + else if outputType.val() == 'existing_taxon' ExistingTaxonForm(this) else - $(this).find('.output-radio[value="Existing subspecies"]').attr("checked","checked") UpgradedTaxonForm(this) OutputsDefaultConfiguration() diff --git a/app/helpers/admin/nomenclature_changes_helper.rb b/app/helpers/admin/nomenclature_changes_helper.rb index 1096167a60..b821758476 100644 --- a/app/helpers/admin/nomenclature_changes_helper.rb +++ b/app/helpers/admin/nomenclature_changes_helper.rb @@ -141,11 +141,26 @@ def global_selection(checked = true) end def outputs_selection ff + ff.object.output_type ||= if ff.object.taxon_concept_id.nil? + 'new_taxon' + elsif ff.object.taxon_concept && + !ff.object.new_scientific_name.blank? && + ff.object.taxon_concept.full_name != ff.object.new_scientific_name + # this scenario occurrs when an existing taxon will change name + 'existing_subspecies' + else + 'existing_taxon' + end content_tag(:div, class: 'outputs_selection') do - [ 'New taxon', 'Existing subspecies', 'Existing taxon'].each do |opt| + ['New taxon', 'Existing subspecies', 'Existing taxon'].each do |opt| + opt_val = opt.downcase.gsub(/\s+/, '_') concat content_tag(:span, - radio_button_tag(ff.object.taxon_concept.try(:full_name) || 'output'+ff.options[:child_index].to_s, - opt, false, class: 'output-radio') + ' ' + opt) + ff.radio_button( + :output_type, + opt_val, + {class: 'output-radio'} + ) + ' ' + opt + ) end concat ff.link_to_remove 'Remove output' end diff --git a/app/models/nomenclature_change/output.rb b/app/models/nomenclature_change/output.rb index 28d466ea6f..ffe329cada 100644 --- a/app/models/nomenclature_change/output.rb +++ b/app/models/nomenclature_change/output.rb @@ -33,12 +33,15 @@ class NomenclatureChange::Output < ActiveRecord::Base include PgArrayParser track_who_does_it + attr_accessor :output_type # New taxon, Existing subspecies, Existing taxon attr_accessible :nomenclature_change_id, :taxon_concept_id, :new_taxon_concept_id, :rank_id, :new_scientific_name, :new_author_year, :new_name_status, :new_parent_id, :new_rank_id, :taxonomy_id, :accepted_taxon_ids, :note_en, :note_es, :note_fr, :internal_note, :is_primary_output, :parent_reassignments_attributes, :name_reassignments_attributes, - :distribution_reassignments_attributes, :legislation_reassignments_attributes, :hybrid_parent_id, :other_hybrid_parent_id, :tag_list + :distribution_reassignments_attributes, :legislation_reassignments_attributes, + :hybrid_parent_id, :other_hybrid_parent_id, :tag_list, + :output_type belongs_to :nomenclature_change belongs_to :taxon_concept From 66c52a5c33da23da6fa138fc65c2693a9fbb272f Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Tue, 15 Mar 2016 22:02:05 +0000 Subject: [PATCH 105/365] Remove new name button from interface --- app/views/admin/nomenclature_changes/index.html.erb | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/app/views/admin/nomenclature_changes/index.html.erb b/app/views/admin/nomenclature_changes/index.html.erb index b8797d931d..4dbba7a461 100644 --- a/app/views/admin/nomenclature_changes/index.html.erb +++ b/app/views/admin/nomenclature_changes/index.html.erb @@ -5,17 +5,6 @@ To make editorial changes to taxon concept properties (such as correcting misspellings) please use the edit function on a taxon concept's page.

- - - - From 073fec6230724f0f8968a4bed19605d4a2d7df7e Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Tue, 15 Mar 2016 22:07:26 +0000 Subject: [PATCH 106/365] Remove new name related files --- .../new_name_controller.rb | 92 ---------- app/models/nomenclature_change/new_name.rb | 91 ---------- .../new_name/constructor.rb | 46 ----- .../nomenclature_change/new_name/processor.rb | 20 --- .../new_name/accepted_names.html.erb | 22 --- .../new_name/author_year.html.erb | 19 -- .../new_name/hybrid_parents.html.erb | 33 ---- .../new_name/name_status.html.erb | 20 --- .../new_name/nomenclature_notes.html.erb | 22 --- .../new_name/parent.html.erb | 21 --- .../new_name/rank.html.erb | 20 --- .../new_name/scientific_name.html.erb | 22 --- .../new_name/summary.html.erb | 3 - .../new_name/taxonomy.html.erb | 19 -- .../new_name_controller_spec.rb | 168 ------------------ 15 files changed, 618 deletions(-) delete mode 100644 app/controllers/admin/nomenclature_changes/new_name_controller.rb delete mode 100644 app/models/nomenclature_change/new_name.rb delete mode 100644 app/models/nomenclature_change/new_name/constructor.rb delete mode 100644 app/models/nomenclature_change/new_name/processor.rb delete mode 100644 app/views/admin/nomenclature_changes/new_name/accepted_names.html.erb delete mode 100644 app/views/admin/nomenclature_changes/new_name/author_year.html.erb delete mode 100644 app/views/admin/nomenclature_changes/new_name/hybrid_parents.html.erb delete mode 100644 app/views/admin/nomenclature_changes/new_name/name_status.html.erb delete mode 100644 app/views/admin/nomenclature_changes/new_name/nomenclature_notes.html.erb delete mode 100644 app/views/admin/nomenclature_changes/new_name/parent.html.erb delete mode 100644 app/views/admin/nomenclature_changes/new_name/rank.html.erb delete mode 100644 app/views/admin/nomenclature_changes/new_name/scientific_name.html.erb delete mode 100644 app/views/admin/nomenclature_changes/new_name/summary.html.erb delete mode 100644 app/views/admin/nomenclature_changes/new_name/taxonomy.html.erb delete mode 100644 spec/controllers/admin/nomenclature_changes/new_name_controller_spec.rb diff --git a/app/controllers/admin/nomenclature_changes/new_name_controller.rb b/app/controllers/admin/nomenclature_changes/new_name_controller.rb deleted file mode 100644 index f1e41fd95f..0000000000 --- a/app/controllers/admin/nomenclature_changes/new_name_controller.rb +++ /dev/null @@ -1,92 +0,0 @@ -class Admin::NomenclatureChanges::NewNameController < Admin::NomenclatureChanges::BuildController - - steps *NomenclatureChange::NewName::STEPS - - before_filter :set_name_status, only: [:show] - - def show - builder = NomenclatureChange::NewName::Constructor.new(@nomenclature_change) - case step - when :name_status - set_events - builder.build_output - when :parent - set_new_name_taxonomy - skip_or_previous_step if @name_status != 'A' - when :accepted_names - set_new_name_taxonomy - skip_or_previous_step if @name_status != 'S' - when :hybrid_parents - set_new_name_taxonomy - skip_or_previous_step if @name_status != 'H' - when :nomenclature_notes - builder.build_output_notes - load_tags - when :summary - processor = NomenclatureChange::NewName::Processor.new(@nomenclature_change) - @summary = processor.summary - end - render_wizard - end - - def update - @nomenclature_change.assign_attributes( - (params[:nomenclature_change_new_name] || {}).merge({ - :status => (step == steps.last ? NomenclatureChange::SUBMITTED : step.to_s) - }) - ) - - success = @nomenclature_change.valid? - - case step - when :name_status - set_events unless success - when :rank - case @nomenclature_change.output.new_name_status - when 'S' then jump_to(:accepted_names) - when 'H' then jump_to(:hybrid_parents) - end - when :parent, :accepted_names, :hybrid_parents - set_new_name_taxonomy - end - - render_wizard @nomenclature_change - end - - private - def klass - NomenclatureChange::NewName - end - - def set_name_status - @name_status = '' - if @nomenclature_change.output and - [:parent, :accepted_names, :hybrid_parents].include?(step) - @name_status = @nomenclature_change.output.new_name_status - end - end - - def set_new_name_taxonomy - @taxonomy = Taxonomy.find(@nomenclature_change.output.taxonomy_id) - end - - def skip_or_previous_step - if params[:back] - if step == :accepted_names || step == :parent - jump_to(:rank) - elsif step == :hybrid_parents - case @nomenclature_change.output.new_name_status - when 'A' then jump_to(:parent) - when 'S' then jump_to(:accepted_names) - end - end - else - skip_step - end - end - - def load_tags - @tags = PresetTag.where(:model => PresetTag::TYPES[:TaxonConcept]) - end - -end diff --git a/app/models/nomenclature_change/new_name.rb b/app/models/nomenclature_change/new_name.rb deleted file mode 100644 index e209e5d0be..0000000000 --- a/app/models/nomenclature_change/new_name.rb +++ /dev/null @@ -1,91 +0,0 @@ -# event_id :integer -# type :string(255) not null -# status :string(255) not null -# created_by_id :integer not null -# updated_by_id :integer not null -# created_at :datetime not null -# updated_at :datetime not null - -class NomenclatureChange::NewName < NomenclatureChange - build_steps(:name_status, :taxonomy, :rank, :parent, :accepted_names, - :hybrid_parents, :scientific_name, :author_year, - :nomenclature_notes, :summary) - attr_accessible :output_attributes - - has_one :output, :inverse_of => :nomenclature_change, - :class_name => NomenclatureChange::Output, - :foreign_key => :nomenclature_change_id, - :dependent => :destroy - - accepts_nested_attributes_for :output, :allow_destroy => true - - validates :status, inclusion: { - in: self.status_dict, - message: "%{value} is not a valid status" - } - validate :required_different_name, if: :scientific_name_step? - validate :parent_at_immediately_higher_rank, if: :parent_step? - validate :required_accepted_names, if: :accepted_names_step? - validate :required_hybrids, if: :hybrid_parents_step? - - def scientific_name_step? - status == 'scientific_name' - end - - def parent_step? - status == 'parent' - end - - def accepted_names_step? - status == 'accepted_names' - end - - def hybrid_parents_step? - status == 'hybrid_parents' - end - - def required_accepted_names - if output.present? - unless output.accepted_taxon_ids.present? - errors.add(:outputs, "at least an accepted name is required") - return false - end - end - end - - def required_hybrids - if output.present? - unless output.hybrid_parent_id && output.other_hybrid_parent_id - errors.add(:outputs, "Hybrid parents are required") - return false; - end - end - end - - def required_different_name - if output.present? - if output.new_full_name.nil? - errors.add(:outputs, "Scientific name is required") - return false - elsif output.taxon_name_already_existing? && - !output.new_full_name.nil? - errors.add(:outputs, "Name already existing") - return false - end - end - end - - def new_output_parent - nil - end - - def parent_at_immediately_higher_rank - return true if (output.new_parent.rank.name == 'KINGDOM' && output.new_parent.full_name == 'Plantae' && output.new_rank.name == 'ORDER') - unless output.new_parent.rank.taxonomic_position >= output.new_rank.parent_rank_lower_bound && - output.new_parent.rank.taxonomic_position < output.new_rank.taxonomic_position - errors.add(:new_parent_id, "must be at immediately higher rank") - return false - end - end - -end diff --git a/app/models/nomenclature_change/new_name/constructor.rb b/app/models/nomenclature_change/new_name/constructor.rb deleted file mode 100644 index 7f0a69954b..0000000000 --- a/app/models/nomenclature_change/new_name/constructor.rb +++ /dev/null @@ -1,46 +0,0 @@ -class NomenclatureChange::NewName::Constructor - include NomenclatureChange::ConstructorHelpers - - def initialize(nomenclature_change) - @nomenclature_change = nomenclature_change - end - - def build_output - @nomenclature_change.build_output if @nomenclature_change.output.nil? - end - - def multi_lingual_output_note(output, event) - result = {} - [:en, :es, :fr].each do |lng| - note = '

' - note << new_name_note(output, lng) - note << following_taxonomic_changes(event, lng) if event - note << '.

' - result[lng] = note - end - result - end - - def build_output_notes - output = @nomenclature_change.output - event = @nomenclature_change.event - if output.note_en.blank? - note = multi_lingual_output_note(output, event) - output.note_en = note[:en] - output.note_es = note[:es] - output.note_fr = note[:fr] - end - end - - def new_name_note(output, lng) - output_html = taxon_concept_html(output.display_full_name, output.display_rank_name) - I18n.with_locale(lng) do - I18n.translate( - 'new_name.new_name_note', - output_taxon: output_html, - year: Date.current.year, - default: 'Translation missing' - ) - end - end -end diff --git a/app/models/nomenclature_change/new_name/processor.rb b/app/models/nomenclature_change/new_name/processor.rb deleted file mode 100644 index 5b110d4f4d..0000000000 --- a/app/models/nomenclature_change/new_name/processor.rb +++ /dev/null @@ -1,20 +0,0 @@ -class NomenclatureChange::NewName::Processor < NomenclatureChange::Processor - - def summary - result = [] - @subprocessors.each{ |processor| result << processor.summary } - result.flatten(1) - end - - private - - def prepare_chain - chain = [] - chain << NomenclatureChange::OutputTaxonConceptProcessor.new(@output) - end - - def initialize_inputs_and_outputs - @output = @nc.output - end - -end diff --git a/app/views/admin/nomenclature_changes/new_name/accepted_names.html.erb b/app/views/admin/nomenclature_changes/new_name/accepted_names.html.erb deleted file mode 100644 index 4821be22d5..0000000000 --- a/app/views/admin/nomenclature_changes/new_name/accepted_names.html.erb +++ /dev/null @@ -1,22 +0,0 @@ -

New name: accepted names

-

- - Assign accepted names -

-<%= nomenclature_change_form do |f| %> -
- <%= f.fields_for :output do |ff| %> - -
- <%= ff.text_field :accepted_taxon_ids, { - :class => 'taxon-concept-multiple', - :'data-name' => TaxonConcept.fetch_taxons_full_name(ff.object.accepted_taxon_ids).to_s, - :'data-name-status' => 'A', - :'data-name-status-filter' => ['A'].to_json, - :'data-taxonomy-id' => @taxonomy.id, - :multiple => 'multiple' - } %> -
- <% end %> -
-<% end %> diff --git a/app/views/admin/nomenclature_changes/new_name/author_year.html.erb b/app/views/admin/nomenclature_changes/new_name/author_year.html.erb deleted file mode 100644 index a928478003..0000000000 --- a/app/views/admin/nomenclature_changes/new_name/author_year.html.erb +++ /dev/null @@ -1,19 +0,0 @@ -

New name: author-year

-

- - Assign author-year -

-<%= nomenclature_change_form do |f| %> - -
- <%= f.fields_for :output do |ff| %> - -
- <%= ff.text_field :new_author_year, { - :class => 'new-author-year' - } %> -
- <% end %> -
- -<% end %> \ No newline at end of file diff --git a/app/views/admin/nomenclature_changes/new_name/hybrid_parents.html.erb b/app/views/admin/nomenclature_changes/new_name/hybrid_parents.html.erb deleted file mode 100644 index 1d906524ac..0000000000 --- a/app/views/admin/nomenclature_changes/new_name/hybrid_parents.html.erb +++ /dev/null @@ -1,33 +0,0 @@ -

New name: hybrid parents

-

- - Assign hybrid parents -

-<%= nomenclature_change_form do |f| %> - <%= f.fields_for :output do |ff| %> -
- -
- <%= ff.text_field :hybrid_parent_id, { - :class => 'taxon-concept', - :'data-name' => ff.object.hybrid_parent.try(:full_name), - :'data-name-status' => ff.object.hybrid_parent.try(:name_status), - :'data-name-status-filter' => ['A'].to_json, - :'data-taxonomy-id' => @taxonomy.id - } %> -
-
-
- -
- <%= ff.text_field :other_hybrid_parent_id, { - :class => 'taxon-concept', - :'data-name' => ff.object.other_hybrid_parent.try(:full_name), - :'data-name-status' => ff.object.other_hybrid_parent.try(:name_status), - :'data-name-status-filter' => ['A'].to_json, - :'data-taxonomy-id' => @taxonomy.id - } %> -
-
- <% end %> -<% end %> diff --git a/app/views/admin/nomenclature_changes/new_name/name_status.html.erb b/app/views/admin/nomenclature_changes/new_name/name_status.html.erb deleted file mode 100644 index 4466b59c48..0000000000 --- a/app/views/admin/nomenclature_changes/new_name/name_status.html.erb +++ /dev/null @@ -1,20 +0,0 @@ -

New name: name status

-

- - Assign name status -

-<%= nomenclature_change_form do |f| %> - <%= render 'admin/nomenclature_changes/build/event_selector', :f => f %> -
- <%= f.fields_for :output do |ff| %> - -
- <%= ff.select :new_name_status, - options_for_select(['A', 'S', 'H'], - ff.object.new_name_status), - {} - %> -
- <% end %> -
-<% end %> diff --git a/app/views/admin/nomenclature_changes/new_name/nomenclature_notes.html.erb b/app/views/admin/nomenclature_changes/new_name/nomenclature_notes.html.erb deleted file mode 100644 index 631b16b740..0000000000 --- a/app/views/admin/nomenclature_changes/new_name/nomenclature_notes.html.erb +++ /dev/null @@ -1,22 +0,0 @@ -

New name: nomenclature change notes

-<%= nomenclature_change_form do |f| %> - <%= f.fields_for :output do |ff| %> -
- -
- <%= ff.select :tag_list, - options_from_collection_for_select( - @tags, - :name, - :name, - ff.object.tag_list - ), {}, - { :multiple => true, :class => 'tags', :style => "width: 220px"} - %> -
-
- <%= render partial: 'admin/nomenclature_changes/build/nomenclature_notes', - locals: {ff: ff} - %> - <% end %> -<% end %> diff --git a/app/views/admin/nomenclature_changes/new_name/parent.html.erb b/app/views/admin/nomenclature_changes/new_name/parent.html.erb deleted file mode 100644 index 5e9e5d8623..0000000000 --- a/app/views/admin/nomenclature_changes/new_name/parent.html.erb +++ /dev/null @@ -1,21 +0,0 @@ -

New name: parent

-

- - Assign parent -

-<%= nomenclature_change_form do |f| %> -
- <%= f.fields_for :output do |ff| %> - -
- <%= ff.text_field :new_parent_id, { - :class => 'taxon-concept parent-taxon', - :'data-name' => ff.object.new_parent.try(:full_name), - :'data-name-status' => ff.object.new_parent.try(:name_status), - :'data-name-status-filter' => ['A'].to_json, - :'data-taxonomy-id' => @taxonomy.id - } %> -
- <% end %> -
-<% end %> diff --git a/app/views/admin/nomenclature_changes/new_name/rank.html.erb b/app/views/admin/nomenclature_changes/new_name/rank.html.erb deleted file mode 100644 index 9da910d332..0000000000 --- a/app/views/admin/nomenclature_changes/new_name/rank.html.erb +++ /dev/null @@ -1,20 +0,0 @@ -

New name: rank

-

- - Assign rank -

-<%= nomenclature_change_form do |f| %> -
- <%= f.fields_for :output do |ff| %> - -
- <%= ff.select :new_rank_id, - options_for_select(ranks_collection, - ff.object.new_rank_id), - {} - %> -
- <% end %> -
- -<% end %> \ No newline at end of file diff --git a/app/views/admin/nomenclature_changes/new_name/scientific_name.html.erb b/app/views/admin/nomenclature_changes/new_name/scientific_name.html.erb deleted file mode 100644 index 69e04a4849..0000000000 --- a/app/views/admin/nomenclature_changes/new_name/scientific_name.html.erb +++ /dev/null @@ -1,22 +0,0 @@ -

New name: scientific name

-

- - Assign scientific name -

-<%= nomenclature_change_form do |f| %> - -
- <%= f.fields_for :output do |ff| %> - -
- <%= ff.text_field :new_scientific_name, { - :class => 'new-scientific-name' - } %> - -
- <% end %> -
- -<% end %> diff --git a/app/views/admin/nomenclature_changes/new_name/summary.html.erb b/app/views/admin/nomenclature_changes/new_name/summary.html.erb deleted file mode 100644 index 51cee6b80a..0000000000 --- a/app/views/admin/nomenclature_changes/new_name/summary.html.erb +++ /dev/null @@ -1,3 +0,0 @@ -

New name: summary

- -<%= render partial: 'admin/nomenclature_changes/build/summary' %> diff --git a/app/views/admin/nomenclature_changes/new_name/taxonomy.html.erb b/app/views/admin/nomenclature_changes/new_name/taxonomy.html.erb deleted file mode 100644 index 5052fb012c..0000000000 --- a/app/views/admin/nomenclature_changes/new_name/taxonomy.html.erb +++ /dev/null @@ -1,19 +0,0 @@ -

New name: taxonomy

-

- - Assign taxonomy -

-<%= nomenclature_change_form do |f| %> -
- <%= f.fields_for :output do |ff| %> - -
- <%= ff.select :taxonomy_id, - options_for_select([["CITES_EU",1],["CMS",2]], - ff.object.taxonomy_id), - {} - %> -
- <% end %> -
-<% end %> \ No newline at end of file diff --git a/spec/controllers/admin/nomenclature_changes/new_name_controller_spec.rb b/spec/controllers/admin/nomenclature_changes/new_name_controller_spec.rb deleted file mode 100644 index 2fe06e1718..0000000000 --- a/spec/controllers/admin/nomenclature_changes/new_name_controller_spec.rb +++ /dev/null @@ -1,168 +0,0 @@ -require 'spec_helper' - -describe Admin::NomenclatureChanges::NewNameController do - login_admin - - describe 'GET show' do - before(:each) do - @new_name = create(:nomenclature_change_new_name) - end - context :name_status do - it 'renders the name_status template' do - get :show, id: :name_status, nomenclature_change_id: @new_name.id - response.should render_template('name_status') - end - end - context :taxonomy do - it 'renders the taxonomy template' do - get :show, id: :taxonomy, nomenclature_change_id: @new_name.id - response.should render_template('taxonomy') - end - end - context :rank do - it 'renders the taxonomy template' do - get :show, id: :rank, nomenclature_change_id: @new_name.id - response.should render_template('rank') - end - end - context 'when is an accepted name' do - before(:each) do - @taxonomy = create(:taxonomy, name: "CITES_EU") - create(:nomenclature_change_output, - nomenclature_change: @new_name, - new_name_status: 'A', - taxonomy_id: @taxonomy.id - ) - end - it 'renders the parent template' do - get :show, id: :parent, nomenclature_change_id: @new_name.id - response.should render_template('parent') - end - end - context 'when is a synonym' do - before(:each) do - @taxonomy = create(:taxonomy, name: "CITES_EU") - create(:nomenclature_change_output, - nomenclature_change: @new_name, - new_name_status: 'S', - taxonomy_id: @taxonomy.id - ) - end - it 'renders the accepted_names template' do - get :show, id: :accepted_names, nomenclature_change_id: @new_name.id - response.should render_template('accepted_names') - end - end - context 'when is an hybrid' do - before(:each) do - @taxonomy = create(:taxonomy, name: "CITES_EU") - create(:nomenclature_change_output, - nomenclature_change: @new_name, - new_name_status: 'H', - taxonomy_id: @taxonomy.id - ) - end - it 'renders the hybrid_parents template' do - get :show, id: :hybrid_parents, nomenclature_change_id: @new_name.id - response.should render_template('hybrid_parents') - end - end - context :scientific_name do - it 'renders the scientific name template' do - get :show, id: :scientific_name, nomenclature_change_id: @new_name.id - response.should render_template('scientific_name') - end - end - context :summary do - before(:each) do - @taxonomy = create(:taxonomy, name: "CITES_EU") - create(:nomenclature_change_output, - nomenclature_change: @new_name, - new_name_status: 'S', - taxonomy_id: @taxonomy.id - ) - end - it 'renders the summary template' do - get :show, id: :summary, nomenclature_change_id: @new_name.id - response.should render_template('summary') - end - end - end - - describe 'POST create' do - it 'redirects to new_name wizard' do - post :create, nomenclature_change_id: 'new' - response.should redirect_to(admin_nomenclature_change_new_name_url( - nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'name_status' - )) - end - end - - describe 'PUT update' do - before(:each) do - @new_name = create(:nomenclature_change_new_name) - @taxonomy = create(:taxonomy, name: "CITES_EU") - @rank = create(:rank, name: "SUBSPECIES") - end - context 'when successful' do - it 'redirects to next step' do - put :update, nomenclature_change_new_name: { - output_attributes: { new_name_status: 'A' }, - }, nomenclature_change_id: @new_name.id, id: 'name_status' - response.should redirect_to(admin_nomenclature_change_new_name_url( - nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'taxonomy' - )) - end - end - context 'when unsuccessful' do - it 're-renders step' do - put :update, nomenclature_change_new_name: { - output_attributes: { new_scientific_name: nil } - }, nomenclature_change_id: @new_name.id, id: 'scientific_name' - response.should render_template('scientific_name') - end - end - context 'when is accepted name' do - it 'redirects to parent step' do - put :update, nomenclature_change_new_name: { - output_attributes: { - new_name_status: 'A', - taxonomy_id: @taxonomy.id, - rank_id: @rank.id - }, - }, nomenclature_change_id: @new_name.id, id: 'rank' - response.should redirect_to(admin_nomenclature_change_new_name_url( - nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'parent' - )) - end - end - context 'when is synonym' do - it 'redirects to accepted names step' do - put :update, nomenclature_change_new_name: { - output_attributes: { - new_name_status: 'S', - taxonomy_id: @taxonomy.id, - rank_id: @rank.id - }, - }, nomenclature_change_id: @new_name.id, id: 'rank' - response.should redirect_to(admin_nomenclature_change_new_name_url( - nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'accepted_names' - )) - end - end - context 'when is synonym' do - it 'redirects to hybrid parents step' do - put :update, nomenclature_change_new_name: { - output_attributes: { - new_name_status: 'H', - taxonomy_id: @taxonomy.id, - rank_id: @rank.id - }, - }, nomenclature_change_id: @new_name.id, id: 'rank' - response.should redirect_to(admin_nomenclature_change_new_name_url( - nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'hybrid_parents' - )) - end - end - end -end From 28b91b3765654fadf25eec9e7102341916720a72 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Tue, 15 Mar 2016 22:15:58 +0000 Subject: [PATCH 107/365] Remove links to new name --- app/views/admin/hybrid_relationships/_form.html.erb | 3 --- app/views/admin/synonym_relationships/_form.html.erb | 3 --- 2 files changed, 6 deletions(-) diff --git a/app/views/admin/hybrid_relationships/_form.html.erb b/app/views/admin/hybrid_relationships/_form.html.erb index 5664fb494d..fdf89e82bd 100644 --- a/app/views/admin/hybrid_relationships/_form.html.erb +++ b/app/views/admin/hybrid_relationships/_form.html.erb @@ -18,7 +18,4 @@ } %> -

- <%= link_to 'Create a new hybrid', admin_nomenclature_changes_path %> -

<% end %> diff --git a/app/views/admin/synonym_relationships/_form.html.erb b/app/views/admin/synonym_relationships/_form.html.erb index fea36ebd02..b5858acfea 100644 --- a/app/views/admin/synonym_relationships/_form.html.erb +++ b/app/views/admin/synonym_relationships/_form.html.erb @@ -18,7 +18,4 @@ } %> -

- <%= link_to 'Create a new synonym', admin_nomenclature_changes_path %> -

<% end %> From 975a3644e1beb808aea89859b165b25e691132b8 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Tue, 15 Mar 2016 22:24:29 +0000 Subject: [PATCH 108/365] Remove NewName from factories --- spec/factories/nomenclature_changes.rb | 3 --- 1 file changed, 3 deletions(-) diff --git a/spec/factories/nomenclature_changes.rb b/spec/factories/nomenclature_changes.rb index 5d5466be43..8fb57fb7e5 100644 --- a/spec/factories/nomenclature_changes.rb +++ b/spec/factories/nomenclature_changes.rb @@ -20,9 +20,6 @@ factory :nomenclature_change_status_to_synonym, class: NomenclatureChange::StatusToSynonym do type 'NomenclatureChange::StatusToSynonym' end - factory :nomenclature_change_new_name, class: NomenclatureChange::NewName do - type 'NomenclatureChange::NewName' - end end factory :nomenclature_change_input, class: NomenclatureChange::Input, From 08a52c6025b0d708758bd76777b57b978759bbb9 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Tue, 15 Mar 2016 22:32:20 +0000 Subject: [PATCH 109/365] Remove NewName bits from code --- app/helpers/admin/nomenclature_changes_helper.rb | 7 ------- app/models/nomenclature_change/output.rb | 6 +++--- .../nomenclature_change/output_taxon_concept_processor.rb | 7 ------- 3 files changed, 3 insertions(+), 17 deletions(-) diff --git a/app/helpers/admin/nomenclature_changes_helper.rb b/app/helpers/admin/nomenclature_changes_helper.rb index b821758476..d170a6ad07 100644 --- a/app/helpers/admin/nomenclature_changes_helper.rb +++ b/app/helpers/admin/nomenclature_changes_helper.rb @@ -184,17 +184,12 @@ def nomenclature_change_header when @nc.is_a?(NomenclatureChange::StatusToAccepted) content_tag(:h1, "NomenclatureChange #{@nc.id} - STATUS TO ACCEPTED", nil) + content_tag(:div, @nc.primary_output.note_en.html_safe, class: 'well well-small') - when @nc.is_a?(NomenclatureChange::NewName) - content_tag(:h1, "NomenclatureChange #{@nc.id} - NEW NAME", nil) + - content_tag(:div, @nc.output.note_en.html_safe, class: 'well well-small') end end def generate_input_content if @nc.is_a?(NomenclatureChange::Lump) lump_inputs_tags + lump_inputs_content - elsif @nc.is_a?(NomenclatureChange::NewName) - '' elsif @nc.input split_input_tag + split_input_content end @@ -317,8 +312,6 @@ def inner_content(input_or_output,tc) def select_outputs if @nc.is_a?(NomenclatureChange::Split) @nc.outputs - elsif @nc.is_a?(NomenclatureChange::NewName) - @nc.output else [@nc.primary_output, @nc.secondary_output].compact end diff --git a/app/models/nomenclature_change/output.rb b/app/models/nomenclature_change/output.rb index ffe329cada..68e341b9c6 100644 --- a/app/models/nomenclature_change/output.rb +++ b/app/models/nomenclature_change/output.rb @@ -77,11 +77,11 @@ class NomenclatureChange::Output < ActiveRecord::Base belongs_to :other_hybrid_parent, :class_name => TaxonConcept, :foreign_key => :other_hybrid_parent_id validates :nomenclature_change, :presence => true validates :new_scientific_name, :presence => true, - :if => Proc.new { |c| c.taxon_concept_id.blank? && !c.nomenclature_change.is_a?(NomenclatureChange::NewName) } + :if => Proc.new { |c| c.taxon_concept_id.blank? } validates :new_parent_id, :presence => true, - :if => Proc.new { |c| c.taxon_concept_id.blank? && !c.nomenclature_change.is_a?(NomenclatureChange::NewName) } + :if => Proc.new { |c| c.taxon_concept_id.blank? } validate :validate_tmp_taxon_concept, - :if => Proc.new { |c| (c.will_create_taxon? || c.will_update_taxon?) && !c.nomenclature_change.is_a?(NomenclatureChange::NewName) } + :if => Proc.new { |c| (c.will_create_taxon? || c.will_update_taxon?) } before_validation :populate_taxon_concept_fields, :if => Proc.new { |c| (c.new_record? || c.taxon_concept_id_changed?) && c.taxon_concept } diff --git a/app/models/nomenclature_change/output_taxon_concept_processor.rb b/app/models/nomenclature_change/output_taxon_concept_processor.rb index 80f179d037..8f3dc5c09a 100644 --- a/app/models/nomenclature_change/output_taxon_concept_processor.rb +++ b/app/models/nomenclature_change/output_taxon_concept_processor.rb @@ -30,13 +30,6 @@ def summary name_status = @output.new_name_status || @output.taxon_concept.try(:name_status) if @output.taxon_concept.blank? res << "New #{rank_name} #{full_name} (#{name_status}) will be created" - if @output.nomenclature_change.is_a?(NomenclatureChange::NewName) - case name_status - when 'A' then res << "Parent: #{@output.new_parent.full_name}" - when 'S' then res << "Accepted names: #{@output.fetch_accepted_taxons_full_name.join(',')}" - when 'H' then res << "Parents: #{@output.hybrid_parent.full_name},#{@output.other_hybrid_parent.full_name}" - end - end elsif @output.will_create_taxon? res << "New #{rank_name} #{full_name} (#{name_status}) will be created, based on #{@output.taxon_concept.full_name}" if ['A', 'N', 'H'].include? @output.taxon_concept.name_status From fb36d06a84c9d6d33368f701486cef21604a2644 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Wed, 16 Mar 2016 09:58:54 +0000 Subject: [PATCH 110/365] Remove new_name resource from routes --- config/routes.rb | 1 - 1 file changed, 1 deletion(-) diff --git a/config/routes.rb b/config/routes.rb index 19e644bfe5..e6118ec4c4 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -156,7 +156,6 @@ resources :status_to_synonym, controller: 'nomenclature_changes/status_to_synonym' resources :status_swap, controller: 'nomenclature_changes/status_swap' - resources :new_name, controller: 'nomenclature_changes/new_name' end match 'exports' => 'exports#index' match 'exports/download' => 'exports#download' From 6e5b1c092f699c45523330ed2fac1a460c4e001a Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Thu, 17 Mar 2016 15:29:01 +0000 Subject: [PATCH 111/365] Fix bug in printing out lump output --- app/helpers/admin/nomenclature_changes_helper.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/helpers/admin/nomenclature_changes_helper.rb b/app/helpers/admin/nomenclature_changes_helper.rb index d170a6ad07..18e41b4b5a 100644 --- a/app/helpers/admin/nomenclature_changes_helper.rb +++ b/app/helpers/admin/nomenclature_changes_helper.rb @@ -246,10 +246,11 @@ def lump_output_content end def lump_output_tag + tc = @nc.output.new_taxon_concept || @nc.output.taxon_concept content_tag(:ul, class: 'nav nav-tabs') do content_tag(:li, class: 'active') do - concat link_to("#{@nc.output.taxon_concept.full_name}", - "#output_#{@nc.output.taxon_concept.full_name.downcase.tr(' ', '_')}") + concat link_to("#{tc.full_name}", + "#output_#{tc.full_name.downcase.tr(' ', '_')}") end end end From b9aad2959a6e6a4b385e1a2a3ef66645edbbd0c6 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Thu, 17 Mar 2016 15:56:29 +0000 Subject: [PATCH 112/365] Remove unnecessary fields from output --- app/models/nomenclature_change/output.rb | 54 ++----------------- ...ary_new_name_related_fields_from_output.rb | 13 +++++ 2 files changed, 18 insertions(+), 49 deletions(-) create mode 100644 db/migrate/20160317154107_remove_unnecessary_new_name_related_fields_from_output.rb diff --git a/app/models/nomenclature_change/output.rb b/app/models/nomenclature_change/output.rb index 68e341b9c6..aa25db1d90 100644 --- a/app/models/nomenclature_change/output.rb +++ b/app/models/nomenclature_change/output.rb @@ -36,12 +36,10 @@ class NomenclatureChange::Output < ActiveRecord::Base attr_accessor :output_type # New taxon, Existing subspecies, Existing taxon attr_accessible :nomenclature_change_id, :taxon_concept_id, :new_taxon_concept_id, :rank_id, :new_scientific_name, :new_author_year, - :new_name_status, :new_parent_id, :new_rank_id, :taxonomy_id, :accepted_taxon_ids, + :new_name_status, :new_parent_id, :new_rank_id, :taxonomy_id, :note_en, :note_es, :note_fr, :internal_note, :is_primary_output, :parent_reassignments_attributes, :name_reassignments_attributes, - :distribution_reassignments_attributes, :legislation_reassignments_attributes, - :hybrid_parent_id, :other_hybrid_parent_id, :tag_list, - :output_type + :distribution_reassignments_attributes, :legislation_reassignments_attributes, :tag_list belongs_to :nomenclature_change belongs_to :taxon_concept @@ -73,8 +71,7 @@ class NomenclatureChange::Output < ActiveRecord::Base :foreign_key => :nomenclature_change_output_id, :dependent => :destroy belongs_to :new_parent, :class_name => TaxonConcept, :foreign_key => :new_parent_id belongs_to :new_rank, :class_name => Rank, :foreign_key => :new_rank_id - belongs_to :hybrid_parent, :class_name => TaxonConcept, :foreign_key => :hybrid_parent_id - belongs_to :other_hybrid_parent, :class_name => TaxonConcept, :foreign_key => :other_hybrid_parent_id + validates :nomenclature_change, :presence => true validates :new_scientific_name, :presence => true, :if => Proc.new { |c| c.taxon_concept_id.blank? } @@ -85,13 +82,6 @@ class NomenclatureChange::Output < ActiveRecord::Base before_validation :populate_taxon_concept_fields, :if => Proc.new { |c| (c.new_record? || c.taxon_concept_id_changed?) && c.taxon_concept } - def accepted_taxon_ids - parse_pg_array(read_attribute(:accepted_taxon_ids)||"").compact - end - - def accepted_taxon_ids=(ary) - write_attribute(:accepted_taxon_ids, "{#{ary && ary.join(',')}}") - end def tag_list parse_pg_array(read_attribute(:tag_list)||"").compact @@ -101,6 +91,7 @@ def tag_list=(ary) write_attribute(:tag_list, "{#{ary && ary.join(',')}}") end + def populate_taxon_concept_fields self.parent_id = taxon_concept.parent_id_changed? ? taxon_concept.parent_id_was : taxon_concept.parent_id self.rank_id = taxon_concept.rank_id_changed? ? taxon_concept.rank_id_was : taxon_concept.rank_id @@ -128,19 +119,6 @@ def display_rank_name try(:new_rank).try(:name) || taxon_concept.try(:rank).try(:name) end - def fetch_accepted_taxons_full_name - if accepted_taxon_ids.present? - ActiveRecord::Base.connection.execute( - <<-SQL - SELECT tc.full_name - FROM taxon_concepts tc - WHERE tc.id = ANY (ARRAY#{accepted_taxon_ids.map(&:to_i)}) - ORDER BY tc.id - SQL - ).map{ |row| row['full_name']} - end - end - # Returns true when the new taxon has a different name from old one def will_create_taxon? taxon_concept.nil? || @@ -175,11 +153,7 @@ def tmp_taxon_concept :full_name => display_full_name, :tag_list => tag_list }) - ).tap do |tc| - add_taxon_synonym(tc, accepted_taxon_ids) - add_taxon_hybrid(tc, hybrid_parent_id) - add_taxon_hybrid(tc, other_hybrid_parent_id) - end + ) elsif will_update_taxon? taxon_concept.assign_attributes(taxon_concept_attrs) taxon_concept @@ -188,24 +162,6 @@ def tmp_taxon_concept end end - def add_taxon_synonym(tc, accepted_taxon_ids) - accepted_taxon_ids.each do |accepted_taxon_id| - tc.inverse_taxon_relationships.build( - :taxon_concept_id => accepted_taxon_id, - :taxon_relationship_type_id => TaxonRelationshipType. - find_by_name(TaxonRelationshipType::HAS_SYNONYM).id - ) - end - end - - def add_taxon_hybrid(tc, other_taxon_id) - tc.inverse_taxon_relationships.build( - :taxon_concept_id => other_taxon_id, - :taxon_relationship_type_id => TaxonRelationshipType. - find_by_name(TaxonRelationshipType::HAS_HYBRID).id - ) if other_taxon_id - end - def validate_tmp_taxon_concept @tmp_taxon_concept = tmp_taxon_concept return true if @tmp_taxon_concept.valid? diff --git a/db/migrate/20160317154107_remove_unnecessary_new_name_related_fields_from_output.rb b/db/migrate/20160317154107_remove_unnecessary_new_name_related_fields_from_output.rb new file mode 100644 index 0000000000..2cb44e295f --- /dev/null +++ b/db/migrate/20160317154107_remove_unnecessary_new_name_related_fields_from_output.rb @@ -0,0 +1,13 @@ +class RemoveUnnecessaryNewNameRelatedFieldsFromOutput < ActiveRecord::Migration + def up + remove_column :nomenclature_change_outputs, :accepted_taxon_ids + remove_column :nomenclature_change_outputs, :hybrid_parent_id + remove_column :nomenclature_change_outputs, :other_hybrid_parent_id + end + + def down + add_column :nomenclature_change_outputs, :accepted_taxon_ids, "INTEGER[]" + add_column :nomenclature_change_outputs, :hybrid_parent_id, :integer + add_column :nomenclature_change_outputs, :other_hybrid_parent_id, :integer + end +end From 5b526a505065d962850aa48ef35342ea733d0aeb Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Fri, 18 Mar 2016 12:43:14 +0000 Subject: [PATCH 113/365] Fix broken create test --- spec/controllers/admin/taxon_concepts_controller_spec.rb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/spec/controllers/admin/taxon_concepts_controller_spec.rb b/spec/controllers/admin/taxon_concepts_controller_spec.rb index 3161cb4ab3..d7affd28a5 100644 --- a/spec/controllers/admin/taxon_concepts_controller_spec.rb +++ b/spec/controllers/admin/taxon_concepts_controller_spec.rb @@ -34,10 +34,15 @@ end describe "XHR POST create" do - let(:taxon_concept_attributes){ build_tc_attributes(:taxon_concept) } it "renders create when successful" do xhr :post, :create, - taxon_concept: taxon_concept_attributes + taxon_concept: { + name_status: 'A', + taxonomy_id: cites_eu.id, + rank_id: create(:rank, name: Rank::GENUS), + full_name: 'Canis', + parent_id: create_cites_eu_family, + } response.should render_template("create") end it "renders new when not successful" do From a90c8250900b893d750feaaa16ede6be2664a81f Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Fri, 18 Mar 2016 12:43:21 +0000 Subject: [PATCH 114/365] Remove unnecessary method --- spec/spec_helper.rb | 6 ------ 1 file changed, 6 deletions(-) diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 6fa5a21497..0cfc18425f 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -104,12 +104,6 @@ def build_attributes(*args) end end -def build_tc_attributes(*args) - build_attributes(*args).delete_if do |k, v| - %w(data listing notes dependents_updated_at dependents_updated_by_id).include? k - end -end - def sign_up(user, opts = {}) options = { terms_and_conditions: true From 0847b804d5564f83c58d1d5c7cc7b8d4233ecdc7 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 15 Mar 2016 12:36:29 +0000 Subject: [PATCH 115/365] removed ability to select S taxa to be turned into accepted names --- .../admin/nomenclature_changes/index.html.erb | 2 +- .../primary_output.html.erb | 21 +++++++++---------- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/app/views/admin/nomenclature_changes/index.html.erb b/app/views/admin/nomenclature_changes/index.html.erb index 4dbba7a461..c68385848a 100644 --- a/app/views/admin/nomenclature_changes/index.html.erb +++ b/app/views/admin/nomenclature_changes/index.html.erb @@ -17,7 +17,7 @@ <% end %> -
+ L_;e6I8M(w__MqMEtU(C6$*bypTiPPW8Dq(3a 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 pjj0K3Dy(}aUJ(|<04SIUX_Erz{|MrLFY-46e Date: Tue, 31 May 2016 13:43:35 +0100 Subject: [PATCH 269/365] indent access modifiers --- .rubocop.yml | 4 ++++ .rubocop_todo.yml | 7 ------- app/controllers/trade/annual_report_uploads_controller.rb | 2 +- app/controllers/trade/sandbox_shipments_controller.rb | 2 +- app/controllers/trade/shipments_controller.rb | 2 +- app/models/species/cites_listings_export.rb | 2 +- app/models/species/cms_listings_export.rb | 2 +- app/models/species/cms_mappings_export.rb | 2 +- app/models/species/common_names_export.rb | 2 +- app/models/species/documents_export.rb | 2 +- app/models/species/eu_decisions_export.rb | 2 +- app/models/species/eu_listings_export.rb | 2 +- app/models/species/iucn_mappings_export.rb | 2 +- app/models/species/listings_export.rb | 2 +- app/models/species/orphaned_taxon_concepts_export.rb | 2 +- app/models/species/search.rb | 2 +- app/models/species/species_reference_output_export.rb | 2 +- app/models/species/standard_reference_output_export.rb | 2 +- app/models/species/synonyms_and_trade_names_export.rb | 2 +- app/models/species/taxon_concepts_distributions_export.rb | 2 +- app/models/species/taxon_concepts_names_export.rb | 2 +- app/models/trade/shipments_comptab_export.rb | 2 +- app/models/trade/shipments_export.rb | 2 +- app/models/trade/shipments_gross_exports_export.rb | 2 +- app/models/trade/shipments_gross_imports_export.rb | 2 +- app/models/trade/shipments_net_exports_export.rb | 2 +- app/models/trade/shipments_net_imports_export.rb | 2 +- app/models/trade/trade_data_downloads_export.rb | 2 +- 28 files changed, 30 insertions(+), 33 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index f70e9c5f7a..264a1168b9 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -3,3 +3,7 @@ inherit_from: .rubocop_todo.yml Style/StringLiterals: EnforcedStyle: single_quotes +# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. +# SupportedStyles: outdent, indent +Style/AccessModifierIndentation: + EnforcedStyle: indent diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 0bf5428892..2f39596ea1 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -201,13 +201,6 @@ Performance/Sample: Performance/TimesMap: Enabled: false -# Offense count: 27 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. -# SupportedStyles: outdent, indent -Style/AccessModifierIndentation: - Enabled: false - # Offense count: 4 Style/AccessorMethodName: Exclude: diff --git a/app/controllers/trade/annual_report_uploads_controller.rb b/app/controllers/trade/annual_report_uploads_controller.rb index 1e1cac78fe..b4c0917189 100644 --- a/app/controllers/trade/annual_report_uploads_controller.rb +++ b/app/controllers/trade/annual_report_uploads_controller.rb @@ -45,7 +45,7 @@ def destroy end end -private + private def annual_report_upload_params params.require(:annual_report_upload).permit( diff --git a/app/controllers/trade/sandbox_shipments_controller.rb b/app/controllers/trade/sandbox_shipments_controller.rb index 193fc38989..6df78900b4 100644 --- a/app/controllers/trade/sandbox_shipments_controller.rb +++ b/app/controllers/trade/sandbox_shipments_controller.rb @@ -46,7 +46,7 @@ def destroy_batch head :no_content end -private + private def sandbox_shipment_params params.require(:sandbox_shipment).permit(*sandbox_shipment_attributes) diff --git a/app/controllers/trade/shipments_controller.rb b/app/controllers/trade/shipments_controller.rb index 3f094a9392..50aa2fefa1 100644 --- a/app/controllers/trade/shipments_controller.rb +++ b/app/controllers/trade/shipments_controller.rb @@ -58,7 +58,7 @@ def accepted_taxa_for_reported_taxon_concept :each_serializer => Trade::TaxonConceptSerializer end -private + private def shipment_attributes [ diff --git a/app/models/species/cites_listings_export.rb b/app/models/species/cites_listings_export.rb index 572e3f90f2..02335ef6f4 100644 --- a/app/models/species/cites_listings_export.rb +++ b/app/models/species/cites_listings_export.rb @@ -1,6 +1,6 @@ class Species::CitesListingsExport < Species::ListingsExport -private + private def designation_name 'cites' diff --git a/app/models/species/cms_listings_export.rb b/app/models/species/cms_listings_export.rb index 267401fb21..1a769a1707 100644 --- a/app/models/species/cms_listings_export.rb +++ b/app/models/species/cms_listings_export.rb @@ -1,6 +1,6 @@ class Species::CmsListingsExport < Species::ListingsExport -private + private def designation_name 'cms' diff --git a/app/models/species/cms_mappings_export.rb b/app/models/species/cms_mappings_export.rb index 5ec5ee4db4..73b17ad226 100644 --- a/app/models/species/cms_mappings_export.rb +++ b/app/models/species/cms_mappings_export.rb @@ -8,7 +8,7 @@ def query rel.select(sql_columns) end -private + private def resource_name 'cms_mappings' diff --git a/app/models/species/common_names_export.rb b/app/models/species/common_names_export.rb index 642ba048d7..4fe0720506 100644 --- a/app/models/species/common_names_export.rb +++ b/app/models/species/common_names_export.rb @@ -7,7 +7,7 @@ def query rel.select(sql_columns) end -private + private def resource_name 'common_names' diff --git a/app/models/species/documents_export.rb b/app/models/species/documents_export.rb index 86362825bf..c4ba2998ba 100644 --- a/app/models/species/documents_export.rb +++ b/app/models/species/documents_export.rb @@ -6,7 +6,7 @@ def query rel.select(sql_columns) end -private + private def resource_name 'documents' diff --git a/app/models/species/eu_decisions_export.rb b/app/models/species/eu_decisions_export.rb index 10cf3de6c6..6897d04a86 100644 --- a/app/models/species/eu_decisions_export.rb +++ b/app/models/species/eu_decisions_export.rb @@ -54,7 +54,7 @@ def query rel end -private + private def resource_name 'eu_decisions' diff --git a/app/models/species/eu_listings_export.rb b/app/models/species/eu_listings_export.rb index b9cd2204bc..b2ebd94df4 100644 --- a/app/models/species/eu_listings_export.rb +++ b/app/models/species/eu_listings_export.rb @@ -5,7 +5,7 @@ def initialize(designation, filters) @include_cites = filters[:include_cites] == "true" end -private + private def designation_name 'eu' diff --git a/app/models/species/iucn_mappings_export.rb b/app/models/species/iucn_mappings_export.rb index b2b72d0580..7b0cb9843a 100644 --- a/app/models/species/iucn_mappings_export.rb +++ b/app/models/species/iucn_mappings_export.rb @@ -9,7 +9,7 @@ def query rel.select(sql_columns) end -private + private def resource_name 'iucn_mappings' diff --git a/app/models/species/listings_export.rb b/app/models/species/listings_export.rb index 9cdb187c6b..f5286ae67e 100644 --- a/app/models/species/listings_export.rb +++ b/app/models/species/listings_export.rb @@ -42,7 +42,7 @@ def query rel end -private + private def resource_name "#{designation_name}_listings" diff --git a/app/models/species/orphaned_taxon_concepts_export.rb b/app/models/species/orphaned_taxon_concepts_export.rb index 064e63047c..acd20aa607 100644 --- a/app/models/species/orphaned_taxon_concepts_export.rb +++ b/app/models/species/orphaned_taxon_concepts_export.rb @@ -7,7 +7,7 @@ def query rel.select(sql_columns) end -private + private def resource_name 'orphaned_taxon_concepts' diff --git a/app/models/species/search.rb b/app/models/species/search.rb index ab76680271..9199fa60c3 100644 --- a/app/models/species/search.rb +++ b/app/models/species/search.rb @@ -25,7 +25,7 @@ def ids @query.pluck(:id) end -private + private def initialize_params(options) @options = Species::SearchParams.sanitize(options) diff --git a/app/models/species/species_reference_output_export.rb b/app/models/species/species_reference_output_export.rb index c5340b4049..e869e2e6e7 100644 --- a/app/models/species/species_reference_output_export.rb +++ b/app/models/species/species_reference_output_export.rb @@ -7,7 +7,7 @@ def query rel.select(sql_columns) end -private + private def resource_name 'species_reference_output' diff --git a/app/models/species/standard_reference_output_export.rb b/app/models/species/standard_reference_output_export.rb index ecab8ba965..89c025d561 100644 --- a/app/models/species/standard_reference_output_export.rb +++ b/app/models/species/standard_reference_output_export.rb @@ -7,7 +7,7 @@ def query rel.select(sql_columns) end -private + private def resource_name 'standard_reference_output' diff --git a/app/models/species/synonyms_and_trade_names_export.rb b/app/models/species/synonyms_and_trade_names_export.rb index f32b625cc7..379fbd9103 100644 --- a/app/models/species/synonyms_and_trade_names_export.rb +++ b/app/models/species/synonyms_and_trade_names_export.rb @@ -7,7 +7,7 @@ def query rel.select(sql_columns) end -private + private def resource_name 'synonyms_and_trade_names' diff --git a/app/models/species/taxon_concepts_distributions_export.rb b/app/models/species/taxon_concepts_distributions_export.rb index 94f834714e..141387ebcd 100644 --- a/app/models/species/taxon_concepts_distributions_export.rb +++ b/app/models/species/taxon_concepts_distributions_export.rb @@ -7,7 +7,7 @@ def query rel.select(sql_columns) end -private + private def resource_name 'taxon_concepts_distributions' diff --git a/app/models/species/taxon_concepts_names_export.rb b/app/models/species/taxon_concepts_names_export.rb index b60d8b3897..091992d587 100644 --- a/app/models/species/taxon_concepts_names_export.rb +++ b/app/models/species/taxon_concepts_names_export.rb @@ -7,7 +7,7 @@ def query rel.select(sql_columns) end -private + private def resource_name 'taxon_concepts_names' diff --git a/app/models/trade/shipments_comptab_export.rb b/app/models/trade/shipments_comptab_export.rb index f0cf4ae1af..cdec8f7737 100644 --- a/app/models/trade/shipments_comptab_export.rb +++ b/app/models/trade/shipments_comptab_export.rb @@ -9,7 +9,7 @@ def query ActiveRecord::Base.connection.execute(query_sql(:limit => true)) end -private + private def query_sql(options) headers = csv_column_headers diff --git a/app/models/trade/shipments_export.rb b/app/models/trade/shipments_export.rb index 5327294513..9045ad0a82 100644 --- a/app/models/trade/shipments_export.rb +++ b/app/models/trade/shipments_export.rb @@ -50,7 +50,7 @@ def get_resource_name resource_name end -private + private def basic_query(options) options[:limit] ? @search.query_with_limit : @search.query diff --git a/app/models/trade/shipments_gross_exports_export.rb b/app/models/trade/shipments_gross_exports_export.rb index 79aa8668ba..2f0750d954 100644 --- a/app/models/trade/shipments_gross_exports_export.rb +++ b/app/models/trade/shipments_gross_exports_export.rb @@ -7,7 +7,7 @@ def full_csv_column_headers csv_column_headers + years end -private + private def query_sql(options) headers = csv_column_headers diff --git a/app/models/trade/shipments_gross_imports_export.rb b/app/models/trade/shipments_gross_imports_export.rb index 44342c8960..e5703e30f4 100644 --- a/app/models/trade/shipments_gross_imports_export.rb +++ b/app/models/trade/shipments_gross_imports_export.rb @@ -2,7 +2,7 @@ class Trade::ShipmentsGrossImportsExport < Trade::ShipmentsGrossExportsExport include Trade::ShipmentReportQueries -private + private # the query before pivoting def subquery_sql(options) diff --git a/app/models/trade/shipments_net_exports_export.rb b/app/models/trade/shipments_net_exports_export.rb index 3e558143bd..4e649acb39 100644 --- a/app/models/trade/shipments_net_exports_export.rb +++ b/app/models/trade/shipments_net_exports_export.rb @@ -2,7 +2,7 @@ class Trade::ShipmentsNetExportsExport < Trade::ShipmentsGrossExportsExport include Trade::ShipmentReportQueries -private + private # the query before pivoting def subquery_sql(options) diff --git a/app/models/trade/shipments_net_imports_export.rb b/app/models/trade/shipments_net_imports_export.rb index bd69b1fad7..3bb299ed26 100644 --- a/app/models/trade/shipments_net_imports_export.rb +++ b/app/models/trade/shipments_net_imports_export.rb @@ -2,7 +2,7 @@ class Trade::ShipmentsNetImportsExport < Trade::ShipmentsGrossExportsExport include Trade::ShipmentReportQueries -private + private # the query before pivoting def subquery_sql(options) diff --git a/app/models/trade/trade_data_downloads_export.rb b/app/models/trade/trade_data_downloads_export.rb index 756fd2d80b..7a469652f6 100644 --- a/app/models/trade/trade_data_downloads_export.rb +++ b/app/models/trade/trade_data_downloads_export.rb @@ -4,7 +4,7 @@ def query Trade::TradeDataDownload.order(:created_at) end -private + private def resource_name 'trade_download_stats' From e402b3224b77f88d407dc1abaa7eac7caa6706a7 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 31 May 2016 13:52:19 +0100 Subject: [PATCH 270/365] temporarily silenced 2 cops --- .rubocop_todo.yml | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 2f39596ea1..029f42385d 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -349,12 +349,7 @@ Style/CommentIndentation: # Configuration parameters: EnforcedStyle, SupportedStyles, SingleLineConditionsOnly. # SupportedStyles: assign_to_condition, assign_inside_condition Style/ConditionalAssignment: - Exclude: - - 'app/controllers/api/v1/taxon_concepts_controller.rb' - - 'app/models/checklist/checklist.rb' - - 'app/models/trade/filter.rb' - - 'lib/modules/html_to_latex.rb' - - 'old_cap/deploy.rb' + Enabled: false # Offense count: 10 # Cop supports --auto-correct. @@ -481,13 +476,7 @@ Style/For: # Offense count: 6 # Configuration parameters: MinBodyLength. Style/GuardClause: - Exclude: - - 'app/models/annotation_observer.rb' - - 'app/models/cites_suspension_notification.rb' - - 'app/models/nomenclature_change.rb' - - 'app/models/nomenclature_change/lump.rb' - - 'app/models/nomenclature_change/split.rb' - - 'lib/tasks/bbgem.rake' + Enabled: false # Offense count: 8225 # Cop supports --auto-correct. From a185ab0b0bf67bde1645be4c3477c5206e095512 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 31 May 2016 14:20:08 +0100 Subject: [PATCH 271/365] Indent the right bracket the same as the start of the line where the left bracket is. --- .rubocop.yml | 5 + .rubocop_todo.yml | 7 - app/models/api_request.rb | 14 +- app/models/quota.rb | 35 +- app/models/taxon_concept_matcher.rb | 6 +- config/deploy.rb | 14 +- db/seeds.rb | 323 +++++++++--------- lib/tasks/elibrary/import.rake | 12 +- .../checklist/higher_taxa_injector_spec.rb | 24 +- 9 files changed, 221 insertions(+), 219 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 264a1168b9..6042b452ec 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -7,3 +7,8 @@ Style/StringLiterals: # SupportedStyles: outdent, indent Style/AccessModifierIndentation: EnforcedStyle: indent + +# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. +# SupportedStyles: special_inside_parentheses, consistent, align_brackets +Style/IndentArray: + EnforcedStyle: consistent diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 029f42385d..c28c405959 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -498,13 +498,6 @@ Style/IfInsideElse: Style/IfUnlessModifier: Enabled: false -# Offense count: 68 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. -# SupportedStyles: special_inside_parentheses, consistent, align_brackets -Style/IndentArray: - Enabled: false - # Offense count: 2 # Cop supports --auto-correct. # Configuration parameters: IndentationWidth. diff --git a/app/models/api_request.rb b/app/models/api_request.rb index c0d9736ad9..ebef6d5980 100644 --- a/app/models/api_request.rb +++ b/app/models/api_request.rb @@ -30,12 +30,14 @@ class ApiRequest < ActiveRecord::Base CONTROLLERS = ['taxon_concepts', 'distributions', 'cites_legislation', 'eu_legislation', 'references'] def self.top_5_most_active_users - subquery = self.recent.select([ - :user_id, - 'COUNT(*) AS cnt', - 'COUNT(NULLIF(response_status = 200, FALSE)) AS success_cnt', - 'COUNT(NULLIF(response_status = 200, TRUE)) AS failure_cnt' - ]).group(:user_id). + subquery = self.recent.select( + [ + :user_id, + 'COUNT(*) AS cnt', + 'COUNT(NULLIF(response_status = 200, FALSE)) AS success_cnt', + 'COUNT(NULLIF(response_status = 200, TRUE)) AS failure_cnt' + ] + ).group(:user_id). where('user_id IS NOT NULL') self.from("(#{subquery.to_sql}) api_requests"). order('cnt DESC').limit(5) diff --git a/app/models/quota.rb b/app/models/quota.rb index d7b84537cf..92c28c54b4 100644 --- a/app/models/quota.rb +++ b/app/models/quota.rb @@ -81,22 +81,25 @@ def self.years_array end def self.count_matching params - Quota.where([ - "EXTRACT(year from start_date) = :year - AND ((:excluded_geo_entities) IS NULL OR geo_entity_id NOT IN (:excluded_geo_entities)) - AND ((:included_geo_entities) IS NULL OR geo_entity_id IN (:included_geo_entities)) - AND ((:excluded_taxon_concepts) IS NULL OR taxon_concept_id NOT IN (:excluded_taxon_concepts)) - AND ((:included_taxon_concepts) IS NULL OR taxon_concept_id IN (:included_taxon_concepts)) - AND is_current = true", - :year => params[:year], - :excluded_geo_entities => params[:excluded_geo_entities_ids].present? ? - params[:excluded_geo_entities_ids].map(&:to_i) : nil, - :included_geo_entities => params[:included_geo_entities_ids].present? ? - params[:included_geo_entities_ids].map(&:to_i) : nil, - :excluded_taxon_concepts => params[:excluded_taxon_concepts_ids].present? ? - params[:excluded_taxon_concepts_ids].split(",").map(&:to_i) : nil, - :included_taxon_concepts => params[:included_taxon_concepts_ids].present? ? - params[:included_taxon_concepts_ids].split(",").map(&:to_i) : nil ]). + Quota.where( + [ + "EXTRACT(year from start_date) = :year + AND ((:excluded_geo_entities) IS NULL OR geo_entity_id NOT IN (:excluded_geo_entities)) + AND ((:included_geo_entities) IS NULL OR geo_entity_id IN (:included_geo_entities)) + AND ((:excluded_taxon_concepts) IS NULL OR taxon_concept_id NOT IN (:excluded_taxon_concepts)) + AND ((:included_taxon_concepts) IS NULL OR taxon_concept_id IN (:included_taxon_concepts)) + AND is_current = true", + :year => params[:year], + :excluded_geo_entities => params[:excluded_geo_entities_ids].present? ? + params[:excluded_geo_entities_ids].map(&:to_i) : nil, + :included_geo_entities => params[:included_geo_entities_ids].present? ? + params[:included_geo_entities_ids].map(&:to_i) : nil, + :excluded_taxon_concepts => params[:excluded_taxon_concepts_ids].present? ? + params[:excluded_taxon_concepts_ids].split(",").map(&:to_i) : nil, + :included_taxon_concepts => params[:included_taxon_concepts_ids].present? ? + params[:included_taxon_concepts_ids].split(",").map(&:to_i) : nil + ] + ). count end end diff --git a/app/models/taxon_concept_matcher.rb b/app/models/taxon_concept_matcher.rb index b95a2ca6ee..6c737ee983 100644 --- a/app/models/taxon_concept_matcher.rb +++ b/app/models/taxon_concept_matcher.rb @@ -19,9 +19,9 @@ def build_rel apply_taxonomy_options_to_rel if @scientific_name.present? @taxon_concepts = @taxon_concepts.where([ - "UPPER(taxon_concepts.full_name) LIKE BTRIM(UPPER(:sci_name_prefix))", - :sci_name_prefix => "#{@scientific_name}%" - ]) + "UPPER(taxon_concepts.full_name) LIKE BTRIM(UPPER(:sci_name_prefix))", + :sci_name_prefix => "#{@scientific_name}%" + ]) end end diff --git a/config/deploy.rb b/config/deploy.rb index 2adbc70fd9..017be062be 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -112,13 +112,13 @@ class PrecompileRequired < StandardError; end #optional set :slack_application, "SAPI" # override Capistrano `application` deployment_animals = [ - ["Loxodonta deployana", ":elephant:"], - ["Canis deployus", ":wolf:"], - ["Panthera capistranis", ":tiger:"], - ["Bison deployon", ":ox:"], - ["Ursus capistranus", ":bear:"], - ["Crotalus rattledeploy", ":snake:"], - ["Caiman assetocompilatus", ":crocodile:"] + ["Loxodonta deployana", ":elephant:"], + ["Canis deployus", ":wolf:"], + ["Panthera capistranis", ":tiger:"], + ["Bison deployon", ":ox:"], + ["Ursus capistranus", ":bear:"], + ["Crotalus rattledeploy", ":snake:"], + ["Caiman assetocompilatus", ":crocodile:"] ] shuffle_deployer = deployment_animals.shuffle.first diff --git a/db/seeds.rb b/db/seeds.rb index 971894506c..fc4c621ba6 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -69,8 +69,8 @@ puts "#{DocumentTag.delete_all} document tags deleted" [ - "I", "II", "III", "IV", "June 1986", "None", - "Post-CoP11", "Post-CoP12", "Post-CoP13" + "I", "II", "III", "IV", "June 1986", "None", + "Post-CoP11", "Post-CoP12", "Post-CoP13" ].each { |tag| DocumentTag::ReviewPhase.create(name: tag) } [ @@ -82,10 +82,10 @@ ].each {|tag| DocumentTag::ProcessStage.create(name: tag) } [ - "Accepted", "Cancelled", "Deferred", - "Redundant", "Rejected", "Transferred to other proposals", - "Withdrawn", "Accepted as amended", "Rejected as amended", - "Adopted" + "Accepted", "Cancelled", "Deferred", + "Redundant", "Rejected", "Transferred to other proposals", + "Withdrawn", "Accepted as amended", "Rejected as amended", + "Adopted" ].each { |tag| DocumentTag::ProposalOutcome.create(name: tag) } puts "#{DocumentTag.count} document tags created" @@ -145,171 +145,170 @@ higher_taxa = [ { - :name => 'Animalia', - :taxonomic_position => '1', - :legacy_id => 1, - :legacy_type => 'Animalia', - :sub_taxa => [ - { - :name => 'Annelida', - :taxonomic_position => '1.4', - :legacy_id => 1, - :legacy_type => 'Animalia', - :sub_taxa => [ - { - :name => 'Hirudinoidea', - :taxonomic_position => '1.4.1', - :legacy_id => 14, - :legacy_type => 'Animalia' - } - ] - }, - { - :name => 'Arthropoda', - :taxonomic_position => '1.3', - :legacy_id => 2, + :name => 'Animalia', + :taxonomic_position => '1', + :legacy_id => 1, :legacy_type => 'Animalia', :sub_taxa => [ - { - :name => 'Arachnida', - :taxonomic_position => '1.3.1', - :legacy_id => 4, - :legacy_type => 'Animalia' + { + :name => 'Annelida', + :taxonomic_position => '1.4', + :legacy_id => 1, + :legacy_type => 'Animalia', + :sub_taxa => [ + { + :name => 'Hirudinoidea', + :taxonomic_position => '1.4.1', + :legacy_id => 14, + :legacy_type => 'Animalia' + } + ] + }, + { + :name => 'Arthropoda', + :taxonomic_position => '1.3', + :legacy_id => 2, + :legacy_type => 'Animalia', + :sub_taxa => [ + { + :name => 'Arachnida', + :taxonomic_position => '1.3.1', + :legacy_id => 4, + :legacy_type => 'Animalia' + }, + { + :name => 'Insecta', + :taxonomic_position => '1.3.2', + :legacy_id => 16, + :legacy_type => 'Animalia' + } + ] + }, + { + :name => 'Chordata', + :taxonomic_position => '1.1', + :legacy_id => 3, + :legacy_type => 'Animalia', + :sub_taxa => [ + { + :name => 'Actinopterygii', + :taxonomic_position => '1.1.6', + :legacy_id => 1, + :legacy_type => 'Animalia' + }, + { + :name => 'Amphibia', + :taxonomic_position => '1.1.4', + :legacy_id => 2, + :legacy_type => 'Animalia' + }, + { + :name => 'Aves', + :taxonomic_position => '1.1.2', + :legacy_id => 5, + :legacy_type => 'Animalia' + }, + { + :name => 'Elasmobranchii', + :taxonomic_position => '1.1.5', + :legacy_id => 11, + :legacy_type => 'Animalia' + }, + { + :name => 'Mammalia', + :taxonomic_position => '1.1.1', + :legacy_id => 17, + :legacy_type => 'Animalia' + }, + { + :name => 'Reptilia', + :taxonomic_position => '1.1.3', + :legacy_id => 23, + :legacy_type => 'Animalia' + }, + { + :name => 'Sarcopterygii', + :taxonomic_position => '1.1.7', + :legacy_id => 24, + :legacy_type => 'Animalia' + }, + { + :name => 'Cephalaspidomorphi', + :taxonomic_position => '1.1.8', + :legacy_id => 7, + :legacy_type => 'Animalia' + } + ] }, { - :name => 'Insecta', - :taxonomic_position => '1.3.2', - :legacy_id => 16, - :legacy_type => 'Animalia' + :name => 'Cnidaria', + :taxonomic_position => '1.6', + :legacy_id => 5, + :legacy_type => 'Animalia', + :sub_taxa => [ + { + :name => 'Anthozoa', + :taxonomic_position => '1.6.1', + :legacy_id => 3, + :legacy_type => 'Animalia' + }, + { + :name => 'Hydrozoa', + :taxonomic_position => '1.6.2', + :legacy_id => 15, + :legacy_type => 'Animalia' + } + ] + }, + { + :name => 'Echinodermata', + :taxonomic_position => '1.2', + :legacy_id => 6, + :legacy_type => 'Animalia', + :sub_taxa => [ + { + :name => 'Holothuroidea', + :taxonomic_position => '1.2.1', + :legacy_id => 41, + :legacy_type => 'Animalia' + }, + { + :name => 'Stelleroidea', + :taxonomic_position => '1.2.2', + :legacy_id => 26, + :legacy_type => 'Animalia' + } + ] + }, + { + :name => 'Mollusca', + :taxonomic_position => '1.5', + :legacy_id => 7, + :legacy_type => 'Animalia', + :sub_taxa => [ + { + :name => 'Bivalvia', + :taxonomic_position => '1.5.1', + :legacy_id => 6, + :legacy_type => 'Animalia' + }, + { + :name => 'Gastropoda', + :taxonomic_position => '1.5.2', + :legacy_id => 13, + :legacy_type => 'Animalia' + } + ] } ] }, { - :name => 'Chordata', - :taxonomic_position => '1.1', - :legacy_id => 3, - :legacy_type => 'Animalia', - :sub_taxa => [ - { - :name => 'Actinopterygii', - :taxonomic_position => '1.1.6', - :legacy_id => 1, - :legacy_type => 'Animalia' - }, - { - :name => 'Amphibia', - :taxonomic_position => '1.1.4', - :legacy_id => 2, - :legacy_type => 'Animalia' - }, - { - :name => 'Aves', - :taxonomic_position => '1.1.2', - :legacy_id => 5, - :legacy_type => 'Animalia' - }, - { - :name => 'Elasmobranchii', - :taxonomic_position => '1.1.5', - :legacy_id => 11, - :legacy_type => 'Animalia' - }, - { - :name => 'Mammalia', - :taxonomic_position => '1.1.1', - :legacy_id => 17, - :legacy_type => 'Animalia' - }, - { - :name => 'Reptilia', - :taxonomic_position => '1.1.3', - :legacy_id => 23, - :legacy_type => 'Animalia' - }, - { - :name => 'Sarcopterygii', - :taxonomic_position => '1.1.7', - :legacy_id => 24, - :legacy_type => 'Animalia' - }, - { - :name => 'Cephalaspidomorphi', - :taxonomic_position => '1.1.8', - :legacy_id => 7, - :legacy_type => 'Animalia' + :name => 'Plantae', + :taxonomic_position => '2', + :legacy_id => 2, + :legacy_type => 'Plantae', + :sub_taxa => [] } - -] -}, - { - :name => 'Cnidaria', - :taxonomic_position => '1.6', - :legacy_id => 5, - :legacy_type => 'Animalia', - :sub_taxa => [ - { - :name => 'Anthozoa', - :taxonomic_position => '1.6.1', - :legacy_id => 3, - :legacy_type => 'Animalia' -}, - { - :name => 'Hydrozoa', - :taxonomic_position => '1.6.2', - :legacy_id => 15, - :legacy_type => 'Animalia' -} -] -}, - { - :name => 'Echinodermata', - :taxonomic_position => '1.2', - :legacy_id => 6, - :legacy_type => 'Animalia', - :sub_taxa => [ - { - :name => 'Holothuroidea', - :taxonomic_position => '1.2.1', - :legacy_id => 41, - :legacy_type => 'Animalia' - }, - { - :name => 'Stelleroidea', - :taxonomic_position => '1.2.2', - :legacy_id => 26, - :legacy_type => 'Animalia' - } -] -}, - { - :name => 'Mollusca', - :taxonomic_position => '1.5', - :legacy_id => 7, - :legacy_type => 'Animalia', - :sub_taxa => [ - { - :name => 'Bivalvia', - :taxonomic_position => '1.5.1', - :legacy_id => 6, - :legacy_type => 'Animalia' -}, - { - :name => 'Gastropoda', - :taxonomic_position => '1.5.2', - :legacy_id => 13, - :legacy_type => 'Animalia' -} -] -} -] -}, - { - :name => 'Plantae', - :taxonomic_position => '2', - :legacy_id => 2, - :legacy_type => 'Plantae', - :sub_taxa => [] -} ] kingdom_rank_id = Rank.find_by_name(Rank::KINGDOM).id diff --git a/lib/tasks/elibrary/import.rake b/lib/tasks/elibrary/import.rake index db84c68724..5060d2ffae 100644 --- a/lib/tasks/elibrary/import.rake +++ b/lib/tasks/elibrary/import.rake @@ -24,8 +24,8 @@ namespace :elibrary do puts "#{DocumentTag.count} document tags" [ - "I", "II", "III", "IV", "June 1986", "None", - "Post-CoP11", "Post-CoP12", "Post-CoP13" + "I", "II", "III", "IV", "June 1986", "None", + "Post-CoP11", "Post-CoP12", "Post-CoP13" ].each { |tag| DocumentTag::ReviewPhase.find_or_create_by_name(name: tag) } [ @@ -37,10 +37,10 @@ namespace :elibrary do ].each {|tag| DocumentTag::ProcessStage.find_or_create_by_name(name: tag) } [ - "Accepted", "Cancelled", "Deferred", - "Redundant", "Rejected", "Transferred to other proposals", - "Withdrawn", "Accepted as amended", "Rejected as amended", - "Adopted" + "Accepted", "Cancelled", "Deferred", + "Redundant", "Rejected", "Transferred to other proposals", + "Withdrawn", "Accepted as amended", "Rejected as amended", + "Adopted" ].each { |tag| DocumentTag::ProposalOutcome.find_or_create_by_name(name: tag) } puts "#{DocumentTag.count} document tags" diff --git a/spec/models/checklist/higher_taxa_injector_spec.rb b/spec/models/checklist/higher_taxa_injector_spec.rb index 06c9fdec76..1389b01a23 100644 --- a/spec/models/checklist/higher_taxa_injector_spec.rb +++ b/spec/models/checklist/higher_taxa_injector_spec.rb @@ -133,8 +133,8 @@ [ @species1_1_1, @species2_1_1_1_1 - ], {:expand_headers => true} - ) + ], {:expand_headers => true} + ) } specify{ headers = hti_different_class.higher_taxa_headers( @@ -165,8 +165,8 @@ [ @species1_1_1, @species2_1_1 - ], {:skip_ancestor_ids => [@family1.id]} - ) + ], {:skip_ancestor_ids => [@family1.id]} + ) } specify{ hti_different_family.run.size.should == 3 @@ -195,8 +195,8 @@ Checklist::HigherTaxaInjector.new( [ @species1_1_1 - ], {:skip_ancestor_ids => [@family1.id]} - ) + ], {:skip_ancestor_ids => [@family1.id]} + ) } specify{ hti_one_species_skip_family.higher_taxa_headers(nil, @species1_1_1).should be_empty @@ -207,8 +207,8 @@ Checklist::HigherTaxaInjector.new( [ @species1_1_1 - ], {:expand_headers => true} - ) + ], {:expand_headers => true} + ) } specify{ headers = hti_one_species_expand_headers.higher_taxa_headers(nil, @species1_1_1) @@ -280,8 +280,8 @@ [ @species1_1_1, @species2_1_1 - ], {:expand_headers => true} - ) + ], {:expand_headers => true} + ) } specify{ headers = hti_different_family.higher_taxa_headers(@species1_1_1, @species2_1_1) @@ -342,8 +342,8 @@ [ @order2, @genus2_1 - ], {:expand_headers => true} - ) + ], {:expand_headers => true} + ) } specify{ headers = hti_different_orders_expand.higher_taxa_headers(@order2, @genus2_1) From 46158221306203587640d7c1ae58841d82b7568e Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 31 May 2016 14:41:33 +0100 Subject: [PATCH 272/365] Indent the right brace the same as the start of the line where the left brace is. --- .rubocop.yml | 5 ++ .rubocop_todo.yml | 7 --- .../trade/sandbox_shipments_controller.rb | 8 ++-- app/models/distribution.rb | 6 +-- app/models/iucn_mapping_manager.rb | 2 +- db/seeds.rb | 16 +++---- lib/tasks/helpers_for_import.rb | 48 +++++++++---------- .../cites_suspensions_controller_spec.rb | 9 ++-- .../admin/eu_opinions_controller_spec.rb | 9 ++-- .../lump_controller_spec.rb | 3 +- .../split_controller_spec.rb | 3 +- ...taxon_cites_suspensions_controller_spec.rb | 9 ++-- .../taxon_eu_suspensions_controller_spec.rb | 9 ++-- .../taxon_listing_changes_controller_spec.rb | 21 ++++---- .../admin/taxon_quotas_controller_spec.rb | 9 ++-- .../api/taxon_concepts_controller_spec.rb | 30 +++++++----- .../cites_trade/exports_controller_spec.rb | 10 ++-- .../trade/exports_controller_spec.rb | 10 ++-- spec/models/api_request_spec.rb | 28 ++++++----- spec/workers/quotas_copy_worker_spec.rb | 4 +- 20 files changed, 136 insertions(+), 110 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 6042b452ec..4baf2ca88e 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -12,3 +12,8 @@ Style/AccessModifierIndentation: # SupportedStyles: special_inside_parentheses, consistent, align_brackets Style/IndentArray: EnforcedStyle: consistent + +# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. +# SupportedStyles: special_inside_parentheses, consistent, align_braces +Style/IndentHash: + EnforcedStyle: consistent diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index c28c405959..f9835c787a 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -506,13 +506,6 @@ Style/IndentAssignment: - 'app/models/nomenclature_change/split/constructor.rb' - 'app/models/taxon_concept.rb' -# Offense count: 329 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. -# SupportedStyles: special_inside_parentheses, consistent, align_braces -Style/IndentHash: - Enabled: false - # Offense count: 82 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. diff --git a/app/controllers/trade/sandbox_shipments_controller.rb b/app/controllers/trade/sandbox_shipments_controller.rb index 6df78900b4..9ef7accf2e 100644 --- a/app/controllers/trade/sandbox_shipments_controller.rb +++ b/app/controllers/trade/sandbox_shipments_controller.rb @@ -6,10 +6,10 @@ def index render :json => @search.results, :each_serializer => Trade::SandboxShipmentSerializer, :meta => { - :total => @search.total_cnt, - :page => @search.page, - :per_page => @search.per_page - } + :total => @search.total_cnt, + :page => @search.page, + :per_page => @search.per_page + } end def update diff --git a/app/models/distribution.rb b/app/models/distribution.rb index 9532e8ba52..b1244e4fb5 100644 --- a/app/models/distribution.rb +++ b/app/models/distribution.rb @@ -40,9 +40,9 @@ def add_existing_references ids unless reference.nil? self.distribution_references. create({ - :distribution_id => self.id, - :reference_id => reference.id - }) + :distribution_id => self.id, + :reference_id => reference.id + }) end end end diff --git a/app/models/iucn_mapping_manager.rb b/app/models/iucn_mapping_manager.rb index 2ee05a4394..7a7fe8fc50 100644 --- a/app/models/iucn_mapping_manager.rb +++ b/app/models/iucn_mapping_manager.rb @@ -48,7 +48,7 @@ def map_taxon_concept taxon_concept, map, data :iucn_author => match['authority'], :iucn_category => match['category'], :details => { - :match => type_of_match(taxon_concept, match), + :match => type_of_match(taxon_concept, match), :no_matches => data["result"].size }, :accepted_name_id => taxon_concept.name_status == 'S' ? taxon_concept.accepted_names.first.try(:id) : nil diff --git a/db/seeds.rb b/db/seeds.rb index fc4c621ba6..26c13e9a6a 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -227,16 +227,16 @@ :legacy_type => 'Animalia' }, { - :name => 'Sarcopterygii', - :taxonomic_position => '1.1.7', - :legacy_id => 24, - :legacy_type => 'Animalia' + :name => 'Sarcopterygii', + :taxonomic_position => '1.1.7', + :legacy_id => 24, + :legacy_type => 'Animalia' }, { - :name => 'Cephalaspidomorphi', - :taxonomic_position => '1.1.8', - :legacy_id => 7, - :legacy_type => 'Animalia' + :name => 'Cephalaspidomorphi', + :taxonomic_position => '1.1.8', + :legacy_id => 7, + :legacy_type => 'Animalia' } ] }, diff --git a/lib/tasks/helpers_for_import.rb b/lib/tasks/helpers_for_import.rb index 41a412fd43..9fc040af5b 100644 --- a/lib/tasks/helpers_for_import.rb +++ b/lib/tasks/helpers_for_import.rb @@ -265,32 +265,32 @@ class CsvToDbMap 'start_date' => 'start_date date' }, 'trade_species_mapping_import' => { - 'cites_name' => 'cites_name varchar', - 'cites_taxon_code' => 'cites_taxon_code varchar', - 'speciesplusid' => 'species_plus_id int', - 'speciesplusname' => 'species_plus_name varchar', - 'rank' => 'rank varchar' + 'cites_name' => 'cites_name varchar', + 'cites_taxon_code' => 'cites_taxon_code varchar', + 'speciesplusid' => 'species_plus_id int', + 'speciesplusname' => 'species_plus_name varchar', + 'rank' => 'rank varchar' }, 'shipments_import' => { - "SHIPMENT_NUMBER" => 'shipment_number int', - "ISO_COUNTRY_CODE" => 'iso_country_code varchar', - "REPORTER_TYPE" => 'reporter_type varchar', - "SHIPMENT_YEAR" => 'shipment_year int', - "APPENDIX" => 'appendix varchar', - "CITES_TAXON_CODE" => 'cites_taxon_code varchar', - "TERM_CODE_1" => 'term_code_1 varchar', - "TERM_CODE_2" => 'term_code_2 varchar', - "UNIT_CODE_1" => 'unit_code_1 varchar', - "UNIT_CODE_2" => 'unit_code_2 varchar', - "QUANTITY_1" => 'quantity_1 numeric', - "QUANTITY_2" => 'quantity_2 numeric', - "EXPORT_COUNTRY_CODE" => 'export_country_code varchar', - "IMPORT_COUNTRY_CODE" => 'import_country_code varchar', - "ORIGIN_COUNTRY_CODE" => 'origin_country_code varchar', - "SOURCE_CODE" => 'source_code varchar', - "PURPOSE_CODE" => 'purpose_code varchar', - "PERMIT_NUMBER_COUNT" => 'permit_number_count int', - "RECORD_LOAD_STATUS" => 'record_load_status varchar' + "SHIPMENT_NUMBER" => 'shipment_number int', + "ISO_COUNTRY_CODE" => 'iso_country_code varchar', + "REPORTER_TYPE" => 'reporter_type varchar', + "SHIPMENT_YEAR" => 'shipment_year int', + "APPENDIX" => 'appendix varchar', + "CITES_TAXON_CODE" => 'cites_taxon_code varchar', + "TERM_CODE_1" => 'term_code_1 varchar', + "TERM_CODE_2" => 'term_code_2 varchar', + "UNIT_CODE_1" => 'unit_code_1 varchar', + "UNIT_CODE_2" => 'unit_code_2 varchar', + "QUANTITY_1" => 'quantity_1 numeric', + "QUANTITY_2" => 'quantity_2 numeric', + "EXPORT_COUNTRY_CODE" => 'export_country_code varchar', + "IMPORT_COUNTRY_CODE" => 'import_country_code varchar', + "ORIGIN_COUNTRY_CODE" => 'origin_country_code varchar', + "SOURCE_CODE" => 'source_code varchar', + "PURPOSE_CODE" => 'purpose_code varchar', + "PERMIT_NUMBER_COUNT" => 'permit_number_count int', + "RECORD_LOAD_STATUS" => 'record_load_status varchar' }, 'permits_import' => { 'SHIPMENT_NUMBER' => 'shipment_number int', diff --git a/spec/controllers/admin/cites_suspensions_controller_spec.rb b/spec/controllers/admin/cites_suspensions_controller_spec.rb index 3655b7cbfc..e350f2e175 100644 --- a/spec/controllers/admin/cites_suspensions_controller_spec.rb +++ b/spec/controllers/admin/cites_suspensions_controller_spec.rb @@ -35,7 +35,8 @@ describe "POST create" do context "when successful" do it "renders index" do - post :create, :cites_suspension => { + post :create, + :cites_suspension => { :start_notification_id => create_cites_suspension_notification.id } response.should redirect_to( @@ -79,7 +80,8 @@ context "when successful" do it "redirects to taxon_concepts cites suspensions page" do - put :update, :cites_suspension => { + put :update, + :cites_suspension => { :publication_date => 1.week.ago }, :id => @cites_suspension.id @@ -90,7 +92,8 @@ end it "renders edit when not successful" do - put :update, :cites_suspension => { + put :update, + :cites_suspension => { :start_notification_id => nil }, :id => @cites_suspension.id diff --git a/spec/controllers/admin/eu_opinions_controller_spec.rb b/spec/controllers/admin/eu_opinions_controller_spec.rb index f2f4101dc1..99d24db535 100644 --- a/spec/controllers/admin/eu_opinions_controller_spec.rb +++ b/spec/controllers/admin/eu_opinions_controller_spec.rb @@ -37,7 +37,8 @@ @eu_decision_type = create(:eu_decision_type) end it "redirects to the EU Opinions index" do - post :create, :eu_opinion => { + post :create, + :eu_opinion => { :eu_decision_type_id => @eu_decision_type.id, :start_date => Date.today, :geo_entity_id => create( @@ -87,7 +88,8 @@ context "when successful" do it "renders taxon_concepts EU Opinions page" do - put :update, :eu_opinion => { + put :update, + :eu_opinion => { :eu_decision_type_id => @eu_decision_type.id }, :id => @eu_opinion.id, @@ -100,7 +102,8 @@ context "when not successful" do it "renders new" do - put :update, :eu_opinion => { + put :update, + :eu_opinion => { :eu_decision_type_id => nil }, :id => @eu_opinion.id, diff --git a/spec/controllers/admin/nomenclature_changes/lump_controller_spec.rb b/spec/controllers/admin/nomenclature_changes/lump_controller_spec.rb index 27546b2ab3..afce323b33 100644 --- a/spec/controllers/admin/nomenclature_changes/lump_controller_spec.rb +++ b/spec/controllers/admin/nomenclature_changes/lump_controller_spec.rb @@ -86,7 +86,8 @@ end context 'when unsuccessful' do it 're-renders step' do - put :update, nomenclature_change_lump: { + put :update, + nomenclature_change_lump: { inputs_attributes: { 0 => {taxon_concept_id: nil} } diff --git a/spec/controllers/admin/nomenclature_changes/split_controller_spec.rb b/spec/controllers/admin/nomenclature_changes/split_controller_spec.rb index b27bb4dde5..90583b520a 100644 --- a/spec/controllers/admin/nomenclature_changes/split_controller_spec.rb +++ b/spec/controllers/admin/nomenclature_changes/split_controller_spec.rb @@ -135,7 +135,8 @@ end context 'when unsuccessful' do it 're-renders step' do - put :update, nomenclature_change_split: { + put :update, + nomenclature_change_split: { input_attributes: {taxon_concept_id: nil} }, nomenclature_change_id: @split.id, id: 'inputs' response.should render_template('inputs') diff --git a/spec/controllers/admin/taxon_cites_suspensions_controller_spec.rb b/spec/controllers/admin/taxon_cites_suspensions_controller_spec.rb index fae5f9c40d..05d4151a5b 100644 --- a/spec/controllers/admin/taxon_cites_suspensions_controller_spec.rb +++ b/spec/controllers/admin/taxon_cites_suspensions_controller_spec.rb @@ -33,7 +33,8 @@ describe "POST create" do context "when successful" do it "renders index" do - post :create, :cites_suspension => { + post :create, + :cites_suspension => { :start_notification_id => create_cites_suspension_notification.id }, :taxon_concept_id => @taxon_concept.id @@ -59,7 +60,8 @@ describe "PUT update" do context "when successful" do it "renders taxon_concepts cites suspensions page" do - put :update, :cites_suspension => { + put :update, + :cites_suspension => { :publication_date => 1.week.ago }, :id => @cites_suspension.id, @@ -71,7 +73,8 @@ end it "renders edit when not successful" do - put :update, :cites_suspension => { + put :update, + :cites_suspension => { :start_notification_id => nil }, :id => @cites_suspension.id, diff --git a/spec/controllers/admin/taxon_eu_suspensions_controller_spec.rb b/spec/controllers/admin/taxon_eu_suspensions_controller_spec.rb index 29ee0c595a..d31d8b87a6 100644 --- a/spec/controllers/admin/taxon_eu_suspensions_controller_spec.rb +++ b/spec/controllers/admin/taxon_eu_suspensions_controller_spec.rb @@ -37,7 +37,8 @@ @eu_decision_type = create(:eu_decision_type) end it "redirects to the EU suspensions index" do - post :create, :eu_suspension => { + post :create, + :eu_suspension => { :eu_decision_type_id => @eu_decision_type.id, :start_date => Date.new(2013,1,1), :geo_entity_id => create( @@ -87,7 +88,8 @@ context "when successful" do it "renders taxon_concepts EU suspensions page" do - put :update, :eu_suspension => { + put :update, + :eu_suspension => { :eu_decision_type_id => @eu_decision_type.id, :geo_entity_id => create( :geo_entity, :geo_entity_type_id => country_geo_entity_type.id @@ -103,7 +105,8 @@ context "when not successful" do it "renders new" do - put :update, :eu_suspension => { + put :update, + :eu_suspension => { :eu_decision_type_id => nil }, :id => @eu_suspension.id, diff --git a/spec/controllers/admin/taxon_listing_changes_controller_spec.rb b/spec/controllers/admin/taxon_listing_changes_controller_spec.rb index 5f5d05f52c..b0eb490658 100644 --- a/spec/controllers/admin/taxon_listing_changes_controller_spec.rb +++ b/spec/controllers/admin/taxon_listing_changes_controller_spec.rb @@ -72,7 +72,8 @@ describe "POST create" do context "when successful" do it "redirects to taxon_concept listing_changes page" do - post :create, :listing_change => { + post :create, + :listing_change => { :change_type_id => @addition.id, :species_listing_id => @appendix.id, :effective_at => 1.week.ago @@ -131,7 +132,8 @@ end context "when successful" do it "redirects to taxon_concept listing_changes page" do - put :update, :listing_change => { + put :update, + :listing_change => { :change_type_id => @addition.id, :species_listing_id => @appendix.id, :effective_at => 1.week.ago @@ -167,7 +169,8 @@ :effective_at => 1.week.ago, :event_id => eu_regulation.id ) - put :update, :listing_change => { + put :update, + :listing_change => { :change_type_id => addition.id, :species_listing_id => annex.id, :effective_at => 1.week.ago @@ -195,13 +198,13 @@ :taxon_concept_id => @taxon_concept.id, :designation_id => @designation.id, :listing_change => { - :annotation_attributes => { - "short_note_en"=>"", "short_note_es"=>"", - "short_note_fr"=>"", "full_note_en"=>"", - "full_note_es"=>"", "full_note_fr"=>"", - "id"=> @annotation.id + :annotation_attributes => { + "short_note_en"=>"", "short_note_es"=>"", + "short_note_fr"=>"", "full_note_en"=>"", + "full_note_es"=>"", "full_note_fr"=>"", + "id"=> @annotation.id + } } - } response.should redirect_to( admin_taxon_concept_designation_listing_changes_url( @taxon_concept, @designation) diff --git a/spec/controllers/admin/taxon_quotas_controller_spec.rb b/spec/controllers/admin/taxon_quotas_controller_spec.rb index 63353bd1eb..32b4ececc3 100644 --- a/spec/controllers/admin/taxon_quotas_controller_spec.rb +++ b/spec/controllers/admin/taxon_quotas_controller_spec.rb @@ -36,7 +36,8 @@ describe "POST create" do context "when successful" do it "renders index" do - post :create, :quota => { + post :create, + :quota => { :quota => 1, :unit_id => @unit.id, :publication_date => 1.week.ago, @@ -88,7 +89,8 @@ context "when successful" do it "renders taxon_concepts quotas page" do - put :update, :quota => { + put :update, + :quota => { :publication_date => 1.week.ago }, :id => @quota.id, @@ -100,7 +102,8 @@ end it "renders new when not successful" do - put :update, :quota => { + put :update, + :quota => { :publication_date => nil }, :id => @quota.id, diff --git a/spec/controllers/api/taxon_concepts_controller_spec.rb b/spec/controllers/api/taxon_concepts_controller_spec.rb index 543962a035..577698e030 100644 --- a/spec/controllers/api/taxon_concepts_controller_spec.rb +++ b/spec/controllers/api/taxon_concepts_controller_spec.rb @@ -3,19 +3,25 @@ describe Api::V1::TaxonConceptsController, :type => :controller do context "GET index" do it " logs with Ahoy with different parameters" do - expect { get :index, { - :taxonomy => 'cites_eu', - :taxon_concept_query => 'stork', - :geo_entity_scope => 'cites', - :page => 1 } }.to change{Ahoy::Event.count}.by(1) - expect(Ahoy::Event.last.visit_id).to_not be(nil) + expect { + get :index, { + :taxonomy => 'cites_eu', + :taxon_concept_query => 'stork', + :geo_entity_scope => 'cites', + :page => 1 + } + }.to change{Ahoy::Event.count}.by(1) + expect(Ahoy::Event.last.visit_id).to_not be(nil) - expect { get :index, { - :taxonomy => 'cites_eu', - :taxon_concept_query => 'dolphin', - :geo_entity_scope => 'cites', - :page => 1 } }.to change{Ahoy::Event.count}.by(1) - expect(@ahoy_event1).to eq(@ahoy_event2) + expect { + get :index, { + :taxonomy => 'cites_eu', + :taxon_concept_query => 'dolphin', + :geo_entity_scope => 'cites', + :page => 1 + } + }.to change{Ahoy::Event.count}.by(1) + expect(@ahoy_event1).to eq(@ahoy_event2) end end end diff --git a/spec/controllers/cites_trade/exports_controller_spec.rb b/spec/controllers/cites_trade/exports_controller_spec.rb index d44532750b..1a0e0a314b 100644 --- a/spec/controllers/cites_trade/exports_controller_spec.rb +++ b/spec/controllers/cites_trade/exports_controller_spec.rb @@ -27,11 +27,11 @@ Trade::TradeDataDownloadLogger.stub(:organization_from).and_return("UNEP-WCMC") lambda do get :download, :filters => { - :report_type => 'comptab', - :exporters_ids => ['40'], - :time_range_start => '1975', - :time_range_end => '2000' - } + :report_type => 'comptab', + :exporters_ids => ['40'], + :time_range_start => '1975', + :time_range_end => '2000' + } end.should change(Trade::TradeDataDownload, :count).by(1) end end diff --git a/spec/controllers/trade/exports_controller_spec.rb b/spec/controllers/trade/exports_controller_spec.rb index 0964e78df4..648084245e 100644 --- a/spec/controllers/trade/exports_controller_spec.rb +++ b/spec/controllers/trade/exports_controller_spec.rb @@ -15,11 +15,11 @@ Trade::ShipmentsExport.any_instance.stub(:public_file_name).and_return('shipments.csv') lambda do get :download, :filters => { - :report_type => :raw, - :exporters_ids => ['40'], - :time_range_start => '1975', - :time_range_end => '2000' - } + :report_type => :raw, + :exporters_ids => ['40'], + :time_range_start => '1975', + :time_range_end => '2000' + } end.should_not change(Trade::TradeDataDownload, :count).by(1) end end diff --git a/spec/models/api_request_spec.rb b/spec/models/api_request_spec.rb index 3e63eb62f8..93c4232181 100644 --- a/spec/models/api_request_spec.rb +++ b/spec/models/api_request_spec.rb @@ -57,13 +57,14 @@ subject { ApiRequest.requests_by_response_status } - specify { expect(subject).to eq({ - '200' => 1, - '400' => 0, - '401' => 0, - '404' => 0, - '422' => 0, - '500' => 1 + specify { + expect(subject).to eq({ + '200' => 1, + '400' => 0, + '401' => 0, + '404' => 0, + '422' => 0, + '500' => 1 }) } end @@ -72,12 +73,13 @@ subject { ApiRequest.requests_by_controller } - specify { expect(subject).to eq({ - 'taxon_concepts' => 2, - 'distributions' => 0, - 'cites_legislation' => 0, - 'eu_legislation' => 0, - 'references' => 0 + specify { + expect(subject).to eq({ + 'taxon_concepts' => 2, + 'distributions' => 0, + 'cites_legislation' => 0, + 'eu_legislation' => 0, + 'references' => 0 }) } end diff --git a/spec/workers/quotas_copy_worker_spec.rb b/spec/workers/quotas_copy_worker_spec.rb index 38cae7a3b5..b8d0979367 100644 --- a/spec/workers/quotas_copy_worker_spec.rb +++ b/spec/workers/quotas_copy_worker_spec.rb @@ -37,7 +37,7 @@ "from_text" => '', "to_text" => '', "url" => '' - } + } } describe "Copy single quota, for a given year" do @@ -53,7 +53,7 @@ describe "Try to copy quota from wrong year" do before(:each) do QuotasCopyWorker.new.perform(job_defaults.merge({ - "from_year" => quota.start_date.year+1 + "from_year" => quota.start_date.year+1 })) end specify { Quota.count(true).should == 1} From ce8abfd552a0173b076cb84c24a1d27855179f7e Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 31 May 2016 15:31:04 +0100 Subject: [PATCH 273/365] fixes to inconsistent indentation --- app/controllers/admin/documents_controller.rb | 2 +- .../admin/hash_annotations_controller.rb | 2 +- .../admin/simple_crud_controller.rb | 8 +- .../admin/taxon_relationships_controller.rb | 6 +- .../trade/statistics_controller.rb | 4 +- app/models/checklist/checklist.rb | 20 +- app/models/checklist/pdf/history_content.rb | 16 +- app/models/cms_mapping_manager.rb | 16 +- app/models/listing_change_observer.rb | 2 +- .../reassignment_helpers.rb | 2 +- app/models/species/listings_export.rb | 2 +- app/models/trade/annual_report_upload.rb | 12 +- app/models/trade/shipment_report_queries.rb | 828 +++++++++--------- .../species/geo_entity_serializer.rb | 2 +- .../inclusion_validation_rule_serializer.rb | 8 +- lib/csv_column_headers_validator.rb | 34 +- lib/tasks/helpers_for_import.rb | 16 +- lib/tasks/import_countries.rake | 5 +- lib/tasks/import_trade_names.rake | 8 +- lib/tasks/import_trade_permits.rake | 52 +- 20 files changed, 523 insertions(+), 522 deletions(-) diff --git a/app/controllers/admin/documents_controller.rb b/app/controllers/admin/documents_controller.rb index 875eb0a52f..329abf6952 100644 --- a/app/controllers/admin/documents_controller.rb +++ b/app/controllers/admin/documents_controller.rb @@ -86,7 +86,7 @@ def collection def load_associations @designations = Designation.where(name: ['CITES', 'EU']).select([:id, :name]).order(:name) @event_types = if @document && @document.event - @event_types = [{id: @document.event.type}] + [{id: @document.event.type}] else Event.event_types_with_names end diff --git a/app/controllers/admin/hash_annotations_controller.rb b/app/controllers/admin/hash_annotations_controller.rb index 90213b70d5..248dd31fea 100644 --- a/app/controllers/admin/hash_annotations_controller.rb +++ b/app/controllers/admin/hash_annotations_controller.rb @@ -5,7 +5,7 @@ class Admin::HashAnnotationsController < Admin::SimpleCrudController protected def collection - @annotations = load_collection.page(params[:page]). + @annotations = load_collection.page(params[:page]). search(params[:query]) end diff --git a/app/controllers/admin/simple_crud_controller.rb b/app/controllers/admin/simple_crud_controller.rb index 00e8ecae72..e981571b7f 100644 --- a/app/controllers/admin/simple_crud_controller.rb +++ b/app/controllers/admin/simple_crud_controller.rb @@ -28,10 +28,10 @@ def destroy failure.html { redirect_to collection_url, :alert => if resource.errors.present? - "Operation #{resource.errors.messages[:base].join(", ")}" - else - "Operation failed" - end + "Operation #{resource.errors.messages[:base].join(", ")}" + else + "Operation failed" + end } end end diff --git a/app/controllers/admin/taxon_relationships_controller.rb b/app/controllers/admin/taxon_relationships_controller.rb index d62e182728..7ad1cb8d05 100644 --- a/app/controllers/admin/taxon_relationships_controller.rb +++ b/app/controllers/admin/taxon_relationships_controller.rb @@ -55,9 +55,9 @@ def destroy def load_taxon_relationship_types @taxon_relationship_type = if params[:taxon_relationship] - TaxonRelationshipType.find(params[:taxon_relationship][:taxon_relationship_type_id]) - else - TaxonRelationshipType.find_by_name(params[:type] || TaxonRelationshipType::EQUAL_TO) + TaxonRelationshipType.find(params[:taxon_relationship][:taxon_relationship_type_id]) + else + TaxonRelationshipType.find_by_name(params[:type] || TaxonRelationshipType::EQUAL_TO) end @taxon_relationship_types = TaxonRelationshipType.order(:name). intertaxonomic diff --git a/app/controllers/trade/statistics_controller.rb b/app/controllers/trade/statistics_controller.rb index 33d3ad99dd..b7974ab0d2 100644 --- a/app/controllers/trade/statistics_controller.rb +++ b/app/controllers/trade/statistics_controller.rb @@ -2,8 +2,8 @@ class Trade::StatisticsController < TradeController layout 'admin' def index - @start_date = params[:stats_start_date] ? Date.parse(params[:stats_start_date]) : Date.today.beginning_of_year - @end_date = params[:stats_end_date] ? Date.parse(params[:stats_end_date]) : Date.today + @start_date = params[:stats_start_date] ? Date.parse(params[:stats_start_date]) : Date.today.beginning_of_year + @end_date = params[:stats_end_date] ? Date.parse(params[:stats_end_date]) : Date.today @years = (1975..Date.today.year).to_a.reverse @total_shipments = Trade::Shipment.count @last_updated = Trade::Shipment.maximum(:updated_at).strftime("%d/%m/%Y %H:%M") diff --git a/app/models/checklist/checklist.rb b/app/models/checklist/checklist.rb index 300c904a4a..2bf6b1707b 100644 --- a/app/models/checklist/checklist.rb +++ b/app/models/checklist/checklist.rb @@ -45,7 +45,7 @@ def initialize_query unless @scientific_name.blank? @taxon_concepts_rel = @taxon_concepts_rel. by_name( - @scientific_name, + @scientific_name, {:synonyms => true, :common_names => true, :subspecies => false} ) end @@ -82,10 +82,10 @@ def prepare_kindom_queries; end def generate @animalia, @plantae = cached_results.partition{ |item| item.kingdom_position == 0 } if @output_layout == :taxonomic - injector = Checklist::HigherTaxaInjector.new(@animalia) - @animalia = injector.run - injector = Checklist::HigherTaxaInjector.new(@plantae) - @plantae = injector.run + injector = Checklist::HigherTaxaInjector.new(@animalia) + @animalia = injector.run + injector = Checklist::HigherTaxaInjector.new(@plantae) + @plantae = injector.run end [self] #TODO just for compatibility with frontend, no sensible reason for this end @@ -106,7 +106,7 @@ def self.summarise_filters(params) # country @countries_count = 0 unless @countries.empty? - summary = [I18n.t('filter_summary.when_no_taxon')] if summary.length == 0 + summary = [I18n.t('filter_summary.when_no_taxon')] if summary.length == 0 countries = GeoEntity.find_all_by_id(@countries) @@ -121,20 +121,20 @@ def self.summarise_filters(params) # region @regions_count = 0 unless @cites_regions.empty? - summary = [I18n.t('filter_summary.when_no_taxon')] if summary.length == 0 + summary = [I18n.t('filter_summary.when_no_taxon')] if summary.length == 0 regions = GeoEntity.find_all_by_id(params[:cites_region_ids]) @regions_count = regions.count if @regions_count > 0 - summary << I18n.t('filter_summary.within_regions') if @countries_count > 0 + summary << I18n.t('filter_summary.within_regions') if @countries_count > 0 summary << "#{regions.count} #{'region'.pluralize(regions.count)}" end end # appendix unless @cites_appendices.empty? - summary = [I18n.t('filter_summary.when_no_taxon')] if summary.length == 0 + summary = [I18n.t('filter_summary.when_no_taxon')] if summary.length == 0 if (!@cites_regions.empty? || !@countries.empty?) && @@ -150,7 +150,7 @@ def self.summarise_filters(params) # name unless @scientific_name.blank? - summary = [I18n.t('filter_summary.when_taxon')] if summary.length == 0 + summary = [I18n.t('filter_summary.when_taxon')] if summary.length == 0 summary << "'#{@scientific_name}'" end diff --git a/app/models/checklist/pdf/history_content.rb b/app/models/checklist/pdf/history_content.rb index 47808a433a..1b7ca7bdb4 100644 --- a/app/models/checklist/pdf/history_content.rb +++ b/app/models/checklist/pdf/history_content.rb @@ -85,14 +85,14 @@ def listing_with_change_type(listing_change) listing_change.species_listing_name end change_type = if listing_change.change_type_name == ChangeType::RESERVATION - '/r' - elsif listing_change.change_type_name == ChangeType::RESERVATION_WITHDRAWAL - '/w' - elsif listing_change.change_type_name == ChangeType::DELETION - 'Del' - else - nil - end + '/r' + elsif listing_change.change_type_name == ChangeType::RESERVATION_WITHDRAWAL + '/w' + elsif listing_change.change_type_name == ChangeType::DELETION + 'Del' + else + nil + end "#{appendix}#{change_type}" end diff --git a/app/models/cms_mapping_manager.rb b/app/models/cms_mapping_manager.rb index 2849ea3457..2d57e81e60 100644 --- a/app/models/cms_mapping_manager.rb +++ b/app/models/cms_mapping_manager.rb @@ -33,18 +33,18 @@ def analyse mapping 'distributions_cms' => species["geographic_range"]["range_states"].size, 'instruments_splus' => taxon_concept && taxon_concept.instruments.map(&:name).join(", "), 'instruments_cms' => species["assessment_information"].map do |ai| - ai["instrument"] && ai["instrument"]["instrument"] - end.join(", "), + ai["instrument"] && ai["instrument"]["instrument"] + end.join(", "), 'listing_splus' => taxon_concept && taxon_concept.listing_changes.first && "#{taxon_concept.listing_changes.first.species_listing.name}: #{taxon_concept. listing_changes.first.effective_at.strftime("%d/%m/%Y")}", 'listing_cms' => if species["appendix_1_date"] - "Appendix I: #{Date.parse(species["appendix_1_date"]).strftime("%d/%m/%Y")}" - elsif species["appendix_2_date"] - "Appendix II: #{Date.parse(species["appendix_2_date"]).strftime("%d/%m/%Y")}" - else - nil - end + "Appendix I: #{Date.parse(species["appendix_1_date"]).strftime("%d/%m/%Y")}" + elsif species["appendix_2_date"] + "Appendix II: #{Date.parse(species["appendix_2_date"]).strftime("%d/%m/%Y")}" + else + nil + end } mapping.save end diff --git a/app/models/listing_change_observer.rb b/app/models/listing_change_observer.rb index 566cab1d06..24a2ce89f1 100644 --- a/app/models/listing_change_observer.rb +++ b/app/models/listing_change_observer.rb @@ -27,7 +27,7 @@ def before_save(listing_change) ) #geographic exclusions - excluded_geo_entities_ids = listing_change.excluded_geo_entities_ids && + excluded_geo_entities_ids = listing_change.excluded_geo_entities_ids && listing_change.excluded_geo_entities_ids.reject(&:blank?) excluded_geo_entities = if excluded_geo_entities_ids && excluded_geo_entities_ids.size > 0 new_exclusions << ListingChange.new( diff --git a/app/models/nomenclature_change/reassignment_helpers.rb b/app/models/nomenclature_change/reassignment_helpers.rb index 4d59ceda80..210f2eee67 100644 --- a/app/models/nomenclature_change/reassignment_helpers.rb +++ b/app/models/nomenclature_change/reassignment_helpers.rb @@ -20,7 +20,7 @@ def self.included(base) end def note_with_resolved_placeholders_en(input, output) - note_with_resolved_placeholders(note_en, input, output) + note_with_resolved_placeholders(note_en, input, output) end def note_with_resolved_placeholders_es(input, output) diff --git a/app/models/species/listings_export.rb b/app/models/species/listings_export.rb index f5286ae67e..76591fd50d 100644 --- a/app/models/species/listings_export.rb +++ b/app/models/species/listings_export.rb @@ -12,7 +12,7 @@ def initialize(designation, filters) :designation_id => @designation.id ).map(&:abbreviation) elsif filters[:appendices] - SpeciesListing.where( + SpeciesListing.where( :abbreviation => filters[:appendices], :designation_id => @designation.id ).map(&:abbreviation) diff --git a/app/models/trade/annual_report_upload.rb b/app/models/trade/annual_report_upload.rb index 7735f35d2a..0205da7c33 100644 --- a/app/models/trade/annual_report_upload.rb +++ b/app/models/trade/annual_report_upload.rb @@ -53,12 +53,12 @@ def validation_errors def to_jq_upload if valid? - { - "id" => self.id, - "name" => read_attribute(:csv_source_file), - "size" => csv_source_file.size, - "url" => csv_source_file.url - } + { + "id" => self.id, + "name" => read_attribute(:csv_source_file), + "size" => csv_source_file.size, + "url" => csv_source_file.url + } else { "name" => read_attribute(:csv_source_file), diff --git a/app/models/trade/shipment_report_queries.rb b/app/models/trade/shipment_report_queries.rb index a69e35e97a..3cd2680a7f 100644 --- a/app/models/trade/shipment_report_queries.rb +++ b/app/models/trade/shipment_report_queries.rb @@ -1,453 +1,453 @@ module Trade::ShipmentReportQueries def raw_query(options) - "SELECT - shipments.id, - year, - appendix, - taxon_concept_id, - full_name_with_spp(ranks.name, taxon_concept_full_name) AS taxon, - reported_taxon_concept_id, - full_name_with_spp(reported_taxon_ranks.name, reported_taxon_concept_full_name) AS reported_taxon, - taxon_concept_class_name AS class_name, - taxon_concept_order_name AS order_name, - taxon_concept_family_name AS family_name, - taxon_concept_genus_name AS genus_name, - importer_id, - importers.iso_code2 AS importer, - exporter_id, - exporters.iso_code2 AS exporter, - reported_by_exporter, - CASE - WHEN reported_by_exporter THEN 'E' - ELSE 'I' - END AS reporter_type, - country_of_origin_id, - countries_of_origin.iso_code2 AS country_of_origin, - CASE WHEN quantity = 0 THEN NULL ELSE quantity END, - unit_id, - units.code AS unit, - units.name_en AS unit_name_en, - units.name_es AS unit_name_es, - units.name_fr AS unit_name_fr, - term_id, - terms.code AS term, - terms.name_en AS term_name_en, - terms.name_es AS term_name_es, - terms.name_fr AS term_name_fr, - purpose_id, - purposes.code AS purpose, - source_id, - sources.code AS source, - import_permit_number, - export_permit_number, - origin_permit_number, - import_permits_ids, - export_permits_ids, - origin_permits_ids, - legacy_shipment_number, - uc.name AS created_by, - uu.name AS updated_by - FROM (#{basic_query(options).to_sql}) shipments - JOIN ranks - ON ranks.id = taxon_concept_rank_id - LEFT JOIN ranks AS reported_taxon_ranks - ON reported_taxon_ranks.id = reported_taxon_concept_rank_id - JOIN geo_entities importers - ON importers.id = importer_id - JOIN geo_entities exporters - ON exporters.id = exporter_id - LEFT JOIN geo_entities countries_of_origin - ON countries_of_origin.id = country_of_origin_id - LEFT JOIN trade_codes units - ON units.id = unit_id - JOIN trade_codes terms - ON terms.id = term_id - LEFT JOIN trade_codes purposes - ON purposes.id = purpose_id - LEFT JOIN trade_codes sources - ON sources.id = source_id - LEFT JOIN users as uc - ON shipments.created_by_id = uc.id - LEFT JOIN users as uu - ON shipments.updated_by_id = uu.id" + "SELECT + shipments.id, + year, + appendix, + taxon_concept_id, + full_name_with_spp(ranks.name, taxon_concept_full_name) AS taxon, + reported_taxon_concept_id, + full_name_with_spp(reported_taxon_ranks.name, reported_taxon_concept_full_name) AS reported_taxon, + taxon_concept_class_name AS class_name, + taxon_concept_order_name AS order_name, + taxon_concept_family_name AS family_name, + taxon_concept_genus_name AS genus_name, + importer_id, + importers.iso_code2 AS importer, + exporter_id, + exporters.iso_code2 AS exporter, + reported_by_exporter, + CASE + WHEN reported_by_exporter THEN 'E' + ELSE 'I' + END AS reporter_type, + country_of_origin_id, + countries_of_origin.iso_code2 AS country_of_origin, + CASE WHEN quantity = 0 THEN NULL ELSE quantity END, + unit_id, + units.code AS unit, + units.name_en AS unit_name_en, + units.name_es AS unit_name_es, + units.name_fr AS unit_name_fr, + term_id, + terms.code AS term, + terms.name_en AS term_name_en, + terms.name_es AS term_name_es, + terms.name_fr AS term_name_fr, + purpose_id, + purposes.code AS purpose, + source_id, + sources.code AS source, + import_permit_number, + export_permit_number, + origin_permit_number, + import_permits_ids, + export_permits_ids, + origin_permits_ids, + legacy_shipment_number, + uc.name AS created_by, + uu.name AS updated_by + FROM (#{basic_query(options).to_sql}) shipments + JOIN ranks + ON ranks.id = taxon_concept_rank_id + LEFT JOIN ranks AS reported_taxon_ranks + ON reported_taxon_ranks.id = reported_taxon_concept_rank_id + JOIN geo_entities importers + ON importers.id = importer_id + JOIN geo_entities exporters + ON exporters.id = exporter_id + LEFT JOIN geo_entities countries_of_origin + ON countries_of_origin.id = country_of_origin_id + LEFT JOIN trade_codes units + ON units.id = unit_id + JOIN trade_codes terms + ON terms.id = term_id + LEFT JOIN trade_codes purposes + ON purposes.id = purpose_id + LEFT JOIN trade_codes sources + ON sources.id = source_id + LEFT JOIN users as uc + ON shipments.created_by_id = uc.id + LEFT JOIN users as uu + ON shipments.updated_by_id = uu.id" end def comptab_query(options) - "SELECT - year, - appendix, - taxon_concept_id, - full_name_with_spp(ranks.name, taxon_concept_full_name) AS taxon, - taxon_concept_class_name AS class_name, - taxon_concept_order_name AS order_name, - taxon_concept_family_name AS family_name, - taxon_concept_genus_name AS genus_name, - importer_id, - importers.iso_code2 AS importer, - exporter_id, - exporters.iso_code2 AS exporter, - country_of_origin_id, - countries_of_origin.iso_code2 AS country_of_origin, - TRIM_DECIMAL_ZERO( - SUM(CASE WHEN reported_by_exporter THEN NULL ELSE quantity END) - ) AS importer_quantity, - TRIM_DECIMAL_ZERO( - SUM(CASE WHEN reported_by_exporter THEN quantity ELSE NULL END) - ) AS exporter_quantity, - term_id, - terms.code AS term, - terms.name_en AS term_name_en, - terms.name_es AS term_name_es, - terms.name_fr AS term_name_fr, - unit_id, - units.code AS unit, - units.name_en AS unit_name_en, - units.name_es AS unit_name_es, - units.name_fr AS unit_name_fr, - purpose_id, - purposes.code AS purpose, - source_id, - sources.code AS source - FROM (#{basic_query(options).to_sql}) shipments - JOIN ranks - ON ranks.id = taxon_concept_rank_id - JOIN geo_entities importers - ON importers.id = importer_id - JOIN geo_entities exporters - ON exporters.id = exporter_id - LEFT JOIN geo_entities countries_of_origin - ON countries_of_origin.id = country_of_origin_id - LEFT JOIN trade_codes units - ON units.id = unit_id - JOIN trade_codes terms - ON terms.id = term_id - LEFT JOIN trade_codes purposes - ON purposes.id = purpose_id - LEFT JOIN trade_codes sources - ON sources.id = source_id - GROUP BY - year, - appendix, - taxon_concept_family_name, - taxon_concept_id, - taxon_concept_full_name, - class_name, - order_name, - family_name, - genus_name, - ranks.name, - importer_id, - importers.iso_code2, - exporter_id, - exporters.iso_code2, - country_of_origin_id, - countries_of_origin.iso_code2, - unit_id, - units.code, - units.name_en, - units.name_es, - units.name_fr, - term_id, - terms.code, - terms.name_en, - terms.name_es, - terms.name_fr, - purpose_id, - purposes.code, - source_id, - sources.code - ORDER BY - year ASC, - appendix, - taxon_concept_family_name, - taxon_concept_full_name, - importers.iso_code2, - exporters.iso_code2, - countries_of_origin.iso_code2, - terms.code, - units.code, - purposes.code, - sources.code" + "SELECT + year, + appendix, + taxon_concept_id, + full_name_with_spp(ranks.name, taxon_concept_full_name) AS taxon, + taxon_concept_class_name AS class_name, + taxon_concept_order_name AS order_name, + taxon_concept_family_name AS family_name, + taxon_concept_genus_name AS genus_name, + importer_id, + importers.iso_code2 AS importer, + exporter_id, + exporters.iso_code2 AS exporter, + country_of_origin_id, + countries_of_origin.iso_code2 AS country_of_origin, + TRIM_DECIMAL_ZERO( + SUM(CASE WHEN reported_by_exporter THEN NULL ELSE quantity END) + ) AS importer_quantity, + TRIM_DECIMAL_ZERO( + SUM(CASE WHEN reported_by_exporter THEN quantity ELSE NULL END) + ) AS exporter_quantity, + term_id, + terms.code AS term, + terms.name_en AS term_name_en, + terms.name_es AS term_name_es, + terms.name_fr AS term_name_fr, + unit_id, + units.code AS unit, + units.name_en AS unit_name_en, + units.name_es AS unit_name_es, + units.name_fr AS unit_name_fr, + purpose_id, + purposes.code AS purpose, + source_id, + sources.code AS source + FROM (#{basic_query(options).to_sql}) shipments + JOIN ranks + ON ranks.id = taxon_concept_rank_id + JOIN geo_entities importers + ON importers.id = importer_id + JOIN geo_entities exporters + ON exporters.id = exporter_id + LEFT JOIN geo_entities countries_of_origin + ON countries_of_origin.id = country_of_origin_id + LEFT JOIN trade_codes units + ON units.id = unit_id + JOIN trade_codes terms + ON terms.id = term_id + LEFT JOIN trade_codes purposes + ON purposes.id = purpose_id + LEFT JOIN trade_codes sources + ON sources.id = source_id + GROUP BY + year, + appendix, + taxon_concept_family_name, + taxon_concept_id, + taxon_concept_full_name, + class_name, + order_name, + family_name, + genus_name, + ranks.name, + importer_id, + importers.iso_code2, + exporter_id, + exporters.iso_code2, + country_of_origin_id, + countries_of_origin.iso_code2, + unit_id, + units.code, + units.name_en, + units.name_es, + units.name_fr, + term_id, + terms.code, + terms.name_en, + terms.name_es, + terms.name_fr, + purpose_id, + purposes.code, + source_id, + sources.code + ORDER BY + year ASC, + appendix, + taxon_concept_family_name, + taxon_concept_full_name, + importers.iso_code2, + exporters.iso_code2, + countries_of_origin.iso_code2, + terms.code, + units.code, + purposes.code, + sources.code" end # this query is the basis of all gross / net reports, # which perform further groupings # it is an envelope for the shipments query def gross_net_query(options) - "SELECT - year, - appendix, - taxon_concept_id, - full_name_with_spp(ranks.name, taxon_concept_full_name) AS taxon, - importer_id, - importers.iso_code2 AS importer, - exporter_id, - exporters.iso_code2 AS exporter, - TRIM_DECIMAL_ZERO( - GREATEST( - SUM(CASE WHEN reported_by_exporter THEN NULL ELSE quantity END), - SUM(CASE WHEN reported_by_exporter THEN quantity ELSE NULL END) - ) - ) AS gross_quantity, - term_id, - terms.code AS term, - terms.name_en AS term_name_en, - terms.name_es AS term_name_es, - terms.name_fr AS term_name_fr, - unit_id, - units.code AS unit, - units.name_en AS unit_name_en, - units.name_es AS unit_name_es, - units.name_fr AS unit_name_fr - FROM (#{basic_query(options).to_sql}) shipments - JOIN ranks - ON ranks.id = taxon_concept_rank_id - JOIN geo_entities importers - ON importers.id = importer_id - JOIN geo_entities exporters - ON exporters.id = exporter_id - LEFT JOIN geo_entities countries_of_origin - ON countries_of_origin.id = country_of_origin_id - LEFT JOIN trade_codes units - ON units.id = unit_id - JOIN trade_codes terms - ON terms.id = term_id - LEFT JOIN trade_codes purposes - ON purposes.id = purpose_id - LEFT JOIN trade_codes sources - ON sources.id = source_id - GROUP BY - year, - appendix, - taxon_concept_id, - taxon_concept_full_name, - ranks.name, - importer_id, - importers.iso_code2, - exporter_id, - exporters.iso_code2, - unit_id, - units.code, - units.name_en, - units.name_es, - units.name_fr, - term_id, - terms.code, - terms.name_en, - terms.name_es, - terms.name_fr" + "SELECT + year, + appendix, + taxon_concept_id, + full_name_with_spp(ranks.name, taxon_concept_full_name) AS taxon, + importer_id, + importers.iso_code2 AS importer, + exporter_id, + exporters.iso_code2 AS exporter, + TRIM_DECIMAL_ZERO( + GREATEST( + SUM(CASE WHEN reported_by_exporter THEN NULL ELSE quantity END), + SUM(CASE WHEN reported_by_exporter THEN quantity ELSE NULL END) + ) + ) AS gross_quantity, + term_id, + terms.code AS term, + terms.name_en AS term_name_en, + terms.name_es AS term_name_es, + terms.name_fr AS term_name_fr, + unit_id, + units.code AS unit, + units.name_en AS unit_name_en, + units.name_es AS unit_name_es, + units.name_fr AS unit_name_fr + FROM (#{basic_query(options).to_sql}) shipments + JOIN ranks + ON ranks.id = taxon_concept_rank_id + JOIN geo_entities importers + ON importers.id = importer_id + JOIN geo_entities exporters + ON exporters.id = exporter_id + LEFT JOIN geo_entities countries_of_origin + ON countries_of_origin.id = country_of_origin_id + LEFT JOIN trade_codes units + ON units.id = unit_id + JOIN trade_codes terms + ON terms.id = term_id + LEFT JOIN trade_codes purposes + ON purposes.id = purpose_id + LEFT JOIN trade_codes sources + ON sources.id = source_id + GROUP BY + year, + appendix, + taxon_concept_id, + taxon_concept_full_name, + ranks.name, + importer_id, + importers.iso_code2, + exporter_id, + exporters.iso_code2, + unit_id, + units.code, + units.name_en, + units.name_es, + units.name_fr, + term_id, + terms.code, + terms.name_en, + terms.name_es, + terms.name_fr" end def gross_exports_query(options) - "WITH gross_net_subquery AS ( - #{gross_net_query(options)} - ) - #{gross_exports_subquery}" + "WITH gross_net_subquery AS ( + #{gross_net_query(options)} + ) + #{gross_exports_subquery}" end def gross_exports_subquery - "SELECT - year, - appendix, - taxon_concept_id, - taxon, - term_id, - term, - term_name_en, - term_name_es, - term_name_fr, - unit_id, - unit, - unit_name_en, - unit_name_es, - unit_name_fr, - exporter_id AS country_id, - exporter AS country, - TRIM_DECIMAL_ZERO( - SUM(gross_quantity) - ) AS gross_quantity - FROM gross_net_subquery - GROUP BY - year, - appendix, - taxon_concept_id, - taxon, - term_id, - term, - term_name_en, - term_name_es, - term_name_fr, - unit_id, - unit, - unit_name_en, - unit_name_es, - unit_name_fr, - exporter_id, - exporter - ORDER BY - appendix, - taxon, - term, - unit, - country" + "SELECT + year, + appendix, + taxon_concept_id, + taxon, + term_id, + term, + term_name_en, + term_name_es, + term_name_fr, + unit_id, + unit, + unit_name_en, + unit_name_es, + unit_name_fr, + exporter_id AS country_id, + exporter AS country, + TRIM_DECIMAL_ZERO( + SUM(gross_quantity) + ) AS gross_quantity + FROM gross_net_subquery + GROUP BY + year, + appendix, + taxon_concept_id, + taxon, + term_id, + term, + term_name_en, + term_name_es, + term_name_fr, + unit_id, + unit, + unit_name_en, + unit_name_es, + unit_name_fr, + exporter_id, + exporter + ORDER BY + appendix, + taxon, + term, + unit, + country" end def gross_imports_query(options) - "WITH gross_net_subquery AS ( - #{gross_net_query(options)} - ) - #{gross_imports_subquery}" + "WITH gross_net_subquery AS ( + #{gross_net_query(options)} + ) + #{gross_imports_subquery}" end def gross_imports_subquery - "SELECT - year, - appendix, - taxon_concept_id, - taxon, - term_id, - term, - term_name_en, - term_name_es, - term_name_fr, - unit_id, - unit, - unit_name_en, - unit_name_es, - unit_name_fr, - importer_id AS country_id, - importer AS country, - TRIM_DECIMAL_ZERO( - SUM(gross_quantity) - ) AS gross_quantity - FROM gross_net_subquery - GROUP BY - year, - appendix, - taxon_concept_id, - taxon, - term_id, - term, - term_name_en, - term_name_es, - term_name_fr, - unit_id, - unit, - unit_name_en, - unit_name_es, - unit_name_fr, - importer_id, - importer - ORDER BY - appendix, - taxon, - term, - unit, - country" + "SELECT + year, + appendix, + taxon_concept_id, + taxon, + term_id, + term, + term_name_en, + term_name_es, + term_name_fr, + unit_id, + unit, + unit_name_en, + unit_name_es, + unit_name_fr, + importer_id AS country_id, + importer AS country, + TRIM_DECIMAL_ZERO( + SUM(gross_quantity) + ) AS gross_quantity + FROM gross_net_subquery + GROUP BY + year, + appendix, + taxon_concept_id, + taxon, + term_id, + term, + term_name_en, + term_name_es, + term_name_fr, + unit_id, + unit, + unit_name_en, + unit_name_es, + unit_name_fr, + importer_id, + importer + ORDER BY + appendix, + taxon, + term, + unit, + country" end def net_exports_query(options) - "WITH exports AS ( - #{gross_exports_query(options)} - ), imports AS ( - #{gross_imports_query(options)} - ) - #{net_exports_subquery}" + "WITH exports AS ( + #{gross_exports_query(options)} + ), imports AS ( + #{gross_imports_query(options)} + ) + #{net_exports_subquery}" end def net_exports_subquery - "SELECT - exports.year, - exports.appendix, - exports.taxon_concept_id, - exports.taxon, - exports.term_id, - exports.term, - exports.term_name_en, - exports.term_name_es, - exports.term_name_fr, - exports.unit_id, - exports.unit, - exports.unit_name_en, - exports.unit_name_es, - exports.unit_name_fr, - exports.country_id, - exports.country, - TRIM_DECIMAL_ZERO( - CASE - WHEN (exports.gross_quantity - COALESCE(imports.gross_quantity, 0)) > 0 - THEN exports.gross_quantity - COALESCE(imports.gross_quantity, 0) - ELSE NULL - END - ) AS gross_quantity - FROM exports - LEFT JOIN imports - ON exports.taxon_concept_id = imports.taxon_concept_id - AND exports.appendix = imports.appendix - AND exports.year = imports.year - AND exports.term_id = imports.term_id - AND (exports.unit_id = imports.unit_id OR exports.unit_id IS NULL AND imports.unit_id IS NULL) - AND exports.year = imports.year - AND exports.country_id = imports.country_id - WHERE (exports.gross_quantity - COALESCE(imports.gross_quantity, 0)) > 0 - ORDER BY - appendix, - taxon, - term, - unit, - country" + "SELECT + exports.year, + exports.appendix, + exports.taxon_concept_id, + exports.taxon, + exports.term_id, + exports.term, + exports.term_name_en, + exports.term_name_es, + exports.term_name_fr, + exports.unit_id, + exports.unit, + exports.unit_name_en, + exports.unit_name_es, + exports.unit_name_fr, + exports.country_id, + exports.country, + TRIM_DECIMAL_ZERO( + CASE + WHEN (exports.gross_quantity - COALESCE(imports.gross_quantity, 0)) > 0 + THEN exports.gross_quantity - COALESCE(imports.gross_quantity, 0) + ELSE NULL + END + ) AS gross_quantity + FROM exports + LEFT JOIN imports + ON exports.taxon_concept_id = imports.taxon_concept_id + AND exports.appendix = imports.appendix + AND exports.year = imports.year + AND exports.term_id = imports.term_id + AND (exports.unit_id = imports.unit_id OR exports.unit_id IS NULL AND imports.unit_id IS NULL) + AND exports.year = imports.year + AND exports.country_id = imports.country_id + WHERE (exports.gross_quantity - COALESCE(imports.gross_quantity, 0)) > 0 + ORDER BY + appendix, + taxon, + term, + unit, + country" end def net_imports_query(options) - "WITH exports AS ( - #{gross_exports_query(options)} - ), imports AS ( - #{gross_imports_query(options)} - ) - #{net_imports_subquery}" + "WITH exports AS ( + #{gross_exports_query(options)} + ), imports AS ( + #{gross_imports_query(options)} + ) + #{net_imports_subquery}" end def net_imports_subquery - "SELECT - imports.year, - imports.appendix, - imports.taxon_concept_id, - imports.taxon, - imports.term_id, - imports.term, - imports.term_name_en, - imports.term_name_es, - imports.term_name_fr, - imports.unit_id, - imports.unit, - imports.unit_name_en, - imports.unit_name_es, - imports.unit_name_fr, - imports.country_id, - imports.country, - TRIM_DECIMAL_ZERO( - CASE - WHEN (imports.gross_quantity - COALESCE(exports.gross_quantity, 0)) > 0 - THEN imports.gross_quantity - COALESCE(exports.gross_quantity, 0) - ELSE NULL - END - ) AS gross_quantity - FROM imports - LEFT JOIN exports - ON exports.taxon_concept_id = imports.taxon_concept_id - AND exports.appendix = imports.appendix - AND exports.year = imports.year - AND exports.term_id = imports.term_id - AND (exports.unit_id = imports.unit_id OR exports.unit_id IS NULL AND imports.unit_id IS NULL) - AND exports.country_id = imports.country_id - WHERE (imports.gross_quantity - COALESCE(exports.gross_quantity, 0)) > 0 - ORDER BY - appendix, - taxon, - term, - unit, - country" + "SELECT + imports.year, + imports.appendix, + imports.taxon_concept_id, + imports.taxon, + imports.term_id, + imports.term, + imports.term_name_en, + imports.term_name_es, + imports.term_name_fr, + imports.unit_id, + imports.unit, + imports.unit_name_en, + imports.unit_name_es, + imports.unit_name_fr, + imports.country_id, + imports.country, + TRIM_DECIMAL_ZERO( + CASE + WHEN (imports.gross_quantity - COALESCE(exports.gross_quantity, 0)) > 0 + THEN imports.gross_quantity - COALESCE(exports.gross_quantity, 0) + ELSE NULL + END + ) AS gross_quantity + FROM imports + LEFT JOIN exports + ON exports.taxon_concept_id = imports.taxon_concept_id + AND exports.appendix = imports.appendix + AND exports.year = imports.year + AND exports.term_id = imports.term_id + AND (exports.unit_id = imports.unit_id OR exports.unit_id IS NULL AND imports.unit_id IS NULL) + AND exports.country_id = imports.country_id + WHERE (imports.gross_quantity - COALESCE(exports.gross_quantity, 0)) > 0 + ORDER BY + appendix, + taxon, + term, + unit, + country" end end diff --git a/app/serializers/species/geo_entity_serializer.rb b/app/serializers/species/geo_entity_serializer.rb index 38985c3bcf..0996f20b58 100644 --- a/app/serializers/species/geo_entity_serializer.rb +++ b/app/serializers/species/geo_entity_serializer.rb @@ -1,6 +1,6 @@ class Species::GeoEntitySerializer < ActiveModel::Serializer attributes :id, :name, :iso_code2, :geo_entity_type def geo_entity_type - object.geo_entity_type.name + object.geo_entity_type.name end end diff --git a/app/serializers/trade/inclusion_validation_rule_serializer.rb b/app/serializers/trade/inclusion_validation_rule_serializer.rb index 7cb367bcbb..8b5f233a18 100644 --- a/app/serializers/trade/inclusion_validation_rule_serializer.rb +++ b/app/serializers/trade/inclusion_validation_rule_serializer.rb @@ -1,9 +1,9 @@ class Trade::InclusionValidationRuleSerializer < Trade::ValidationRuleSerializer - attributes :valid_values_view, :scope + attributes :valid_values_view, :scope def scope - object.sanitized_sandbox_scope.map do |k, v| - "#{k} = #{v ? v : 'NULL'}" - end + object.sanitized_sandbox_scope.map do |k, v| + "#{k} = #{v ? v : 'NULL'}" + end end end diff --git a/lib/csv_column_headers_validator.rb b/lib/csv_column_headers_validator.rb index 982fc8d312..14c99927ff 100644 --- a/lib/csv_column_headers_validator.rb +++ b/lib/csv_column_headers_validator.rb @@ -6,24 +6,24 @@ def validate_each(record, attribute, value) require 'csv' begin CSV.open(value.current_path, "r") do |csv| - reported_column_headers = csv.first.map(&:downcase) - required_column_headers = if (record.point_of_view == 'E') - Trade::SandboxTemplate::CSV_EXPORTER_COLUMNS - else - Trade::SandboxTemplate::CSV_IMPORTER_COLUMNS - end.map(&:classify).map(&:downcase) - missing_columns = required_column_headers - reported_column_headers - excess_columns = reported_column_headers - required_column_headers - if !(missing_columns.empty? && excess_columns.empty?) - error_msg = "invalid column headers: " - unless missing_columns.empty? - error_msg += 'missing: ' + missing_columns.join(', ') + '; ' - end - unless excess_columns.empty? - error_msg += 'excess: ' + excess_columns.join(', ') + '; ' - end - record.errors.add(attribute, error_msg, {}) + reported_column_headers = csv.first.map(&:downcase) + required_column_headers = if (record.point_of_view == 'E') + Trade::SandboxTemplate::CSV_EXPORTER_COLUMNS + else + Trade::SandboxTemplate::CSV_IMPORTER_COLUMNS + end.map(&:classify).map(&:downcase) + missing_columns = required_column_headers - reported_column_headers + excess_columns = reported_column_headers - required_column_headers + if !(missing_columns.empty? && excess_columns.empty?) + error_msg = "invalid column headers: " + unless missing_columns.empty? + error_msg += 'missing: ' + missing_columns.join(', ') + '; ' end + unless excess_columns.empty? + error_msg += 'excess: ' + excess_columns.join(', ') + '; ' + end + record.errors.add(attribute, error_msg, {}) + end end rescue => e Rails.logger.error e.inspect diff --git a/lib/tasks/helpers_for_import.rb b/lib/tasks/helpers_for_import.rb index 9fc040af5b..20f12411e1 100644 --- a/lib/tasks/helpers_for_import.rb +++ b/lib/tasks/helpers_for_import.rb @@ -364,14 +364,14 @@ def csv_headers(path_to_file) end def db_columns_from_csv_headers(path_to_file, table_name, include_data_type = true) - m = CsvToDbMap.instance - #work out the db columns to create - csv_columns = csv_headers(path_to_file) - db_columns = csv_columns.map{ |col| m.csv_to_db(table_name, col) } - db_columns = db_columns.map{ |col| col.sub(/\s\w+$/,'')} unless include_data_type - puts csv_columns.inspect - puts db_columns.inspect - db_columns + m = CsvToDbMap.instance + #work out the db columns to create + csv_columns = csv_headers(path_to_file) + db_columns = csv_columns.map{ |col| m.csv_to_db(table_name, col) } + db_columns = db_columns.map{ |col| col.sub(/\s\w+$/,'')} unless include_data_type + puts csv_columns.inspect + puts db_columns.inspect + db_columns end def create_table_from_csv_headers(path_to_file, table_name) diff --git a/lib/tasks/import_countries.rake b/lib/tasks/import_countries.rake index a139ec54db..70b9d1c0c9 100644 --- a/lib/tasks/import_countries.rake +++ b/lib/tasks/import_countries.rake @@ -45,8 +45,9 @@ namespace :import do CSV.foreach("lib/files/country_codes_en_es_fr_utf8.csv") do |row| country = GeoEntity.find_or_initialize_by_iso_code2(row[0].strip.upcase) unless country.id.nil? - country.update_attributes(:name_fr => row[1].strip, - :name_es => row[2].strip) + country.update_attributes( + :name_fr => row[1].strip, :name_es => row[2].strip + ) end end puts "Countries updated with french and spanish names" diff --git a/lib/tasks/import_trade_names.rake b/lib/tasks/import_trade_names.rake index 52692ae996..ed17ff4417 100644 --- a/lib/tasks/import_trade_names.rake +++ b/lib/tasks/import_trade_names.rake @@ -160,10 +160,10 @@ namespace :import do end TaxonName.joins('LEFT JOIN taxon_concepts ON taxon_name_id = taxon_names.id'). where('taxon_concepts.id IS NULL').each do |t_name| - unless TaxonConcept.where(:taxon_name_id => t_name.id).any? - puts "deleting unnused taxon_name #{t_name.scientific_name}" - t_name.delete - end + unless TaxonConcept.where(:taxon_name_id => t_name.id).any? + puts "deleting unnused taxon_name #{t_name.scientific_name}" + t_name.delete + end end puts "Create trade_names relationship" diff --git a/lib/tasks/import_trade_permits.rake b/lib/tasks/import_trade_permits.rake index 8579b5d70d..ca28d0ab30 100644 --- a/lib/tasks/import_trade_permits.rake +++ b/lib/tasks/import_trade_permits.rake @@ -1,44 +1,44 @@ namespace :import do - desc "Import trade permits from csv file (usage: rake import:trade_permits[path/to/file])" - task :trade_permits, 10.times.map { |i| "file_#{i}".to_sym } => [:environment] do |t, args| + desc "Import trade permits from csv file (usage: rake import:trade_permits[path/to/file])" + task :trade_permits, 10.times.map { |i| "file_#{i}".to_sym } => [:environment] do |t, args| - TMP_TABLE = "permits_import" - permits_import_to_index = {"permits_import" => ["permit_number", "shipment_number", "permit_reporter_type"]} - trade_shipments_indexed = {"trade_shipments" => ["export_permits_ids", "import_permits_ids", "origin_permits_ids"]} - trade_shipments_to_index = {"trade_shipments" => ["legacy_shipment_number"]} + TMP_TABLE = "permits_import" + permits_import_to_index = {"permits_import" => ["permit_number", "shipment_number", "permit_reporter_type"]} + trade_shipments_indexed = {"trade_shipments" => ["export_permits_ids", "import_permits_ids", "origin_permits_ids"]} + trade_shipments_to_index = {"trade_shipments" => ["legacy_shipment_number"]} - files = files_from_args(t, args) - files.each do |file| - drop_table(TMP_TABLE) - create_table_from_csv_headers(file, TMP_TABLE) - copy_data(file, TMP_TABLE) + files = files_from_args(t, args) + files.each do |file| + drop_table(TMP_TABLE) + create_table_from_csv_headers(file, TMP_TABLE) + copy_data(file, TMP_TABLE) - drop_indices(permits_import_to_index) - drop_indices(trade_shipments_to_index) + drop_indices(permits_import_to_index) + drop_indices(trade_shipments_to_index) - drop_table(TMP_TABLE) - create_table_from_csv_headers(file, TMP_TABLE) - copy_data(file, TMP_TABLE) + drop_table(TMP_TABLE) + create_table_from_csv_headers(file, TMP_TABLE) + copy_data(file, TMP_TABLE) - create_indices(permits_import_to_index, "btree") + create_indices(permits_import_to_index, "btree") - populate_trade_permits + populate_trade_permits - drop_indices(trade_shipments_indexed) - create_indices(trade_shipments_to_index, "btree") + drop_indices(trade_shipments_indexed) + create_indices(trade_shipments_to_index, "btree") - insert_into_trade_shipments + insert_into_trade_shipments - create_indices(trade_shipments_indexed, "GIN") - drop_indices(trade_shipments_to_index) - drop_indices(permits_import_to_index) - end + create_indices(trade_shipments_indexed, "GIN") + drop_indices(trade_shipments_to_index) + drop_indices(permits_import_to_index) + end end end def execute_query sql - ActiveRecord::Base.connection.execute(sql) + ActiveRecord::Base.connection.execute(sql) end def drop_indices index From 58571c5d1c759b6fc7901b321c0b985ba13ebb6e Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 31 May 2016 16:03:05 +0100 Subject: [PATCH 274/365] fixed issues with indentation consistency --- .rubocop.yml | 9 + .rubocop_todo.yml | 7 - app/controllers/admin/cites_acs_controller.rb | 13 +- .../admin/cites_cops_controller.rb | 13 +- ...cites_extraordinary_meetings_controller.rb | 13 +- app/controllers/admin/cites_pcs_controller.rb | 13 +- ...tes_suspension_notifications_controller.rb | 15 +- app/controllers/admin/cites_tcs_controller.rb | 13 +- .../admin/designations_controller.rb | 18 +- app/controllers/admin/ec_srgs_controller.rb | 13 +- .../eu_council_regulations_controller.rb | 19 +- .../eu_implementing_regulations_controller.rb | 19 +- .../admin/eu_regulations_controller.rb | 21 +- .../eu_suspension_regulations_controller.rb | 23 +-- app/controllers/admin/events_controller.rb | 18 +- .../admin/instruments_controller.rb | 18 +- .../admin/references_controller.rb | 10 +- .../admin/simple_crud_controller.rb | 8 +- .../admin/taxonomies_controller.rb | 11 +- app/controllers/admin/users_controller.rb | 25 ++- .../v1/document_geo_entities_controller.rb | 17 +- app/models/event.rb | 20 +- app/models/iucn_mapping_manager.rb | 2 +- app/models/species/restrictions_export.rb | 4 +- .../species/eu_listing_change_serializer.rb | 28 +-- lib/capistrano/tasks/config.rake | 59 +++--- lib/tasks/elibrary/import.rake | 2 +- .../elibrary/set_document_designation.rake | 2 +- lib/tasks/import_countries.rake | 2 +- lib/tasks/import_distributions.rake | 4 +- lib/tasks/import_hybrids.rake | 188 +++++++++--------- lib/tasks/trade_appendix_report.rake | 2 +- .../admin/ahoy_events_controller_spec.rb | 10 +- .../admin/ahoy_visits_controller_spec.rb | 6 +- .../admin/eu_opinions_controller_spec.rb | 2 +- .../taxon_eu_suspensions_controller_spec.rb | 2 +- .../checklist/appendix_population_spec.rb | 4 +- ...lation_reassignments_processor_examples.rb | 2 +- .../models/trade/annual_report_upload_spec.rb | 18 +- spec/models/trade/sandbox_spec.rb | 44 ++-- 40 files changed, 351 insertions(+), 366 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 4baf2ca88e..2ed65b6fb8 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -17,3 +17,12 @@ Style/IndentArray: # SupportedStyles: special_inside_parentheses, consistent, align_braces Style/IndentHash: EnforcedStyle: consistent + +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: normal, rails +Style/IndentationConsistency: + EnforcedStyle: normal + Exclude: + - 'lib/tasks/bbgem.rake' + - 'db/migrate/*' + - 'old_cap/*' \ No newline at end of file diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index f9835c787a..3fdf5f639e 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -506,13 +506,6 @@ Style/IndentAssignment: - 'app/models/nomenclature_change/split/constructor.rb' - 'app/models/taxon_concept.rb' -# Offense count: 82 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: normal, rails -Style/IndentationConsistency: - Enabled: false - # Offense count: 126 # Cop supports --auto-correct. # Configuration parameters: Width. diff --git a/app/controllers/admin/cites_acs_controller.rb b/app/controllers/admin/cites_acs_controller.rb index 4cd581bca0..2d735e8dd4 100644 --- a/app/controllers/admin/cites_acs_controller.rb +++ b/app/controllers/admin/cites_acs_controller.rb @@ -5,11 +5,10 @@ class Admin::CitesAcsController < Admin::EventsController :instance_name => 'cites_ac' protected - def collection - @cites_acs ||= end_of_association_chain. - order(:designation_id, :name).includes(:designation). - page(params[:page]). - search(params[:query]) - end - + def collection + @cites_acs ||= end_of_association_chain. + order(:designation_id, :name).includes(:designation). + page(params[:page]). + search(params[:query]) + end end diff --git a/app/controllers/admin/cites_cops_controller.rb b/app/controllers/admin/cites_cops_controller.rb index 3843802419..1e4a0d1217 100644 --- a/app/controllers/admin/cites_cops_controller.rb +++ b/app/controllers/admin/cites_cops_controller.rb @@ -4,11 +4,10 @@ class Admin::CitesCopsController < Admin::EventsController :collection_name => 'cites_cops', :instance_name => 'cites_cop' protected - def collection - @cites_cops ||= end_of_association_chain. - order(:designation_id, :name).includes(:designation). - page(params[:page]). - search(params[:query]) - end - + def collection + @cites_cops ||= end_of_association_chain. + order(:designation_id, :name).includes(:designation). + page(params[:page]). + search(params[:query]) + end end diff --git a/app/controllers/admin/cites_extraordinary_meetings_controller.rb b/app/controllers/admin/cites_extraordinary_meetings_controller.rb index ef38ef2d51..b0f1372039 100644 --- a/app/controllers/admin/cites_extraordinary_meetings_controller.rb +++ b/app/controllers/admin/cites_extraordinary_meetings_controller.rb @@ -5,11 +5,10 @@ class Admin::CitesExtraordinaryMeetingsController < Admin::EventsController :instance_name => 'cites_extraordinary_meeting' protected - def collection - @cites_extraordinary_meetings ||= end_of_association_chain. - order(:designation_id, :name).includes(:designation). - page(params[:page]). - search(params[:query]) - end - + def collection + @cites_extraordinary_meetings ||= end_of_association_chain. + order(:designation_id, :name).includes(:designation). + page(params[:page]). + search(params[:query]) + end end diff --git a/app/controllers/admin/cites_pcs_controller.rb b/app/controllers/admin/cites_pcs_controller.rb index c11b70f37d..5de6aa61f1 100644 --- a/app/controllers/admin/cites_pcs_controller.rb +++ b/app/controllers/admin/cites_pcs_controller.rb @@ -5,11 +5,10 @@ class Admin::CitesPcsController < Admin::EventsController :instance_name => 'cites_pc' protected - def collection - @cites_pcs ||= end_of_association_chain. - order(:designation_id, :name).includes(:designation). - page(params[:page]). - search(params[:query]) - end - + def collection + @cites_pcs ||= end_of_association_chain. + order(:designation_id, :name).includes(:designation). + page(params[:page]). + search(params[:query]) + end end diff --git a/app/controllers/admin/cites_suspension_notifications_controller.rb b/app/controllers/admin/cites_suspension_notifications_controller.rb index 9a8c11aeab..43f51236f5 100644 --- a/app/controllers/admin/cites_suspension_notifications_controller.rb +++ b/app/controllers/admin/cites_suspension_notifications_controller.rb @@ -4,12 +4,11 @@ class Admin::CitesSuspensionNotificationsController < Admin::EventsController :collection_name => 'cites_suspension_notifications', :instance_name => 'cites_suspension_notification' protected - def collection - @cites_suspension_notifications ||= end_of_association_chain. - order('designation_id ASC, events.effective_at DESC, name ASC'). - includes(:designation). - page(params[:page]). - search(params[:query]) - end - + def collection + @cites_suspension_notifications ||= end_of_association_chain. + order('designation_id ASC, events.effective_at DESC, name ASC'). + includes(:designation). + page(params[:page]). + search(params[:query]) + end end diff --git a/app/controllers/admin/cites_tcs_controller.rb b/app/controllers/admin/cites_tcs_controller.rb index 71fdcb5333..3b1dffeb06 100644 --- a/app/controllers/admin/cites_tcs_controller.rb +++ b/app/controllers/admin/cites_tcs_controller.rb @@ -5,11 +5,10 @@ class Admin::CitesTcsController < Admin::EventsController :instance_name => 'cites_tc' protected - def collection - @cites_tcs ||= end_of_association_chain. - order(:designation_id, :name).includes(:designation). - page(params[:page]). - search(params[:query]) - end - + def collection + @cites_tcs ||= end_of_association_chain. + order(:designation_id, :name).includes(:designation). + page(params[:page]). + search(params[:query]) + end end diff --git a/app/controllers/admin/designations_controller.rb b/app/controllers/admin/designations_controller.rb index d2af5625d9..9ce6baf020 100644 --- a/app/controllers/admin/designations_controller.rb +++ b/app/controllers/admin/designations_controller.rb @@ -13,15 +13,13 @@ def index end protected - def collection - @designations ||= end_of_association_chain.order(:name). - page(params[:page]). - search(params[:query]) - end - - def load_associations - @taxonomies = Taxonomy.order(:name) - end + def collection + @designations ||= end_of_association_chain.order(:name). + page(params[:page]). + search(params[:query]) + end + def load_associations + @taxonomies = Taxonomy.order(:name) + end end - diff --git a/app/controllers/admin/ec_srgs_controller.rb b/app/controllers/admin/ec_srgs_controller.rb index 3ef8aefa47..ec0d93fa8a 100644 --- a/app/controllers/admin/ec_srgs_controller.rb +++ b/app/controllers/admin/ec_srgs_controller.rb @@ -5,11 +5,10 @@ class Admin::EcSrgsController < Admin::EventsController :instance_name => 'ec_srg' protected - def collection - @ec_srgs ||= end_of_association_chain. - order('designation_id, effective_at DESC').includes(:designation). - page(params[:page]). - search(params[:query]) - end - + def collection + @ec_srgs ||= end_of_association_chain. + order('designation_id, effective_at DESC').includes(:designation). + page(params[:page]). + search(params[:query]) + end end diff --git a/app/controllers/admin/eu_council_regulations_controller.rb b/app/controllers/admin/eu_council_regulations_controller.rb index 1caea2640c..6809be364b 100644 --- a/app/controllers/admin/eu_council_regulations_controller.rb +++ b/app/controllers/admin/eu_council_regulations_controller.rb @@ -4,15 +4,14 @@ class Admin::EuCouncilRegulationsController < Admin::EventsController :collection_name => 'eu_council_regulations', :instance_name => 'eu_council_regulation' protected - def collection - @eu_council_regulations ||= end_of_association_chain. - order('effective_at DESC, name ASC'). - page(params[:page]). - search(params[:query]) - end - - def list_template - 'admin/eu_regulations_common/list' - end + def collection + @eu_council_regulations ||= end_of_association_chain. + order('effective_at DESC, name ASC'). + page(params[:page]). + search(params[:query]) + end + def list_template + 'admin/eu_regulations_common/list' + end end diff --git a/app/controllers/admin/eu_implementing_regulations_controller.rb b/app/controllers/admin/eu_implementing_regulations_controller.rb index 03a973d855..0f274f7078 100644 --- a/app/controllers/admin/eu_implementing_regulations_controller.rb +++ b/app/controllers/admin/eu_implementing_regulations_controller.rb @@ -4,15 +4,14 @@ class Admin::EuImplementingRegulationsController < Admin::EventsController :collection_name => 'eu_implementing_regulations', :instance_name => 'eu_implementing_regulation' protected - def collection - @eu_implementing_regulations ||= end_of_association_chain. - order('effective_at DESC, name ASC'). - page(params[:page]). - search(params[:query]) - end - - def list_template - 'admin/eu_regulations_common/list' - end + def collection + @eu_implementing_regulations ||= end_of_association_chain. + order('effective_at DESC, name ASC'). + page(params[:page]). + search(params[:query]) + end + def list_template + 'admin/eu_regulations_common/list' + end end diff --git a/app/controllers/admin/eu_regulations_controller.rb b/app/controllers/admin/eu_regulations_controller.rb index 5411027bde..677de883c9 100644 --- a/app/controllers/admin/eu_regulations_controller.rb +++ b/app/controllers/admin/eu_regulations_controller.rb @@ -16,16 +16,15 @@ def deactivate end protected - def collection - @eu_regulations ||= end_of_association_chain. - order('effective_at DESC, name ASC'). - page(params[:page]). - search(params[:query]) - end - - def load_associations - @eu_regulations_for_dropdown = EuRegulation. - order('effective_at DESC, name ASC') - end + def collection + @eu_regulations ||= end_of_association_chain. + order('effective_at DESC, name ASC'). + page(params[:page]). + search(params[:query]) + end + def load_associations + @eu_regulations_for_dropdown = EuRegulation. + order('effective_at DESC, name ASC') + end end diff --git a/app/controllers/admin/eu_suspension_regulations_controller.rb b/app/controllers/admin/eu_suspension_regulations_controller.rb index 6fbfb4b049..ce4f0e7b72 100644 --- a/app/controllers/admin/eu_suspension_regulations_controller.rb +++ b/app/controllers/admin/eu_suspension_regulations_controller.rb @@ -16,17 +16,16 @@ def deactivate end protected - def collection - @eu_suspension_regulations ||= end_of_association_chain. - includes([:creator, :updater]). - order('effective_at DESC, name ASC'). - page(params[:page]). - search(params[:query]) - end - - def load_associations - @eu_suspension_regulations_for_dropdown = EuSuspensionRegulation. - order('effective_at DESC, name ASC') - end + def collection + @eu_suspension_regulations ||= end_of_association_chain. + includes([:creator, :updater]). + order('effective_at DESC, name ASC'). + page(params[:page]). + search(params[:query]) + end + def load_associations + @eu_suspension_regulations_for_dropdown = EuSuspensionRegulation. + order('effective_at DESC, name ASC') + end end diff --git a/app/controllers/admin/events_controller.rb b/app/controllers/admin/events_controller.rb index bd7ae810dc..6ce061e970 100644 --- a/app/controllers/admin/events_controller.rb +++ b/app/controllers/admin/events_controller.rb @@ -32,14 +32,14 @@ def show end protected - def collection - @events ||= end_of_association_chain.order(:designation_id, :name). - includes(:designation). - where(type: 'Event').page(params[:page]). - search(params[:query]) - end + def collection + @events ||= end_of_association_chain.order(:designation_id, :name). + includes(:designation). + where(type: 'Event').page(params[:page]). + search(params[:query]) + end - def load_associations - @designations = Designation.order(:name) - end + def load_associations + @designations = Designation.order(:name) + end end diff --git a/app/controllers/admin/instruments_controller.rb b/app/controllers/admin/instruments_controller.rb index e47a9cb566..b99adf0832 100644 --- a/app/controllers/admin/instruments_controller.rb +++ b/app/controllers/admin/instruments_controller.rb @@ -12,15 +12,13 @@ def index end protected - def collection - @instruments ||= end_of_association_chain.order(:name). - page(params[:page]). - search(params[:query]) - end - - def load_associations - @designations = Designation.order(:name) - end + def collection + @instruments ||= end_of_association_chain.order(:name). + page(params[:page]). + search(params[:query]) + end + def load_associations + @designations = Designation.order(:name) + end end - diff --git a/app/controllers/admin/references_controller.rb b/app/controllers/admin/references_controller.rb index 7a0bfec232..c063023864 100644 --- a/app/controllers/admin/references_controller.rb +++ b/app/controllers/admin/references_controller.rb @@ -24,10 +24,10 @@ def autocomplete end protected - def collection - @references ||= end_of_association_chain.order(:citation). - page(params[:page]). - search(params[:query]) - end + def collection + @references ||= end_of_association_chain.order(:citation). + page(params[:page]). + search(params[:query]) + end end diff --git a/app/controllers/admin/simple_crud_controller.rb b/app/controllers/admin/simple_crud_controller.rb index e981571b7f..00e8ecae72 100644 --- a/app/controllers/admin/simple_crud_controller.rb +++ b/app/controllers/admin/simple_crud_controller.rb @@ -28,10 +28,10 @@ def destroy failure.html { redirect_to collection_url, :alert => if resource.errors.present? - "Operation #{resource.errors.messages[:base].join(", ")}" - else - "Operation failed" - end + "Operation #{resource.errors.messages[:base].join(", ")}" + else + "Operation failed" + end } end end diff --git a/app/controllers/admin/taxonomies_controller.rb b/app/controllers/admin/taxonomies_controller.rb index 946154c969..3e83fb5a26 100644 --- a/app/controllers/admin/taxonomies_controller.rb +++ b/app/controllers/admin/taxonomies_controller.rb @@ -11,10 +11,9 @@ def index end protected - def collection - @taxonomies ||= end_of_association_chain.order(:name). - page(params[:page]). - search(params[:query]) - end + def collection + @taxonomies ||= end_of_association_chain.order(:name). + page(params[:page]). + search(params[:query]) + end end - diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index 7e3a1c07d4..e5c85a97fa 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -35,18 +35,17 @@ def update end protected - def collection - @users ||= end_of_association_chain. - order(:name).page(params[:page]) - end + def collection + @users ||= end_of_association_chain. + order(:name).page(params[:page]) + end - def load_associations - @countries = GeoEntity.joins(:geo_entity_type). - where( - 'geo_entity_types.name' => [GeoEntityType::COUNTRY, GeoEntityType::TERRITORY], - is_current: true - ). - order('name_en') - end + def load_associations + @countries = GeoEntity.joins(:geo_entity_type). + where( + 'geo_entity_types.name' => [GeoEntityType::COUNTRY, GeoEntityType::TERRITORY], + is_current: true + ). + order('name_en') + end end - diff --git a/app/controllers/api/v1/document_geo_entities_controller.rb b/app/controllers/api/v1/document_geo_entities_controller.rb index 9f232963e6..4d37d39faf 100644 --- a/app/controllers/api/v1/document_geo_entities_controller.rb +++ b/app/controllers/api/v1/document_geo_entities_controller.rb @@ -28,14 +28,13 @@ def index end private - def set_locale - locale = params[:locale].try(:downcase).try(:strip) || - 'en' - I18n.locale = if ['en', 'es', 'fr'].include?(locale) - locale - else - 'en' - end + def set_locale + locale = params[:locale].try(:downcase).try(:strip) || + 'en' + I18n.locale = if ['en', 'es', 'fr'].include?(locale) + locale + else + 'en' end - + end end diff --git a/app/models/event.rb b/app/models/event.rb index 90b98491ab..d466eb40dc 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -109,17 +109,17 @@ def deactivate! end protected - def designation_is_cites - cites = Designation.find_by_name('CITES') - unless designation_id && cites && designation_id == cites.id - errors.add(:designation_id, 'should be CITES') - end + def designation_is_cites + cites = Designation.find_by_name('CITES') + unless designation_id && cites && designation_id == cites.id + errors.add(:designation_id, 'should be CITES') end + end - def designation_is_eu - eu = Designation.find_by_name('EU') - unless designation_id && eu && designation_id == eu.id - errors.add(:designation_id, 'should be EU') - end + def designation_is_eu + eu = Designation.find_by_name('EU') + unless designation_id && eu && designation_id == eu.id + errors.add(:designation_id, 'should be EU') end + end end diff --git a/app/models/iucn_mapping_manager.rb b/app/models/iucn_mapping_manager.rb index 7a7fe8fc50..55350c5cf5 100644 --- a/app/models/iucn_mapping_manager.rb +++ b/app/models/iucn_mapping_manager.rb @@ -33,7 +33,7 @@ def fetch_data_for_name full_name @config ||= YAML.load_file(@config_location)[Rails.env] @token ||= @config['iucn_redlist']['token'] @url ||= @config['iucn_redlist']['url'] -puts "#{@url}#{full_name.downcase}?token=#{@token}" + puts "#{@url}#{full_name.downcase}?token=#{@token}" url = URI.escape("#{@url}#{full_name.downcase}?token=#{@token}") JSON.parse(RestClient.get(url)) end diff --git a/app/models/species/restrictions_export.rb b/app/models/species/restrictions_export.rb index 881784071b..d682385255 100644 --- a/app/models/species/restrictions_export.rb +++ b/app/models/species/restrictions_export.rb @@ -25,12 +25,12 @@ def self.fill_taxon_columns restriction taxon = restriction.taxon_concept.hybrid_parents. first.try(:m_taxon_concept) || restriction.taxon_concept.m_taxon_concept - remark = "Issued for hybrid #{restriction.taxon_concept.full_name}" + remark = "Issued for hybrid #{restriction.taxon_concept.full_name}" when "S" taxon = restriction.taxon_concept.accepted_names. first.try(:m_taxon_concept) || restriction.taxon_concept.m_taxon_concept - remark = "Issued for synonym #{restriction.taxon_concept.full_name}" + remark = "Issued for synonym #{restriction.taxon_concept.full_name}" else taxon = nil end diff --git a/app/serializers/species/eu_listing_change_serializer.rb b/app/serializers/species/eu_listing_change_serializer.rb index efe8f217c3..8eaa1946bf 100644 --- a/app/serializers/species/eu_listing_change_serializer.rb +++ b/app/serializers/species/eu_listing_change_serializer.rb @@ -4,21 +4,21 @@ class Species::EuListingChangeSerializer < Species::ListingChangeSerializer :hash_full_note_en, :hash_display, :nomenclature_note_en, :nomenclature_note_fr, :nomenclature_note_es - def change_type - if object.change_type_name == ChangeType::RESERVATION_WITHDRAWAL - "w" - elsif object.change_type_name == ChangeType::DELETION - "x" - else - object.change_type_name.downcase[0] - end + def change_type + if object.change_type_name == ChangeType::RESERVATION_WITHDRAWAL + "w" + elsif object.change_type_name == ChangeType::DELETION + "x" + else + object.change_type_name.downcase[0] end + end - def is_addition - object.change_type_name == ChangeType::ADDITION - end + def is_addition + object.change_type_name == ChangeType::ADDITION + end - def change_type_class - object.change_type_name.downcase - end + def change_type_class + object.change_type_name.downcase + end end diff --git a/lib/capistrano/tasks/config.rake b/lib/capistrano/tasks/config.rake index d60cfb4724..ceb40c33d5 100644 --- a/lib/capistrano/tasks/config.rake +++ b/lib/capistrano/tasks/config.rake @@ -1,10 +1,10 @@ namespace :config do task :setup do - ask(:db_user, 'db_user') - ask(:db_pass, 'db_pass') - ask(:db_name, 'db_name') -# ask(:db_host, 'db_host') -setup_config = <<-EOF + ask(:db_user, 'db_user') + ask(:db_pass, 'db_pass') + ask(:db_name, 'db_name') + # ask(:db_host, 'db_host') + setup_config = <<-EOF #{fetch(:rails_env)}: adapter: postgresql database: #{fetch(:db_name)} @@ -13,18 +13,18 @@ setup_config = <<-EOF socket: /var/run/postgresql/.s.PGSQL.5432 # host: #{fetch(:db_host)} EOF - on roles(:app) do - execute "mkdir -p #{shared_path}/config" - upload! StringIO.new(setup_config), "#{shared_path}/config/database.yml" + on roles(:app) do + execute "mkdir -p #{shared_path}/config" + upload! StringIO.new(setup_config), "#{shared_path}/config/database.yml" end end end namespace :config do task :setup do - ask(:smtp_user, 'smtp_user') - ask(:smtp_password, 'smtp_password') -setup_config = <<-EOF + ask(:smtp_user, 'smtp_user') + ask(:smtp_password, 'smtp_password') + setup_config = <<-EOF "#{fetch(:rails_env)}" => { :default_url_options => { :host => "#{fetch(:domain)}" @@ -41,17 +41,17 @@ setup_config = <<-EOF } } EOF - on roles(:app) do - execute "mkdir -p #{shared_path}/config" - upload! StringIO.new(setup_config), "#{shared_path}/config/mailer_config.yml" + on roles(:app) do + execute "mkdir -p #{shared_path}/config" + upload! StringIO.new(setup_config), "#{shared_path}/config/mailer_config.yml" end end end namespace :config do -task :setup do + task :setup do -vhost_config =<<-EOF + vhost_config =<<-EOF server { listen 80; @@ -119,11 +119,11 @@ server { } EOF - on roles(:app) do - execute "sudo mkdir -p /etc/nginx/sites-available" - upload! StringIO.new(vhost_config), "/tmp/vhost_config" - execute "sudo mv /tmp/vhost_config /etc/nginx/sites-available/#{fetch(:application)}" - execute "sudo ln -s /etc/nginx/sites-available/#{fetch(:application)} /etc/nginx/sites-enabled/#{fetch(:application)}" + on roles(:app) do + execute "sudo mkdir -p /etc/nginx/sites-available" + upload! StringIO.new(vhost_config), "/tmp/vhost_config" + execute "sudo mv /tmp/vhost_config /etc/nginx/sites-available/#{fetch(:application)}" + execute "sudo ln -s /etc/nginx/sites-available/#{fetch(:application)} /etc/nginx/sites-enabled/#{fetch(:application)}" end end end @@ -343,13 +343,13 @@ end namespace :config do desc "Configure app specific event handler" task :setup do - nagios_config = <<-EOF + nagios_config = <<-EOF cd #{deploy_to}/current/ ; nohup bundle exec sidekiq -e production -C #{deploy_to}/current/config/sidekiq.yml -i 0 -P #{shared_path}/tmp/pids/sidekiq.pid >> #{deploy_to}/current/log/sidekiq.log 2>&1 & EOF on roles(:app) do - upload! StringIO.new(nagios_config), "/tmp/nagios_config" - execute "sudo mv /tmp/nagios_config /usr/lib/nagios/plugins/restart-sapi-sidekiq" - execute "chmod a+x /usr/lib/nagios/plugins/restart-sapi-sidekiq" + upload! StringIO.new(nagios_config), "/tmp/nagios_config" + execute "sudo mv /tmp/nagios_config /usr/lib/nagios/plugins/restart-sapi-sidekiq" + execute "chmod a+x /usr/lib/nagios/plugins/restart-sapi-sidekiq" end end end @@ -358,7 +358,7 @@ end namespace :config do desc "Configure logrotate" task :setup do - logrotate_config = <<-EOF + logrotate_config = <<-EOF #{deploy_to}/current/log/*.log { monthly missingok @@ -370,9 +370,8 @@ namespace :config do } EOF on roles(:app) do - upload! StringIO.new(logrotate_config), "/tmp/logrotate_config" - execute "sudo mv /tmp/logrotate_config /etc/logrotate.d/#{fetch(:application)}-logs" - end + upload! StringIO.new(logrotate_config), "/tmp/logrotate_config" + execute "sudo mv /tmp/logrotate_config /etc/logrotate.d/#{fetch(:application)}-logs" + end end end - diff --git a/lib/tasks/elibrary/import.rake b/lib/tasks/elibrary/import.rake index 5060d2ffae..1e22541000 100644 --- a/lib/tasks/elibrary/import.rake +++ b/lib/tasks/elibrary/import.rake @@ -131,7 +131,7 @@ namespace :elibrary do importer.run end end - namespace :citations_no_event do + namespace :citations_no_event do require Rails.root.join('lib/tasks/elibrary/citations_no_event_importer.rb') desc 'Import citations from csv file' task :import => :environment do |task_name| diff --git a/lib/tasks/elibrary/set_document_designation.rake b/lib/tasks/elibrary/set_document_designation.rake index b0a2a1d3a1..0fabc0d805 100644 --- a/lib/tasks/elibrary/set_document_designation.rake +++ b/lib/tasks/elibrary/set_document_designation.rake @@ -5,7 +5,7 @@ namespace :elibrary do 'events.type' => ['CitesCop', 'CitesTc', 'CitesPc', 'CitesAc', 'CitesExtraordinaryMeeting'] ).update_all(designation_id: cites.id) eu = Designation.find_by_name('EU') - Document.joins(:event).where( + Document.joins(:event).where( 'events.type' => 'EcSrg' ).update_all(designation_id: eu.id) end diff --git a/lib/tasks/import_countries.rake b/lib/tasks/import_countries.rake index 70b9d1c0c9..bc3bb9089d 100644 --- a/lib/tasks/import_countries.rake +++ b/lib/tasks/import_countries.rake @@ -50,7 +50,7 @@ namespace :import do ) end end - puts "Countries updated with french and spanish names" + puts "Countries updated with french and spanish names" end end diff --git a/lib/tasks/import_distributions.rake b/lib/tasks/import_distributions.rake index 8c2ee81946..215a03cf59 100644 --- a/lib/tasks/import_distributions.rake +++ b/lib/tasks/import_distributions.rake @@ -41,8 +41,8 @@ namespace :import do ) AS subquery SQL - #TODO do sth about those unknown distributions! - ActiveRecord::Base.connection.execute(sql) + #TODO do sth about those unknown distributions! + ActiveRecord::Base.connection.execute(sql) end end puts "There are now #{Distribution.count} taxon concept distributions in the database" diff --git a/lib/tasks/import_hybrids.rake b/lib/tasks/import_hybrids.rake index 3ab7a1e2f6..4f4468605b 100644 --- a/lib/tasks/import_hybrids.rake +++ b/lib/tasks/import_hybrids.rake @@ -10,102 +10,102 @@ namespace :import do puts "There are #{TaxonConcept.where(:name_status => "H", :taxonomy_id => taxonomy_id).count} Hybrids in the database" - files = files_from_args(t, args) - files.each do |file| - drop_table(TMP_TABLE) - create_table_from_csv_headers(file, TMP_TABLE) - copy_data(file, TMP_TABLE) - - - # Importing Hybrids, step by step: - # TaxonConcepts many to one relationship with taxon_names [scientific_name] - # 1- Insert all scientific_names into taxon_names table (DISTINCT) - # 2- Join back to insert the taxon_concepts - # 3- Create taxon_relationships - sql = <<-SQL - - INSERT INTO taxon_names(scientific_name, created_at, updated_at) - SELECT subquery.*, - now()::date AS created_at, - now()::date AS created_at - FROM ( - SELECT DISTINCT full_hybrid_name - FROM #{TMP_TABLE} - - EXCEPT - - SELECT scientific_name - FROM taxon_names - ) AS subquery; - - INSERT INTO taxon_concepts (full_name, - rank_id, - taxon_name_id, - legacy_trade_code, - taxonomy_id, - name_status, - created_at, - updated_at) + files = files_from_args(t, args) + files.each do |file| + drop_table(TMP_TABLE) + create_table_from_csv_headers(file, TMP_TABLE) + copy_data(file, TMP_TABLE) + + + # Importing Hybrids, step by step: + # TaxonConcepts many to one relationship with taxon_names [scientific_name] + # 1- Insert all scientific_names into taxon_names table (DISTINCT) + # 2- Join back to insert the taxon_concepts + # 3- Create taxon_relationships + sql = <<-SQL + + INSERT INTO taxon_names(scientific_name, created_at, updated_at) + SELECT subquery.*, + now()::date AS created_at, + now()::date AS created_at + FROM ( + SELECT DISTINCT full_hybrid_name + FROM #{TMP_TABLE} + + EXCEPT + + SELECT scientific_name + FROM taxon_names + ) AS subquery; + + INSERT INTO taxon_concepts (full_name, + rank_id, + taxon_name_id, + legacy_trade_code, + taxonomy_id, + name_status, + created_at, + updated_at) + SELECT + subquery.*, + now()::date AS created_at, + now()::date AS updated_at + FROM ( SELECT - subquery.*, - now()::date AS created_at, - now()::date AS updated_at - FROM ( - SELECT - full_hybrid_name, - r.id as rank_id, - tn.id as taxon_names_id, - legacy_cites_taxon_code as legacy_trade_code, - #{taxonomy_id}, 'H' - FROM #{TMP_TABLE} - INNER JOIN ranks r ON hybrid_rank = r.name - INNER JOIN taxon_names tn ON full_hybrid_name = tn.scientific_name - - EXCEPT - - SELECT full_name, rank_id, taxon_name_id, - legacy_trade_code, - taxonomy_id, name_status - FROM taxon_concepts - WHERE taxon_concepts.taxonomy_id = #{taxonomy_id} - AND legacy_trade_code IS NOT NULL AND name_status = 'H' - - ) AS subquery; - - INSERT INTO taxon_relationships - (taxon_concept_id, - other_taxon_concept_id, - taxon_relationship_type_id, - created_at, - updated_at) + full_hybrid_name, + r.id as rank_id, + tn.id as taxon_names_id, + legacy_cites_taxon_code as legacy_trade_code, + #{taxonomy_id}, 'H' + FROM #{TMP_TABLE} + INNER JOIN ranks r ON hybrid_rank = r.name + INNER JOIN taxon_names tn ON full_hybrid_name = tn.scientific_name + + EXCEPT + + SELECT full_name, rank_id, taxon_name_id, + legacy_trade_code, + taxonomy_id, name_status + FROM taxon_concepts + WHERE taxon_concepts.taxonomy_id = #{taxonomy_id} + AND legacy_trade_code IS NOT NULL AND name_status = 'H' + + ) AS subquery; + + INSERT INTO taxon_relationships + (taxon_concept_id, + other_taxon_concept_id, + taxon_relationship_type_id, + created_at, + updated_at) + SELECT + subquery.*, + now()::date AS created_at, + now()::date AS updated_at + FROM ( SELECT - subquery.*, - now()::date AS created_at, - now()::date AS updated_at - FROM ( - SELECT - taxon_concepts.id, - other_taxon_concepts.id, - #{taxon_relationship_type_id} - FROM #{TMP_TABLE} hi - INNER JOIN taxon_concepts - ON species_plus_id = taxon_concepts.id - LEFT JOIN taxon_concepts other_taxon_concepts - ON full_hybrid_name = other_taxon_concepts.full_name - - EXCEPT - - SELECT taxon_concept_id, other_taxon_concept_id, - taxon_relationship_type_id - FROM taxon_relationships - WHERE taxon_relationship_type_id = #{taxon_relationship_type_id} - ) AS subquery; - SQL - ActiveRecord::Base.connection.execute(sql) - puts "There are #{TaxonConcept.where(:name_status => "H", - :taxonomy_id => taxonomy_id).count} Hybrids in the database" - - end + taxon_concepts.id, + other_taxon_concepts.id, + #{taxon_relationship_type_id} + FROM #{TMP_TABLE} hi + INNER JOIN taxon_concepts + ON species_plus_id = taxon_concepts.id + LEFT JOIN taxon_concepts other_taxon_concepts + ON full_hybrid_name = other_taxon_concepts.full_name + + EXCEPT + + SELECT taxon_concept_id, other_taxon_concept_id, + taxon_relationship_type_id + FROM taxon_relationships + WHERE taxon_relationship_type_id = #{taxon_relationship_type_id} + ) AS subquery; + SQL + ActiveRecord::Base.connection.execute(sql) + puts "There are #{TaxonConcept.where(:name_status => "H", + :taxonomy_id => taxonomy_id).count} Hybrids in the database" + + end end end diff --git a/lib/tasks/trade_appendix_report.rake b/lib/tasks/trade_appendix_report.rake index bebcaa52e2..bb1b477b3c 100644 --- a/lib/tasks/trade_appendix_report.rake +++ b/lib/tasks/trade_appendix_report.rake @@ -2,7 +2,7 @@ namespace :trade do task :appendix_report => :environment do dir = 'tmp/appendix_report' - Dir.mkdir(dir) unless File.exists?(dir) + Dir.mkdir(dir) unless File.exists?(dir) puts "Saving appendix report in #{dir}" # (1975..Trade::Shipment.scoped.maximum(:year)).each do |year| # puts year diff --git a/spec/controllers/admin/ahoy_events_controller_spec.rb b/spec/controllers/admin/ahoy_events_controller_spec.rb index 8b8485b172..7dbfa2a019 100644 --- a/spec/controllers/admin/ahoy_events_controller_spec.rb +++ b/spec/controllers/admin/ahoy_events_controller_spec.rb @@ -6,10 +6,12 @@ describe "index" do - let!(:ahoy_event1) {FactoryGirl.create(:ahoy_event, - :name => "Search")} - let!(:ahoy_event2) {FactoryGirl.create(:ahoy_event, - :name => "Taxon Concept")} + let!(:ahoy_event1) { + FactoryGirl.create(:ahoy_event, :name => "Search") + } + let!(:ahoy_event2) { + FactoryGirl.create(:ahoy_event, :name => "Taxon Concept") + } describe "GET index" do it "assigns to @ahoy_events sorted by time DESC" do diff --git a/spec/controllers/admin/ahoy_visits_controller_spec.rb b/spec/controllers/admin/ahoy_visits_controller_spec.rb index 74735cae72..ace830bc75 100644 --- a/spec/controllers/admin/ahoy_visits_controller_spec.rb +++ b/spec/controllers/admin/ahoy_visits_controller_spec.rb @@ -4,9 +4,9 @@ describe Admin::AhoyVisitsController, :type => :controller do login_admin -describe "index" do - let!(:ahoy_visit1) {FactoryGirl.create(:ahoy_visit, :browser => "Safari", :device_type => "Desktop")} - let!(:ahoy_visit2) {FactoryGirl.create(:ahoy_visit, :browser => "Firefox", :device_type => "Desktop")} + describe "index" do + let!(:ahoy_visit1) {FactoryGirl.create(:ahoy_visit, :browser => "Safari", :device_type => "Desktop")} + let!(:ahoy_visit2) {FactoryGirl.create(:ahoy_visit, :browser => "Firefox", :device_type => "Desktop")} describe "GET index" do it "assigns to @ahoy_events sorted by time DESC" do diff --git a/spec/controllers/admin/eu_opinions_controller_spec.rb b/spec/controllers/admin/eu_opinions_controller_spec.rb index 99d24db535..cf277f5dbd 100644 --- a/spec/controllers/admin/eu_opinions_controller_spec.rb +++ b/spec/controllers/admin/eu_opinions_controller_spec.rb @@ -46,7 +46,7 @@ ) }, :taxon_concept_id => @taxon_concept.id - response.should redirect_to(admin_taxon_concept_eu_opinions_url(@taxon_concept.id)) + response.should redirect_to(admin_taxon_concept_eu_opinions_url(@taxon_concept.id)) end end diff --git a/spec/controllers/admin/taxon_eu_suspensions_controller_spec.rb b/spec/controllers/admin/taxon_eu_suspensions_controller_spec.rb index d31d8b87a6..f874f51468 100644 --- a/spec/controllers/admin/taxon_eu_suspensions_controller_spec.rb +++ b/spec/controllers/admin/taxon_eu_suspensions_controller_spec.rb @@ -46,7 +46,7 @@ ) }, :taxon_concept_id => @taxon_concept.id - response.should redirect_to(admin_taxon_concept_eu_suspensions_url(@taxon_concept.id)) + response.should redirect_to(admin_taxon_concept_eu_suspensions_url(@taxon_concept.id)) end end diff --git a/spec/models/checklist/appendix_population_spec.rb b/spec/models/checklist/appendix_population_spec.rb index 9b2bd0e665..c649606717 100644 --- a/spec/models/checklist/appendix_population_spec.rb +++ b/spec/models/checklist/appendix_population_spec.rb @@ -107,7 +107,7 @@ end end context "when App II" do - subject{ + subject{ checklist = Checklist::Checklist.new({ :cites_appendices => ['II'], :country_ids => [poland.id] @@ -147,7 +147,7 @@ end context "when App I or II" do context "when Poland" do - subject{ + subject{ checklist = Checklist::Checklist.new({ :cites_appendices => ['I', 'II'], :country_ids => [poland.id] diff --git a/spec/models/nomenclature_change/shared/output_legislation_reassignments_processor_examples.rb b/spec/models/nomenclature_change/shared/output_legislation_reassignments_processor_examples.rb index e6860dcf24..55d377dfea 100644 --- a/spec/models/nomenclature_change/shared/output_legislation_reassignments_processor_examples.rb +++ b/spec/models/nomenclature_change/shared/output_legislation_reassignments_processor_examples.rb @@ -59,7 +59,7 @@ output: output, reassignable_type: 'CitesSuspension' ) - create( + create( :nomenclature_change_output_legislation_reassignment, output: output, reassignable_type: 'Quota' diff --git a/spec/models/trade/annual_report_upload_spec.rb b/spec/models/trade/annual_report_upload_spec.rb index f18e357828..d73aff3569 100644 --- a/spec/models/trade/annual_report_upload_spec.rb +++ b/spec/models/trade/annual_report_upload_spec.rb @@ -70,7 +70,7 @@ def invalid_file } specify {subject.should be_valid} end - context "when uploaded file as exporter with importer column headers" do + context "when uploaded file as exporter with importer column headers" do subject{ build( :annual_report_upload, @@ -86,14 +86,14 @@ def invalid_file let!(:format_validation_rule){ create_year_format_validation } - subject{ - create( - :annual_report_upload, - :point_of_view => 'I', - :csv_source_file => importer_file - ) - } - specify{ subject.validation_errors.should be_empty} + subject{ + create( + :annual_report_upload, + :point_of_view => 'I', + :csv_source_file => importer_file + ) + } + specify{ subject.validation_errors.should be_empty } end describe :create do diff --git a/spec/models/trade/sandbox_spec.rb b/spec/models/trade/sandbox_spec.rb index 190967b82a..67bc762720 100644 --- a/spec/models/trade/sandbox_spec.rb +++ b/spec/models/trade/sandbox_spec.rb @@ -1,29 +1,29 @@ require 'spec_helper' describe Trade::Sandbox, :drops_tables => true do - before(:each) do - genus = create_cites_eu_genus( - :taxon_name => create(:taxon_name, :scientific_name => 'Acipenser') - ) - @species = create_cites_eu_species( - :taxon_name => create(:taxon_name, :scientific_name => 'baerii'), - :parent_id => genus.id - ) - create(:term, :code => 'CAV') - create(:unit, :code => 'KIL') - country = create(:geo_entity_type, :name => 'COUNTRY') - @argentina = create(:geo_entity, - :geo_entity_type => country, - :name => 'Argentina', - :iso_code2 => 'AR' - ) + before(:each) do + genus = create_cites_eu_genus( + :taxon_name => create(:taxon_name, :scientific_name => 'Acipenser') + ) + @species = create_cites_eu_species( + :taxon_name => create(:taxon_name, :scientific_name => 'baerii'), + :parent_id => genus.id + ) + create(:term, :code => 'CAV') + create(:unit, :code => 'KIL') + country = create(:geo_entity_type, :name => 'COUNTRY') + @argentina = create(:geo_entity, + :geo_entity_type => country, + :name => 'Argentina', + :iso_code2 => 'AR' + ) - @portugal = create(:geo_entity, - :geo_entity_type => country, - :name => 'Portugal', - :iso_code2 => 'PT' - ) - end + @portugal = create(:geo_entity, + :geo_entity_type => country, + :name => 'Portugal', + :iso_code2 => 'PT' + ) + end let(:annual_report_upload){ aru = build(:annual_report_upload, :trading_country_id => @argentina.id, :point_of_view => 'I') aru.save(:validate => false) From 48af1d19c9ce4915660eae400c6dac94e4baedca Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 31 May 2016 16:03:27 +0100 Subject: [PATCH 275/365] specified taret ruby version fro rubocop --- .rubocop.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.rubocop.yml b/.rubocop.yml index 2ed65b6fb8..24c639951f 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,5 +1,8 @@ inherit_from: .rubocop_todo.yml +AllCops: + TargetRubyVersion: 2.2 + Style/StringLiterals: EnforcedStyle: single_quotes From bcd58c53a075891f49e45ee253a4c0e1863f42fb Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 31 May 2016 16:07:01 +0100 Subject: [PATCH 276/365] Indent the first line of the right-hand-side of a multi-line assignment. --- .rubocop_todo.yml | 8 -------- app/models/nomenclature_change/split/constructor.rb | 4 ++-- app/models/taxon_concept.rb | 3 +-- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 3fdf5f639e..4e0d98f95e 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -498,14 +498,6 @@ Style/IfInsideElse: Style/IfUnlessModifier: Enabled: false -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: IndentationWidth. -Style/IndentAssignment: - Exclude: - - 'app/models/nomenclature_change/split/constructor.rb' - - 'app/models/taxon_concept.rb' - # Offense count: 126 # Cop supports --auto-correct. # Configuration parameters: Width. diff --git a/app/models/nomenclature_change/split/constructor.rb b/app/models/nomenclature_change/split/constructor.rb index 2ec8187ff8..ef8c6427a1 100644 --- a/app/models/nomenclature_change/split/constructor.rb +++ b/app/models/nomenclature_change/split/constructor.rb @@ -101,8 +101,8 @@ def outputs_for_reassignments end def output_split_from(output, input, lng) - output_html = - if output.scientific_name.present? && output.new_scientific_name.present? + output_html = if output.scientific_name.present? && + output.new_scientific_name.present? taxon_concept_html(output.display_full_name, output.display_rank_name, output.scientific_name, output.rank.name) else diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index 4754e554ee..4197013b88 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -494,8 +494,7 @@ def maximum_2_hybrid_parents def ensure_taxonomic_position if new_record? && fixed_order_required? && taxonomic_position.blank? - prev_taxonomic_position = - if parent + prev_taxonomic_position = if parent last_sibling = TaxonConcept.where(:parent_id => parent_id). maximum(:taxonomic_position) last_sibling || (parent.taxonomic_position + '.0') From 06cfe12fad8c922c9d9db9f8a5f579dfdc8e29e2 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 31 May 2016 16:21:34 +0100 Subject: [PATCH 277/365] symmetrical array brace layout --- .rubocop.yml | 7 ++++++- .rubocop_todo.yml | 16 ---------------- app/models/country_dictionary.rb | 3 ++- app/models/taxon_concept.rb | 15 ++++++++++----- app/models/trade/validation_rule.rb | 6 ++++-- app/workers/permit_cleanup_worker.rb | 6 ++++-- app/workers/quotas_copy_worker.rb | 6 ++++-- lib/modules/downloads_cache.rb | 6 ++++-- lib/modules/trade/appendix_report.rb | 6 ++++-- ...pecies_without_legislation_or_trade_report.rb | 3 ++- 10 files changed, 40 insertions(+), 34 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 24c639951f..fec836dc6c 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -28,4 +28,9 @@ Style/IndentationConsistency: Exclude: - 'lib/tasks/bbgem.rake' - 'db/migrate/*' - - 'old_cap/*' \ No newline at end of file + - 'old_cap/*' + +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: symmetrical, new_line, same_line +Style/MultilineArrayBraceLayout: + EnforcedStyle: symmetrical diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 4e0d98f95e..c89869a01a 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -545,22 +545,6 @@ Style/MethodCallParentheses: Style/MethodDefParentheses: Enabled: false -# Offense count: 16 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: symmetrical, new_line, same_line -Style/MultilineArrayBraceLayout: - Exclude: - - 'app/models/country_dictionary.rb' - - 'app/models/quota.rb' - - 'app/models/taxon_concept.rb' - - 'app/models/trade/validation_rule.rb' - - 'app/workers/permit_cleanup_worker.rb' - - 'app/workers/quotas_copy_worker.rb' - - 'lib/modules/downloads_cache.rb' - - 'lib/modules/trade/appendix_report.rb' - - 'lib/modules/trade/species_without_legislation_or_trade_report.rb' - # Offense count: 2 Style/MultilineBlockChain: Exclude: diff --git a/app/models/country_dictionary.rb b/app/models/country_dictionary.rb index 36cee5df0d..49a59e8ba7 100644 --- a/app/models/country_dictionary.rb +++ b/app/models/country_dictionary.rb @@ -3,7 +3,8 @@ class CountryDictionary def initialize @collection = GeoEntity. - select([:"geo_entities.id", :name_en, :name_es, :name_fr, + select([ + :"geo_entities.id", :name_en, :name_es, :name_fr, :"UPPER(geo_entities.iso_code2) AS iso_code2" ]). joins(:geo_entity_type). diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index 4197013b88..24f6882008 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -78,13 +78,15 @@ class TaxonConcept < ActiveRecord::Base :conditions => [ "taxon_relationship_type_id IN (SELECT id FROM taxon_relationship_types - WHERE name = '#{TaxonRelationshipType::HAS_SYNONYM}')"] + WHERE name = '#{TaxonRelationshipType::HAS_SYNONYM}')" + ] has_many :inverse_synonym_relationships, :class_name => 'TaxonRelationship', :foreign_key => :other_taxon_concept_id, :dependent => :destroy, :conditions => [ "taxon_relationship_type_id IN (SELECT id FROM taxon_relationship_types - WHERE name = '#{TaxonRelationshipType::HAS_SYNONYM}')"] + WHERE name = '#{TaxonRelationshipType::HAS_SYNONYM}')" + ] has_many :synonyms, :class_name => 'TaxonConcept', :through => :synonym_relationships, :source => :other_taxon_concept has_many :accepted_names, :class_name => 'TaxonConcept', @@ -102,7 +104,8 @@ class TaxonConcept < ActiveRecord::Base :conditions => [ "taxon_relationship_type_id IN (SELECT id FROM taxon_relationship_types - WHERE name = '#{TaxonRelationshipType::HAS_HYBRID}')"] + WHERE name = '#{TaxonRelationshipType::HAS_HYBRID}')" + ] has_many :hybrids, :class_name => 'TaxonConcept', :through => :hybrid_relationships, :source => :other_taxon_concept has_many :hybrid_parents, :class_name => 'TaxonConcept', @@ -112,13 +115,15 @@ class TaxonConcept < ActiveRecord::Base :conditions => [ "taxon_relationship_type_id IN (SELECT id FROM taxon_relationship_types - WHERE name = '#{TaxonRelationshipType::HAS_TRADE_NAME}')"] + WHERE name = '#{TaxonRelationshipType::HAS_TRADE_NAME}')" + ] has_many :inverse_trade_name_relationships, :class_name => 'TaxonRelationship', :foreign_key => :other_taxon_concept_id, :dependent => :destroy, :conditions => [ "taxon_relationship_type_id IN (SELECT id FROM taxon_relationship_types - WHERE name = '#{TaxonRelationshipType::HAS_TRADE_NAME}')"] + WHERE name = '#{TaxonRelationshipType::HAS_TRADE_NAME}')" + ] has_many :trade_names, :class_name => 'TaxonConcept', :through => :trade_name_relationships, :source => :other_taxon_concept has_many :accepted_names_for_trade_name, :class_name => 'TaxonConcept', diff --git a/app/models/trade/validation_rule.rb b/app/models/trade/validation_rule.rb index e92e91e932..ff71b082a1 100644 --- a/app/models/trade/validation_rule.rb +++ b/app/models/trade/validation_rule.rb @@ -158,7 +158,8 @@ def required_column_names if is_strict column_names else - column_names & ['taxon_concept_id', 'taxon_name', 'appendix', 'year', 'term_code', + column_names & [ + 'taxon_concept_id', 'taxon_name', 'appendix', 'year', 'term_code', 'trading_partner', 'importer', 'exporter', 'reporter_type', 'quantity' ] end @@ -168,7 +169,8 @@ def required_shipments_columns if is_strict shipments_columns else - shipments_columns & ['taxon_concept_id', 'appendix', 'year', 'term_id', + shipments_columns & [ + 'taxon_concept_id', 'appendix', 'year', 'term_id', 'exporter_id', 'importer_id', 'reporter_type', 'quantity' ] end diff --git a/app/workers/permit_cleanup_worker.rb b/app/workers/permit_cleanup_worker.rb index bb9feffa8e..f7d13d3065 100644 --- a/app/workers/permit_cleanup_worker.rb +++ b/app/workers/permit_cleanup_worker.rb @@ -19,8 +19,10 @@ def perform(permits_ids=[]) WHERE trade_permits.id = unused_permits.id SQL ActiveRecord::Base.connection.execute( - ActiveRecord::Base.send(:sanitize_sql_array, [sql, + ActiveRecord::Base.send(:sanitize_sql_array, [ + sql, permits_ids: permits_ids.map(&:to_i) - ])) + ]) + ) end end diff --git a/app/workers/quotas_copy_worker.rb b/app/workers/quotas_copy_worker.rb index e5103c580c..6e527c6c9d 100644 --- a/app/workers/quotas_copy_worker.rb +++ b/app/workers/quotas_copy_worker.rb @@ -20,7 +20,8 @@ def perform(options) ) SQL ActiveRecord::Base.connection.execute( - ActiveRecord::Base.send(:sanitize_sql_array, [sql, + ActiveRecord::Base.send(:sanitize_sql_array, [ + sql, :from_year => options["from_year"], :start_date => Date.parse(options["start_date"]), :end_date => Date.parse(options["end_date"]), @@ -37,6 +38,7 @@ def perform(options) :to_text => options["to_text"], :current_user_id => options["current_user_id"], :url => options["url"] - ])) + ]) + ) end end diff --git a/lib/modules/downloads_cache.rb b/lib/modules/downloads_cache.rb index 3f567a475b..14d0a1ed99 100644 --- a/lib/modules/downloads_cache.rb +++ b/lib/modules/downloads_cache.rb @@ -1,7 +1,8 @@ module DownloadsCache LISTINGS_DOWNLOAD_DIRS = ['checklist', 'eu_listings', 'cites_listings', 'cms_listings'] - ADMIN_DOWNLOAD_DIRS = ['taxon_concepts_names', 'synonyms_and_trade_names', + ADMIN_DOWNLOAD_DIRS = [ + 'taxon_concepts_names', 'synonyms_and_trade_names', 'orphaned_taxon_concepts', 'taxon_concepts_distributions', 'common_names', 'species_reference_output', 'standard_reference_output', 'documents' @@ -9,7 +10,8 @@ module DownloadsCache DOWNLOAD_DIRS = LISTINGS_DOWNLOAD_DIRS + [ 'quotas', 'cites_suspensions', 'eu_decisions', 'shipments', 'comptab', 'gross_exports', 'gross_imports', 'net_exports', 'net_imports', - 'trade_download_stats'] + ADMIN_DOWNLOAD_DIRS + 'trade_download_stats' + ] + ADMIN_DOWNLOAD_DIRS def self.quotas_path downloads_path('quotas') diff --git a/lib/modules/trade/appendix_report.rb b/lib/modules/trade/appendix_report.rb index fd5813c778..5bd507cbc4 100644 --- a/lib/modules/trade/appendix_report.rb +++ b/lib/modules/trade/appendix_report.rb @@ -18,12 +18,14 @@ def initialize(shipments_rel) ).uniq @query = Trade::Shipment.from("(#{@query.to_sql}) s"). - select(['s.id', :legacy_shipment_number, :taxon_concept_id, + select([ + 's.id', :legacy_shipment_number, :taxon_concept_id, :full_name, :year, :appendix, 'ARRAY_TO_STRING(ARRAY_AGG_NOTNULL(auto_appendix ORDER BY auto_appendix), \'/\')' ]). joins('JOIN taxon_concepts ON s.taxon_concept_id = taxon_concepts.id'). - group(['s.id', :legacy_shipment_number, :taxon_concept_id, + group([ + 's.id', :legacy_shipment_number, :taxon_concept_id, 'taxon_concepts.full_name', :year, :appendix ]).order([:full_name, :year, :appendix, 's.id']) diff --git a/lib/modules/trade/species_without_legislation_or_trade_report.rb b/lib/modules/trade/species_without_legislation_or_trade_report.rb index 6d41b982f0..8c01180536 100644 --- a/lib/modules/trade/species_without_legislation_or_trade_report.rb +++ b/lib/modules/trade/species_without_legislation_or_trade_report.rb @@ -99,7 +99,8 @@ def initialize def export(file_path) export_to_csv( :query => @report_query, - :csv_columns => ["ID", "Legacy id", "Kingdom", "Phylum", "Class", + :csv_columns => [ + "ID", "Legacy id", "Kingdom", "Phylum", "Class", "Order", "Family", "Genus", "Species", "Full name", "Author year", "Name Status", "Has CITES listed descendants?", "Has EU listed descendants?", From 716a868e8bec31a8752eef3cb61922a301db607f Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 31 May 2016 16:27:32 +0100 Subject: [PATCH 278/365] symmetrical hash brace layout --- .rubocop.yml | 5 +++++ .rubocop_todo.yml | 13 ------------- app/models/checklist/pdf/index_query.rb | 3 ++- app/models/preset_tag.rb | 3 ++- spec/controllers/trade/shipments_controller_spec.rb | 3 ++- 5 files changed, 11 insertions(+), 16 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index fec836dc6c..9c26a15af9 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -34,3 +34,8 @@ Style/IndentationConsistency: # SupportedStyles: symmetrical, new_line, same_line Style/MultilineArrayBraceLayout: EnforcedStyle: symmetrical + +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: symmetrical, new_line, same_line +Style/MultilineHashBraceLayout: + EnforcedStyle: symmetrical diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index c89869a01a..d4533f7ffd 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -555,19 +555,6 @@ Style/MultilineBlockChain: Style/MultilineBlockLayout: Enabled: false -# Offense count: 7 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: symmetrical, new_line, same_line -Style/MultilineHashBraceLayout: - Exclude: - - 'app/controllers/admin/simple_crud_controller.rb' - - 'app/controllers/admin/taxon_concepts_controller.rb' - - 'app/models/checklist/pdf/index_query.rb' - - 'app/models/preset_tag.rb' - - 'spec/controllers/api/taxon_concepts_controller_spec.rb' - - 'spec/controllers/trade/shipments_controller_spec.rb' - # Offense count: 147 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. diff --git a/app/models/checklist/pdf/index_query.rb b/app/models/checklist/pdf/index_query.rb index 295d2200f2..7105cc4805 100644 --- a/app/models/checklist/pdf/index_query.rb +++ b/app/models/checklist/pdf/index_query.rb @@ -18,7 +18,8 @@ def initialize(rel, options) distinct_columns = [:name_type, :sort_name, :lng] distinct_columns_values = { - :name_type => {:basic => "'basic'", + :name_type => { + :basic => "'basic'", :english => "'common'", :spanish => "'common'", :french => "'common'", diff --git a/app/models/preset_tag.rb b/app/models/preset_tag.rb index 25923eddbc..3e540de48f 100644 --- a/app/models/preset_tag.rb +++ b/app/models/preset_tag.rb @@ -18,7 +18,8 @@ class PresetTag < ActiveRecord::Base } validates :name, :presence => true, :uniqueness => { - :scope => :model, :case_sensitive => false } + :scope => :model, :case_sensitive => false + } validates :model, :inclusion => { :in => TYPES.values } def self.search query diff --git a/spec/controllers/trade/shipments_controller_spec.rb b/spec/controllers/trade/shipments_controller_spec.rb index b2d374881e..97341e7073 100644 --- a/spec/controllers/trade/shipments_controller_spec.rb +++ b/spec/controllers/trade/shipments_controller_spec.rb @@ -175,7 +175,8 @@ time_range_end: @shipment2.year, reporter_type: 'I', exporters_ids: [@portugal.id.to_s, @argentina.id.to_s], - importers_ids: [@portugal.id.to_s, @argentina.id.to_s]} + importers_ids: [@portugal.id.to_s, @argentina.id.to_s] + } Trade::Shipment.count.should == 1 end From 00391873f1d479ab2f038802cc0726d22a2d6748 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Wed, 1 Jun 2016 09:45:25 +0100 Subject: [PATCH 279/365] Require parentheses around the arguments in method definitions --- .rubocop_todo.yml | 7 ------- app/helpers/admin_helper.rb | 4 ++-- app/helpers/application_helper.rb | 4 ++-- app/models/annotation.rb | 2 +- app/models/change_observer.rb | 2 +- app/models/cites_suspension.rb | 2 +- app/models/cms_mapping_manager.rb | 2 +- app/models/common_name.rb | 2 +- app/models/dashboard_stats.rb | 4 ++-- app/models/designation.rb | 2 +- app/models/distribution.rb | 2 +- app/models/eu_suspension.rb | 2 +- app/models/event.rb | 2 +- app/models/geo_entity.rb | 2 +- app/models/instrument.rb | 2 +- app/models/iucn_mapping_manager.rb | 10 +++++----- app/models/language.rb | 2 +- app/models/listing_change.rb | 2 +- app/models/m_taxon_concept.rb | 2 +- .../nomenclature_change/constructor_helpers.rb | 4 ++-- app/models/preset_tag.rb | 2 +- app/models/quota.rb | 4 ++-- app/models/reference.rb | 2 +- app/models/species/restrictions_export.rb | 2 +- app/models/species_listing.rb | 2 +- app/models/taxonomy.rb | 2 +- app/models/term_trade_codes_pair.rb | 2 +- app/models/trade/taxon_concept_term_pair.rb | 2 +- app/models/trade/trade_data_download_logger.rb | 4 ++-- app/models/trade_code.rb | 2 +- app/models/trade_restriction.rb | 14 +++++++------- lib/capistrano/tasks/smoke_test.rake | 2 +- lib/modules/dictionary.rb | 4 ++-- lib/modules/sapi/summary.rb | 4 ++-- lib/tasks/import_species.rake | 2 +- lib/tasks/import_trade_permits.rake | 6 +++--- old_cap/deploy.rb | 2 +- 37 files changed, 56 insertions(+), 63 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index d4533f7ffd..6ec676cbd7 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -538,13 +538,6 @@ Style/MethodCallParentheses: - 'lib/tasks/taxonomy_mapping.rake' - 'lib/tasks/update_eu_decisions_with_missing_source.rake' -# Offense count: 60 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: require_parentheses, require_no_parentheses, require_no_parentheses_except_multiline -Style/MethodDefParentheses: - Enabled: false - # Offense count: 2 Style/MultilineBlockChain: Exclude: diff --git a/app/helpers/admin_helper.rb b/app/helpers/admin_helper.rb index fd073b54e0..7de6b70e13 100644 --- a/app/helpers/admin_helper.rb +++ b/app/helpers/admin_helper.rb @@ -15,7 +15,7 @@ def ancestors_path(taxon_concept) end.compact.join(' > ').html_safe end - def tracking_info record + def tracking_info(record) info = <<-HTML

Created by #{record.creator.try(:name) || "DATA_IMPORT"} on #{record.created_at.strftime("%d/%m/%Y")}
@@ -30,7 +30,7 @@ def tracking_info record end.html_safe end - def internal_notes record + def internal_notes(record) return '' unless record.internal_notes.present? info = content_tag(:div) do content_tag(:b, 'Internal notes:') + diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 8bec27805a..67d9ad0195 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -14,7 +14,7 @@ def speciesplus_taxon_concept_url(taxon_concept) end end - def error_message_for field + def error_message_for(field) return "" if resource.errors[field].empty? && field != :password_confirmation message = if field == :password_confirmation @@ -34,7 +34,7 @@ def error_message_for field to_html "#{field.to_s.humanize.capitalize} #{message}" end - def to_html message + def to_html(message) content_tag :div, content_tag(:p, message, class: "error-message"), class: "error-box" end diff --git a/app/models/annotation.rb b/app/models/annotation.rb index c45c1c5753..11fe2e1c17 100644 --- a/app/models/annotation.rb +++ b/app/models/annotation.rb @@ -40,7 +40,7 @@ class Annotation < ActiveRecord::Base scope :for_eu, joins(:event).where("events.type = 'EuRegulation'"). order([:parent_symbol, :symbol]) - def self.search query + def self.search(query) if query.present? where("UPPER(symbol) LIKE UPPER(:query) OR UPPER(parent_symbol) LIKE UPPER(:query) diff --git a/app/models/change_observer.rb b/app/models/change_observer.rb index ef1b4b344e..614c3c004f 100644 --- a/app/models/change_observer.rb +++ b/app/models/change_observer.rb @@ -27,7 +27,7 @@ def before_destroy(model) protected - def clear_cache model + def clear_cache(model) DownloadsCacheCleanupWorker.perform_async(model.class.to_s.tableize.to_sym) end diff --git a/app/models/cites_suspension.rb b/app/models/cites_suspension.rb index 8eb76c834e..c67a12ab54 100644 --- a/app/models/cites_suspension.rb +++ b/app/models/cites_suspension.rb @@ -78,7 +78,7 @@ def end_date_formatted end_date ? end_date.strftime('%d/%m/%Y') : '' end - def self.search query + def self.search(query) if query.present? where("UPPER(geo_entities.name_en) LIKE UPPER(:query) OR UPPER(geo_entities.iso_code2) LIKE UPPER(:query) diff --git a/app/models/cms_mapping_manager.rb b/app/models/cms_mapping_manager.rb index 2d57e81e60..0afd9c2492 100644 --- a/app/models/cms_mapping_manager.rb +++ b/app/models/cms_mapping_manager.rb @@ -21,7 +21,7 @@ def sync end end - def analyse mapping + def analyse(mapping) url = URI.escape(@show_url+mapping.cms_taxon_name) species = JSON.parse(RestClient.get(url)).first if species diff --git a/app/models/common_name.rb b/app/models/common_name.rb index 9fb12e02ad..91f23ee4c4 100644 --- a/app/models/common_name.rb +++ b/app/models/common_name.rb @@ -19,7 +19,7 @@ class CommonName < ActiveRecord::Base validates :name, :presence => true, :uniqueness => {:scope => :language_id} - def self.english_to_pdf common_name + def self.english_to_pdf(common_name) words = common_name.split return common_name if words.size == 1 words.last + ", " + common_name.chomp(" "+words.last) diff --git a/app/models/dashboard_stats.rb b/app/models/dashboard_stats.rb index 6cf55cfc3a..ca7dd630e8 100644 --- a/app/models/dashboard_stats.rb +++ b/app/models/dashboard_stats.rb @@ -29,7 +29,7 @@ def trade private - def species_stats_per_taxonomy taxonomy_name + def species_stats_per_taxonomy(taxonomy_name) taxonomy = Taxonomy.find_by_name(taxonomy_name) classes = taxonomy && MTaxonConcept.where( :taxonomy_id => taxonomy.id, @@ -49,7 +49,7 @@ def species_stats_per_taxonomy taxonomy_name end || [] end - def trade_stats_per_reporter_type reporter_type + def trade_stats_per_reporter_type(reporter_type) source = Source.find_by_code('W') term = Term.find_by_code('LIV') purpose = Purpose.find_by_code('T') diff --git a/app/models/designation.rb b/app/models/designation.rb index 73818fbcb6..adceaddfae 100644 --- a/app/models/designation.rb +++ b/app/models/designation.rb @@ -43,7 +43,7 @@ def can_be_deleted? super() && !has_protected_name? end - def self.search query + def self.search(query) if query.present? where("UPPER(name) LIKE UPPER(:query)", :query => "%#{query}%") diff --git a/app/models/distribution.rb b/app/models/distribution.rb index b1244e4fb5..7d61ccb337 100644 --- a/app/models/distribution.rb +++ b/app/models/distribution.rb @@ -32,7 +32,7 @@ class Distribution < ActiveRecord::Base validates :taxon_concept_id, :uniqueness => { :scope => :geo_entity_id, :message => 'already has this distribution' } - def add_existing_references ids + def add_existing_references(ids) reference_ids = ids.split(",") reference_ids.each do |r| diff --git a/app/models/eu_suspension.rb b/app/models/eu_suspension.rb index 94550735ea..d44dd04d79 100644 --- a/app/models/eu_suspension.rb +++ b/app/models/eu_suspension.rb @@ -28,7 +28,7 @@ class EuSuspension < EuDecision - def self.search query + def self.search(query) if query.present? where("UPPER(taxon_concepts.full_name) LIKE UPPER(:query) ", :query => "%#{query}%") diff --git a/app/models/event.rb b/app/models/event.rb index d466eb40dc..908c024a69 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -90,7 +90,7 @@ def end_date_formatted end_date && end_date.strftime("%d/%m/%Y") end - def self.search query + def self.search(query) if query.present? where("UPPER(events.name) LIKE UPPER(:query) OR UPPER(events.description) LIKE UPPER(:query)", diff --git a/app/models/geo_entity.rb b/app/models/geo_entity.rb index 5e8cd77dca..3edc61ada3 100644 --- a/app/models/geo_entity.rb +++ b/app/models/geo_entity.rb @@ -105,7 +105,7 @@ def as_json(options={}) super(:only =>[:id, :iso_code2, :is_current], :methods => [:name]) end - def self.search query + def self.search(query) if query.present? where("UPPER(name_en) LIKE UPPER(:query) OR UPPER(name_fr) LIKE UPPER(:query) diff --git a/app/models/instrument.rb b/app/models/instrument.rb index 88b21eb8f7..171ff1bf9a 100644 --- a/app/models/instrument.rb +++ b/app/models/instrument.rb @@ -17,7 +17,7 @@ class Instrument < ActiveRecord::Base belongs_to :designation has_many :taxon_instruments - def self.search query + def self.search(query) if query.present? where("UPPER(name) LIKE UPPER(:query)", :query => "%#{query}%") diff --git a/app/models/iucn_mapping_manager.rb b/app/models/iucn_mapping_manager.rb index 55350c5cf5..7c437660f2 100644 --- a/app/models/iucn_mapping_manager.rb +++ b/app/models/iucn_mapping_manager.rb @@ -13,7 +13,7 @@ def sync end end - def sync_taxon_concept taxon_concept + def sync_taxon_concept(taxon_concept) mapping = IucnMapping.find_or_create_by_taxon_concept_id(taxon_concept.id) full_name = if taxon_concept.rank_id == @subspecies.id taxon_concept.full_name.insert(taxon_concept.full_name.rindex(/ /), " ssp.") @@ -28,7 +28,7 @@ def sync_taxon_concept taxon_concept end end - def fetch_data_for_name full_name + def fetch_data_for_name(full_name) @config_location ||= Rails.root.join('config/secrets.yml') @config ||= YAML.load_file(@config_location)[Rails.env] @token ||= @config['iucn_redlist']['token'] @@ -38,7 +38,7 @@ def fetch_data_for_name full_name JSON.parse(RestClient.get(url)) end - def map_taxon_concept taxon_concept, map, data + def map_taxon_concept(taxon_concept, map, data) begin match = data["result"].first puts "#{taxon_concept.full_name} #{taxon_concept.author_year} <=> #{match["scientific_name"]} #{match["authority"]}" @@ -60,7 +60,7 @@ def map_taxon_concept taxon_concept, map, data end end - def type_of_match tc, match + def type_of_match(tc, match) if tc.full_name == match["scientific_name"] if strip_authors(tc.author_year) == strip_authors(match["authority"]) puts "FULL_MATCH!" @@ -72,7 +72,7 @@ def type_of_match tc, match end end - def strip_authors author + def strip_authors(author) return '' unless author author.split(" "). reject{|p| ["and", "&", "&", ","].include?(p)}. diff --git a/app/models/language.rb b/app/models/language.rb index 705d6785e3..d3d085287a 100644 --- a/app/models/language.rb +++ b/app/models/language.rb @@ -21,7 +21,7 @@ class Language < ActiveRecord::Base validates :iso_code1, :uniqueness => true, :length => {:is => 2}, :allow_blank => true validates :iso_code3, :presence => true, :uniqueness => true, :length => {:is => 3} - def self.search query + def self.search(query) if query.present? where("UPPER(name_en) LIKE UPPER(:query) OR UPPER(name_fr) LIKE UPPER(:query) OR diff --git a/app/models/listing_change.rb b/app/models/listing_change.rb index e444a943d9..94a47182ee 100644 --- a/app/models/listing_change.rb +++ b/app/models/listing_change.rb @@ -112,7 +112,7 @@ def scientific_name taxon_concept && taxon_concept.full_name end - def self.search query + def self.search(query) if query.present? where("UPPER(taxon_concepts.full_name) LIKE UPPER(:query) OR UPPER(change_types.name) LIKE UPPER(:query) diff --git a/app/models/m_taxon_concept.rb b/app/models/m_taxon_concept.rb index 02dc524f33..bc2dbcb111 100644 --- a/app/models/m_taxon_concept.rb +++ b/app/models/m_taxon_concept.rb @@ -202,7 +202,7 @@ def synonyms_with_authors synonyms.each_with_index.map { |syn, idx| "#{syn} #{synonyms_author_years[idx]}" } end - def db_ary_to_array ary + def db_ary_to_array(ary) if respond_to?(ary) parse_pg_array( send(ary)|| '').compact.map do |e| e.force_encoding('utf-8') diff --git a/app/models/nomenclature_change/constructor_helpers.rb b/app/models/nomenclature_change/constructor_helpers.rb index a5ec88b6c1..1f096c8569 100644 --- a/app/models/nomenclature_change/constructor_helpers.rb +++ b/app/models/nomenclature_change/constructor_helpers.rb @@ -205,7 +205,7 @@ def multi_lingual_legislation_note(note_type) result end - def lower_ranks_cases full_name, existing_name, existing_rank_name + def lower_ranks_cases(full_name, existing_name, existing_rank_name) if existing_name.blank? "#{full_name}" elsif LOWER_RANKS.include?(existing_rank_name) && existing_name.present? @@ -215,7 +215,7 @@ def lower_ranks_cases full_name, existing_name, existing_rank_name end end - def higher_ranks_cases full_name, existing_name, existing_rank_name + def higher_ranks_cases(full_name, existing_name, existing_rank_name) if existing_name.blank? full_name.upcase elsif LOWER_RANKS.include?(existing_rank_name) && existing_name.present? diff --git a/app/models/preset_tag.rb b/app/models/preset_tag.rb index 3e540de48f..36cac2717a 100644 --- a/app/models/preset_tag.rb +++ b/app/models/preset_tag.rb @@ -22,7 +22,7 @@ class PresetTag < ActiveRecord::Base } validates :model, :inclusion => { :in => TYPES.values } - def self.search query + def self.search(query) if query.present? where("UPPER(name) LIKE UPPER(:query) OR UPPER(model) LIKE UPPER(:query)", diff --git a/app/models/quota.rb b/app/models/quota.rb index 92c28c54b4..e96884a7ca 100644 --- a/app/models/quota.rb +++ b/app/models/quota.rb @@ -54,7 +54,7 @@ def end_date_formatted end_date ? end_date.strftime('%d/%m/%Y') : Time.now.end_of_year.strftime("%d/%m/%Y") end - def self.search query + def self.search(query) if query.present? where("UPPER(geo_entities.name_en) LIKE UPPER(:query) OR UPPER(geo_entities.iso_code2) LIKE UPPER(:query) @@ -80,7 +80,7 @@ def self.years_array group(:years).order('years DESC').map(&:years) end - def self.count_matching params + def self.count_matching(params) Quota.where( [ "EXTRACT(year from start_date) = :year diff --git a/app/models/reference.rb b/app/models/reference.rb index b741e9eaf6..16442bd0ed 100644 --- a/app/models/reference.rb +++ b/app/models/reference.rb @@ -24,7 +24,7 @@ class Reference < ActiveRecord::Base has_many :taxon_concept_references has_many :distribution_references - def self.search query + def self.search(query) if query.present? where("UPPER(citation) LIKE UPPER(:query)", :query => "%#{query}%") diff --git a/app/models/species/restrictions_export.rb b/app/models/species/restrictions_export.rb index d682385255..e2a6a9f197 100644 --- a/app/models/species/restrictions_export.rb +++ b/app/models/species/restrictions_export.rb @@ -15,7 +15,7 @@ class Species::RestrictionsExport 'Full Name', 'Rank' ] - def self.fill_taxon_columns restriction + def self.fill_taxon_columns(restriction) columns = [] remark = "" case restriction.taxon_concept.try(:name_status) diff --git a/app/models/species_listing.rb b/app/models/species_listing.rb index 58dcd661ee..db8159748f 100644 --- a/app/models/species_listing.rb +++ b/app/models/species_listing.rb @@ -19,7 +19,7 @@ class SpeciesListing < ActiveRecord::Base validates :name, :presence => true, :uniqueness => {:scope => :designation_id} validates :abbreviation, :presence => true, :uniqueness => {:scope => :designation_id} - def self.search query + def self.search(query) if query.present? where("UPPER(species_listings.name) LIKE UPPER(:query) OR UPPER(species_listings.abbreviation) LIKE UPPER(:query) diff --git a/app/models/taxonomy.rb b/app/models/taxonomy.rb index 0b8896ca3f..03e608a91b 100644 --- a/app/models/taxonomy.rb +++ b/app/models/taxonomy.rb @@ -22,7 +22,7 @@ class Taxonomy < ActiveRecord::Base :if => lambda { |t| t.name_changed? && t.class.dict.include?(t.name_was) }, :on => :update - def self.search query + def self.search(query) if query.present? where("UPPER(name) LIKE UPPER(:query)", :query => "%#{query}%") diff --git a/app/models/term_trade_codes_pair.rb b/app/models/term_trade_codes_pair.rb index d6bae10b4c..8a72101f76 100644 --- a/app/models/term_trade_codes_pair.rb +++ b/app/models/term_trade_codes_pair.rb @@ -18,7 +18,7 @@ class TermTradeCodesPair < ActiveRecord::Base validates :term_id, :presence => true, :uniqueness => {:scope => :trade_code_id} - def self.search query + def self.search(query) if query.present? where("UPPER(trade_codes.code) LIKE UPPER(:query) OR UPPER(terms.code) LIKE UPPER(:query)", diff --git a/app/models/trade/taxon_concept_term_pair.rb b/app/models/trade/taxon_concept_term_pair.rb index 2ba791a574..ead16dd886 100644 --- a/app/models/trade/taxon_concept_term_pair.rb +++ b/app/models/trade/taxon_concept_term_pair.rb @@ -18,7 +18,7 @@ class Trade::TaxonConceptTermPair < ActiveRecord::Base belongs_to :taxon_concept belongs_to :term, :class_name => "TradeCode" - def self.search query + def self.search(query) if query.present? where("UPPER(taxon_concepts.full_name) LIKE UPPER(:query) OR UPPER(trade_codes.code) LIKE UPPER(:query)", diff --git a/app/models/trade/trade_data_download_logger.rb b/app/models/trade/trade_data_download_logger.rb index 1ebf181d14..b7ec8d6a4b 100644 --- a/app/models/trade/trade_data_download_logger.rb +++ b/app/models/trade/trade_data_download_logger.rb @@ -3,7 +3,7 @@ module Trade::TradeDataDownloadLogger module_function - def log_download request, search_params, rows + def log_download(request, search_params, rows) data = {} data["user_ip"] = request.ip data["number_of_rows"] = rows @@ -29,7 +29,7 @@ def log_download request, search_params, rows private - def self.get_field_values param, model + def self.get_field_values(param, model) if param == "" then return 'All' end if param == nil then return '' end if model.to_s == 'GeoEntity' diff --git a/app/models/trade_code.rb b/app/models/trade_code.rb index cc8e3600c3..bf96f30b9c 100644 --- a/app/models/trade_code.rb +++ b/app/models/trade_code.rb @@ -19,7 +19,7 @@ class TradeCode < ActiveRecord::Base validates :code, :presence => true, :uniqueness => {:scope => :type} - def self.search query + def self.search(query) if query.present? where("UPPER(code) LIKE UPPER(:query) OR UPPER(name_en) LIKE UPPER(:query) diff --git a/app/models/trade_restriction.rb b/app/models/trade_restriction.rb index 80b47ab7e6..7f7a6da3a7 100644 --- a/app/models/trade_restriction.rb +++ b/app/models/trade_restriction.rb @@ -80,7 +80,7 @@ def unit_name unit_id ? unit.name_en : '' end - def self.export filters + def self.export(filters) return false unless export_query(filters).any? path = "public/downloads/#{self.to_s.tableize}/" latest = self.order("updated_at DESC"). @@ -101,7 +101,7 @@ def self.export filters ] end - def self.export_query filters + def self.export_query(filters) self.joins(:geo_entity). joins(<<-SQL LEFT JOIN taxon_concepts ON taxon_concepts.id = trade_restrictions.taxon_concept_id @@ -127,7 +127,7 @@ def self.csv_columns_headers end.flatten end - def self.to_csv file_path, filters + def self.to_csv(file_path, filters) limit = 1000 offset = 0 csv_separator_char = case filters[:csv_separator] @@ -159,14 +159,14 @@ def self.to_csv file_path, filters end end - def self.filter_is_current set + def self.filter_is_current(set) if set == "current" return where(:is_current => true) end scoped end - def self.filter_geo_entities filters + def self.filter_geo_entities(filters) if filters.has_key?("geo_entities_ids") geo_entities_ids = GeoEntity.nodes_and_descendants( filters["geo_entities_ids"] @@ -176,7 +176,7 @@ def self.filter_geo_entities filters scoped end - def self.filter_taxon_concepts filters + def self.filter_taxon_concepts(filters) if filters.has_key?("taxon_concepts_ids") conds_str = <<-SQL ARRAY[ @@ -191,7 +191,7 @@ def self.filter_taxon_concepts filters scoped end - def self.filter_years filters + def self.filter_years(filters) if filters.has_key?("years") return where('EXTRACT(YEAR FROM trade_restrictions.start_date) IN (?)', filters["years"]) diff --git a/lib/capistrano/tasks/smoke_test.rake b/lib/capistrano/tasks/smoke_test.rake index d1f76bd19e..9e5e4b5e96 100644 --- a/lib/capistrano/tasks/smoke_test.rake +++ b/lib/capistrano/tasks/smoke_test.rake @@ -34,7 +34,7 @@ namespace :smoke_test do slack_smoke_notification message end - def slack_smoke_notification message + def slack_smoke_notification(message) uri = URI.parse("https://hooks.slack.com/services/T028F7AGY/B036GEF7T/#{fetch(:slack_token)}") payload = { diff --git a/lib/modules/dictionary.rb b/lib/modules/dictionary.rb index 28b721c814..c9d2d65a0d 100644 --- a/lib/modules/dictionary.rb +++ b/lib/modules/dictionary.rb @@ -7,7 +7,7 @@ def self.included(base) module ClassMethods #builds a set of constants like: KEY = 'KEY' #as well as a method self.dict that returns all of those constants' values - def build_dictionary *keys + def build_dictionary(*keys) # keys.each do |key| # const_set key.to_s.upcase, key.to_s.upcase # end @@ -15,7 +15,7 @@ def build_dictionary *keys build_basic_dictionary(*keys){ |key| key.to_s.upcase } end - def build_basic_dictionary *keys + def build_basic_dictionary(*keys) keys.each do |key| const_set key.to_s.upcase, if block_given? diff --git a/lib/modules/sapi/summary.rb b/lib/modules/sapi/summary.rb index 4b1a507055..c889675943 100644 --- a/lib/modules/sapi/summary.rb +++ b/lib/modules/sapi/summary.rb @@ -75,7 +75,7 @@ def self.trade_restrictions_stats trade end - def self.taxonomy_kingdom_stats taxonomy, kingdom + def self.taxonomy_kingdom_stats(taxonomy, kingdom) stats = {} t = Taxonomy.find_by_name(taxonomy) k = TaxonConcept.find_by_full_name_and_taxonomy_id(kingdom, t.id) @@ -210,7 +210,7 @@ def self.kingdom_summary(t, k) puts "" end - def self.print_count_for klass, count + def self.print_count_for(klass, count) puts "#{count} #{klass}" end diff --git a/lib/tasks/import_species.rake b/lib/tasks/import_species.rake index 04bc474772..a7324d9873 100644 --- a/lib/tasks/import_species.rake +++ b/lib/tasks/import_species.rake @@ -31,7 +31,7 @@ end # Copies data from the temporary table to the correct tables in the database # # @param [String] which the rank to be copied. -def import_data_for kingdom, rank, synonyms=nil +def import_data_for(kingdom, rank, synonyms=nil) puts "Importing #{rank}" rank_id = Rank.select(:id).where(:name => rank).first.id existing = TaxonConcept.where(:rank_id => rank_id).count diff --git a/lib/tasks/import_trade_permits.rake b/lib/tasks/import_trade_permits.rake index ca28d0ab30..4cb4e6c047 100644 --- a/lib/tasks/import_trade_permits.rake +++ b/lib/tasks/import_trade_permits.rake @@ -37,11 +37,11 @@ namespace :import do end end -def execute_query sql +def execute_query(sql) ActiveRecord::Base.connection.execute(sql) end -def drop_indices index +def drop_indices(index) index.each do |table, columns| columns.each do |column| sql = <<-SQL @@ -53,7 +53,7 @@ def drop_indices index end end -def create_indices table_columns, method +def create_indices(table_columns, method) table_columns.each do |table,columns| columns.each do |column| sql = <<-SQL diff --git a/old_cap/deploy.rb b/old_cap/deploy.rb index 8f17e76ee8..4b1e57463a 100644 --- a/old_cap/deploy.rb +++ b/old_cap/deploy.rb @@ -372,7 +372,7 @@ slack_smoke_notification message end -def slack_smoke_notification message +def slack_smoke_notification(message) uri = URI.parse("https://hooks.slack.com/services/T028F7AGY/B036GEF7T/#{slack_token}") payload = { From c8f1d2f63a99cdc0200c4465978043f3050d4809 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Wed, 1 Jun 2016 09:48:32 +0100 Subject: [PATCH 280/365] Do not use parentheses for method calls with no arguments --- .rubocop_todo.yml | 13 ------------- app/controllers/trade/exports_controller.rb | 2 +- app/controllers/trade/statistics_controller.rb | 2 +- app/models/nomenclature_change/split/constructor.rb | 2 +- lib/tasks/import_countries.rake | 2 +- lib/tasks/map_eu_opinions_to_ec_srgs.rake | 2 +- ...p_eu_suspensions_to_terminating_regulations.rake | 2 +- lib/tasks/taxonomy_mapping.rake | 6 +++--- .../update_eu_decisions_with_missing_source.rake | 2 +- 9 files changed, 10 insertions(+), 23 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 6ec676cbd7..d1b0fa07a3 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -525,19 +525,6 @@ Style/LineEndConcatenation: Exclude: - 'app/helpers/admin_helper.rb' -# Offense count: 10 -# Cop supports --auto-correct. -Style/MethodCallParentheses: - Exclude: - - 'app/controllers/trade/exports_controller.rb' - - 'app/controllers/trade/statistics_controller.rb' - - 'app/models/nomenclature_change/split/constructor.rb' - - 'lib/tasks/import_countries.rake' - - 'lib/tasks/map_eu_opinions_to_ec_srgs.rake' - - 'lib/tasks/map_eu_suspensions_to_terminating_regulations.rake' - - 'lib/tasks/taxonomy_mapping.rake' - - 'lib/tasks/update_eu_decisions_with_missing_source.rake' - # Offense count: 2 Style/MultilineBlockChain: Exclude: diff --git a/app/controllers/trade/exports_controller.rb b/app/controllers/trade/exports_controller.rb index 42b36c2c8a..460ead8c82 100644 --- a/app/controllers/trade/exports_controller.rb +++ b/app/controllers/trade/exports_controller.rb @@ -23,7 +23,7 @@ def download end def download_stats - stats = Trade::TradeDataDownloadsExport.new() + stats = Trade::TradeDataDownloadsExport.new respond_to do |format| format.html { result = stats.export diff --git a/app/controllers/trade/statistics_controller.rb b/app/controllers/trade/statistics_controller.rb index b7974ab0d2..2af1a3e27c 100644 --- a/app/controllers/trade/statistics_controller.rb +++ b/app/controllers/trade/statistics_controller.rb @@ -14,7 +14,7 @@ def index where("created_at::DATE BETWEEN ? AND ?", @start_date, @end_date). where('created_at != updated_at'). count - @taxon_concepts_in_trade = Trade::Shipment.from('(SELECT taxon_concept_id FROM trade_shipments GROUP BY taxon_concept_id) s').count() + @taxon_concepts_in_trade = Trade::Shipment.from('(SELECT taxon_concept_id FROM trade_shipments GROUP BY taxon_concept_id) s').count end def summary_creation diff --git a/app/models/nomenclature_change/split/constructor.rb b/app/models/nomenclature_change/split/constructor.rb index ef8c6427a1..32b470b210 100644 --- a/app/models/nomenclature_change/split/constructor.rb +++ b/app/models/nomenclature_change/split/constructor.rb @@ -14,7 +14,7 @@ def build_outputs @nomenclature_change.outputs.build( taxon_concept_id: @nomenclature_change.input.taxon_concept_id ) - @nomenclature_change.outputs.build() + @nomenclature_change.outputs.build end end diff --git a/lib/tasks/import_countries.rake b/lib/tasks/import_countries.rake index bc3bb9089d..a5b02b4dc7 100644 --- a/lib/tasks/import_countries.rake +++ b/lib/tasks/import_countries.rake @@ -33,7 +33,7 @@ namespace :import do ) SQL ActiveRecord::Base.connection.execute(sql) - link_countries() + link_countries end puts "There are now #{GeoEntity.count(conditions: {geo_entity_type_id: country_type.id})} countries in the database" puts "There are now #{GeoEntity.count(conditions: {geo_entity_type_id: territory_type.id})} territories in the database." diff --git a/lib/tasks/map_eu_opinions_to_ec_srgs.rake b/lib/tasks/map_eu_opinions_to_ec_srgs.rake index 67595eefb6..62cf623519 100644 --- a/lib/tasks/map_eu_opinions_to_ec_srgs.rake +++ b/lib/tasks/map_eu_opinions_to_ec_srgs.rake @@ -38,5 +38,5 @@ task :map_eu_opinions_to_ec_srgs => :environment do RETURNING *; SQL res = ActiveRecord::Base.connection.execute update_query - puts "#{res.cmd_tuples()} rows linked to EC SRG meetings" + puts "#{res.cmd_tuples} rows linked to EC SRG meetings" end diff --git a/lib/tasks/map_eu_suspensions_to_terminating_regulations.rake b/lib/tasks/map_eu_suspensions_to_terminating_regulations.rake index 3d417ed871..ca05732681 100644 --- a/lib/tasks/map_eu_suspensions_to_terminating_regulations.rake +++ b/lib/tasks/map_eu_suspensions_to_terminating_regulations.rake @@ -18,5 +18,5 @@ task :map_eu_suspensions_to_terminating_regulations => :environment do RETURNING *; SQL res = ActiveRecord::Base.connection.execute update_query - puts "#{res.cmd_tuples()} rows linked to terminating EU Suspension Regulations" + puts "#{res.cmd_tuples} rows linked to terminating EU Suspension Regulations" end diff --git a/lib/tasks/taxonomy_mapping.rake b/lib/tasks/taxonomy_mapping.rake index 625b713b89..2d66b6b990 100644 --- a/lib/tasks/taxonomy_mapping.rake +++ b/lib/tasks/taxonomy_mapping.rake @@ -2,16 +2,16 @@ namespace :taxonomy_mapping do desc 'Update mapping between CITES species and IUCN species' task :iucn_mapping => :environment do - Admin::IucnMappingManager.sync() + Admin::IucnMappingManager.sync end desc 'Update mapping between CMS species in Species+ and CMS species' task :cms_mapping => :environment do - Admin::CmsMappingManager.sync() + Admin::CmsMappingManager.sync end desc 'Copy CITES distribution data to CMS species' task :fill_cms_distributions => :environment do - Admin::CmsMappingManager.fill_cms_distributions() + Admin::CmsMappingManager.fill_cms_distributions end end diff --git a/lib/tasks/update_eu_decisions_with_missing_source.rake b/lib/tasks/update_eu_decisions_with_missing_source.rake index 4d7051e6db..08901928b8 100644 --- a/lib/tasks/update_eu_decisions_with_missing_source.rake +++ b/lib/tasks/update_eu_decisions_with_missing_source.rake @@ -44,6 +44,6 @@ namespace :update do SQL res = ActiveRecord::Base.connection.execute update_query - puts "#{res.cmd_tuples()} rows linked to 'W' source" + puts "#{res.cmd_tuples} rows linked to 'W' source" end end From 4eb42f89760263a561cd1a4f642c9005d3510cc0 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Wed, 1 Jun 2016 09:55:08 +0100 Subject: [PATCH 281/365] Use && instead of and --- .rubocop.yml | 7 +++++++ .rubocop_todo.yml | 12 ------------ app/controllers/api/v1/documents_controller.rb | 2 +- app/controllers/species/exports_controller.rb | 2 +- 4 files changed, 9 insertions(+), 14 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 9c26a15af9..58d457a177 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -39,3 +39,10 @@ Style/MultilineArrayBraceLayout: # SupportedStyles: symmetrical, new_line, same_line Style/MultilineHashBraceLayout: EnforcedStyle: symmetrical + +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: always, conditionals +Style/AndOr: + Exclude: + - 'lib/tasks/bbgem.rake' + - 'db/migrate/*' diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index d1b0fa07a3..4ebd608f1a 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -238,18 +238,6 @@ Style/AlignHash: Style/AlignParameters: Enabled: false -# Offense count: 7 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: always, conditionals -Style/AndOr: - Exclude: - - 'app/controllers/api/v1/documents_controller.rb' - - 'app/controllers/species/exports_controller.rb' - - 'db/migrate/20120530135534_setup_hstore.rb' - - 'db/migrate/20120703141230_setup_tablefunc.rb' - - 'lib/tasks/bbgem.rake' - # Offense count: 993 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, ProceduralMethods, FunctionalMethods, IgnoredMethods. diff --git a/app/controllers/api/v1/documents_controller.rb b/app/controllers/api/v1/documents_controller.rb index abbc48dbf1..2d45d61794 100644 --- a/app/controllers/api/v1/documents_controller.rb +++ b/app/controllers/api/v1/documents_controller.rb @@ -70,7 +70,7 @@ def download_zip end if missing_files.present? if missing_files.length == @documents.count - render_404 and return + render_404 && return end zos.put_next_entry('missing_files.txt') zos.print missing_files.join("\n\n") diff --git a/app/controllers/species/exports_controller.rb b/app/controllers/species/exports_controller.rb index 4e5598e363..5f0ce77373 100644 --- a/app/controllers/species/exports_controller.rb +++ b/app/controllers/species/exports_controller.rb @@ -53,7 +53,7 @@ def set_csv_separator def ensure_data_type_and_filters unless params[:data_type] && params[:filters] - render :nothing => true, :status => :unprocessable_entity and return false + render(:nothing => true, :status => :unprocessable_entity) && (return false) end end end From 1bdf90ae5c98dc6f9a7adcf38a7607a01e0694a8 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Wed, 1 Jun 2016 10:09:51 +0100 Subject: [PATCH 282/365] Require end statement of a do..end block is on its own line --- .rubocop_todo.yml | 15 ---- .../cites_suspension_notification_spec.rb | 32 ++++--- spec/models/designation_spec.rb | 16 ++-- .../shared/split_definitions.rb | 3 +- spec/models/purpose_spec.rb | 6 +- spec/models/source_spec.rb | 20 ++--- spec/models/taxon_relationship_spec.rb | 88 +++++++++++++------ spec/models/term_spec.rb | 20 ++--- 8 files changed, 109 insertions(+), 91 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 4ebd608f1a..e9d4e7b824 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -248,21 +248,6 @@ Style/AlignParameters: Style/BlockDelimiters: Enabled: false -# Offense count: 25 -# Cop supports --auto-correct. -Style/BlockEndNewline: - Exclude: - - 'spec/controllers/admin/ahoy_events_controller_spec.rb' - - 'spec/controllers/api/taxon_concepts_controller_spec.rb' - - 'spec/models/cites_suspension_notification_spec.rb' - - 'spec/models/designation_spec.rb' - - 'spec/models/nomenclature_change/shared/split_definitions.rb' - - 'spec/models/purpose_spec.rb' - - 'spec/models/source_spec.rb' - - 'spec/models/taxon_concept_prefix_matcher_spec.rb' - - 'spec/models/taxon_relationship_spec.rb' - - 'spec/models/term_spec.rb' - # Offense count: 243 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. diff --git a/spec/models/cites_suspension_notification_spec.rb b/spec/models/cites_suspension_notification_spec.rb index df3810ca3e..0d9175f38f 100644 --- a/spec/models/cites_suspension_notification_spec.rb +++ b/spec/models/cites_suspension_notification_spec.rb @@ -56,25 +56,31 @@ end context "when dependent objects attached" do context "when start notification" do - let!(:cites_suspension){ create( - :cites_suspension, :start_notification => cites_suspension_notification - ) } + let!(:cites_suspension){ + create( + :cites_suspension, :start_notification => cites_suspension_notification + ) + } specify { cites_suspension_notification.destroy.should be_false } end context "when end notification" do - let!(:cites_suspension){ create( - :cites_suspension, - :start_notification => create_cites_suspension_notification, - :end_notification => cites_suspension_notification - ) } + let!(:cites_suspension){ + create( + :cites_suspension, + :start_notification => create_cites_suspension_notification, + :end_notification => cites_suspension_notification + ) + } specify { cites_suspension_notification.destroy.should be_false } end context "when confirmation notification, make sure it gets destroyed" do - let!(:cites_suspension){ create( - :cites_suspension, - :start_notification => create_cites_suspension_notification, - :confirmation_notifications => [cites_suspension_notification] - ) } + let!(:cites_suspension){ + create( + :cites_suspension, + :start_notification => create_cites_suspension_notification, + :confirmation_notifications => [cites_suspension_notification] + ) + } subject { cites_suspension_notification.cites_suspension_confirmations } specify{ cites_suspension_notification.destroy diff --git a/spec/models/designation_spec.rb b/spec/models/designation_spec.rb index fa40639dac..65294cf735 100644 --- a/spec/models/designation_spec.rb +++ b/spec/models/designation_spec.rb @@ -32,14 +32,18 @@ describe :update do context "when updating a non-protected name" do let(:designation){ create(:designation) } - specify{ designation.update_attributes( - {:name => 'RULES OF INTERGALACTIC TRADE'} - ).should be_true } + specify{ + designation.update_attributes( + {:name => 'RULES OF INTERGALACTIC TRADE'} + ).should be_true + } end context "when updating a protected name" do - specify{ cites.update_attributes( - {:name => 'RULES OF INTERGALACTIC TRADE'} - ).should be_false } + specify{ + cites.update_attributes( + {:name => 'RULES OF INTERGALACTIC TRADE'} + ).should be_false + } end context "when updating taxonomy with no dependent objects attached" do let(:designation){ create(:designation) } diff --git a/spec/models/nomenclature_change/shared/split_definitions.rb b/spec/models/nomenclature_change/shared/split_definitions.rb index 1e2e6ae5db..54934f3858 100644 --- a/spec/models/nomenclature_change/shared/split_definitions.rb +++ b/spec/models/nomenclature_change/shared/split_definitions.rb @@ -105,7 +105,8 @@ taxon_concept: input_species, other_taxon_concept: create_cites_eu_species(name_status: 'S'), taxon_relationship_type: synonym_relationship_type - )} + ) + } name1 = create(:taxon_relationship, taxon_concept: input_species, other_taxon_concept: create_cites_eu_species(name_status: 'S'), diff --git a/spec/models/purpose_spec.rb b/spec/models/purpose_spec.rb index b426a0af27..aed80360d3 100644 --- a/spec/models/purpose_spec.rb +++ b/spec/models/purpose_spec.rb @@ -23,11 +23,13 @@ context "when dependent objects attached" do let(:purpose){ create(:purpose) } context "when CITES suspension" do - let!(:cites_suspension){ create( + let!(:cites_suspension){ + create( :cites_suspension, :purposes => [purpose], :start_notification_id => create_cites_suspension_notification.id - ) } + ) + } specify { purpose.destroy.should be_false } end context "when shipments" do diff --git a/spec/models/source_spec.rb b/spec/models/source_spec.rb index 4435af5add..5678339571 100644 --- a/spec/models/source_spec.rb +++ b/spec/models/source_spec.rb @@ -22,20 +22,14 @@ end context "when dependent objects attached" do let(:source){ create(:source) } - #context "when EU opinion" do - # let!(:eu_opinion){ create(:eu_opinion, :source => source)} - # specify { source.destroy.should be_false } - #end - #context "when EU suspension" do - # let!(:eu_suspension){ create(:eu_suspension, :source => source)} - # specify { source.destroy.should be_false } - #end context "when CITES suspension" do - let!(:cites_suspension){ create( - :cites_suspension, - :sources => [source], - :start_notification_id => create_cites_suspension_notification.id - ) } + let!(:cites_suspension){ + create( + :cites_suspension, + :sources => [source], + :start_notification_id => create_cites_suspension_notification.id + ) + } specify { source.destroy.should be_false } end context "when CITES quota" do diff --git a/spec/models/taxon_relationship_spec.rb b/spec/models/taxon_relationship_spec.rb index ccad54b0dc..dd5f860076 100644 --- a/spec/models/taxon_relationship_spec.rb +++ b/spec/models/taxon_relationship_spec.rb @@ -49,12 +49,20 @@ let(:taxon_concept) { create(:taxon_concept, :taxonomy_id => taxonomy.id) } let(:taxon_concept2) { create(:taxon_concept, :taxonomy_id => taxonomy2.id) } let(:taxon_relationship_type) { create(:taxon_relationship_type) } - let!(:taxon_relationship) { create(:taxon_relationship, :taxon_concept_id => taxon_concept.id, - :other_taxon_concept_id => taxon_concept2.id, - :taxon_relationship_type_id => taxon_relationship_type.id) } - let(:taxon_relationship2) { build(:taxon_relationship, :taxon_concept_id => taxon_concept.id, - :other_taxon_concept_id => taxon_concept2.id, - :taxon_relationship_type_id => taxon_relationship_type.id) } + let!(:taxon_relationship) { + create(:taxon_relationship, + :taxon_concept_id => taxon_concept.id, + :other_taxon_concept_id => taxon_concept2.id, + :taxon_relationship_type_id => taxon_relationship_type.id + ) + } + let(:taxon_relationship2) { + build(:taxon_relationship, + :taxon_concept_id => taxon_concept.id, + :other_taxon_concept_id => taxon_concept2.id, + :taxon_relationship_type_id => taxon_relationship_type.id + ) + } specify { taxon_relationship2.valid? == false } end end @@ -67,14 +75,22 @@ let(:taxon_concept2) { create(:taxon_concept, :taxonomy_id => taxonomy2.id) } let(:taxon_relationship_type) { create(:taxon_relationship_type, :is_intertaxonomic => true) } let(:taxon_relationship_type2) { create(:taxon_relationship_type, :is_intertaxonomic => true) } - let!(:taxon_relationship) { create(:taxon_relationship, :taxon_concept_id => taxon_concept.id, - :other_taxon_concept_id => taxon_concept2.id, - :taxon_relationship_type_id => taxon_relationship_type.id) } - let(:taxon_relationship2) { build(:taxon_relationship, :taxon_concept_id => taxon_concept.id, - :other_taxon_concept_id => taxon_concept2.id, - :taxon_relationship_type_id => taxon_relationship_type2.id) } - specify { - taxon_relationship2.valid?.should == false + let!(:taxon_relationship) { + create(:taxon_relationship, + :taxon_concept_id => taxon_concept.id, + :other_taxon_concept_id => taxon_concept2.id, + :taxon_relationship_type_id => taxon_relationship_type.id + ) + } + let(:taxon_relationship2) { + build(:taxon_relationship, + :taxon_concept_id => taxon_concept.id, + :other_taxon_concept_id => taxon_concept2.id, + :taxon_relationship_type_id => taxon_relationship_type2.id + ) + } + specify { + taxon_relationship2.valid?.should == false } end context "adding an intertaxonomic relationship between taxon concepts that are already related in the opposite direction (B -> A)" do @@ -84,14 +100,22 @@ let(:taxon_concept2) { create(:taxon_concept, :taxonomy_id => taxonomy2.id) } let(:taxon_relationship_type) { create(:taxon_relationship_type, :is_intertaxonomic => true) } let(:taxon_relationship_type2) { create(:taxon_relationship_type, :is_intertaxonomic => true) } - let!(:taxon_relationship) { create(:taxon_relationship, :taxon_concept_id => taxon_concept.id, - :other_taxon_concept_id => taxon_concept2.id, - :taxon_relationship_type_id => taxon_relationship_type.id) } + let!(:taxon_relationship) { + create(:taxon_relationship, + :taxon_concept_id => taxon_concept.id, + :other_taxon_concept_id => taxon_concept2.id, + :taxon_relationship_type_id => taxon_relationship_type.id + ) + } - let(:taxon_relationship2) { build(:taxon_relationship, :taxon_concept_id => taxon_concept2.id, - :other_taxon_concept_id => taxon_concept.id, - :taxon_relationship_type_id => taxon_relationship_type2.id) } - specify { + let(:taxon_relationship2) { + build(:taxon_relationship, + :taxon_concept_id => taxon_concept2.id, + :other_taxon_concept_id => taxon_concept.id, + :taxon_relationship_type_id => taxon_relationship_type2.id + ) + } + specify { taxon_relationship2.valid?.should == false } end @@ -103,15 +127,23 @@ let(:taxon_concept3) { create(:taxon_concept, :taxonomy_id => taxonomy2.id) } let(:taxon_relationship_type) { create(:taxon_relationship_type, :is_intertaxonomic => true) } let(:taxon_relationship_type2) { create(:taxon_relationship_type, :is_intertaxonomic => true) } - let!(:taxon_relationship) { create(:taxon_relationship, :taxon_concept_id => taxon_concept.id, - :other_taxon_concept_id => taxon_concept2.id, - :taxon_relationship_type_id => taxon_relationship_type.id) } + let!(:taxon_relationship) { + create(:taxon_relationship, + :taxon_concept_id => taxon_concept.id, + :other_taxon_concept_id => taxon_concept2.id, + :taxon_relationship_type_id => taxon_relationship_type.id + ) + } - let(:taxon_relationship2) { build(:taxon_relationship, :taxon_concept_id => taxon_concept.id, - :other_taxon_concept_id => taxon_concept3.id, - :taxon_relationship_type_id => taxon_relationship_type2.id) } + let(:taxon_relationship2) { + build(:taxon_relationship, + :taxon_concept_id => taxon_concept.id, + :other_taxon_concept_id => taxon_concept3.id, + :taxon_relationship_type_id => taxon_relationship_type2.id + ) + } - specify { + specify { taxon_relationship2.valid?.should == true } end diff --git a/spec/models/term_spec.rb b/spec/models/term_spec.rb index 402999b35c..927f5a3fa4 100644 --- a/spec/models/term_spec.rb +++ b/spec/models/term_spec.rb @@ -22,20 +22,14 @@ end context "when dependent objects attached" do let(:term){ create(:term) } - #context "when EU opinion" do - # let!(:eu_opinion){ create(:eu_opinion, :term => term)} - # specify { term.destroy.should be_false } - #end - #context "when EU suspension" do - # let!(:eu_suspension){ create(:eu_suspension, :term => term)} - # specify { term.destroy.should be_false } - #end context "when CITES suspension" do - let!(:cites_suspension){ create( - :cites_suspension, - :terms => [term], - :start_notification_id => create_cites_suspension_notification.id - ) } + let!(:cites_suspension){ + create( + :cites_suspension, + :terms => [term], + :start_notification_id => create_cites_suspension_notification.id + ) + } specify { term.destroy.should be_false } end context "when CITES quota" do From 0339a04d6545c591cd1a66dd768dc2f4e25646d9 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Wed, 1 Jun 2016 10:32:23 +0100 Subject: [PATCH 283/365] Indent when as deep as case --- .rubocop_todo.yml | 7 ---- app/controllers/admin/exports_controller.rb | 40 +++++++++---------- app/controllers/application_controller.rb | 8 ++-- app/controllers/species/exports_controller.rb | 16 ++++---- .../admin/nomenclature_changes_helper.rb | 32 +++++++-------- app/models/cms_mapping.rb | 12 +++--- app/models/iucn_mapping.rb | 24 +++++------ app/models/species/csv_copy_export.rb | 7 ++-- app/models/species/restrictions_export.rb | 28 ++++++------- app/models/taxon_concept_data.rb | 17 ++++---- .../trade/reported_taxon_concept_resolver.rb | 5 ++- app/models/trade/shipments_export_factory.rb | 24 +++++------ app/models/trade_restriction.rb | 5 ++- 13 files changed, 111 insertions(+), 114 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index e9d4e7b824..4a7c084aff 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -255,13 +255,6 @@ Style/BlockDelimiters: Style/BracesAroundHashParameters: Enabled: false -# Offense count: 45 -# Cop supports --auto-correct. -# Configuration parameters: IndentWhenRelativeTo, SupportedStyles, IndentOneStep, IndentationWidth. -# SupportedStyles: case, end -Style/CaseIndentation: - Enabled: false - # Offense count: 348 # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: nested, compact diff --git a/app/controllers/admin/exports_controller.rb b/app/controllers/admin/exports_controller.rb index 65ecdb91a1..a7f2573e16 100644 --- a/app/controllers/admin/exports_controller.rb +++ b/app/controllers/admin/exports_controller.rb @@ -12,26 +12,26 @@ def download end }) case params[:data_type] - when 'Names' - result = Species::TaxonConceptsNamesExport.new(filters).export - when 'SynonymsAndTradeNames' - result = Species::SynonymsAndTradeNamesExport.new(filters).export - when 'CommonNames' - result = Species::CommonNamesExport.new(filters).export - when 'OrphanedTaxonConcepts' - result = Species::OrphanedTaxonConceptsExport.new(filters).export - when 'SpeciesReferenceOutput' - result = Species::SpeciesReferenceOutputExport.new(filters).export - when 'StandardReferenceOutput' - result = Species::StandardReferenceOutputExport.new(filters).export - when 'Distributions' - result = Species::TaxonConceptsDistributionsExport.new(filters).export - when 'Documents' - result = Species::DocumentsExport.new(filters).export - when 'IucnMappings' - result = Species::IucnMappingsExport.new.export - when 'CmsMappings' - result = Species::CmsMappingsExport.new.export + when 'Names' + result = Species::TaxonConceptsNamesExport.new(filters).export + when 'SynonymsAndTradeNames' + result = Species::SynonymsAndTradeNamesExport.new(filters).export + when 'CommonNames' + result = Species::CommonNamesExport.new(filters).export + when 'OrphanedTaxonConcepts' + result = Species::OrphanedTaxonConceptsExport.new(filters).export + when 'SpeciesReferenceOutput' + result = Species::SpeciesReferenceOutputExport.new(filters).export + when 'StandardReferenceOutput' + result = Species::StandardReferenceOutputExport.new(filters).export + when 'Distributions' + result = Species::TaxonConceptsDistributionsExport.new(filters).export + when 'Documents' + result = Species::DocumentsExport.new(filters).export + when 'IucnMappings' + result = Species::IucnMappingsExport.new.export + when 'CmsMappings' + result = Species::CmsMappingsExport.new.export end if result.is_a?(Array) # this was added in order to prevent download managers from diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 29c391700f..f52275beef 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -16,10 +16,10 @@ class ApplicationController < ActionController::Base redirect_to rescue_path, alert: if current_user.is_manager_or_contributor? case exception.action - when :destroy - "You are not authorised to destroy that record" - else - exception.message + when :destroy + "You are not authorised to destroy that record" + else + exception.message end else "You are not authorised to access this page" diff --git a/app/controllers/species/exports_controller.rb b/app/controllers/species/exports_controller.rb index 5f0ce77373..02137a4a9d 100644 --- a/app/controllers/species/exports_controller.rb +++ b/app/controllers/species/exports_controller.rb @@ -8,14 +8,14 @@ def download :csv_separator => cookies['speciesplus.csv_separator'].try(:to_sym) }) case params[:data_type] - when 'Quotas' - result = Quota.export @filters - when 'CitesSuspensions' - result = CitesSuspension.export @filters - when 'Listings' - result = Species::ListingsExportFactory.new(@filters).export - when 'EuDecisions' - result = Species::EuDecisionsExport.new(@filters).export + when 'Quotas' + result = Quota.export @filters + when 'CitesSuspensions' + result = CitesSuspension.export @filters + when 'Listings' + result = Species::ListingsExportFactory.new(@filters).export + when 'EuDecisions' + result = Species::EuDecisionsExport.new(@filters).export end respond_to do |format| format.html { diff --git a/app/helpers/admin/nomenclature_changes_helper.rb b/app/helpers/admin/nomenclature_changes_helper.rb index 18e41b4b5a..c9d9509e41 100644 --- a/app/helpers/admin/nomenclature_changes_helper.rb +++ b/app/helpers/admin/nomenclature_changes_helper.rb @@ -168,22 +168,22 @@ def outputs_selection ff def nomenclature_change_header case - when @nc.is_a?(NomenclatureChange::Split) - concat content_tag(:h1, "NomenclatureChange #{@nc.id} - SPLIT", nil) - content_tag(:div, @nc.input.note_en.html_safe, class: 'well well-small') - when @nc.is_a?(NomenclatureChange::Lump) - concat content_tag(:h1, "NomenclatureChange #{@nc.id} - LUMP", nil) - content_tag(:div, @nc.output.note_en.html_safe, class: 'well well-small') - when @nc.is_a?(NomenclatureChange::StatusSwap) - content_tag(:h1, "NomenclatureChange #{@nc.id} - STATUS SWAP", nil) + - content_tag(:div, @nc.primary_output.internal_note.html_safe, class: 'well well-small') + - content_tag(:div, @nc.secondary_output.note_en.html_safe, class: 'well well-small') - when @nc.is_a?(NomenclatureChange::StatusToSynonym) - content_tag(:h1, "NomenclatureChange #{@nc.id} - STATUS TO SYNONYM", nil) + - content_tag(:div, @nc.primary_output.internal_note.html_safe, class: 'well well-small') - when @nc.is_a?(NomenclatureChange::StatusToAccepted) - content_tag(:h1, "NomenclatureChange #{@nc.id} - STATUS TO ACCEPTED", nil) + - content_tag(:div, @nc.primary_output.note_en.html_safe, class: 'well well-small') + when @nc.is_a?(NomenclatureChange::Split) + concat content_tag(:h1, "NomenclatureChange #{@nc.id} - SPLIT", nil) + content_tag(:div, @nc.input.note_en.html_safe, class: 'well well-small') + when @nc.is_a?(NomenclatureChange::Lump) + concat content_tag(:h1, "NomenclatureChange #{@nc.id} - LUMP", nil) + content_tag(:div, @nc.output.note_en.html_safe, class: 'well well-small') + when @nc.is_a?(NomenclatureChange::StatusSwap) + content_tag(:h1, "NomenclatureChange #{@nc.id} - STATUS SWAP", nil) + + content_tag(:div, @nc.primary_output.internal_note.html_safe, class: 'well well-small') + + content_tag(:div, @nc.secondary_output.note_en.html_safe, class: 'well well-small') + when @nc.is_a?(NomenclatureChange::StatusToSynonym) + content_tag(:h1, "NomenclatureChange #{@nc.id} - STATUS TO SYNONYM", nil) + + content_tag(:div, @nc.primary_output.internal_note.html_safe, class: 'well well-small') + when @nc.is_a?(NomenclatureChange::StatusToAccepted) + content_tag(:h1, "NomenclatureChange #{@nc.id} - STATUS TO ACCEPTED", nil) + + content_tag(:div, @nc.primary_output.note_en.html_safe, class: 'well well-small') end end diff --git a/app/models/cms_mapping.rb b/app/models/cms_mapping.rb index 6360df02da..5cbf5902c9 100644 --- a/app/models/cms_mapping.rb +++ b/app/models/cms_mapping.rb @@ -23,12 +23,12 @@ class CmsMapping < ActiveRecord::Base scope :filter, lambda { |option| case option - when "MATCHES" - where('taxon_concept_id IS NOT NULL') - when "MISSING_SPECIES_PLUS" - where(:taxon_concept_id => nil) - else - scoped + when "MATCHES" + where('taxon_concept_id IS NOT NULL') + when "MISSING_SPECIES_PLUS" + where(:taxon_concept_id => nil) + else + scoped end } end diff --git a/app/models/iucn_mapping.rb b/app/models/iucn_mapping.rb index 22ba015833..230795fd8d 100644 --- a/app/models/iucn_mapping.rb +++ b/app/models/iucn_mapping.rb @@ -24,18 +24,18 @@ class IucnMapping < ActiveRecord::Base scope :filter, lambda { |option| case option - when "ALL" - scoped - when "MATCHING" - where('iucn_taxon_id IS NOT NULL') - when "NON_MATCHING" - where(:iucn_taxon_id => nil) - when 'SYNONYMS' - where('accepted_name_id IS NOT NULL') - when 'ACCEPTED' - where(:accepted_name_id => nil) - else - where("details->'match' = ?", option) + when "ALL" + scoped + when "MATCHING" + where('iucn_taxon_id IS NOT NULL') + when "NON_MATCHING" + where(:iucn_taxon_id => nil) + when 'SYNONYMS' + where('accepted_name_id IS NOT NULL') + when 'ACCEPTED' + where(:accepted_name_id => nil) + else + where("details->'match' = ?", option) end } end diff --git a/app/models/species/csv_copy_export.rb b/app/models/species/csv_copy_export.rb index 20e2c8c082..0e568208f0 100644 --- a/app/models/species/csv_copy_export.rb +++ b/app/models/species/csv_copy_export.rb @@ -34,11 +34,12 @@ def query private def initialize_csv_separator(csv_separator) - @csv_separator, @csv_separator_char = case csv_separator + @csv_separator, @csv_separator_char = + case csv_separator when :semicolon then [:semicolon, ';'] else [:comma, ','] - end - end + end + end def initialize_file_name @file_name = path + Digest::SHA1.hexdigest( diff --git a/app/models/species/restrictions_export.rb b/app/models/species/restrictions_export.rb index e2a6a9f197..57be48b78c 100644 --- a/app/models/species/restrictions_export.rb +++ b/app/models/species/restrictions_export.rb @@ -19,20 +19,20 @@ def self.fill_taxon_columns(restriction) columns = [] remark = "" case restriction.taxon_concept.try(:name_status) - when "A" - taxon = restriction.taxon_concept.try(:m_taxon_concept) - when "H" - taxon = restriction.taxon_concept.hybrid_parents. - first.try(:m_taxon_concept) || - restriction.taxon_concept.m_taxon_concept - remark = "Issued for hybrid #{restriction.taxon_concept.full_name}" - when "S" - taxon = restriction.taxon_concept.accepted_names. - first.try(:m_taxon_concept) || - restriction.taxon_concept.m_taxon_concept - remark = "Issued for synonym #{restriction.taxon_concept.full_name}" - else - taxon = nil + when "A" + taxon = restriction.taxon_concept.try(:m_taxon_concept) + when "H" + taxon = restriction.taxon_concept.hybrid_parents. + first.try(:m_taxon_concept) || + restriction.taxon_concept.m_taxon_concept + remark = "Issued for hybrid #{restriction.taxon_concept.full_name}" + when "S" + taxon = restriction.taxon_concept.accepted_names. + first.try(:m_taxon_concept) || + restriction.taxon_concept.m_taxon_concept + remark = "Issued for synonym #{restriction.taxon_concept.full_name}" + else + taxon = nil end return [""]*(TAXONOMY_COLUMNS.size+1) unless taxon #return array with empty strings TAXONOMY_COLUMNS.each do |c| diff --git a/app/models/taxon_concept_data.rb b/app/models/taxon_concept_data.rb index 84784d470d..08d2e62159 100644 --- a/app/models/taxon_concept_data.rb +++ b/app/models/taxon_concept_data.rb @@ -39,14 +39,15 @@ def higher_taxa_from_parent data = if @taxon_concept.parent && @taxon_concept.parent.data @taxon_concept.parent.data else - fake_parent = case @taxon_concept.name_status - when 'H' - @taxon_concept.hybrid_parents.first - when 'S' - @taxon_concept.accepted_names.first - when 'T' - @taxon_concept.accepted_names_for_trade_name.first - end + fake_parent = + case @taxon_concept.name_status + when 'H' + @taxon_concept.hybrid_parents.first + when 'S' + @taxon_concept.accepted_names.first + when 'T' + @taxon_concept.accepted_names_for_trade_name.first + end fake_parent && fake_parent.data end return nil unless data diff --git a/app/models/trade/reported_taxon_concept_resolver.rb b/app/models/trade/reported_taxon_concept_resolver.rb index 66c5b2ff70..e14808e77f 100644 --- a/app/models/trade/reported_taxon_concept_resolver.rb +++ b/app/models/trade/reported_taxon_concept_resolver.rb @@ -4,13 +4,14 @@ def initialize(reported_taxon_concept_id) # automatically resolve accepted taxon name reported_taxon = TaxonConcept.find_by_id(reported_taxon_concept_id) return [] unless reported_taxon - @accepted_taxa = reported_taxon && case reported_taxon.name_status + @accepted_taxa = reported_taxon && + case reported_taxon.name_status when 'S' reported_taxon.accepted_names when 'T' reported_taxon.accepted_names_for_trade_name else [reported_taxon] - end + end end end diff --git a/app/models/trade/shipments_export_factory.rb b/app/models/trade/shipments_export_factory.rb index a82585abf4..695c5dac25 100644 --- a/app/models/trade/shipments_export_factory.rb +++ b/app/models/trade/shipments_export_factory.rb @@ -7,18 +7,18 @@ def self.new(filters) @report_type = :comptab end case @report_type - when :comptab - Trade::ShipmentsComptabExport.new(filters) - when :gross_exports - Trade::ShipmentsGrossExportsExport.new(filters) - when :gross_imports - Trade::ShipmentsGrossImportsExport.new(filters) - when :net_exports - Trade::ShipmentsNetExportsExport.new(filters) - when :net_imports - Trade::ShipmentsNetImportsExport.new(filters) - else - Trade::ShipmentsExport.new(filters) + when :comptab + Trade::ShipmentsComptabExport.new(filters) + when :gross_exports + Trade::ShipmentsGrossExportsExport.new(filters) + when :gross_imports + Trade::ShipmentsGrossImportsExport.new(filters) + when :net_exports + Trade::ShipmentsNetExportsExport.new(filters) + when :net_imports + Trade::ShipmentsNetImportsExport.new(filters) + else + Trade::ShipmentsExport.new(filters) end end diff --git a/app/models/trade_restriction.rb b/app/models/trade_restriction.rb index 7f7a6da3a7..0ec720a7f5 100644 --- a/app/models/trade_restriction.rb +++ b/app/models/trade_restriction.rb @@ -130,10 +130,11 @@ def self.csv_columns_headers def self.to_csv(file_path, filters) limit = 1000 offset = 0 - csv_separator_char = case filters[:csv_separator] + csv_separator_char = + case filters[:csv_separator] when :semicolon then ';' else ',' - end + end CSV.open(file_path, 'wb', {:col_sep => csv_separator_char}) do |csv| csv << Species::RestrictionsExport::TAXONOMY_COLUMN_NAMES + ['Remarks'] + self.csv_columns_headers From c52e377b75a6633fb3bcd4d420749bfcec0b471e Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Wed, 1 Jun 2016 10:57:47 +0100 Subject: [PATCH 284/365] Place the . on the previous line, together with the method call receiver --- .rubocop.yml | 7 +++++++ .rubocop_todo.yml | 7 ------- app/models/checklist/checklist.rb | 16 +++++++++------- app/models/trade_restriction.rb | 4 ++-- 4 files changed, 18 insertions(+), 16 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 58d457a177..0d0d349c58 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -46,3 +46,10 @@ Style/AndOr: Exclude: - 'lib/tasks/bbgem.rake' - 'db/migrate/*' + +# Offense count: 551 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: leading, trailing +Style/DotPosition: + EnforcedStyle: trailing diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 4a7c084aff..a8bd99a05f 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -331,13 +331,6 @@ Style/DeprecatedHashMethods: Style/Documentation: Enabled: false -# Offense count: 551 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: leading, trailing -Style/DotPosition: - Enabled: false - # Offense count: 1 Style/DoubleNegation: Exclude: diff --git a/app/models/checklist/checklist.rb b/app/models/checklist/checklist.rb index 2bf6b1707b..871f874c08 100644 --- a/app/models/checklist/checklist.rb +++ b/app/models/checklist/checklist.rb @@ -187,13 +187,15 @@ def download_location(params, type, format) params.delete(:action) params.delete(:controller) - @filename = Digest::SHA1.hexdigest(params - .merge(type: type) - .merge(locale: I18n.locale) - .to_hash - .symbolize_keys! - .sort - .to_s) + @filename = Digest::SHA1.hexdigest( + params. + merge(type: type). + merge(locale: I18n.locale). + to_hash. + symbolize_keys!. + sort. + to_s + ) return [Rails.root, '/public/downloads/checklist/', @filename, '.', format].join end diff --git a/app/models/trade_restriction.rb b/app/models/trade_restriction.rb index 0ec720a7f5..bfddf68028 100644 --- a/app/models/trade_restriction.rb +++ b/app/models/trade_restriction.rb @@ -89,8 +89,8 @@ def self.export(filters) file_name = Digest::SHA1.hexdigest( filters.merge(:latest_date => latest). to_hash. - symbolize_keys!.sort - .to_s + symbolize_keys!.sort. + to_s )+"_cites_#{self.to_s.downcase}s.csv" if !File.file?(path+file_name) self.to_csv(path+file_name, filters) From 9f3afa5864f233c25266e594f2f378961d613d92 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Wed, 1 Jun 2016 11:24:27 +0100 Subject: [PATCH 285/365] Align else with if --- .rubocop_todo.yml | 5 -- app/controllers/activities_controller.rb | 13 ++-- .../admin/document_batches_controller.rb | 11 ++-- app/controllers/admin/documents_controller.rb | 33 +++++----- app/controllers/admin/exports_controller.rb | 13 ++-- .../admin/taxon_listing_changes_controller.rb | 30 +++++----- .../admin/taxon_relationships_controller.rb | 11 ++-- app/controllers/admin/users_controller.rb | 11 ++-- .../v1/document_geo_entities_controller.rb | 11 ++-- app/controllers/cites_trade_controller.rb | 30 +++++----- app/controllers/registrations_controller.rb | 17 +++--- app/controllers/trade_controller.rb | 28 +++++---- app/models/checklist/checklist.rb | 11 ++-- app/models/checklist/higher_taxa_injector.rb | 27 +++++---- app/models/checklist/higher_taxa_item.rb | 11 ++-- app/models/checklist/pdf/helpers.rb | 15 ++--- app/models/checklist/pdf/history_content.rb | 41 +++++++------ app/models/checklist/pdf/index_query.rb | 39 ++++++------ app/models/checklist/timeline.rb | 55 ++++++++--------- app/models/cms_mapping_manager.rb | 15 ++--- app/models/document_search.rb | 11 ++-- .../output_taxon_concept_processor.rb | 11 ++-- .../nomenclature_change/split/constructor.rb | 15 ++--- .../status_change/constructor_helpers.rb | 11 ++-- .../status_change_processor.rb | 11 ++-- app/models/species/listings_export.rb | 46 +++++++------- app/models/species/listings_export_factory.rb | 11 ++-- app/models/species/search.rb | 11 ++-- .../species/taxon_concept_prefix_matcher.rb | 60 ++++++++++--------- app/models/taxon_concept.rb | 18 +++--- app/models/taxon_concept_data.rb | 44 +++++++------- app/models/trade/filter.rb | 27 +++++---- app/models/trade/sandbox.rb | 11 ++-- app/models/trade/shipment_observer.rb | 11 ++-- .../active_record_comparison_attributes.rb | 13 ++-- lib/csv_column_headers_validator.rb | 11 ++-- lib/modules/sapi/geoip.rb | 11 ++-- lib/modules/search_param_sanitiser.rb | 26 ++++---- 38 files changed, 413 insertions(+), 373 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index a8bd99a05f..03863f181a 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -336,11 +336,6 @@ Style/DoubleNegation: Exclude: - 'app/models/eu_decision_type.rb' -# Offense count: 70 -# Cop supports --auto-correct. -Style/ElseAlignment: - Enabled: false - # Offense count: 1 # Cop supports --auto-correct. Style/EmptyCaseCondition: diff --git a/app/controllers/activities_controller.rb b/app/controllers/activities_controller.rb index af1bdd9b8c..faeea900ce 100644 --- a/app/controllers/activities_controller.rb +++ b/app/controllers/activities_controller.rb @@ -8,12 +8,13 @@ def activities end linechart_end_date = Time.now @start_week = params[:start_week] && Date.parse(params[:start_week]) - topten_start_date, topten_end_date = if @start_week - start_date = @start_week - [start_date, start_date + 7] - else - [linechart_start_date, linechart_end_date] - end + topten_start_date, topten_end_date = + if @start_week + start_date = @start_week + [start_date, start_date + 7] + else + [linechart_start_date, linechart_end_date] + end @toptens_cites = TaxonConceptViewStats.new( topten_start_date, topten_end_date, Taxonomy::CITES_EU ).results diff --git a/app/controllers/admin/document_batches_controller.rb b/app/controllers/admin/document_batches_controller.rb index 1b6c656bd3..08b50f0321 100644 --- a/app/controllers/admin/document_batches_controller.rb +++ b/app/controllers/admin/document_batches_controller.rb @@ -33,11 +33,12 @@ def load_associations @event = Event.find(params[:event_id]) if params[:event_id] @languages = Language.select([:id, :name_en, :name_es, :name_fr]).order(:name_en) @english = Language.find_by_iso_code1('EN') - @document_types = if @event - @event.class.elibrary_document_types.map { |l| [l.display_name, l.name] } - else - Document.elibrary_document_types.map { |l| [l.display_name, l.name] } - end + @document_types = + if @event + @event.class.elibrary_document_types.map { |l| [l.display_name, l.name] } + else + Document.elibrary_document_types.map { |l| [l.display_name, l.name] } + end end def document_batch_params diff --git a/app/controllers/admin/documents_controller.rb b/app/controllers/admin/documents_controller.rb index 329abf6952..caea5187a4 100644 --- a/app/controllers/admin/documents_controller.rb +++ b/app/controllers/admin/documents_controller.rb @@ -85,11 +85,12 @@ def collection def load_associations @designations = Designation.where(name: ['CITES', 'EU']).select([:id, :name]).order(:name) - @event_types = if @document && @document.event - [{id: @document.event.type}] - else - Event.event_types_with_names - end + @event_types = + if @document && @document.event + [{id: @document.event.type}] + else + Event.event_types_with_names + end @events = Event.where(type: @event_types.map{ |t| t[:id] }).order(:published_at).reverse_order @event = Event.find(params[:event_id]) if params[:event_id].present? @languages = Language.select([:id, :name_en, :name_es, :name_fr]). @@ -107,20 +108,22 @@ def success_redirect end def failure_redirect - alert = if resource.errors.present? - "Operation #{resource.errors.messages[:base].join(", ")}" - else - "Operation failed" - end + alert = + if resource.errors.present? + "Operation #{resource.errors.messages[:base].join(", ")}" + else + "Operation failed" + end redirect_to redirect_url, :alert => alert end def redirect_url event_id = params[:event_id] - url = if event_id.present? - admin_event_documents_url(Event.find(event_id)) - else - admin_documents_url - end + url = + if event_id.present? + admin_event_documents_url(Event.find(event_id)) + else + admin_documents_url + end end end diff --git a/app/controllers/admin/exports_controller.rb b/app/controllers/admin/exports_controller.rb index a7f2573e16..5f23fd6bff 100644 --- a/app/controllers/admin/exports_controller.rb +++ b/app/controllers/admin/exports_controller.rb @@ -4,12 +4,13 @@ def index; end def download filters = (params[:filters] || {}).merge({ - :csv_separator => if params[:filters] && params[:filters][:csv_separator] && - params[:filters][:csv_separator].downcase.strip.to_sym == :semicolon - :semicolon - else - :comma - end + :csv_separator => + if params[:filters] && params[:filters][:csv_separator] && + params[:filters][:csv_separator].downcase.strip.to_sym == :semicolon + :semicolon + else + :comma + end }) case params[:data_type] when 'Names' diff --git a/app/controllers/admin/taxon_listing_changes_controller.rb b/app/controllers/admin/taxon_listing_changes_controller.rb index 236b0c1e29..e43bb0cc60 100644 --- a/app/controllers/admin/taxon_listing_changes_controller.rb +++ b/app/controllers/admin/taxon_listing_changes_controller.rb @@ -95,20 +95,22 @@ def load_change_types @species_listings = @designation.species_listings.order(:abbreviation) @geo_entities = GeoEntity.order(:name_en).joins(:geo_entity_type). where(:is_current => true, :geo_entity_types => {:name => 'COUNTRY'}) - @hash_annotations = if @designation.is_eu? - Annotation.for_eu - elsif @designation.is_cites? - Annotation.for_cites - else - [] - end - @events = if @designation.is_eu? - EuRegulation.order('effective_at DESC') - elsif @designation.is_cites? - CitesCop.order('effective_at DESC') - else - [] - end + @hash_annotations = + if @designation.is_eu? + Annotation.for_eu + elsif @designation.is_cites? + Annotation.for_cites + else + [] + end + @events = + if @designation.is_eu? + EuRegulation.order('effective_at DESC') + elsif @designation.is_cites? + CitesCop.order('effective_at DESC') + else + [] + end end def load_listing_changes diff --git a/app/controllers/admin/taxon_relationships_controller.rb b/app/controllers/admin/taxon_relationships_controller.rb index 7ad1cb8d05..1d64432dfc 100644 --- a/app/controllers/admin/taxon_relationships_controller.rb +++ b/app/controllers/admin/taxon_relationships_controller.rb @@ -54,11 +54,12 @@ def destroy protected def load_taxon_relationship_types - @taxon_relationship_type = if params[:taxon_relationship] - TaxonRelationshipType.find(params[:taxon_relationship][:taxon_relationship_type_id]) - else - TaxonRelationshipType.find_by_name(params[:type] || TaxonRelationshipType::EQUAL_TO) - end + @taxon_relationship_type = + if params[:taxon_relationship] + TaxonRelationshipType.find(params[:taxon_relationship][:taxon_relationship_type_id]) + else + TaxonRelationshipType.find_by_name(params[:type] || TaxonRelationshipType::EQUAL_TO) + end @taxon_relationship_types = TaxonRelationshipType.order(:name). intertaxonomic end diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index e5c85a97fa..731480a608 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -17,11 +17,12 @@ def edit end def update - update_result = if params[:user][:password].blank? - @user.update_without_password(params[:user]) - else - @user.update_attributes(params[:user]) - end + update_result = + if params[:user][:password].blank? + @user.update_without_password(params[:user]) + else + @user.update_attributes(params[:user]) + end respond_to do |format| format.js { if update_result diff --git a/app/controllers/api/v1/document_geo_entities_controller.rb b/app/controllers/api/v1/document_geo_entities_controller.rb index 4d37d39faf..7ba2be799f 100644 --- a/app/controllers/api/v1/document_geo_entities_controller.rb +++ b/app/controllers/api/v1/document_geo_entities_controller.rb @@ -31,10 +31,11 @@ def index def set_locale locale = params[:locale].try(:downcase).try(:strip) || 'en' - I18n.locale = if ['en', 'es', 'fr'].include?(locale) - locale - else - 'en' - end + I18n.locale = + if ['en', 'es', 'fr'].include?(locale) + locale + else + 'en' + end end end diff --git a/app/controllers/cites_trade_controller.rb b/app/controllers/cites_trade_controller.rb index 13b7753c49..57e5c36edc 100644 --- a/app/controllers/cites_trade_controller.rb +++ b/app/controllers/cites_trade_controller.rb @@ -23,20 +23,22 @@ def search_params # if taxon search comes from the genus selector, search descendants :taxon_with_descendants => (params[:filters] && params[:filters][:selection_taxon] == 'genus'), - :report_type => if params[:filters] && params[:filters][:report_type] && - Trade::ShipmentsExportFactory.public_report_types.include?( - report_type = params[:filters][:report_type].downcase.strip.to_sym - ) - report_type - else - :comptab - end, - :csv_separator => if params[:filters] && params[:filters][:csv_separator] && - params[:filters][:csv_separator].downcase.strip.to_sym == :semicolon - :semicolon - else - :comma - end + :report_type => + if params[:filters] && params[:filters][:report_type] && + Trade::ShipmentsExportFactory.public_report_types.include?( + report_type = params[:filters][:report_type].downcase.strip.to_sym + ) + report_type + else + :comptab + end, + :csv_separator => + if params[:filters] && params[:filters][:csv_separator] && + params[:filters][:csv_separator].downcase.strip.to_sym == :semicolon + :semicolon + else + :comma + end }) end diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index 98675e4a27..68fb4e419a 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -2,14 +2,15 @@ class RegistrationsController < Devise::RegistrationsController def update @user = User.find(current_user.id) - successfully_updated = if needs_password?(@user, params) - @user.update_with_password(devise_parameter_sanitizer.sanitize(:account_update)) - else - # remove the virtual current_password attribute - # update_without_password doesn't know how to ignore it - params[:user].delete(:current_password) - @user.update_without_password(devise_parameter_sanitizer.sanitize(:account_update)) - end + successfully_updated = + if needs_password?(@user, params) + @user.update_with_password(devise_parameter_sanitizer.sanitize(:account_update)) + else + # remove the virtual current_password attribute + # update_without_password doesn't know how to ignore it + params[:user].delete(:current_password) + @user.update_without_password(devise_parameter_sanitizer.sanitize(:account_update)) + end if successfully_updated set_flash_message :notice, :updated diff --git a/app/controllers/trade_controller.rb b/app/controllers/trade_controller.rb index 2dcb938b4b..b0cf5fea85 100644 --- a/app/controllers/trade_controller.rb +++ b/app/controllers/trade_controller.rb @@ -41,19 +41,21 @@ def search_params :internal => true, # always search descendants :taxon_with_descendants => true, - :report_type => if params[:filters] && params[:filters][:report_type] && - Trade::ShipmentsExportFactory.report_types & - [report_type = params[:filters][:report_type].downcase.strip.to_sym] - report_type - else - :raw - end, - :csv_separator => if params[:filters] && params[:filters][:csv_separator] && - params[:filters][:csv_separator].downcase.strip.to_sym == :semicolon - :semicolon - else - :comma - end + :report_type => + if params[:filters] && params[:filters][:report_type] && + Trade::ShipmentsExportFactory.report_types & + [report_type = params[:filters][:report_type].downcase.strip.to_sym] + report_type + else + :raw + end, + :csv_separator => + if params[:filters] && params[:filters][:csv_separator] && + params[:filters][:csv_separator].downcase.strip.to_sym == :semicolon + :semicolon + else + :comma + end }) end diff --git a/app/models/checklist/checklist.rb b/app/models/checklist/checklist.rb index 871f874c08..3bd45525b2 100644 --- a/app/models/checklist/checklist.rb +++ b/app/models/checklist/checklist.rb @@ -55,11 +55,12 @@ def initialize_query end #order - @taxon_concepts_rel = if @output_layout == :taxonomic - @taxon_concepts_rel.taxonomic_layout - else - @taxon_concepts_rel.alphabetical_layout - end + @taxon_concepts_rel = + if @output_layout == :taxonomic + @taxon_concepts_rel.taxonomic_layout + else + @taxon_concepts_rel.alphabetical_layout + end @query = @taxon_concepts_rel. includes(:current_cites_additions). diff --git a/app/models/checklist/higher_taxa_injector.rb b/app/models/checklist/higher_taxa_injector.rb index 80d3762a84..311d49aeeb 100644 --- a/app/models/checklist/higher_taxa_injector.rb +++ b/app/models/checklist/higher_taxa_injector.rb @@ -66,22 +66,23 @@ def run_summary #returns array of HigherTaxaItems that need to be inserted #between prev_item and curr_item in the taxonomic layout def higher_taxa_headers(prev_item, curr_item) - ranks = if prev_item.nil? - @header_ranks - else - tmp = [] + ranks = + if prev_item.nil? + @header_ranks + else + tmp = [] - for rank in @header_ranks.reverse - rank_id_attr = "#{rank.downcase}_id" - curr_item.send(rank_id_attr) - if prev_item.send(rank_id_attr) != curr_item.send(rank_id_attr) - tmp << rank - else - break + for rank in @header_ranks.reverse + rank_id_attr = "#{rank.downcase}_id" + curr_item.send(rank_id_attr) + if prev_item.send(rank_id_attr) != curr_item.send(rank_id_attr) + tmp << rank + else + break + end end + tmp.reverse end - tmp.reverse - end ranks = [ranks.last].compact unless @expand_headers diff --git a/app/models/checklist/higher_taxa_item.rb b/app/models/checklist/higher_taxa_item.rb index 21556d2e86..38a0aec219 100644 --- a/app/models/checklist/higher_taxa_item.rb +++ b/app/models/checklist/higher_taxa_item.rb @@ -6,11 +6,12 @@ def initialize(taxon_concept) end def ancestors_ranks - taxa = if kingdom_name == 'Plantae' - ['FAMILY', 'SUBFAMILY'] - else - ['PHYLUM', 'CLASS', 'ORDER', 'FAMILY', 'SUBFAMILY'] - end + taxa = + if kingdom_name == 'Plantae' + ['FAMILY', 'SUBFAMILY'] + else + ['PHYLUM', 'CLASS', 'ORDER', 'FAMILY', 'SUBFAMILY'] + end current_idx = taxa.index(rank_name) || 0 0.upto(current_idx).map do |i| taxa[i] diff --git a/app/models/checklist/pdf/helpers.rb b/app/models/checklist/pdf/helpers.rb index c52a5a3c21..99a24c7a51 100644 --- a/app/models/checklist/pdf/helpers.rb +++ b/app/models/checklist/pdf/helpers.rb @@ -15,15 +15,16 @@ def common_names_with_lng_initials(taxon_concept) end def taxon_name_at_rank(taxon_concept) - res = if ['FAMILY','SUBFAMILY','ORDER','CLASS'].include? taxon_concept.rank_name - LatexToPdf.escape_latex(taxon_concept.full_name.upcase) - else - if ['SPECIES', 'SUBSPECIES', 'GENUS'].include? taxon_concept.rank_name - "\\textit{#{LatexToPdf.escape_latex(taxon_concept.full_name)}}" + res = + if ['FAMILY','SUBFAMILY','ORDER','CLASS'].include? taxon_concept.rank_name + LatexToPdf.escape_latex(taxon_concept.full_name.upcase) else - LatexToPdf.escape_latex(taxon_concept.full_name) + if ['SPECIES', 'SUBSPECIES', 'GENUS'].include? taxon_concept.rank_name + "\\textit{#{LatexToPdf.escape_latex(taxon_concept.full_name)}}" + else + LatexToPdf.escape_latex(taxon_concept.full_name) + end end - end res += " #{LatexToPdf.escape_latex(taxon_concept.spp)}" if taxon_concept.spp res end diff --git a/app/models/checklist/pdf/history_content.rb b/app/models/checklist/pdf/history_content.rb index 1b7ca7bdb4..0a75e4a330 100644 --- a/app/models/checklist/pdf/history_content.rb +++ b/app/models/checklist/pdf/history_content.rb @@ -79,20 +79,22 @@ def listed_taxa(tex, listed_taxa_ary, kingdom_name='FAUNA') end def listing_with_change_type(listing_change) - appendix = if listing_change.change_type_name == ChangeType::DELETION - nil - else - listing_change.species_listing_name - end - change_type = if listing_change.change_type_name == ChangeType::RESERVATION - '/r' - elsif listing_change.change_type_name == ChangeType::RESERVATION_WITHDRAWAL - '/w' - elsif listing_change.change_type_name == ChangeType::DELETION - 'Del' - else - nil - end + appendix = + if listing_change.change_type_name == ChangeType::DELETION + nil + else + listing_change.species_listing_name + end + change_type = + if listing_change.change_type_name == ChangeType::RESERVATION + '/r' + elsif listing_change.change_type_name == ChangeType::RESERVATION_WITHDRAWAL + '/w' + elsif listing_change.change_type_name == ChangeType::DELETION + 'Del' + else + nil + end "#{appendix}#{change_type}" end @@ -114,11 +116,12 @@ def annotation_for_language(listing_change, lng) end def listed_taxon_name(taxon_concept) - res = if ['FAMILY','SUBFAMILY','ORDER','CLASS'].include? taxon_concept.rank_name - taxon_concept.full_name.upcase - else - taxon_concept.full_name - end + res = + if ['FAMILY','SUBFAMILY','ORDER','CLASS'].include? taxon_concept.rank_name + taxon_concept.full_name.upcase + else + taxon_concept.full_name + end if ['SPECIES', 'SUBSPECIES', 'GENUS'].include? taxon_concept.rank_name res = "\\emph{#{res}}" end diff --git a/app/models/checklist/pdf/index_query.rb b/app/models/checklist/pdf/index_query.rb index 7105cc4805..b50987f24a 100644 --- a/app/models/checklist/pdf/index_query.rb +++ b/app/models/checklist/pdf/index_query.rb @@ -30,25 +30,26 @@ def initialize(rel, options) :english => "REGEXP_REPLACE(UNNEST(english_names_ary), '(.+) (.+)', '\\2, \\1')", :spanish => 'UNNEST(spanish_names_ary)', :french => 'UNNEST(french_names_ary)', - :synonym => if @authors - <<-SQL - UNNEST(ARRAY(SELECT synonym || - CASE - WHEN author_year IS NOT NULL - THEN ' ' || author_year - ELSE '' - END - FROM ( - (SELECT synonym, ROW_NUMBER() OVER() AS id FROM (SELECT * FROM UNNEST(synonyms_ary) AS synonym) q) synonyms - LEFT JOIN - (SELECT author_year, ROW_NUMBER() OVER() AS id FROM (SELECT * FROM UNNEST(synonyms_author_years_ary) AS author_year) q) author_years - ON synonyms.id = author_years.id - ) - )) - SQL - else - 'UNNEST(synonyms_ary)' - end + :synonym => + if @authors + <<-SQL + UNNEST(ARRAY(SELECT synonym || + CASE + WHEN author_year IS NOT NULL + THEN ' ' || author_year + ELSE '' + END + FROM ( + (SELECT synonym, ROW_NUMBER() OVER() AS id FROM (SELECT * FROM UNNEST(synonyms_ary) AS synonym) q) synonyms + LEFT JOIN + (SELECT author_year, ROW_NUMBER() OVER() AS id FROM (SELECT * FROM UNNEST(synonyms_author_years_ary) AS author_year) q) author_years + ON synonyms.id = author_years.id + ) + )) + SQL + else + 'UNNEST(synonyms_ary)' + end }, :lng => { :english => "'E'", diff --git a/app/models/checklist/timeline.rb b/app/models/checklist/timeline.rb index 62446b00c2..d6dbdcbbe9 100644 --- a/app/models/checklist/timeline.rb +++ b/app/models/checklist/timeline.rb @@ -66,34 +66,35 @@ def change_consecutive_additions_to_amendments def add_intervals (@timelines + [self]).flatten.each do |timeline| timeline.timeline_events.each_with_index do |event, idx| - interval = if idx < (timeline.timeline_events.size - 1) - next_event = timeline.timeline_events[idx + 1] - if !( - event.is_deletion? && next_event.is_addition? || - event.is_reservation_withdrawal? && next_event.is_reservation? - ) - Checklist::TimelineInterval.new( - :taxon_concept_id => @taxon_concept_id, - :listing_change_id => event.id, - :start_pos => event.pos, - :end_pos => next_event.pos - ) + interval = + if idx < (timeline.timeline_events.size - 1) + next_event = timeline.timeline_events[idx + 1] + if !( + event.is_deletion? && next_event.is_addition? || + event.is_reservation_withdrawal? && next_event.is_reservation? + ) + Checklist::TimelineInterval.new( + :taxon_concept_id => @taxon_concept_id, + :listing_change_id => event.id, + :start_pos => event.pos, + :end_pos => next_event.pos + ) + end + else + # the meaning of @current: there is a current listing in this appdx + # this is to ensure an appdx III deletion does not terminate + # the timeline if appdx III is still current + if (event.is_addition? || event.is_amendment? || event.is_deletion?) && + @current || event.is_reservation? && event.is_current + @continues_in_present = true + Checklist::TimelineInterval.new( + :taxon_concept_id => @taxon_concept_id, + :listing_change_id => event.id, + :start_pos => event.pos, + :end_pos => 1 + ) + end end - else - # the meaning of @current: there is a current listing in this appdx - # this is to ensure an appdx III deletion does not terminate - # the timeline if appdx III is still current - if (event.is_addition? || event.is_amendment? || event.is_deletion?) && - @current || event.is_reservation? && event.is_current - @continues_in_present = true - Checklist::TimelineInterval.new( - :taxon_concept_id => @taxon_concept_id, - :listing_change_id => event.id, - :start_pos => event.pos, - :end_pos => 1 - ) - end - end timeline.timeline_intervals << interval if interval end end diff --git a/app/models/cms_mapping_manager.rb b/app/models/cms_mapping_manager.rb index 0afd9c2492..c1cce8d7d3 100644 --- a/app/models/cms_mapping_manager.rb +++ b/app/models/cms_mapping_manager.rb @@ -38,13 +38,14 @@ def analyse(mapping) 'listing_splus' => taxon_concept && taxon_concept.listing_changes.first && "#{taxon_concept.listing_changes.first.species_listing.name}: #{taxon_concept. listing_changes.first.effective_at.strftime("%d/%m/%Y")}", - 'listing_cms' => if species["appendix_1_date"] - "Appendix I: #{Date.parse(species["appendix_1_date"]).strftime("%d/%m/%Y")}" - elsif species["appendix_2_date"] - "Appendix II: #{Date.parse(species["appendix_2_date"]).strftime("%d/%m/%Y")}" - else - nil - end + 'listing_cms' => + if species["appendix_1_date"] + "Appendix I: #{Date.parse(species["appendix_1_date"]).strftime("%d/%m/%Y")}" + elsif species["appendix_2_date"] + "Appendix II: #{Date.parse(species["appendix_2_date"]).strftime("%d/%m/%Y")}" + else + nil + end } mapping.save end diff --git a/app/models/document_search.rb b/app/models/document_search.rb index 9a393a5e2c..70bc8b6fe3 100644 --- a/app/models/document_search.rb +++ b/app/models/document_search.rb @@ -162,11 +162,12 @@ def add_document_tags_condition def add_ordering_for_admin return if @title_query.present? - @query = if @events_ids.present? - @query.order(['date_raw DESC', :title]) - else - @query.order('created_at DESC') - end + @query = + if @events_ids.present? + @query.order(['date_raw DESC', :title]) + else + @query.order('created_at DESC') + end end def add_ordering_for_public diff --git a/app/models/nomenclature_change/output_taxon_concept_processor.rb b/app/models/nomenclature_change/output_taxon_concept_processor.rb index 2fe1e0fddb..23d741bd69 100644 --- a/app/models/nomenclature_change/output_taxon_concept_processor.rb +++ b/app/models/nomenclature_change/output_taxon_concept_processor.rb @@ -41,11 +41,12 @@ def summary res << "#{@output.taxon_concept.full_name} rank changed from #{@output.taxon_concept.rank.name} to #{@output.new_rank.name}" end if @output.new_parent - res << if @output.taxon_concept.parent - "#{@output.taxon_concept.full_name} parent changed from #{@output.taxon_concept.parent.full_name} to #{@output.new_parent.full_name}" - else - "#{@output.taxon_concept.full_name} parent set to #{@output.new_parent.full_name}" - end + res << + if @output.taxon_concept.parent + "#{@output.taxon_concept.full_name} parent changed from #{@output.taxon_concept.parent.full_name} to #{@output.new_parent.full_name}" + else + "#{@output.taxon_concept.full_name} parent set to #{@output.new_parent.full_name}" + end end if @output.new_name_status.present? res << "#{@output.taxon_concept.full_name} name status changed from #{@output.taxon_concept.name_status} to #{@output.new_name_status}" diff --git a/app/models/nomenclature_change/split/constructor.rb b/app/models/nomenclature_change/split/constructor.rb index 32b470b210..0624d7fc04 100644 --- a/app/models/nomenclature_change/split/constructor.rb +++ b/app/models/nomenclature_change/split/constructor.rb @@ -101,13 +101,14 @@ def outputs_for_reassignments end def output_split_from(output, input, lng) - output_html = if output.scientific_name.present? && - output.new_scientific_name.present? - taxon_concept_html(output.display_full_name, output.display_rank_name, - output.scientific_name, output.rank.name) - else - taxon_concept_html(output.display_full_name, output.display_rank_name) - end + output_html = + if output.scientific_name.present? && + output.new_scientific_name.present? + taxon_concept_html(output.display_full_name, output.display_rank_name, + output.scientific_name, output.rank.name) + else + taxon_concept_html(output.display_full_name, output.display_rank_name) + end input_html = taxon_concept_html(input.taxon_concept.full_name, input.taxon_concept.rank.name) I18n.with_locale(lng) do I18n.translate( diff --git a/app/models/nomenclature_change/status_change/constructor_helpers.rb b/app/models/nomenclature_change/status_change/constructor_helpers.rb index 74dc29f14c..9b1bc13a5e 100644 --- a/app/models/nomenclature_change/status_change/constructor_helpers.rb +++ b/app/models/nomenclature_change/status_change/constructor_helpers.rb @@ -127,11 +127,12 @@ def multi_lingual_quota_note def input_output_for_reassignment input = @nomenclature_change.input - output = if @nomenclature_change.needs_to_relay_associations? - @nomenclature_change.secondary_output - elsif @nomenclature_change.needs_to_receive_associations? - @nomenclature_change.primary_output - end + output = + if @nomenclature_change.needs_to_relay_associations? + @nomenclature_change.secondary_output + elsif @nomenclature_change.needs_to_receive_associations? + @nomenclature_change.primary_output + end return false unless input && output yield(input, output) end diff --git a/app/models/nomenclature_change/status_change_processor.rb b/app/models/nomenclature_change/status_change_processor.rb index 88475e6ff1..652af666ac 100644 --- a/app/models/nomenclature_change/status_change_processor.rb +++ b/app/models/nomenclature_change/status_change_processor.rb @@ -3,11 +3,12 @@ class NomenclatureChange::StatusChangeProcessor def initialize(input_or_output, linked_inputs_or_outputs = []) @input_or_output = input_or_output @linked_inputs_or_outputs = linked_inputs_or_outputs - @old_status = if @input_or_output.kind_of? NomenclatureChange::Output - @input_or_output.name_status.dup - else - @input_or_output.taxon_concept.name_status.dup - end + @old_status = + if @input_or_output.kind_of? NomenclatureChange::Output + @input_or_output.name_status.dup + else + @input_or_output.taxon_concept.name_status.dup + end end def summary diff --git a/app/models/species/listings_export.rb b/app/models/species/listings_export.rb index 76591fd50d..01411efd46 100644 --- a/app/models/species/listings_export.rb +++ b/app/models/species/listings_export.rb @@ -6,17 +6,18 @@ def initialize(designation, filters) @taxon_concepts_ids = filters[:taxon_concepts_ids] @geo_entities_ids = filters[:geo_entities_ids] - @species_listings_ids = if filters[:species_listings_ids] - SpeciesListing.where( - :id => filters[:species_listings_ids], - :designation_id => @designation.id - ).map(&:abbreviation) - elsif filters[:appendices] - SpeciesListing.where( - :abbreviation => filters[:appendices], - :designation_id => @designation.id - ).map(&:abbreviation) - end + @species_listings_ids = + if filters[:species_listings_ids] + SpeciesListing.where( + :id => filters[:species_listings_ids], + :designation_id => @designation.id + ).map(&:abbreviation) + elsif filters[:appendices] + SpeciesListing.where( + :abbreviation => filters[:appendices], + :designation_id => @designation.id + ).map(&:abbreviation) + end initialize_csv_separator(@filters[:csv_separator]) initialize_file_name end @@ -25,17 +26,18 @@ def query rel = MTaxonConcept.from(table_name). select(sql_columns). order('taxonomic_position') - rel = if @geo_entities_ids - MTaxonConceptFilterByAppendixPopulationQuery.new( - rel, @species_listings_ids, @geo_entities_ids - ).relation(@designation.name) - elsif @species_listings_ids - MTaxonConceptFilterByAppendixQuery.new( - rel, @species_listings_ids - ).relation(@designation.name) - else - rel - end + rel = + if @geo_entities_ids + MTaxonConceptFilterByAppendixPopulationQuery.new( + rel, @species_listings_ids, @geo_entities_ids + ).relation(@designation.name) + elsif @species_listings_ids + MTaxonConceptFilterByAppendixQuery.new( + rel, @species_listings_ids + ).relation(@designation.name) + else + rel + end if @taxon_concepts_ids rel = MTaxonConceptFilterByIdWithDescendants.new(rel, @taxon_concepts_ids).relation end diff --git a/app/models/species/listings_export_factory.rb b/app/models/species/listings_export_factory.rb index 08348d3ead..a7d9c1e31a 100644 --- a/app/models/species/listings_export_factory.rb +++ b/app/models/species/listings_export_factory.rb @@ -1,10 +1,11 @@ class Species::ListingsExportFactory def self.new(filters = {}) - @designation = if filters[:designation_id] - Designation.find(filters[:designation_id]) - elsif filters[:designation] - Designation.find_by_name(filters[:designation].upcase) - end + @designation = + if filters[:designation_id] + Designation.find(filters[:designation_id]) + elsif filters[:designation] + Designation.find_by_name(filters[:designation].upcase) + end if @designation && @designation.name == 'CMS' Species::CmsListingsExport.new(@designation, filters) elsif @designation && @designation.name == 'EU' diff --git a/app/models/species/search.rb b/app/models/species/search.rb index 9199fa60c3..c510153763 100644 --- a/app/models/species/search.rb +++ b/app/models/species/search.rb @@ -36,11 +36,12 @@ def initialize_params(options) def initialize_query @query = MTaxonConcept.taxonomic_layout - @query = if @taxonomy == :cms - @query.by_cms_taxonomy - else - @query.by_cites_eu_taxonomy - end + @query = + if @taxonomy == :cms + @query.by_cms_taxonomy + else + @query.by_cites_eu_taxonomy + end if @visibility == :speciesplus @query = @query.where(:show_in_species_plus => true) diff --git a/app/models/species/taxon_concept_prefix_matcher.rb b/app/models/species/taxon_concept_prefix_matcher.rb index 48a2fc9dba..73c431bc7e 100644 --- a/app/models/species/taxon_concept_prefix_matcher.rb +++ b/app/models/species/taxon_concept_prefix_matcher.rb @@ -27,46 +27,50 @@ def initialize_options(options) def initialize_query @query = MAutoCompleteTaxonConcept.scoped - @query = if @visibility == :trade - @query.order(:full_name) - else - @query.order([:rank_order, :full_name]) - end + @query = + if @visibility == :trade + @query.order(:full_name) + else + @query.order([:rank_order, :full_name]) + end unless @ranks.empty? @query = @query.where(:rank_name => @ranks) end - @query = if @taxonomy == :cms - @query.by_cms_taxonomy - else - @query.by_cites_eu_taxonomy - end + @query = + if @taxonomy == :cms + @query.by_cms_taxonomy + else + @query.by_cites_eu_taxonomy + end - @query = if @visibility == :trade_internal && @include_synonyms - @query # no filter on name_status for internal search on reported taxon - elsif @visibility == :trade_internal && !@include_synonyms - @query.where(:show_in_trade_internal_ac => true) - elsif @visibility == :trade - @query.where(:show_in_trade_ac => true) - elsif @visibility == :elibrary - @query.where("show_in_species_plus_ac OR name_status = 'N'") - else - @query.where(:show_in_species_plus_ac => true) - end + @query = + if @visibility == :trade_internal && @include_synonyms + @query # no filter on name_status for internal search on reported taxon + elsif @visibility == :trade_internal && !@include_synonyms + @query.where(:show_in_trade_internal_ac => true) + elsif @visibility == :trade + @query.where(:show_in_trade_ac => true) + elsif @visibility == :elibrary + @query.where("show_in_species_plus_ac OR name_status = 'N'") + else + @query.where(:show_in_species_plus_ac => true) + end # different types of name matching are required # in Species+ & Checklist the name may match any of: scientific name, synonyms, # common names as well as not CITES listed subspecies # in trade dropdowns the matching on subspecies does not occur # in addition, the 'reported taxon' in internal trade matches only on self - types_of_match = if @visibility == :trade_internal && @include_synonyms - ['SELF'] - elsif [:trade_internal, :trade].include? @visibility - ['SELF', 'SYNONYM', 'COMMON_NAME'] - else - ['SELF', 'SYNONYM', 'COMMON_NAME', 'SUBSPECIES'] - end + types_of_match = + if @visibility == :trade_internal && @include_synonyms + ['SELF'] + elsif [:trade_internal, :trade].include? @visibility + ['SELF', 'SYNONYM', 'COMMON_NAME'] + else + ['SELF', 'SYNONYM', 'COMMON_NAME', 'SUBSPECIES'] + end @query = @query. select('id, full_name, rank_name, name_status, diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index 24f6882008..4754e554ee 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -78,15 +78,13 @@ class TaxonConcept < ActiveRecord::Base :conditions => [ "taxon_relationship_type_id IN (SELECT id FROM taxon_relationship_types - WHERE name = '#{TaxonRelationshipType::HAS_SYNONYM}')" - ] + WHERE name = '#{TaxonRelationshipType::HAS_SYNONYM}')"] has_many :inverse_synonym_relationships, :class_name => 'TaxonRelationship', :foreign_key => :other_taxon_concept_id, :dependent => :destroy, :conditions => [ "taxon_relationship_type_id IN (SELECT id FROM taxon_relationship_types - WHERE name = '#{TaxonRelationshipType::HAS_SYNONYM}')" - ] + WHERE name = '#{TaxonRelationshipType::HAS_SYNONYM}')"] has_many :synonyms, :class_name => 'TaxonConcept', :through => :synonym_relationships, :source => :other_taxon_concept has_many :accepted_names, :class_name => 'TaxonConcept', @@ -104,8 +102,7 @@ class TaxonConcept < ActiveRecord::Base :conditions => [ "taxon_relationship_type_id IN (SELECT id FROM taxon_relationship_types - WHERE name = '#{TaxonRelationshipType::HAS_HYBRID}')" - ] + WHERE name = '#{TaxonRelationshipType::HAS_HYBRID}')"] has_many :hybrids, :class_name => 'TaxonConcept', :through => :hybrid_relationships, :source => :other_taxon_concept has_many :hybrid_parents, :class_name => 'TaxonConcept', @@ -115,15 +112,13 @@ class TaxonConcept < ActiveRecord::Base :conditions => [ "taxon_relationship_type_id IN (SELECT id FROM taxon_relationship_types - WHERE name = '#{TaxonRelationshipType::HAS_TRADE_NAME}')" - ] + WHERE name = '#{TaxonRelationshipType::HAS_TRADE_NAME}')"] has_many :inverse_trade_name_relationships, :class_name => 'TaxonRelationship', :foreign_key => :other_taxon_concept_id, :dependent => :destroy, :conditions => [ "taxon_relationship_type_id IN (SELECT id FROM taxon_relationship_types - WHERE name = '#{TaxonRelationshipType::HAS_TRADE_NAME}')" - ] + WHERE name = '#{TaxonRelationshipType::HAS_TRADE_NAME}')"] has_many :trade_names, :class_name => 'TaxonConcept', :through => :trade_name_relationships, :source => :other_taxon_concept has_many :accepted_names_for_trade_name, :class_name => 'TaxonConcept', @@ -499,7 +494,8 @@ def maximum_2_hybrid_parents def ensure_taxonomic_position if new_record? && fixed_order_required? && taxonomic_position.blank? - prev_taxonomic_position = if parent + prev_taxonomic_position = + if parent last_sibling = TaxonConcept.where(:parent_id => parent_id). maximum(:taxonomic_position) last_sibling || (parent.taxonomic_position + '.0') diff --git a/app/models/taxon_concept_data.rb b/app/models/taxon_concept_data.rb index 08d2e62159..7d11467565 100644 --- a/app/models/taxon_concept_data.rb +++ b/app/models/taxon_concept_data.rb @@ -36,32 +36,34 @@ def higher_taxa_from_self def higher_taxa_from_parent field_names = higher_taxa_field_names - data = if @taxon_concept.parent && @taxon_concept.parent.data - @taxon_concept.parent.data - else - fake_parent = - case @taxon_concept.name_status - when 'H' - @taxon_concept.hybrid_parents.first - when 'S' - @taxon_concept.accepted_names.first - when 'T' - @taxon_concept.accepted_names_for_trade_name.first - end - fake_parent && fake_parent.data - end + data = + if @taxon_concept.parent && @taxon_concept.parent.data + @taxon_concept.parent.data + else + fake_parent = + case @taxon_concept.name_status + when 'H' + @taxon_concept.hybrid_parents.first + when 'S' + @taxon_concept.accepted_names.first + when 'T' + @taxon_concept.accepted_names_for_trade_name.first + end + fake_parent && fake_parent.data + end return nil unless data data.slice(*field_names) end def higher_taxa_field_names - higher_taxa_ranks = if @rank_name - # ranks above this taxon (inclusive of this taxon's rank) - Rank.in_range(@rank_name, Rank::KINGDOM) - else - # all ranks - Rank.in_range(nil, nil) - end + higher_taxa_ranks = + if @rank_name + # ranks above this taxon (inclusive of this taxon's rank) + Rank.in_range(@rank_name, Rank::KINGDOM) + else + # all ranks + Rank.in_range(nil, nil) + end higher_taxa_ranks.map do |r| ["#{r.downcase}_id", "#{r.downcase}_name"] end.flatten diff --git a/app/models/trade/filter.rb b/app/models/trade/filter.rb index 9ec4e9ad7a..f0ec05fdb5 100644 --- a/app/models/trade/filter.rb +++ b/app/models/trade/filter.rb @@ -29,19 +29,20 @@ def initialize_query @query = Trade::Shipment.from('trade_shipments_with_taxa_view trade_shipments') unless @taxon_concepts_ids.empty? - cascading_ranks = if @internal - # always cascade if query is coming from the internal interface - Rank.in_range(Rank::SPECIES, Rank::KINGDOM) - elsif @taxon_with_descendants && !@internal - # the magnificent hack to make sure that queries coming from the public - # interface cascade to taxon descendants when searching by genus, - # but only through the 'genus' selector, not 'taxon' - Rank.in_range(Rank::SPECIES, Rank::GENUS) - else - # this has to be public interface + search by taxon - # only cascade for species - Rank.in_range(Rank::SPECIES, Rank::SPECIES) - end + cascading_ranks = + if @internal + # always cascade if query is coming from the internal interface + Rank.in_range(Rank::SPECIES, Rank::KINGDOM) + elsif @taxon_with_descendants && !@internal + # the magnificent hack to make sure that queries coming from the public + # interface cascade to taxon descendants when searching by genus, + # but only through the 'genus' selector, not 'taxon' + Rank.in_range(Rank::SPECIES, Rank::GENUS) + else + # this has to be public interface + search by taxon + # only cascade for species + Rank.in_range(Rank::SPECIES, Rank::SPECIES) + end taxon_concepts = MTaxonConcept.where(id: @taxon_concepts_ids) taxon_concepts_conditions = taxon_concepts.map do |tc| diff --git a/app/models/trade/sandbox.rb b/app/models/trade/sandbox.rb index 4345a4e938..bf7ffc2507 100644 --- a/app/models/trade/sandbox.rb +++ b/app/models/trade/sandbox.rb @@ -71,11 +71,12 @@ def create_target_table def copy_csv_to_target_table require 'psql_command' - columns_in_csv_order = if (@annual_report_upload.point_of_view == 'E') - Trade::SandboxTemplate::EXPORTER_COLUMNS - else - Trade::SandboxTemplate::IMPORTER_COLUMNS - end + columns_in_csv_order = + if (@annual_report_upload.point_of_view == 'E') + Trade::SandboxTemplate::EXPORTER_COLUMNS + else + Trade::SandboxTemplate::IMPORTER_COLUMNS + end cmd = Trade::SandboxTemplate.copy_stmt(@table_name, @csv_file_path, columns_in_csv_order) PsqlCommand.new(cmd).execute end diff --git a/app/models/trade/shipment_observer.rb b/app/models/trade/shipment_observer.rb index ddc0621d6e..7a12461e8e 100644 --- a/app/models/trade/shipment_observer.rb +++ b/app/models/trade/shipment_observer.rb @@ -9,11 +9,12 @@ def before_save(shipment) shipment.origin_permits_ids_was ].each do |permits_ids| # no idea why this is sometimes a string and sometimes an Array - @old_permits_ids += if permits_ids.is_a?(Array) - permits_ids.dup - else - parse_pg_array(permits_ids || '') - end + @old_permits_ids += + if permits_ids.is_a?(Array) + permits_ids.dup + else + parse_pg_array(permits_ids || '') + end end unless shipment.reported_taxon_concept_id shipment.reported_taxon_concept_id = shipment.taxon_concept_id diff --git a/config/initializers/active_record_comparison_attributes.rb b/config/initializers/active_record_comparison_attributes.rb index 1e653f209b..d13a5cf9d7 100644 --- a/config/initializers/active_record_comparison_attributes.rb +++ b/config/initializers/active_record_comparison_attributes.rb @@ -20,12 +20,13 @@ def comparison_conditions(comparison_attributes=nil) a = self.class.scoped arel_nodes = [] comparison_attributes.each do |attr_name, attr_val| - arel_nodes << if self.class.text_attributes.include? attr_name - Arel::Nodes::NamedFunction.new('SQUISH_NULL', [a.table[attr_name]]). - eq(attr_val.presence) - else - a.table[attr_name].eq(attr_val) - end + arel_nodes << + if self.class.text_attributes.include? attr_name + Arel::Nodes::NamedFunction.new('SQUISH_NULL', [a.table[attr_name]]). + eq(attr_val.presence) + else + a.table[attr_name].eq(attr_val) + end end arel_nodes.inject(&:and) end diff --git a/lib/csv_column_headers_validator.rb b/lib/csv_column_headers_validator.rb index 14c99927ff..77cc783bf6 100644 --- a/lib/csv_column_headers_validator.rb +++ b/lib/csv_column_headers_validator.rb @@ -7,11 +7,12 @@ def validate_each(record, attribute, value) begin CSV.open(value.current_path, "r") do |csv| reported_column_headers = csv.first.map(&:downcase) - required_column_headers = if (record.point_of_view == 'E') - Trade::SandboxTemplate::CSV_EXPORTER_COLUMNS - else - Trade::SandboxTemplate::CSV_IMPORTER_COLUMNS - end.map(&:classify).map(&:downcase) + required_column_headers = + if (record.point_of_view == 'E') + Trade::SandboxTemplate::CSV_EXPORTER_COLUMNS + else + Trade::SandboxTemplate::CSV_IMPORTER_COLUMNS + end.map(&:classify).map(&:downcase) missing_columns = required_column_headers - reported_column_headers excess_columns = reported_column_headers - required_column_headers if !(missing_columns.empty? && excess_columns.empty?) diff --git a/lib/modules/sapi/geoip.rb b/lib/modules/sapi/geoip.rb index c55c9c6766..d171d3d4f3 100644 --- a/lib/modules/sapi/geoip.rb +++ b/lib/modules/sapi/geoip.rb @@ -18,11 +18,12 @@ def initialize def resolve(ip) result = country_and_city(ip).merge(organisation(ip)) result.each do |k, v| - result[k] = if v.nil? - 'Unknown' - else - v.force_encoding("ISO-8859-1").encode("UTF-8") - end + result[k] = + if v.nil? + 'Unknown' + else + v.force_encoding("ISO-8859-1").encode("UTF-8") + end end end diff --git a/lib/modules/search_param_sanitiser.rb b/lib/modules/search_param_sanitiser.rb index 4c2bb3f455..506480d52b 100644 --- a/lib/modules/search_param_sanitiser.rb +++ b/lib/modules/search_param_sanitiser.rb @@ -19,22 +19,24 @@ def sanitise_boolean(b, default = nil) end def sanitise_positive_integer(i, default = nil) - new_i = if i.is_a?(String) - tmp = i.to_i - tmp.to_s == i ? tmp : nil - else - i - end + new_i = + if i.is_a?(String) + tmp = i.to_i + tmp.to_s == i ? tmp : nil + else + i + end new_i && new_i > 0 ? new_i : default end def sanitise_float(f, default = nil) - new_f = if f.is_a?(String) - tmp = f.to_f - tmp.to_s == f ? tmp : nil - else - f - end + new_f = + if f.is_a?(String) + tmp = f.to_f + tmp.to_s == f ? tmp : nil + else + f + end new_f || default end From 4838799ebd4743673bbbaa04b9b980cc59bc33dc Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Wed, 1 Jun 2016 13:14:54 +0100 Subject: [PATCH 286/365] Hash#has_key? is deprecated in favor of Hash#key? --- .rubocop_todo.yml | 10 ---------- app/controllers/trade/shipments_controller.rb | 6 +++--- app/models/trade/validation_rule.rb | 4 ++-- app/models/trade_restriction.rb | 6 +++--- 4 files changed, 8 insertions(+), 18 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 03863f181a..488e28674b 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -317,16 +317,6 @@ Style/CommentIndentation: Style/ConditionalAssignment: Enabled: false -# Offense count: 10 -# Cop supports --auto-correct. -Style/DeprecatedHashMethods: - Exclude: - - 'app/controllers/api/v1/geo_entities_controller.rb' - - 'app/controllers/checklist/geo_entities_controller.rb' - - 'app/controllers/trade/shipments_controller.rb' - - 'app/models/trade/validation_rule.rb' - - 'app/models/trade_restriction.rb' - # Offense count: 623 Style/Documentation: Enabled: false diff --git a/app/controllers/trade/shipments_controller.rb b/app/controllers/trade/shipments_controller.rb index 50aa2fefa1..074cb80e78 100644 --- a/app/controllers/trade/shipments_controller.rb +++ b/app/controllers/trade/shipments_controller.rb @@ -100,13 +100,13 @@ def batch_update_params unless reporter_type.blank? res[:reported_by_exporter] = Trade::Shipment.reporter_type_to_reported_by_exporter(reporter_type) end - if res.has_key?(:import_permit_number) && res[:import_permit_number].nil? + if res.key?(:import_permit_number) && res[:import_permit_number].nil? res[:import_permits_ids] = nil end - if res.has_key?(:export_permit_number) && res[:export_permit_number].nil? + if res.key?(:export_permit_number) && res[:export_permit_number].nil? res[:export_permits_ids] = nil end - if res.has_key?(:origin_permit_number) && res[:origin_permit_number].nil? + if res.key?(:origin_permit_number) && res[:origin_permit_number].nil? res[:origin_permits_ids] = nil end res diff --git a/app/models/trade/validation_rule.rb b/app/models/trade/validation_rule.rb index ff71b082a1..849a4f992a 100644 --- a/app/models/trade/validation_rule.rb +++ b/app/models/trade/validation_rule.rb @@ -112,14 +112,14 @@ def sanitized_shipments_scope (scope_def.keys & ['inclusion', 'exclusion']).each do |k| tmp_def[k] = scope_def[k].map{ |value| GeoEntity.find_by_iso_code2(value).id } end - tmp_def['blank'] = scope_def['blank'] if scope_def.has_key?('blank') + tmp_def['blank'] = scope_def['blank'] if scope_def.key?('blank') res[scope_column + '_id'] = tmp_def when /(.+)_code$/ tmp_def = {} (scope_def.keys & ['inclusion', 'exclusion']).each do |k| tmp_def[k] = scope_def[k].map{ |value| TradeCode.find_by_type_and_code($1.capitalize, value).id } end - tmp_def['blank'] = scope_def['blank'] if scope_def.has_key?('blank') + tmp_def['blank'] = scope_def['blank'] if scope_def.key?('blank') res[$1 + '_id'] = tmp_def else tmp_def = {} diff --git a/app/models/trade_restriction.rb b/app/models/trade_restriction.rb index bfddf68028..e7db16dc9a 100644 --- a/app/models/trade_restriction.rb +++ b/app/models/trade_restriction.rb @@ -168,7 +168,7 @@ def self.filter_is_current(set) end def self.filter_geo_entities(filters) - if filters.has_key?("geo_entities_ids") + if filters.key?("geo_entities_ids") geo_entities_ids = GeoEntity.nodes_and_descendants( filters["geo_entities_ids"] ).map(&:id) @@ -178,7 +178,7 @@ def self.filter_geo_entities(filters) end def self.filter_taxon_concepts(filters) - if filters.has_key?("taxon_concepts_ids") + if filters.key?("taxon_concepts_ids") conds_str = <<-SQL ARRAY[ taxon_concepts_mview.id, taxon_concepts_mview.family_id, @@ -193,7 +193,7 @@ def self.filter_taxon_concepts(filters) end def self.filter_years(filters) - if filters.has_key?("years") + if filters.key?("years") return where('EXTRACT(YEAR FROM trade_restrictions.start_date) IN (?)', filters["years"]) end From ebe9db598ebbcd23265b5e5e09365eaecd768173 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Wed, 1 Jun 2016 13:25:00 +0100 Subject: [PATCH 287/365] Use empty lines between method definitions --- .rubocop_todo.yml | 6 ------ app/models/checklist/checklist.rb | 1 + app/models/checklist/history_fetcher.rb | 1 + app/models/checklist/index_fetcher.rb | 1 + app/models/checklist/pdf/index_fetcher.rb | 1 + app/models/cites_suspension.rb | 1 + app/models/m_taxon_concept.rb | 10 ++++++++++ app/serializers/species/cites_suspension_serializer.rb | 1 + app/serializers/species/eu_decision_serializer.rb | 4 ++++ app/serializers/species/quota_serializer.rb | 2 ++ .../trade/annual_report_upload_serializer.rb | 4 ++++ .../trade/shipment_comptab_export_serializer.rb | 2 ++ .../trade/shipment_gross_net_export_serializer.rb | 1 + .../trade/show_annual_report_upload_serializer.rb | 6 ++++++ .../active_record_comparison_attributes.rb | 1 + config/initializers/migration_helpers.rb | 1 + lib/modules/downloads_cache.rb | 1 + lib/modules/sapi.rb | 3 +++ spec/models/trade/annual_report_upload_spec.rb | 3 +++ spec/support/sapi_helpers.rb | 9 +++++++++ 20 files changed, 53 insertions(+), 6 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 488e28674b..2984732ca0 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -346,12 +346,6 @@ Style/EmptyElse: - 'app/models/rank.rb' - 'app/models/trade/shipment.rb' -# Offense count: 53 -# Cop supports --auto-correct. -# Configuration parameters: AllowAdjacentOneLineDefs. -Style/EmptyLineBetweenDefs: - Enabled: false - # Offense count: 67 # Cop supports --auto-correct. Style/EmptyLines: diff --git a/app/models/checklist/checklist.rb b/app/models/checklist/checklist.rb index 3bd45525b2..25c39001f1 100644 --- a/app/models/checklist/checklist.rb +++ b/app/models/checklist/checklist.rb @@ -73,6 +73,7 @@ def prepare_queries end def prepare_main_query; end + def prepare_kindom_queries; end # Takes the current search query and adds metadata diff --git a/app/models/checklist/history_fetcher.rb b/app/models/checklist/history_fetcher.rb index e9f44ad29a..3d17f2b822 100644 --- a/app/models/checklist/history_fetcher.rb +++ b/app/models/checklist/history_fetcher.rb @@ -4,6 +4,7 @@ def initialize(relation) @limit = 1000 @offset = 0 end + def next results = @relation.limit(@limit).offset(@offset) @offset += @limit diff --git a/app/models/checklist/index_fetcher.rb b/app/models/checklist/index_fetcher.rb index 2b52943e5b..065a13a460 100644 --- a/app/models/checklist/index_fetcher.rb +++ b/app/models/checklist/index_fetcher.rb @@ -4,6 +4,7 @@ def initialize(relation) @limit = 5000 @offset = 0 end + def next results = @relation.limit(@limit).offset(@offset) @offset += @limit diff --git a/app/models/checklist/pdf/index_fetcher.rb b/app/models/checklist/pdf/index_fetcher.rb index e10055335a..6ff5b4653d 100644 --- a/app/models/checklist/pdf/index_fetcher.rb +++ b/app/models/checklist/pdf/index_fetcher.rb @@ -4,6 +4,7 @@ def initialize(query) @limit = 5000 @offset = 0 end + def next results = MTaxonConcept.find_by_sql( @query.to_sql(@limit, @offset) diff --git a/app/models/cites_suspension.rb b/app/models/cites_suspension.rb index c67a12ab54..ad32f05db2 100644 --- a/app/models/cites_suspension.rb +++ b/app/models/cites_suspension.rb @@ -66,6 +66,7 @@ def handle_current_flag def start_notification_name start_notification && start_notification.name end + def end_notification_name end_notification && end_notification.name end diff --git a/app/models/m_taxon_concept.rb b/app/models/m_taxon_concept.rb index bc2dbcb111..7cda5adfe7 100644 --- a/app/models/m_taxon_concept.rb +++ b/app/models/m_taxon_concept.rb @@ -223,15 +223,25 @@ def countries_ids end def countries_iso_codes; all_distribution_iso_codes; end + def countries_full_names; all_distribution; end + def all_distribution; parse_pg_array(all_distribution_ary || ''); end + def all_distribution_iso_codes; parse_pg_array(all_distribution_iso_codes_ary || ''); end + def native_distribution; parse_pg_array(native_distribution_ary || ''); end + def introduced_distribution; parse_pg_array(introduced_distribution_ary || ''); end + def introduced_uncertain_distribution; parse_pg_array(introduced_uncertain_distribution_ary || ''); end + def reintroduced_distribution; parse_pg_array(reintroduced_distribution_ary || ''); end + def extinct_distribution; parse_pg_array(extinct_distribution_ary || ''); end + def extinct_uncertain_distribution; parse_pg_array(extinct_uncertain_distribution_ary || ''); end + def uncertain_distribution; parse_pg_array(uncertain_distribution_ary || ''); end def recently_changed diff --git a/app/serializers/species/cites_suspension_serializer.rb b/app/serializers/species/cites_suspension_serializer.rb index 20a04740ec..e47cce26e5 100644 --- a/app/serializers/species/cites_suspension_serializer.rb +++ b/app/serializers/species/cites_suspension_serializer.rb @@ -9,6 +9,7 @@ class Species::CitesSuspensionSerializer < ActiveModel::Serializer def geo_entity object['geo_entity_en'] && JSON.parse(object['geo_entity_en']) end + def start_notification object['start_notification'] && JSON.parse(object['start_notification']) end diff --git a/app/serializers/species/eu_decision_serializer.rb b/app/serializers/species/eu_decision_serializer.rb index 9b124fa449..b7dd12233a 100644 --- a/app/serializers/species/eu_decision_serializer.rb +++ b/app/serializers/species/eu_decision_serializer.rb @@ -12,15 +12,19 @@ class Species::EuDecisionSerializer < ActiveModel::Serializer def eu_decision_type object['eu_decision_type'] && JSON.parse(object['eu_decision_type']) end + def geo_entity object['geo_entity_en'] && JSON.parse(object['geo_entity_en']) end + def start_event object['start_event'] && JSON.parse(object['start_event']) end + def source object['source_en'] && JSON.parse(object['source_en']) end + def term object['term_en'] && JSON.parse(object['term_en']) end diff --git a/app/serializers/species/quota_serializer.rb b/app/serializers/species/quota_serializer.rb index c0e9459af4..3556983fe7 100644 --- a/app/serializers/species/quota_serializer.rb +++ b/app/serializers/species/quota_serializer.rb @@ -8,9 +8,11 @@ class Species::QuotaSerializer < ActiveModel::Serializer def geo_entity object['geo_entity_en'] && JSON.parse(object['geo_entity_en']) end + def unit object['unit_en'] && JSON.parse(object['unit_en']) end + def quota object['quota_for_display'] end diff --git a/app/serializers/trade/annual_report_upload_serializer.rb b/app/serializers/trade/annual_report_upload_serializer.rb index 0c6a010ed5..393e611135 100644 --- a/app/serializers/trade/annual_report_upload_serializer.rb +++ b/app/serializers/trade/annual_report_upload_serializer.rb @@ -5,15 +5,19 @@ class Trade::AnnualReportUploadSerializer < ActiveModel::Serializer def file_name object.csv_source_file.try(:path) && File.basename(object.csv_source_file.path) end + def created_at object.created_at.strftime("%d/%m/%y") end + def updated_at object.updated_at.strftime("%d/%m/%y") end + def created_by object.creator && object.creator.name end + def updated_by object.creator && object.updater.name end diff --git a/app/serializers/trade/shipment_comptab_export_serializer.rb b/app/serializers/trade/shipment_comptab_export_serializer.rb index 34c40e7fd5..d4bf40e9d7 100644 --- a/app/serializers/trade/shipment_comptab_export_serializer.rb +++ b/app/serializers/trade/shipment_comptab_export_serializer.rb @@ -3,9 +3,11 @@ class Trade::ShipmentComptabExportSerializer < ActiveModel::Serializer def rows object.query end + def column_headers object.csv_column_headers end + def table_title I18n.t "table_title.#{object.get_resource_name}" end diff --git a/app/serializers/trade/shipment_gross_net_export_serializer.rb b/app/serializers/trade/shipment_gross_net_export_serializer.rb index d3e725f5ab..a0690529d7 100644 --- a/app/serializers/trade/shipment_gross_net_export_serializer.rb +++ b/app/serializers/trade/shipment_gross_net_export_serializer.rb @@ -3,6 +3,7 @@ class Trade::ShipmentGrossNetExportSerializer < Trade::ShipmentComptabExportSeri def rows object.query end + def column_headers object.full_csv_column_headers end diff --git a/app/serializers/trade/show_annual_report_upload_serializer.rb b/app/serializers/trade/show_annual_report_upload_serializer.rb index 2c1c2824ee..cb51ed40e4 100644 --- a/app/serializers/trade/show_annual_report_upload_serializer.rb +++ b/app/serializers/trade/show_annual_report_upload_serializer.rb @@ -8,21 +8,27 @@ class Trade::ShowAnnualReportUploadSerializer < ActiveModel::Serializer def validation_errors object.validation_errors.sort_by(&:error_message) end + def file_name object.csv_source_file.try(:path) && File.basename(object.csv_source_file.path) end + def has_primary_errors !validation_errors.index{ |ve| ve.is_primary }.nil? end + def created_at object.created_at.strftime("%d/%m/%y") end + def updated_at object.updated_at.strftime("%d/%m/%y") end + def created_by object.creator && object.creator.name end + def updated_by object.creator && object.updater.name end diff --git a/config/initializers/active_record_comparison_attributes.rb b/config/initializers/active_record_comparison_attributes.rb index d13a5cf9d7..a95c7c1f53 100644 --- a/config/initializers/active_record_comparison_attributes.rb +++ b/config/initializers/active_record_comparison_attributes.rb @@ -8,6 +8,7 @@ module ClassMethods def ignored_attributes [:id, :created_at, :updated_at, :created_by_id, :updated_by_id, :original_id] end + def text_attributes; []; end end diff --git a/config/initializers/migration_helpers.rb b/config/initializers/migration_helpers.rb index 71dd9bca5a..f4073eed57 100644 --- a/config/initializers/migration_helpers.rb +++ b/config/initializers/migration_helpers.rb @@ -3,6 +3,7 @@ def view_sql(timestamp,view) File.read(Rails.root.join("db/views/#{view}/#{timestamp}.sql")) end + def function_sql(timestamp,function) File.read(Rails.root.join("db/functions/#{function}/#{timestamp}.sql")) end diff --git a/lib/modules/downloads_cache.rb b/lib/modules/downloads_cache.rb index 14d0a1ed99..45316f77fd 100644 --- a/lib/modules/downloads_cache.rb +++ b/lib/modules/downloads_cache.rb @@ -198,6 +198,7 @@ def self.update_species_downloads end puts "#{Time.now} all EU Decisions download generated in #{elapsed_time}s" end + def self.update_admin_downloads puts "Updating admin downloads" [Taxonomy::CITES_EU, Taxonomy::CMS].each do |taxonomy_name| diff --git a/lib/modules/sapi.rb b/lib/modules/sapi.rb index aeb313cf0a..42e60cb403 100644 --- a/lib/modules/sapi.rb +++ b/lib/modules/sapi.rb @@ -5,12 +5,15 @@ module Sapi def self.rebuild Sapi::StoredProcedures.rebuild end + def self.drop_indexes Sapi::Indexes.drop_indexes end + def self.create_indexes Sapi::Indexes.create_indexes end + def self.database_summary Sapi::Summary.database_summary end diff --git a/spec/models/trade/annual_report_upload_spec.rb b/spec/models/trade/annual_report_upload_spec.rb index d73aff3569..c0d680a4be 100644 --- a/spec/models/trade/annual_report_upload_spec.rb +++ b/spec/models/trade/annual_report_upload_spec.rb @@ -24,16 +24,19 @@ def exporter_file File.join(Rails.root, 'spec', 'support', 'annual_report_upload_exporter.csv') ) end + def importer_file Rack::Test::UploadedFile.new( File.join(Rails.root, 'spec', 'support', 'annual_report_upload_importer.csv') ) end + def importer_file_w_blanks Rack::Test::UploadedFile.new( File.join(Rails.root, 'spec', 'support', 'annual_report_upload_importer_blanks.csv') ) end + def invalid_file Rack::Test::UploadedFile.new( File.join(Rails.root, 'spec', 'support', 'annual_report_upload_invalid.csv') diff --git a/spec/support/sapi_helpers.rb b/spec/support/sapi_helpers.rb index 9f887b0444..812f206788 100644 --- a/spec/support/sapi_helpers.rb +++ b/spec/support/sapi_helpers.rb @@ -354,12 +354,14 @@ def create_year_format_validation :is_strict => true ) end + def create_taxon_concept_appendix_year_validation create(:taxon_concept_appendix_year_validation_rule, :is_primary => false, :is_strict => true ) end + def create_term_unit_validation create(:inclusion_validation_rule, :column_names => ['term_code', 'unit_code'], @@ -367,6 +369,7 @@ def create_term_unit_validation :is_primary => false ) end + def create_term_purpose_validation create(:inclusion_validation_rule, :column_names => ['term_code', 'purpose_code'], @@ -374,6 +377,7 @@ def create_term_purpose_validation :is_primary => false ) end + def create_taxon_concept_term_validation create(:inclusion_validation_rule, :column_names => ['taxon_concept_id', 'term_code'], @@ -382,6 +386,7 @@ def create_taxon_concept_term_validation :is_strict => true ) end + def create_taxon_concept_country_of_origin_validation create(:inclusion_validation_rule, :scope => { @@ -395,6 +400,7 @@ def create_taxon_concept_country_of_origin_validation :is_strict => true ) end + def create_taxon_concept_exporter_validation create(:inclusion_validation_rule, :scope => { @@ -409,6 +415,7 @@ def create_taxon_concept_exporter_validation :is_strict => true ) end + def create_exporter_country_of_origin_validation create(:distinct_values_validation_rule, :column_names => ['exporter', 'country_of_origin'], @@ -416,6 +423,7 @@ def create_exporter_country_of_origin_validation :is_strict => true ) end + def create_exporter_importer_validation create(:distinct_values_validation_rule, :column_names => ['exporter', 'importer'], @@ -423,6 +431,7 @@ def create_exporter_importer_validation :is_strict => true ) end + def create_taxon_concept_source_validation create(:taxon_concept_source_validation_rule, :column_names => ['taxon_concept_id', 'source_code'], From 2d3fc29078a39c1f8c51cb8952f5d51c88cabeab Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Wed, 1 Jun 2016 13:27:17 +0100 Subject: [PATCH 288/365] Remove extra blank lines --- .rubocop_todo.yml | 5 ----- Gemfile | 1 - app/controllers/admin/eu_suspensions_controller.rb | 1 - app/controllers/admin/listing_changes_controller.rb | 1 - app/controllers/api/v1/documents_controller.rb | 1 - app/controllers/application_controller.rb | 1 - app/models/checklist/higher_taxa_injector.rb | 1 - app/models/cms_mapping.rb | 1 - app/models/document_collection_order.rb | 1 - app/models/download.rb | 1 - app/models/eu_regulation.rb | 2 -- app/models/trade/filter.rb | 1 - app/serializers/species/show_taxon_concept_serializer.rb | 1 - .../species/show_taxon_concept_serializer_cites.rb | 1 - config/deploy.rb | 7 ------- config/deploy/production.rb | 7 ------- config/deploy/staging.rb | 8 -------- lib/capistrano/tasks/config.rake | 6 ------ lib/modules/sapi/indexes.rb | 1 - lib/modules/sapi/summary.rb | 1 - lib/tasks/import_cms_listings.rake | 1 - lib/tasks/import_countries.rake | 2 -- lib/tasks/import_hybrids.rake | 1 - lib/tasks/import_trade_permits.rake | 1 - lib/tasks/import_trade_shipments.rake | 1 - old_cap/deploy.rb | 3 --- old_cap/deploy/production.rb | 1 - .../admin/taxon_concept_comments_controller_spec.rb | 1 - spec/models/eu_decision_spec.rb | 1 - .../nomenclature_change/status_swap/processor_spec.rb | 1 - spec/models/trade/filter_spec.rb | 5 ----- spec/models/trade/shipment_spec.rb | 1 - spec/shared/caiman_latirostris.rb | 1 - spec/shared/cervus_elaphus.rb | 1 - 34 files changed, 70 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 2984732ca0..74e112322c 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -346,11 +346,6 @@ Style/EmptyElse: - 'app/models/rank.rb' - 'app/models/trade/shipment.rb' -# Offense count: 67 -# Cop supports --auto-correct. -Style/EmptyLines: - Enabled: false - # Offense count: 54 # Cop supports --auto-correct. Style/EmptyLinesAroundAccessModifier: diff --git a/Gemfile b/Gemfile index 0574aecd27..9d8175ca28 100644 --- a/Gemfile +++ b/Gemfile @@ -71,7 +71,6 @@ end # Use unicorn as the app server # gem 'unicorn' - # To use debugger # gem 'ruby-debug19', :require => 'ruby-debug' diff --git a/app/controllers/admin/eu_suspensions_controller.rb b/app/controllers/admin/eu_suspensions_controller.rb index c55948d452..88fe3d175a 100644 --- a/app/controllers/admin/eu_suspensions_controller.rb +++ b/app/controllers/admin/eu_suspensions_controller.rb @@ -1,7 +1,6 @@ class Admin::EuSuspensionsController < Admin::StandardAuthorizationController belongs_to :eu_suspension_regulation - protected def collection @eu_suspensions ||= end_of_association_chain. diff --git a/app/controllers/admin/listing_changes_controller.rb b/app/controllers/admin/listing_changes_controller.rb index fbdfbff490..259df96305 100644 --- a/app/controllers/admin/listing_changes_controller.rb +++ b/app/controllers/admin/listing_changes_controller.rb @@ -1,7 +1,6 @@ class Admin::ListingChangesController < Admin::StandardAuthorizationController belongs_to :eu_regulation - protected def collection @listing_changes ||= end_of_association_chain. diff --git a/app/controllers/api/v1/documents_controller.rb b/app/controllers/api/v1/documents_controller.rb index 2d45d61794..e56f346c93 100644 --- a/app/controllers/api/v1/documents_controller.rb +++ b/app/controllers/api/v1/documents_controller.rb @@ -95,7 +95,6 @@ def render_404 status: 404 end - def render_403 render file: "#{Rails.root}/public/403", layout: false, formats: [:html], status: 403 diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index f52275beef..06fd9ad628 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -40,7 +40,6 @@ def set_locale I18n.locale = params[:locale] || I18n.default_locale end - def metadata_for_search(search) { :total => search.total_cnt, diff --git a/app/models/checklist/higher_taxa_injector.rb b/app/models/checklist/higher_taxa_injector.rb index 311d49aeeb..b12d9e2577 100644 --- a/app/models/checklist/higher_taxa_injector.rb +++ b/app/models/checklist/higher_taxa_injector.rb @@ -62,7 +62,6 @@ def run_summary res end - #returns array of HigherTaxaItems that need to be inserted #between prev_item and curr_item in the taxonomic layout def higher_taxa_headers(prev_item, curr_item) diff --git a/app/models/cms_mapping.rb b/app/models/cms_mapping.rb index 5cbf5902c9..63566cf1f2 100644 --- a/app/models/cms_mapping.rb +++ b/app/models/cms_mapping.rb @@ -20,7 +20,6 @@ class CmsMapping < ActiveRecord::Base belongs_to :taxon_concept belongs_to :accepted_name, :class_name => 'TaxonConcept' - scope :filter, lambda { |option| case option when "MATCHES" diff --git a/app/models/document_collection_order.rb b/app/models/document_collection_order.rb index 26afa4cf55..63440403d6 100644 --- a/app/models/document_collection_order.rb +++ b/app/models/document_collection_order.rb @@ -32,5 +32,4 @@ def update(id_sort_index_hash) DocumentSearch.clear_cache end - end diff --git a/app/models/download.rb b/app/models/download.rb index 56ad7ed446..06a18ec483 100644 --- a/app/models/download.rb +++ b/app/models/download.rb @@ -19,7 +19,6 @@ class Download < ActiveRecord::Base validates :format, :presence => true, :inclusion => { :in => %w(pdf csv json) } validates :doc_type, :presence => true, :inclusion => { :in => %w(history index) } - COMPLETED = 'completed' FAILED = 'failed' WORKING = 'working' diff --git a/app/models/eu_regulation.rb b/app/models/eu_regulation.rb index 3f88283572..0510d3c857 100644 --- a/app/models/eu_regulation.rb +++ b/app/models/eu_regulation.rb @@ -33,8 +33,6 @@ class EuRegulation < Event validate :designation_is_eu validates :effective_at, :presence => true - - def activate! super notify_observers(:after_activate) diff --git a/app/models/trade/filter.rb b/app/models/trade/filter.rb index f0ec05fdb5..715ae3a48a 100644 --- a/app/models/trade/filter.rb +++ b/app/models/trade/filter.rb @@ -118,7 +118,6 @@ def initialize_query @query = @query.where(:source_id => nil) end - if !@countries_of_origin_ids.empty? local_field = "country_of_origin_id" blank_query = @country_of_origin_blank ? "OR country_of_origin_id IS NULL" : "" diff --git a/app/serializers/species/show_taxon_concept_serializer.rb b/app/serializers/species/show_taxon_concept_serializer.rb index 92a510d0ec..14191b8e21 100644 --- a/app/serializers/species/show_taxon_concept_serializer.rb +++ b/app/serializers/species/show_taxon_concept_serializer.rb @@ -10,7 +10,6 @@ class Species::ShowTaxonConceptSerializer < ActiveModel::Serializer has_many :taxon_concept_references, :serializer => Species::ReferenceSerializer, :key => :references - def rank_name object.data['rank_name'] end diff --git a/app/serializers/species/show_taxon_concept_serializer_cites.rb b/app/serializers/species/show_taxon_concept_serializer_cites.rb index 2ae9ca8f36..a8858dea07 100644 --- a/app/serializers/species/show_taxon_concept_serializer_cites.rb +++ b/app/serializers/species/show_taxon_concept_serializer_cites.rb @@ -274,7 +274,6 @@ def eu_listing_changes ).all end - def cites_listing object.listing && object.listing['cites_listing'] end diff --git a/config/deploy.rb b/config/deploy.rb index 017be062be..a413af3d25 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -13,7 +13,6 @@ set :backup_path, "/home/#{fetch(:deploy_user)}/Backup" - # Default value for :scm is :git set :scm, :git set :scm_username, "unepwcmc-read" @@ -21,7 +20,6 @@ # Default value for :format is :pretty # set :format, :pretty - set :rvm_type, :user set :rvm_ruby_version, '2.2.3' @@ -31,15 +29,12 @@ # Default value for :pty is false set :pty, true - set :ssh_options, { forward_agent: true, } - before "deploy:symlink:shared", "rsync:sync" - # Default value for :linked_files is [] set :linked_files, %w{config/database.yml config/mailer_config.yml config/secrets.yml .env} @@ -98,8 +93,6 @@ class PrecompileRequired < StandardError; end end end - - require 'yaml' require 'json' secrets = YAML.load(File.open('config/secrets.yml')) diff --git a/config/deploy/production.rb b/config/deploy/production.rb index b0c890853d..470442207d 100644 --- a/config/deploy/production.rb +++ b/config/deploy/production.rb @@ -15,7 +15,6 @@ set :backup_path, "/home/#{fetch(:deploy_user)}/Backup" - # server-based syntax # ====================== # Defines a single server with a list of roles and multiple properties. @@ -25,8 +24,6 @@ # server 'example.com', user: 'deploy', roles: %w{app web}, other_property: :other_value # server 'db.example.com', user: 'deploy', roles: %w{db} - - # role-based syntax # ================== @@ -39,8 +36,6 @@ # role :web, %w{user1@primary.com user2@additional.com}, other_property: :other_value # role :db, %w{deploy@example.com} - - # Configuration # ============= # You can set any configuration variable like in config/deploy.rb @@ -49,8 +44,6 @@ # http://capistranorb.com/documentation/getting-started/configuration/ # Feel free to add new variables to customise your setup. - - # Custom SSH Options # ================== # You may pass any option but keep in mind that net/ssh understands a diff --git a/config/deploy/staging.rb b/config/deploy/staging.rb index 0871e0be57..d8d02a0848 100644 --- a/config/deploy/staging.rb +++ b/config/deploy/staging.rb @@ -13,8 +13,6 @@ set :app_port, "80" - - # server-based syntax # ====================== # Defines a single server with a list of roles and multiple properties. @@ -24,8 +22,6 @@ # server 'example.com', user: 'deploy', roles: %w{app web}, other_property: :other_value # server 'db.example.com', user: 'deploy', roles: %w{db} - - # role-based syntax # ================== @@ -38,8 +34,6 @@ # role :web, %w{user1@primary.com user2@additional.com}, other_property: :other_value # role :db, %w{deploy@example.com} - - # Configuration # ============= # You can set any configuration variable like in config/deploy.rb @@ -48,8 +42,6 @@ # http://capistranorb.com/documentation/getting-started/configuration/ # Feel free to add new variables to customise your setup. - - # Custom SSH Options # ================== # You may pass any option but keep in mind that net/ssh understands a diff --git a/lib/capistrano/tasks/config.rake b/lib/capistrano/tasks/config.rake index ceb40c33d5..3b56925e6e 100644 --- a/lib/capistrano/tasks/config.rake +++ b/lib/capistrano/tasks/config.rake @@ -324,8 +324,6 @@ namespace :config do end end - - namespace :config do desc "Configure app specific nagios monitoring" task :setup do @@ -337,9 +335,6 @@ namespace :config do end end - - - namespace :config do desc "Configure app specific event handler" task :setup do @@ -354,7 +349,6 @@ cd #{deploy_to}/current/ ; nohup bundle exec sidekiq -e production -C #{deploy_t end end - namespace :config do desc "Configure logrotate" task :setup do diff --git a/lib/modules/sapi/indexes.rb b/lib/modules/sapi/indexes.rb index ce933bec94..53db38e3c4 100644 --- a/lib/modules/sapi/indexes.rb +++ b/lib/modules/sapi/indexes.rb @@ -180,6 +180,5 @@ def self.create_indexes_on_shipments ActiveRecord::Base.connection.execute(sql) end - end end diff --git a/lib/modules/sapi/summary.rb b/lib/modules/sapi/summary.rb index c889675943..a5dc1e993c 100644 --- a/lib/modules/sapi/summary.rb +++ b/lib/modules/sapi/summary.rb @@ -1,7 +1,6 @@ module Sapi module Summary - def self.database_stats stats = {} stats[:core] = self.core_stats diff --git a/lib/tasks/import_cms_listings.rake b/lib/tasks/import_cms_listings.rake index a697cdb6a2..267907f602 100644 --- a/lib/tasks/import_cms_listings.rake +++ b/lib/tasks/import_cms_listings.rake @@ -194,7 +194,6 @@ namespace :import do puts "INSERTING listed populations (listing distributions)" ActiveRecord::Base.connection.execute(sql) - sql = <<-SQL INSERT INTO instruments(name, designation_id, created_at, updated_at) SELECT DISTINCT BTRIM(#{TMP_TABLE}.designation), #{designation.id}, diff --git a/lib/tasks/import_countries.rake b/lib/tasks/import_countries.rake index a5b02b4dc7..48a1ea464d 100644 --- a/lib/tasks/import_countries.rake +++ b/lib/tasks/import_countries.rake @@ -39,7 +39,6 @@ namespace :import do puts "There are now #{GeoEntity.count(conditions: {geo_entity_type_id: territory_type.id})} territories in the database." end - desc "Add country names in spanish and french" task :countries_translations => [:environment] do CSV.foreach("lib/files/country_codes_en_es_fr_utf8.csv") do |row| @@ -54,7 +53,6 @@ namespace :import do end end - def link_countries puts "Link territories to countries and countries to respective CITES regions" puts "There are #{GeoRelationship.count} geo_relationships in the database." diff --git a/lib/tasks/import_hybrids.rake b/lib/tasks/import_hybrids.rake index 4f4468605b..59c862fc90 100644 --- a/lib/tasks/import_hybrids.rake +++ b/lib/tasks/import_hybrids.rake @@ -16,7 +16,6 @@ namespace :import do create_table_from_csv_headers(file, TMP_TABLE) copy_data(file, TMP_TABLE) - # Importing Hybrids, step by step: # TaxonConcepts many to one relationship with taxon_names [scientific_name] # 1- Insert all scientific_names into taxon_names table (DISTINCT) diff --git a/lib/tasks/import_trade_permits.rake b/lib/tasks/import_trade_permits.rake index 4cb4e6c047..a68b8d0303 100644 --- a/lib/tasks/import_trade_permits.rake +++ b/lib/tasks/import_trade_permits.rake @@ -7,7 +7,6 @@ namespace :import do trade_shipments_indexed = {"trade_shipments" => ["export_permits_ids", "import_permits_ids", "origin_permits_ids"]} trade_shipments_to_index = {"trade_shipments" => ["legacy_shipment_number"]} - files = files_from_args(t, args) files.each do |file| drop_table(TMP_TABLE) diff --git a/lib/tasks/import_trade_shipments.rake b/lib/tasks/import_trade_shipments.rake index 88f74049c4..c7a9673b56 100644 --- a/lib/tasks/import_trade_shipments.rake +++ b/lib/tasks/import_trade_shipments.rake @@ -74,7 +74,6 @@ namespace :import do end end - def drop_create_and_copy_temp(tmp_table, file) puts "Creating temp table" drop_table(tmp_table) diff --git a/old_cap/deploy.rb b/old_cap/deploy.rb index 4b1e57463a..c2ad25c9f6 100644 --- a/old_cap/deploy.rb +++ b/old_cap/deploy.rb @@ -35,7 +35,6 @@ set :slack_username, shuffle_deployer[0] # displayed as name of message sender set :slack_emoji, shuffle_deployer[1] # will be used as the avatar for the message - set :generate_webserver_config, false require 'rvm/capistrano' @@ -47,7 +46,6 @@ # and Apache configs. Should be unique on the Brightbox set :application, "sapi" - # got sick of "gem X not found in any of the sources" when using the default whenever recipe # probable source of issue: # https://github.com/javan/whenever/commit/7ae1009c31deb03c5db4a68f5fc99ea099ce5655 @@ -81,7 +79,6 @@ end end - # Target directory for the application on the web and app servers. set(:deploy_to) { File.join("", "home", user, application) } diff --git a/old_cap/deploy/production.rb b/old_cap/deploy/production.rb index f570d058c0..aeb5de4f19 100644 --- a/old_cap/deploy/production.rb +++ b/old_cap/deploy/production.rb @@ -6,7 +6,6 @@ ## List of servers server "unepwcmc-013.vm.brightbox.net", :app, :web, :db, :primary => true - set :application, "sapi" set :server_name, "sapi.unepwcmc-013.vm.brightbox.net" set :sudo_user, "rails" diff --git a/spec/controllers/admin/taxon_concept_comments_controller_spec.rb b/spec/controllers/admin/taxon_concept_comments_controller_spec.rb index f68ca10cac..b1e4406634 100644 --- a/spec/controllers/admin/taxon_concept_comments_controller_spec.rb +++ b/spec/controllers/admin/taxon_concept_comments_controller_spec.rb @@ -26,7 +26,6 @@ end end - describe 'PUT update' do let(:comment){ @taxon_concept.comments.create({note: 'bleh'}) } it 'redirects to index with notice when success' do diff --git a/spec/models/eu_decision_spec.rb b/spec/models/eu_decision_spec.rb index 072023af4c..2a52adea0e 100644 --- a/spec/models/eu_decision_spec.rb +++ b/spec/models/eu_decision_spec.rb @@ -83,5 +83,4 @@ end end - end diff --git a/spec/models/nomenclature_change/status_swap/processor_spec.rb b/spec/models/nomenclature_change/status_swap/processor_spec.rb index f0447d2d0e..a4532799be 100644 --- a/spec/models/nomenclature_change/status_swap/processor_spec.rb +++ b/spec/models/nomenclature_change/status_swap/processor_spec.rb @@ -47,7 +47,6 @@ end end - describe :summary do let(:status_change){ a_to_s_with_swap } specify { expect(processor.summary).to be_kind_of(Array) } diff --git a/spec/models/trade/filter_spec.rb b/spec/models/trade/filter_spec.rb index 06e6f28b96..8ae8bd3913 100644 --- a/spec/models/trade/filter_spec.rb +++ b/spec/models/trade/filter_spec.rb @@ -134,21 +134,18 @@ specify { subject.length.should == 2 } end - context "when searching for units_ids" do subject { Trade::Filter.new({:units_ids => [@unit.id]}).results } specify { subject.should include(@shipment1) } specify { subject.length.should == 2 } end - context "when searching for purposes_ids" do subject { Trade::Filter.new({:purposes_ids => [@purpose.id]}).results } specify { subject.should include(@shipment1) } specify { subject.length.should == 6 } end - context "when searching for sources_ids" do context "when code" do subject { Trade::Filter.new({:sources_ids => [@source.id]}).results } @@ -238,7 +235,6 @@ end end - context "when searching by permit" do context "when permit number" do subject { Trade::Filter.new({:internal => true, :permits_ids => [@export_permit1.id]}).results } @@ -279,6 +275,5 @@ specify { subject.total_cnt.should == 6 } end - end end diff --git a/spec/models/trade/shipment_spec.rb b/spec/models/trade/shipment_spec.rb index 210b62036d..3154d4069e 100644 --- a/spec/models/trade/shipment_spec.rb +++ b/spec/models/trade/shipment_spec.rb @@ -70,7 +70,6 @@ describe "secondary validations" do - before(:each) do # an animal @genus = create_cites_eu_genus( diff --git a/spec/shared/caiman_latirostris.rb b/spec/shared/caiman_latirostris.rb index 0048409af2..cb5e54a862 100644 --- a/spec/shared/caiman_latirostris.rb +++ b/spec/shared/caiman_latirostris.rb @@ -152,7 +152,6 @@ :is_party => false ) - Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings self.instance_variables.each do |t| var = self.instance_variable_get(t) diff --git a/spec/shared/cervus_elaphus.rb b/spec/shared/cervus_elaphus.rb index eccbdd42d8..0f43d12c47 100644 --- a/spec/shared/cervus_elaphus.rb +++ b/spec/shared/cervus_elaphus.rb @@ -50,7 +50,6 @@ :is_current => true ) - create_eu_B_addition( :taxon_concept => @subspecies1, :effective_at => '2013-10-08', From a5e2f127710d13e36219c1d901467fd2a5f588c1 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 3 Jun 2016 14:31:10 +0100 Subject: [PATCH 289/365] Annotation keywords like TODO should be all upper case, followed by a colon, and a space, then a note describing the problem --- .rubocop_todo.yml | 19 ------------------- app/models/checklist/checklist.rb | 4 ++-- app/models/checklist/pdf/index_content.rb | 2 +- app/models/checklist/timeline.rb | 2 +- app/models/document.rb | 2 +- .../trade/distinct_values_validation_rule.rb | 2 +- app/models/trade/sandbox.rb | 2 +- .../checklist/checklist_serializer.rb | 2 +- lib/tasks/helpers_for_import.rb | 2 +- lib/tasks/import_distributions.rake | 2 +- 10 files changed, 10 insertions(+), 29 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 74e112322c..fced6bfd65 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -281,25 +281,6 @@ Style/ColonMethodCall: - 'lib/tasks/db_migrate_plpgsql.rake' - 'lib/tasks/import.rake' -# Offense count: 13 -# Cop supports --auto-correct. -# Configuration parameters: Keywords. -# Keywords: TODO, FIXME, OPTIMIZE, HACK, REVIEW -Style/CommentAnnotation: - Exclude: - - 'app/controllers/api/v1/geo_entities_controller.rb' - - 'app/controllers/checklist/geo_entities_controller.rb' - - 'app/models/checklist/checklist.rb' - - 'app/models/checklist/pdf/index_content.rb' - - 'app/models/checklist/timeline.rb' - - 'app/models/document.rb' - - 'app/models/trade/distinct_values_validation_rule.rb' - - 'app/models/trade/sandbox.rb' - - 'app/serializers/checklist/checklist_serializer.rb' - - 'config/routes.rb' - - 'lib/tasks/helpers_for_import.rb' - - 'lib/tasks/import_distributions.rake' - # Offense count: 5 # Cop supports --auto-correct. Style/CommentIndentation: diff --git a/app/models/checklist/checklist.rb b/app/models/checklist/checklist.rb index 25c39001f1..90216d93f0 100644 --- a/app/models/checklist/checklist.rb +++ b/app/models/checklist/checklist.rb @@ -89,7 +89,7 @@ def generate injector = Checklist::HigherTaxaInjector.new(@plantae) @plantae = injector.run end - [self] #TODO just for compatibility with frontend, no sensible reason for this + [self] #TODO: just for compatibility with frontend, no sensible reason for this end # Converts a list of search filters into a limited length @@ -166,7 +166,7 @@ def self.summarise_filters(params) end end - #TODO common names, authors + #TODO: common names, authors if summary.length > 0 summary.join(" ") diff --git a/app/models/checklist/pdf/index_content.rb b/app/models/checklist/pdf/index_content.rb index 951572acd0..0ad7fb5197 100644 --- a/app/models/checklist/pdf/index_content.rb +++ b/app/models/checklist/pdf/index_content.rb @@ -1,4 +1,4 @@ -# TODO replace rank name strings with constants from the Rank model +# TODO: replace rank name strings with constants from the Rank model # or better yet, define methods such as "ranks_below_family" # in the rank class to clean up the code here module Checklist::Pdf::IndexContent diff --git a/app/models/checklist/timeline.rb b/app/models/checklist/timeline.rb index d6dbdcbbe9..ed9f3f8a4e 100644 --- a/app/models/checklist/timeline.rb +++ b/app/models/checklist/timeline.rb @@ -24,7 +24,7 @@ def add_event(event) proportionate_time_span = event.effective_at - @time_start position = (proportionate_time_span / (@time_end - @time_start)).round(2) event.pos = position - if event.is_addition? # TODO inclusion event with appendix change + if event.is_addition? # TODO: inclusion event with appendix change add_addition_event(event) elsif event.is_deletion? add_deletion_event(event) diff --git a/app/models/document.rb b/app/models/document.rb index 91e9b934a5..46c71c2599 100644 --- a/app/models/document.rb +++ b/app/models/document.rb @@ -48,7 +48,7 @@ class Document < ActiveRecord::Base validates :title, presence: true validates :date, presence: true validates_uniqueness_of :primary_language_document_id, scope: :language_id, allow_nil: true - # TODO validates inclusion of type in available types + # TODO: validates inclusion of type in available types accepts_nested_attributes_for :citations, :allow_destroy => true, :reject_if => proc { |attributes| attributes['stringy_taxon_concept_ids'].blank? && ( diff --git a/app/models/trade/distinct_values_validation_rule.rb b/app/models/trade/distinct_values_validation_rule.rb index ae5b5d497d..65806d0881 100644 --- a/app/models/trade/distinct_values_validation_rule.rb +++ b/app/models/trade/distinct_values_validation_rule.rb @@ -17,7 +17,7 @@ class Trade::DistinctValuesValidationRule < Trade::InclusionValidationRule - # TODO should have a validation for at least 2 column names + # TODO: should have a validation for at least 2 column names def validation_errors_for_shipment(shipment) return nil unless shipment_in_scope?(shipment) diff --git a/app/models/trade/sandbox.rb b/app/models/trade/sandbox.rb index bf7ffc2507..da76cc9ad8 100644 --- a/app/models/trade/sandbox.rb +++ b/app/models/trade/sandbox.rb @@ -44,7 +44,7 @@ def shipments end def shipments=(new_shipments) - #TODO handle errors + #TODO: handle errors new_shipments.each do |shipment| s = @ar_klass.find_by_id(shipment.delete('id')) s.delete_or_update_attributes(shipment) diff --git a/app/serializers/checklist/checklist_serializer.rb b/app/serializers/checklist/checklist_serializer.rb index e9a8c41158..59c9e00414 100644 --- a/app/serializers/checklist/checklist_serializer.rb +++ b/app/serializers/checklist/checklist_serializer.rb @@ -1,6 +1,6 @@ class Checklist::ChecklistSerializer < ActiveModel::Serializer cached - attributes :result_cnt, :total_cnt #TODO move this to a meta object for consistency with Species+ + attributes :result_cnt, :total_cnt #TODO: move this to a meta object for consistency with Species+ has_many :animalia, :serializer => Checklist::TaxonConceptSerializer has_many :plantae, :serializer => Checklist::TaxonConceptSerializer diff --git a/lib/tasks/helpers_for_import.rb b/lib/tasks/helpers_for_import.rb index 20f12411e1..8b61c20d2a 100644 --- a/lib/tasks/helpers_for_import.rb +++ b/lib/tasks/helpers_for_import.rb @@ -71,7 +71,7 @@ class CsvToDbMap 'name_es' => 'name_es varchar', 'name_fr' => 'name_fr varchar' }, - #TODO legacy type for countries? + #TODO: legacy type for countries? 'countries_import' => { 'ISO2' => 'iso2 varchar', 'short_name' => 'name varchar', diff --git a/lib/tasks/import_distributions.rake b/lib/tasks/import_distributions.rake index 215a03cf59..ac6639342c 100644 --- a/lib/tasks/import_distributions.rake +++ b/lib/tasks/import_distributions.rake @@ -41,7 +41,7 @@ namespace :import do ) AS subquery SQL - #TODO do sth about those unknown distributions! + #TODO: do sth about those unknown distributions! ActiveRecord::Base.connection.execute(sql) end end From 0d046dfd960f02a7eb283cff1f5885f2250d7b4c Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 3 Jun 2016 14:32:49 +0100 Subject: [PATCH 290/365] Consistent comment indentation --- .rubocop_todo.yml | 10 ---------- app/controllers/cites_trade/shipments_controller.rb | 4 ++-- app/models/search_params.rb | 8 ++++---- lib/tasks/import_cms_listings.rake | 6 +++--- 4 files changed, 9 insertions(+), 19 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index fced6bfd65..36c9408542 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -281,16 +281,6 @@ Style/ColonMethodCall: - 'lib/tasks/db_migrate_plpgsql.rake' - 'lib/tasks/import.rake' -# Offense count: 5 -# Cop supports --auto-correct. -Style/CommentIndentation: - Exclude: - - 'app/controllers/cites_trade/shipments_controller.rb' - - 'app/models/search_params.rb' - - 'config/initializers/geocoder.rb' - - 'db/schema.rb' - - 'lib/tasks/import_cms_listings.rake' - # Offense count: 6 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, SingleLineConditionsOnly. diff --git a/app/controllers/cites_trade/shipments_controller.rb b/app/controllers/cites_trade/shipments_controller.rb index dd501d2b8e..d02e4f4e62 100644 --- a/app/controllers/cites_trade/shipments_controller.rb +++ b/app/controllers/cites_trade/shipments_controller.rb @@ -7,8 +7,8 @@ def index })) render :json => @search, :serializer => serializer_for_search(@search) - # note: not returning search metadata here, since we're not paginating - # and calculating the total # of results for reports is expensive + # note: not returning search metadata here, since we're not paginating + # and calculating the total # of results for reports is expensive end private diff --git a/app/models/search_params.rb b/app/models/search_params.rb index 702cac3e7c..ffacb33eca 100644 --- a/app/models/search_params.rb +++ b/app/models/search_params.rb @@ -1,7 +1,7 @@ - # 'taxonomy' => {'id' => x} - # 'rank' => {'id' => x, 'scope' => [parent|ancestors]} - # 'taxon_concept' => {'id' => x, 'scope' => [ancestors]} - # 'scientific_name' +# 'taxonomy' => {'id' => x} +# 'rank' => {'id' => x, 'scope' => [parent|ancestors]} +# 'taxon_concept' => {'id' => x, 'scope' => [ancestors]} +# 'scientific_name' class SearchParams include ActiveModel::Conversion extend ActiveModel::Naming diff --git a/lib/tasks/import_cms_listings.rake b/lib/tasks/import_cms_listings.rake index 267907f602..cfe6b2de6d 100644 --- a/lib/tasks/import_cms_listings.rake +++ b/lib/tasks/import_cms_listings.rake @@ -229,9 +229,9 @@ namespace :import do end puts "DROPPING temporary column and view" -# ActiveRecord::Base.connection.execute("ALTER TABLE listing_changes DROP COLUMN import_row_id") -# ActiveRecord::Base.connection.execute("ALTER TABLE annotations DROP COLUMN import_row_id") -# ActiveRecord::Base.connection.execute("DROP VIEW cms_listings_import_view") + # ActiveRecord::Base.connection.execute("ALTER TABLE listing_changes DROP COLUMN import_row_id") + # ActiveRecord::Base.connection.execute("ALTER TABLE annotations DROP COLUMN import_row_id") + # ActiveRecord::Base.connection.execute("DROP VIEW cms_listings_import_view") new_listings_count = ListingChange.joins(:species_listing). where(:species_listings => {:designation_id => designation.id}).count From 1a5f091326ac7a24e6d6c38c197cc1f681a3b5a6 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 3 Jun 2016 14:35:43 +0100 Subject: [PATCH 291/365] Keep a blank line before and after private / protected --- .rubocop_todo.yml | 5 ----- app/controllers/admin/change_types_controller.rb | 1 + app/controllers/admin/cites_acs_controller.rb | 1 + app/controllers/admin/cites_cops_controller.rb | 1 + .../admin/cites_extraordinary_meetings_controller.rb | 1 + app/controllers/admin/cites_pcs_controller.rb | 1 + .../admin/cites_suspension_notifications_controller.rb | 1 + app/controllers/admin/cites_tcs_controller.rb | 1 + app/controllers/admin/designations_controller.rb | 1 + app/controllers/admin/distributions_controller.rb | 1 + app/controllers/admin/ec_srgs_controller.rb | 1 + app/controllers/admin/eu_council_regulations_controller.rb | 1 + app/controllers/admin/eu_decision_types_controller.rb | 1 + .../admin/eu_implementing_regulations_controller.rb | 1 + app/controllers/admin/eu_regulations_controller.rb | 1 + .../admin/eu_suspension_regulations_controller.rb | 1 + app/controllers/admin/eu_suspensions_controller.rb | 1 + app/controllers/admin/events_controller.rb | 1 + app/controllers/admin/hash_annotations_controller.rb | 1 + app/controllers/admin/instruments_controller.rb | 1 + app/controllers/admin/languages_controller.rb | 1 + app/controllers/admin/listing_changes_controller.rb | 1 + .../admin/nomenclature_changes/build_controller.rb | 1 + .../admin/nomenclature_changes/lump_controller.rb | 1 + .../admin/nomenclature_changes/split_controller.rb | 1 + .../admin/nomenclature_changes/status_swap_controller.rb | 1 + .../nomenclature_changes/status_to_accepted_controller.rb | 1 + .../nomenclature_changes/status_to_synonym_controller.rb | 1 + app/controllers/admin/references_controller.rb | 1 + app/controllers/admin/species_listings_controller.rb | 1 + app/controllers/admin/tags_controller.rb | 1 + app/controllers/admin/taxon_listing_changes_controller.rb | 1 + app/controllers/admin/taxonomies_controller.rb | 1 + app/controllers/admin/users_controller.rb | 1 + app/controllers/api/v1/document_geo_entities_controller.rb | 1 + app/controllers/checklist/taxon_concepts_controller.rb | 1 + app/controllers/checklist/timelines_controller.rb | 1 + app/models/checklist/pdf/index_annotations_key.rb | 1 + app/models/event.rb | 1 + app/models/nomenclature_change/status_change_processor.rb | 1 + app/models/nomenclature_change/status_swap/constructor.rb | 1 + .../nomenclature_change/taxonomic_tree_name_resolver.rb | 1 + app/models/purpose.rb | 1 + app/models/source.rb | 1 + app/models/taxon_concept_prefix_matcher.rb | 1 + app/models/taxon_concept_view_stats.rb | 1 + app/models/term.rb | 1 + app/models/trade/annual_report_upload.rb | 1 + app/models/trade/distinct_values_validation_rule.rb | 1 + app/models/trade/format_validation_rule.rb | 1 + app/models/trade/numericality_validation_rule.rb | 1 + app/models/trade/sandbox_template.rb | 1 + app/models/unit.rb | 1 + app/models/user.rb | 1 + 54 files changed, 53 insertions(+), 5 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 36c9408542..e99604f0a5 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -317,11 +317,6 @@ Style/EmptyElse: - 'app/models/rank.rb' - 'app/models/trade/shipment.rb' -# Offense count: 54 -# Cop supports --auto-correct. -Style/EmptyLinesAroundAccessModifier: - Enabled: false - # Offense count: 253 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. diff --git a/app/controllers/admin/change_types_controller.rb b/app/controllers/admin/change_types_controller.rb index 22420416a3..b48233155a 100644 --- a/app/controllers/admin/change_types_controller.rb +++ b/app/controllers/admin/change_types_controller.rb @@ -1,6 +1,7 @@ class Admin::ChangeTypesController < Admin::StandardAuthorizationController protected + def collection @change_types ||= end_of_association_chain.includes(:designation). order('designation_id, name'). diff --git a/app/controllers/admin/cites_acs_controller.rb b/app/controllers/admin/cites_acs_controller.rb index 2d735e8dd4..e41df48599 100644 --- a/app/controllers/admin/cites_acs_controller.rb +++ b/app/controllers/admin/cites_acs_controller.rb @@ -5,6 +5,7 @@ class Admin::CitesAcsController < Admin::EventsController :instance_name => 'cites_ac' protected + def collection @cites_acs ||= end_of_association_chain. order(:designation_id, :name).includes(:designation). diff --git a/app/controllers/admin/cites_cops_controller.rb b/app/controllers/admin/cites_cops_controller.rb index 1e4a0d1217..830b3a9316 100644 --- a/app/controllers/admin/cites_cops_controller.rb +++ b/app/controllers/admin/cites_cops_controller.rb @@ -4,6 +4,7 @@ class Admin::CitesCopsController < Admin::EventsController :collection_name => 'cites_cops', :instance_name => 'cites_cop' protected + def collection @cites_cops ||= end_of_association_chain. order(:designation_id, :name).includes(:designation). diff --git a/app/controllers/admin/cites_extraordinary_meetings_controller.rb b/app/controllers/admin/cites_extraordinary_meetings_controller.rb index b0f1372039..f9ae43014c 100644 --- a/app/controllers/admin/cites_extraordinary_meetings_controller.rb +++ b/app/controllers/admin/cites_extraordinary_meetings_controller.rb @@ -5,6 +5,7 @@ class Admin::CitesExtraordinaryMeetingsController < Admin::EventsController :instance_name => 'cites_extraordinary_meeting' protected + def collection @cites_extraordinary_meetings ||= end_of_association_chain. order(:designation_id, :name).includes(:designation). diff --git a/app/controllers/admin/cites_pcs_controller.rb b/app/controllers/admin/cites_pcs_controller.rb index 5de6aa61f1..7f9d4e144b 100644 --- a/app/controllers/admin/cites_pcs_controller.rb +++ b/app/controllers/admin/cites_pcs_controller.rb @@ -5,6 +5,7 @@ class Admin::CitesPcsController < Admin::EventsController :instance_name => 'cites_pc' protected + def collection @cites_pcs ||= end_of_association_chain. order(:designation_id, :name).includes(:designation). diff --git a/app/controllers/admin/cites_suspension_notifications_controller.rb b/app/controllers/admin/cites_suspension_notifications_controller.rb index 43f51236f5..0e9a65cdea 100644 --- a/app/controllers/admin/cites_suspension_notifications_controller.rb +++ b/app/controllers/admin/cites_suspension_notifications_controller.rb @@ -4,6 +4,7 @@ class Admin::CitesSuspensionNotificationsController < Admin::EventsController :collection_name => 'cites_suspension_notifications', :instance_name => 'cites_suspension_notification' protected + def collection @cites_suspension_notifications ||= end_of_association_chain. order('designation_id ASC, events.effective_at DESC, name ASC'). diff --git a/app/controllers/admin/cites_tcs_controller.rb b/app/controllers/admin/cites_tcs_controller.rb index 3b1dffeb06..acb4655cba 100644 --- a/app/controllers/admin/cites_tcs_controller.rb +++ b/app/controllers/admin/cites_tcs_controller.rb @@ -5,6 +5,7 @@ class Admin::CitesTcsController < Admin::EventsController :instance_name => 'cites_tc' protected + def collection @cites_tcs ||= end_of_association_chain. order(:designation_id, :name).includes(:designation). diff --git a/app/controllers/admin/designations_controller.rb b/app/controllers/admin/designations_controller.rb index 9ce6baf020..327d13dd87 100644 --- a/app/controllers/admin/designations_controller.rb +++ b/app/controllers/admin/designations_controller.rb @@ -13,6 +13,7 @@ def index end protected + def collection @designations ||= end_of_association_chain.order(:name). page(params[:page]). diff --git a/app/controllers/admin/distributions_controller.rb b/app/controllers/admin/distributions_controller.rb index 7f1c2ae850..aaf46da5cb 100644 --- a/app/controllers/admin/distributions_controller.rb +++ b/app/controllers/admin/distributions_controller.rb @@ -60,6 +60,7 @@ def destroy end protected + def load_tags_and_geo_entities @geo_entities = GeoEntity.order(:name_en).joins(:geo_entity_type). where(:is_current => true, diff --git a/app/controllers/admin/ec_srgs_controller.rb b/app/controllers/admin/ec_srgs_controller.rb index ec0d93fa8a..adda0b4356 100644 --- a/app/controllers/admin/ec_srgs_controller.rb +++ b/app/controllers/admin/ec_srgs_controller.rb @@ -5,6 +5,7 @@ class Admin::EcSrgsController < Admin::EventsController :instance_name => 'ec_srg' protected + def collection @ec_srgs ||= end_of_association_chain. order('designation_id, effective_at DESC').includes(:designation). diff --git a/app/controllers/admin/eu_council_regulations_controller.rb b/app/controllers/admin/eu_council_regulations_controller.rb index 6809be364b..2454da326f 100644 --- a/app/controllers/admin/eu_council_regulations_controller.rb +++ b/app/controllers/admin/eu_council_regulations_controller.rb @@ -4,6 +4,7 @@ class Admin::EuCouncilRegulationsController < Admin::EventsController :collection_name => 'eu_council_regulations', :instance_name => 'eu_council_regulation' protected + def collection @eu_council_regulations ||= end_of_association_chain. order('effective_at DESC, name ASC'). diff --git a/app/controllers/admin/eu_decision_types_controller.rb b/app/controllers/admin/eu_decision_types_controller.rb index 6d4e49b091..bfc9b69298 100644 --- a/app/controllers/admin/eu_decision_types_controller.rb +++ b/app/controllers/admin/eu_decision_types_controller.rb @@ -13,6 +13,7 @@ def create failure.js { render 'new' } end end + protected def collection diff --git a/app/controllers/admin/eu_implementing_regulations_controller.rb b/app/controllers/admin/eu_implementing_regulations_controller.rb index 0f274f7078..1dbbd30179 100644 --- a/app/controllers/admin/eu_implementing_regulations_controller.rb +++ b/app/controllers/admin/eu_implementing_regulations_controller.rb @@ -4,6 +4,7 @@ class Admin::EuImplementingRegulationsController < Admin::EventsController :collection_name => 'eu_implementing_regulations', :instance_name => 'eu_implementing_regulation' protected + def collection @eu_implementing_regulations ||= end_of_association_chain. order('effective_at DESC, name ASC'). diff --git a/app/controllers/admin/eu_regulations_controller.rb b/app/controllers/admin/eu_regulations_controller.rb index 677de883c9..8a38ca275e 100644 --- a/app/controllers/admin/eu_regulations_controller.rb +++ b/app/controllers/admin/eu_regulations_controller.rb @@ -16,6 +16,7 @@ def deactivate end protected + def collection @eu_regulations ||= end_of_association_chain. order('effective_at DESC, name ASC'). diff --git a/app/controllers/admin/eu_suspension_regulations_controller.rb b/app/controllers/admin/eu_suspension_regulations_controller.rb index ce4f0e7b72..b3e599ccbd 100644 --- a/app/controllers/admin/eu_suspension_regulations_controller.rb +++ b/app/controllers/admin/eu_suspension_regulations_controller.rb @@ -16,6 +16,7 @@ def deactivate end protected + def collection @eu_suspension_regulations ||= end_of_association_chain. includes([:creator, :updater]). diff --git a/app/controllers/admin/eu_suspensions_controller.rb b/app/controllers/admin/eu_suspensions_controller.rb index 88fe3d175a..63c8e19eef 100644 --- a/app/controllers/admin/eu_suspensions_controller.rb +++ b/app/controllers/admin/eu_suspensions_controller.rb @@ -2,6 +2,7 @@ class Admin::EuSuspensionsController < Admin::StandardAuthorizationController belongs_to :eu_suspension_regulation protected + def collection @eu_suspensions ||= end_of_association_chain. includes([ diff --git a/app/controllers/admin/events_controller.rb b/app/controllers/admin/events_controller.rb index 6ce061e970..f1367304a0 100644 --- a/app/controllers/admin/events_controller.rb +++ b/app/controllers/admin/events_controller.rb @@ -32,6 +32,7 @@ def show end protected + def collection @events ||= end_of_association_chain.order(:designation_id, :name). includes(:designation). diff --git a/app/controllers/admin/hash_annotations_controller.rb b/app/controllers/admin/hash_annotations_controller.rb index 248dd31fea..c00357d779 100644 --- a/app/controllers/admin/hash_annotations_controller.rb +++ b/app/controllers/admin/hash_annotations_controller.rb @@ -4,6 +4,7 @@ class Admin::HashAnnotationsController < Admin::SimpleCrudController :instance_name => 'annotation' protected + def collection @annotations = load_collection.page(params[:page]). search(params[:query]) diff --git a/app/controllers/admin/instruments_controller.rb b/app/controllers/admin/instruments_controller.rb index b99adf0832..a69b0a9188 100644 --- a/app/controllers/admin/instruments_controller.rb +++ b/app/controllers/admin/instruments_controller.rb @@ -12,6 +12,7 @@ def index end protected + def collection @instruments ||= end_of_association_chain.order(:name). page(params[:page]). diff --git a/app/controllers/admin/languages_controller.rb b/app/controllers/admin/languages_controller.rb index f07c28a80b..e109c77dc4 100644 --- a/app/controllers/admin/languages_controller.rb +++ b/app/controllers/admin/languages_controller.rb @@ -1,6 +1,7 @@ class Admin::LanguagesController < Admin::StandardAuthorizationController protected + def collection @languages ||= end_of_association_chain.order(:iso_code3). page(params[:page]). diff --git a/app/controllers/admin/listing_changes_controller.rb b/app/controllers/admin/listing_changes_controller.rb index 259df96305..fcb5cbf2fa 100644 --- a/app/controllers/admin/listing_changes_controller.rb +++ b/app/controllers/admin/listing_changes_controller.rb @@ -2,6 +2,7 @@ class Admin::ListingChangesController < Admin::StandardAuthorizationController belongs_to :eu_regulation protected + def collection @listing_changes ||= end_of_association_chain. includes([ diff --git a/app/controllers/admin/nomenclature_changes/build_controller.rb b/app/controllers/admin/nomenclature_changes/build_controller.rb index 35b620604a..91cf9ce4ec 100644 --- a/app/controllers/admin/nomenclature_changes/build_controller.rb +++ b/app/controllers/admin/nomenclature_changes/build_controller.rb @@ -46,6 +46,7 @@ def skip_or_previous_step end private + def klass NomenclatureChange end diff --git a/app/controllers/admin/nomenclature_changes/lump_controller.rb b/app/controllers/admin/nomenclature_changes/lump_controller.rb index e11e34992b..1d44ba6203 100644 --- a/app/controllers/admin/nomenclature_changes/lump_controller.rb +++ b/app/controllers/admin/nomenclature_changes/lump_controller.rb @@ -52,6 +52,7 @@ def update end private + def klass NomenclatureChange::Lump end diff --git a/app/controllers/admin/nomenclature_changes/split_controller.rb b/app/controllers/admin/nomenclature_changes/split_controller.rb index 44b047b037..d01eb558e3 100644 --- a/app/controllers/admin/nomenclature_changes/split_controller.rb +++ b/app/controllers/admin/nomenclature_changes/split_controller.rb @@ -53,6 +53,7 @@ def update end private + def klass NomenclatureChange::Split end diff --git a/app/controllers/admin/nomenclature_changes/status_swap_controller.rb b/app/controllers/admin/nomenclature_changes/status_swap_controller.rb index 2ae3306ae3..75aa7531cb 100644 --- a/app/controllers/admin/nomenclature_changes/status_swap_controller.rb +++ b/app/controllers/admin/nomenclature_changes/status_swap_controller.rb @@ -48,6 +48,7 @@ def update end private + def klass NomenclatureChange::StatusSwap end diff --git a/app/controllers/admin/nomenclature_changes/status_to_accepted_controller.rb b/app/controllers/admin/nomenclature_changes/status_to_accepted_controller.rb index 1a7ff6d87a..f60d63886e 100644 --- a/app/controllers/admin/nomenclature_changes/status_to_accepted_controller.rb +++ b/app/controllers/admin/nomenclature_changes/status_to_accepted_controller.rb @@ -36,6 +36,7 @@ def update end private + def klass NomenclatureChange::StatusToAccepted end diff --git a/app/controllers/admin/nomenclature_changes/status_to_synonym_controller.rb b/app/controllers/admin/nomenclature_changes/status_to_synonym_controller.rb index 6b7b457058..df3ef63fde 100644 --- a/app/controllers/admin/nomenclature_changes/status_to_synonym_controller.rb +++ b/app/controllers/admin/nomenclature_changes/status_to_synonym_controller.rb @@ -47,6 +47,7 @@ def update end private + def klass NomenclatureChange::StatusToSynonym end diff --git a/app/controllers/admin/references_controller.rb b/app/controllers/admin/references_controller.rb index c063023864..69a6c2b7b2 100644 --- a/app/controllers/admin/references_controller.rb +++ b/app/controllers/admin/references_controller.rb @@ -24,6 +24,7 @@ def autocomplete end protected + def collection @references ||= end_of_association_chain.order(:citation). page(params[:page]). diff --git a/app/controllers/admin/species_listings_controller.rb b/app/controllers/admin/species_listings_controller.rb index e5435ce303..158c28e07a 100644 --- a/app/controllers/admin/species_listings_controller.rb +++ b/app/controllers/admin/species_listings_controller.rb @@ -1,6 +1,7 @@ class Admin::SpeciesListingsController < Admin::StandardAuthorizationController protected + def collection @species_listings ||= end_of_association_chain.includes(:designation). order('designation_id, species_listings.name'). diff --git a/app/controllers/admin/tags_controller.rb b/app/controllers/admin/tags_controller.rb index b6a440a4a3..0ba405df34 100644 --- a/app/controllers/admin/tags_controller.rb +++ b/app/controllers/admin/tags_controller.rb @@ -2,6 +2,7 @@ class Admin::TagsController < Admin::SimpleCrudController defaults :resource_class => PresetTag, :collection_name => 'tags', :instance_name => 'tag' authorize_resource :class => false + protected def collection diff --git a/app/controllers/admin/taxon_listing_changes_controller.rb b/app/controllers/admin/taxon_listing_changes_controller.rb index e43bb0cc60..645861b537 100644 --- a/app/controllers/admin/taxon_listing_changes_controller.rb +++ b/app/controllers/admin/taxon_listing_changes_controller.rb @@ -72,6 +72,7 @@ def destroy end protected + def build_dependants unless @listing_change.party_listing_distribution @listing_change.build_party_listing_distribution( diff --git a/app/controllers/admin/taxonomies_controller.rb b/app/controllers/admin/taxonomies_controller.rb index 3e83fb5a26..74cfc4bf34 100644 --- a/app/controllers/admin/taxonomies_controller.rb +++ b/app/controllers/admin/taxonomies_controller.rb @@ -11,6 +11,7 @@ def index end protected + def collection @taxonomies ||= end_of_association_chain.order(:name). page(params[:page]). diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb index 731480a608..899ac1cee2 100644 --- a/app/controllers/admin/users_controller.rb +++ b/app/controllers/admin/users_controller.rb @@ -36,6 +36,7 @@ def update end protected + def collection @users ||= end_of_association_chain. order(:name).page(params[:page]) diff --git a/app/controllers/api/v1/document_geo_entities_controller.rb b/app/controllers/api/v1/document_geo_entities_controller.rb index 7ba2be799f..ae693a7f36 100644 --- a/app/controllers/api/v1/document_geo_entities_controller.rb +++ b/app/controllers/api/v1/document_geo_entities_controller.rb @@ -28,6 +28,7 @@ def index end private + def set_locale locale = params[:locale].try(:downcase).try(:strip) || 'en' diff --git a/app/controllers/checklist/taxon_concepts_controller.rb b/app/controllers/checklist/taxon_concepts_controller.rb index 37cf7652a1..a750ce9e75 100644 --- a/app/controllers/checklist/taxon_concepts_controller.rb +++ b/app/controllers/checklist/taxon_concepts_controller.rb @@ -27,6 +27,7 @@ def summarise_filters end private + # this disables json root for this controller # remove when checklist frontend upgraded to new Ember.js def default_serializer_options diff --git a/app/controllers/checklist/timelines_controller.rb b/app/controllers/checklist/timelines_controller.rb index a09306ce9e..f7464cef8f 100644 --- a/app/controllers/checklist/timelines_controller.rb +++ b/app/controllers/checklist/timelines_controller.rb @@ -11,6 +11,7 @@ def index end private + # this disables json root for this controller # remove when checklist frontent upgraded to new Ember.js def default_serializer_options diff --git a/app/models/checklist/pdf/index_annotations_key.rb b/app/models/checklist/pdf/index_annotations_key.rb index 605e341fff..4a93c0e3d4 100644 --- a/app/models/checklist/pdf/index_annotations_key.rb +++ b/app/models/checklist/pdf/index_annotations_key.rb @@ -42,6 +42,7 @@ def hash_annotations_key end private + def non_hash_annotations MCitesListingChange. joins(:taxon_concept). diff --git a/app/models/event.rb b/app/models/event.rb index 908c024a69..45d864e183 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -109,6 +109,7 @@ def deactivate! end protected + def designation_is_cites cites = Designation.find_by_name('CITES') unless designation_id && cites && designation_id == cites.id diff --git a/app/models/nomenclature_change/status_change_processor.rb b/app/models/nomenclature_change/status_change_processor.rb index 652af666ac..c8e4d76b07 100644 --- a/app/models/nomenclature_change/status_change_processor.rb +++ b/app/models/nomenclature_change/status_change_processor.rb @@ -36,6 +36,7 @@ def summary end private + def create_relationships(taxon_concept, rel_type) @linked_names.each do |linked_name| Rails.logger.debug "Creating #{rel_type.name} relationship with #{linked_name.full_name}" diff --git a/app/models/nomenclature_change/status_swap/constructor.rb b/app/models/nomenclature_change/status_swap/constructor.rb index 8a54e8b4a5..cea634ae0f 100644 --- a/app/models/nomenclature_change/status_swap/constructor.rb +++ b/app/models/nomenclature_change/status_swap/constructor.rb @@ -19,6 +19,7 @@ def build_secondary_output_note end private + def legislation_note(lng) input = @nomenclature_change.input output = @nomenclature_change.secondary_output diff --git a/app/models/nomenclature_change/taxonomic_tree_name_resolver.rb b/app/models/nomenclature_change/taxonomic_tree_name_resolver.rb index c8aacd5f26..aae947a747 100644 --- a/app/models/nomenclature_change/taxonomic_tree_name_resolver.rb +++ b/app/models/nomenclature_change/taxonomic_tree_name_resolver.rb @@ -11,6 +11,7 @@ def process end private + def resolve(node) @expected_full_name = node.expected_full_name(node.parent) return node if name_compatible_with_parent?(node) diff --git a/app/models/purpose.rb b/app/models/purpose.rb index f8d3e83966..04cdeeeeee 100644 --- a/app/models/purpose.rb +++ b/app/models/purpose.rb @@ -19,6 +19,7 @@ class Purpose < TradeCode has_many :shipments, :class_name => 'Trade::Shipment' protected + def dependent_objects_map { 'trade restrictions' => trade_restriction_purposes, diff --git a/app/models/source.rb b/app/models/source.rb index bf6533e096..885e78f8e3 100644 --- a/app/models/source.rb +++ b/app/models/source.rb @@ -20,6 +20,7 @@ class Source < TradeCode has_many :shipments, :class_name => 'Trade::Shipment' protected + def dependent_objects_map { 'EU decisions' => eu_decisions, diff --git a/app/models/taxon_concept_prefix_matcher.rb b/app/models/taxon_concept_prefix_matcher.rb index 03068eb6fe..f9b0621972 100644 --- a/app/models/taxon_concept_prefix_matcher.rb +++ b/app/models/taxon_concept_prefix_matcher.rb @@ -7,6 +7,7 @@ def initialize(search_params) end protected + def build_rel super apply_rank_options_to_rel diff --git a/app/models/taxon_concept_view_stats.rb b/app/models/taxon_concept_view_stats.rb index 99dbaaaaf9..ecc46ffffc 100644 --- a/app/models/taxon_concept_view_stats.rb +++ b/app/models/taxon_concept_view_stats.rb @@ -11,6 +11,7 @@ def results end private + def query Ahoy::Event.select(<<-SQL properties->>'id' AS tc_id, diff --git a/app/models/term.rb b/app/models/term.rb index f4f9d55fdc..2eed4f2799 100644 --- a/app/models/term.rb +++ b/app/models/term.rb @@ -20,6 +20,7 @@ class Term < TradeCode has_many :shipments, :class_name => 'Trade::Shipment' protected + def dependent_objects_map { 'EU decisions' => eu_decisions, diff --git a/app/models/trade/annual_report_upload.rb b/app/models/trade/annual_report_upload.rb index 0205da7c33..079d8b141a 100644 --- a/app/models/trade/annual_report_upload.rb +++ b/app/models/trade/annual_report_upload.rb @@ -92,6 +92,7 @@ def submit end private + # Expects a relation object def run_validations(validation_rules) validation_errors = [] diff --git a/app/models/trade/distinct_values_validation_rule.rb b/app/models/trade/distinct_values_validation_rule.rb index 65806d0881..99a922e4d8 100644 --- a/app/models/trade/distinct_values_validation_rule.rb +++ b/app/models/trade/distinct_values_validation_rule.rb @@ -33,6 +33,7 @@ def validation_errors_for_shipment(shipment) end private + # Returns records that have the same value for both columns # specified in column_names. If more then 2 columns are specified, # only the first two are taken into consideration. diff --git a/app/models/trade/format_validation_rule.rb b/app/models/trade/format_validation_rule.rb index 34f7bee2df..3bb0038bb9 100644 --- a/app/models/trade/format_validation_rule.rb +++ b/app/models/trade/format_validation_rule.rb @@ -23,6 +23,7 @@ def error_message end private + # Returns records that do not pass the regex test for all columns # specified in column_names. def matching_records(table_name) diff --git a/app/models/trade/numericality_validation_rule.rb b/app/models/trade/numericality_validation_rule.rb index 213876be8d..5d234b0a0e 100644 --- a/app/models/trade/numericality_validation_rule.rb +++ b/app/models/trade/numericality_validation_rule.rb @@ -22,6 +22,7 @@ def error_message end private + # Returns records that do not pass the ISNUMERIC test for all columns # specified in column_names. def matching_records(table_name) diff --git a/app/models/trade/sandbox_template.rb b/app/models/trade/sandbox_template.rb index 6df3a4da5c..252ddab312 100644 --- a/app/models/trade/sandbox_template.rb +++ b/app/models/trade/sandbox_template.rb @@ -112,6 +112,7 @@ def self.destroy_batch(sandbox_shipments_ids) end private + def self.create_table_stmt(target_table_name) sql = <<-SQL CREATE TABLE #{target_table_name} (PRIMARY KEY(id)) diff --git a/app/models/unit.rb b/app/models/unit.rb index 361c6cf17b..bb4e418e1f 100644 --- a/app/models/unit.rb +++ b/app/models/unit.rb @@ -20,6 +20,7 @@ class Unit < TradeCode has_many :shipments, :class_name => 'Trade::Shipment' protected + def dependent_objects_map { 'quotas' => quotas, diff --git a/app/models/user.rb b/app/models/user.rb index aed80e2465..50eb53426f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -97,6 +97,7 @@ def can_be_deleted? end private + def set_default_role self.role ||= 'api' end From f60a55660ad5065c3792d1ea969239b8f21edaf2 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 3 Jun 2016 14:40:01 +0100 Subject: [PATCH 292/365] No extra empty lines around method body --- .rubocop_todo.yml | 15 --------------- app/models/listing_change_observer.rb | 1 - ...concept_filter_by_appendix_population_query.rb | 1 - .../status_change/processor_helpers.rb | 1 - app/models/species/cites_listings_export.rb | 1 - app/models/trade/filter.rb | 2 -- ...606102741_create_nomenclature_change_inputs.rb | 1 - .../20140811101246_add_timestamps_to_documents.rb | 1 - ...0918090432_create_document_proposal_details.rb | 1 - ..._change_multi_permit_number_columns_to_text.rb | 1 - ...te_unique_index_on_taxon_concept_references.rb | 1 - 11 files changed, 26 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index e99604f0a5..c7e9eee3ec 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -331,21 +331,6 @@ Style/EmptyLinesAroundBlockBody: Style/EmptyLinesAroundClassBody: Enabled: false -# Offense count: 11 -# Cop supports --auto-correct. -Style/EmptyLinesAroundMethodBody: - Exclude: - - 'app/models/listing_change_observer.rb' - - 'app/models/m_taxon_concept_filter_by_appendix_population_query.rb' - - 'app/models/nomenclature_change/status_change/processor_helpers.rb' - - 'app/models/species/cites_listings_export.rb' - - 'app/models/trade/filter.rb' - - 'db/migrate/20140606102741_create_nomenclature_change_inputs.rb' - - 'db/migrate/20140811101246_add_timestamps_to_documents.rb' - - 'db/migrate/20140918090432_create_document_proposal_details.rb' - - 'db/migrate/20141014125738_change_multi_permit_number_columns_to_text.rb' - - 'db/migrate/20150421112808_create_unique_index_on_taxon_concept_references.rb' - # Offense count: 71 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. diff --git a/app/models/listing_change_observer.rb b/app/models/listing_change_observer.rb index 24a2ce89f1..24a0ae4fe0 100644 --- a/app/models/listing_change_observer.rb +++ b/app/models/listing_change_observer.rb @@ -1,7 +1,6 @@ class ListingChangeObserver < ActiveRecord::Observer def before_save(listing_change) - #check if annotation should be deleted if listing_change.annotation && listing_change.annotation.short_note_en.blank? && diff --git a/app/models/m_taxon_concept_filter_by_appendix_population_query.rb b/app/models/m_taxon_concept_filter_by_appendix_population_query.rb index 20b787c6c6..a25c242872 100644 --- a/app/models/m_taxon_concept_filter_by_appendix_population_query.rb +++ b/app/models/m_taxon_concept_filter_by_appendix_population_query.rb @@ -37,7 +37,6 @@ def relation(designation_name = 'CITES') ).where( "countries_ids_ary && ARRAY[#{@geo_entities_in_clause}]" ) - end end diff --git a/app/models/nomenclature_change/status_change/processor_helpers.rb b/app/models/nomenclature_change/status_change/processor_helpers.rb index 3eb99d4dab..64da92cd92 100644 --- a/app/models/nomenclature_change/status_change/processor_helpers.rb +++ b/app/models/nomenclature_change/status_change/processor_helpers.rb @@ -14,7 +14,6 @@ def reassignment_processor(output) else NomenclatureChange::ReassignmentCopyProcessor.new(@input, output) end - end # Generate a summary based on the subprocessors chain diff --git a/app/models/species/cites_listings_export.rb b/app/models/species/cites_listings_export.rb index 02335ef6f4..0e651df01d 100644 --- a/app/models/species/cites_listings_export.rb +++ b/app/models/species/cites_listings_export.rb @@ -33,7 +33,6 @@ def csv_column_headers 'Extinct_Distribution', 'Extinct(?)_Distribution', 'Distribution_Uncertain' ] - end end diff --git a/app/models/trade/filter.rb b/app/models/trade/filter.rb index 715ae3a48a..b19cf7ea61 100644 --- a/app/models/trade/filter.rb +++ b/app/models/trade/filter.rb @@ -138,7 +138,6 @@ def initialize_query end initialize_internal_query if @internal - end def initialize_internal_query @@ -178,7 +177,6 @@ def initialize_internal_query @query = @query.where(:quantity => @quantity) end end - end end diff --git a/db/migrate/20140606102741_create_nomenclature_change_inputs.rb b/db/migrate/20140606102741_create_nomenclature_change_inputs.rb index 4bc638fca5..9c5d042d6f 100644 --- a/db/migrate/20140606102741_create_nomenclature_change_inputs.rb +++ b/db/migrate/20140606102741_create_nomenclature_change_inputs.rb @@ -21,6 +21,5 @@ def change add_foreign_key 'nomenclature_change_inputs', 'taxon_concepts', name: 'nomenclature_change_inputs_taxon_concept_id_fk', column: 'taxon_concept_id' - end end diff --git a/db/migrate/20140811101246_add_timestamps_to_documents.rb b/db/migrate/20140811101246_add_timestamps_to_documents.rb index 4d01863f4c..9b5ca82ab6 100644 --- a/db/migrate/20140811101246_add_timestamps_to_documents.rb +++ b/db/migrate/20140811101246_add_timestamps_to_documents.rb @@ -1,6 +1,5 @@ class AddTimestampsToDocuments < ActiveRecord::Migration def change - add_column :documents, :created_at, :datetime add_column :documents, :updated_at, :datetime execute 'UPDATE documents SET created_at = NOW() WHERE created_at IS NULL' diff --git a/db/migrate/20140918090432_create_document_proposal_details.rb b/db/migrate/20140918090432_create_document_proposal_details.rb index 28853cbec9..87a7ca8c75 100644 --- a/db/migrate/20140918090432_create_document_proposal_details.rb +++ b/db/migrate/20140918090432_create_document_proposal_details.rb @@ -13,6 +13,5 @@ def change column: :document_id add_foreign_key :proposal_details, :document_tags, name: :proposal_details_proposal_outcome_id_fk, column: :proposal_outcome_id - end end diff --git a/db/migrate/20141014125738_change_multi_permit_number_columns_to_text.rb b/db/migrate/20141014125738_change_multi_permit_number_columns_to_text.rb index 559103ad8b..cfba6c0ad0 100644 --- a/db/migrate/20141014125738_change_multi_permit_number_columns_to_text.rb +++ b/db/migrate/20141014125738_change_multi_permit_number_columns_to_text.rb @@ -65,7 +65,6 @@ def up ALTER COLUMN origin_permit_number TYPE TEXT; SQL execute sql - end def down diff --git a/db/migrate/20150421112808_create_unique_index_on_taxon_concept_references.rb b/db/migrate/20150421112808_create_unique_index_on_taxon_concept_references.rb index 603c59682c..0bc2109913 100644 --- a/db/migrate/20150421112808_create_unique_index_on_taxon_concept_references.rb +++ b/db/migrate/20150421112808_create_unique_index_on_taxon_concept_references.rb @@ -27,7 +27,6 @@ def up add_index "taxon_concept_references", ["taxon_concept_id", "reference_id"], name: "index_taxon_concept_references_on_taxon_concept_id_and_ref_id", unique: true - end def down From e9985165c5e9e94abd146a784615b74353b31f5a Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 3 Jun 2016 14:46:34 +0100 Subject: [PATCH 293/365] Removed redundant spacing --- .rubocop.yml | 6 ++++++ .rubocop_todo.yml | 6 ------ Gemfile | 2 +- Guardfile | 2 +- .../admin/taxon_eu_suspensions_controller.rb | 2 +- .../admin/taxon_listing_changes_controller.rb | 2 +- app/models/checklist/pdf/document.rb | 2 +- app/models/species/eu_decisions_export.rb | 6 +++--- app/models/trade/annual_report_upload_observer.rb | 2 +- app/models/trade/shipment_observer.rb | 2 +- ..._name_appendix_year_validation_rule_serializer.rb | 2 +- app/serializers/trade/validation_rule_serializer.rb | 2 +- config.ru | 2 +- config/deploy.rb | 2 +- config/environments/test.rb | 2 +- lib/modules/latex_to_pdf.rb | 2 +- lib/modules/sapi/summary.rb | 12 ++++++------ script/rails | 4 ++-- spec/factories/common_names.rb | 2 +- spec/factories/distributions.rb | 2 +- spec/factories/trade.rb | 4 ++-- 21 files changed, 34 insertions(+), 34 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 0d0d349c58..a3e8735e0c 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -53,3 +53,9 @@ Style/AndOr: # SupportedStyles: leading, trailing Style/DotPosition: EnforcedStyle: trailing + +# Configuration parameters: AllowForAlignment, ForceEqualSignAlignment. +Style/ExtraSpacing: + AllowForAlignment: true + Exclude: + - 'db/migrate/*' diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index c7e9eee3ec..b725ca3df5 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -338,12 +338,6 @@ Style/EmptyLinesAroundClassBody: Style/EmptyLinesAroundModuleBody: Enabled: false -# Offense count: 97 -# Cop supports --auto-correct. -# Configuration parameters: AllowForAlignment, ForceEqualSignAlignment. -Style/ExtraSpacing: - Enabled: false - # Offense count: 193 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. diff --git a/Gemfile b/Gemfile index 9d8175ca28..454942f498 100644 --- a/Gemfile +++ b/Gemfile @@ -95,7 +95,7 @@ group :development do gem 'capistrano', '~> 3.4', require: false gem 'capistrano-rails', '~> 1.1', require: false gem 'capistrano-bundler', '~> 1.1', require: false - gem 'capistrano-rvm', '~> 0.1', require: false + gem 'capistrano-rvm', '~> 0.1', require: false gem 'capistrano-sidekiq' gem 'capistrano-maintenance', '~> 1.0', require: false gem 'capistrano-passenger', '~> 0.2.0', require: false diff --git a/Guardfile b/Guardfile index acdd661d3f..85996ad9a7 100644 --- a/Guardfile +++ b/Guardfile @@ -13,5 +13,5 @@ guard 'livereload' do watch(%r{public/.+\.(css|js|html)}) watch(%r{config/locales/.+\.yml}) # Rails Assets Pipeline - watch(%r{(app|vendor)/assets/\w+/(.+\.(css|js|html)).*}) { |m| "/assets/#{m[2]}" } + watch(%r{(app|vendor)/assets/\w+/(.+\.(css|js|html)).*}) { |m| "/assets/#{m[2]}" } end diff --git a/app/controllers/admin/taxon_eu_suspensions_controller.rb b/app/controllers/admin/taxon_eu_suspensions_controller.rb index 78738057f3..53e4806766 100644 --- a/app/controllers/admin/taxon_eu_suspensions_controller.rb +++ b/app/controllers/admin/taxon_eu_suspensions_controller.rb @@ -12,7 +12,7 @@ class Admin::TaxonEuSuspensionsController < Admin::SimpleCrudController def update update! do |success, failure| success.html { - if "1" == params[:redirect_to_eu_suspension_reg] + if "1" == params[:redirect_to_eu_suspension_reg] redirect_to admin_eu_suspension_regulation_eu_suspensions_url( @eu_suspension.start_event_id) else diff --git a/app/controllers/admin/taxon_listing_changes_controller.rb b/app/controllers/admin/taxon_listing_changes_controller.rb index 645861b537..629fe5b638 100644 --- a/app/controllers/admin/taxon_listing_changes_controller.rb +++ b/app/controllers/admin/taxon_listing_changes_controller.rb @@ -48,7 +48,7 @@ def edit def update update! do |success, failure| success.html { - if "1" == params[:redirect_to_eu_reg] + if "1" == params[:redirect_to_eu_reg] redirect_to admin_eu_regulation_listing_changes_path(@listing_change.event) else redirect_to admin_taxon_concept_designation_listing_changes_url(@taxon_concept, @designation) diff --git a/app/models/checklist/pdf/document.rb b/app/models/checklist/pdf/document.rb index 9899b3608a..0692c79853 100644 --- a/app/models/checklist/pdf/document.rb +++ b/app/models/checklist/pdf/document.rb @@ -41,7 +41,7 @@ def document end @template_tex = [tmp_dir_path, "/#{@input_name}.tex"].join - @tmp_tex = [tmp_dir_path, "/_#{@input_name}.tex"].join + @tmp_tex = [tmp_dir_path, "/_#{@input_name}.tex"].join # create the dynamic part File.open(@tmp_tex, "wb") do |tex| yield tex diff --git a/app/models/species/eu_decisions_export.rb b/app/models/species/eu_decisions_export.rb index 6897d04a86..1447be7da8 100644 --- a/app/models/species/eu_decisions_export.rb +++ b/app/models/species/eu_decisions_export.rb @@ -68,9 +68,9 @@ def csv_column_headers headers = [ 'Kingdom', 'Phylum', 'Class', 'Order', 'Family', 'Genus', 'Species', 'Subspecies', - 'Full Name', 'Rank', 'Date of Decision', 'Valid since', 'Party', - 'EU Decision', 'Source', 'Term', - 'Notes', 'Document', "Valid on Date: #{DateTime.now.strftime('%d/%m/%Y')}" + 'Full Name', 'Rank', 'Date of Decision', 'Valid since', 'Party', + 'EU Decision', 'Source', 'Term', + 'Notes', 'Document', "Valid on Date: #{DateTime.now.strftime('%d/%m/%Y')}" ] end diff --git a/app/models/trade/annual_report_upload_observer.rb b/app/models/trade/annual_report_upload_observer.rb index 3d1034c9a0..e52ca3794f 100644 --- a/app/models/trade/annual_report_upload_observer.rb +++ b/app/models/trade/annual_report_upload_observer.rb @@ -1,4 +1,4 @@ -class Trade::AnnualReportUploadObserver < ActiveRecord::Observer +class Trade::AnnualReportUploadObserver < ActiveRecord::Observer def after_create(annual_report_upload) annual_report_upload.copy_to_sandbox diff --git a/app/models/trade/shipment_observer.rb b/app/models/trade/shipment_observer.rb index 7a12461e8e..d2b46e6529 100644 --- a/app/models/trade/shipment_observer.rb +++ b/app/models/trade/shipment_observer.rb @@ -17,7 +17,7 @@ def before_save(shipment) end end unless shipment.reported_taxon_concept_id - shipment.reported_taxon_concept_id = shipment.taxon_concept_id + shipment.reported_taxon_concept_id = shipment.taxon_concept_id end end diff --git a/app/serializers/trade/species_name_appendix_year_validation_rule_serializer.rb b/app/serializers/trade/species_name_appendix_year_validation_rule_serializer.rb index 85bb854710..a24e85bc3c 100644 --- a/app/serializers/trade/species_name_appendix_year_validation_rule_serializer.rb +++ b/app/serializers/trade/species_name_appendix_year_validation_rule_serializer.rb @@ -1,3 +1,3 @@ class Trade::TaxonConceptAppendixYearValidationRuleSerializer < Trade::InclusionValidationRuleSerializer - attributes :valid_values_view + attributes :valid_values_view end \ No newline at end of file diff --git a/app/serializers/trade/validation_rule_serializer.rb b/app/serializers/trade/validation_rule_serializer.rb index 0f0948e958..afb6cc9ed1 100644 --- a/app/serializers/trade/validation_rule_serializer.rb +++ b/app/serializers/trade/validation_rule_serializer.rb @@ -1,4 +1,4 @@ class Trade::ValidationRuleSerializer < ActiveModel::Serializer - attributes :id, :type, :column_names, :run_order, :is_primary, + attributes :id, :type, :column_names, :run_order, :is_primary, :created_at, :updated_at end diff --git a/config.ru b/config.ru index a4cb03c4c1..41aebeb9ef 100644 --- a/config.ru +++ b/config.ru @@ -1,4 +1,4 @@ # This file is used by Rack-based servers to start the application. -require ::File.expand_path('../config/environment', __FILE__) +require ::File.expand_path('../config/environment', __FILE__) run SAPI::Application diff --git a/config/deploy.rb b/config/deploy.rb index a413af3d25..f2b5bbd5de 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -95,7 +95,7 @@ class PrecompileRequired < StandardError; end require 'yaml' require 'json' -secrets = YAML.load(File.open('config/secrets.yml')) +secrets = YAML.load(File.open('config/secrets.yml')) set :slack_token, secrets["development"]["capistrano_slack"] # comes from inbound webhook integration set :api_token, secrets["development"]["api_token"] diff --git a/config/environments/test.rb b/config/environments/test.rb index 89bae4146b..c1ddbb2df6 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -22,7 +22,7 @@ config.action_dispatch.show_exceptions = false # Disable request forgery protection in test environment - config.action_controller.allow_forgery_protection = false + config.action_controller.allow_forgery_protection = false # Tell Action Mailer not to deliver emails to the real world. # The :test delivery method accumulates sent emails in the diff --git a/lib/modules/latex_to_pdf.rb b/lib/modules/latex_to_pdf.rb index 2e8885e9c1..de46938dc8 100644 --- a/lib/modules/latex_to_pdf.rb +++ b/lib/modules/latex_to_pdf.rb @@ -60,7 +60,7 @@ class << (@latex_escaper=Object.new) '>' => 'greater' } - def latex_esc(text) # :nodoc: + def latex_esc(text) # :nodoc: text.gsub(ESCAPE_RE) {|m| if $1 "\\#{m}" diff --git a/lib/modules/sapi/summary.rb b/lib/modules/sapi/summary.rb index a5dc1e993c..4775be5d40 100644 --- a/lib/modules/sapi/summary.rb +++ b/lib/modules/sapi/summary.rb @@ -85,7 +85,7 @@ def self.taxonomy_kingdom_stats(taxonomy, kingdom) stats[:synonym_taxa] = TaxonConcept.where( :taxonomy_id => t.id, :name_status => 'S' ).where(["(data->'kingdom_id')::INT = ?", k.id]).count - stats[:other_taxa] = TaxonConcept.where( + stats[:other_taxa] = TaxonConcept.where( :taxonomy_id => t.id ).where(["(data->'kingdom_id')::INT = ?", k.id]). where("name_status NOT IN ('A', 'S')").count @@ -95,8 +95,8 @@ def self.taxonomy_kingdom_stats(taxonomy, kingdom) distributions = Distribution.joins(:taxon_concept). where(:taxon_concepts => {:taxonomy_id => t.id }). where(["(data->'kingdom_id')::INT = ?", k.id]) - stats[:distributions] = distributions.count - stats[:distribution_tags] = ActiveRecord::Base.connection.execute(<<-SQL + stats[:distributions] = distributions.count + stats[:distribution_tags] = ActiveRecord::Base.connection.execute(<<-SQL SELECT COUNT(*) FROM taggings INNER JOIN distributions ON taggings.taggable_id = distributions.id AND @@ -107,14 +107,14 @@ def self.taxonomy_kingdom_stats(taxonomy, kingdom) AND (data->'kingdom_id')::INT = #{k.id}; SQL ).values.flatten[0] - stats[:distribution_references] = DistributionReference. + stats[:distribution_references] = DistributionReference. joins(:distribution => :taxon_concept). where(:taxon_concepts => {:taxonomy_id => t.id }). where(["(data->'kingdom_id')::INT = ?", k.id]).count - stats[:taxon_references] = TaxonConceptReference.joins(:taxon_concept). + stats[:taxon_references] = TaxonConceptReference.joins(:taxon_concept). where(:taxon_concepts => {:taxonomy_id => t.id }). where(["(data->'kingdom_id')::INT = ?", k.id]).count - stats[:taxon_standard_references] = TaxonConceptReference.joins(:taxon_concept). + stats[:taxon_standard_references] = TaxonConceptReference.joins(:taxon_concept). where(:taxon_concepts => {:taxonomy_id => t.id }, :taxon_concept_references => {:is_standard => true}). where(["(data->'kingdom_id')::INT = ?", k.id]).count stats[:common_names] = TaxonCommon.joins(:taxon_concept). diff --git a/script/rails b/script/rails index f8da2cffd4..bd79dce518 100755 --- a/script/rails +++ b/script/rails @@ -1,6 +1,6 @@ #!/usr/bin/env ruby # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. -APP_PATH = File.expand_path('../../config/application', __FILE__) -require File.expand_path('../../config/boot', __FILE__) +APP_PATH = File.expand_path('../../config/application', __FILE__) +require File.expand_path('../../config/boot', __FILE__) require 'rails/commands' diff --git a/spec/factories/common_names.rb b/spec/factories/common_names.rb index b7594602f4..b3dfa3e422 100644 --- a/spec/factories/common_names.rb +++ b/spec/factories/common_names.rb @@ -3,7 +3,7 @@ factory :language do sequence(:name_en) { |n| "lng#{n}" } sequence(:iso_code1) { |n| [n, n+1].map{ |i| (65 + i%26).chr }.join } - sequence(:iso_code3) { |n| [n, n+1, n+2].map{ |i| (65 + i%26).chr }.join } + sequence(:iso_code3) { |n| [n, n+1, n+2].map{ |i| (65 + i%26).chr }.join } end factory :taxon_common do diff --git a/spec/factories/distributions.rb b/spec/factories/distributions.rb index 436b1c7484..da9c2402fc 100644 --- a/spec/factories/distributions.rb +++ b/spec/factories/distributions.rb @@ -17,7 +17,7 @@ factory :geo_entity, :aliases => [:related_geo_entity, :trading_country, :importer, :exporter] do geo_entity_type name_en 'Wonderland' - sequence(:iso_code2) { |n| [n, n+1].map{ |i| (65 + i%26).chr }.join } + sequence(:iso_code2) { |n| [n, n+1].map{ |i| (65 + i%26).chr }.join } is_current true end diff --git a/spec/factories/trade.rb b/spec/factories/trade.rb index 46fab23a1c..4705dede93 100644 --- a/spec/factories/trade.rb +++ b/spec/factories/trade.rb @@ -12,12 +12,12 @@ end factory :term, :class => Term do - sequence(:code) { |n| [n, n+1, n+2].map{ |i| (97 + i%26).chr }.join } + sequence(:code) { |n| [n, n+1, n+2].map{ |i| (97 + i%26).chr }.join } sequence(:name_en) { |n| "Term @{n}" } end factory :unit, :class => Unit do - sequence(:code) { |n| [n, n+1, n+2].map{ |i| (97 + i%26).chr }.join } + sequence(:code) { |n| [n, n+1, n+2].map{ |i| (97 + i%26).chr }.join } sequence(:name_en) { |n| "Unit @{n}" } end end From fec28cf06c651f75e0d460438f681825f8f8488c Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 3 Jun 2016 15:21:55 +0100 Subject: [PATCH 294/365] Correct indentation of first method parameter --- .rubocop.yml | 5 + .rubocop_todo.yml | 7 -- app/controllers/admin/documents_controller.rb | 4 +- app/models/api_request.rb | 14 +-- .../reassignment_copy_processor.rb | 4 +- app/models/quota.rb | 37 +++--- app/models/taxon_concept_prefix_matcher.rb | 64 +++++------ app/models/taxon_relationship.rb | 13 ++- app/models/trade/inclusion_validation_rule.rb | 12 +- lib/modules/sapi/summary.rb | 20 ++-- lib/tasks/import.rake | 22 ++-- .../lump_controller_spec.rb | 24 ++-- .../split_controller_spec.rb | 48 +++++--- .../admin/taxon_quotas_controller_spec.rb | 3 +- .../shared/lump_definitions.rb | 3 +- .../shared/split_definitions.rb | 7 +- ...cept_appendix_year_validation_rule_spec.rb | 16 +-- spec/shared/agalychnis.rb | 22 ++-- spec/shared/agave.rb | 42 +++---- spec/shared/ailuropoda.rb | 28 ++--- spec/shared/arctocephalus.rb | 50 ++++----- spec/shared/boa_constrictor.rb | 28 ++--- spec/shared/caiman_latirostris.rb | 60 +++++----- spec/shared/canis_lupus.rb | 24 ++-- spec/shared/caretta_caretta_cms.rb | 12 +- spec/shared/cedrela_montana.rb | 8 +- spec/shared/cervus_elaphus.rb | 42 +++---- spec/shared/cervus_elaphus_cms.rb | 24 ++-- spec/shared/colophon.rb | 14 +-- spec/shared/dalbergia.rb | 6 +- spec/shared/diospyros.rb | 42 +++---- spec/shared/falconiformes.rb | 106 +++++++++--------- spec/shared/hirudo_medicinalis.rb | 14 +-- spec/shared/loxodonta_africana.rb | 36 +++--- spec/shared/loxodonta_africana_cms.rb | 6 +- spec/shared/mellivora_capensis.rb | 50 ++++----- spec/shared/moschus.rb | 52 ++++----- spec/shared/notomys_aquilo.rb | 12 +- spec/shared/pecari_tajacu.rb | 6 +- spec/shared/pereskia.rb | 44 ++++---- spec/shared/platysternon_megacephalum.rb | 36 +++--- spec/shared/pristis_microdon.rb | 44 ++++---- spec/shared/pseudomys_fieldi.rb | 18 +-- spec/shared/psittaciformes.rb | 74 ++++++------ spec/shared/tapiridae.rb | 28 ++--- spec/shared/uroplatus.rb | 14 +-- spec/shared/varanidae.rb | 28 ++--- 47 files changed, 647 insertions(+), 626 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index a3e8735e0c..19097b9c80 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -59,3 +59,8 @@ Style/ExtraSpacing: AllowForAlignment: true Exclude: - 'db/migrate/*' + +# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. +# SupportedStyles: consistent, special_for_inner_method_call, special_for_inner_method_call_in_parentheses +Style/FirstParameterIndentation: + Enabled: true diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index b725ca3df5..09ba6489f2 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -338,13 +338,6 @@ Style/EmptyLinesAroundClassBody: Style/EmptyLinesAroundModuleBody: Enabled: false -# Offense count: 193 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. -# SupportedStyles: consistent, special_for_inner_method_call, special_for_inner_method_call_in_parentheses -Style/FirstParameterIndentation: - Enabled: false - # Offense count: 3 # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: for, each diff --git a/app/controllers/admin/documents_controller.rb b/app/controllers/admin/documents_controller.rb index caea5187a4..1378ec379c 100644 --- a/app/controllers/admin/documents_controller.rb +++ b/app/controllers/admin/documents_controller.rb @@ -99,8 +99,8 @@ def load_associations @taxonomy = Taxonomy.find_by_name(Taxonomy::CITES_EU) @geo_entities = GeoEntity.select(['geo_entities.id', :name_en]). joins(:geo_entity_type).where( - :"geo_entity_types.name" => [GeoEntityType::COUNTRY, GeoEntityType::TERRITORY] - ).order(:name_en) + :"geo_entity_types.name" => [GeoEntityType::COUNTRY, GeoEntityType::TERRITORY] + ).order(:name_en) end def success_redirect diff --git a/app/models/api_request.rb b/app/models/api_request.rb index ebef6d5980..b0575c0ab1 100644 --- a/app/models/api_request.rb +++ b/app/models/api_request.rb @@ -31,13 +31,13 @@ class ApiRequest < ActiveRecord::Base def self.top_5_most_active_users subquery = self.recent.select( - [ - :user_id, - 'COUNT(*) AS cnt', - 'COUNT(NULLIF(response_status = 200, FALSE)) AS success_cnt', - 'COUNT(NULLIF(response_status = 200, TRUE)) AS failure_cnt' - ] - ).group(:user_id). + [ + :user_id, + 'COUNT(*) AS cnt', + 'COUNT(NULLIF(response_status = 200, FALSE)) AS success_cnt', + 'COUNT(NULLIF(response_status = 200, TRUE)) AS failure_cnt' + ] + ).group(:user_id). where('user_id IS NOT NULL') self.from("(#{subquery.to_sql}) api_requests"). order('cnt DESC').limit(5) diff --git a/app/models/nomenclature_change/reassignment_copy_processor.rb b/app/models/nomenclature_change/reassignment_copy_processor.rb index e8de5c4435..4852f62cc5 100644 --- a/app/models/nomenclature_change/reassignment_copy_processor.rb +++ b/app/models/nomenclature_change/reassignment_copy_processor.rb @@ -99,8 +99,8 @@ def build_listing_change_associations(reassignable, copied_object) listing_change_id: copied_object.id }).first || party_listing_distribution && copied_object.build_party_listing_distribution( - party_listing_distribution.comparison_attributes - ) + party_listing_distribution.comparison_attributes + ) # taxonomic exclusions (population exclusions already duplicated) reassignable.exclusions.where('taxon_concept_id IS NOT NULL').each do |exclusion| !copied_object.new_record? && exclusion.duplicates({ diff --git a/app/models/quota.rb b/app/models/quota.rb index e96884a7ca..7318e96888 100644 --- a/app/models/quota.rb +++ b/app/models/quota.rb @@ -82,24 +82,23 @@ def self.years_array def self.count_matching(params) Quota.where( - [ - "EXTRACT(year from start_date) = :year - AND ((:excluded_geo_entities) IS NULL OR geo_entity_id NOT IN (:excluded_geo_entities)) - AND ((:included_geo_entities) IS NULL OR geo_entity_id IN (:included_geo_entities)) - AND ((:excluded_taxon_concepts) IS NULL OR taxon_concept_id NOT IN (:excluded_taxon_concepts)) - AND ((:included_taxon_concepts) IS NULL OR taxon_concept_id IN (:included_taxon_concepts)) - AND is_current = true", - :year => params[:year], - :excluded_geo_entities => params[:excluded_geo_entities_ids].present? ? - params[:excluded_geo_entities_ids].map(&:to_i) : nil, - :included_geo_entities => params[:included_geo_entities_ids].present? ? - params[:included_geo_entities_ids].map(&:to_i) : nil, - :excluded_taxon_concepts => params[:excluded_taxon_concepts_ids].present? ? - params[:excluded_taxon_concepts_ids].split(",").map(&:to_i) : nil, - :included_taxon_concepts => params[:included_taxon_concepts_ids].present? ? - params[:included_taxon_concepts_ids].split(",").map(&:to_i) : nil - ] - ). - count + [ + "EXTRACT(year from start_date) = :year + AND ((:excluded_geo_entities) IS NULL OR geo_entity_id NOT IN (:excluded_geo_entities)) + AND ((:included_geo_entities) IS NULL OR geo_entity_id IN (:included_geo_entities)) + AND ((:excluded_taxon_concepts) IS NULL OR taxon_concept_id NOT IN (:excluded_taxon_concepts)) + AND ((:included_taxon_concepts) IS NULL OR taxon_concept_id IN (:included_taxon_concepts)) + AND is_current = true", + :year => params[:year], + :excluded_geo_entities => params[:excluded_geo_entities_ids].present? ? + params[:excluded_geo_entities_ids].map(&:to_i) : nil, + :included_geo_entities => params[:included_geo_entities_ids].present? ? + params[:included_geo_entities_ids].map(&:to_i) : nil, + :excluded_taxon_concepts => params[:excluded_taxon_concepts_ids].present? ? + params[:excluded_taxon_concepts_ids].split(",").map(&:to_i) : nil, + :included_taxon_concepts => params[:included_taxon_concepts_ids].present? ? + params[:included_taxon_concepts_ids].split(",").map(&:to_i) : nil + ] + ).count end end diff --git a/app/models/taxon_concept_prefix_matcher.rb b/app/models/taxon_concept_prefix_matcher.rb index f9b0621972..6734cd4ad2 100644 --- a/app/models/taxon_concept_prefix_matcher.rb +++ b/app/models/taxon_concept_prefix_matcher.rb @@ -53,46 +53,46 @@ def apply_taxon_concept_options_to_rel taxon_concept = TaxonConcept.find(@taxon_concept_id) if @taxon_concept_scope if @taxon_concept_scope.to_sym == :ancestors @taxon_concepts = @taxon_concepts.joins( - <<-SQL - INNER JOIN ( - WITH RECURSIVE node AS ( - SELECT h.id, h.parent_id - FROM taxon_concepts h - WHERE id = #{taxon_concept.parent_id} + <<-SQL + INNER JOIN ( + WITH RECURSIVE node AS ( + SELECT h.id, h.parent_id + FROM taxon_concepts h + WHERE id = #{taxon_concept.parent_id} - UNION ALL + UNION ALL - SELECT hi.id, hi.parent_id - FROM node - JOIN taxon_concepts hi - ON hi.id = node.parent_id - ) - SELECT id FROM node - ) ancestors - ON ancestors.id = taxon_concepts.id - SQL + SELECT hi.id, hi.parent_id + FROM node + JOIN taxon_concepts hi + ON hi.id = node.parent_id + ) + SELECT id FROM node + ) ancestors + ON ancestors.id = taxon_concepts.id + SQL ) elsif @taxon_concept_scope.to_sym == :descendants @taxon_concepts = @taxon_concepts.joins( - <<-SQL - INNER JOIN ( - WITH RECURSIVE node AS ( - SELECT h.id - FROM taxon_concepts h - WHERE parent_id = #{taxon_concept.id} + <<-SQL + INNER JOIN ( + WITH RECURSIVE node AS ( + SELECT h.id + FROM taxon_concepts h + WHERE parent_id = #{taxon_concept.id} - UNION ALL + UNION ALL - SELECT hi.id - FROM node - JOIN taxon_concepts hi - ON hi.parent_id = node.id - ) - SELECT id FROM node - ) descendants - ON descendants.id = taxon_concepts.id - SQL + SELECT hi.id + FROM node + JOIN taxon_concepts hi + ON hi.parent_id = node.id + ) + SELECT id FROM node + ) descendants + ON descendants.id = taxon_concepts.id + SQL ) end end diff --git a/app/models/taxon_relationship.rb b/app/models/taxon_relationship.rb index db744ed470..73c22404bc 100644 --- a/app/models/taxon_relationship.rb +++ b/app/models/taxon_relationship.rb @@ -68,9 +68,10 @@ def create_opposite def destroy_opposite TaxonRelationship.where( - :taxon_concept_id => self.other_taxon_concept_id, - :other_taxon_concept_id => self.taxon_concept_id, - :taxon_relationship_type_id => self.taxon_relationship_type_id). + :taxon_concept_id => self.other_taxon_concept_id, + :other_taxon_concept_id => self.taxon_concept_id, + :taxon_relationship_type_id => self.taxon_relationship_type_id + ). delete_all end @@ -78,8 +79,10 @@ def destroy_opposite # ONE intertaxonomic Taxon Relationship. Unless the TaxonRelationships # share the same TaxonRelationshipType and this is bidirectional def intertaxonomic_relationship_uniqueness - if TaxonRelationship.where(:taxon_concept_id => self.taxon_concept_id, - :other_taxon_concept_id => self.other_taxon_concept_id). + if TaxonRelationship.where( + :taxon_concept_id => self.taxon_concept_id, + :other_taxon_concept_id => self.other_taxon_concept_id + ). joins(:taxon_relationship_type). where(:taxon_relationship_types => { :is_intertaxonomic => true }).any? || TaxonRelationship.where(:taxon_concept_id => self.other_taxon_concept_id, diff --git a/app/models/trade/inclusion_validation_rule.rb b/app/models/trade/inclusion_validation_rule.rb index d56e76845d..c65fb0ced2 100644 --- a/app/models/trade/inclusion_validation_rule.rb +++ b/app/models/trade/inclusion_validation_rule.rb @@ -48,12 +48,12 @@ def validation_errors(annual_report_upload) matching_records_grouped(annual_report_upload.sandbox.table_name).map do |mr| values_hash = Hash[column_names_for_display.map{ |cn| [cn, mr.send(cn)] }] Trade::ValidationError.new( - :error_message => error_message(values_hash), - :annual_report_upload_id => annual_report_upload.id, - :validation_rule_id => self.id, - :error_count => mr.error_count, - :matching_records_ids => parse_pg_array(mr.matching_records_ids), - :is_primary => self.is_primary + :error_message => error_message(values_hash), + :annual_report_upload_id => annual_report_upload.id, + :validation_rule_id => self.id, + :error_count => mr.error_count, + :matching_records_ids => parse_pg_array(mr.matching_records_ids), + :is_primary => self.is_primary ) end end diff --git a/lib/modules/sapi/summary.rb b/lib/modules/sapi/summary.rb index 4775be5d40..99ae6e4f83 100644 --- a/lib/modules/sapi/summary.rb +++ b/lib/modules/sapi/summary.rb @@ -79,17 +79,17 @@ def self.taxonomy_kingdom_stats(taxonomy, kingdom) t = Taxonomy.find_by_name(taxonomy) k = TaxonConcept.find_by_full_name_and_taxonomy_id(kingdom, t.id) stats[:accepted_taxa] = TaxonConcept.where( - :taxonomy_id => t.id, - :name_status => 'A'). - where(["(data->'kingdom_id')::INT = ?", k.id]).count - stats[:synonym_taxa] = TaxonConcept.where( - :taxonomy_id => t.id, :name_status => 'S' - ).where(["(data->'kingdom_id')::INT = ?", k.id]).count + :taxonomy_id => t.id, + :name_status => 'A' + ).where(["(data->'kingdom_id')::INT = ?", k.id]).count + stats[:synonym_taxa] = TaxonConcept.where( + :taxonomy_id => t.id, :name_status => 'S' + ).where(["(data->'kingdom_id')::INT = ?", k.id]).count stats[:other_taxa] = TaxonConcept.where( - :taxonomy_id => t.id - ).where(["(data->'kingdom_id')::INT = ?", k.id]). + :taxonomy_id => t.id + ).where(["(data->'kingdom_id')::INT = ?", k.id]). where("name_status NOT IN ('A', 'S')").count - stats[:listing_changes] = ListingChange.joins(:taxon_concept). + stats[:listing_changes] = ListingChange.joins(:taxon_concept). where(:taxon_concepts => {:taxonomy_id => t.id }). where(["(data->'kingdom_id')::INT = ?", k.id]).count distributions = Distribution.joins(:taxon_concept). @@ -102,7 +102,7 @@ def self.taxonomy_kingdom_stats(taxonomy, kingdom) taggings.taggable_id = distributions.id AND taggings.taggable_type = 'Distribution' INNER JOIN taxon_concepts ON - distributions.taxon_concept_id = taxon_concepts.id + distributions.taxon_concept_id = taxon_concepts.id AND taxon_concepts.taxonomy_id = #{t.id} AND (data->'kingdom_id')::INT = #{k.id}; SQL diff --git a/lib/tasks/import.rake b/lib/tasks/import.rake index b5951604a5..b892255882 100644 --- a/lib/tasks/import.rake +++ b/lib/tasks/import.rake @@ -75,25 +75,25 @@ namespace :import do task :references => :environment do Rake::Task["import:references"].invoke( - 'lib/files/animals/animalia_references_utf8.csv', - 'lib/files/plants/plantae_references_utf8.csv' + 'lib/files/animals/animalia_references_utf8.csv', + 'lib/files/plants/plantae_references_utf8.csv' ) Rake::Task["import:reference_distribution_links"].invoke( - 'lib/files/animals/animalia_reference_distribution_links_utf8.csv', - 'lib/files/plants/plantae_reference_distribution_links_utf8.csv' + 'lib/files/animals/animalia_reference_distribution_links_utf8.csv', + 'lib/files/plants/plantae_reference_distribution_links_utf8.csv' ) Rake::Task["import:reference_accepted_links"].invoke( - 'lib/files/animals/animalia_reference_accepted_links_utf8.csv', - 'lib/files/plants/plantae_reference_accepted_links_utf8.csv' + 'lib/files/animals/animalia_reference_accepted_links_utf8.csv', + 'lib/files/plants/plantae_reference_accepted_links_utf8.csv' ) Rake::Task["import:reference_synonym_links"].invoke( - 'lib/files/animals/animalia_reference_synonym_links_utf8.csv', - 'lib/files/plants/plantae_reference_synonym_links_utf8.csv' + 'lib/files/animals/animalia_reference_synonym_links_utf8.csv', + 'lib/files/plants/plantae_reference_synonym_links_utf8.csv' ) Rake::Task["import:standard_reference_links"].invoke( - 'lib/files/animals/animalia_standard_reference_links_utf8.csv', - 'lib/files/animals/CMS_standard_reference_links_utf8.csv', - 'lib/files/plants/plantae_standard_reference_links_utf8.csv' + 'lib/files/animals/animalia_standard_reference_links_utf8.csv', + 'lib/files/animals/CMS_standard_reference_links_utf8.csv', + 'lib/files/plants/plantae_standard_reference_links_utf8.csv' ) end diff --git a/spec/controllers/admin/nomenclature_changes/lump_controller_spec.rb b/spec/controllers/admin/nomenclature_changes/lump_controller_spec.rb index afce323b33..ad63893842 100644 --- a/spec/controllers/admin/nomenclature_changes/lump_controller_spec.rb +++ b/spec/controllers/admin/nomenclature_changes/lump_controller_spec.rb @@ -46,9 +46,11 @@ context "when no legislation" do it 'redirects to next step' do get :show, id: :legislation, nomenclature_change_id: @lump.id - response.should redirect_to(admin_nomenclature_change_lump_url( - nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'summary' - )) + response.should redirect_to( + admin_nomenclature_change_lump_url( + nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'summary' + ) + ) end end it 'renders the summary template' do @@ -61,9 +63,11 @@ describe 'POST create' do it 'redirects to lump wizard' do post :create, nomenclature_change_id: 'new' - response.should redirect_to(admin_nomenclature_change_lump_url( - nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'inputs' - )) + response.should redirect_to( + admin_nomenclature_change_lump_url( + nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'inputs' + ) + ) end end @@ -79,9 +83,11 @@ 1 => {taxon_concept_id: create_cites_eu_species.id} } }, nomenclature_change_id: @lump.id, id: 'inputs' - response.should redirect_to(admin_nomenclature_change_lump_url( - nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'outputs' - )) + response.should redirect_to( + admin_nomenclature_change_lump_url( + nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'outputs' + ) + ) end end context 'when unsuccessful' do diff --git a/spec/controllers/admin/nomenclature_changes/split_controller_spec.rb b/spec/controllers/admin/nomenclature_changes/split_controller_spec.rb index 90583b520a..c3a85b1943 100644 --- a/spec/controllers/admin/nomenclature_changes/split_controller_spec.rb +++ b/spec/controllers/admin/nomenclature_changes/split_controller_spec.rb @@ -43,9 +43,11 @@ context "when no children" do it 'redirects to next step' do get :show, id: :children, nomenclature_change_id: @split.id - response.should redirect_to(admin_nomenclature_change_split_url( - nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'names' - )) + response.should redirect_to( + admin_nomenclature_change_split_url( + nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'names' + ) + ) end end context "when names present" do @@ -64,9 +66,11 @@ context "when no names" do it 'redirects to next step' do get :show, id: :names, nomenclature_change_id: @split.id - response.should redirect_to(admin_nomenclature_change_split_url( - nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'distribution' - )) + response.should redirect_to( + admin_nomenclature_change_split_url( + nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'distribution' + ) + ) end end context "when distribution present" do @@ -81,9 +85,11 @@ context "when no distribution" do it 'redirects to next step' do get :show, id: :distribution, nomenclature_change_id: @split.id - response.should redirect_to(admin_nomenclature_change_split_url( - nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'legislation' - )) + response.should redirect_to( + admin_nomenclature_change_split_url( + nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'legislation' + ) + ) end end context "when legislation present" do @@ -98,9 +104,11 @@ context "when no legislation" do it 'redirects to next step' do get :show, id: :legislation, nomenclature_change_id: @split.id - response.should redirect_to(admin_nomenclature_change_split_url( - nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'summary' - )) + response.should redirect_to( + admin_nomenclature_change_split_url( + nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'summary' + ) + ) end end it 'renders the summary template' do @@ -113,9 +121,11 @@ describe 'POST create' do it 'redirects to split wizard' do post :create, nomenclature_change_id: 'new' - response.should redirect_to(admin_nomenclature_change_split_url( - nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'inputs' - )) + response.should redirect_to( + admin_nomenclature_change_split_url( + nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'inputs' + ) + ) end end @@ -128,9 +138,11 @@ put :update, nomenclature_change_split: { input_attributes: {taxon_concept_id: create_cites_eu_species.id} }, nomenclature_change_id: @split.id, id: 'inputs' - response.should redirect_to(admin_nomenclature_change_split_url( - nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'outputs' - )) + response.should redirect_to( + admin_nomenclature_change_split_url( + nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'outputs' + ) + ) end end context 'when unsuccessful' do diff --git a/spec/controllers/admin/taxon_quotas_controller_spec.rb b/spec/controllers/admin/taxon_quotas_controller_spec.rb index 32b4ececc3..54e28bfb92 100644 --- a/spec/controllers/admin/taxon_quotas_controller_spec.rb +++ b/spec/controllers/admin/taxon_quotas_controller_spec.rb @@ -132,7 +132,8 @@ describe "Authorization for contributors" do login_contributor - let!(:quota) { create( + let!(:quota) { + create( :quota, :unit_id => @unit.id, :taxon_concept_id => @taxon_concept.id, diff --git a/spec/models/nomenclature_change/shared/lump_definitions.rb b/spec/models/nomenclature_change/shared/lump_definitions.rb index b0583d154e..0ea067cb87 100644 --- a/spec/models/nomenclature_change/shared/lump_definitions.rb +++ b/spec/models/nomenclature_change/shared/lump_definitions.rb @@ -3,7 +3,8 @@ let(:input_species1){ input_species } let(:input_species2){ create_cites_eu_species } let(:output_species){ create_cites_eu_species } - let(:errorus_genus){ create_cites_eu_genus( + let(:errorus_genus){ + create_cites_eu_genus( taxon_name: create(:taxon_name, scientific_name: 'Errorus') ) } diff --git a/spec/models/nomenclature_change/shared/split_definitions.rb b/spec/models/nomenclature_change/shared/split_definitions.rb index 54934f3858..49537c605a 100644 --- a/spec/models/nomenclature_change/shared/split_definitions.rb +++ b/spec/models/nomenclature_change/shared/split_definitions.rb @@ -12,9 +12,10 @@ let(:input_species){ create_cites_eu_species(parent: genus1) } let(:output_species1){ create_cites_eu_species(parent: genus1) } let(:output_species2){ create_cites_eu_species(parent: genus2) } - let(:errorus_genus){ create_cites_eu_genus( - taxon_name: create(:taxon_name, scientific_name: 'Errorus') - ) + let(:errorus_genus){ + create_cites_eu_genus( + taxon_name: create(:taxon_name, scientific_name: 'Errorus') + ) } let(:output_subspecies2){ create_cites_eu_subspecies( diff --git a/spec/models/trade/taxon_concept_appendix_year_validation_rule_spec.rb b/spec/models/trade/taxon_concept_appendix_year_validation_rule_spec.rb index 61bfc0f74d..3396d31bc2 100644 --- a/spec/models/trade/taxon_concept_appendix_year_validation_rule_spec.rb +++ b/spec/models/trade/taxon_concept_appendix_year_validation_rule_spec.rb @@ -36,18 +36,18 @@ :parent_id => genus.id ) create_cites_I_addition( - :taxon_concept => @species, - :effective_at => '1990-01-18' + :taxon_concept => @species, + :effective_at => '1990-01-18' ) create_cites_I_addition( - :taxon_concept => @species, - :effective_at => '1997-09-18', - :is_current => true + :taxon_concept => @species, + :effective_at => '1997-09-18', + :is_current => true ) cites_lc2 = create_cites_II_addition( - :taxon_concept => @species, - :effective_at => '1997-09-18', - :is_current => true + :taxon_concept => @species, + :effective_at => '1997-09-18', + :is_current => true ) synonym = create_cites_eu_species( :taxon_name => create(:taxon_name, :scientific_name => 'Loxodonta cyclotis'), diff --git a/spec/shared/agalychnis.rb b/spec/shared/agalychnis.rb index d1ed932bad..a299d0394d 100644 --- a/spec/shared/agalychnis.rb +++ b/spec/shared/agalychnis.rb @@ -16,23 +16,23 @@ ) create_cites_II_addition( - :taxon_concept => @genus, - :effective_at => '2010-06-23', - :is_current => true + :taxon_concept => @genus, + :effective_at => '2010-06-23', + :is_current => true ) create_eu_B_addition( - :taxon_concept => @genus, - :effective_at => '2012-12-15', - :event => reg2012, - :is_current => false + :taxon_concept => @genus, + :effective_at => '2012-12-15', + :event => reg2012, + :is_current => false ) create_eu_B_addition( - :taxon_concept => @genus, - :effective_at => '2013-08-10', - :event => reg2013, - :is_current => true + :taxon_concept => @genus, + :effective_at => '2013-08-10', + :event => reg2013, + :is_current => true ) @ref = create( diff --git a/spec/shared/agave.rb b/spec/shared/agave.rb index a41c1a514d..cedbb6209e 100644 --- a/spec/shared/agave.rb +++ b/spec/shared/agave.rb @@ -30,40 +30,40 @@ ) create_cites_I_addition( - :taxon_concept => @species1, - :effective_at => '1983-07-29' + :taxon_concept => @species1, + :effective_at => '1983-07-29' ) create_cites_I_addition( - :taxon_concept => @species2, - :effective_at => '1983-07-29', - :is_current => true + :taxon_concept => @species2, + :effective_at => '1983-07-29', + :is_current => true ) create_cites_I_deletion( - :taxon_concept => @species1, - :effective_at => '2007-09-13', - :is_current => true + :taxon_concept => @species1, + :effective_at => '2007-09-13', + :is_current => true ) create_eu_A_addition( - :taxon_concept => @species1, - :effective_at => '1997-06-01', - :is_current => false + :taxon_concept => @species1, + :effective_at => '1997-06-01', + :is_current => false ) create_eu_A_addition( - :taxon_concept => @species2, - :effective_at => '1997-06-01', - :is_current => false + :taxon_concept => @species2, + :effective_at => '1997-06-01', + :is_current => false ) create_eu_A_deletion( - :taxon_concept => @species1, - :effective_at => '2008-04-11', - :is_current => false + :taxon_concept => @species1, + :effective_at => '2008-04-11', + :is_current => false ) create_eu_A_addition( - :taxon_concept => @species2, - :effective_at => '2013-08-10', - :event => reg2013, - :is_current => true + :taxon_concept => @species2, + :effective_at => '2013-08-10', + :event => reg2013, + :is_current => true ) Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings diff --git a/spec/shared/ailuropoda.rb b/spec/shared/ailuropoda.rb index a138873548..f1dc84e56d 100644 --- a/spec/shared/ailuropoda.rb +++ b/spec/shared/ailuropoda.rb @@ -19,27 +19,27 @@ ) create_cites_II_addition( - :taxon_concept => @family, - :effective_at => '1992-06-11', - :is_current => true + :taxon_concept => @family, + :effective_at => '1992-06-11', + :is_current => true ) create_cites_I_addition( - :taxon_concept => @species, - :effective_at => '1984-03-14', - :is_current => true + :taxon_concept => @species, + :effective_at => '1984-03-14', + :is_current => true ) create_eu_B_addition( - :taxon_concept => @family, - :effective_at => '2013-08-10', - :event => reg2013, - :is_current => true + :taxon_concept => @family, + :effective_at => '2013-08-10', + :event => reg2013, + :is_current => true ) create_eu_A_addition( - :taxon_concept => @species, - :effective_at => '2013-08-10', - :event => reg2013, - :is_current => true + :taxon_concept => @species, + :effective_at => '2013-08-10', + :event => reg2013, + :is_current => true ) Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings diff --git a/spec/shared/arctocephalus.rb b/spec/shared/arctocephalus.rb index 41cf862054..c14a4083fb 100644 --- a/spec/shared/arctocephalus.rb +++ b/spec/shared/arctocephalus.rb @@ -64,46 +64,46 @@ ) create_cites_II_addition( - :taxon_concept => @species1, - :effective_at => '1975-07-01' + :taxon_concept => @species1, + :effective_at => '1975-07-01' ) create_cites_II_addition( - :taxon_concept => @species2, - :effective_at => '1975-07-01' + :taxon_concept => @species2, + :effective_at => '1975-07-01' ) create_cites_II_addition( - :taxon_concept => @genus, - :effective_at => '1977-02-04', - :is_current => true + :taxon_concept => @genus, + :effective_at => '1977-02-04', + :is_current => true ) create_cites_II_addition( - :taxon_concept => @species1, - :effective_at => '1977-02-04', - :inclusion_taxon_concept_id => @genus.id, - :is_current => true + :taxon_concept => @species1, + :effective_at => '1977-02-04', + :inclusion_taxon_concept_id => @genus.id, + :is_current => true ) create_cites_II_addition( - :taxon_concept => @species2, - :effective_at => '1977-02-04', - :inclusion_taxon_concept_id => @genus.id + :taxon_concept => @species2, + :effective_at => '1977-02-04', + :inclusion_taxon_concept_id => @genus.id ) create_cites_I_addition( - :taxon_concept => @species2, - :effective_at => '1979-06-28', - :is_current => true + :taxon_concept => @species2, + :effective_at => '1979-06-28', + :is_current => true ) create_eu_A_addition( - :taxon_concept => @species2, - :effective_at => '2013-08-10', - :event => reg2013, - :is_current => true + :taxon_concept => @species2, + :effective_at => '2013-08-10', + :event => reg2013, + :is_current => true ) create_eu_B_addition( - :taxon_concept => @genus, - :effective_at => '2013-08-10', - :event => reg2013, - :is_current => true + :taxon_concept => @genus, + :effective_at => '2013-08-10', + :event => reg2013, + :is_current => true ) Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings diff --git a/spec/shared/boa_constrictor.rb b/spec/shared/boa_constrictor.rb index c91f8d4f04..49cf5aec5d 100644 --- a/spec/shared/boa_constrictor.rb +++ b/spec/shared/boa_constrictor.rb @@ -44,8 +44,8 @@ ) create_cites_II_addition( - :taxon_concept => @species, - :effective_at => '1975-07-01' + :taxon_concept => @species, + :effective_at => '1975-07-01' ) create_cites_II_addition( :taxon_concept => @family, @@ -53,20 +53,20 @@ :is_current => true ) create_cites_II_addition( - :taxon_concept => @species, - :effective_at => '1977-02-04', - :inclusion_taxon_concept_id => @family.id, - :is_current => true + :taxon_concept => @species, + :effective_at => '1977-02-04', + :inclusion_taxon_concept_id => @family.id, + :is_current => true ) create_cites_II_addition( - :taxon_concept => @subspecies1, - :effective_at => '1977-02-04', - :inclusion_taxon_concept_id => @family.id + :taxon_concept => @subspecies1, + :effective_at => '1977-02-04', + :inclusion_taxon_concept_id => @family.id ) create_cites_I_addition( - :taxon_concept => @subspecies1, - :effective_at => '1987-10-22', - :is_current => true + :taxon_concept => @subspecies1, + :effective_at => '1987-10-22', + :is_current => true ) create_eu_B_addition( @@ -76,10 +76,10 @@ :is_current => true ) create_eu_A_addition( - :taxon_concept => @subspecies1, + :taxon_concept => @subspecies1, :effective_at => '2013-08-10', :event => reg2013, - :is_current => true + :is_current => true ) Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings diff --git a/spec/shared/caiman_latirostris.rb b/spec/shared/caiman_latirostris.rb index cb5e54a862..e7ca6a0ef4 100644 --- a/spec/shared/caiman_latirostris.rb +++ b/spec/shared/caiman_latirostris.rb @@ -79,9 +79,9 @@ :is_current => true ) create_cites_I_addition( - :taxon_concept => @species, - :effective_at => '1975-07-01', - :is_current => true + :taxon_concept => @species, + :effective_at => '1975-07-01', + :is_current => true ) a_I = create( :annotation, @@ -94,11 +94,11 @@ :display_in_index => true ) cites_lc = create_cites_II_addition( - :taxon_concept => @species, - :annotation_id => a_II.id, - :effective_at => '1997-09-18', - :inclusion_taxon_concept_id => @order.id, - :is_current => true + :taxon_concept => @species, + :annotation_id => a_II.id, + :effective_at => '1997-09-18', + :inclusion_taxon_concept_id => @order.id, + :is_current => true ) create( :listing_distribution, @@ -108,22 +108,22 @@ ) create_eu_A_addition( - :taxon_concept => @species, - :effective_at => '1997-06-01', - :event => reg1997 + :taxon_concept => @species, + :effective_at => '1997-06-01', + :event => reg1997 ) create_eu_B_addition( - :taxon_concept => @order, - :effective_at => '2013-10-08', - :event => reg2013, - :is_current => true + :taxon_concept => @order, + :effective_at => '2013-10-08', + :event => reg2013, + :is_current => true ) eu_lc_b = create_eu_B_addition( - :taxon_concept => @species, - :annotation_id => a_II.id, - :effective_at => '2013-10-08', - :event => reg2013, - :is_current => true + :taxon_concept => @species, + :annotation_id => a_II.id, + :effective_at => '2013-10-08', + :event => reg2013, + :is_current => true ) create( :listing_distribution, @@ -132,18 +132,18 @@ :is_party => false ) eu_lc_a = create_eu_A_addition( - :taxon_concept => @species, - :annotation_id => a_I.id, - :effective_at => '2013-10-08', - :event => reg2013, - :is_current => true + :taxon_concept => @species, + :annotation_id => a_I.id, + :effective_at => '2013-10-08', + :event => reg2013, + :is_current => true ) eu_lc_a_exception = create_eu_A_exception( - :taxon_concept => @species, - :effective_at => '2013-10-08', - :event => reg2013, - :parent_id => eu_lc_a.id, - :is_current => true + :taxon_concept => @species, + :effective_at => '2013-10-08', + :event => reg2013, + :parent_id => eu_lc_a.id, + :is_current => true ) create( :listing_distribution, diff --git a/spec/shared/canis_lupus.rb b/spec/shared/canis_lupus.rb index a8d42e9d23..8b6dccb38f 100644 --- a/spec/shared/canis_lupus.rb +++ b/spec/shared/canis_lupus.rb @@ -94,24 +94,24 @@ end create_cites_II_addition( - :taxon_concept => @species, - :effective_at => '1977-02-04' + :taxon_concept => @species, + :effective_at => '1977-02-04' ) create_cites_II_addition( - :taxon_concept => @subspecies, - :effective_at => '1977-02-04', - :inclusion_taxon_concept_id => @species.id, - :is_current => true + :taxon_concept => @subspecies, + :effective_at => '1977-02-04', + :inclusion_taxon_concept_id => @species.id, + :is_current => true ) cites_lc_I = create_cites_I_addition( - :taxon_concept => @species, - :effective_at => '2010-06-23', - :is_current => true + :taxon_concept => @species, + :effective_at => '2010-06-23', + :is_current => true ) cites_lc_II = create_cites_II_addition( - :taxon_concept => @species, - :effective_at => '2010-06-23', - :is_current => true + :taxon_concept => @species, + :effective_at => '2010-06-23', + :is_current => true ) cites_lc_II_exc = create_cites_II_exception( :taxon_concept => @species, diff --git a/spec/shared/caretta_caretta_cms.rb b/spec/shared/caretta_caretta_cms.rb index c30413f80e..649d163f73 100644 --- a/spec/shared/caretta_caretta_cms.rb +++ b/spec/shared/caretta_caretta_cms.rb @@ -19,15 +19,15 @@ ) create_cms_II_addition( - :taxon_concept => @family, - :effective_at => '1983-11-01', - :is_current => true + :taxon_concept => @family, + :effective_at => '1983-11-01', + :is_current => true ) create_cms_I_addition( - :taxon_concept => @species, - :effective_at => '1986-01-24', - :is_current => true + :taxon_concept => @species, + :effective_at => '1986-01-24', + :is_current => true ) Sapi::StoredProcedures.rebuild_cms_taxonomy_and_listings diff --git a/spec/shared/cedrela_montana.rb b/spec/shared/cedrela_montana.rb index fa0bbf9f2e..810609b5c5 100644 --- a/spec/shared/cedrela_montana.rb +++ b/spec/shared/cedrela_montana.rb @@ -18,10 +18,10 @@ ) create_eu_D_addition( - :taxon_concept => @species, - :effective_at => '2013-08-10', - :event => reg2013, - :is_current => true + :taxon_concept => @species, + :effective_at => '2013-08-10', + :event => reg2013, + :is_current => true ) Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings diff --git a/spec/shared/cervus_elaphus.rb b/spec/shared/cervus_elaphus.rb index 0f43d12c47..0411a776f5 100644 --- a/spec/shared/cervus_elaphus.rb +++ b/spec/shared/cervus_elaphus.rb @@ -35,38 +35,38 @@ ) create_cites_II_addition( - :taxon_concept => @subspecies1, - :effective_at => '1975-07-01', - :is_current => true + :taxon_concept => @subspecies1, + :effective_at => '1975-07-01', + :is_current => true ) create_cites_III_addition( - :taxon_concept => @subspecies2, - :effective_at => '1976-04-22', - :is_current => true + :taxon_concept => @subspecies2, + :effective_at => '1976-04-22', + :is_current => true ) create_cites_I_addition( - :taxon_concept => @subspecies3, - :effective_at => '1975-07-01', - :is_current => true + :taxon_concept => @subspecies3, + :effective_at => '1975-07-01', + :is_current => true ) create_eu_B_addition( - :taxon_concept => @subspecies1, - :effective_at => '2013-10-08', - :event => reg2013, - :is_current => true + :taxon_concept => @subspecies1, + :effective_at => '2013-10-08', + :event => reg2013, + :is_current => true ) create_eu_C_addition( - :taxon_concept => @subspecies2, - :effective_at => '2013-10-08', - :event => reg2013, - :is_current => true + :taxon_concept => @subspecies2, + :effective_at => '2013-10-08', + :event => reg2013, + :is_current => true ) create_eu_A_addition( - :taxon_concept => @subspecies3, - :effective_at => '2013-10-08', - :event => reg2013, - :is_current => true + :taxon_concept => @subspecies3, + :effective_at => '2013-10-08', + :event => reg2013, + :is_current => true ) Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings diff --git a/spec/shared/cervus_elaphus_cms.rb b/spec/shared/cervus_elaphus_cms.rb index f4ffd549b8..edc66d38d1 100644 --- a/spec/shared/cervus_elaphus_cms.rb +++ b/spec/shared/cervus_elaphus_cms.rb @@ -26,24 +26,24 @@ ) create_cms_I_addition( - :taxon_concept => @species, - :effective_at => '1979-01-01', - :is_current => true + :taxon_concept => @species, + :effective_at => '1979-01-01', + :is_current => true ) create_cms_I_addition( - :taxon_concept => @subspecies2, - :effective_at => '1979-01-01', - :is_current => true + :taxon_concept => @subspecies2, + :effective_at => '1979-01-01', + :is_current => true ) create_cms_I_addition( - :taxon_concept => @species, - :effective_at => '2006-02-23', - :is_current => true + :taxon_concept => @species, + :effective_at => '2006-02-23', + :is_current => true ) create_cms_II_addition( - :taxon_concept => @species, - :effective_at => '2006-02-23', - :is_current => true + :taxon_concept => @species, + :effective_at => '2006-02-23', + :is_current => true ) create( diff --git a/spec/shared/colophon.rb b/spec/shared/colophon.rb index 2752149890..5b2e6d4270 100644 --- a/spec/shared/colophon.rb +++ b/spec/shared/colophon.rb @@ -28,9 +28,9 @@ ) cites_lc = create_cites_III_addition( - :taxon_concept => @genus, - :effective_at => '2000-09-13', - :is_current => true + :taxon_concept => @genus, + :effective_at => '2000-09-13', + :is_current => true ) create( :listing_distribution, @@ -40,10 +40,10 @@ ) eu_lc = create_eu_C_addition( - :taxon_concept => @genus, - :effective_at => '2013-10-08', - :event => reg2013, - :is_current => true + :taxon_concept => @genus, + :effective_at => '2013-10-08', + :event => reg2013, + :is_current => true ) create( :listing_distribution, diff --git a/spec/shared/dalbergia.rb b/spec/shared/dalbergia.rb index 0e2e8fd97f..217a5763dd 100644 --- a/spec/shared/dalbergia.rb +++ b/spec/shared/dalbergia.rb @@ -53,9 +53,9 @@ ) cites_lc = create_cites_II_addition( - :taxon_concept => @genus, - :effective_at => '2013-06-12', - :is_current => true + :taxon_concept => @genus, + :effective_at => '2013-06-12', + :is_current => true ) create( diff --git a/spec/shared/diospyros.rb b/spec/shared/diospyros.rb index f7985ecc8a..008365436a 100644 --- a/spec/shared/diospyros.rb +++ b/spec/shared/diospyros.rb @@ -50,9 +50,9 @@ ) cites_lc = create_cites_III_addition( - :taxon_concept => @species1, - :effective_at => '2011-12-22', - :is_current => false + :taxon_concept => @species1, + :effective_at => '2011-12-22', + :is_current => false ) create( @@ -63,10 +63,10 @@ ) eu_lc = create_eu_C_addition( - :taxon_concept => @species1, - :effective_at => '2012-12-15', - :event => reg2012, - :is_current => false + :taxon_concept => @species1, + :effective_at => '2012-12-15', + :event => reg2012, + :is_current => false ) create( @@ -77,9 +77,9 @@ ) cites_lc = create_cites_III_deletion( - :taxon_concept => @species1, - :effective_at => '2013-06-12', - :is_current => false + :taxon_concept => @species1, + :effective_at => '2013-06-12', + :is_current => false ) create( @@ -90,9 +90,9 @@ ) cites_lc = create_cites_II_addition( - :taxon_concept => @genus, - :effective_at => '2013-06-12', - :is_current => true + :taxon_concept => @genus, + :effective_at => '2013-06-12', + :is_current => true ) create( @@ -103,17 +103,17 @@ ) create_cites_II_addition( - :taxon_concept => @species1, - :effective_at => '2013-06-12', - :inclusion_taxon_concept_id => @genus.id, - :is_current => true + :taxon_concept => @species1, + :effective_at => '2013-06-12', + :inclusion_taxon_concept_id => @genus.id, + :is_current => true ) eu_lc = create_eu_B_addition( - :taxon_concept => @genus, - :effective_at => '2013-08-10', - :event => reg2013, - :is_current => true + :taxon_concept => @genus, + :effective_at => '2013-08-10', + :event => reg2013, + :is_current => true ) create( diff --git a/spec/shared/falconiformes.rb b/spec/shared/falconiformes.rb index 7a31fc738b..c791158d20 100644 --- a/spec/shared/falconiformes.rb +++ b/spec/shared/falconiformes.rb @@ -71,90 +71,90 @@ ) cites_lc1 = create_cites_II_addition( - :taxon_concept => @order, - :effective_at => '1979-06-28', - :is_current => true + :taxon_concept => @order, + :effective_at => '1979-06-28', + :is_current => true ) create_cites_II_exception( - :taxon_concept => @family1, - :effective_at => '1979-06-28', - :parent_id => cites_lc1.id + :taxon_concept => @family1, + :effective_at => '1979-06-28', + :parent_id => cites_lc1.id ) create_cites_I_addition( - :taxon_concept => @species1_1, - :effective_at => '1975-07-01', - :is_current => true + :taxon_concept => @species1_1, + :effective_at => '1975-07-01', + :is_current => true ) create_cites_III_addition( - :taxon_concept => @species1_2, - :effective_at => '1987-04-13', - :is_current => true + :taxon_concept => @species1_2, + :effective_at => '1987-04-13', + :is_current => true ) create_cites_II_addition( - :taxon_concept => @family2, - :effective_at => '1975-07-01' + :taxon_concept => @family2, + :effective_at => '1975-07-01' ) create_cites_II_addition( - :taxon_concept => @family2, - :effective_at => '1979-06-28', - :inclusion_taxon_concept_id => @order.id, - :is_current => true + :taxon_concept => @family2, + :effective_at => '1979-06-28', + :inclusion_taxon_concept_id => @order.id, + :is_current => true ) create_cites_II_addition( - :taxon_concept => @species2_1, - :effective_at => '1975-07-01' + :taxon_concept => @species2_1, + :effective_at => '1975-07-01' ) create_cites_I_addition( - :taxon_concept => @species2_1, - :effective_at => '1977-02-04', - :is_current => true + :taxon_concept => @species2_1, + :effective_at => '1977-02-04', + :is_current => true ) create_cites_I_addition( - :taxon_concept => @species2_3, - :effective_at => '1977-02-04', - :is_current => true + :taxon_concept => @species2_3, + :effective_at => '1977-02-04', + :is_current => true ) create_cites_I_addition( - :taxon_concept => @subspecies2_3_1, - :effective_at => '1977-02-04', - :inclusion_taxon_concept_id => @species2_3.id, - :is_current => true + :taxon_concept => @subspecies2_3_1, + :effective_at => '1977-02-04', + :inclusion_taxon_concept_id => @species2_3.id, + :is_current => true ) eu_lc1 = create_eu_B_addition( - :taxon_concept => @order, - :effective_at => '2013-08-10', - :event => reg2013, - :is_current => true + :taxon_concept => @order, + :effective_at => '2013-08-10', + :event => reg2013, + :is_current => true ) create_eu_B_exception( - :taxon_concept => @family1, - :effective_at => '2013-08-10', - :parent_id => eu_lc1.id + :taxon_concept => @family1, + :effective_at => '2013-08-10', + :parent_id => eu_lc1.id ) create_eu_A_addition( - :taxon_concept => @species1_1, - :effective_at => '2013-08-10', - :event => reg2013, - :is_current => true + :taxon_concept => @species1_1, + :effective_at => '2013-08-10', + :event => reg2013, + :is_current => true ) create_eu_C_addition( - :taxon_concept => @species1_2, - :effective_at => '2013-08-10', - :event => reg2013, - :is_current => true + :taxon_concept => @species1_2, + :effective_at => '2013-08-10', + :event => reg2013, + :is_current => true ) create_eu_A_addition( - :taxon_concept => @species2_1, - :effective_at => '2013-08-10', - :event => reg2013, - :is_current => true + :taxon_concept => @species2_1, + :effective_at => '2013-08-10', + :event => reg2013, + :is_current => true ) create_eu_A_addition( - :taxon_concept => @species2_3, - :effective_at => '2013-08-10', - :event => reg2013, - :is_current => true + :taxon_concept => @species2_3, + :effective_at => '2013-08-10', + :event => reg2013, + :is_current => true ) Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings diff --git a/spec/shared/hirudo_medicinalis.rb b/spec/shared/hirudo_medicinalis.rb index d62581d086..7413aff45e 100644 --- a/spec/shared/hirudo_medicinalis.rb +++ b/spec/shared/hirudo_medicinalis.rb @@ -19,15 +19,15 @@ ) create_cites_II_addition( - :taxon_concept => @species, - :effective_at => '1987-10-22', - :is_current => true + :taxon_concept => @species, + :effective_at => '1987-10-22', + :is_current => true ) create_eu_B_addition( - :taxon_concept => @species, - :effective_at => '2013-10-08', - :event => reg2013, - :is_current => true + :taxon_concept => @species, + :effective_at => '2013-10-08', + :event => reg2013, + :is_current => true ) Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings diff --git a/spec/shared/loxodonta_africana.rb b/spec/shared/loxodonta_africana.rb index e08bce904c..ac904178e9 100644 --- a/spec/shared/loxodonta_africana.rb +++ b/spec/shared/loxodonta_africana.rb @@ -60,12 +60,12 @@ create(:distribution, :taxon_concept_id => @species.id, :geo_entity_id => botswana.id) cites_lc1 = create_cites_I_addition( - :taxon_concept => @species, - :effective_at => '1997-09-18' + :taxon_concept => @species, + :effective_at => '1997-09-18' ) cites_lc2 = create_cites_II_addition( - :taxon_concept => @species, - :effective_at => '1997-09-18' + :taxon_concept => @species, + :effective_at => '1997-09-18' ) [botswana, namibia, zimbabwe].each do |country| create( @@ -76,26 +76,26 @@ ) end cites_lc1 = create_cites_I_addition( - :taxon_concept => @species, - :effective_at => '2000-07-19', - :is_current => true + :taxon_concept => @species, + :effective_at => '2000-07-19', + :is_current => true ) cites_lc2 = create_cites_II_addition( - :taxon_concept => @species, - :effective_at => '2000-07-19', - :is_current => true + :taxon_concept => @species, + :effective_at => '2000-07-19', + :is_current => true ) eu_lc1 = create_eu_A_addition( - :taxon_concept => @species, - :effective_at => '2013-08-10', - :event => reg2013, - :is_current => true + :taxon_concept => @species, + :effective_at => '2013-08-10', + :event => reg2013, + :is_current => true ) eu_lc2 = create_eu_B_addition( - :taxon_concept => @species, - :effective_at => '2013-08-10', - :event => reg2013, - :is_current => true + :taxon_concept => @species, + :effective_at => '2013-08-10', + :event => reg2013, + :is_current => true ) [botswana, namibia, zambia, zimbabwe].each do |country| create( diff --git a/spec/shared/loxodonta_africana_cms.rb b/spec/shared/loxodonta_africana_cms.rb index 2a5135dd1a..623acc43cf 100644 --- a/spec/shared/loxodonta_africana_cms.rb +++ b/spec/shared/loxodonta_africana_cms.rb @@ -19,9 +19,9 @@ ) create_cms_II_addition( - :taxon_concept => @species, - :effective_at => '1979-01-01', - :is_current => true + :taxon_concept => @species, + :effective_at => '1979-01-01', + :is_current => true ) Sapi::StoredProcedures.rebuild_cms_taxonomy_and_listings diff --git a/spec/shared/mellivora_capensis.rb b/spec/shared/mellivora_capensis.rb index 1c11632432..0c0e5ca540 100644 --- a/spec/shared/mellivora_capensis.rb +++ b/spec/shared/mellivora_capensis.rb @@ -34,9 +34,9 @@ ) cites_lc1 = create_cites_III_addition( - :taxon_concept => @species, - :effective_at => '1976-02-26', - :is_current => false + :taxon_concept => @species, + :effective_at => '1976-02-26', + :is_current => false ) create( :listing_distribution, @@ -44,9 +44,9 @@ :listing_change => cites_lc1 ) cites_lc2 = create_cites_III_addition( - :taxon_concept => @species, - :effective_at => '1978-04-24', - :is_current => true + :taxon_concept => @species, + :effective_at => '1978-04-24', + :is_current => true ) create( :listing_distribution, @@ -54,9 +54,9 @@ :listing_change => cites_lc2 ) cites_lc3 = create_cites_III_deletion( - :taxon_concept => @species, - :effective_at => '2007-03-04', - :is_current => true + :taxon_concept => @species, + :effective_at => '2007-03-04', + :is_current => true ) create( :listing_distribution, @@ -65,9 +65,9 @@ ) eu_lc1 = create_eu_C_addition( - :taxon_concept => @species, - :effective_at => '2005-08-22', - :event => reg2005 + :taxon_concept => @species, + :effective_at => '2005-08-22', + :event => reg2005 ) create( :listing_distribution, @@ -75,9 +75,9 @@ :listing_change => eu_lc1 ) eu_lc2 = create_eu_C_addition( - :taxon_concept => @species, - :effective_at => '2005-08-22', - :event => reg2005 + :taxon_concept => @species, + :effective_at => '2005-08-22', + :event => reg2005 ) create( :listing_distribution, @@ -85,9 +85,9 @@ :listing_change => eu_lc2 ) eu_lc3 = create_eu_C_addition( - :taxon_concept => @species, - :effective_at => '2008-04-11', - :event => reg2008 + :taxon_concept => @species, + :effective_at => '2008-04-11', + :event => reg2008 ) create( :listing_distribution, @@ -95,9 +95,9 @@ :listing_change => eu_lc3 ) eu_lc4 = create_eu_C_deletion( - :taxon_concept => @species, - :effective_at => '2008-04-11', - :event => reg2008 + :taxon_concept => @species, + :effective_at => '2008-04-11', + :event => reg2008 ) create( :listing_distribution, @@ -105,10 +105,10 @@ :listing_change => eu_lc4 ) eu_lc5 = create_eu_C_addition( - :taxon_concept => @species, - :effective_at => '2013-08-10', - :event => reg2013, - :is_current => true + :taxon_concept => @species, + :effective_at => '2013-08-10', + :event => reg2013, + :is_current => true ) create( :listing_distribution, diff --git a/spec/shared/moschus.rb b/spec/shared/moschus.rb index 60e8f07538..100e732a0f 100644 --- a/spec/shared/moschus.rb +++ b/spec/shared/moschus.rb @@ -73,21 +73,21 @@ end create_cites_I_addition( - :taxon_concept => @subspecies, - :effective_at => '1975-07-01', - :is_current => false + :taxon_concept => @subspecies, + :effective_at => '1975-07-01', + :is_current => false ) create_cites_II_addition( - :taxon_concept => @genus, - :effective_at => '1979-06-28', - :is_current => false + :taxon_concept => @genus, + :effective_at => '1979-06-28', + :is_current => false ) lc = create_cites_I_addition( - :taxon_concept => @species2, - :effective_at => '1979-06-28', - :is_current => false + :taxon_concept => @species2, + :effective_at => '1979-06-28', + :is_current => false ) create( :listing_distribution, @@ -97,23 +97,23 @@ ) create_cites_II_addition( - :taxon_concept => @species2, - :effective_at => '1979-06-28', - :inclusion_taxon_concept_id => @genus.id, - :is_current => false + :taxon_concept => @species2, + :effective_at => '1979-06-28', + :inclusion_taxon_concept_id => @genus.id, + :is_current => false ) create_cites_I_addition( - :taxon_concept => @subspecies, - :effective_at => '1979-06-28', - :inclusion_taxon_concept_id => @species2.id, - :is_current => true + :taxon_concept => @subspecies, + :effective_at => '1979-06-28', + :inclusion_taxon_concept_id => @species2.id, + :is_current => true ) cites_lc1 = create_cites_I_addition( - :taxon_concept => @genus, - :effective_at => '1983-07-29', - :is_current => true + :taxon_concept => @genus, + :effective_at => '1983-07-29', + :is_current => true ) [bhutan, india, nepal].each do |country| create( @@ -124,9 +124,9 @@ ) end cites_lc2 = create_cites_II_addition( - :taxon_concept => @genus, - :effective_at => '1983-07-29', - :is_current => true + :taxon_concept => @genus, + :effective_at => '1983-07-29', + :is_current => true ) cites_lc2_exc = create_cites_II_exception( @@ -144,9 +144,9 @@ end cites_lc3 = create_cites_I_deletion( - :taxon_concept => @species2, - :effective_at => '1983-07-29', - :is_current => false + :taxon_concept => @species2, + :effective_at => '1983-07-29', + :is_current => false ) create( diff --git a/spec/shared/notomys_aquilo.rb b/spec/shared/notomys_aquilo.rb index 9f397d1b40..928e1ca454 100644 --- a/spec/shared/notomys_aquilo.rb +++ b/spec/shared/notomys_aquilo.rb @@ -19,14 +19,14 @@ ) create_cites_I_addition( - :taxon_concept => @species, - :effective_at => '1975-07-01' + :taxon_concept => @species, + :effective_at => '1975-07-01' ) create_cites_II_addition( - :taxon_concept => @species, - :effective_at => '1979-06-28', - :inclusion_taxon_concept_id => @genus.id, - :is_current => true + :taxon_concept => @species, + :effective_at => '1979-06-28', + :inclusion_taxon_concept_id => @genus.id, + :is_current => true ) cites_del = create_cites_II_deletion( :taxon_concept => @genus, diff --git a/spec/shared/pecari_tajacu.rb b/spec/shared/pecari_tajacu.rb index 287701b33a..2fc963cdce 100644 --- a/spec/shared/pecari_tajacu.rb +++ b/spec/shared/pecari_tajacu.rb @@ -64,9 +64,9 @@ ) cites_lc1 = create_cites_II_addition( - :taxon_concept => @species, - :effective_at => '1987-10-22', - :is_current => true + :taxon_concept => @species, + :effective_at => '1987-10-22', + :is_current => true ) cites_lc1_exc = create_cites_II_exception( :taxon_concept => @species, diff --git a/spec/shared/pereskia.rb b/spec/shared/pereskia.rb index f3111903a9..08014d82a2 100644 --- a/spec/shared/pereskia.rb +++ b/spec/shared/pereskia.rb @@ -18,41 +18,41 @@ ) cites_lc1 = create_cites_II_addition( - :taxon_concept => @family, - :effective_at => '2010-06-23', - :is_current => true + :taxon_concept => @family, + :effective_at => '2010-06-23', + :is_current => true ) create_cites_II_exception( - :taxon_concept => @genus1, - :effective_at => '2010-06-23', - :parent_id => cites_lc1.id + :taxon_concept => @genus1, + :effective_at => '2010-06-23', + :parent_id => cites_lc1.id ) create_cites_II_addition( - :taxon_concept => @genus2, - :effective_at => '1975-07-01' + :taxon_concept => @genus2, + :effective_at => '1975-07-01' ) create_cites_I_addition( - :taxon_concept => @genus2, - :effective_at => '1992-06-11', - :is_current => true + :taxon_concept => @genus2, + :effective_at => '1992-06-11', + :is_current => true ) eu_lc1 = create_eu_B_addition( - :taxon_concept => @family, - :effective_at => '2013-08-10', - :event => reg2013, - :is_current => true + :taxon_concept => @family, + :effective_at => '2013-08-10', + :event => reg2013, + :is_current => true ) create_eu_B_exception( - :taxon_concept => @genus1, - :effective_at => '2013-08-10', - :parent_id => eu_lc1.id + :taxon_concept => @genus1, + :effective_at => '2013-08-10', + :parent_id => eu_lc1.id ) create_eu_A_addition( - :taxon_concept => @genus2, - :effective_at => '2013-08-10', - :event => reg2013, - :is_current => true + :taxon_concept => @genus2, + :effective_at => '2013-08-10', + :event => reg2013, + :is_current => true ) Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings diff --git a/spec/shared/platysternon_megacephalum.rb b/spec/shared/platysternon_megacephalum.rb index ccb86a5384..3cdd5cfd72 100644 --- a/spec/shared/platysternon_megacephalum.rb +++ b/spec/shared/platysternon_megacephalum.rb @@ -20,36 +20,36 @@ ) create_cites_II_addition( - :taxon_concept => @species, - :effective_at => '2003-02-13', - :is_current => false + :taxon_concept => @species, + :effective_at => '2003-02-13', + :is_current => false ) create_eu_B_addition( - :taxon_concept => @species, - :effective_at => '2012-12-15', - :event => reg2012, - :is_current => false + :taxon_concept => @species, + :effective_at => '2012-12-15', + :event => reg2012, + :is_current => false ) create_cites_I_addition( - :taxon_concept => @family, - :effective_at => '2013-06-12', - :is_current => true + :taxon_concept => @family, + :effective_at => '2013-06-12', + :is_current => true ) create_eu_A_addition( - :taxon_concept => @family, - :effective_at => '2013-08-10', - :event => reg2013, - :is_current => true + :taxon_concept => @family, + :effective_at => '2013-08-10', + :event => reg2013, + :is_current => true ) create_cites_I_addition( - :taxon_concept => @species, - :effective_at => '2013-06-12', - :inclusion_taxon_concept_id => @family.id, - :is_current => true + :taxon_concept => @species, + :effective_at => '2013-06-12', + :inclusion_taxon_concept_id => @family.id, + :is_current => true ) Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings diff --git a/spec/shared/pristis_microdon.rb b/spec/shared/pristis_microdon.rb index 2e90a87c92..45e464ae53 100644 --- a/spec/shared/pristis_microdon.rb +++ b/spec/shared/pristis_microdon.rb @@ -20,27 +20,27 @@ ) create_cites_I_addition( - :taxon_concept => @family, - :effective_at => '2007-09-13', - :is_current => true + :taxon_concept => @family, + :effective_at => '2007-09-13', + :is_current => true ) create_cites_II_addition( - :taxon_concept => @species, - :effective_at => '2007-09-13', - :is_current => false + :taxon_concept => @species, + :effective_at => '2007-09-13', + :is_current => false ) create_cites_I_addition( - :taxon_concept => @species, - :effective_at => '2013-06-12', - :inclusion_taxon_concept_id => @family.id, - :is_current => true + :taxon_concept => @species, + :effective_at => '2013-06-12', + :inclusion_taxon_concept_id => @family.id, + :is_current => true ) eu_lc = create_eu_A_addition( - :taxon_concept => @family, - :effective_at => '2012-12-15', - :event => reg2012, - :is_current => false + :taxon_concept => @family, + :effective_at => '2012-12-15', + :event => reg2012, + :is_current => false ) create_eu_A_exception( :taxon_concept => @species, @@ -48,16 +48,16 @@ :parent_id => eu_lc.id ) create_eu_B_addition( - :taxon_concept => @family, - :effective_at => '2012-12-15', - :event => reg2012, - :is_current => false + :taxon_concept => @family, + :effective_at => '2012-12-15', + :event => reg2012, + :is_current => false ) create_eu_A_addition( - :taxon_concept => @family, - :effective_at => '2013-08-10', - :event => reg2013, - :is_current => true + :taxon_concept => @family, + :effective_at => '2013-08-10', + :event => reg2013, + :is_current => true ) Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings diff --git a/spec/shared/pseudomys_fieldi.rb b/spec/shared/pseudomys_fieldi.rb index f44b002676..610baa780f 100644 --- a/spec/shared/pseudomys_fieldi.rb +++ b/spec/shared/pseudomys_fieldi.rb @@ -24,8 +24,8 @@ ) create_cites_I_addition( - :taxon_concept => @species, - :effective_at => '1975-07-01' + :taxon_concept => @species, + :effective_at => '1975-07-01' ) cites_del = create_cites_I_deletion( :taxon_concept => @species, @@ -38,16 +38,16 @@ :parent_id => cites_del.id ) create_cites_I_addition( - :taxon_concept => @subspecies, - :effective_at => '1975-07-01', - :is_current => true + :taxon_concept => @subspecies, + :effective_at => '1975-07-01', + :is_current => true ) create_eu_A_addition( - :taxon_concept => @subspecies, - :effective_at => '2013-08-10', - :event => reg2013, - :is_current => true + :taxon_concept => @subspecies, + :effective_at => '2013-08-10', + :event => reg2013, + :is_current => true ) Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings diff --git a/spec/shared/psittaciformes.rb b/spec/shared/psittaciformes.rb index 6fe274147e..2db57afe57 100644 --- a/spec/shared/psittaciformes.rb +++ b/spec/shared/psittaciformes.rb @@ -87,13 +87,13 @@ ) create_cites_II_addition( - :taxon_concept => @order, - :effective_at => '1981-06-06' + :taxon_concept => @order, + :effective_at => '1981-06-06' ) cites_lc = create_cites_II_addition( - :taxon_concept => @order, - :effective_at => '2005-01-12', - :is_current => true + :taxon_concept => @order, + :effective_at => '2005-01-12', + :is_current => true ) create_cites_II_exception( :taxon_concept => @species2_1, @@ -106,43 +106,43 @@ :parent_id => cites_lc.id ) create_cites_II_addition( - :taxon_concept => @species1_1, - :effective_at => '1975-07-01' + :taxon_concept => @species1_1, + :effective_at => '1975-07-01' ) create_cites_I_addition( - :taxon_concept => @species1_1, - :effective_at => '1987-10-22', - :is_current => true + :taxon_concept => @species1_1, + :effective_at => '1987-10-22', + :is_current => true ) create_cites_II_addition( - :taxon_concept => @species1_2_1, - :effective_at => '1981-06-06' + :taxon_concept => @species1_2_1, + :effective_at => '1981-06-06' ) create_cites_I_addition( - :taxon_concept => @species1_2_1, - :effective_at => '1992-06-11', - :is_current => true + :taxon_concept => @species1_2_1, + :effective_at => '1992-06-11', + :is_current => true ) create_cites_III_addition( - :taxon_concept => @family2, - :effective_at => '1976-02-26' + :taxon_concept => @family2, + :effective_at => '1976-02-26' ) create_cites_II_addition( - :taxon_concept => @family2, - :effective_at => '1981-06-06' + :taxon_concept => @family2, + :effective_at => '1981-06-06' ) create_cites_II_addition( - :taxon_concept => @genus2_1, - :effective_at => '1981-06-06' + :taxon_concept => @genus2_1, + :effective_at => '1981-06-06' ) create_cites_II_addition( - :taxon_concept => @family2, - :effective_at => '1981-06-06' + :taxon_concept => @family2, + :effective_at => '1981-06-06' ) cites_lc1 = create_cites_II_addition( - :taxon_concept => @family2, - :effective_at => '2005-01-12', - :is_current => true + :taxon_concept => @family2, + :effective_at => '2005-01-12', + :is_current => true ) create_cites_II_exception( :taxon_concept => @species2_1, @@ -153,18 +153,18 @@ :parent_id => cites_lc1.id ) create_cites_II_deletion( - :taxon_concept => @species2_1, - :effective_at => '2005-01-12', - :is_current => true + :taxon_concept => @species2_1, + :effective_at => '2005-01-12', + :is_current => true ) create_cites_II_addition( - :taxon_concept => @species2_2_1, - :effective_at => '1981-06-06', - :is_current => true + :taxon_concept => @species2_2_1, + :effective_at => '1981-06-06', + :is_current => true ) cites_lc1 = create_cites_III_addition( - :taxon_concept => @species2_3, - :effective_at => '1976-02-26' + :taxon_concept => @species2_3, + :effective_at => '1976-02-26' ) create( :listing_distribution, @@ -172,9 +172,9 @@ :listing_change => cites_lc1 ) cites_lc2 = create_cites_III_deletion( - :taxon_concept => @species2_3, - :effective_at => '2007-03-04', - :is_current => true + :taxon_concept => @species2_3, + :effective_at => '2007-03-04', + :is_current => true ) create( :listing_distribution, diff --git a/spec/shared/tapiridae.rb b/spec/shared/tapiridae.rb index cb8bd40b67..68f1bd02a2 100644 --- a/spec/shared/tapiridae.rb +++ b/spec/shared/tapiridae.rb @@ -21,27 +21,27 @@ end create_cites_I_addition( - :taxon_concept => @family, - :effective_at => '1975-07-01', - :is_current => true + :taxon_concept => @family, + :effective_at => '1975-07-01', + :is_current => true ) create_cites_II_addition( - :taxon_concept => @species, - :effective_at => '1977-02-04', - :is_current => true + :taxon_concept => @species, + :effective_at => '1977-02-04', + :is_current => true ) create_eu_A_addition( - :taxon_concept => @family, - :effective_at => '2013-10-08', - :event => reg2013, - :is_current => true + :taxon_concept => @family, + :effective_at => '2013-10-08', + :event => reg2013, + :is_current => true ) create_eu_B_addition( - :taxon_concept => @species, - :effective_at => '2013-10-08', - :event => reg2013, - :is_current => true + :taxon_concept => @species, + :effective_at => '2013-10-08', + :event => reg2013, + :is_current => true ) Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings diff --git a/spec/shared/uroplatus.rb b/spec/shared/uroplatus.rb index 4bb2aab454..0f696da7b9 100644 --- a/spec/shared/uroplatus.rb +++ b/spec/shared/uroplatus.rb @@ -24,15 +24,15 @@ ) create_cites_II_addition( - :taxon_concept => @genus, - :effective_at => '2005-01-12', - :is_current => true + :taxon_concept => @genus, + :effective_at => '2005-01-12', + :is_current => true ) create_eu_B_addition( - :taxon_concept => @genus, - :effective_at => '2013-10-08', - :event => reg2013, - :is_current => true + :taxon_concept => @genus, + :effective_at => '2013-10-08', + :event => reg2013, + :is_current => true ) @ref = create( diff --git a/spec/shared/varanidae.rb b/spec/shared/varanidae.rb index 63551d8882..e299b06d68 100644 --- a/spec/shared/varanidae.rb +++ b/spec/shared/varanidae.rb @@ -23,27 +23,27 @@ ) create_cites_II_addition( - :taxon_concept => @genus, - :effective_at => '1975-07-01', - :is_current => true + :taxon_concept => @genus, + :effective_at => '1975-07-01', + :is_current => true ) create_cites_I_addition( - :taxon_concept => @species1, - :effective_at => '1975-07-01', - :is_current => true + :taxon_concept => @species1, + :effective_at => '1975-07-01', + :is_current => true ) create_eu_B_addition( - :taxon_concept => @genus, - :effective_at => '2013-10-08', - :event => reg2013, - :is_current => true + :taxon_concept => @genus, + :effective_at => '2013-10-08', + :event => reg2013, + :is_current => true ) create_eu_A_addition( - :taxon_concept => @species1, - :effective_at => '2013-10-08', - :event => reg2013, - :is_current => true + :taxon_concept => @species1, + :effective_at => '2013-10-08', + :event => reg2013, + :is_current => true ) @ref1 = create( From 8858a15573a9db5900611610693510d405e5bf2d Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 3 Jun 2016 15:41:34 +0100 Subject: [PATCH 295/365] Use 2 spaces for indentation --- .rubocop.yml | 7 ++++ .rubocop_todo.yml | 6 ---- app/models/listing_change_observer.rb | 34 +++++++++--------- .../status_to_synonym/constructor.rb | 9 ++--- app/models/trade_restriction.rb | 2 +- config/initializers/devise.rb | 2 +- .../api/geo_entities_controller_spec.rb | 12 +++---- .../api/taxon_concepts_controller_spec.rb | 36 +++++++++---------- .../checklist/geo_entities_controller_spec.rb | 12 +++---- .../annual_report_uploads_controller_spec.rb | 4 +-- .../appendix_population_and_region_spec.rb | 18 +++++----- spec/models/checklist/scientific_name_spec.rb | 8 ++--- .../models/trade/annual_report_upload_spec.rb | 22 ++++++------ spec/shared/boa_constrictor.rb | 6 ++-- spec/shared/caiman_latirostris.rb | 6 ++-- 15 files changed, 94 insertions(+), 90 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 19097b9c80..61803c48ec 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -64,3 +64,10 @@ Style/ExtraSpacing: # SupportedStyles: consistent, special_for_inner_method_call, special_for_inner_method_call_in_parentheses Style/FirstParameterIndentation: Enabled: true + +# Configuration parameters: Width. +Style/IndentationWidth: + Exclude: + - 'lib/tasks/bbgem.rake' + - 'db/migrate/*' + - 'old_cap/*' diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 09ba6489f2..0d628b5453 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -369,12 +369,6 @@ Style/IfInsideElse: Style/IfUnlessModifier: Enabled: false -# Offense count: 126 -# Cop supports --auto-correct. -# Configuration parameters: Width. -Style/IndentationWidth: - Enabled: false - # Offense count: 12 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. diff --git a/app/models/listing_change_observer.rb b/app/models/listing_change_observer.rb index 24a0ae4fe0..a6e87e4877 100644 --- a/app/models/listing_change_observer.rb +++ b/app/models/listing_change_observer.rb @@ -28,27 +28,29 @@ def before_save(listing_change) #geographic exclusions excluded_geo_entities_ids = listing_change.excluded_geo_entities_ids && listing_change.excluded_geo_entities_ids.reject(&:blank?) - excluded_geo_entities = if excluded_geo_entities_ids && excluded_geo_entities_ids.size > 0 - new_exclusions << ListingChange.new( - :change_type_id => exclusion_change_type.id, - :species_listing_id => listing_change.species_listing_id, - :taxon_concept_id => listing_change.taxon_concept_id, - :geo_entity_ids => excluded_geo_entities_ids - ) - end - - #taxonomic exclusions - excluded_taxon_concepts_ids = listing_change.excluded_taxon_concepts_ids && - listing_change.excluded_taxon_concepts_ids.split(',').reject(&:blank?) - excluded_taxon_concepts = if excluded_taxon_concepts_ids && excluded_taxon_concepts_ids.size > 0 - excluded_taxon_concepts_ids.map do |id| + excluded_geo_entities = + if excluded_geo_entities_ids && excluded_geo_entities_ids.size > 0 new_exclusions << ListingChange.new( :change_type_id => exclusion_change_type.id, :species_listing_id => listing_change.species_listing_id, - :taxon_concept_id => id + :taxon_concept_id => listing_change.taxon_concept_id, + :geo_entity_ids => excluded_geo_entities_ids ) end - end + + #taxonomic exclusions + excluded_taxon_concepts_ids = listing_change.excluded_taxon_concepts_ids && + listing_change.excluded_taxon_concepts_ids.split(',').reject(&:blank?) + excluded_taxon_concepts = + if excluded_taxon_concepts_ids && excluded_taxon_concepts_ids.size > 0 + excluded_taxon_concepts_ids.map do |id| + new_exclusions << ListingChange.new( + :change_type_id => exclusion_change_type.id, + :species_listing_id => listing_change.species_listing_id, + :taxon_concept_id => id + ) + end + end listing_change.exclusions = new_exclusions end diff --git a/app/models/nomenclature_change/status_to_synonym/constructor.rb b/app/models/nomenclature_change/status_to_synonym/constructor.rb index f59a76a461..6ed5b0815a 100644 --- a/app/models/nomenclature_change/status_to_synonym/constructor.rb +++ b/app/models/nomenclature_change/status_to_synonym/constructor.rb @@ -9,10 +9,11 @@ def initialize(nomenclature_change) def build_secondary_output if @nomenclature_change.secondary_output.nil? - secondary_output_tc = if @nomenclature_change.requires_accepted_name_assignment? - primary_output_tc = @nomenclature_change.primary_output.try(:taxon_concept) - primary_output_tc && primary_output_tc.accepted_names_for_trade_name.first - end + secondary_output_tc = + if @nomenclature_change.requires_accepted_name_assignment? + primary_output_tc = @nomenclature_change.primary_output.try(:taxon_concept) + primary_output_tc && primary_output_tc.accepted_names_for_trade_name.first + end @nomenclature_change.build_secondary_output( is_primary_output: false, taxon_concept_id: secondary_output_tc.try(:id) diff --git a/app/models/trade_restriction.rb b/app/models/trade_restriction.rb index e7db16dc9a..16b16e0e6a 100644 --- a/app/models/trade_restriction.rb +++ b/app/models/trade_restriction.rb @@ -156,8 +156,8 @@ def self.to_csv(file_path, filters) csv << row end offset += limit - end end + end end def self.filter_is_current(set) diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 8c3ce7b29e..caaf98c2d2 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -264,7 +264,7 @@ #custom redirection when login fails config.warden do |manager| - manager.failure_app = CustomFailure + manager.failure_app = CustomFailure end Warden::Manager.after_set_user do |user,auth,opts| diff --git a/spec/controllers/api/geo_entities_controller_spec.rb b/spec/controllers/api/geo_entities_controller_spec.rb index 727335490d..785791decf 100644 --- a/spec/controllers/api/geo_entities_controller_spec.rb +++ b/spec/controllers/api/geo_entities_controller_spec.rb @@ -18,12 +18,12 @@ ) } let!(:andorra){ - create( - :geo_entity, - :geo_entity_type => country_geo_entity_type, - :name => 'andorra', - :iso_code2 => 'AD' - ) + create( + :geo_entity, + :geo_entity_type => country_geo_entity_type, + :name => 'andorra', + :iso_code2 => 'AD' + ) } let!(:french_guiana){ create( diff --git a/spec/controllers/api/taxon_concepts_controller_spec.rb b/spec/controllers/api/taxon_concepts_controller_spec.rb index 577698e030..df1b1ab778 100644 --- a/spec/controllers/api/taxon_concepts_controller_spec.rb +++ b/spec/controllers/api/taxon_concepts_controller_spec.rb @@ -3,25 +3,25 @@ describe Api::V1::TaxonConceptsController, :type => :controller do context "GET index" do it " logs with Ahoy with different parameters" do - expect { - get :index, { - :taxonomy => 'cites_eu', - :taxon_concept_query => 'stork', - :geo_entity_scope => 'cites', - :page => 1 - } - }.to change{Ahoy::Event.count}.by(1) - expect(Ahoy::Event.last.visit_id).to_not be(nil) + expect { + get :index, { + :taxonomy => 'cites_eu', + :taxon_concept_query => 'stork', + :geo_entity_scope => 'cites', + :page => 1 + } + }.to change{Ahoy::Event.count}.by(1) + expect(Ahoy::Event.last.visit_id).to_not be(nil) - expect { - get :index, { - :taxonomy => 'cites_eu', - :taxon_concept_query => 'dolphin', - :geo_entity_scope => 'cites', - :page => 1 - } - }.to change{Ahoy::Event.count}.by(1) - expect(@ahoy_event1).to eq(@ahoy_event2) + expect { + get :index, { + :taxonomy => 'cites_eu', + :taxon_concept_query => 'dolphin', + :geo_entity_scope => 'cites', + :page => 1 + } + }.to change{Ahoy::Event.count}.by(1) + expect(@ahoy_event1).to eq(@ahoy_event2) end end end diff --git a/spec/controllers/checklist/geo_entities_controller_spec.rb b/spec/controllers/checklist/geo_entities_controller_spec.rb index 78d12b9f77..06f6017a24 100644 --- a/spec/controllers/checklist/geo_entities_controller_spec.rb +++ b/spec/controllers/checklist/geo_entities_controller_spec.rb @@ -18,12 +18,12 @@ ) } let!(:andorra){ - create( - :geo_entity, - :geo_entity_type => country_geo_entity_type, - :name => 'andorra', - :iso_code2 => 'AD' - ) + create( + :geo_entity, + :geo_entity_type => country_geo_entity_type, + :name => 'andorra', + :iso_code2 => 'AD' + ) } let!(:french_guiana){ create( diff --git a/spec/controllers/trade/annual_report_uploads_controller_spec.rb b/spec/controllers/trade/annual_report_uploads_controller_spec.rb index 2c4ec1e323..70781994fa 100644 --- a/spec/controllers/trade/annual_report_uploads_controller_spec.rb +++ b/spec/controllers/trade/annual_report_uploads_controller_spec.rb @@ -19,7 +19,7 @@ def exporter_csv create( :annual_report_upload, :point_of_view => 'E', - :trading_country_id => france.id, + :trading_country_id => france.id, :csv_source_file => exporter_csv ) } @@ -40,7 +40,7 @@ def exporter_csv get :index, is_done: 0, format: :json response.body.should have_json_size(1).at_path('annual_report_uploads') end - end + end describe "GET show" do it "should return success" do diff --git a/spec/models/checklist/appendix_population_and_region_spec.rb b/spec/models/checklist/appendix_population_and_region_spec.rb index 0d957e1ce8..15ca358fcd 100644 --- a/spec/models/checklist/appendix_population_and_region_spec.rb +++ b/spec/models/checklist/appendix_population_and_region_spec.rb @@ -50,15 +50,15 @@ end end context "when South America" do - subject{ - checklist = Checklist::Checklist.new({ - :cites_region_ids => [south_america.id] - }) - checklist.results - } - specify do - subject.should include(@species) - end + subject{ + checklist = Checklist::Checklist.new({ + :cites_region_ids => [south_america.id] + }) + checklist.results + } + specify do + subject.should include(@species) + end end context "when North America" do subject{ diff --git a/spec/models/checklist/scientific_name_spec.rb b/spec/models/checklist/scientific_name_spec.rb index a76df5a30e..afd1828be8 100644 --- a/spec/models/checklist/scientific_name_spec.rb +++ b/spec/models/checklist/scientific_name_spec.rb @@ -14,8 +14,8 @@ checklist.results } specify{ - subject.first.full_name.should == @species2.full_name - subject.size.should == 1 + subject.first.full_name.should == @species2.full_name + subject.size.should == 1 } end context "by common name" do @@ -27,8 +27,8 @@ checklist.results } specify{ - subject.first.full_name.should == @species2.full_name - subject.size.should == 1 + subject.first.full_name.should == @species2.full_name + subject.size.should == 1 } end end diff --git a/spec/models/trade/annual_report_upload_spec.rb b/spec/models/trade/annual_report_upload_spec.rb index c0d680a4be..3e967b3e7a 100644 --- a/spec/models/trade/annual_report_upload_spec.rb +++ b/spec/models/trade/annual_report_upload_spec.rb @@ -117,17 +117,17 @@ def invalid_file end describe :destroy do - subject{ - create( - :annual_report_upload, - :point_of_view => 'I', - :csv_source_file => importer_file - ) - } - specify{ - subject.sandbox.should_receive(:destroy) - subject.destroy - } + subject{ + create( + :annual_report_upload, + :point_of_view => 'I', + :csv_source_file => importer_file + ) + } + specify{ + subject.sandbox.should_receive(:destroy) + subject.destroy + } end describe :submit do diff --git a/spec/shared/boa_constrictor.rb b/spec/shared/boa_constrictor.rb index 49cf5aec5d..2a3f061e6f 100644 --- a/spec/shared/boa_constrictor.rb +++ b/spec/shared/boa_constrictor.rb @@ -1,8 +1,8 @@ shared_context "Boa constrictor" do let(:en){ - create(:language, :name => 'Spanish', :iso_code1 => 'ES', :iso_code3 => 'SPA') - create(:language, :name => 'French', :iso_code1 => 'FR', :iso_code3 => 'FRA') - create(:language, :name => 'English', :iso_code1 => 'EN', :iso_code3 => 'ENG') + create(:language, :name => 'Spanish', :iso_code1 => 'ES', :iso_code3 => 'SPA') + create(:language, :name => 'French', :iso_code1 => 'FR', :iso_code3 => 'FRA') + create(:language, :name => 'English', :iso_code1 => 'EN', :iso_code3 => 'ENG') } before(:all) do @order = create_cites_eu_order( diff --git a/spec/shared/caiman_latirostris.rb b/spec/shared/caiman_latirostris.rb index e7ca6a0ef4..45ffe3e857 100644 --- a/spec/shared/caiman_latirostris.rb +++ b/spec/shared/caiman_latirostris.rb @@ -2,9 +2,9 @@ shared_context "Caiman latirostris" do let(:en){ - create(:language, :name => 'Spanish', :iso_code1 => 'ES', :iso_code3 => 'SPA') - create(:language, :name => 'French', :iso_code1 => 'FR', :iso_code3 => 'FRA') - create(:language, :name => 'English', :iso_code1 => 'EN', :iso_code3 => 'ENG') + create(:language, :name => 'Spanish', :iso_code1 => 'ES', :iso_code3 => 'SPA') + create(:language, :name => 'French', :iso_code1 => 'FR', :iso_code3 => 'FRA') + create(:language, :name => 'English', :iso_code1 => 'EN', :iso_code3 => 'ENG') } let(:argentina){ create( From 5b146dd56d0300d243dafbcea3c44ab02901f7b4 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 3 Jun 2016 15:45:21 +0100 Subject: [PATCH 296/365] Removed trailing whitespace --- .rubocop_todo.yml | 5 ----- app/controllers/admin/distributions_controller.rb | 2 +- app/controllers/admin/quotas_controller.rb | 2 +- app/controllers/pages_controller.rb | 2 +- app/controllers/trade/statistics_controller.rb | 8 ++++---- app/models/checklist/csv/history.rb | 2 +- app/models/checklist/higher_taxa_injector.rb | 2 +- app/models/checklist/json/history_content.rb | 2 +- app/models/checklist/json/index_content.rb | 4 ++-- app/models/designation.rb | 2 +- app/models/distribution_reference.rb | 2 +- app/models/events_by_type_stats.rb | 2 +- app/models/instrument.rb | 2 +- app/models/listing_change.rb | 2 +- .../delete_unreassigned_processor.rb | 2 +- app/models/species_listing.rb | 4 ++-- app/models/taxonomy.rb | 2 +- app/models/term_trade_codes_pair.rb | 4 ++-- app/models/trade/filter.rb | 4 ++-- app/models/trade/taxon_concept_term_pair.rb | 12 ++++++------ app/models/trade/validation_rule.rb | 2 +- app/models/trade_code.rb | 4 ++-- .../species/cites_listing_change_serializer.rb | 2 +- .../species/cms_instruments_serializer.rb | 2 +- .../species/show_taxon_concept_serializer.rb | 2 +- .../trade/shipment_from_view_serializer.rb | 4 ++-- .../20140929092236_add_rank_name_to_sandbox_views.rb | 2 +- ...remove_status_change_from_nomenclature_changes.rb | 2 +- lib/capistrano/tasks/config.rake | 6 +++--- lib/modules/statistics.rb | 10 +++++----- lib/scripts/get_listed_species_per_country.rb | 6 +++--- lib/tasks/bbgem.rake | 6 +++--- lib/tasks/import_cites_listings.rake | 12 ++++++------ lib/tasks/import_cites_parties.rake | 2 +- lib/tasks/import_cites_quotas.rake | 4 ++-- lib/tasks/import_standard_reference_links.rake | 6 +++--- lib/tasks/import_synonyms.rake | 2 +- .../checklist/appendix_population_and_region_spec.rb | 2 +- spec/models/checklist/pdf/index_fetcher_spec.rb | 6 +++--- spec/models/taxon_concept/boa_constrictor_spec.rb | 2 +- spec/models/trade/annual_report_upload_spec.rb | 2 +- .../trade/reported_taxon_concept_resolver_spec.rb | 4 ++-- spec/shared/boa_constrictor.rb | 4 ++-- spec/shared/caiman_latirostris.rb | 6 +++--- spec/shared/dalbergia.rb | 2 +- spec/support/sapi_helpers.rb | 6 +++--- 46 files changed, 85 insertions(+), 90 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 0d628b5453..17cee90ba4 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -808,11 +808,6 @@ Style/TrailingCommaInLiteral: - 'lib/modules/trade/appendix_report.rb' - 'spec/controllers/cites_trade/shipments_controller_spec.rb' -# Offense count: 98 -# Cop supports --auto-correct. -Style/TrailingWhitespace: - Enabled: false - # Offense count: 7 # Cop supports --auto-correct. Style/UnlessElse: diff --git a/app/controllers/admin/distributions_controller.rb b/app/controllers/admin/distributions_controller.rb index aaf46da5cb..0f5fc269e6 100644 --- a/app/controllers/admin/distributions_controller.rb +++ b/app/controllers/admin/distributions_controller.rb @@ -49,7 +49,7 @@ def create def destroy destroy! do |success, failure| success.html { - redirect_to admin_taxon_concept_distributions_url(@taxon_concept), + redirect_to admin_taxon_concept_distributions_url(@taxon_concept), :notice => 'Operation succeeded' } failure.html { diff --git a/app/controllers/admin/quotas_controller.rb b/app/controllers/admin/quotas_controller.rb index b3b68bf9ef..a85f69218c 100644 --- a/app/controllers/admin/quotas_controller.rb +++ b/app/controllers/admin/quotas_controller.rb @@ -18,7 +18,7 @@ def duplication def duplicate quota_params = params[:quotas].merge(:current_user_id => current_user.id) QuotasCopyWorker.perform_async(quota_params) - redirect_to admin_quotas_path({:year => params[:quotas][:start_date].split("/")[2]}), + redirect_to admin_quotas_path({:year => params[:quotas][:start_date].split("/")[2]}), :notice => "Your quotas are being duplicated in the background. They will be available from this page in a few seconds (please refresh it)" end diff --git a/app/controllers/pages_controller.rb b/app/controllers/pages_controller.rb index 2fd3a8c84e..05f7b383c1 100644 --- a/app/controllers/pages_controller.rb +++ b/app/controllers/pages_controller.rb @@ -1,6 +1,6 @@ class PagesController < ApplicationController layout 'pages' - + def about end diff --git a/app/controllers/trade/statistics_controller.rb b/app/controllers/trade/statistics_controller.rb index 2af1a3e27c..52032bcb07 100644 --- a/app/controllers/trade/statistics_controller.rb +++ b/app/controllers/trade/statistics_controller.rb @@ -18,8 +18,8 @@ def index end def summary_creation - @created_date_selected = if params[:date] - params[:date]['createdDateSelected'].to_i + @created_date_selected = if params[:date] + params[:date]['createdDateSelected'].to_i else Time.now.year end @@ -28,8 +28,8 @@ def summary_creation end def summary_year - @date_selected = if params[:date] - Date.parse("01/01/#{params[:date]['yearSelected']}") + @date_selected = if params[:date] + Date.parse("01/01/#{params[:date]['yearSelected']}") else Date.today end diff --git a/app/models/checklist/csv/history.rb b/app/models/checklist/csv/history.rb index f82aae3e53..db81d03775 100644 --- a/app/models/checklist/csv/history.rb +++ b/app/models/checklist/csv/history.rb @@ -51,7 +51,7 @@ def select_columns "strip_tags(cites_listing_changes_mview.nomenclature_note_en) AS nomenclature_note_en" ] end - + def taxon_concepts_csv_columns [ :id, diff --git a/app/models/checklist/higher_taxa_injector.rb b/app/models/checklist/higher_taxa_injector.rb index b12d9e2577..7e6fd131f8 100644 --- a/app/models/checklist/higher_taxa_injector.rb +++ b/app/models/checklist/higher_taxa_injector.rb @@ -89,7 +89,7 @@ def higher_taxa_headers(prev_item, curr_item) @last_ancestor_ids = @header_ranks.map{ |rank| curr_item.send("#{rank.downcase}_id") } ranks.each_with_index do |rank, idx| higher_taxon_id = curr_item.send("#{rank.downcase}_id") - + unless (prev_item && prev_item.send("#{rank.downcase}_id") == higher_taxon_id && !@expand_headers) higher_taxon = @higher_taxa[higher_taxon_id] if higher_taxon && !(@skip_ancestor_ids && @skip_ancestor_ids.include?(higher_taxon.id)) diff --git a/app/models/checklist/json/history_content.rb b/app/models/checklist/json/history_content.rb index 0a203580e9..f6ce95b193 100644 --- a/app/models/checklist/json/history_content.rb +++ b/app/models/checklist/json/history_content.rb @@ -2,7 +2,7 @@ module Checklist::Json::HistoryContent def content(json_file) json_file << @taxon_concepts_rel.active_model_serializer.new( - @taxon_concepts_rel, + @taxon_concepts_rel, :each_serializer => Checklist::HistoryTaxonConceptSerializer, :authors => @authors ).to_json diff --git a/app/models/checklist/json/index_content.rb b/app/models/checklist/json/index_content.rb index d92a6df65e..fde92ad0c9 100644 --- a/app/models/checklist/json/index_content.rb +++ b/app/models/checklist/json/index_content.rb @@ -2,14 +2,14 @@ module Checklist::Json::IndexContent def content(json_file) json_file << @taxon_concepts_rel.active_model_serializer.new( - @taxon_concepts_rel, + @taxon_concepts_rel, :each_serializer => Checklist::IndexTaxonConceptSerializer, :authors => @authors, :synonyms => @synonyms, :english_names => @english_common_names, :spanish_names => @spanish_common_names, :french_names => @french_common_names - ).to_json + ).to_json end end \ No newline at end of file diff --git a/app/models/designation.rb b/app/models/designation.rb index adceaddfae..f877809ee7 100644 --- a/app/models/designation.rb +++ b/app/models/designation.rb @@ -45,7 +45,7 @@ def can_be_deleted? def self.search(query) if query.present? - where("UPPER(name) LIKE UPPER(:query)", + where("UPPER(name) LIKE UPPER(:query)", :query => "%#{query}%") else scoped diff --git a/app/models/distribution_reference.rb b/app/models/distribution_reference.rb index ed8ee42dd8..1959ffc8b1 100644 --- a/app/models/distribution_reference.rb +++ b/app/models/distribution_reference.rb @@ -13,7 +13,7 @@ class DistributionReference < ActiveRecord::Base track_who_does_it - attr_accessible :reference_id, :distribution_id, :created_by_id, + attr_accessible :reference_id, :distribution_id, :created_by_id, :updated_by_id belongs_to :reference diff --git a/app/models/events_by_type_stats.rb b/app/models/events_by_type_stats.rb index 7cf2f46c21..105863c0bf 100644 --- a/app/models/events_by_type_stats.rb +++ b/app/models/events_by_type_stats.rb @@ -32,5 +32,5 @@ def data ) q SQL ).select([:start_date, :taxon_concept_cnt, :search_cnt]) - end + end end diff --git a/app/models/instrument.rb b/app/models/instrument.rb index 171ff1bf9a..a709adfe54 100644 --- a/app/models/instrument.rb +++ b/app/models/instrument.rb @@ -19,7 +19,7 @@ class Instrument < ActiveRecord::Base def self.search(query) if query.present? - where("UPPER(name) LIKE UPPER(:query)", + where("UPPER(name) LIKE UPPER(:query)", :query => "%#{query}%") else scoped diff --git a/app/models/listing_change.rb b/app/models/listing_change.rb index 94a47182ee..ebb5b6287d 100644 --- a/app/models/listing_change.rb +++ b/app/models/listing_change.rb @@ -31,7 +31,7 @@ class ListingChange < ActiveRecord::Base attr_accessible :taxon_concept_id, :species_listing_id, :change_type_id, :effective_at, :is_current, :parent_id, :geo_entity_ids, :party_listing_distribution_attributes, :inclusion_taxon_concept_id, - :annotation_attributes, :hash_annotation_id, :event_id, + :annotation_attributes, :hash_annotation_id, :event_id, :excluded_geo_entities_ids, :excluded_taxon_concepts_ids, :internal_notes, :nomenclature_note_en, :nomenclature_note_es, :nomenclature_note_fr, :created_by_id, :updated_by_id diff --git a/app/models/nomenclature_change/delete_unreassigned_processor.rb b/app/models/nomenclature_change/delete_unreassigned_processor.rb index c1c596b4c5..48736a06a3 100644 --- a/app/models/nomenclature_change/delete_unreassigned_processor.rb +++ b/app/models/nomenclature_change/delete_unreassigned_processor.rb @@ -10,7 +10,7 @@ def run end def process_unreassigned_distributions - distributions = @input.distribution_reassignments.map{ |dr| + distributions = @input.distribution_reassignments.map{ |dr| dr.reassignable if _is_input_reassignment(dr) }.compact diff --git a/app/models/species_listing.rb b/app/models/species_listing.rb index db8159748f..af6e8ce98c 100644 --- a/app/models/species_listing.rb +++ b/app/models/species_listing.rb @@ -21,9 +21,9 @@ class SpeciesListing < ActiveRecord::Base def self.search(query) if query.present? - where("UPPER(species_listings.name) LIKE UPPER(:query) + where("UPPER(species_listings.name) LIKE UPPER(:query) OR UPPER(species_listings.abbreviation) LIKE UPPER(:query) - OR UPPER(designations.name) LIKE UPPER(:query)", + OR UPPER(designations.name) LIKE UPPER(:query)", :query => "%#{query}%"). joins(:designation) else diff --git a/app/models/taxonomy.rb b/app/models/taxonomy.rb index 03e608a91b..004b68a052 100644 --- a/app/models/taxonomy.rb +++ b/app/models/taxonomy.rb @@ -24,7 +24,7 @@ class Taxonomy < ActiveRecord::Base def self.search(query) if query.present? - where("UPPER(name) LIKE UPPER(:query)", + where("UPPER(name) LIKE UPPER(:query)", :query => "%#{query}%") else scoped diff --git a/app/models/term_trade_codes_pair.rb b/app/models/term_trade_codes_pair.rb index 8a72101f76..56cf75b029 100644 --- a/app/models/term_trade_codes_pair.rb +++ b/app/models/term_trade_codes_pair.rb @@ -20,8 +20,8 @@ class TermTradeCodesPair < ActiveRecord::Base def self.search(query) if query.present? - where("UPPER(trade_codes.code) LIKE UPPER(:query) - OR UPPER(terms.code) LIKE UPPER(:query)", + where("UPPER(trade_codes.code) LIKE UPPER(:query) + OR UPPER(terms.code) LIKE UPPER(:query)", :query => "%#{query}%"). joins(<<-SQL LEFT JOIN trade_codes diff --git a/app/models/trade/filter.rb b/app/models/trade/filter.rb index b19cf7ea61..16b8ba1528 100644 --- a/app/models/trade/filter.rb +++ b/app/models/trade/filter.rb @@ -44,7 +44,7 @@ def initialize_query Rank.in_range(Rank::SPECIES, Rank::SPECIES) end taxon_concepts = MTaxonConcept.where(id: @taxon_concepts_ids) - taxon_concepts_conditions = + taxon_concepts_conditions = taxon_concepts.map do |tc| [:id, tc.id] end + taxon_concepts.select do |tc| @@ -60,7 +60,7 @@ def initialize_query unless @reported_taxon_concepts_ids.empty? cascading_ranks = Rank.in_range(Rank::SPECIES, Rank::KINGDOM) reported_taxon_concepts = MTaxonConcept.where(id: @reported_taxon_concepts_ids) - reported_taxon_concepts_conditions = + reported_taxon_concepts_conditions = reported_taxon_concepts.map do |tc| [:id, tc.id] end + reported_taxon_concepts.select do |tc| diff --git a/app/models/trade/taxon_concept_term_pair.rb b/app/models/trade/taxon_concept_term_pair.rb index ead16dd886..89405fc0c7 100644 --- a/app/models/trade/taxon_concept_term_pair.rb +++ b/app/models/trade/taxon_concept_term_pair.rb @@ -20,14 +20,14 @@ class Trade::TaxonConceptTermPair < ActiveRecord::Base def self.search(query) if query.present? - where("UPPER(taxon_concepts.full_name) LIKE UPPER(:query) - OR UPPER(trade_codes.code) LIKE UPPER(:query)", + where("UPPER(taxon_concepts.full_name) LIKE UPPER(:query) + OR UPPER(trade_codes.code) LIKE UPPER(:query)", :query => "%#{query}%"). joins(<<-SQL - LEFT JOIN taxon_concepts - ON taxon_concepts.id = trade_taxon_concept_term_pairs.taxon_concept_id - LEFT JOIN trade_codes - ON trade_codes.id = trade_taxon_concept_term_pairs.term_id + LEFT JOIN taxon_concepts + ON taxon_concepts.id = trade_taxon_concept_term_pairs.taxon_concept_id + LEFT JOIN trade_codes + ON trade_codes.id = trade_taxon_concept_term_pairs.term_id SQL ) else diff --git a/app/models/trade/validation_rule.rb b/app/models/trade/validation_rule.rb index 849a4f992a..4e9b916f08 100644 --- a/app/models/trade/validation_rule.rb +++ b/app/models/trade/validation_rule.rb @@ -113,7 +113,7 @@ def sanitized_shipments_scope tmp_def[k] = scope_def[k].map{ |value| GeoEntity.find_by_iso_code2(value).id } end tmp_def['blank'] = scope_def['blank'] if scope_def.key?('blank') - res[scope_column + '_id'] = tmp_def + res[scope_column + '_id'] = tmp_def when /(.+)_code$/ tmp_def = {} (scope_def.keys & ['inclusion', 'exclusion']).each do |k| diff --git a/app/models/trade_code.rb b/app/models/trade_code.rb index bf96f30b9c..a2452e78f1 100644 --- a/app/models/trade_code.rb +++ b/app/models/trade_code.rb @@ -21,10 +21,10 @@ class TradeCode < ActiveRecord::Base def self.search(query) if query.present? - where("UPPER(code) LIKE UPPER(:query) + where("UPPER(code) LIKE UPPER(:query) OR UPPER(name_en) LIKE UPPER(:query) OR UPPER(name_fr) LIKE UPPER(:query) - OR UPPER(name_es) LIKE UPPER(:query)", + OR UPPER(name_es) LIKE UPPER(:query)", :query => "%#{query}%") else scoped diff --git a/app/serializers/species/cites_listing_change_serializer.rb b/app/serializers/species/cites_listing_change_serializer.rb index 06ef321534..9db5d68c27 100644 --- a/app/serializers/species/cites_listing_change_serializer.rb +++ b/app/serializers/species/cites_listing_change_serializer.rb @@ -12,7 +12,7 @@ def change_type object.change_type_name.downcase[0] end end - + def is_addition object.change_type_name == ChangeType::ADDITION end diff --git a/app/serializers/species/cms_instruments_serializer.rb b/app/serializers/species/cms_instruments_serializer.rb index b970b7c428..fae3514c65 100644 --- a/app/serializers/species/cms_instruments_serializer.rb +++ b/app/serializers/species/cms_instruments_serializer.rb @@ -1,7 +1,7 @@ class Species::CmsInstrumentsSerializer < ActiveModel::Serializer attributes :effective_from_formatted, :name - def name + def name object.instrument.name end end diff --git a/app/serializers/species/show_taxon_concept_serializer.rb b/app/serializers/species/show_taxon_concept_serializer.rb index 14191b8e21..4404c3448e 100644 --- a/app/serializers/species/show_taxon_concept_serializer.rb +++ b/app/serializers/species/show_taxon_concept_serializer.rb @@ -108,7 +108,7 @@ def distribution_references distributions_with_tags_and_references end - def cache_key + def cache_key key = [ self.class.name, self.id, diff --git a/app/serializers/trade/shipment_from_view_serializer.rb b/app/serializers/trade/shipment_from_view_serializer.rb index 636d1264f6..002304f3e7 100644 --- a/app/serializers/trade/shipment_from_view_serializer.rb +++ b/app/serializers/trade/shipment_from_view_serializer.rb @@ -8,7 +8,7 @@ class Trade::ShipmentFromViewSerializer < ActiveModel::Serializer def taxon_concept { - id: object.taxon_concept_id, + id: object.taxon_concept_id, full_name: object.taxon_concept_full_name + " (#{object.taxon_concept_name_status})", author_year: object.taxon_concept_author_year } @@ -16,7 +16,7 @@ def taxon_concept def reported_taxon_concept { - id: object.reported_taxon_concept_id, + id: object.reported_taxon_concept_id, full_name: object.reported_taxon_concept_full_name + " (#{object.reported_taxon_concept_name_status})", author_year: object.reported_taxon_concept_author_year } diff --git a/db/migrate/20140929092236_add_rank_name_to_sandbox_views.rb b/db/migrate/20140929092236_add_rank_name_to_sandbox_views.rb index 38b98383d6..2b1f818ef2 100644 --- a/db/migrate/20140929092236_add_rank_name_to_sandbox_views.rb +++ b/db/migrate/20140929092236_add_rank_name_to_sandbox_views.rb @@ -48,7 +48,7 @@ def change CASE WHEN aru.point_of_view = ''E'' THEN trading_partner - ELSE geo_entities.iso_code2 + ELSE geo_entities.iso_code2 END AS importer, taxon_concepts.full_name AS accepted_taxon_name, taxon_concepts.data->''rank_name'' AS rank, diff --git a/db/migrate/20141008094314_remove_status_change_from_nomenclature_changes.rb b/db/migrate/20141008094314_remove_status_change_from_nomenclature_changes.rb index 9e2f0f671b..b9ad5a1c6a 100644 --- a/db/migrate/20141008094314_remove_status_change_from_nomenclature_changes.rb +++ b/db/migrate/20141008094314_remove_status_change_from_nomenclature_changes.rb @@ -27,7 +27,7 @@ def up SELECT reassignment_targets.* FROM nomenclature_change_reassignment_targets reassignment_targets JOIN outputs - ON outputs.id = reassignment_targets.nomenclature_change_output_id + ON outputs.id = reassignment_targets.nomenclature_change_output_id ), deleted_reassignment_targets AS ( DELETE FROM nomenclature_change_reassignment_targets USING reassignment_targets diff --git a/lib/capistrano/tasks/config.rake b/lib/capistrano/tasks/config.rake index 3b56925e6e..5cf27ea732 100644 --- a/lib/capistrano/tasks/config.rake +++ b/lib/capistrano/tasks/config.rake @@ -77,7 +77,7 @@ server { passenger_pass_header X-Sendfile-Type; passenger_ruby /home/#{fetch(:deploy_user)}/.rvm/gems/ruby-#{fetch(:rvm_ruby_version)}/wrappers/ruby; - + location ~ ^/downloads/(.*)$ { alias #{deploy_to}/shared/public/downloads/$1; internal; @@ -89,7 +89,7 @@ server { add_header 'Access-Control-Allow-Methods' "GET, POST, PUT, DELETE, OPTIONS"; add_header 'Access-Control-Allow-Headers' "X-Requested-With, X-Prototype-Version"; add_header 'Access-Control-Max-Age' 1728000; - + gzip on; location ~ ^/assets/ { root #{deploy_to}/current/public; @@ -98,7 +98,7 @@ server { add_header ETag ""; break; } - + error_page 503 @503; # Return a 503 error if the maintenance page exists. diff --git a/lib/modules/statistics.rb b/lib/modules/statistics.rb index fc816521aa..432b48af06 100644 --- a/lib/modules/statistics.rb +++ b/lib/modules/statistics.rb @@ -1,17 +1,17 @@ module Statistics - def self.get_total_transactions_per_year + def self.get_total_transactions_per_year trade_transactions = {} years = Trade::Shipment.where("year is not null").uniq.pluck(:year) years.each{ |y| unless y.nil? - reported_by_exporter = Trade::Shipment.where(:year => y, + reported_by_exporter = Trade::Shipment.where(:year => y, :reported_by_exporter => true).count - reported_by_importer = Trade::Shipment.where(:year => y, + reported_by_importer = Trade::Shipment.where(:year => y, :reported_by_exporter => false).count total_transactions = Trade::Shipment.where(:year => y).count - trade_transactions[y] = {:total => total_transactions, - :reported_by_exporter => reported_by_exporter, + trade_transactions[y] = {:total => total_transactions, + :reported_by_exporter => reported_by_exporter, :reported_by_importer => reported_by_importer} end } diff --git a/lib/scripts/get_listed_species_per_country.rb b/lib/scripts/get_listed_species_per_country.rb index 8d718ad101..6c9537e49a 100644 --- a/lib/scripts/get_listed_species_per_country.rb +++ b/lib/scripts/get_listed_species_per_country.rb @@ -9,12 +9,12 @@ countries.each do |country| [:cites_eu, :cms].each do |taxonomy| params = { - :taxonomy=>taxonomy.to_s, :taxon_concept_query=>"", + :taxonomy=>taxonomy.to_s, :taxon_concept_query=>"", :geo_entities_ids=>["#{country.id}"], :page=>"1" } search = Species::Search.new(params) - result = { - :iso_2 => country.iso_code2, + result = { + :iso_2 => country.iso_code2, :total_listed_species => search.results.count } results[taxonomy] << result diff --git a/lib/tasks/bbgem.rake b/lib/tasks/bbgem.rake index f91cdb0cf8..dd64e7e349 100644 --- a/lib/tasks/bbgem.rake +++ b/lib/tasks/bbgem.rake @@ -1,5 +1,5 @@ # Generated with 'brightbox' on 2013-06-27 08:45:55 +0100 -unless Rake::Task.task_defined?("db:create") +unless Rake::Task.task_defined?("db:create") namespace(:db) do task :create do puts "This is a dummy task installed by the Brightbox command" @@ -9,7 +9,7 @@ task :create do end end end -unless Rake::Task.task_defined?("db:check:config") +unless Rake::Task.task_defined?("db:check:config") def rails_env if defined?(Rails) and Rails.respond_to? :env @@ -37,7 +37,7 @@ elsif db && db !~ /\A#{config['username']}/ pe "database name should start with '#{config['username']}' if using cluster" end end - + require 'yaml' def read_database_yml diff --git a/lib/tasks/import_cites_listings.rake b/lib/tasks/import_cites_listings.rake index 5149bebf08..857c198bb6 100644 --- a/lib/tasks/import_cites_listings.rake +++ b/lib/tasks/import_cites_listings.rake @@ -236,16 +236,16 @@ namespace :import do # Acipenser fulvescens, Incilius periglenes sql = <<-SQL WITH explicit_not_current_deletions AS ( - SELECT listing_changes.* FROM taxon_concepts - JOIN listing_changes ON listing_changes.taxon_concept_id = taxon_concepts.id + SELECT listing_changes.* FROM taxon_concepts + JOIN listing_changes ON listing_changes.taxon_concept_id = taxon_concepts.id AND change_type_id = #{d.id} AND effective_at = '1983-07-29' - WHERE taxonomy_id = #{taxonomy.id} + WHERE taxonomy_id = #{taxonomy.id} AND legacy_type = 'Animalia' and legacy_id = 223 UNION - SELECT listing_changes.* FROM taxon_concepts - JOIN listing_changes ON listing_changes.taxon_concept_id = taxon_concepts.id + SELECT listing_changes.* FROM taxon_concepts + JOIN listing_changes ON listing_changes.taxon_concept_id = taxon_concepts.id AND change_type_id = #{d.id} AND effective_at = '1985-08-01' - WHERE taxonomy_id = #{taxonomy.id} + WHERE taxonomy_id = #{taxonomy.id} AND legacy_type = 'Animalia' and legacy_id = 3172 ) UPDATE listing_changes SET explicit_change = TRUE diff --git a/lib/tasks/import_cites_parties.rake b/lib/tasks/import_cites_parties.rake index 460d0c97a2..0784daed98 100644 --- a/lib/tasks/import_cites_parties.rake +++ b/lib/tasks/import_cites_parties.rake @@ -14,7 +14,7 @@ namespace :import do ON designations.name = '#{Designation::CITES}' EXCEPT SELECT q.designation_id, q.geo_entity_id FROM designation_geo_entities q - INNER JOIN designations ON q.designation_id = designations.id + INNER JOIN designations ON q.designation_id = designations.id WHERE designations.name = '#{Designation::CITES}' ) AS subquery SQL diff --git a/lib/tasks/import_cites_quotas.rake b/lib/tasks/import_cites_quotas.rake index 614a8a6389..f5afdc7169 100644 --- a/lib/tasks/import_cites_quotas.rake +++ b/lib/tasks/import_cites_quotas.rake @@ -37,7 +37,7 @@ namespace :import do INSERT INTO trade_restrictions(is_current, start_date, end_date, geo_entity_id, quota, publication_date, notes, type, unit_id, taxon_concept_id, public_display, url, created_at, updated_at, import_row_id) SELECT DISTINCT #{TMP_TABLE}_view.is_current, start_date, end_date, geo_entities.id, quota, publication_date, - #{TMP_TABLE}_view.notes, 'Quota', units.id, taxon_concepts.id, public_display, url, + #{TMP_TABLE}_view.notes, 'Quota', units.id, taxon_concepts.id, public_display, url, CASE WHEN #{TMP_TABLE}_view.created_at IS NULL THEN current_date ELSE #{TMP_TABLE}_view.created_at @@ -53,7 +53,7 @@ namespace :import do UPPER(taxon_concepts.legacy_type) = UPPER(BTRIM(#{TMP_TABLE}_view.kingdom)) AND taxon_concepts.taxonomy_id = #{taxonomy_id} AND taxon_concepts.rank_id = ranks.id LEFT JOIN trade_codes AS units ON UPPER(units.code) = UPPER(BTRIM(#{TMP_TABLE}_view.unit)) AND units.type = 'Unit' - WHERE taxon_concepts.id IS NOT NULL AND geo_entities.id IS NOT NULL + WHERE taxon_concepts.id IS NOT NULL AND geo_entities.id IS NOT NULL SQL ActiveRecord::Base.connection.execute(sql) diff --git a/lib/tasks/import_standard_reference_links.rake b/lib/tasks/import_standard_reference_links.rake index 5039dd1807..2cdf32801b 100644 --- a/lib/tasks/import_standard_reference_links.rake +++ b/lib/tasks/import_standard_reference_links.rake @@ -66,14 +66,14 @@ namespace :import do sql = <<-SQL WITH standard_references_as_ids AS ( WITH standard_references_per_exclusion AS ( - SELECT rank, taxon_legacy_id, ref_legacy_id, '#{kingdom}'::VARCHAR AS legacy_type, is_cascaded, + SELECT rank, taxon_legacy_id, ref_legacy_id, '#{kingdom}'::VARCHAR AS legacy_type, is_cascaded, CASE WHEN exclusions IS NULL THEN NULL ELSE split_part(regexp_split_to_table(exclusions,','),':',1) END AS exclusion_rank, CASE WHEN exclusions IS NULL THEN NULL ELSE split_part(regexp_split_to_table(exclusions,','),':',2) END AS exclusion_legacy_id FROM #{TMP_TABLE} ) SELECT taxon_concepts.id AS taxon_concept_id, ARRAY_AGG(exclusion_taxon_concepts.id)::VARCHAR AS exclusions, - "references".id AS reference_id, + "references".id AS reference_id, is_cascaded FROM standard_references_per_exclusion INNER JOIN ranks @@ -96,7 +96,7 @@ namespace :import do GROUP BY taxon_concept_id, reference_id, is_cascaded ) UPDATE taxon_concept_references SET is_standard = TRUE, - is_cascaded = + is_cascaded = CASE WHEN standard_references_as_ids.is_cascaded IS NOT NULL THEN standard_references_as_ids.is_cascaded diff --git a/lib/tasks/import_synonyms.rake b/lib/tasks/import_synonyms.rake index d71f5609d7..df12c86b3f 100644 --- a/lib/tasks/import_synonyms.rake +++ b/lib/tasks/import_synonyms.rake @@ -63,7 +63,7 @@ namespace :import do end } - EXCEPT + EXCEPT SELECT taxon_concept_id, other_taxon_concept_id FROM taxon_relationships diff --git a/spec/models/checklist/appendix_population_and_region_spec.rb b/spec/models/checklist/appendix_population_and_region_spec.rb index 15ca358fcd..33c7185295 100644 --- a/spec/models/checklist/appendix_population_and_region_spec.rb +++ b/spec/models/checklist/appendix_population_and_region_spec.rb @@ -1,7 +1,7 @@ #Encoding: UTF-8 require 'spec_helper' -describe Checklist do +describe Checklist do include_context "Pecari tajacu" context "search by cites populations" do diff --git a/spec/models/checklist/pdf/index_fetcher_spec.rb b/spec/models/checklist/pdf/index_fetcher_spec.rb index 23f4156caf..fb7ca1243b 100644 --- a/spec/models/checklist/pdf/index_fetcher_spec.rb +++ b/spec/models/checklist/pdf/index_fetcher_spec.rb @@ -1,12 +1,12 @@ require 'spec_helper' describe Checklist::Pdf::IndexFetcher do - let(:en){ + let(:en){ create(:language, :name_en => 'French', :iso_code1 => 'FR', :iso_code3 => 'FRA') create(:language, :name_en => 'Spanish', :iso_code1 => 'ES', :iso_code3 => 'SPA') create(:language, :name_en => 'English', :iso_code1 => 'EN', :iso_code3 => 'ENG') } - let(:es){ + let(:es){ Language.find_by_name_en("Spanish") } @@ -17,7 +17,7 @@ :language => en ) } - let(:spanish_common_name){ + let(:spanish_common_name){ create( :common_name, :name => 'Lolgato domestico', diff --git a/spec/models/taxon_concept/boa_constrictor_spec.rb b/spec/models/taxon_concept/boa_constrictor_spec.rb index 20b2c5518b..25d0bd981a 100644 --- a/spec/models/taxon_concept/boa_constrictor_spec.rb +++ b/spec/models/taxon_concept/boa_constrictor_spec.rb @@ -69,7 +69,7 @@ end context "for subspecies Boa constrictor constrictor" do specify{ @subspecies2.cites_listed.should be_false } - end + end end describe :cites_show do diff --git a/spec/models/trade/annual_report_upload_spec.rb b/spec/models/trade/annual_report_upload_spec.rb index 3e967b3e7a..ff5af97392 100644 --- a/spec/models/trade/annual_report_upload_spec.rb +++ b/spec/models/trade/annual_report_upload_spec.rb @@ -99,7 +99,7 @@ def invalid_file specify{ subject.validation_errors.should be_empty } end - describe :create do + describe :create do before(:each){ Trade::CsvSourceFileUploader.enable_processing = true } context "when blank lines in import file" do subject{ diff --git a/spec/models/trade/reported_taxon_concept_resolver_spec.rb b/spec/models/trade/reported_taxon_concept_resolver_spec.rb index 91519b7b5e..e2e1c9a160 100644 --- a/spec/models/trade/reported_taxon_concept_resolver_spec.rb +++ b/spec/models/trade/reported_taxon_concept_resolver_spec.rb @@ -12,7 +12,7 @@ :taxon_concept => @accepted_name, :other_taxon_concept => @trade_name, :taxon_relationship_type => trade_name_relationship_type - ) + ) end let(:resolver){ Trade::ReportedTaxonConceptResolver.new(@trade_name.id) @@ -31,7 +31,7 @@ :taxon_concept => @accepted_name, :other_taxon_concept => @synonym, :taxon_relationship_type => synonym_relationship_type - ) + ) end let(:resolver){ Trade::ReportedTaxonConceptResolver.new(@synonym.id) diff --git a/spec/shared/boa_constrictor.rb b/spec/shared/boa_constrictor.rb index 2a3f061e6f..e48ffbed33 100644 --- a/spec/shared/boa_constrictor.rb +++ b/spec/shared/boa_constrictor.rb @@ -1,8 +1,8 @@ shared_context "Boa constrictor" do let(:en){ create(:language, :name => 'Spanish', :iso_code1 => 'ES', :iso_code3 => 'SPA') - create(:language, :name => 'French', :iso_code1 => 'FR', :iso_code3 => 'FRA') - create(:language, :name => 'English', :iso_code1 => 'EN', :iso_code3 => 'ENG') + create(:language, :name => 'French', :iso_code1 => 'FR', :iso_code3 => 'FRA') + create(:language, :name => 'English', :iso_code1 => 'EN', :iso_code3 => 'ENG') } before(:all) do @order = create_cites_eu_order( diff --git a/spec/shared/caiman_latirostris.rb b/spec/shared/caiman_latirostris.rb index 45ffe3e857..56da7aa9ac 100644 --- a/spec/shared/caiman_latirostris.rb +++ b/spec/shared/caiman_latirostris.rb @@ -1,10 +1,10 @@ #Encoding: utf-8 shared_context "Caiman latirostris" do - let(:en){ + let(:en){ create(:language, :name => 'Spanish', :iso_code1 => 'ES', :iso_code3 => 'SPA') - create(:language, :name => 'French', :iso_code1 => 'FR', :iso_code3 => 'FRA') - create(:language, :name => 'English', :iso_code1 => 'EN', :iso_code3 => 'ENG') + create(:language, :name => 'French', :iso_code1 => 'FR', :iso_code3 => 'FRA') + create(:language, :name => 'English', :iso_code1 => 'EN', :iso_code3 => 'ENG') } let(:argentina){ create( diff --git a/spec/shared/dalbergia.rb b/spec/shared/dalbergia.rb index 217a5763dd..bf9b19f909 100644 --- a/spec/shared/dalbergia.rb +++ b/spec/shared/dalbergia.rb @@ -57,7 +57,7 @@ :effective_at => '2013-06-12', :is_current => true ) - + create( :listing_distribution, :listing_change => cites_lc, diff --git a/spec/support/sapi_helpers.rb b/spec/support/sapi_helpers.rb index 812f206788..1ae71be178 100644 --- a/spec/support/sapi_helpers.rb +++ b/spec/support/sapi_helpers.rb @@ -27,18 +27,18 @@ end end end - d + d } let(:eu){ d = Designation.find_by_taxonomy_id_and_name(cites_eu.id, Designation::EU) unless d d = create(:designation, :name => Designation::EU, :taxonomy => cites_eu) - %w(ADDITION DELETION RESERVATION RESERVATION_WITHDRAWAL EXCEPTION).each do |ch| + %w(ADDITION DELETION RESERVATION RESERVATION_WITHDRAWAL EXCEPTION).each do |ch| unless ChangeType.find_by_designation_id_and_name(d.id, ch) create(:change_type, :name => ch, :designation => d) end - %w(A B C D).each do |app| + %w(A B C D).each do |app| unless SpeciesListing.find_by_designation_id_and_abbreviation(d.id, app) create( :species_listing, :name => "Annex #{app}", :abbreviation => app, From 001ebc90d4acbeedf9bfe101613f6a3426484e3a Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 3 Jun 2016 15:49:25 +0100 Subject: [PATCH 297/365] Removed trailing comma in literals --- .rubocop_todo.yml | 11 ----------- app/controllers/admin/iucn_mappings_controller.rb | 2 +- config/deploy.rb | 2 +- lib/modules/trade/appendix_report.rb | 2 +- .../cites_trade/shipments_controller_spec.rb | 8 ++++---- 5 files changed, 7 insertions(+), 18 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 17cee90ba4..29fb425907 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -797,17 +797,6 @@ Style/TrailingCommaInArguments: - 'spec/models/taxon_concept/validation_spec.rb' - 'spec/shared/colophon.rb' -# Offense count: 7 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyleForMultiline, SupportedStyles. -# SupportedStyles: comma, consistent_comma, no_comma -Style/TrailingCommaInLiteral: - Exclude: - - 'app/controllers/admin/iucn_mappings_controller.rb' - - 'config/deploy.rb' - - 'lib/modules/trade/appendix_report.rb' - - 'spec/controllers/cites_trade/shipments_controller_spec.rb' - # Offense count: 7 # Cop supports --auto-correct. Style/UnlessElse: diff --git a/app/controllers/admin/iucn_mappings_controller.rb b/app/controllers/admin/iucn_mappings_controller.rb index d48297c7ab..a32b5ca22a 100644 --- a/app/controllers/admin/iucn_mappings_controller.rb +++ b/app/controllers/admin/iucn_mappings_controller.rb @@ -10,7 +10,7 @@ def index :non_matching => IucnMapping.filter("NON_MATCHING").count, :synonyms => IucnMapping.filter('SYNONYMS').count, :accepted => IucnMapping.filter('ACCEPTED').count, - :all => IucnMapping.count, + :all => IucnMapping.count } end diff --git a/config/deploy.rb b/config/deploy.rb index f2b5bbd5de..5ba1a35cd8 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -30,7 +30,7 @@ set :pty, true set :ssh_options, { - forward_agent: true, + forward_agent: true } before "deploy:symlink:shared", "rsync:sync" diff --git a/lib/modules/trade/appendix_report.rb b/lib/modules/trade/appendix_report.rb index 5bd507cbc4..9be1573aed 100644 --- a/lib/modules/trade/appendix_report.rb +++ b/lib/modules/trade/appendix_report.rb @@ -39,7 +39,7 @@ def export(file_path, diff = false) export_to_csv( :query => (diff ? @diff_query : @query), :csv_columns => [ - 'ID', 'Legacy Shipment ID', 'Taxon ID', 'Accepted Taxon', 'Year', 'Appendix', 'Auto Appendix', + 'ID', 'Legacy Shipment ID', 'Taxon ID', 'Accepted Taxon', 'Year', 'Appendix', 'Auto Appendix' ], :file_path => file_path, :encoding => 'latin1', diff --git a/spec/controllers/cites_trade/shipments_controller_spec.rb b/spec/controllers/cites_trade/shipments_controller_spec.rb index 50d5df0b0b..3c24bb073d 100644 --- a/spec/controllers/cites_trade/shipments_controller_spec.rb +++ b/spec/controllers/cites_trade/shipments_controller_spec.rb @@ -8,19 +8,19 @@ context "serializer" do it "should return comptab export when report_type invalid" do get :index, filters: { - report_type: 'raw', + report_type: 'raw' }, format: :json response.body.should have_json_path('shipment_comptab_export') end it "should return comptab export when report_type = comptab" do get :index, filters: { - report_type: 'comptab', + report_type: 'comptab' }, format: :json response.body.should have_json_path('shipment_comptab_export') end it "should return gross net export when report_type = gross_exports" do get :index, filters: { - report_type: 'gross_exports', + report_type: 'gross_exports' }, format: :json response.body.should have_json_path('shipment_gross_net_export') end @@ -33,7 +33,7 @@ get :index, filters: { report_type: 'gross_exports', time_range_start: 2012, - time_range_end: 2013, + time_range_end: 2013 }, format: :json response.body.should have_json_size(4).at_path('shipment_gross_net_export/rows') end From 65b43d1ad495620408ba8356ab1e9a8bd719abfa Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 3 Jun 2016 15:50:52 +0100 Subject: [PATCH 298/365] Avoid comma after the last parameter of a method call --- .rubocop_todo.yml | 10 ---------- spec/models/checklist/pdf/index_fetcher_spec.rb | 2 +- spec/shared/colophon.rb | 4 ++-- 3 files changed, 3 insertions(+), 13 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 29fb425907..2b9c6bae0a 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -787,16 +787,6 @@ Style/Tab: Style/TrailingBlankLines: Enabled: false -# Offense count: 5 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyleForMultiline, SupportedStyles. -# SupportedStyles: comma, consistent_comma, no_comma -Style/TrailingCommaInArguments: - Exclude: - - 'spec/models/checklist/pdf/index_fetcher_spec.rb' - - 'spec/models/taxon_concept/validation_spec.rb' - - 'spec/shared/colophon.rb' - # Offense count: 7 # Cop supports --auto-correct. Style/UnlessElse: diff --git a/spec/models/checklist/pdf/index_fetcher_spec.rb b/spec/models/checklist/pdf/index_fetcher_spec.rb index fb7ca1243b..170c1e737f 100644 --- a/spec/models/checklist/pdf/index_fetcher_spec.rb +++ b/spec/models/checklist/pdf/index_fetcher_spec.rb @@ -61,7 +61,7 @@ :taxon_relationship, :taxon_relationship_type => synonym_relationship_type, :taxon_concept_id => tc.id, - :other_taxon_concept_id => synonym.id, + :other_taxon_concept_id => synonym.id ) Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings } diff --git a/spec/shared/colophon.rb b/spec/shared/colophon.rb index 5b2e6d4270..65a114798c 100644 --- a/spec/shared/colophon.rb +++ b/spec/shared/colophon.rb @@ -20,11 +20,11 @@ ) @genus = create_cites_eu_genus( :taxon_name => create(:taxon_name, :scientific_name => 'Colophon'), - :parent => @family, + :parent => @family ) @species = create_cites_eu_species( :taxon_name => create(:taxon_name, :scientific_name => 'barnardi'), - :parent => @genus, + :parent => @genus ) cites_lc = create_cites_III_addition( From 1269e9063f02299a60348587e2849a5b627893b9 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 10 Jun 2016 10:15:51 +0100 Subject: [PATCH 299/365] fixed post-merge style issues --- .rubocop.yml | 10 +- .rubocop_todo.yml | 2 + .../admin/simple_crud_controller.rb | 40 ++++---- .../admin/taxon_concepts_controller.rb | 93 ++++++++++--------- .../checklist/geo_entities_controller.rb | 2 +- .../admin/nomenclature_changes_helper.rb | 27 +++--- app/models/geo_entity_search.rb | 15 +-- .../cascading_notes_processor.rb | 11 ++- app/models/nomenclature_change/output.rb | 26 +++--- .../reassignment_copy_processor.rb | 1 - .../reassignment_summarizer.rb | 51 +++++----- .../reassignment_transfer_processor.rb | 11 +-- .../nomenclature_change/split/processor.rb | 2 +- .../status_downgrade_processor.rb | 1 - .../status_swap/processor.rb | 15 +-- .../taxonomic_tree_name_resolver.rb | 22 +++-- app/models/taxon_concept.rb | 62 +++++++------ app/models/taxon_concept_observer.rb | 45 ++++----- app/workers/update_taxonomy_worker.rb | 1 - config/routes.rb | 2 +- ...53_add_empty_string_as_default_to_notes.rb | 2 +- lib/modules/search_cache.rb | 3 +- .../status_swap_controller_spec.rb | 24 +++-- .../status_to_accepted_controller_spec.rb | 16 ++-- .../status_to_synonym_controller_spec.rb | 16 ++-- .../admin/taxon_concepts_controller_spec.rb | 4 +- spec/factories/ranks.rb | 26 +++--- spec/models/hybrid_relationship_spec.rb | 2 +- .../shared/split_definitions.rb | 3 +- .../status_swap/processor_spec.rb | 1 - spec/models/taxon_concept/validation_spec.rb | 4 +- .../taxon_concept_prefix_matcher_spec.rb | 32 ++++--- 32 files changed, 313 insertions(+), 259 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 61803c48ec..9b24992118 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -2,6 +2,10 @@ inherit_from: .rubocop_todo.yml AllCops: TargetRubyVersion: 2.2 + Exclude: + - 'lib/tasks/bbgem.rake' + - 'db/schema.rb' + - 'old_cap/*' Style/StringLiterals: EnforcedStyle: single_quotes @@ -26,9 +30,8 @@ Style/IndentHash: Style/IndentationConsistency: EnforcedStyle: normal Exclude: - - 'lib/tasks/bbgem.rake' - 'db/migrate/*' - - 'old_cap/*' + - 'config/initializers/normalise_blank_values.rb' # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: symmetrical, new_line, same_line @@ -44,7 +47,6 @@ Style/MultilineHashBraceLayout: # SupportedStyles: always, conditionals Style/AndOr: Exclude: - - 'lib/tasks/bbgem.rake' - 'db/migrate/*' # Offense count: 551 @@ -68,6 +70,4 @@ Style/FirstParameterIndentation: # Configuration parameters: Width. Style/IndentationWidth: Exclude: - - 'lib/tasks/bbgem.rake' - 'db/migrate/*' - - 'old_cap/*' diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 2b9c6bae0a..4221d69942 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -19,6 +19,7 @@ Lint/AmbiguousOperator: # Configuration parameters: AllowSafeAssignment. Lint/AssignmentInCondition: Exclude: + - 'app/models/nomenclature_change/output.rb' - 'lib/tasks/bbgem.rake' # Offense count: 21 @@ -766,6 +767,7 @@ Style/SymbolProc: - 'app/serializers/trade/show_annual_report_upload_serializer.rb' - 'lib/tasks/db_migrate_plpgsql.rake' - 'lib/tasks/elibrary/importable.rb' + - 'spec/factories/ranks.rb' - 'spec/models/nomenclature_change/lump/constructor_spec.rb' - 'spec/models/nomenclature_change/split/constructor_spec.rb' diff --git a/app/controllers/admin/simple_crud_controller.rb b/app/controllers/admin/simple_crud_controller.rb index 00e8ecae72..1f55d6bb84 100644 --- a/app/controllers/admin/simple_crud_controller.rb +++ b/app/controllers/admin/simple_crud_controller.rb @@ -27,7 +27,8 @@ def destroy success.html { redirect_to collection_url, :notice => 'Operation succeeded' } failure.html { redirect_to collection_url, - :alert => if resource.errors.present? + :alert => + if resource.errors.present? "Operation #{resource.errors.messages[:base].join(", ")}" else "Operation failed" @@ -37,23 +38,26 @@ def destroy end protected - def load_associations; end - - def load_search - load_taxonomies - @taxon_concept ||= TaxonConcept.find(params[:taxon_concept_id]) - @search_params = SearchParams.new( - { :taxonomy => { :id => @taxon_concept.taxonomy_id }, - :scientific_name => @taxon_concept.full_name, - :name_status => @taxon_concept.name_status - }) - end - def load_taxonomies - @taxonomies ||= Taxonomy.order(:name) - end + def load_associations; end - def load_ranks - @ranks = Rank.order(:taxonomic_position) - end + def load_search + load_taxonomies + @taxon_concept ||= TaxonConcept.find(params[:taxon_concept_id]) + @search_params = SearchParams.new( + { + :taxonomy => { :id => @taxon_concept.taxonomy_id }, + :scientific_name => @taxon_concept.full_name, + :name_status => @taxon_concept.name_status + } + ) + end + + def load_taxonomies + @taxonomies ||= Taxonomy.order(:name) + end + + def load_ranks + @ranks = Rank.order(:taxonomic_position) + end end diff --git a/app/controllers/admin/taxon_concepts_controller.rb b/app/controllers/admin/taxon_concepts_controller.rb index 1d98bec79c..9dae748f30 100644 --- a/app/controllers/admin/taxon_concepts_controller.rb +++ b/app/controllers/admin/taxon_concepts_controller.rb @@ -76,57 +76,62 @@ def autocomplete end protected - # used in create - def collection - @taxon_concepts ||= end_of_association_chain.where(:name_status => 'A'). - includes([:rank, :taxonomy, :taxon_name, :parent]). - order(:taxonomic_position).page(params[:page]) - end - def determine_layout - action_name == 'index' ? 'admin' : 'taxon_concepts' - end + # used in create + def collection + @taxon_concepts ||= end_of_association_chain.where(:name_status => 'A'). + includes([:rank, :taxonomy, :taxon_name, :parent]). + order(:taxonomic_position).page(params[:page]) + end - def sanitize_search_params - @search_params = SearchParams.new( - params[:search_params] || - { :taxonomy => { :id => Taxonomy. - where(:name => Taxonomy::CITES_EU).limit(1).select(:id).first.id } - }) - end + def determine_layout + action_name == 'index' ? 'admin' : 'taxon_concepts' + end - def load_tags - @tags = PresetTag.where(:model => PresetTag::TYPES[:TaxonConcept]) - end + def sanitize_search_params + @search_params = SearchParams.new( + params[:search_params] || + { + :taxonomy => { + :id => Taxonomy.where(:name => Taxonomy::CITES_EU).limit(1). + select(:id).first.id + } + } + ) + end - def split_stringified_ids_lists - return true if !params[:taxon_concept] || !params[:taxon_concept][:name_status] - ids_list_key = case params[:taxon_concept][:name_status] - when 'S' then :accepted_names_ids - when 'T' then :accepted_names_for_trade_name_ids - when 'H' then :hybrid_parents_ids - else nil - end - if ids_list_key && - params[:taxon_concept].has_key?(ids_list_key) && - (stringified_ids_list = params[:taxon_concept][ids_list_key]) && - stringified_ids_list.is_a?(String) - params[:taxon_concept][ids_list_key] = stringified_ids_list.split(',').map(&:to_i) + def load_tags + @tags = PresetTag.where(:model => PresetTag::TYPES[:TaxonConcept]) + end + + def split_stringified_ids_lists + return true if !params[:taxon_concept] || !params[:taxon_concept][:name_status] + ids_list_key = + case params[:taxon_concept][:name_status] + when 'S' then :accepted_names_ids + when 'T' then :accepted_names_for_trade_name_ids + when 'H' then :hybrid_parents_ids end + if ids_list_key && + params[:taxon_concept].key?(ids_list_key) && + (stringified_ids_list = params[:taxon_concept][ids_list_key]) && + stringified_ids_list.is_a?(String) + params[:taxon_concept][ids_list_key] = stringified_ids_list.split(',').map(&:to_i) end + end - def render_new_by_name_status - if @taxon_concept.is_synonym? - render('new_synonym') - elsif @taxon_concept.is_hybrid? - render('new_hybrid') - elsif @taxon_concept.is_trade_name? - render('new_trade_name') - elsif @taxon_concept.name_status == 'N' - render('new_n_name') - else - render('new') - end + def render_new_by_name_status + if @taxon_concept.is_synonym? + render('new_synonym') + elsif @taxon_concept.is_hybrid? + render('new_hybrid') + elsif @taxon_concept.is_trade_name? + render('new_trade_name') + elsif @taxon_concept.name_status == 'N' + render('new_n_name') + else + render('new') end + end end diff --git a/app/controllers/checklist/geo_entities_controller.rb b/app/controllers/checklist/geo_entities_controller.rb index 97e259d1d1..12f3ded3e9 100644 --- a/app/controllers/checklist/geo_entities_controller.rb +++ b/app/controllers/checklist/geo_entities_controller.rb @@ -10,6 +10,7 @@ def index end private + # this disables json root for this controller # remove when checklist frontend upgraded to new Ember.js def default_serializer_options @@ -17,5 +18,4 @@ def default_serializer_options root: false } end - end diff --git a/app/helpers/admin/nomenclature_changes_helper.rb b/app/helpers/admin/nomenclature_changes_helper.rb index c9d9509e41..c7936af268 100644 --- a/app/helpers/admin/nomenclature_changes_helper.rb +++ b/app/helpers/admin/nomenclature_changes_helper.rb @@ -31,7 +31,7 @@ def progress_bar end end - def print_summary summary + def print_summary(summary) if summary.kind_of?(Array) content_tag(:ul) do summary.each{ |line| concat print_summary(line) } @@ -140,17 +140,18 @@ def global_selection(checked = true) html.html_safe end - def outputs_selection ff - ff.object.output_type ||= if ff.object.taxon_concept_id.nil? - 'new_taxon' - elsif ff.object.taxon_concept && - !ff.object.new_scientific_name.blank? && - ff.object.taxon_concept.full_name != ff.object.new_scientific_name - # this scenario occurrs when an existing taxon will change name - 'existing_subspecies' - else - 'existing_taxon' - end + def outputs_selection(ff) + ff.object.output_type ||= + if ff.object.taxon_concept_id.nil? + 'new_taxon' + elsif ff.object.taxon_concept && + !ff.object.new_scientific_name.blank? && + ff.object.taxon_concept.full_name != ff.object.new_scientific_name + # this scenario occurrs when an existing taxon will change name + 'existing_subspecies' + else + 'existing_taxon' + end content_tag(:div, class: 'outputs_selection') do ['New taxon', 'Existing subspecies', 'Existing taxon'].each do |opt| opt_val = opt.downcase.gsub(/\s+/, '_') @@ -318,7 +319,7 @@ def select_outputs end end - def sorted_parent_reassignments ff + def sorted_parent_reassignments(ff) ff.object.parent_reassignments.sort_by{ |reassignment| reassignment.reassignable.full_name } end diff --git a/app/models/geo_entity_search.rb b/app/models/geo_entity_search.rb index 7b5543664b..b7ac002043 100644 --- a/app/models/geo_entity_search.rb +++ b/app/models/geo_entity_search.rb @@ -14,17 +14,18 @@ def results private def initialize_params(options) - @geo_entity_types_set = GeoEntityType::SETS.has_key?( + @geo_entity_types_set = GeoEntityType::SETS.key?( options[:geo_entity_types_set] ) && options[:geo_entity_types_set] || GeoEntityType::DEFAULT_SET - @locale = if options[:locale] && - ['en', 'es', 'fr'].include?(options[:locale].downcase) - options[:locale] - else - I18n.locale - end + @locale = + if options[:locale] && + ['en', 'es', 'fr'].include?(options[:locale].downcase) + options[:locale] + else + I18n.locale + end @options = { geo_entity_types_set: @geo_entity_types_set, locale: @locale diff --git a/app/models/nomenclature_change/cascading_notes_processor.rb b/app/models/nomenclature_change/cascading_notes_processor.rb index eeb9811c29..f8d2fe69d9 100644 --- a/app/models/nomenclature_change/cascading_notes_processor.rb +++ b/app/models/nomenclature_change/cascading_notes_processor.rb @@ -5,11 +5,12 @@ def initialize(input_or_output) end def run - @taxon_concept = if @input_or_output.kind_of? NomenclatureChange::Output - @input_or_output.new_taxon_concept || @input_or_output.taxon_concept - else - @input_or_output.taxon_concept - end + @taxon_concept = + if @input_or_output.kind_of? NomenclatureChange::Output + @input_or_output.new_taxon_concept || @input_or_output.taxon_concept + else + @input_or_output.taxon_concept + end return false unless @taxon_concept descendents_for_note_cascading(@taxon_concept).each do |d| Rails.logger.debug("Processing note for descendant #{d.full_name} of input #{@taxon_concept.full_name}") diff --git a/app/models/nomenclature_change/output.rb b/app/models/nomenclature_change/output.rb index 6825b84034..8f0534bb55 100644 --- a/app/models/nomenclature_change/output.rb +++ b/app/models/nomenclature_change/output.rb @@ -82,7 +82,6 @@ class NomenclatureChange::Output < ActiveRecord::Base before_validation :populate_taxon_concept_fields, :if => Proc.new { |c| (c.new_record? || c.taxon_concept_id_changed?) && c.taxon_concept } - def tag_list parse_pg_array(read_attribute(:tag_list)||"").compact end @@ -91,7 +90,6 @@ def tag_list=(ary) write_attribute(:tag_list, "{#{ary && ary.join(',')}}") end - def populate_taxon_concept_fields self.parent_id = taxon_concept.parent_id_changed? ? taxon_concept.parent_id_was : taxon_concept.parent_id self.rank_id = taxon_concept.rank_id_changed? ? taxon_concept.rank_id_was : taxon_concept.rank_id @@ -138,11 +136,12 @@ def will_update_taxon? def tmp_taxon_concept name_status_to_save = (new_name_status.present? ? new_name_status : name_status) - scientific_name = if ['A', 'N'].include?(name_status_to_save) - display_full_name.split.last - else - display_full_name - end + scientific_name = + if ['A', 'N'].include?(name_status_to_save) + display_full_name.split.last + else + display_full_name + end taxon_concept_attrs = { parent_id: new_parent_id || parent_id, rank_id: new_rank_id || rank_id, @@ -152,9 +151,12 @@ def tmp_taxon_concept } if will_create_taxon? - taxonomy = (taxonomy_id.present? ? Taxonomy.find(taxonomy_id) : - Taxonomy.find_by_name(Taxonomy::CITES_EU) - ) + taxonomy = + if taxonomy_id.present? + Taxonomy.find(taxonomy_id) + else + Taxonomy.find_by_name(Taxonomy::CITES_EU) + end TaxonConcept.new( taxon_concept_attrs.merge({ taxonomy_id: taxonomy.id, @@ -186,14 +188,14 @@ def expected_parent_name if rank.name == Rank::SPECIES display_full_name.split[0] elsif [Rank::SUBSPECIES, Rank::VARIETY].include?(rank.name) - display_full_name.split[0..1].join (' ') + display_full_name.split[0..1].join ' ' else nil end end def default_parent - if ['S', 'T'].include? name_status && + if ['S', 'T'].include?(name_status) && parent_full_name = expected_parent_name TaxonConcept.where( taxonomy_id: Taxonomy.find_by_name(Taxonomy::CITES_EU).try(:id), diff --git a/app/models/nomenclature_change/reassignment_copy_processor.rb b/app/models/nomenclature_change/reassignment_copy_processor.rb index 4852f62cc5..fa8b25cf16 100644 --- a/app/models/nomenclature_change/reassignment_copy_processor.rb +++ b/app/models/nomenclature_change/reassignment_copy_processor.rb @@ -82,7 +82,6 @@ def copy_distribution_taggings(reassignable, copied_object) taggable_id: copied_object.id }).first || copied_object.taggings.build(tagging.comparison_attributes) end - end def build_listing_change_associations(reassignable, copied_object) diff --git a/app/models/nomenclature_change/reassignment_summarizer.rb b/app/models/nomenclature_change/reassignment_summarizer.rb index e75f7d96b7..543832333d 100644 --- a/app/models/nomenclature_change/reassignment_summarizer.rb +++ b/app/models/nomenclature_change/reassignment_summarizer.rb @@ -46,14 +46,15 @@ def summary def output_children_summary children_cnt = @input.taxon_concept.children.count return nil unless children_cnt > 0 - cnt = if @input.is_a?(NomenclatureChange::Output) - children_cnt - else - @input.parent_reassignments.includes(:reassignment_targets). - where( - 'nomenclature_change_reassignment_targets.nomenclature_change_output_id' => @output.id - ).count - end + cnt = + if @input.is_a?(NomenclatureChange::Output) + children_cnt + else + @input.parent_reassignments.includes(:reassignment_targets). + where( + 'nomenclature_change_reassignment_targets.nomenclature_change_output_id' => @output.id + ).count + end "#{cnt} (of #{children_cnt}) children" end @@ -63,28 +64,30 @@ def output_names_summary @input.taxon_concept.hybrids.count + @input.taxon_concept.trade_names.count return nil unless names_cnt > 0 - cnt = if @input.is_a?(NomenclatureChange::Output) - names_cnt - else - @input.name_reassignments.includes(:reassignment_targets). - where( - 'nomenclature_change_reassignment_targets.nomenclature_change_output_id' => @output.id - ).count - end + cnt = + if @input.is_a?(NomenclatureChange::Output) + names_cnt + else + @input.name_reassignments.includes(:reassignment_targets). + where( + 'nomenclature_change_reassignment_targets.nomenclature_change_output_id' => @output.id + ).count + end "#{cnt} (of #{names_cnt}) names" end def output_distribution_summary distributions_cnt = @input.taxon_concept.distributions.count return nil unless distributions_cnt > 0 - cnt = if @input.is_a?(NomenclatureChange::Output) - distributions_cnt - else - @input.distribution_reassignments.includes(:reassignment_targets). - where( - 'nomenclature_change_reassignment_targets.nomenclature_change_output_id' => @output.id - ).count - end + cnt = + if @input.is_a?(NomenclatureChange::Output) + distributions_cnt + else + @input.distribution_reassignments.includes(:reassignment_targets). + where( + 'nomenclature_change_reassignment_targets.nomenclature_change_output_id' => @output.id + ).count + end "#{cnt} (of #{distributions_cnt}) distributions" end diff --git a/app/models/nomenclature_change/reassignment_transfer_processor.rb b/app/models/nomenclature_change/reassignment_transfer_processor.rb index 83f01c1c91..cefa75cd9e 100644 --- a/app/models/nomenclature_change/reassignment_transfer_processor.rb +++ b/app/models/nomenclature_change/reassignment_transfer_processor.rb @@ -73,8 +73,8 @@ def transfer_distribution_references(reassigned_object, reassignable) distribution_references_to_transfer = distribution_references_to_transfer. where( 'reference_id NOT IN (?)', - reassigned_object.distribution_references.select(:reference_id) - .map(&:reference_id) + reassigned_object.distribution_references.select(:reference_id). + map(&:reference_id) ) end distribution_references_to_transfer.update_all(distribution_id: reassigned_object.id) @@ -97,7 +97,7 @@ def transfer_distribution_taggings(reassigned_object, reassignable) def transfer_party_listing_distribution(reassigned_object, reassignable) return if reassigned_object.party_listing_distribution - return if !reassignable.party_listing_distribution + return unless reassignable.party_listing_distribution reassignable.party_listing_distribution.update_attribute(:listing_change_id, reassigned_object.id) end @@ -109,14 +109,13 @@ def transfer_listing_distributions(reassigned_object, reassignable) listing_distributions_to_transfer = listing_distributions_to_transfer. where( 'geo_entity_id NOT IN (?)', - reassigned_object.listing_distributions.select(:geo_entity_id) - .map(&:geo_entity_id) + reassigned_object.listing_distributions.select(:geo_entity_id). + map(&:geo_entity_id) ) end listing_distributions_to_transfer.update_all(listing_change_id: reassigned_object.id) end - def transfer_taxonomic_exclusions(reassigned_object, reassignable) return if reassignable.taxonomic_exclusions.count == 0 taxonomic_exclusions_to_transfer = reassignable.taxonomic_exclusions diff --git a/app/models/nomenclature_change/split/processor.rb b/app/models/nomenclature_change/split/processor.rb index 59d307758f..7524717723 100644 --- a/app/models/nomenclature_change/split/processor.rb +++ b/app/models/nomenclature_change/split/processor.rb @@ -51,7 +51,7 @@ def prepare_chain chain << NomenclatureChange::CascadingNotesProcessor.new(output) end end - if !input_is_one_of_outputs + unless input_is_one_of_outputs chain << NomenclatureChange::CascadingNotesProcessor.new(@input) end unless input_is_one_of_outputs diff --git a/app/models/nomenclature_change/status_downgrade_processor.rb b/app/models/nomenclature_change/status_downgrade_processor.rb index 6caea57c59..62d467ca2d 100644 --- a/app/models/nomenclature_change/status_downgrade_processor.rb +++ b/app/models/nomenclature_change/status_downgrade_processor.rb @@ -41,7 +41,6 @@ def run Rails.logger.debug "Updating shipments to have taxon concept = #{default_accepted_name.full_name}" @trade_to_reassign.update_all(taxon_concept_id: default_accepted_name.id) end - end private diff --git a/app/models/nomenclature_change/status_swap/processor.rb b/app/models/nomenclature_change/status_swap/processor.rb index 1c930e9dfe..f63a92de12 100644 --- a/app/models/nomenclature_change/status_swap/processor.rb +++ b/app/models/nomenclature_change/status_swap/processor.rb @@ -12,13 +12,14 @@ def prepare_chain chain << reassignment_processor(@secondary_output) - chain << if @primary_output.new_name_status == 'A' - linked_names = @secondary_output ? [@secondary_output] : [] - NomenclatureChange::StatusUpgradeProcessor.new(@primary_output, linked_names) - else - accepted_names = @secondary_output ? [@secondary_output] : [] - NomenclatureChange::StatusDowngradeProcessor.new(@primary_output, accepted_names) - end + chain << + if @primary_output.new_name_status == 'A' + linked_names = @secondary_output ? [@secondary_output] : [] + NomenclatureChange::StatusUpgradeProcessor.new(@primary_output, linked_names) + else + accepted_names = @secondary_output ? [@secondary_output] : [] + NomenclatureChange::StatusDowngradeProcessor.new(@primary_output, accepted_names) + end chain.compact end diff --git a/app/models/nomenclature_change/taxonomic_tree_name_resolver.rb b/app/models/nomenclature_change/taxonomic_tree_name_resolver.rb index aae947a747..844bbe40a1 100644 --- a/app/models/nomenclature_change/taxonomic_tree_name_resolver.rb +++ b/app/models/nomenclature_change/taxonomic_tree_name_resolver.rb @@ -23,11 +23,12 @@ def resolve(node) full_name: @expected_full_name ) # match on author & year as well - compatible_node = if node.author_year.blank? - compatible_node.where('SQUISH_NULL(author_year) IS NULL') - else - compatible_node.where(author_year: node.author_year) - end.first + compatible_node = + if node.author_year.blank? + compatible_node.where('SQUISH_NULL(author_year) IS NULL') + else + compatible_node.where(author_year: node.author_year) + end.first if !compatible_node compatible_node = create_compatible_node(node) elsif compatible_node && !['A', 'N'].include?(compatible_node.name_status) @@ -49,11 +50,12 @@ def resolve(node) end def create_compatible_node(node) - expected_scientific_name = if ['A', 'N'].include?(node.name_status) - @expected_full_name.split.last - else - @expected_full_name - end + expected_scientific_name = + if ['A', 'N'].include?(node.name_status) + @expected_full_name.split.last + else + @expected_full_name + end compatible_node = TaxonConcept.create( taxonomy_id: node.taxonomy_id, scientific_name: expected_scientific_name, diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index 4754e554ee..02081a5472 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -78,13 +78,15 @@ class TaxonConcept < ActiveRecord::Base :conditions => [ "taxon_relationship_type_id IN (SELECT id FROM taxon_relationship_types - WHERE name = '#{TaxonRelationshipType::HAS_SYNONYM}')"] + WHERE name = '#{TaxonRelationshipType::HAS_SYNONYM}')" + ] has_many :inverse_synonym_relationships, :class_name => 'TaxonRelationship', :foreign_key => :other_taxon_concept_id, :dependent => :destroy, :conditions => [ "taxon_relationship_type_id IN (SELECT id FROM taxon_relationship_types - WHERE name = '#{TaxonRelationshipType::HAS_SYNONYM}')"] + WHERE name = '#{TaxonRelationshipType::HAS_SYNONYM}')" + ] has_many :synonyms, :class_name => 'TaxonConcept', :through => :synonym_relationships, :source => :other_taxon_concept has_many :accepted_names, :class_name => 'TaxonConcept', @@ -102,7 +104,8 @@ class TaxonConcept < ActiveRecord::Base :conditions => [ "taxon_relationship_type_id IN (SELECT id FROM taxon_relationship_types - WHERE name = '#{TaxonRelationshipType::HAS_HYBRID}')"] + WHERE name = '#{TaxonRelationshipType::HAS_HYBRID}')" + ] has_many :hybrids, :class_name => 'TaxonConcept', :through => :hybrid_relationships, :source => :other_taxon_concept has_many :hybrid_parents, :class_name => 'TaxonConcept', @@ -112,13 +115,15 @@ class TaxonConcept < ActiveRecord::Base :conditions => [ "taxon_relationship_type_id IN (SELECT id FROM taxon_relationship_types - WHERE name = '#{TaxonRelationshipType::HAS_TRADE_NAME}')"] + WHERE name = '#{TaxonRelationshipType::HAS_TRADE_NAME}')" + ] has_many :inverse_trade_name_relationships, :class_name => 'TaxonRelationship', :foreign_key => :other_taxon_concept_id, :dependent => :destroy, :conditions => [ "taxon_relationship_type_id IN (SELECT id FROM taxon_relationship_types - WHERE name = '#{TaxonRelationshipType::HAS_TRADE_NAME}')"] + WHERE name = '#{TaxonRelationshipType::HAS_TRADE_NAME}')" + ] has_many :trade_names, :class_name => 'TaxonConcept', :through => :trade_name_relationships, :source => :other_taxon_concept has_many :accepted_names_for_trade_name, :class_name => 'TaxonConcept', @@ -240,11 +245,12 @@ def self.fetch_taxons_full_name(taxon_ids) end def scientific_name=(str) - scientific_name = if ['A', 'N'].include?(name_status) - TaxonName.sanitize_scientific_name(str) - else - str - end + scientific_name = + if ['A', 'N'].include?(name_status) + TaxonName.sanitize_scientific_name(str) + else + str + end tn = TaxonName.where(["UPPER(scientific_name) = UPPER(?)", scientific_name]).first if tn self.taxon_name = tn @@ -349,11 +355,12 @@ def inherited_standard_taxon_concept_references def expected_full_name(parent) if self.rank && Rank.in_range(Rank::VARIETY, Rank::SPECIES).include?(self.rank.name) - parent.full_name + if self.rank.name == Rank::VARIETY - ' var. ' - else - ' ' - end + (self.taxon_name.try(:scientific_name).try(:downcase) || '') + parent.full_name + + if self.rank.name == Rank::VARIETY + ' var. ' + else + ' ' + end + (self.taxon_name.try(:scientific_name).try(:downcase) || '') else self.full_name end @@ -361,7 +368,7 @@ def expected_full_name(parent) def rebuild_taxonomy?(params) new_full_name = params[:taxon_concept] ? params[:taxon_concept][:full_name] : '' - new_full_name and new_full_name != full_name and + new_full_name && new_full_name != full_name && Rank.in_range(Rank::VARIETY, Rank::GENUS).include?(rank.name) end @@ -414,11 +421,12 @@ def add_remove_relationships(new_taxa, removed_taxa, rel_type) def init_accepted_taxa(new_ids) return [[],[]] unless ['S', 'T', 'H'].include?(name_status) - current_ids = case name_status + current_ids = + case name_status when 'S' then accepted_names.pluck(:id) when 'T' then accepted_names_for_trade_name.pluck(:id) when 'H' then hybrid_parents.pluck(:id) - end + end ids_to_add = new_ids - current_ids ids_to_remove = current_ids - new_ids @@ -495,15 +503,15 @@ def maximum_2_hybrid_parents def ensure_taxonomic_position if new_record? && fixed_order_required? && taxonomic_position.blank? prev_taxonomic_position = - if parent - last_sibling = TaxonConcept.where(:parent_id => parent_id). - maximum(:taxonomic_position) - last_sibling || (parent.taxonomic_position + '.0') - else - last_root = TaxonConcept.where(:parent_id => nil). - maximum(:taxonomic_position) - last_root || '0' - end + if parent + last_sibling = TaxonConcept.where(:parent_id => parent_id). + maximum(:taxonomic_position) + last_sibling || (parent.taxonomic_position + '.0') + else + last_root = TaxonConcept.where(:parent_id => nil). + maximum(:taxonomic_position) + last_root || '0' + end prev_taxonomic_position_parts = prev_taxonomic_position.split('.') prev_taxonomic_position_parts << (prev_taxonomic_position_parts.pop || 0).to_i + 1 self.taxonomic_position = prev_taxonomic_position_parts.join('.') diff --git a/app/models/taxon_concept_observer.rb b/app/models/taxon_concept_observer.rb index 5c85f045bc..e4677df0b3 100644 --- a/app/models/taxon_concept_observer.rb +++ b/app/models/taxon_concept_observer.rb @@ -1,30 +1,31 @@ class TaxonConceptObserver < ActiveRecord::Observer def before_validation(taxon_concept) - taxon_concept.full_name = if taxon_concept.rank && - taxon_concept.parent && - ['A', 'N'].include?(taxon_concept.name_status) - rank_name = taxon_concept.rank.name - parent_full_name = taxon_concept.parent.full_name - name = taxon_concept.scientific_name - # if name is present, just in case it is a multipart name - # e.g. when changing status from S, T, H - # make sure to only use last part - if name.present? - name = TaxonName.sanitize_scientific_name(name) - end - if name.blank? - nil - elsif [Rank::SPECIES, Rank::SUBSPECIES].include?(rank_name) - "#{parent_full_name} #{name.downcase}" - elsif rank_name == Rank::VARIETY - "#{parent_full_name} var. #{name.downcase}" + taxon_concept.full_name = + if taxon_concept.rank && + taxon_concept.parent && + ['A', 'N'].include?(taxon_concept.name_status) + rank_name = taxon_concept.rank.name + parent_full_name = taxon_concept.parent.full_name + name = taxon_concept.scientific_name + # if name is present, just in case it is a multipart name + # e.g. when changing status from S, T, H + # make sure to only use last part + if name.present? + name = TaxonName.sanitize_scientific_name(name) + end + if name.blank? + nil + elsif [Rank::SPECIES, Rank::SUBSPECIES].include?(rank_name) + "#{parent_full_name} #{name.downcase}" + elsif rank_name == Rank::VARIETY + "#{parent_full_name} var. #{name.downcase}" + else + name + end else - name + taxon_concept.scientific_name end - else - taxon_concept.scientific_name - end end def after_create(taxon_concept) diff --git a/app/workers/update_taxonomy_worker.rb b/app/workers/update_taxonomy_worker.rb index 32d1ae2dd5..d8c48ee9e0 100644 --- a/app/workers/update_taxonomy_worker.rb +++ b/app/workers/update_taxonomy_worker.rb @@ -20,6 +20,5 @@ def perform 'touched_at IS NOT NULL AND touched_at > updated_at' ) end - end end diff --git a/config/routes.rb b/config/routes.rb index 085bf4661d..bfa86e9e09 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -202,7 +202,7 @@ end namespace :checklist do - resources :geo_entities, :only => [:index] #TODO move to API + resources :geo_entities, :only => [:index] #TODO: move to API resources :downloads do member do get :download diff --git a/db/migrate/20151005141953_add_empty_string_as_default_to_notes.rb b/db/migrate/20151005141953_add_empty_string_as_default_to_notes.rb index c40bf2d63f..647343f949 100644 --- a/db/migrate/20151005141953_add_empty_string_as_default_to_notes.rb +++ b/db/migrate/20151005141953_add_empty_string_as_default_to_notes.rb @@ -41,6 +41,6 @@ def change SET internal_note='' WHERE internal_note IS NULL; SQL - ) + ) end end diff --git a/lib/modules/search_cache.rb b/lib/modules/search_cache.rb index c34a1c2b78..0764501d91 100644 --- a/lib/modules/search_cache.rb +++ b/lib/modules/search_cache.rb @@ -22,7 +22,8 @@ def cached_total_cnt end end -private + private + def generic_cache_key(suffix) raw_key = @options.merge(:locale => I18n.locale).to_a.sort. unshift("#{self.class.name}-#{suffix}"). diff --git a/spec/controllers/admin/nomenclature_changes/status_swap_controller_spec.rb b/spec/controllers/admin/nomenclature_changes/status_swap_controller_spec.rb index 1b944d5df7..e6b19cd132 100644 --- a/spec/controllers/admin/nomenclature_changes/status_swap_controller_spec.rb +++ b/spec/controllers/admin/nomenclature_changes/status_swap_controller_spec.rb @@ -39,9 +39,11 @@ context "when no legislation" do it 'redirects to next step' do get :show, id: :legislation, nomenclature_change_id: @status_change.id - response.should redirect_to(admin_nomenclature_change_status_swap_url( - nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'summary' - )) + response.should redirect_to( + admin_nomenclature_change_status_swap_url( + nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'summary' + ) + ) end end end @@ -59,9 +61,11 @@ describe 'POST create' do it 'redirects to status_change wizard' do post :create, nomenclature_change_id: 'new' - response.should redirect_to(admin_nomenclature_change_status_swap_url( - nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'primary_output' - )) + response.should redirect_to( + admin_nomenclature_change_status_swap_url( + nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'primary_output' + ) + ) end end @@ -77,9 +81,11 @@ new_name_status: 'S' } }, nomenclature_change_id: @status_change.id, id: 'primary_output' - response.should redirect_to(admin_nomenclature_change_status_swap_url( - nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'secondary_output' - )) + response.should redirect_to( + admin_nomenclature_change_status_swap_url( + nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'secondary_output' + ) + ) end end context 'when unsuccessful' do diff --git a/spec/controllers/admin/nomenclature_changes/status_to_accepted_controller_spec.rb b/spec/controllers/admin/nomenclature_changes/status_to_accepted_controller_spec.rb index 1dd40ccb41..47ba9a1fa9 100644 --- a/spec/controllers/admin/nomenclature_changes/status_to_accepted_controller_spec.rb +++ b/spec/controllers/admin/nomenclature_changes/status_to_accepted_controller_spec.rb @@ -28,9 +28,11 @@ describe 'POST create' do it 'redirects to status_change wizard' do post :create, nomenclature_change_id: 'new' - response.should redirect_to(admin_nomenclature_change_status_to_accepted_url( - nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'primary_output' - )) + response.should redirect_to( + admin_nomenclature_change_status_to_accepted_url( + nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'primary_output' + ) + ) end end @@ -52,9 +54,11 @@ new_name_status: 'A' } }, nomenclature_change_id: @status_change.id, id: 'primary_output' - response.should redirect_to(admin_nomenclature_change_status_to_accepted_url( - nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'summary' - )) + response.should redirect_to( + admin_nomenclature_change_status_to_accepted_url( + nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'summary' + ) + ) end end context 'when unsuccessful' do diff --git a/spec/controllers/admin/nomenclature_changes/status_to_synonym_controller_spec.rb b/spec/controllers/admin/nomenclature_changes/status_to_synonym_controller_spec.rb index 4c498fc664..bbfac76a6a 100644 --- a/spec/controllers/admin/nomenclature_changes/status_to_synonym_controller_spec.rb +++ b/spec/controllers/admin/nomenclature_changes/status_to_synonym_controller_spec.rb @@ -39,9 +39,11 @@ describe 'POST create' do it 'redirects to status_change wizard' do post :create, nomenclature_change_id: 'new' - response.should redirect_to(admin_nomenclature_change_status_to_synonym_url( - nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'primary_output' - )) + response.should redirect_to( + admin_nomenclature_change_status_to_synonym_url( + nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'primary_output' + ) + ) end end @@ -57,9 +59,11 @@ new_name_status: 'S' } }, nomenclature_change_id: @status_change.id, id: 'primary_output' - response.should redirect_to(admin_nomenclature_change_status_to_synonym_url( - nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'relay' - )) + response.should redirect_to( + admin_nomenclature_change_status_to_synonym_url( + nomenclature_change_id: assigns(:nomenclature_change).id, :id => 'relay' + ) + ) end end context 'when unsuccessful' do diff --git a/spec/controllers/admin/taxon_concepts_controller_spec.rb b/spec/controllers/admin/taxon_concepts_controller_spec.rb index 61a88ac58e..e9dd6d0ef9 100644 --- a/spec/controllers/admin/taxon_concepts_controller_spec.rb +++ b/spec/controllers/admin/taxon_concepts_controller_spec.rb @@ -36,12 +36,12 @@ describe "XHR POST create" do it "renders create when successful" do xhr :post, :create, - taxon_concept: { + taxon_concept: { name_status: 'A', taxonomy_id: cites_eu.id, rank_id: create(:rank, name: Rank::GENUS), scientific_name: 'Canis', - parent_id: create_cites_eu_family, + parent_id: create_cites_eu_family } response.should render_template("create") end diff --git a/spec/factories/ranks.rb b/spec/factories/ranks.rb index c39e0c8a96..5a806b8abe 100644 --- a/spec/factories/ranks.rb +++ b/spec/factories/ranks.rb @@ -44,18 +44,20 @@ def attributes_for_variety FactoryGirl.define do factory :rank do - name { [ - Rank::KINGDOM, - Rank::PHYLUM, - Rank::CLASS, - Rank::ORDER, - Rank::FAMILY, - Rank::SUBFAMILY, - Rank::GENUS, - Rank::SPECIES, - Rank::SUBSPECIES, - Rank::VARIETY - ].sample } + name { + [ + Rank::KINGDOM, + Rank::PHYLUM, + Rank::CLASS, + Rank::ORDER, + Rank::FAMILY, + Rank::SUBFAMILY, + Rank::GENUS, + Rank::SPECIES, + Rank::SUBSPECIES, + Rank::VARIETY + ].sample + } display_name_en { |r| r.name } initialize_with { Rank.find_by_name(name) || new(attributes_for_rank(name)) } end diff --git a/spec/models/hybrid_relationship_spec.rb b/spec/models/hybrid_relationship_spec.rb index 6b6748278d..fec65538b0 100644 --- a/spec/models/hybrid_relationship_spec.rb +++ b/spec/models/hybrid_relationship_spec.rb @@ -54,7 +54,7 @@ hybrid_rel.save tc.hybrids.map(&:full_name).should include('Lolcatus lolatus x lolcatus') } - specify{ + specify{ hybrid_rel.save another_hybrid_rel.save hybrid_rel.other_taxon_concept = another_hybrid diff --git a/spec/models/nomenclature_change/shared/split_definitions.rb b/spec/models/nomenclature_change/shared/split_definitions.rb index 49537c605a..52a9619716 100644 --- a/spec/models/nomenclature_change/shared/split_definitions.rb +++ b/spec/models/nomenclature_change/shared/split_definitions.rb @@ -74,7 +74,8 @@ input_attributes: {taxon_concept_id: input_species.id}, outputs_attributes: { 0 => { taxon_concept_id: output_species1.id }, - 1 => { taxon_concept_id: output_species2.id, + 1 => { + taxon_concept_id: output_species2.id, new_name_status: 'A', new_parent_id: genus2.id } diff --git a/spec/models/nomenclature_change/status_swap/processor_spec.rb b/spec/models/nomenclature_change/status_swap/processor_spec.rb index a4532799be..9d6ea8ff94 100644 --- a/spec/models/nomenclature_change/status_swap/processor_spec.rb +++ b/spec/models/nomenclature_change/status_swap/processor_spec.rb @@ -15,7 +15,6 @@ tc } - before(:each){ synonym_relationship_type } let(:processor){ NomenclatureChange::StatusSwap::Processor.new(status_change) } let(:primary_output_taxon_concept){ status_change.primary_output.taxon_concept } diff --git a/spec/models/taxon_concept/validation_spec.rb b/spec/models/taxon_concept/validation_spec.rb index fec49adc73..5aa9b7c67f 100644 --- a/spec/models/taxon_concept/validation_spec.rb +++ b/spec/models/taxon_concept/validation_spec.rb @@ -91,13 +91,13 @@ let!(:tc1) { create_cites_eu_subspecies( parent: tc_parent, - taxon_name: create(:taxon_name, scientific_name: 'duplicatus'), + taxon_name: create(:taxon_name, scientific_name: 'duplicatus') ) } let(:tc2) { build_cites_eu_subspecies( parent: tc_parent, - taxon_name: build(:taxon_name, scientific_name: 'duplicatus'), + taxon_name: build(:taxon_name, scientific_name: 'duplicatus') ) } specify { tc2.should have(1).error_on(:full_name) } diff --git a/spec/models/taxon_concept_prefix_matcher_spec.rb b/spec/models/taxon_concept_prefix_matcher_spec.rb index 5bf455bfa9..9e7d3802e6 100644 --- a/spec/models/taxon_concept_prefix_matcher_spec.rb +++ b/spec/models/taxon_concept_prefix_matcher_spec.rb @@ -75,8 +75,10 @@ TaxonConceptPrefixMatcher.new parent_matcher_params } - specify{ parent_matcher.taxon_concepts.map(&:full_name).should == - ['Aab', 'Aac'] } + specify{ + parent_matcher.taxon_concepts.map(&:full_name).should == + ['Aab', 'Aac'] + } let(:ancestor_matcher_params){ SearchParams.new( @@ -89,8 +91,10 @@ TaxonConceptPrefixMatcher.new ancestor_matcher_params } - specify{ ancestor_matcher.taxon_concepts.map(&:full_name).should == - ['Aaa'] } + specify{ + ancestor_matcher.taxon_concepts.map(&:full_name).should == + ['Aaa'] + } let(:self_and_ancestor_matcher_params){ SearchParams.new( @@ -102,9 +106,11 @@ let(:self_and_ancestor_matcher){ TaxonConceptPrefixMatcher.new self_and_ancestor_matcher_params } - - specify{ self_and_ancestor_matcher.taxon_concepts.map(&:full_name).should == - ['Aaa', 'Aaab'] } + + specify{ + self_and_ancestor_matcher.taxon_concepts.map(&:full_name).should == + ['Aaa', 'Aaab'] + } end context "when taxon concept scope applied" do @@ -119,8 +125,10 @@ TaxonConceptPrefixMatcher.new ancestor_matcher_params } - specify{ ancestor_matcher.taxon_concepts.map(&:full_name).should == - ['Aaa', 'Aab', 'Aac'] } + specify{ + ancestor_matcher.taxon_concepts.map(&:full_name).should == + ['Aaa', 'Aab', 'Aac'] + } let(:descendant_matcher_params){ SearchParams.new( @@ -133,8 +141,10 @@ TaxonConceptPrefixMatcher.new descendant_matcher_params } - specify{ descendant_matcher.taxon_concepts.map(&:full_name).should == - ['Aaab', 'Aab', 'Abb'] } + specify{ + descendant_matcher.taxon_concepts.map(&:full_name).should == + ['Aaab', 'Aab', 'Abb'] + } end end From 26a1f1fb62de3083d925ca9202c420b00e92a362 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 10 Jun 2016 10:16:22 +0100 Subject: [PATCH 300/365] enabled hound --- .hound.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.hound.yml b/.hound.yml index 42713ec565..b7945ab908 100644 --- a/.hound.yml +++ b/.hound.yml @@ -1,3 +1,3 @@ ruby: enabled: true - config_file: .rubocop_todo.yml + config_file: .rubocop.yml From 74643a40fe2912310aa32b6b9b87262bd4f4c342 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Thu, 9 Jun 2016 13:43:19 +0100 Subject: [PATCH 301/365] Configure I18n not to fallback to english if translation missing --- config/environments/production.rb | 2 +- config/environments/staging.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/config/environments/production.rb b/config/environments/production.rb index 83a1fdc689..bc23ea6786 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -59,7 +59,7 @@ # Enable locale fallbacks for I18n (makes lookups for any locale fall back to # the I18n.default_locale when a translation can not be found) - config.i18n.fallbacks = true + config.i18n.fallbacks = false # Send deprecation notices to registered listeners config.active_support.deprecation = :notify diff --git a/config/environments/staging.rb b/config/environments/staging.rb index 0fca2cda79..6c480b4a0a 100644 --- a/config/environments/staging.rb +++ b/config/environments/staging.rb @@ -59,7 +59,7 @@ # Enable locale fallbacks for I18n (makes lookups for any locale fall back to # the I18n.default_locale when a translation can not be found) - config.i18n.fallbacks = true + config.i18n.fallbacks = false # Send deprecation notices to registered listeners config.active_support.deprecation = :notify From 6a89ac2f1f822dbb66082116d935c822d1f69dfc Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Thu, 9 Jun 2016 13:43:51 +0100 Subject: [PATCH 302/365] If translation is missing use empty message as default --- app/models/nomenclature_change/constructor_helpers.rb | 4 ++-- app/models/nomenclature_change/lump/constructor.rb | 8 ++++---- app/models/nomenclature_change/split/constructor.rb | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/models/nomenclature_change/constructor_helpers.rb b/app/models/nomenclature_change/constructor_helpers.rb index 1f096c8569..514c7f6be1 100644 --- a/app/models/nomenclature_change/constructor_helpers.rb +++ b/app/models/nomenclature_change/constructor_helpers.rb @@ -184,7 +184,7 @@ def in_year(event, lng) I18n.translate( 'in_year', year: event && event.effective_at.try(:year) || Date.today.year, - default: 'Translation missing' + default: '' ) end end @@ -197,7 +197,7 @@ def multi_lingual_legislation_note(note_type) I18n.translate( note_type, input_taxon: input_html, output_taxon: output_html, - default: 'Translation missing' + default: '' ) end end diff --git a/app/models/nomenclature_change/lump/constructor.rb b/app/models/nomenclature_change/lump/constructor.rb index c489657877..1e19914be4 100644 --- a/app/models/nomenclature_change/lump/constructor.rb +++ b/app/models/nomenclature_change/lump/constructor.rb @@ -59,7 +59,7 @@ def input_lumped_into(input, output, lng) 'lump.input_lumped_into', input_taxon: input_html, output_taxon: output_html, - default: 'Translation missing' + default: '' ) end end @@ -74,7 +74,7 @@ def output_lumped_from(output, inputs, lng) 'lump.output_lumped_from', output_taxon: output_html, input_taxa: inputs_html, - default: 'Translation missing' + default: '' ) end end @@ -124,13 +124,13 @@ def legislation_note(lng) output = @nomenclature_change.output input_html = taxon_concept_html('[[input]]', output.display_rank_name) output_html = taxon_concept_html(output.display_full_name, output.display_rank_name) - note = '

' + note = '' note << yield(input_html, output_html) note << in_year(@nomenclature_change.event, lng) if @nomenclature_change.event note << following_taxonomic_changes(@nomenclature_change.event, lng) end - note + '.

' + note = "

#{note}.

" if note.present? end def multi_lingual_listing_change_note diff --git a/app/models/nomenclature_change/split/constructor.rb b/app/models/nomenclature_change/split/constructor.rb index 0624d7fc04..ce808fc33f 100644 --- a/app/models/nomenclature_change/split/constructor.rb +++ b/app/models/nomenclature_change/split/constructor.rb @@ -165,13 +165,13 @@ def legislation_note(lng) input = @nomenclature_change.input input_html = taxon_concept_html(input.taxon_concept.full_name, input.taxon_concept.rank.name) output_html = taxon_concept_html('[[output]]', input.taxon_concept.rank.name) - note = '

' + note = '' note << yield(input_html, output_html) note << in_year(@nomenclature_change.event, lng) if @nomenclature_change.event note << following_taxonomic_changes(@nomenclature_change.event, lng) end - note + '.

' + note = "

#{note}.

" if note.present? end def multi_lingual_listing_change_note From 72b1a1e2e62925e9091e5e1366519d0c365c1640 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Mon, 13 Jun 2016 13:41:16 +0100 Subject: [PATCH 303/365] Translate listing_change nomenclature_note without fallback --- app/models/m_listing_change.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/models/m_listing_change.rb b/app/models/m_listing_change.rb index 0bce020ef7..6ed8ddd343 100644 --- a/app/models/m_listing_change.rb +++ b/app/models/m_listing_change.rb @@ -11,6 +11,7 @@ def self.included(base) translates :full_note, fallback: false translates :hash_full_note, :inherited_short_note, :inherited_full_note, :auto_note, :party_full_name + translates :nomenclature_note, fallback: false end end From 34994645e2c7d81f16cf0543897f4a785c0f43bf Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Mon, 13 Jun 2016 13:43:47 +0100 Subject: [PATCH 304/365] Replace 'Translation missing' with empty string in split and constructor_helpers --- app/models/nomenclature_change/split/constructor.rb | 4 ++-- .../nomenclature_change/status_change/constructor_helpers.rb | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/nomenclature_change/split/constructor.rb b/app/models/nomenclature_change/split/constructor.rb index ce808fc33f..f186c55eae 100644 --- a/app/models/nomenclature_change/split/constructor.rb +++ b/app/models/nomenclature_change/split/constructor.rb @@ -89,7 +89,7 @@ def input_split_into(input, outputs, lng) 'split.input_split_into', output_taxa: outputs_html, input_taxon: input_html, - default: 'Translation missing' + default: '' ) end end @@ -115,7 +115,7 @@ def output_split_from(output, input, lng) 'split.output_split_from', output_taxon: output_html, input_taxon: input_html, - default: 'Translation missing' + default: '' ) end end diff --git a/app/models/nomenclature_change/status_change/constructor_helpers.rb b/app/models/nomenclature_change/status_change/constructor_helpers.rb index 9b1bc13a5e..258638b64d 100644 --- a/app/models/nomenclature_change/status_change/constructor_helpers.rb +++ b/app/models/nomenclature_change/status_change/constructor_helpers.rb @@ -82,7 +82,7 @@ def status_elevated_to_accepted_name(output_new, output_old, lng) "status_change.status_elevated_to_accepted_name", output_new_taxon: output_new_html, output_old_taxon: output_old_html, - default: 'Translation missing' + default: '' ) end end From 38d5c40b70ff6a0ebe4755b429fbb073a1da9219 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 13 Jun 2016 15:04:19 +0100 Subject: [PATCH 305/365] removed obsolete method --- app/models/m_listing_change.rb | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/models/m_listing_change.rb b/app/models/m_listing_change.rb index 6ed8ddd343..1370b01732 100644 --- a/app/models/m_listing_change.rb +++ b/app/models/m_listing_change.rb @@ -41,10 +41,6 @@ def countries_full_names CountryDictionary.instance.get_names_by_ids(countries_ids).compact end - def nomenclature_note - self.nomenclature_note_en - end - def to_timeline_event Checklist::TimelineEvent.new( self.as_json( From 4e02131e6faedfe804fd705cd59327b26e0cd102 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 30 Jun 2016 12:03:19 +0100 Subject: [PATCH 306/365] update schema annotations --- app/models/document.rb | 1 + app/models/document/agenda_items.rb | 1 + app/models/document/commission_notes.rb | 1 + .../detailed_summary_of_conclusions.rb | 1 + app/models/document/list_of_participants.rb | 1 + app/models/document/meeting_agenda.rb | 1 + app/models/document/ndf_consultation.rb | 1 + app/models/document/non_detriment_findings.rb | 1 + app/models/document/proposal.rb | 1 + .../range_state_consultation_letter.rb | 1 + .../document/review_of_significant_trade.rb | 1 + .../document/short_summary_of_conclusions.rb | 1 + app/models/document/unep_wcmc_report.rb | 1 + app/models/nomenclature_change/input.rb | 8 ++++---- app/models/nomenclature_change/output.rb | 10 ++++++---- spec/models/api_request_spec.rb | 19 ++++++++++++++++++- spec/models/document_spec.rb | 1 + spec/models/nomenclature_change/input_spec.rb | 8 ++++---- .../models/nomenclature_change/output_spec.rb | 10 ++++++---- 19 files changed, 52 insertions(+), 17 deletions(-) diff --git a/app/models/document.rb b/app/models/document.rb index 46c71c2599..3a4049b341 100644 --- a/app/models/document.rb +++ b/app/models/document.rb @@ -21,6 +21,7 @@ # original_id :integer # discussion_id :integer # discussion_sort_index :integer +# designation_id :integer # class Document < ActiveRecord::Base diff --git a/app/models/document/agenda_items.rb b/app/models/document/agenda_items.rb index d68030a82c..1f20558c06 100644 --- a/app/models/document/agenda_items.rb +++ b/app/models/document/agenda_items.rb @@ -21,6 +21,7 @@ # original_id :integer # discussion_id :integer # discussion_sort_index :integer +# designation_id :integer # class Document::AgendaItems < Document diff --git a/app/models/document/commission_notes.rb b/app/models/document/commission_notes.rb index 90ca179e3b..366b236928 100644 --- a/app/models/document/commission_notes.rb +++ b/app/models/document/commission_notes.rb @@ -21,6 +21,7 @@ # original_id :integer # discussion_id :integer # discussion_sort_index :integer +# designation_id :integer # class Document::CommissionNotes < Document diff --git a/app/models/document/detailed_summary_of_conclusions.rb b/app/models/document/detailed_summary_of_conclusions.rb index ffd737eef4..a850a1ffa0 100644 --- a/app/models/document/detailed_summary_of_conclusions.rb +++ b/app/models/document/detailed_summary_of_conclusions.rb @@ -21,6 +21,7 @@ # original_id :integer # discussion_id :integer # discussion_sort_index :integer +# designation_id :integer # class Document::DetailedSummaryOfConclusions < Document diff --git a/app/models/document/list_of_participants.rb b/app/models/document/list_of_participants.rb index a9a80c84eb..841b5abc33 100644 --- a/app/models/document/list_of_participants.rb +++ b/app/models/document/list_of_participants.rb @@ -21,6 +21,7 @@ # original_id :integer # discussion_id :integer # discussion_sort_index :integer +# designation_id :integer # class Document::ListOfParticipants < Document diff --git a/app/models/document/meeting_agenda.rb b/app/models/document/meeting_agenda.rb index bae837a3aa..d060bfa0b7 100644 --- a/app/models/document/meeting_agenda.rb +++ b/app/models/document/meeting_agenda.rb @@ -21,6 +21,7 @@ # original_id :integer # discussion_id :integer # discussion_sort_index :integer +# designation_id :integer # class Document::MeetingAgenda < Document diff --git a/app/models/document/ndf_consultation.rb b/app/models/document/ndf_consultation.rb index 822411a3b2..2a00e10bb6 100644 --- a/app/models/document/ndf_consultation.rb +++ b/app/models/document/ndf_consultation.rb @@ -21,6 +21,7 @@ # original_id :integer # discussion_id :integer # discussion_sort_index :integer +# designation_id :integer # class Document::NdfConsultation < Document diff --git a/app/models/document/non_detriment_findings.rb b/app/models/document/non_detriment_findings.rb index b192c4dd1c..36d1f3cb9b 100644 --- a/app/models/document/non_detriment_findings.rb +++ b/app/models/document/non_detriment_findings.rb @@ -21,6 +21,7 @@ # original_id :integer # discussion_id :integer # discussion_sort_index :integer +# designation_id :integer # class Document::NonDetrimentFindings < Document diff --git a/app/models/document/proposal.rb b/app/models/document/proposal.rb index d6dfebd60a..76bbbf388c 100644 --- a/app/models/document/proposal.rb +++ b/app/models/document/proposal.rb @@ -21,6 +21,7 @@ # original_id :integer # discussion_id :integer # discussion_sort_index :integer +# designation_id :integer # class Document::Proposal < Document diff --git a/app/models/document/range_state_consultation_letter.rb b/app/models/document/range_state_consultation_letter.rb index 817f6ac52e..6ce5637c6a 100644 --- a/app/models/document/range_state_consultation_letter.rb +++ b/app/models/document/range_state_consultation_letter.rb @@ -21,6 +21,7 @@ # original_id :integer # discussion_id :integer # discussion_sort_index :integer +# designation_id :integer # class Document::RangeStateConsultationLetter < Document diff --git a/app/models/document/review_of_significant_trade.rb b/app/models/document/review_of_significant_trade.rb index 768b71eef2..4ddcdc5cde 100644 --- a/app/models/document/review_of_significant_trade.rb +++ b/app/models/document/review_of_significant_trade.rb @@ -21,6 +21,7 @@ # original_id :integer # discussion_id :integer # discussion_sort_index :integer +# designation_id :integer # class Document::ReviewOfSignificantTrade < Document diff --git a/app/models/document/short_summary_of_conclusions.rb b/app/models/document/short_summary_of_conclusions.rb index 62b00b7add..b1a2497858 100644 --- a/app/models/document/short_summary_of_conclusions.rb +++ b/app/models/document/short_summary_of_conclusions.rb @@ -21,6 +21,7 @@ # original_id :integer # discussion_id :integer # discussion_sort_index :integer +# designation_id :integer # class Document::ShortSummaryOfConclusions < Document diff --git a/app/models/document/unep_wcmc_report.rb b/app/models/document/unep_wcmc_report.rb index bc59772886..d97b4b3ebc 100644 --- a/app/models/document/unep_wcmc_report.rb +++ b/app/models/document/unep_wcmc_report.rb @@ -21,6 +21,7 @@ # original_id :integer # discussion_id :integer # discussion_sort_index :integer +# designation_id :integer # class Document::UnepWcmcReport < Document diff --git a/app/models/nomenclature_change/input.rb b/app/models/nomenclature_change/input.rb index 8a2be92f4e..1c3739917d 100644 --- a/app/models/nomenclature_change/input.rb +++ b/app/models/nomenclature_change/input.rb @@ -5,14 +5,14 @@ # id :integer not null, primary key # nomenclature_change_id :integer not null # taxon_concept_id :integer not null -# note_en :text -# note_es :text -# note_fr :text -# internal_note :text +# note_en :text default("") # created_by_id :integer not null # updated_by_id :integer not null # created_at :datetime not null # updated_at :datetime not null +# internal_note :text default("") +# note_es :text default("") +# note_fr :text default("") # # Represents an input of a nomenclature change. diff --git a/app/models/nomenclature_change/output.rb b/app/models/nomenclature_change/output.rb index 8f0534bb55..2bdbe21464 100644 --- a/app/models/nomenclature_change/output.rb +++ b/app/models/nomenclature_change/output.rb @@ -11,20 +11,22 @@ # new_scientific_name :string(255) # new_author_year :string(255) # new_name_status :string(255) -# note_en :text -# note_es :text -# note_fr :text +# note_en :text default("") # created_by_id :integer not null # updated_by_id :integer not null # created_at :datetime not null # updated_at :datetime not null -# internal_note :text +# internal_note :text default("") # is_primary_output :boolean default(TRUE) # parent_id :integer # rank_id :integer # scientific_name :string(255) # author_year :string(255) # name_status :string(255) +# note_es :text default("") +# note_fr :text default("") +# taxonomy_id :integer +# tag_list :text default("--- []\n") # # Represents an output of a nomenclature change. diff --git a/spec/models/api_request_spec.rb b/spec/models/api_request_spec.rb index 93c4232181..87b60aa649 100644 --- a/spec/models/api_request_spec.rb +++ b/spec/models/api_request_spec.rb @@ -1,3 +1,20 @@ +# == Schema Information +# +# Table name: api_requests +# +# id :integer not null, primary key +# user_id :integer +# controller :string(255) +# action :string(255) +# format :string(255) +# params :text +# ip :string(255) +# response_status :integer +# error_message :text +# created_at :datetime not null +# updated_at :datetime not null +# + require 'spec_helper' describe ApiRequest do @@ -83,4 +100,4 @@ }) } end -end \ No newline at end of file +end diff --git a/spec/models/document_spec.rb b/spec/models/document_spec.rb index 637b517e71..4bb5befafd 100644 --- a/spec/models/document_spec.rb +++ b/spec/models/document_spec.rb @@ -21,6 +21,7 @@ # original_id :integer # discussion_id :integer # discussion_sort_index :integer +# designation_id :integer # require 'spec_helper' diff --git a/spec/models/nomenclature_change/input_spec.rb b/spec/models/nomenclature_change/input_spec.rb index 5b6fa25fc6..bba06995b2 100644 --- a/spec/models/nomenclature_change/input_spec.rb +++ b/spec/models/nomenclature_change/input_spec.rb @@ -5,14 +5,14 @@ # id :integer not null, primary key # nomenclature_change_id :integer not null # taxon_concept_id :integer not null -# note_en :text -# note_es :text -# note_fr :text -# internal_note :text +# note_en :text default("") # created_by_id :integer not null # updated_by_id :integer not null # created_at :datetime not null # updated_at :datetime not null +# internal_note :text default("") +# note_es :text default("") +# note_fr :text default("") # require 'spec_helper' diff --git a/spec/models/nomenclature_change/output_spec.rb b/spec/models/nomenclature_change/output_spec.rb index 667586f7fa..486f875b20 100644 --- a/spec/models/nomenclature_change/output_spec.rb +++ b/spec/models/nomenclature_change/output_spec.rb @@ -11,20 +11,22 @@ # new_scientific_name :string(255) # new_author_year :string(255) # new_name_status :string(255) -# note_en :text -# note_es :text -# note_fr :text -# internal_note :text +# note_en :text default("") # created_by_id :integer not null # updated_by_id :integer not null # created_at :datetime not null # updated_at :datetime not null +# internal_note :text default("") # is_primary_output :boolean default(TRUE) # parent_id :integer # rank_id :integer # scientific_name :string(255) # author_year :string(255) # name_status :string(255) +# note_es :text default("") +# note_fr :text default("") +# taxonomy_id :integer +# tag_list :text default("--- []\n") # require 'spec_helper' From 6309d0ed7af311426a879dcf19f1fa62d497191c Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Thu, 30 Jun 2016 11:39:15 +0100 Subject: [PATCH 307/365] Get nomenclature_note based on the selected language --- app/models/checklist/pdf/history_content.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/checklist/pdf/history_content.rb b/app/models/checklist/pdf/history_content.rb index 0a75e4a330..98ff337720 100644 --- a/app/models/checklist/pdf/history_content.rb +++ b/app/models/checklist/pdf/history_content.rb @@ -103,7 +103,7 @@ def annotation_for_language(listing_change, lng) listing_change.send("short_note_#{lng}") ) nomenclature_note = LatexToPdf.html2latex( - listing_change.nomenclature_note_en + listing_change.send("nomenclature_note_#{lng}") ) if listing_change.display_in_footnote full_note = listing_change.send("full_note_#{lng}") From a57985dfa640d608108183408b41600fad708d2d Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 30 Jun 2016 13:02:22 +0100 Subject: [PATCH 308/365] calculate higher taxa for N taxon concepts --- db/plpgsql/002_rebuild_taxonomy.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/db/plpgsql/002_rebuild_taxonomy.sql b/db/plpgsql/002_rebuild_taxonomy.sql index ff7bead156..12fb5bf95d 100644 --- a/db/plpgsql/002_rebuild_taxonomy.sql +++ b/db/plpgsql/002_rebuild_taxonomy.sql @@ -261,7 +261,7 @@ CREATE OR REPLACE FUNCTION rebuild_taxonomy_for_node(node_id integer) RETURNS vo FROM taxon_concepts h INNER JOIN taxon_names ON h.taxon_name_id = taxon_names.id INNER JOIN ranks ON h.rank_id = ranks.id - WHERE name_status = 'A' AND + WHERE name_status IN ('A', 'N') AND CASE WHEN node_id IS NOT NULL THEN h.id = node_id ELSE h.parent_id IS NULL @@ -275,7 +275,7 @@ CREATE OR REPLACE FUNCTION rebuild_taxonomy_for_node(node_id integer) RETURNS vo hstore(LOWER(ranks.name) || '_id', (hi.id)::VARCHAR) FROM q JOIN taxon_concepts hi - ON hi.parent_id = q.id AND hi.name_status = 'A' + ON hi.parent_id = q.id AND hi.name_status IN ('A', 'N') INNER JOIN taxon_names ON hi.taxon_name_id = taxon_names.id INNER JOIN ranks ON hi.rank_id = ranks.id ) From debb875394cf2018777ef51eacd3238f81942292 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 30 Jun 2016 11:57:54 +0100 Subject: [PATCH 309/365] added type casts to some text fields in taxon_concepts_view to ensure max length constraints --- app/models/m_taxon_concept.rb | 56 ++-- ...160630084345_create_taxon_concepts_view.rb | 9 + .../001_rebuild_taxon_concepts_mview.sql | 276 +----------------- .../taxon_concepts_view/20160630084345.sql | 258 ++++++++++++++++ 4 files changed, 292 insertions(+), 307 deletions(-) create mode 100644 db/migrate/20160630084345_create_taxon_concepts_view.rb create mode 100644 db/views/taxon_concepts_view/20160630084345.sql diff --git a/app/models/m_taxon_concept.rb b/app/models/m_taxon_concept.rb index 7cda5adfe7..75d7a70f1a 100644 --- a/app/models/m_taxon_concept.rb +++ b/app/models/m_taxon_concept.rb @@ -10,22 +10,22 @@ # name_status :string(255) # rank_id :integer # rank_name :string(255) -# rank_display_name_en :text -# rank_display_name_es :text -# rank_display_name_fr :text +# rank_display_name_en :string(255) +# rank_display_name_es :string(255) +# rank_display_name_fr :string(255) # spp :boolean # cites_accepted :boolean # kingdom_position :integer # taxonomic_position :string(255) -# kingdom_name :text -# phylum_name :text -# class_name :text -# order_name :text -# family_name :text -# subfamily_name :text -# genus_name :text -# species_name :text -# subspecies_name :text +# kingdom_name :string(255) +# phylum_name :string(255) +# class_name :string(255) +# order_name :string(255) +# family_name :string(255) +# subfamily_name :string(255) +# genus_name :string(255) +# species_name :string(255) +# subspecies_name :string(255) # kingdom_id :integer # phylum_id :integer # class_id :integer @@ -41,24 +41,24 @@ # cites_listed :boolean # cites_listed_descendants :boolean # cites_show :boolean -# cites_status :text -# cites_listing_original :text -# cites_listing :text +# cites_status :string(255) +# cites_listing_original :string(255) +# cites_listing :string(255) # cites_listing_updated_at :datetime -# ann_symbol :text -# hash_ann_symbol :text -# hash_ann_parent_symbol :text +# ann_symbol :string(255) +# hash_ann_symbol :string(255) +# hash_ann_parent_symbol :string(255) # eu_listed :boolean # eu_show :boolean -# eu_status :text -# eu_listing_original :text -# eu_listing :text +# eu_status :string(255) +# eu_listing_original :string(255) +# eu_listing :string(255) # eu_listing_updated_at :datetime # cms_listed :boolean # cms_show :boolean -# cms_status :text -# cms_listing_original :text -# cms_listing :text +# cms_status :string(255) +# cms_listing_original :string(255) +# cms_listing :string(255) # cms_listing_updated_at :datetime # species_listings_ids :string # species_listings_ids_aggregated :string @@ -75,14 +75,6 @@ # synonyms_author_years_ary :string # countries_ids_ary :string # all_distribution_iso_codes_ary :string -# all_distribution_ary :string -# native_distribution_ary :string -# introduced_distribution_ary :string -# introduced_uncertain_distribution_ary :string -# reintroduced_distribution_ary :string -# extinct_distribution_ary :string -# extinct_uncertain_distribution_ary :string -# uncertain_distribution_ary :string # all_distribution_ary_en :string # native_distribution_ary_en :string # introduced_distribution_ary_en :string diff --git a/db/migrate/20160630084345_create_taxon_concepts_view.rb b/db/migrate/20160630084345_create_taxon_concepts_view.rb new file mode 100644 index 0000000000..4dcf410189 --- /dev/null +++ b/db/migrate/20160630084345_create_taxon_concepts_view.rb @@ -0,0 +1,9 @@ +class CreateTaxonConceptsView < ActiveRecord::Migration + def up + execute "DROP VIEW IF EXISTS taxon_concepts_view" + execute "CREATE VIEW taxon_concepts_view AS #{view_sql('20160630084345', 'taxon_concepts_view')}" + end + + def down + end +end diff --git a/db/mviews/001_rebuild_taxon_concepts_mview.sql b/db/mviews/001_rebuild_taxon_concepts_mview.sql index 0c5198dd3b..e9f8cb89f8 100644 --- a/db/mviews/001_rebuild_taxon_concepts_mview.sql +++ b/db/mviews/001_rebuild_taxon_concepts_mview.sql @@ -3,285 +3,13 @@ CREATE OR REPLACE FUNCTION rebuild_taxon_concepts_mview() RETURNS void AS $$ BEGIN DROP table IF EXISTS taxon_concepts_mview_tmp CASCADE; - DROP view IF EXISTS taxon_concepts_view_tmp; - - CREATE OR REPLACE VIEW taxon_concepts_view_tmp AS - SELECT taxon_concepts.id, - taxon_concepts.parent_id, - taxon_concepts.taxonomy_id, - CASE - WHEN taxonomies.name = 'CITES_EU' THEN TRUE - ELSE FALSE - END AS taxonomy_is_cites_eu, - full_name, - name_status, - rank_id, - ranks.name AS rank_name, - ranks.display_name_en AS rank_display_name_en, - ranks.display_name_es AS rank_display_name_es, - ranks.display_name_fr AS rank_display_name_fr, - (data->'spp')::BOOLEAN AS spp, - (data->'cites_accepted')::BOOLEAN AS cites_accepted, - CASE - WHEN data->'kingdom_name' = 'Animalia' THEN 0 - ELSE 1 - END AS kingdom_position, - taxon_concepts.taxonomic_position, - data->'kingdom_name' AS kingdom_name, - data->'phylum_name' AS phylum_name, - data->'class_name' AS class_name, - data->'order_name' AS order_name, - data->'family_name' AS family_name, - data->'subfamily_name' AS subfamily_name, - data->'genus_name' AS genus_name, - LOWER(data->'species_name') AS species_name, - LOWER(data->'subspecies_name') AS subspecies_name, - (data->'kingdom_id')::INTEGER AS kingdom_id, - (data->'phylum_id')::INTEGER AS phylum_id, - (data->'class_id')::INTEGER AS class_id, - (data->'order_id')::INTEGER AS order_id, - (data->'family_id')::INTEGER AS family_id, - (data->'subfamily_id')::INTEGER AS subfamily_id, - (data->'genus_id')::INTEGER AS genus_id, - (data->'species_id')::INTEGER AS species_id, - (data->'subspecies_id')::INTEGER AS subspecies_id, - CASE - WHEN listing->'cites_I' = 'I' THEN TRUE - ELSE FALSE - END AS cites_I, - CASE - WHEN listing->'cites_II' = 'II' THEN TRUE - ELSE FALSE - END AS cites_II, - CASE - WHEN listing->'cites_III' = 'III' THEN TRUE - ELSE FALSE - END AS cites_III, - CASE - WHEN listing->'cites_status' = 'LISTED' AND listing->'cites_level_of_listing' = 't' - THEN TRUE - WHEN listing->'cites_status' = 'LISTED' - THEN FALSE - ELSE NULL - END AS cites_listed, - (listing->'cites_listed_descendants')::BOOLEAN AS cites_listed_descendants, - (listing->'cites_show')::BOOLEAN AS cites_show, - --(listing->'cites_status_original')::BOOLEAN AS cites_status_original, --doesn't seem to be used - listing->'cites_status' AS cites_status, - listing->'cites_listing_original' AS cites_listing_original, --used in CSV downloads - listing->'cites_listing' AS cites_listing, - (listing->'cites_listing_updated_at')::TIMESTAMP AS cites_listing_updated_at, - (listing->'ann_symbol') AS ann_symbol, - (listing->'hash_ann_symbol') AS hash_ann_symbol, - (listing->'hash_ann_parent_symbol') AS hash_ann_parent_symbol, - CASE - WHEN listing->'eu_status' = 'LISTED' AND listing->'eu_level_of_listing' = 't' - THEN TRUE - WHEN listing->'eu_status' = 'LISTED' - THEN FALSE - ELSE NULL - END AS eu_listed, - (listing->'eu_show')::BOOLEAN AS eu_show, - --(listing->'eu_status_original')::BOOLEAN AS eu_status_original, --doesn't seem to be used - listing->'eu_status' AS eu_status, - listing->'eu_listing_original' AS eu_listing_original, - listing->'eu_listing' AS eu_listing, - (listing->'eu_listing_updated_at')::TIMESTAMP AS eu_listing_updated_at, - CASE - WHEN listing->'cms_status' = 'LISTED' AND listing->'cms_level_of_listing' = 't' - THEN TRUE - WHEN listing->'cms_status' = 'LISTED' - THEN FALSE - ELSE NULL - END AS cms_listed, - (listing->'cms_show')::BOOLEAN AS cms_show, - listing->'cms_status' AS cms_status, - listing->'cms_listing_original' AS cms_listing_original, - listing->'cms_listing' AS cms_listing, - (listing->'cms_listing_updated_at')::TIMESTAMP AS cms_listing_updated_at, - (listing->'species_listings_ids')::INT[] AS species_listings_ids, - (listing->'species_listings_ids_aggregated')::INT[] AS species_listings_ids_aggregated, - author_year, - taxon_concepts.created_at, - taxon_concepts.updated_at, - taxon_concepts.dependents_updated_at, - common_names.*, - synonyms.*, - countries_ids_ary, - all_distribution_iso_codes_ary, - -- BEGIN remove once checklist translation has been deployed - all_distribution_ary_en AS all_distribution_ary, - native_distribution_ary_en AS native_distribution_ary, - introduced_distribution_ary_en AS introduced_distribution_ary, - introduced_uncertain_distribution_ary_en AS introduced_uncertain_distribution_ary, - reintroduced_distribution_ary_en AS reintroduced_distribution_ary, - extinct_distribution_ary_en AS extinct_distribution_ary, - extinct_uncertain_distribution_ary_en AS extinct_uncertain_distribution_ary, - uncertain_distribution_ary_en AS uncertain_distribution_ary, - -- END remove once checklist translation has been deployed - all_distribution_ary_en, - native_distribution_ary_en, - introduced_distribution_ary_en, - introduced_uncertain_distribution_ary_en, - reintroduced_distribution_ary_en, - extinct_distribution_ary_en, - extinct_uncertain_distribution_ary_en, - uncertain_distribution_ary_en, - all_distribution_ary_es, - native_distribution_ary_es, - introduced_distribution_ary_es, - introduced_uncertain_distribution_ary_es, - reintroduced_distribution_ary_es, - extinct_distribution_ary_es, - extinct_uncertain_distribution_ary_es, - uncertain_distribution_ary_es, - all_distribution_ary_fr, - native_distribution_ary_fr, - introduced_distribution_ary_fr, - introduced_uncertain_distribution_ary_fr, - reintroduced_distribution_ary_fr, - extinct_distribution_ary_fr, - extinct_uncertain_distribution_ary_fr, - uncertain_distribution_ary_fr, - CASE - WHEN - name_status = 'A' - AND ( - ranks.name = 'SPECIES' - OR ( - ranks.name = 'SUBSPECIES' - AND ( - taxonomies.name = 'CITES_EU' - AND ( - (listing->'cites_historically_listed')::BOOLEAN - OR (listing->'eu_historically_listed')::BOOLEAN - ) - OR - taxonomies.name = 'CMS' - AND (listing->'cms_historically_listed')::BOOLEAN - ) - ) - ) - THEN TRUE - ELSE FALSE - END AS show_in_species_plus - FROM taxon_concepts - JOIN ranks ON ranks.id = rank_id - JOIN taxonomies ON taxonomies.id = taxon_concepts.taxonomy_id - LEFT JOIN ( - SELECT * - FROM - CROSSTAB( - 'SELECT taxon_commons.taxon_concept_id AS taxon_concept_id_com, languages.iso_code1 AS lng, - ARRAY_AGG_NOTNULL(common_names.name ORDER BY common_names.name) AS common_names_ary - FROM "taxon_commons" - INNER JOIN "common_names" - ON "common_names"."id" = "taxon_commons"."common_name_id" - INNER JOIN "languages" - ON "languages"."id" = "common_names"."language_id" AND UPPER(languages.iso_code1) IN (''EN'', ''FR'', ''ES'') - GROUP BY taxon_commons.taxon_concept_id, languages.iso_code1 - ORDER BY 1,2', - 'SELECT DISTINCT languages.iso_code1 FROM languages WHERE UPPER(languages.iso_code1) IN (''EN'', ''FR'', ''ES'') order by 1' - ) AS ct( - taxon_concept_id_com INTEGER, - english_names_ary VARCHAR[], spanish_names_ary VARCHAR[], french_names_ary VARCHAR[] - ) - ) common_names ON taxon_concepts.id = common_names.taxon_concept_id_com - LEFT JOIN ( - SELECT taxon_relationships.taxon_concept_id AS taxon_concept_id_syn, - ARRAY_AGG_NOTNULL(synonym_tc.full_name) AS synonyms_ary, - ARRAY_AGG_NOTNULL(synonym_tc.author_year) AS synonyms_author_years_ary - FROM taxon_relationships - JOIN "taxon_relationship_types" - ON "taxon_relationship_types"."id" = "taxon_relationships"."taxon_relationship_type_id" - AND "taxon_relationship_types"."name" = 'HAS_SYNONYM' - JOIN taxon_concepts AS synonym_tc - ON synonym_tc.id = taxon_relationships.other_taxon_concept_id - GROUP BY taxon_relationships.taxon_concept_id - ) synonyms ON taxon_concepts.id = synonyms.taxon_concept_id_syn - LEFT JOIN ( - SELECT distributions.taxon_concept_id AS taxon_concept_id_cnt, - ARRAY_AGG_NOTNULL(geo_entities.id ORDER BY geo_entities.name_en) AS countries_ids_ary, - ARRAY_AGG_NOTNULL(geo_entities.iso_code2 ORDER BY geo_entities.name_en) AS all_distribution_iso_codes_ary, - ARRAY_AGG_NOTNULL(geo_entities.name_en ORDER BY geo_entities.name_en) AS all_distribution_ary_en, - ARRAY_AGG_NOTNULL(geo_entities.name_en ORDER BY geo_entities.name_es) AS all_distribution_ary_es, - ARRAY_AGG_NOTNULL(geo_entities.name_en ORDER BY geo_entities.name_fr) AS all_distribution_ary_fr - FROM distributions - JOIN geo_entities - ON distributions.geo_entity_id = geo_entities.id - JOIN "geo_entity_types" - ON "geo_entity_types"."id" = "geo_entities"."geo_entity_type_id" - AND (geo_entity_types.name = 'COUNTRY' OR geo_entity_types.name = 'TERRITORY') - GROUP BY distributions.taxon_concept_id - ) countries_ids ON taxon_concepts.id = countries_ids.taxon_concept_id_cnt - LEFT JOIN ( - SELECT * - FROM CROSSTAB( - 'SELECT distributions.taxon_concept_id, - CASE WHEN tags.name IS NULL THEN ''NATIVE'' ELSE UPPER(tags.name) END || ''_'' || lng AS tag, - ARRAY_AGG_NOTNULL(geo_entities.name ORDER BY geo_entities.name) AS locations_ary - FROM distributions - JOIN ( - SELECT geo_entities.id, geo_entities.iso_code2, ''EN'' AS lng, geo_entities.name_en AS name FROM geo_entities - UNION - SELECT geo_entities.id, geo_entities.iso_code2, ''ES'' AS lng, geo_entities.name_es AS name FROM geo_entities - UNION - SELECT geo_entities.id, geo_entities.iso_code2, ''FR'' AS lng, geo_entities.name_fr AS name FROM geo_entities - ) geo_entities - ON geo_entities.id = distributions.geo_entity_id - LEFT JOIN taggings - ON taggable_id = distributions.id AND taggable_type = ''Distribution'' - LEFT JOIN tags - ON tags.id = taggings.tag_id - AND ( - UPPER(tags.name) IN ( - ''INTRODUCED'', ''INTRODUCED (?)'', ''REINTRODUCED'', - ''EXTINCT'', ''EXTINCT (?)'', ''DISTRIBUTION UNCERTAIN'' - ) OR tags.name IS NULL - ) - GROUP BY distributions.taxon_concept_id, tags.name, geo_entities.lng - ', - 'SELECT * FROM UNNEST( - ARRAY[ - ''NATIVE_EN'', ''INTRODUCED_EN'', ''INTRODUCED (?)_EN'', ''REINTRODUCED_EN'', - ''EXTINCT_EN'', ''EXTINCT (?)_EN'', ''DISTRIBUTION UNCERTAIN_EN'', - ''NATIVE_ES'', ''INTRODUCED_ES'', ''INTRODUCED (?)_ES'', ''REINTRODUCED_ES'', - ''EXTINCT_ES'', ''EXTINCT (?)_ES'', ''DISTRIBUTION UNCERTAIN_ES'', - ''NATIVE_FR'', ''INTRODUCED_FR'', ''INTRODUCED (?)_FR'', ''REINTRODUCED_FR'', - ''EXTINCT_FR'', ''EXTINCT (?)_FR'', ''DISTRIBUTION UNCERTAIN_FR'' - ])' - ) AS ct( - taxon_concept_id INTEGER, - native_distribution_ary_en VARCHAR[], - introduced_distribution_ary_en VARCHAR[], - introduced_uncertain_distribution_ary_en VARCHAR[], - reintroduced_distribution_ary_en VARCHAR[], - extinct_distribution_ary_en VARCHAR[], - extinct_uncertain_distribution_ary_en VARCHAR[], - uncertain_distribution_ary_en VARCHAR[], - native_distribution_ary_es VARCHAR[], - introduced_distribution_ary_es VARCHAR[], - introduced_uncertain_distribution_ary_es VARCHAR[], - reintroduced_distribution_ary_es VARCHAR[], - extinct_distribution_ary_es VARCHAR[], - extinct_uncertain_distribution_ary_es VARCHAR[], - uncertain_distribution_ary_es VARCHAR[], - native_distribution_ary_fr VARCHAR[], - introduced_distribution_ary_fr VARCHAR[], - introduced_uncertain_distribution_ary_fr VARCHAR[], - reintroduced_distribution_ary_fr VARCHAR[], - extinct_distribution_ary_fr VARCHAR[], - extinct_uncertain_distribution_ary_fr VARCHAR[], - uncertain_distribution_ary_fr VARCHAR[] - ) - ) distributions_by_tag ON taxon_concepts.id = distributions_by_tag.taxon_concept_id; RAISE INFO 'Creating taxon concepts materialized view (tmp)'; CREATE TABLE taxon_concepts_mview_tmp AS SELECT *, false as dirty, null::timestamp with time zone as expiry - FROM taxon_concepts_view_tmp; + FROM taxon_concepts_view; RAISE INFO 'Creating indexes on taxon concepts materialized view (tmp)'; CREATE INDEX ON taxon_concepts_mview_tmp (id); @@ -295,8 +23,6 @@ CREATE OR REPLACE FUNCTION rebuild_taxon_concepts_mview() RETURNS void RAISE INFO 'Swapping taxon concepts materialized view'; DROP table IF EXISTS taxon_concepts_mview CASCADE; ALTER TABLE taxon_concepts_mview_tmp RENAME TO taxon_concepts_mview; - DROP view IF EXISTS taxon_concepts_view CASCADE; - ALTER TABLE taxon_concepts_view_tmp RENAME TO taxon_concepts_view; DROP table IF EXISTS auto_complete_taxon_concepts_mview_tmp CASCADE; RAISE INFO 'Creating auto complete taxon concepts materialized view (tmp)'; diff --git a/db/views/taxon_concepts_view/20160630084345.sql b/db/views/taxon_concepts_view/20160630084345.sql new file mode 100644 index 0000000000..c85df28021 --- /dev/null +++ b/db/views/taxon_concepts_view/20160630084345.sql @@ -0,0 +1,258 @@ +SELECT + taxon_concepts.id, + taxon_concepts.parent_id, + taxon_concepts.taxonomy_id, + CASE + WHEN taxonomies.name = 'CITES_EU' THEN TRUE + ELSE FALSE + END AS taxonomy_is_cites_eu, + full_name::VARCHAR(255), + name_status::VARCHAR(255), + rank_id, + ranks.name::VARCHAR(255) AS rank_name, + ranks.display_name_en::VARCHAR(255) AS rank_display_name_en, + ranks.display_name_es::VARCHAR(255) AS rank_display_name_es, + ranks.display_name_fr::VARCHAR(255) AS rank_display_name_fr, + (data->'spp')::BOOLEAN AS spp, + (data->'cites_accepted')::BOOLEAN AS cites_accepted, + CASE + WHEN data->'kingdom_name' = 'Animalia' THEN 0 + ELSE 1 + END AS kingdom_position, + taxon_concepts.taxonomic_position::VARCHAR(255), + (data->'kingdom_name')::VARCHAR(255) AS kingdom_name, + (data->'phylum_name')::VARCHAR(255) AS phylum_name, + (data->'class_name')::VARCHAR(255) AS class_name, + (data->'order_name')::VARCHAR(255) AS order_name, + (data->'family_name')::VARCHAR(255) AS family_name, + (data->'subfamily_name')::VARCHAR(255) AS subfamily_name, + (data->'genus_name')::VARCHAR(255) AS genus_name, + (LOWER(data->'species_name'))::VARCHAR(255) AS species_name, + (LOWER(data->'subspecies_name'))::VARCHAR(255) AS subspecies_name, + (data->'kingdom_id')::INTEGER AS kingdom_id, + (data->'phylum_id')::INTEGER AS phylum_id, + (data->'class_id')::INTEGER AS class_id, + (data->'order_id')::INTEGER AS order_id, + (data->'family_id')::INTEGER AS family_id, + (data->'subfamily_id')::INTEGER AS subfamily_id, + (data->'genus_id')::INTEGER AS genus_id, + (data->'species_id')::INTEGER AS species_id, + (data->'subspecies_id')::INTEGER AS subspecies_id, + CASE + WHEN listing->'cites_I' = 'I' THEN TRUE + ELSE FALSE + END AS cites_I, + CASE + WHEN listing->'cites_II' = 'II' THEN TRUE + ELSE FALSE + END AS cites_II, + CASE + WHEN listing->'cites_III' = 'III' THEN TRUE + ELSE FALSE + END AS cites_III, + CASE + WHEN listing->'cites_status' = 'LISTED' AND listing->'cites_level_of_listing' = 't' + THEN TRUE + WHEN listing->'cites_status' = 'LISTED' + THEN FALSE + ELSE NULL + END AS cites_listed, + (listing->'cites_listed_descendants')::BOOLEAN AS cites_listed_descendants, + (listing->'cites_show')::BOOLEAN AS cites_show, + (listing->'cites_status')::VARCHAR(255) AS cites_status, + (listing->'cites_listing_original')::VARCHAR(255) AS cites_listing_original, --used in CSV downloads + (listing->'cites_listing')::VARCHAR(255) AS cites_listing, + (listing->'cites_listing_updated_at')::TIMESTAMP AS cites_listing_updated_at, + (listing->'ann_symbol')::VARCHAR(255) AS ann_symbol, + (listing->'hash_ann_symbol')::VARCHAR(255) AS hash_ann_symbol, + (listing->'hash_ann_parent_symbol')::VARCHAR(255) AS hash_ann_parent_symbol, + CASE + WHEN listing->'eu_status' = 'LISTED' AND listing->'eu_level_of_listing' = 't' + THEN TRUE + WHEN listing->'eu_status' = 'LISTED' + THEN FALSE + ELSE NULL + END AS eu_listed, + (listing->'eu_show')::BOOLEAN AS eu_show, + (listing->'eu_status')::VARCHAR(255) AS eu_status, + (listing->'eu_listing_original')::VARCHAR(255) AS eu_listing_original, + (listing->'eu_listing')::VARCHAR(255) AS eu_listing, + (listing->'eu_listing_updated_at')::TIMESTAMP AS eu_listing_updated_at, + CASE + WHEN listing->'cms_status' = 'LISTED' AND listing->'cms_level_of_listing' = 't' + THEN TRUE + WHEN listing->'cms_status' = 'LISTED' + THEN FALSE + ELSE NULL + END AS cms_listed, + (listing->'cms_show')::BOOLEAN AS cms_show, + (listing->'cms_status')::VARCHAR(255) AS cms_status, + (listing->'cms_listing_original')::VARCHAR(255) AS cms_listing_original, + (listing->'cms_listing')::VARCHAR(255) AS cms_listing, + (listing->'cms_listing_updated_at')::TIMESTAMP AS cms_listing_updated_at, + (listing->'species_listings_ids')::INT[] AS species_listings_ids, + (listing->'species_listings_ids_aggregated')::INT[] AS species_listings_ids_aggregated, + author_year::VARCHAR(255), + taxon_concepts.created_at, + taxon_concepts.updated_at, + taxon_concepts.dependents_updated_at, + common_names.*, + synonyms.*, + countries_ids_ary, + all_distribution_iso_codes_ary, + all_distribution_ary_en, + native_distribution_ary_en, + introduced_distribution_ary_en, + introduced_uncertain_distribution_ary_en, + reintroduced_distribution_ary_en, + extinct_distribution_ary_en, + extinct_uncertain_distribution_ary_en, + uncertain_distribution_ary_en, + all_distribution_ary_es, + native_distribution_ary_es, + introduced_distribution_ary_es, + introduced_uncertain_distribution_ary_es, + reintroduced_distribution_ary_es, + extinct_distribution_ary_es, + extinct_uncertain_distribution_ary_es, + uncertain_distribution_ary_es, + all_distribution_ary_fr, + native_distribution_ary_fr, + introduced_distribution_ary_fr, + introduced_uncertain_distribution_ary_fr, + reintroduced_distribution_ary_fr, + extinct_distribution_ary_fr, + extinct_uncertain_distribution_ary_fr, + uncertain_distribution_ary_fr, + CASE + WHEN + name_status = 'A' + AND ( + ranks.name = 'SPECIES' + OR ( + ranks.name = 'SUBSPECIES' + AND ( + taxonomies.name = 'CITES_EU' + AND ( + (listing->'cites_historically_listed')::BOOLEAN + OR (listing->'eu_historically_listed')::BOOLEAN + ) + OR + taxonomies.name = 'CMS' + AND (listing->'cms_historically_listed')::BOOLEAN + ) + ) + ) + THEN TRUE + ELSE FALSE + END AS show_in_species_plus +FROM taxon_concepts +JOIN ranks ON ranks.id = rank_id +JOIN taxonomies ON taxonomies.id = taxon_concepts.taxonomy_id +LEFT JOIN ( + SELECT * + FROM + CROSSTAB( + 'SELECT taxon_commons.taxon_concept_id AS taxon_concept_id_com, languages.iso_code1 AS lng, + ARRAY_AGG_NOTNULL(common_names.name ORDER BY common_names.name) AS common_names_ary + FROM "taxon_commons" + INNER JOIN "common_names" + ON "common_names"."id" = "taxon_commons"."common_name_id" + INNER JOIN "languages" + ON "languages"."id" = "common_names"."language_id" AND UPPER(languages.iso_code1) IN (''EN'', ''FR'', ''ES'') + GROUP BY taxon_commons.taxon_concept_id, languages.iso_code1 + ORDER BY 1,2', + 'SELECT DISTINCT languages.iso_code1 FROM languages WHERE UPPER(languages.iso_code1) IN (''EN'', ''FR'', ''ES'') order by 1' + ) AS ct( + taxon_concept_id_com INTEGER, + english_names_ary VARCHAR[], spanish_names_ary VARCHAR[], french_names_ary VARCHAR[] + ) +) common_names ON taxon_concepts.id = common_names.taxon_concept_id_com +LEFT JOIN ( + SELECT taxon_relationships.taxon_concept_id AS taxon_concept_id_syn, + ARRAY_AGG_NOTNULL(synonym_tc.full_name) AS synonyms_ary, + ARRAY_AGG_NOTNULL(synonym_tc.author_year) AS synonyms_author_years_ary + FROM taxon_relationships + JOIN "taxon_relationship_types" + ON "taxon_relationship_types"."id" = "taxon_relationships"."taxon_relationship_type_id" + AND "taxon_relationship_types"."name" = 'HAS_SYNONYM' + JOIN taxon_concepts AS synonym_tc + ON synonym_tc.id = taxon_relationships.other_taxon_concept_id + GROUP BY taxon_relationships.taxon_concept_id +) synonyms ON taxon_concepts.id = synonyms.taxon_concept_id_syn +LEFT JOIN ( + SELECT distributions.taxon_concept_id AS taxon_concept_id_cnt, + ARRAY_AGG_NOTNULL(geo_entities.id ORDER BY geo_entities.name_en) AS countries_ids_ary, + ARRAY_AGG_NOTNULL(geo_entities.iso_code2 ORDER BY geo_entities.name_en) AS all_distribution_iso_codes_ary, + ARRAY_AGG_NOTNULL(geo_entities.name_en ORDER BY geo_entities.name_en) AS all_distribution_ary_en, + ARRAY_AGG_NOTNULL(geo_entities.name_en ORDER BY geo_entities.name_es) AS all_distribution_ary_es, + ARRAY_AGG_NOTNULL(geo_entities.name_en ORDER BY geo_entities.name_fr) AS all_distribution_ary_fr + FROM distributions + JOIN geo_entities + ON distributions.geo_entity_id = geo_entities.id + JOIN "geo_entity_types" + ON "geo_entity_types"."id" = "geo_entities"."geo_entity_type_id" + AND (geo_entity_types.name = 'COUNTRY' OR geo_entity_types.name = 'TERRITORY') + GROUP BY distributions.taxon_concept_id +) countries_ids ON taxon_concepts.id = countries_ids.taxon_concept_id_cnt +LEFT JOIN ( + SELECT * + FROM CROSSTAB( + 'SELECT distributions.taxon_concept_id, + CASE WHEN tags.name IS NULL THEN ''NATIVE'' ELSE UPPER(tags.name) END || ''_'' || lng AS tag, + ARRAY_AGG_NOTNULL(geo_entities.name ORDER BY geo_entities.name) AS locations_ary + FROM distributions + JOIN ( + SELECT geo_entities.id, geo_entities.iso_code2, ''EN'' AS lng, geo_entities.name_en AS name FROM geo_entities + UNION + SELECT geo_entities.id, geo_entities.iso_code2, ''ES'' AS lng, geo_entities.name_es AS name FROM geo_entities + UNION + SELECT geo_entities.id, geo_entities.iso_code2, ''FR'' AS lng, geo_entities.name_fr AS name FROM geo_entities + ) geo_entities + ON geo_entities.id = distributions.geo_entity_id + LEFT JOIN taggings + ON taggable_id = distributions.id AND taggable_type = ''Distribution'' + LEFT JOIN tags + ON tags.id = taggings.tag_id + AND ( + UPPER(tags.name) IN ( + ''INTRODUCED'', ''INTRODUCED (?)'', ''REINTRODUCED'', + ''EXTINCT'', ''EXTINCT (?)'', ''DISTRIBUTION UNCERTAIN'' + ) OR tags.name IS NULL + ) + GROUP BY distributions.taxon_concept_id, tags.name, geo_entities.lng + ', + 'SELECT * FROM UNNEST( + ARRAY[ + ''NATIVE_EN'', ''INTRODUCED_EN'', ''INTRODUCED (?)_EN'', ''REINTRODUCED_EN'', + ''EXTINCT_EN'', ''EXTINCT (?)_EN'', ''DISTRIBUTION UNCERTAIN_EN'', + ''NATIVE_ES'', ''INTRODUCED_ES'', ''INTRODUCED (?)_ES'', ''REINTRODUCED_ES'', + ''EXTINCT_ES'', ''EXTINCT (?)_ES'', ''DISTRIBUTION UNCERTAIN_ES'', + ''NATIVE_FR'', ''INTRODUCED_FR'', ''INTRODUCED (?)_FR'', ''REINTRODUCED_FR'', + ''EXTINCT_FR'', ''EXTINCT (?)_FR'', ''DISTRIBUTION UNCERTAIN_FR'' + ])' + ) AS ct( + taxon_concept_id INTEGER, + native_distribution_ary_en VARCHAR[], + introduced_distribution_ary_en VARCHAR[], + introduced_uncertain_distribution_ary_en VARCHAR[], + reintroduced_distribution_ary_en VARCHAR[], + extinct_distribution_ary_en VARCHAR[], + extinct_uncertain_distribution_ary_en VARCHAR[], + uncertain_distribution_ary_en VARCHAR[], + native_distribution_ary_es VARCHAR[], + introduced_distribution_ary_es VARCHAR[], + introduced_uncertain_distribution_ary_es VARCHAR[], + reintroduced_distribution_ary_es VARCHAR[], + extinct_distribution_ary_es VARCHAR[], + extinct_uncertain_distribution_ary_es VARCHAR[], + uncertain_distribution_ary_es VARCHAR[], + native_distribution_ary_fr VARCHAR[], + introduced_distribution_ary_fr VARCHAR[], + introduced_uncertain_distribution_ary_fr VARCHAR[], + reintroduced_distribution_ary_fr VARCHAR[], + extinct_distribution_ary_fr VARCHAR[], + extinct_uncertain_distribution_ary_fr VARCHAR[], + uncertain_distribution_ary_fr VARCHAR[] + ) +) distributions_by_tag ON taxon_concepts.id = distributions_by_tag.taxon_concept_id; From 27a63fb448b0b14f838fab6127487bead8d14904 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 30 Jun 2016 13:32:34 +0100 Subject: [PATCH 310/365] enabled Lint/BlockAlignment --- .rubocop_todo.yml | 7 ------- app/controllers/api/v1/purposes_controller.rb | 4 ++-- app/controllers/api/v1/sources_controller.rb | 4 ++-- app/controllers/api/v1/terms_controller.rb | 4 ++-- app/controllers/api/v1/units_controller.rb | 4 ++-- app/models/document.rb | 8 ++++---- 6 files changed, 12 insertions(+), 19 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 4221d69942..ff3ce0b701 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -22,13 +22,6 @@ Lint/AssignmentInCondition: - 'app/models/nomenclature_change/output.rb' - 'lib/tasks/bbgem.rake' -# Offense count: 21 -# Cop supports --auto-correct. -# Configuration parameters: AlignWith, SupportedStyles. -# SupportedStyles: either, start_of_block, start_of_line -Lint/BlockAlignment: - Enabled: false - # Offense count: 11 # Cop supports --auto-correct. Lint/DeprecatedClassMethods: diff --git a/app/controllers/api/v1/purposes_controller.rb b/app/controllers/api/v1/purposes_controller.rb index 3fa54b01df..c722b57285 100644 --- a/app/controllers/api/v1/purposes_controller.rb +++ b/app/controllers/api/v1/purposes_controller.rb @@ -1,7 +1,7 @@ class Api::V1::PurposesController < ApplicationController caches_action :index, :cache_path => Proc.new { |c| - {:locale => "en"}.merge(c.params.select{|k,v| !v.blank? && "locale" == k}) - } + {:locale => "en"}.merge(c.params.select{|k,v| !v.blank? && "locale" == k}) + } def index @purposes = Purpose.all(:order => "code") render :json => @purposes, diff --git a/app/controllers/api/v1/sources_controller.rb b/app/controllers/api/v1/sources_controller.rb index 3fd4d5e2c5..404607e617 100644 --- a/app/controllers/api/v1/sources_controller.rb +++ b/app/controllers/api/v1/sources_controller.rb @@ -1,7 +1,7 @@ class Api::V1::SourcesController < ApplicationController caches_action :index, :cache_path => Proc.new { |c| - {:locale => "en"}.merge(c.params.select{|k,v| !v.blank? && "locale" == k}) - } + {:locale => "en"}.merge(c.params.select{|k,v| !v.blank? && "locale" == k}) + } def index @sources = Source.all(:order => "code") render :json => @sources, diff --git a/app/controllers/api/v1/terms_controller.rb b/app/controllers/api/v1/terms_controller.rb index f4651cdb93..e8de151c5e 100644 --- a/app/controllers/api/v1/terms_controller.rb +++ b/app/controllers/api/v1/terms_controller.rb @@ -1,7 +1,7 @@ class Api::V1::TermsController < ApplicationController caches_action :index, :cache_path => Proc.new { |c| - {:locale => "en"}.merge(c.params.select{|k,v| !v.blank? && "locale" == k}) - } + {:locale => "en"}.merge(c.params.select{|k,v| !v.blank? && "locale" == k}) + } def index @terms = Term.all(:order => "code") render :json => @terms, diff --git a/app/controllers/api/v1/units_controller.rb b/app/controllers/api/v1/units_controller.rb index 2e86dc430a..f7d7bbd89c 100644 --- a/app/controllers/api/v1/units_controller.rb +++ b/app/controllers/api/v1/units_controller.rb @@ -1,7 +1,7 @@ class Api::V1::UnitsController < ApplicationController caches_action :index, :cache_path => Proc.new { |c| - {:locale => "en"}.merge(c.params.select{|k,v| !v.blank? && "locale" == k}) - } + {:locale => "en"}.merge(c.params.select{|k,v| !v.blank? && "locale" == k}) + } def index @units = Unit.all(:order => "code") render :json => @units, diff --git a/app/models/document.rb b/app/models/document.rb index 3a4049b341..749288e2cf 100644 --- a/app/models/document.rb +++ b/app/models/document.rb @@ -52,10 +52,10 @@ class Document < ActiveRecord::Base # TODO: validates inclusion of type in available types accepts_nested_attributes_for :citations, :allow_destroy => true, :reject_if => proc { |attributes| - attributes['stringy_taxon_concept_ids'].blank? && ( - attributes['geo_entity_ids'].blank? || attributes['geo_entity_ids'].reject(&:blank?).empty? - ) - } + attributes['stringy_taxon_concept_ids'].blank? && ( + attributes['geo_entity_ids'].blank? || attributes['geo_entity_ids'].reject(&:blank?).empty? + ) + } mount_uploader :filename, DocumentFileUploader before_validation :set_title From 58fef3e9b625bee81387a420287b904f51d06000 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 30 Jun 2016 13:35:26 +0100 Subject: [PATCH 311/365] enabled Lint/DuplicateMethods --- .rubocop_todo.yml | 5 ----- app/models/taxon_concept_observer.rb | 5 +---- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index ff3ce0b701..61ae378b46 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -34,11 +34,6 @@ Lint/DeprecatedClassMethods: - 'lib/tasks/elibrary/document_files_importer.rb' - 'lib/tasks/trade_appendix_report.rake' -# Offense count: 1 -Lint/DuplicateMethods: - Exclude: - - 'app/models/taxon_concept_observer.rb' - # Offense count: 2 Lint/DuplicatedKey: Exclude: diff --git a/app/models/taxon_concept_observer.rb b/app/models/taxon_concept_observer.rb index e4677df0b3..1fc2688088 100644 --- a/app/models/taxon_concept_observer.rb +++ b/app/models/taxon_concept_observer.rb @@ -40,6 +40,7 @@ def after_destroy(taxon_concept) Species::Search.increment_cache_iterator Species::TaxonConceptPrefixMatcher.increment_cache_iterator Checklist::Checklist.increment_cache_iterator + DownloadsCacheCleanupWorker.perform_async(:taxon_concepts) end def after_update(taxon_concept) @@ -86,8 +87,4 @@ def after_save(taxon_concept) DownloadsCacheCleanupWorker.perform_async(:taxon_concepts) end - def after_destroy(taxon_concept) - DownloadsCacheCleanupWorker.perform_async(:taxon_concepts) - end - end From e93b96fa5e0989b96136a42495dc8840f427b6f3 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 30 Jun 2016 13:36:43 +0100 Subject: [PATCH 312/365] enabled Lint/DuplicatedKey --- .rubocop_todo.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 61ae378b46..34b118765d 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -34,12 +34,6 @@ Lint/DeprecatedClassMethods: - 'lib/tasks/elibrary/document_files_importer.rb' - 'lib/tasks/trade_appendix_report.rake' -# Offense count: 2 -Lint/DuplicatedKey: - Exclude: - - 'app/models/checklist/column_display_name_mapping.rb' - - 'spec/models/trade/shipment_spec.rb' - # Offense count: 69 # Cop supports --auto-correct. # Configuration parameters: AlignWith, SupportedStyles, AutoCorrect. From a61cb51386e44f4af10ea220414db66fd9d22535 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 30 Jun 2016 13:38:08 +0100 Subject: [PATCH 313/365] enabled Lint/EndAlignment --- .rubocop_todo.yml | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 34b118765d..595247d390 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -34,13 +34,6 @@ Lint/DeprecatedClassMethods: - 'lib/tasks/elibrary/document_files_importer.rb' - 'lib/tasks/trade_appendix_report.rake' -# Offense count: 69 -# Cop supports --auto-correct. -# Configuration parameters: AlignWith, SupportedStyles, AutoCorrect. -# SupportedStyles: keyword, variable, start_of_line -Lint/EndAlignment: - Enabled: false - # Offense count: 2 Lint/HandleExceptions: Exclude: From a09ceed68d5080f353498fb6c4ac1f20d3459d2b Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 30 Jun 2016 13:47:28 +0100 Subject: [PATCH 314/365] regenerated .rubocop_todo.yml --- .rubocop_todo.yml | 186 +++++++++++++++++++++++----------------------- 1 file changed, 93 insertions(+), 93 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 595247d390..93a00bba6e 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,6 +1,6 @@ # This configuration was generated by # `rubocop --auto-gen-config` -# on 2016-05-31 10:54:17 +0100 using RuboCop version 0.40.0. +# on 2016-06-30 13:44:53 +0100 using RuboCop version 0.40.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new @@ -20,7 +20,6 @@ Lint/AmbiguousOperator: Lint/AssignmentInCondition: Exclude: - 'app/models/nomenclature_change/output.rb' - - 'lib/tasks/bbgem.rake' # Offense count: 11 # Cop supports --auto-correct. @@ -39,7 +38,7 @@ Lint/HandleExceptions: Exclude: - 'config/initializers/ahoy.rb' -# Offense count: 12 +# Offense count: 13 Lint/IneffectiveAccessModifier: Exclude: - 'app/models/api_request.rb' @@ -83,7 +82,7 @@ Lint/ShadowingOuterLocalVariable: - 'app/helpers/application_helper.rb' - 'app/models/checklist/higher_taxa_injector.rb' -# Offense count: 31 +# Offense count: 29 # Cop supports --auto-correct. # Configuration parameters: AllowUnusedKeywordArguments. Lint/UnusedBlockArgument: @@ -103,7 +102,7 @@ Lint/UselessAccessModifier: - 'app/models/trade/sandbox_template.rb' - 'app/models/trade/trade_data_download_logger.rb' -# Offense count: 94 +# Offense count: 102 Lint/UselessAssignment: Enabled: false @@ -119,26 +118,26 @@ Lint/Void: - 'spec/models/dashboard_stats_trade_spec.rb' - 'spec/models/taxon_concept/moschus_spec.rb' -# Offense count: 203 +# Offense count: 197 Metrics/AbcSize: Max: 743 -# Offense count: 30 +# Offense count: 31 # Configuration parameters: CountComments. Metrics/ClassLength: Max: 800 -# Offense count: 56 +# Offense count: 54 Metrics/CyclomaticComplexity: Max: 31 -# Offense count: 2643 +# Offense count: 2427 # Configuration parameters: AllowHeredoc, AllowURI, URISchemes. # URISchemes: http, https Metrics/LineLength: Max: 562 -# Offense count: 388 +# Offense count: 402 # Configuration parameters: CountComments. Metrics/MethodLength: Max: 798 @@ -148,7 +147,7 @@ Metrics/MethodLength: Metrics/ModuleLength: Max: 427 -# Offense count: 44 +# Offense count: 42 Metrics/PerceivedComplexity: Max: 37 @@ -158,19 +157,17 @@ Performance/RangeInclude: Exclude: - 'app/models/checklist/checklist.rb' -# Offense count: 2 +# Offense count: 1 # Cop supports --auto-correct. Performance/RedundantMatch: Exclude: - 'lib/capistrano/tasks/smoke_test.rake' - - 'old_cap/deploy.rb' -# Offense count: 2 +# Offense count: 1 # Cop supports --auto-correct. Performance/Sample: Exclude: - 'config/deploy.rb' - - 'old_cap/deploy.rb' # Offense count: 25 # Cop supports --auto-correct. @@ -195,26 +192,33 @@ Style/Alias: - 'app/models/nomenclature_change/status_change/constructor_helpers.rb' - 'lib/modules/downloads_cache.rb' -# Offense count: 49 +# Offense count: 18 # Cop supports --auto-correct. Style/AlignArray: - Enabled: false + Exclude: + - 'app/models/checklist/pdf/index_query.rb' + - 'app/models/document_collection_order.rb' + - 'app/models/trade/taxon_concept_source_validation_rule.rb' + - 'config/application.rb' + - 'config/environments/production.rb' + - 'config/environments/staging.rb' + - 'spec/support/sapi_helpers.rb' -# Offense count: 484 +# Offense count: 432 # Cop supports --auto-correct. # Configuration parameters: EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle, SupportedLastArgumentHashStyles. # SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit Style/AlignHash: Enabled: false -# Offense count: 492 +# Offense count: 549 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: with_first_parameter, with_fixed_indentation Style/AlignParameters: Enabled: false -# Offense count: 993 +# Offense count: 1051 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, ProceduralMethods, FunctionalMethods, IgnoredMethods. # SupportedStyles: line_count_based, semantic, braces_for_chaining @@ -224,27 +228,27 @@ Style/AlignParameters: Style/BlockDelimiters: Enabled: false -# Offense count: 243 +# Offense count: 245 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: braces, no_braces, context_dependent Style/BracesAroundHashParameters: Enabled: false -# Offense count: 348 +# Offense count: 351 # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: nested, compact Style/ClassAndModuleChildren: Enabled: false -# Offense count: 48 +# Offense count: 50 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: is_a?, kind_of? Style/ClassCheck: Enabled: false -# Offense count: 200 +# Offense count: 204 # Cop supports --auto-correct. Style/ClosingParenthesisIndentation: Enabled: false @@ -257,14 +261,18 @@ Style/ColonMethodCall: - 'lib/tasks/db_migrate_plpgsql.rake' - 'lib/tasks/import.rake' -# Offense count: 6 +# Offense count: 5 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, SingleLineConditionsOnly. # SupportedStyles: assign_to_condition, assign_inside_condition Style/ConditionalAssignment: - Enabled: false + Exclude: + - 'app/controllers/api/v1/taxon_concepts_controller.rb' + - 'app/models/checklist/checklist.rb' + - 'app/models/trade/filter.rb' + - 'lib/modules/html_to_latex.rb' -# Offense count: 623 +# Offense count: 643 Style/Documentation: Enabled: false @@ -279,7 +287,7 @@ Style/EmptyCaseCondition: Exclude: - 'app/helpers/admin/nomenclature_changes_helper.rb' -# Offense count: 7 +# Offense count: 8 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: empty, nil, both @@ -300,14 +308,14 @@ Style/EmptyElse: Style/EmptyLinesAroundBlockBody: Enabled: false -# Offense count: 351 +# Offense count: 345 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: empty_lines, no_empty_lines Style/EmptyLinesAroundClassBody: Enabled: false -# Offense count: 71 +# Offense count: 72 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: empty_lines, no_empty_lines @@ -320,12 +328,17 @@ Style/EmptyLinesAroundModuleBody: Style/For: Enabled: false -# Offense count: 6 +# Offense count: 5 # Configuration parameters: MinBodyLength. Style/GuardClause: - Enabled: false + Exclude: + - 'app/models/annotation_observer.rb' + - 'app/models/cites_suspension_notification.rb' + - 'app/models/nomenclature_change.rb' + - 'app/models/nomenclature_change/lump.rb' + - 'app/models/nomenclature_change/split.rb' -# Offense count: 8225 +# Offense count: 7517 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, UseHashRocketsWithSymbolValues. # SupportedStyles: ruby19, ruby19_no_mixed_keys, hash_rockets @@ -339,13 +352,13 @@ Style/IfInsideElse: - 'app/models/checklist/pdf/helpers.rb' - 'app/models/checklist/timeline.rb' -# Offense count: 33 +# Offense count: 31 # Cop supports --auto-correct. # Configuration parameters: MaxLineLength. Style/IfUnlessModifier: Enabled: false -# Offense count: 12 +# Offense count: 8 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: line_count_dependent, lambda, literal @@ -355,7 +368,7 @@ Style/Lambda: - 'app/models/taxon_concept.rb' - 'app/models/taxonomy.rb' -# Offense count: 180 +# Offense count: 167 # Cop supports --auto-correct. Style/LeadingCommentSpace: Enabled: false @@ -371,36 +384,39 @@ Style/MultilineBlockChain: Exclude: - 'app/models/trade/filter.rb' -# Offense count: 38 +# Offense count: 9 # Cop supports --auto-correct. Style/MultilineBlockLayout: - Enabled: false + Exclude: + - 'app/controllers/api/v1/documents_controller.rb' + - 'spec/models/document_spec.rb' + - 'spec/models/nomenclature_change/shared/split_definitions.rb' + - 'spec/models/trade/filter_spec.rb' -# Offense count: 147 +# Offense count: 162 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: symmetrical, new_line, same_line Style/MultilineMethodCallBraceLayout: Enabled: false -# Offense count: 370 +# Offense count: 369 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. # SupportedStyles: aligned, indented Style/MultilineMethodCallIndentation: Enabled: false -# Offense count: 95 +# Offense count: 112 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. # SupportedStyles: aligned, indented Style/MultilineOperationIndentation: Enabled: false -# Offense count: 7 +# Offense count: 6 Style/MultilineTernaryOperator: Exclude: - - 'app/models/nomenclature_change/lump.rb' - 'app/models/quota.rb' - 'app/workers/quotas_copy_worker.rb' @@ -426,12 +442,24 @@ Style/NegatedIf: - 'lib/csv_column_headers_validator.rb' - 'lib/tasks/helpers_for_import.rb' -# Offense count: 19 +# Offense count: 15 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, MinBodyLength, SupportedStyles. # SupportedStyles: skip_modifier_ifs, always Style/Next: - Enabled: false + Exclude: + - 'app/models/checklist/higher_taxa_injector.rb' + - 'app/models/distribution.rb' + - 'app/models/nomenclature_change/split.rb' + - 'app/models/trade/validation_rule.rb' + - 'lib/modules/statistics.rb' + - 'lib/tasks/import_trade_names.rake' + - 'spec/shared/boa_constrictor.rb' + - 'spec/shared/canis_lupus.rb' + - 'spec/shared/cervus_elaphus_cms.rb' + - 'spec/shared/falconiformes.rb' + - 'spec/shared/psittaciformes.rb' + - 'spec/support/sapi_helpers.rb' # Offense count: 1 # Cop supports --auto-correct. @@ -448,7 +476,7 @@ Style/Not: - 'app/models/checklist/pdf/history_content.rb' - 'app/models/checklist/pdf/index_content.rb' -# Offense count: 13 +# Offense count: 12 # Cop supports --auto-correct. Style/NumericLiterals: MinDigits: 15 @@ -493,7 +521,7 @@ Style/PerlBackrefs: - 'lib/tasks/elibrary/citations_importer.rb' - 'lib/tasks/elibrary/documents_importer.rb' -# Offense count: 41 +# Offense count: 42 # Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist. # NamePrefix: is_, has_, have_ # NamePrefixBlacklist: is_, has_, have_ @@ -501,16 +529,14 @@ Style/PerlBackrefs: Style/PredicateName: Enabled: false -# Offense count: 16 +# Offense count: 11 # Cop supports --auto-correct. Style/Proc: Exclude: - - 'app/controllers/api/v1/geo_entities_controller.rb' - 'app/controllers/api/v1/purposes_controller.rb' - 'app/controllers/api/v1/sources_controller.rb' - 'app/controllers/api/v1/terms_controller.rb' - 'app/controllers/api/v1/units_controller.rb' - - 'app/controllers/checklist/geo_entities_controller.rb' - 'app/models/nomenclature_change/lump.rb' - 'app/models/nomenclature_change/output.rb' - 'app/models/taxon_relationship.rb' @@ -528,7 +554,7 @@ Style/RedundantParentheses: Exclude: - 'app/models/trade/inclusion_validation_rule.rb' -# Offense count: 4 +# Offense count: 3 # Cop supports --auto-correct. # Configuration parameters: AllowMultipleReturnValues. Style/RedundantReturn: @@ -536,9 +562,8 @@ Style/RedundantReturn: - 'app/models/checklist/checklist.rb' - 'app/models/eu_suspension.rb' - 'app/models/m_taxon_concept.rb' - - 'app/models/nomenclature_change/output.rb' -# Offense count: 249 +# Offense count: 246 # Cop supports --auto-correct. Style/RedundantSelf: Enabled: false @@ -572,7 +597,7 @@ Style/SignalException: Exclude: - 'lib/tasks/elibrary/import.rake' -# Offense count: 37 +# Offense count: 39 # Cop supports --auto-correct. # Configuration parameters: AllowIfMethodIsEmpty. Style/SingleLineMethods: @@ -585,7 +610,7 @@ Style/SpaceAfterColon: - 'app/helpers/taxon_concept_helper.rb' - 'lib/tasks/resolve_host_to_country.rake' -# Offense count: 98 +# Offense count: 99 # Cop supports --auto-correct. Style/SpaceAfterComma: Enabled: false @@ -605,20 +630,20 @@ Style/SpaceAfterNot: - 'app/models/checklist/pdf/history_content.rb' - 'app/models/checklist/pdf/index_content.rb' -# Offense count: 12 +# Offense count: 10 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: space, no_space Style/SpaceAroundEqualsInParameterDefault: Enabled: false -# Offense count: 101 +# Offense count: 93 # Cop supports --auto-correct. # Configuration parameters: AllowForAlignment. Style/SpaceAroundOperators: Enabled: false -# Offense count: 1001 +# Offense count: 1018 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: space, no_space @@ -632,41 +657,30 @@ Style/SpaceBeforeComment: - 'lib/modules/latex_to_pdf.rb' - 'lib/scripts/get_listed_species_per_country.rb' -# Offense count: 2 -# Cop supports --auto-correct. -# Configuration parameters: AllowForAlignment. -Style/SpaceBeforeFirstArg: - Exclude: - - 'app/serializers/trade/inclusion_validation_rule_serializer.rb' - - 'app/serializers/trade/species_name_appendix_year_validation_rule_serializer.rb' - -# Offense count: 326 +# Offense count: 317 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters. # SupportedStyles: space, no_space Style/SpaceInsideBlockBraces: Enabled: false -# Offense count: 13 +# Offense count: 9 # Cop supports --auto-correct. Style/SpaceInsideBrackets: Exclude: - - 'app/helpers/admin/nomenclature_changes_helper.rb' - 'app/models/country_dictionary.rb' - - 'app/models/quota.rb' - 'app/models/trade/taxon_concept_appendix_year_validation_rule.rb' - 'config/initializers/devise.rb' - 'config/routes.rb' - - 'old_cap/deploy.rb' -# Offense count: 698 +# Offense count: 697 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SupportedStyles. # SupportedStyles: space, no_space Style/SpaceInsideHashLiteralBraces: Enabled: false -# Offense count: 35 +# Offense count: 33 # Cop supports --auto-correct. Style/SpaceInsideParens: Exclude: @@ -682,7 +696,6 @@ Style/SpaceInsideParens: - 'lib/tasks/elibrary/citations_rst_importer.rb' - 'lib/tasks/elibrary/document_discussions_importer.rb' - 'lib/tasks/elibrary/documents_importer.rb' - - 'old_cap/deploy.rb' - 'spec/controllers/admin/taxon_eu_suspensions_controller_spec.rb' - 'spec/controllers/admin/taxon_listing_changes_controller_spec.rb' @@ -704,7 +717,7 @@ Style/SpaceInsideStringInterpolation: Style/SpecialGlobalVars: EnforcedStyle: use_perl_names -# Offense count: 6753 +# Offense count: 4985 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, ConsistentQuotesInMultiline. # SupportedStyles: single_quotes, double_quotes @@ -725,7 +738,7 @@ Style/SymbolLiteral: - 'lib/tasks/elibrary/document_discussions_importer.rb' - 'lib/tasks/elibrary/users_importer.rb' -# Offense count: 16 +# Offense count: 17 # Cop supports --auto-correct. # Configuration parameters: IgnoredMethods. # IgnoredMethods: respond_to, define_method @@ -746,25 +759,14 @@ Style/SymbolProc: - 'spec/models/nomenclature_change/lump/constructor_spec.rb' - 'spec/models/nomenclature_change/split/constructor_spec.rb' -# Offense count: 23 -# Cop supports --auto-correct. -Style/Tab: - Exclude: - - 'app/controllers/admin/hash_annotations_controller.rb' - - 'app/controllers/trade/statistics_controller.rb' - - 'app/serializers/species/geo_entity_serializer.rb' - - 'app/serializers/trade/inclusion_validation_rule_serializer.rb' - - 'spec/controllers/api/taxon_concepts_controller_spec.rb' - - 'spec/models/checklist/scientific_name_spec.rb' - -# Offense count: 130 +# Offense count: 121 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. # SupportedStyles: final_newline, final_blank_line Style/TrailingBlankLines: Enabled: false -# Offense count: 7 +# Offense count: 5 # Cop supports --auto-correct. Style/UnlessElse: Exclude: @@ -773,9 +775,8 @@ Style/UnlessElse: - 'app/models/checklist/timeline.rb' - 'app/models/nomenclature_change/split/processor.rb' - 'app/models/nomenclature_change/status_change_processor.rb' - - 'app/models/nomenclature_change/taxonomic_tree_name_resolver.rb' -# Offense count: 25 +# Offense count: 22 # Cop supports --auto-correct. Style/UnneededInterpolation: Exclude: @@ -788,7 +789,6 @@ Style/UnneededInterpolation: - 'app/uploaders/trade/csv_source_file_uploader.rb' - 'lib/psql_command.rb' - 'lib/scripts/get_listed_species_per_country.rb' - - 'old_cap/deploy.rb' - 'spec/controllers/admin/event_documents_controller_spec.rb' - 'spec/factories/listings.rb' - 'spec/models/listing_change_spec.rb' @@ -806,7 +806,7 @@ Style/WhileUntilDo: Exclude: - 'app/models/trade_restriction.rb' -# Offense count: 314 +# Offense count: 295 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, MinSize, WordRegex. # SupportedStyles: percent, brackets From a8ff2d84ebf7672383c6f8c91a93f5205ce41239 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 30 Jun 2016 14:00:52 +0100 Subject: [PATCH 315/365] disabled 2 noisy cops --- .rubocop_todo.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 93a00bba6e..a1d9755799 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -266,6 +266,7 @@ Style/ColonMethodCall: # Configuration parameters: EnforcedStyle, SupportedStyles, SingleLineConditionsOnly. # SupportedStyles: assign_to_condition, assign_inside_condition Style/ConditionalAssignment: + Enabled: false Exclude: - 'app/controllers/api/v1/taxon_concepts_controller.rb' - 'app/models/checklist/checklist.rb' @@ -331,6 +332,7 @@ Style/For: # Offense count: 5 # Configuration parameters: MinBodyLength. Style/GuardClause: + Enabled: false Exclude: - 'app/models/annotation_observer.rb' - 'app/models/cites_suspension_notification.rb' From 7d98a9050dfa462f6f6b98c7310a67e10d1d7c5b Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 30 Jun 2016 14:01:10 +0100 Subject: [PATCH 316/365] enabled Style/SpaceAfterColon --- .rubocop_todo.yml | 7 ------- app/helpers/taxon_concept_helper.rb | 10 +++++----- lib/tasks/resolve_host_to_country.rake | 2 +- 3 files changed, 6 insertions(+), 13 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index a1d9755799..c3a7509f0f 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -605,13 +605,6 @@ Style/SignalException: Style/SingleLineMethods: Enabled: false -# Offense count: 6 -# Cop supports --auto-correct. -Style/SpaceAfterColon: - Exclude: - - 'app/helpers/taxon_concept_helper.rb' - - 'lib/tasks/resolve_host_to_country.rake' - # Offense count: 99 # Cop supports --auto-correct. Style/SpaceAfterComma: diff --git a/app/helpers/taxon_concept_helper.rb b/app/helpers/taxon_concept_helper.rb index 17a8bd7c63..f8a3b38d46 100644 --- a/app/helpers/taxon_concept_helper.rb +++ b/app/helpers/taxon_concept_helper.rb @@ -229,16 +229,16 @@ def taxon_concept_internal_note_label(comment) def taxon_concept_internal_note_form(comment) form_for [:admin, @taxon_concept, comment] do |f| - content_tag(:table, style:'width:100%') do + content_tag(:table, style: 'width:100%') do content_tag(:tr) do - content_tag(:td, style:'width:30%') do + content_tag(:td, style: 'width:30%') do taxon_concept_internal_note_label(comment) end + content_tag(:td) do f.text_area( :note, rows: 4, - style:'width:100%' + style: 'width:100%' ) + f.hidden_field(:comment_type) + f.submit('Update', class: 'btn btn-primary') @@ -250,9 +250,9 @@ def taxon_concept_internal_note_form(comment) def taxon_concept_internal_note_display(comment) return '' unless comment - content_tag(:table, style:'width:100%') do + content_tag(:table, style: 'width:100%') do content_tag(:tr) do - content_tag(:td, style:'width:30%') do + content_tag(:td, style: 'width:30%') do taxon_concept_internal_note_label(comment) end + content_tag(:td, comment.note) diff --git a/lib/tasks/resolve_host_to_country.rake b/lib/tasks/resolve_host_to_country.rake index ee037825ed..302b3a2d04 100644 --- a/lib/tasks/resolve_host_to_country.rake +++ b/lib/tasks/resolve_host_to_country.rake @@ -1,6 +1,6 @@ task :resolve_host_to_country => :environment do require 'csv' - hosts = CSV.read('/home/agnessa/Data/hosts.csv', headers:true) + hosts = CSV.read('/home/agnessa/Data/hosts.csv', headers: true) hosts_and_countries = hosts.map do |row| geo_ip_data = Sapi::GeoIP.instance.resolve(row[0]) [row[0], geo_ip_data[:country]] From 0966a281f6d57575c6c188a677bb7f0a9f5c5180 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 1 Jul 2016 09:14:51 +0100 Subject: [PATCH 317/365] enabled Style/SpaceAfterComma --- .rubocop_todo.yml | 5 ----- app/controllers/admin/quotas_controller.rb | 2 +- app/controllers/api/v1/purposes_controller.rb | 2 +- app/controllers/api/v1/sources_controller.rb | 2 +- .../api/v1/taxon_concepts_controller.rb | 2 +- app/controllers/api/v1/terms_controller.rb | 2 +- app/controllers/api/v1/units_controller.rb | 2 +- app/helpers/admin/api_usage_helper.rb | 2 +- app/helpers/admin/nomenclature_changes_helper.rb | 14 +++++++------- app/models/checklist/pdf/helpers.rb | 2 +- app/models/checklist/pdf/history_content.rb | 4 ++-- app/models/iucn_mapping_manager.rb | 2 +- app/models/taxon_concept.rb | 2 +- app/models/trade/shipments_export.rb | 2 +- app/workers/downloads_cache_cleanup_worker.rb | 2 +- app/workers/permit_cleanup_worker.rb | 2 +- config/initializers/devise.rb | 4 ++-- config/initializers/migration_helpers.rb | 4 ++-- config/initializers/preload_sti_models.rb | 4 ++-- db/migrate/20140709084708_create_ahoy_events.rb | 2 +- lib/modules/csv_exportable.rb | 2 +- lib/modules/downloads_cache.rb | 2 +- lib/modules/latex_to_pdf.rb | 8 ++++---- lib/psql_command.rb | 2 +- lib/tasks/db_migrate_plpgsql.rake | 2 +- lib/tasks/helpers_for_import.rb | 4 ++-- lib/tasks/import_trade_permits.rake | 4 ++-- lib/tasks/import_trade_shipments.rake | 4 ++-- .../controllers/admin/documents_controller_spec.rb | 10 +++++----- .../admin/event_documents_controller_spec.rb | 2 +- .../admin/taxon_eu_suspensions_controller_spec.rb | 2 +- spec/factories.rb | 2 +- spec/shared/agalychnis.rb | 2 +- spec/shared/agave.rb | 2 +- spec/shared/ailuropoda.rb | 2 +- spec/shared/arctocephalus.rb | 2 +- spec/shared/boa_constrictor.rb | 2 +- spec/shared/caiman_latirostris.rb | 2 +- spec/shared/canis_lupus.rb | 2 +- spec/shared/caretta_caretta_cms.rb | 2 +- spec/shared/cedrela_montana.rb | 2 +- spec/shared/cervus_elaphus.rb | 2 +- spec/shared/cervus_elaphus_cms.rb | 2 +- spec/shared/colophon.rb | 2 +- spec/shared/dalbergia.rb | 2 +- spec/shared/diospyros.rb | 2 +- spec/shared/falconiformes.rb | 2 +- spec/shared/hirudo_medicinalis.rb | 2 +- spec/shared/loxodonta_africana.rb | 2 +- spec/shared/loxodonta_africana_cms.rb | 2 +- spec/shared/mellivora_capensis.rb | 2 +- spec/shared/moschus.rb | 2 +- spec/shared/natator_depressus.rb | 2 +- spec/shared/notomys_aquilo.rb | 2 +- spec/shared/panax_ginseng.rb | 2 +- spec/shared/pecari_tajacu.rb | 2 +- spec/shared/pereskia.rb | 2 +- spec/shared/platysternon_megacephalum.rb | 2 +- spec/shared/pristis_microdon.rb | 2 +- spec/shared/pseudomys_fieldi.rb | 2 +- spec/shared/psittaciformes.rb | 2 +- spec/shared/tapiridae.rb | 2 +- spec/shared/uroplatus.rb | 2 +- spec/shared/varanidae.rb | 2 +- 64 files changed, 83 insertions(+), 88 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index c3a7509f0f..bd3ef9a760 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -605,11 +605,6 @@ Style/SignalException: Style/SingleLineMethods: Enabled: false -# Offense count: 99 -# Cop supports --auto-correct. -Style/SpaceAfterComma: - Enabled: false - # Offense count: 1 # Cop supports --auto-correct. Style/SpaceAfterMethodName: diff --git a/app/controllers/admin/quotas_controller.rb b/app/controllers/admin/quotas_controller.rb index a85f69218c..2faa04877f 100644 --- a/app/controllers/admin/quotas_controller.rb +++ b/app/controllers/admin/quotas_controller.rb @@ -3,7 +3,7 @@ class Admin::QuotasController < Admin::StandardAuthorizationController def index @years = Quota.years_array if params[:year] && !@years.include?(params[:year]) - @years = @years.push(params[:year]).sort{|a,b| b <=> a} + @years = @years.push(params[:year]).sort{|a, b| b <=> a} end index! end diff --git a/app/controllers/api/v1/purposes_controller.rb b/app/controllers/api/v1/purposes_controller.rb index c722b57285..3976268cb6 100644 --- a/app/controllers/api/v1/purposes_controller.rb +++ b/app/controllers/api/v1/purposes_controller.rb @@ -1,6 +1,6 @@ class Api::V1::PurposesController < ApplicationController caches_action :index, :cache_path => Proc.new { |c| - {:locale => "en"}.merge(c.params.select{|k,v| !v.blank? && "locale" == k}) + {:locale => "en"}.merge(c.params.select{|k, v| !v.blank? && "locale" == k}) } def index @purposes = Purpose.all(:order => "code") diff --git a/app/controllers/api/v1/sources_controller.rb b/app/controllers/api/v1/sources_controller.rb index 404607e617..cd3c298da4 100644 --- a/app/controllers/api/v1/sources_controller.rb +++ b/app/controllers/api/v1/sources_controller.rb @@ -1,6 +1,6 @@ class Api::V1::SourcesController < ApplicationController caches_action :index, :cache_path => Proc.new { |c| - {:locale => "en"}.merge(c.params.select{|k,v| !v.blank? && "locale" == k}) + {:locale => "en"}.merge(c.params.select{|k, v| !v.blank? && "locale" == k}) } def index @sources = Source.all(:order => "code") diff --git a/app/controllers/api/v1/taxon_concepts_controller.rb b/app/controllers/api/v1/taxon_concepts_controller.rb index 2d20de3c0c..a7fcc4aa17 100644 --- a/app/controllers/api/v1/taxon_concepts_controller.rb +++ b/app/controllers/api/v1/taxon_concepts_controller.rb @@ -41,6 +41,6 @@ def track_index end def track_show - ahoy.track "Taxon Concept",{:id => @taxon_concept.id, :full_name => @taxon_concept.full_name, :taxonomy_name => @taxon_concept.taxonomy.name, :rank_name => @taxon_concept.rank_name, :family_name => @taxon_concept.data['family_name']} + ahoy.track "Taxon Concept", {:id => @taxon_concept.id, :full_name => @taxon_concept.full_name, :taxonomy_name => @taxon_concept.taxonomy.name, :rank_name => @taxon_concept.rank_name, :family_name => @taxon_concept.data['family_name']} end end diff --git a/app/controllers/api/v1/terms_controller.rb b/app/controllers/api/v1/terms_controller.rb index e8de151c5e..23c94d2ef0 100644 --- a/app/controllers/api/v1/terms_controller.rb +++ b/app/controllers/api/v1/terms_controller.rb @@ -1,6 +1,6 @@ class Api::V1::TermsController < ApplicationController caches_action :index, :cache_path => Proc.new { |c| - {:locale => "en"}.merge(c.params.select{|k,v| !v.blank? && "locale" == k}) + {:locale => "en"}.merge(c.params.select{|k, v| !v.blank? && "locale" == k}) } def index @terms = Term.all(:order => "code") diff --git a/app/controllers/api/v1/units_controller.rb b/app/controllers/api/v1/units_controller.rb index f7d7bbd89c..3250bac2ab 100644 --- a/app/controllers/api/v1/units_controller.rb +++ b/app/controllers/api/v1/units_controller.rb @@ -1,6 +1,6 @@ class Api::V1::UnitsController < ApplicationController caches_action :index, :cache_path => Proc.new { |c| - {:locale => "en"}.merge(c.params.select{|k,v| !v.blank? && "locale" == k}) + {:locale => "en"}.merge(c.params.select{|k, v| !v.blank? && "locale" == k}) } def index @units = Unit.all(:order => "code") diff --git a/app/helpers/admin/api_usage_helper.rb b/app/helpers/admin/api_usage_helper.rb index 2326a22d54..1c5d05d343 100644 --- a/app/helpers/admin/api_usage_helper.rb +++ b/app/helpers/admin/api_usage_helper.rb @@ -12,7 +12,7 @@ def controller_colours # and anything else with 'Failed' and return newly constructed hash def sanitise_hash_for_line_graph(hash) new_hash = {} - hash.map { |k,v| + hash.map { |k, v| n = k[0] == 200 ? 'Successful' : 'Failed' new_hash[[n, k[1]]] = v } diff --git a/app/helpers/admin/nomenclature_changes_helper.rb b/app/helpers/admin/nomenclature_changes_helper.rb index c7936af268..b819ed7182 100644 --- a/app/helpers/admin/nomenclature_changes_helper.rb +++ b/app/helpers/admin/nomenclature_changes_helper.rb @@ -219,10 +219,10 @@ def lump_inputs_content @nc.inputs.each_with_index do |input, idx| tc = input.taxon_concept if idx == 0 - concat content_tag(:div, inner_content(input,tc), + concat content_tag(:div, inner_content(input, tc), {id: "#{tc.full_name.downcase.tr(" ", "_")}", class: "tab-pane fade in active"}) else - concat content_tag(:div, inner_content(input,tc), + concat content_tag(:div, inner_content(input, tc), {id: "#{tc.full_name.downcase.tr(" ", "_")}", class: "tab-pane fade"}) end end @@ -289,17 +289,17 @@ def outputs_content outputs.each_with_index do |output, idx| tc = output.new_taxon_concept || output.taxon_concept if idx == 0 - concat content_tag(:div, inner_content(output,tc), + concat content_tag(:div, inner_content(output, tc), {id: "#{tc.full_name.downcase.tr(" ", "_")}", class: "tab-pane fade in active"}) else - concat content_tag(:div, inner_content(output,tc), + concat content_tag(:div, inner_content(output, tc), {id: "#{tc.full_name.downcase.tr(" ", "_")}", class: "tab-pane fade"}) end end end end - def inner_content(input_or_output,tc) + def inner_content(input_or_output, tc) is_output = input_or_output.is_a?(NomenclatureChange::Output) content_tag(:p, content_tag(:i, link_to(tc.full_name, admin_taxon_concept_names_path(tc)), nil) @@ -342,7 +342,7 @@ def name_reassignment_label(reassignment) end def select_taxonomy - select("taxonomy","taxonomy_id", Taxonomy.all.collect {|t| [t.name, t.id]}) + select("taxonomy", "taxonomy_id", Taxonomy.all.collect {|t| [t.name, t.id]}) end def select_rank @@ -360,7 +360,7 @@ def taxon_concepts_collection def new_name_scientific_name_hint case @nomenclature_change.output.new_name_status when 'A' then "e.g. 'africana' for Loxodonta africana" - when 'S','H' then "e.g. Loxodonta africana" + when 'S', 'H' then "e.g. Loxodonta africana" end end end diff --git a/app/models/checklist/pdf/helpers.rb b/app/models/checklist/pdf/helpers.rb index 99a24c7a51..a00931fb04 100644 --- a/app/models/checklist/pdf/helpers.rb +++ b/app/models/checklist/pdf/helpers.rb @@ -16,7 +16,7 @@ def common_names_with_lng_initials(taxon_concept) def taxon_name_at_rank(taxon_concept) res = - if ['FAMILY','SUBFAMILY','ORDER','CLASS'].include? taxon_concept.rank_name + if ['FAMILY', 'SUBFAMILY', 'ORDER', 'CLASS'].include? taxon_concept.rank_name LatexToPdf.escape_latex(taxon_concept.full_name.upcase) else if ['SPECIES', 'SUBSPECIES', 'GENUS'].include? taxon_concept.rank_name diff --git a/app/models/checklist/pdf/history_content.rb b/app/models/checklist/pdf/history_content.rb index 98ff337720..3592300693 100644 --- a/app/models/checklist/pdf/history_content.rb +++ b/app/models/checklist/pdf/history_content.rb @@ -117,7 +117,7 @@ def annotation_for_language(listing_change, lng) def listed_taxon_name(taxon_concept) res = - if ['FAMILY','SUBFAMILY','ORDER','CLASS'].include? taxon_concept.rank_name + if ['FAMILY', 'SUBFAMILY', 'ORDER', 'CLASS'].include? taxon_concept.rank_name taxon_concept.full_name.upcase else taxon_concept.full_name @@ -137,7 +137,7 @@ def higher_taxon_name(taxon_concept) "\\section*{\\underline{#{taxon_concept.full_name.upcase}} #{common_names}}\n" elsif taxon_concept.rank_name == 'ORDER' && taxon_concept.kingdom_name == 'Animalia' "\\subsection*{#{taxon_concept.full_name.upcase} #{common_names}}\n" - elsif ['FAMILY','SUBFAMILY'].include? taxon_concept.rank_name + elsif ['FAMILY', 'SUBFAMILY'].include? taxon_concept.rank_name "\\subsection*{#{taxon_concept.full_name.upcase} #{common_names}}\n" end end diff --git a/app/models/iucn_mapping_manager.rb b/app/models/iucn_mapping_manager.rb index 7c437660f2..d4ad959723 100644 --- a/app/models/iucn_mapping_manager.rb +++ b/app/models/iucn_mapping_manager.rb @@ -7,7 +7,7 @@ def sync @subspecies = Rank.where(:name => Rank::SUBSPECIES).first taxonomy = Taxonomy.where(:name => Taxonomy::CITES_EU).first - TaxonConcept.where(:rank_id => [species.id, @subspecies.id], :name_status => ['A','S'], + TaxonConcept.where(:rank_id => [species.id, @subspecies.id], :name_status => ['A', 'S'], :taxonomy_id => taxonomy.id).each do |taxon_concept| sync_taxon_concept taxon_concept end diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index 02081a5472..8d0063207b 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -420,7 +420,7 @@ def add_remove_relationships(new_taxa, removed_taxa, rel_type) end def init_accepted_taxa(new_ids) - return [[],[]] unless ['S', 'T', 'H'].include?(name_status) + return [[], []] unless ['S', 'T', 'H'].include?(name_status) current_ids = case name_status when 'S' then accepted_names.pluck(:id) diff --git a/app/models/trade/shipments_export.rb b/app/models/trade/shipments_export.rb index 9045ad0a82..c519eaecb8 100644 --- a/app/models/trade/shipments_export.rb +++ b/app/models/trade/shipments_export.rb @@ -79,7 +79,7 @@ def table_name def copy_stmt # escape quotes around attributes for psql sql = <<-PSQL - \\COPY (#{query_sql(:limit => !internal?).gsub(/"/,"\\\"")}) + \\COPY (#{query_sql(:limit => !internal?).gsub(/"/, "\\\"")}) TO ? WITH DELIMITER '#{@csv_separator_char}' ENCODING 'latin1' diff --git a/app/workers/downloads_cache_cleanup_worker.rb b/app/workers/downloads_cache_cleanup_worker.rb index a259a27716..8cdcf104b0 100644 --- a/app/workers/downloads_cache_cleanup_worker.rb +++ b/app/workers/downloads_cache_cleanup_worker.rb @@ -1,6 +1,6 @@ class DownloadsCacheCleanupWorker include Sidekiq::Worker - sidekiq_options :queue => :admin,:backtrace => 50 + sidekiq_options :queue => :admin, :backtrace => 50 def perform(type_of_cache) DownloadsCache.send(:"clear_#{type_of_cache}") diff --git a/app/workers/permit_cleanup_worker.rb b/app/workers/permit_cleanup_worker.rb index f7d13d3065..f31d1d8c0a 100644 --- a/app/workers/permit_cleanup_worker.rb +++ b/app/workers/permit_cleanup_worker.rb @@ -1,6 +1,6 @@ class PermitCleanupWorker include Sidekiq::Worker - sidekiq_options :queue => :admin,:backtrace => 50 + sidekiq_options :queue => :admin, :backtrace => 50 def perform(permits_ids=[]) return if permits_ids.empty? diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index caaf98c2d2..a9d6a1f8bd 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -267,11 +267,11 @@ manager.failure_app = CustomFailure end - Warden::Manager.after_set_user do |user,auth,opts| + Warden::Manager.after_set_user do |user, auth, opts| auth.cookies[:"speciesplus.signed_in"] = 1 end - Warden::Manager.before_logout do |user,auth,opts| + Warden::Manager.before_logout do |user, auth, opts| auth.cookies.delete :"speciesplus.signed_in" end diff --git a/config/initializers/migration_helpers.rb b/config/initializers/migration_helpers.rb index f4073eed57..667d1a6027 100644 --- a/config/initializers/migration_helpers.rb +++ b/config/initializers/migration_helpers.rb @@ -1,10 +1,10 @@ # http://pivotallabs.com/rails-and-sql-views-part-2-migrations/ ActiveRecord::Migration.class_eval do - def view_sql(timestamp,view) + def view_sql(timestamp, view) File.read(Rails.root.join("db/views/#{view}/#{timestamp}.sql")) end - def function_sql(timestamp,function) + def function_sql(timestamp, function) File.read(Rails.root.join("db/functions/#{function}/#{timestamp}.sql")) end end diff --git a/config/initializers/preload_sti_models.rb b/config/initializers/preload_sti_models.rb index 95d0dfee9e..9e348fd5ee 100644 --- a/config/initializers/preload_sti_models.rb +++ b/config/initializers/preload_sti_models.rb @@ -1,10 +1,10 @@ if Rails.env.development? - require_dependency File.join("app","models","document.rb") + require_dependency File.join("app", "models", "document.rb") Dir.glob(Rails.root.join("app/models/document/*.rb")).each do |path| require_dependency path end %w[cites_cop cites_ac cites_pc cites_tc cites_extraordinary_meeting ec_srg].each do |c| - require_dependency File.join("app","models","#{c}.rb") + require_dependency File.join("app", "models", "#{c}.rb") end end \ No newline at end of file diff --git a/db/migrate/20140709084708_create_ahoy_events.rb b/db/migrate/20140709084708_create_ahoy_events.rb index b754046c0f..e7f39aac27 100644 --- a/db/migrate/20140709084708_create_ahoy_events.rb +++ b/db/migrate/20140709084708_create_ahoy_events.rb @@ -9,7 +9,7 @@ def change # add t.string :user_type if polymorphic t.string :name - t.column :properties,:json + t.column :properties, :json t.timestamp :time end diff --git a/lib/modules/csv_exportable.rb b/lib/modules/csv_exportable.rb index eccaa1b527..f5171cb639 100644 --- a/lib/modules/csv_exportable.rb +++ b/lib/modules/csv_exportable.rb @@ -11,7 +11,7 @@ def copy_stmt(options) basic_query = query_sql(options[:query], options[:csv_columns]) # escape quotes around attributes for psql sql =<<-PSQL - \\COPY (#{basic_query.gsub(/"/,"\\\"")}) + \\COPY (#{basic_query.gsub(/"/, "\\\"")}) TO :file_name WITH DELIMITER :delimiter ENCODING :encoding diff --git a/lib/modules/downloads_cache.rb b/lib/modules/downloads_cache.rb index 45316f77fd..e6625e4713 100644 --- a/lib/modules/downloads_cache.rb +++ b/lib/modules/downloads_cache.rb @@ -80,7 +80,7 @@ def self.clear_taxon_instruments end def self.clear_taxon_concept_references - clear_dirs(['species_reference_output','standard_reference_output']) + clear_dirs(['species_reference_output', 'standard_reference_output']) end def self.clear_documents diff --git a/lib/modules/latex_to_pdf.rb b/lib/modules/latex_to_pdf.rb index de46938dc8..cc75f65c17 100644 --- a/lib/modules/latex_to_pdf.rb +++ b/lib/modules/latex_to_pdf.rb @@ -13,17 +13,17 @@ def self.config # The dir argument is the name of the intermediate files directory. # # The input argument is the name of the tex file without the '.tex' - def self.generate_pdf_from_file(dir,input) + def self.generate_pdf_from_file(dir, input) Process.waitpid( fork do begin Dir.chdir dir original_stdout, original_stderr = $stdout, $stderr - $stderr = $stdout = File.open("#{input}.log","a") + $stderr = $stdout = File.open("#{input}.log", "a") args=config[:arguments] + %w[-shell-escape -interaction batchmode] + ["#{input}.tex"] - exec config[:command],*args + exec config[:command], *args rescue - File.open("#{input}.log",'a') {|io| + File.open("#{input}.log", 'a') {|io| io.write("#{$!.message}:\n#{$!.backtrace.join("\n")}\n") } ensure diff --git a/lib/psql_command.rb b/lib/psql_command.rb index 8d564c915d..ace411b476 100644 --- a/lib/psql_command.rb +++ b/lib/psql_command.rb @@ -8,7 +8,7 @@ def initialize(sql_cmd) @password = db_conf[:password] @database = db_conf[:database] # remove comments form multi line sql - @sql_cmd = sql_cmd.gsub(/--.*$/,' ') + @sql_cmd = sql_cmd.gsub(/--.*$/, ' ') @psql_cmd = "psql -h #{@host} -p #{@port} -U #{@username} #{@database}" end diff --git a/lib/tasks/db_migrate_plpgsql.rake b/lib/tasks/db_migrate_plpgsql.rake index 683329daf8..3092cedc55 100644 --- a/lib/tasks/db_migrate_plpgsql.rake +++ b/lib/tasks/db_migrate_plpgsql.rake @@ -2,7 +2,7 @@ namespace :db do namespace :migrate do desc "Run custom sql scripts" task :sql => :environment do - ['helpers','mviews', 'plpgsql'].each do |dir| + ['helpers', 'mviews', 'plpgsql'].each do |dir| files = Dir.glob(Rails.root.join("db/#{dir}/*.sql")) files.sort.each do |file| puts file diff --git a/lib/tasks/helpers_for_import.rb b/lib/tasks/helpers_for_import.rb index 8b61c20d2a..31b94ec439 100644 --- a/lib/tasks/helpers_for_import.rb +++ b/lib/tasks/helpers_for_import.rb @@ -357,7 +357,7 @@ def file_ok?(path_to_file) def csv_headers(path_to_file) res = nil CSV.foreach(path_to_file) do |row| - res = row.map{ |h| h && h.chomp.sub(/^\W/,'') }.compact + res = row.map{ |h| h && h.chomp.sub(/^\W/, '') }.compact break end res @@ -368,7 +368,7 @@ def db_columns_from_csv_headers(path_to_file, table_name, include_data_type = tr #work out the db columns to create csv_columns = csv_headers(path_to_file) db_columns = csv_columns.map{ |col| m.csv_to_db(table_name, col) } - db_columns = db_columns.map{ |col| col.sub(/\s\w+$/,'')} unless include_data_type + db_columns = db_columns.map{ |col| col.sub(/\s\w+$/, '')} unless include_data_type puts csv_columns.inspect puts db_columns.inspect db_columns diff --git a/lib/tasks/import_trade_permits.rake b/lib/tasks/import_trade_permits.rake index a68b8d0303..5f88515375 100644 --- a/lib/tasks/import_trade_permits.rake +++ b/lib/tasks/import_trade_permits.rake @@ -53,7 +53,7 @@ def drop_indices(index) end def create_indices(table_columns, method) - table_columns.each do |table,columns| + table_columns.each do |table, columns| columns.each do |column| sql = <<-SQL CREATE INDEX index_#{table}_on_#{column} @@ -81,7 +81,7 @@ end def insert_into_trade_shipments permits_entity = {"import" => "I", "export" => 'E', "origin" => 'O'} - permits_entity.each do |k,v| + permits_entity.each do |k, v| sql = <<-SQL WITH grouped_permits AS ( SELECT array_agg(id) AS ids, diff --git a/lib/tasks/import_trade_shipments.rake b/lib/tasks/import_trade_shipments.rake index c7a9673b56..69e4df44b1 100644 --- a/lib/tasks/import_trade_shipments.rake +++ b/lib/tasks/import_trade_shipments.rake @@ -32,7 +32,7 @@ namespace :import do SQL ActiveRecord::Base.connection.execute(sql) fix_term_codes = {12227624 => "LIV", 12225022 => "DER", 12224783 => "DER"} - fix_term_codes.each do |shipment_number,term_code| + fix_term_codes.each do |shipment_number, term_code| sql = <<-SQL UPDATE shipments_import SET term_code_1 = '#{term_code}' WHERE shipment_number = #{shipment_number}; SQL @@ -60,7 +60,7 @@ namespace :import do SQL ActiveRecord::Base.connection.execute(sql) fix_term_codes = {12227624 => "LIV", 12225022 => "DER", 12224783 => "DER"} - fix_term_codes.each do |shipment_number,term_code| + fix_term_codes.each do |shipment_number, term_code| sql = <<-SQL UPDATE shipments_import SET term_code_1 = '#{term_code}' WHERE shipment_number = #{shipment_number}; SQL diff --git a/spec/controllers/admin/documents_controller_spec.rb b/spec/controllers/admin/documents_controller_spec.rb index 9bb01d1c85..edad38cefd 100644 --- a/spec/controllers/admin/documents_controller_spec.rb +++ b/spec/controllers/admin/documents_controller_spec.rb @@ -2,8 +2,8 @@ describe Admin::DocumentsController, sidekiq: :inline do login_admin - let(:event){ create(:event, published_at: DateTime.new(2014,12,25)) } - let(:event2){ create(:event, published_at: DateTime.new(2015,12,12)) } + let(:event){ create(:event, published_at: DateTime.new(2014, 12, 25)) } + let(:event2){ create(:event, published_at: DateTime.new(2015, 12, 12)) } let(:taxon_concept){ create(:taxon_concept) } let(:geo_entity){ create(:geo_entity) } let(:proposal_outcome){ create(:proposal_outcome) } @@ -20,7 +20,7 @@ describe "GET index" do before(:each) do - @document3 = create(:document, :title => 'CC no event!', date: DateTime.new(2014,01,01)) + @document3 = create(:document, :title => 'CC no event!', date: DateTime.new(2014, 01, 01)) DocumentSearch.refresh_citations_and_documents end @@ -64,7 +64,7 @@ end context 'by proposal outcome' do before(:each) do - @document3 = create(:proposal, event: create_cites_cop(published_at: DateTime.new(2014,01,01))) + @document3 = create(:proposal, event: create_cites_cop(published_at: DateTime.new(2014, 01, 01))) create(:proposal_details, document_id: @document3.id, proposal_outcome_id: proposal_outcome.id) DocumentSearch.refresh_citations_and_documents end @@ -75,7 +75,7 @@ end context 'by document tags' do before(:each) do - @document3 = create(:review_of_significant_trade, event: create_ec_srg(published_at: DateTime.new(2014,01,01))) + @document3 = create(:review_of_significant_trade, event: create_ec_srg(published_at: DateTime.new(2014, 01, 01))) create(:review_details, document_id: @document3.id, review_phase_id: review_phase.id, process_stage_id: process_stage.id) DocumentSearch.refresh_citations_and_documents end diff --git a/spec/controllers/admin/event_documents_controller_spec.rb b/spec/controllers/admin/event_documents_controller_spec.rb index f3619370f1..e09dc70e16 100644 --- a/spec/controllers/admin/event_documents_controller_spec.rb +++ b/spec/controllers/admin/event_documents_controller_spec.rb @@ -2,7 +2,7 @@ describe Admin::EventDocumentsController, sidekiq: :inline do login_admin - let(:event){ create(:event, published_at: DateTime.new(2014,12,25)) } + let(:event){ create(:event, published_at: DateTime.new(2014, 12, 25)) } describe "ordering" do before(:each) do diff --git a/spec/controllers/admin/taxon_eu_suspensions_controller_spec.rb b/spec/controllers/admin/taxon_eu_suspensions_controller_spec.rb index f874f51468..8249254c39 100644 --- a/spec/controllers/admin/taxon_eu_suspensions_controller_spec.rb +++ b/spec/controllers/admin/taxon_eu_suspensions_controller_spec.rb @@ -40,7 +40,7 @@ post :create, :eu_suspension => { :eu_decision_type_id => @eu_decision_type.id, - :start_date => Date.new(2013,1,1), + :start_date => Date.new(2013, 1, 1), :geo_entity_id => create( :geo_entity, :geo_entity_type_id => country_geo_entity_type.id ) diff --git a/spec/factories.rb b/spec/factories.rb index b3a8c3a9e8..05322a51d2 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -91,7 +91,7 @@ eu_decision_type factory :eu_opinion, class: EuOpinion do - start_date Date.new(2013,1,1) + start_date Date.new(2013, 1, 1) end factory :eu_suspension, class: EuSuspension diff --git a/spec/shared/agalychnis.rb b/spec/shared/agalychnis.rb index a299d0394d..f8cca602bd 100644 --- a/spec/shared/agalychnis.rb +++ b/spec/shared/agalychnis.rb @@ -56,7 +56,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload end end diff --git a/spec/shared/agave.rb b/spec/shared/agave.rb index cedbb6209e..de71dee9a6 100644 --- a/spec/shared/agave.rb +++ b/spec/shared/agave.rb @@ -70,7 +70,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload end end diff --git a/spec/shared/ailuropoda.rb b/spec/shared/ailuropoda.rb index f1dc84e56d..77f2bb8eec 100644 --- a/spec/shared/ailuropoda.rb +++ b/spec/shared/ailuropoda.rb @@ -46,7 +46,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload end end diff --git a/spec/shared/arctocephalus.rb b/spec/shared/arctocephalus.rb index c14a4083fb..bd2db54b84 100644 --- a/spec/shared/arctocephalus.rb +++ b/spec/shared/arctocephalus.rb @@ -110,7 +110,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload end end diff --git a/spec/shared/boa_constrictor.rb b/spec/shared/boa_constrictor.rb index e48ffbed33..97c9050230 100644 --- a/spec/shared/boa_constrictor.rb +++ b/spec/shared/boa_constrictor.rb @@ -86,7 +86,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload self.instance_variable_set(:"#{t}_ac", MAutoCompleteTaxonConcept. diff --git a/spec/shared/caiman_latirostris.rb b/spec/shared/caiman_latirostris.rb index 56da7aa9ac..c06394418d 100644 --- a/spec/shared/caiman_latirostris.rb +++ b/spec/shared/caiman_latirostris.rb @@ -156,7 +156,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload end end diff --git a/spec/shared/canis_lupus.rb b/spec/shared/canis_lupus.rb index 8b6dccb38f..5f5f07df20 100644 --- a/spec/shared/canis_lupus.rb +++ b/spec/shared/canis_lupus.rb @@ -171,7 +171,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload self.instance_variable_set(:"#{t}_ac", MAutoCompleteTaxonConcept. diff --git a/spec/shared/caretta_caretta_cms.rb b/spec/shared/caretta_caretta_cms.rb index 649d163f73..2e44e4258a 100644 --- a/spec/shared/caretta_caretta_cms.rb +++ b/spec/shared/caretta_caretta_cms.rb @@ -34,7 +34,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload end end diff --git a/spec/shared/cedrela_montana.rb b/spec/shared/cedrela_montana.rb index 810609b5c5..9c6afdbaaf 100644 --- a/spec/shared/cedrela_montana.rb +++ b/spec/shared/cedrela_montana.rb @@ -28,7 +28,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload end end diff --git a/spec/shared/cervus_elaphus.rb b/spec/shared/cervus_elaphus.rb index 0411a776f5..3f2e695017 100644 --- a/spec/shared/cervus_elaphus.rb +++ b/spec/shared/cervus_elaphus.rb @@ -73,7 +73,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload end end diff --git a/spec/shared/cervus_elaphus_cms.rb b/spec/shared/cervus_elaphus_cms.rb index edc66d38d1..29bb500fe7 100644 --- a/spec/shared/cervus_elaphus_cms.rb +++ b/spec/shared/cervus_elaphus_cms.rb @@ -56,7 +56,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload self.instance_variable_set(:"#{t}_ac", MAutoCompleteTaxonConcept. diff --git a/spec/shared/colophon.rb b/spec/shared/colophon.rb index 65a114798c..c8918ca39c 100644 --- a/spec/shared/colophon.rb +++ b/spec/shared/colophon.rb @@ -56,7 +56,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload end end diff --git a/spec/shared/dalbergia.rb b/spec/shared/dalbergia.rb index bf9b19f909..e5520ada82 100644 --- a/spec/shared/dalbergia.rb +++ b/spec/shared/dalbergia.rb @@ -69,7 +69,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload end end diff --git a/spec/shared/diospyros.rb b/spec/shared/diospyros.rb index 008365436a..d16965fe0d 100644 --- a/spec/shared/diospyros.rb +++ b/spec/shared/diospyros.rb @@ -127,7 +127,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload end end diff --git a/spec/shared/falconiformes.rb b/spec/shared/falconiformes.rb index c791158d20..ddd69ae665 100644 --- a/spec/shared/falconiformes.rb +++ b/spec/shared/falconiformes.rb @@ -161,7 +161,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload self.instance_variable_set(:"#{t}_ac", MAutoCompleteTaxonConcept. diff --git a/spec/shared/hirudo_medicinalis.rb b/spec/shared/hirudo_medicinalis.rb index 7413aff45e..d7d3b57849 100644 --- a/spec/shared/hirudo_medicinalis.rb +++ b/spec/shared/hirudo_medicinalis.rb @@ -34,7 +34,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload end end diff --git a/spec/shared/loxodonta_africana.rb b/spec/shared/loxodonta_africana.rb index ac904178e9..6cf3c4a355 100644 --- a/spec/shared/loxodonta_africana.rb +++ b/spec/shared/loxodonta_africana.rb @@ -116,7 +116,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload end end diff --git a/spec/shared/loxodonta_africana_cms.rb b/spec/shared/loxodonta_africana_cms.rb index 623acc43cf..417b2e3732 100644 --- a/spec/shared/loxodonta_africana_cms.rb +++ b/spec/shared/loxodonta_africana_cms.rb @@ -28,7 +28,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload end end diff --git a/spec/shared/mellivora_capensis.rb b/spec/shared/mellivora_capensis.rb index 0c0e5ca540..2fe2bd97c9 100644 --- a/spec/shared/mellivora_capensis.rb +++ b/spec/shared/mellivora_capensis.rb @@ -120,7 +120,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload end end diff --git a/spec/shared/moschus.rb b/spec/shared/moschus.rb index 100e732a0f..e10d46f58f 100644 --- a/spec/shared/moschus.rb +++ b/spec/shared/moschus.rb @@ -160,7 +160,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload end end diff --git a/spec/shared/natator_depressus.rb b/spec/shared/natator_depressus.rb index 7076586d29..726df9c02d 100644 --- a/spec/shared/natator_depressus.rb +++ b/spec/shared/natator_depressus.rb @@ -53,7 +53,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload end end diff --git a/spec/shared/notomys_aquilo.rb b/spec/shared/notomys_aquilo.rb index 928e1ca454..560c99b83a 100644 --- a/spec/shared/notomys_aquilo.rb +++ b/spec/shared/notomys_aquilo.rb @@ -38,7 +38,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload end end diff --git a/spec/shared/panax_ginseng.rb b/spec/shared/panax_ginseng.rb index 3c9cb4864f..1e6ef60767 100644 --- a/spec/shared/panax_ginseng.rb +++ b/spec/shared/panax_ginseng.rb @@ -88,7 +88,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload end end diff --git a/spec/shared/pecari_tajacu.rb b/spec/shared/pecari_tajacu.rb index 2fc963cdce..94e1e69dd6 100644 --- a/spec/shared/pecari_tajacu.rb +++ b/spec/shared/pecari_tajacu.rb @@ -110,7 +110,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload end end diff --git a/spec/shared/pereskia.rb b/spec/shared/pereskia.rb index 08014d82a2..2cfb852421 100644 --- a/spec/shared/pereskia.rb +++ b/spec/shared/pereskia.rb @@ -59,7 +59,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload end end diff --git a/spec/shared/platysternon_megacephalum.rb b/spec/shared/platysternon_megacephalum.rb index 3cdd5cfd72..9c60a6add9 100644 --- a/spec/shared/platysternon_megacephalum.rb +++ b/spec/shared/platysternon_megacephalum.rb @@ -56,7 +56,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload end end diff --git a/spec/shared/pristis_microdon.rb b/spec/shared/pristis_microdon.rb index 45e464ae53..e9c68e1e7a 100644 --- a/spec/shared/pristis_microdon.rb +++ b/spec/shared/pristis_microdon.rb @@ -64,7 +64,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload end end diff --git a/spec/shared/pseudomys_fieldi.rb b/spec/shared/pseudomys_fieldi.rb index 610baa780f..1d6671b7ac 100644 --- a/spec/shared/pseudomys_fieldi.rb +++ b/spec/shared/pseudomys_fieldi.rb @@ -54,7 +54,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload end end diff --git a/spec/shared/psittaciformes.rb b/spec/shared/psittaciformes.rb index 2db57afe57..9d3fb3d5f3 100644 --- a/spec/shared/psittaciformes.rb +++ b/spec/shared/psittaciformes.rb @@ -254,7 +254,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload self.instance_variable_set(:"#{t}_ac", MAutoCompleteTaxonConcept. diff --git a/spec/shared/tapiridae.rb b/spec/shared/tapiridae.rb index 68f1bd02a2..b479909fa6 100644 --- a/spec/shared/tapiridae.rb +++ b/spec/shared/tapiridae.rb @@ -48,7 +48,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload end end diff --git a/spec/shared/uroplatus.rb b/spec/shared/uroplatus.rb index 0f696da7b9..fa00c69f9d 100644 --- a/spec/shared/uroplatus.rb +++ b/spec/shared/uroplatus.rb @@ -56,7 +56,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload end end diff --git a/spec/shared/varanidae.rb b/spec/shared/varanidae.rb index e299b06d68..9f641ebbeb 100644 --- a/spec/shared/varanidae.rb +++ b/spec/shared/varanidae.rb @@ -82,7 +82,7 @@ self.instance_variables.each do |t| var = self.instance_variable_get(t) if var.kind_of? TaxonConcept - self.instance_variable_set(t,MTaxonConcept.find(var.id)) + self.instance_variable_set(t, MTaxonConcept.find(var.id)) self.instance_variable_get(t).reload end end From 691a84a19530e40b7141652cf54e00d9dcc73e50 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 1 Jul 2016 09:17:03 +0100 Subject: [PATCH 318/365] enabled Style/SpaceAroundEqualsInParameterDefault --- .rubocop_todo.yml | 7 ------- app/models/checklist/history.rb | 2 +- app/models/checklist/index.rb | 2 +- app/models/checklist/pdf/history.rb | 2 +- app/models/checklist/pdf/history_content.rb | 2 +- app/models/checklist/pdf/index.rb | 2 +- app/models/geo_entity.rb | 2 +- app/models/taxon_concept_view_stats.rb | 2 +- app/workers/permit_cleanup_worker.rb | 2 +- config/initializers/active_record_comparison_attributes.rb | 2 +- lib/tasks/import_species.rake | 2 +- 11 files changed, 10 insertions(+), 17 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index bd3ef9a760..769cce4c1c 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -620,13 +620,6 @@ Style/SpaceAfterNot: - 'app/models/checklist/pdf/history_content.rb' - 'app/models/checklist/pdf/index_content.rb' -# Offense count: 10 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: space, no_space -Style/SpaceAroundEqualsInParameterDefault: - Enabled: false - # Offense count: 93 # Cop supports --auto-correct. # Configuration parameters: AllowForAlignment. diff --git a/app/models/checklist/history.rb b/app/models/checklist/history.rb index 89367fa6f5..5baed3d6a5 100644 --- a/app/models/checklist/history.rb +++ b/app/models/checklist/history.rb @@ -1,7 +1,7 @@ class Checklist::History < Checklist::Checklist attr_reader :download_name - def initialize(options={}) + def initialize(options = {}) options = { :output_layout => :taxonomic, :show_english => true, diff --git a/app/models/checklist/index.rb b/app/models/checklist/index.rb index fd373fa07e..c754752777 100644 --- a/app/models/checklist/index.rb +++ b/app/models/checklist/index.rb @@ -1,7 +1,7 @@ class Checklist::Index < Checklist::Checklist attr_reader :download_name - def initialize(options={}) + def initialize(options = {}) params = options.merge({:output_layout => :alphabetical}) @download_path = download_location(params, "index", ext) # If a cached download exists, only initialize the params for the diff --git a/app/models/checklist/pdf/history.rb b/app/models/checklist/pdf/history.rb index b3726ecced..b53dd004b1 100644 --- a/app/models/checklist/pdf/history.rb +++ b/app/models/checklist/pdf/history.rb @@ -4,7 +4,7 @@ class Checklist::Pdf::History < Checklist::History include Checklist::Pdf::Helpers include Checklist::Pdf::HistoryContent - def initialize(options={}) + def initialize(options = {}) super(options) @input_name = 'history' end diff --git a/app/models/checklist/pdf/history_content.rb b/app/models/checklist/pdf/history_content.rb index 3592300693..7088e02c06 100644 --- a/app/models/checklist/pdf/history_content.rb +++ b/app/models/checklist/pdf/history_content.rb @@ -48,7 +48,7 @@ def kingdom(tex, fetcher, kingdom_name) end while not kingdom.empty? end - def listed_taxa(tex, listed_taxa_ary, kingdom_name='FAUNA') + def listed_taxa(tex, listed_taxa_ary, kingdom_name = 'FAUNA') tex << "\\listingtable#{kingdom_name.downcase}{" rows = [] listed_taxa_ary.each do |tc| diff --git a/app/models/checklist/pdf/index.rb b/app/models/checklist/pdf/index.rb index bcc382270a..aa3fb8a2b3 100644 --- a/app/models/checklist/pdf/index.rb +++ b/app/models/checklist/pdf/index.rb @@ -4,7 +4,7 @@ class Checklist::Pdf::Index < Checklist::Index include Checklist::Pdf::Helpers include Checklist::Pdf::IndexContent - def initialize(options={}) + def initialize(options = {}) super(options) @input_name = 'index' end diff --git a/app/models/geo_entity.rb b/app/models/geo_entity.rb index 3edc61ada3..b2c193c9b7 100644 --- a/app/models/geo_entity.rb +++ b/app/models/geo_entity.rb @@ -101,7 +101,7 @@ def contained_geo_entities GeoEntity.contained_geo_entities(self.id) end - def as_json(options={}) + def as_json(options = {}) super(:only =>[:id, :iso_code2, :is_current], :methods => [:name]) end diff --git a/app/models/taxon_concept_view_stats.rb b/app/models/taxon_concept_view_stats.rb index ecc46ffffc..04631a2830 100644 --- a/app/models/taxon_concept_view_stats.rb +++ b/app/models/taxon_concept_view_stats.rb @@ -1,6 +1,6 @@ class TaxonConceptViewStats - def initialize(start_date, end_date, taxonomy=Taxonomy::CITES_EU) + def initialize(start_date, end_date, taxonomy = Taxonomy::CITES_EU) @start_date = start_date @end_date = end_date @taxonomy = taxonomy diff --git a/app/workers/permit_cleanup_worker.rb b/app/workers/permit_cleanup_worker.rb index f31d1d8c0a..f521c5d19d 100644 --- a/app/workers/permit_cleanup_worker.rb +++ b/app/workers/permit_cleanup_worker.rb @@ -2,7 +2,7 @@ class PermitCleanupWorker include Sidekiq::Worker sidekiq_options :queue => :admin, :backtrace => 50 - def perform(permits_ids=[]) + def perform(permits_ids = []) return if permits_ids.empty? sql = <<-SQL WITH unused_permits(id) AS ( diff --git a/config/initializers/active_record_comparison_attributes.rb b/config/initializers/active_record_comparison_attributes.rb index a95c7c1f53..ff2b0ba6ee 100644 --- a/config/initializers/active_record_comparison_attributes.rb +++ b/config/initializers/active_record_comparison_attributes.rb @@ -16,7 +16,7 @@ def comparison_attributes attributes.except(*self.class.ignored_attributes.map(&:to_s)).symbolize_keys end - def comparison_conditions(comparison_attributes=nil) + def comparison_conditions(comparison_attributes = nil) comparison_attributes ||= self.comparison_attributes a = self.class.scoped arel_nodes = [] diff --git a/lib/tasks/import_species.rake b/lib/tasks/import_species.rake index a7324d9873..bf070bdb87 100644 --- a/lib/tasks/import_species.rake +++ b/lib/tasks/import_species.rake @@ -31,7 +31,7 @@ end # Copies data from the temporary table to the correct tables in the database # # @param [String] which the rank to be copied. -def import_data_for(kingdom, rank, synonyms=nil) +def import_data_for(kingdom, rank, synonyms = nil) puts "Importing #{rank}" rank_id = Rank.select(:id).where(:name => rank).first.id existing = TaxonConcept.where(:rank_id => rank_id).count From 23080643ca590ed1bf8d606a65220c2d0549deae Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 1 Jul 2016 09:20:14 +0100 Subject: [PATCH 319/365] enabled Style/SpaceBeforeComment --- .rubocop_todo.yml | 7 ------- lib/modules/latex_to_pdf.rb | 2 +- lib/scripts/get_listed_species_per_country.rb | 2 +- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 769cce4c1c..65ceaf721d 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -633,13 +633,6 @@ Style/SpaceAroundOperators: Style/SpaceBeforeBlockBraces: Enabled: false -# Offense count: 2 -# Cop supports --auto-correct. -Style/SpaceBeforeComment: - Exclude: - - 'lib/modules/latex_to_pdf.rb' - - 'lib/scripts/get_listed_species_per_country.rb' - # Offense count: 317 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters. diff --git a/lib/modules/latex_to_pdf.rb b/lib/modules/latex_to_pdf.rb index cc75f65c17..269cb302f8 100644 --- a/lib/modules/latex_to_pdf.rb +++ b/lib/modules/latex_to_pdf.rb @@ -74,7 +74,7 @@ def latex_esc(text) # :nodoc: # :startdoc: end - @latex_escaper.latex_esc(text.to_s)#.html_safe + @latex_escaper.latex_esc(text.to_s) #.html_safe end def self.html2latex(text) diff --git a/lib/scripts/get_listed_species_per_country.rb b/lib/scripts/get_listed_species_per_country.rb index 6c9537e49a..65b0cd0c5b 100644 --- a/lib/scripts/get_listed_species_per_country.rb +++ b/lib/scripts/get_listed_species_per_country.rb @@ -4,7 +4,7 @@ require '../../config/environment.rb' results = { :cites_eu=>[], :cms=>[] } -countries = GeoEntity.where("geo_entity_type_id = 1")#.limit(2) +countries = GeoEntity.where("geo_entity_type_id = 1") #.limit(2) countries.each do |country| [:cites_eu, :cms].each do |taxonomy| From 1a7bf34fcd36884f9756e707076c535359f2d7bc Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 1 Jul 2016 09:22:25 +0100 Subject: [PATCH 320/365] enabled Style/SpaceAfterMethodName --- .rubocop_todo.yml | 6 ------ app/models/dashboard_stats.rb | 2 +- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 65ceaf721d..83444a276c 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -605,12 +605,6 @@ Style/SignalException: Style/SingleLineMethods: Enabled: false -# Offense count: 1 -# Cop supports --auto-correct. -Style/SpaceAfterMethodName: - Exclude: - - 'app/models/dashboard_stats.rb' - # Offense count: 4 # Cop supports --auto-correct. Style/SpaceAfterNot: diff --git a/app/models/dashboard_stats.rb b/app/models/dashboard_stats.rb index ca7dd630e8..2991335f2e 100644 --- a/app/models/dashboard_stats.rb +++ b/app/models/dashboard_stats.rb @@ -5,7 +5,7 @@ class DashboardStats attr_reader :geo_entity, :kingdom, :time_range_start, :time_range_end, :trade_limit - def initialize (geo_entity, options) + def initialize(geo_entity, options) @geo_entity = geo_entity @kingdom = options[:kingdom] || 'Animalia' @trade_limit = options[:trade_limit] From 3005667f6cf566413aacb28e2e34e2c994b5400b Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 1 Jul 2016 09:30:42 +0100 Subject: [PATCH 321/365] enabled Style/SpaceInsideBlockBraces --- .rubocop_todo.yml | 7 -- app/controllers/admin/quotas_controller.rb | 2 +- .../api/geo_relationships_controller.rb | 2 +- app/controllers/api/ranks_controller.rb | 2 +- ...auto_complete_taxon_concepts_controller.rb | 2 +- app/controllers/api/v1/purposes_controller.rb | 2 +- app/controllers/api/v1/sources_controller.rb | 2 +- app/controllers/api/v1/terms_controller.rb | 2 +- app/controllers/api/v1/units_controller.rb | 2 +- app/controllers/species/ember_controller.rb | 2 +- .../admin/nomenclature_changes_helper.rb | 6 +- app/helpers/admin_helper.rb | 14 ++-- app/models/change_type.rb | 2 +- app/models/iucn_mapping_manager.rb | 2 +- ...n_concept_filter_by_id_with_descendants.rb | 2 +- app/models/taxon_concept.rb | 2 +- app/models/trade/filter.rb | 4 +- app/models/trade/inclusion_validation_rule.rb | 2 +- .../trade/shipments_gross_exports_export.rb | 4 +- .../taxon_concept_source_validation_rule.rb | 4 +- db/seeds.rb | 2 +- lib/modules/dictionary.rb | 2 +- lib/tasks/elibrary/import.rake | 2 +- lib/tasks/helpers_for_import.rb | 2 +- lib/tasks/import_cites_parties.rake | 2 +- lib/tasks/import_trade_names.rake | 2 +- ...date_eu_decisions_with_missing_source.rake | 2 +- .../admin/ahoy_visits_controller_spec.rb | 4 +- .../admin/instruments_controller_spec.rb | 2 +- .../api/taxon_concepts_controller_spec.rb | 4 +- .../registrations_controller_spec.rb | 2 +- spec/factories.rb | 14 ++-- spec/factories/common_names.rb | 2 +- spec/factories/listings.rb | 6 +- spec/models/checklist/timeline_spec.rb | 14 ++-- spec/models/cites_cop_spec.rb | 4 +- .../cites_suspension_notification_spec.rb | 4 +- spec/models/cites_suspension_spec.rb | 32 ++++---- spec/models/designation_spec.rb | 8 +- spec/models/document_batch_spec.rb | 4 +- spec/models/eu_regulation_spec.rb | 4 +- spec/models/event_spec.rb | 8 +- spec/models/listing_change_spec.rb | 16 ++-- .../lump/constructor_spec.rb | 2 +- spec/models/preset_tag_spec.rb | 6 +- spec/models/quota_spec.rb | 4 +- spec/models/rank_spec.rb | 2 +- spec/models/source_spec.rb | 2 +- .../invisible_subspecies_search_spec.rb | 4 +- spec/models/species/listings_export_spec.rb | 2 +- spec/models/species/search_spec.rb | 8 +- .../taxon_concept_prefix_matcher_spec.rb | 24 +++--- .../species/visible_subspecies_search_spec.rb | 2 +- spec/models/taxon_concept/colophon_spec.rb | 4 +- spec/models/taxon_concept/destroy_spec.rb | 20 ++--- spec/models/taxon_concept/validation_spec.rb | 2 +- .../taxon_concept_prefix_matcher_spec.rb | 8 +- spec/models/taxon_relationship_spec.rb | 8 +- spec/models/taxonomy_spec.rb | 6 +- spec/models/term_spec.rb | 2 +- .../models/trade/annual_report_upload_spec.rb | 18 ++--- spec/models/trade/permit_matcher_spec.rb | 10 +-- spec/models/unit_spec.rb | 2 +- spec/models/user_spec.rb | 6 +- spec/spec_helper.rb | 6 +- spec/workers/quotas_copy_worker_spec.rb | 76 +++++++++---------- 66 files changed, 213 insertions(+), 220 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 83444a276c..2db576da08 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -627,13 +627,6 @@ Style/SpaceAroundOperators: Style/SpaceBeforeBlockBraces: Enabled: false -# Offense count: 317 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters. -# SupportedStyles: space, no_space -Style/SpaceInsideBlockBraces: - Enabled: false - # Offense count: 9 # Cop supports --auto-correct. Style/SpaceInsideBrackets: diff --git a/app/controllers/admin/quotas_controller.rb b/app/controllers/admin/quotas_controller.rb index 2faa04877f..cbb2eea702 100644 --- a/app/controllers/admin/quotas_controller.rb +++ b/app/controllers/admin/quotas_controller.rb @@ -3,7 +3,7 @@ class Admin::QuotasController < Admin::StandardAuthorizationController def index @years = Quota.years_array if params[:year] && !@years.include?(params[:year]) - @years = @years.push(params[:year]).sort{|a, b| b <=> a} + @years = @years.push(params[:year]).sort{ |a, b| b <=> a } end index! end diff --git a/app/controllers/api/geo_relationships_controller.rb b/app/controllers/api/geo_relationships_controller.rb index 30591939a8..daa6ecaabc 100644 --- a/app/controllers/api/geo_relationships_controller.rb +++ b/app/controllers/api/geo_relationships_controller.rb @@ -7,6 +7,6 @@ class Api::GeoRelationshipsController < ApplicationController def collection @geo_relationship_types ||= end_of_association_chain.order(:name). select([:id, :name]). - map{|d| {:value => d.id, :text => d.name}} + map{ |d| {:value => d.id, :text => d.name} } end end \ No newline at end of file diff --git a/app/controllers/api/ranks_controller.rb b/app/controllers/api/ranks_controller.rb index eac70126fc..9dbe4ad5b9 100644 --- a/app/controllers/api/ranks_controller.rb +++ b/app/controllers/api/ranks_controller.rb @@ -7,6 +7,6 @@ class Api::RanksController < ApplicationController def collection @ranks ||= end_of_association_chain. select([:id, :name]). - map{|d| {:value => d.id, :text => d.name}} + map{ |d| {:value => d.id, :text => d.name} } end end diff --git a/app/controllers/api/v1/auto_complete_taxon_concepts_controller.rb b/app/controllers/api/v1/auto_complete_taxon_concepts_controller.rb index 579d04d1e7..03ddbe8518 100644 --- a/app/controllers/api/v1/auto_complete_taxon_concepts_controller.rb +++ b/app/controllers/api/v1/auto_complete_taxon_concepts_controller.rb @@ -11,7 +11,7 @@ def index :rank_headers => @taxon_concepts.map(&:rank_display_name).uniq.map do |r| { :rank_name => r, - :taxon_concept_ids => @taxon_concepts.select{|tc| tc.rank_display_name == r}.map(&:id) + :taxon_concept_ids => @taxon_concepts.select{ |tc| tc.rank_display_name == r }.map(&:id) } end } diff --git a/app/controllers/api/v1/purposes_controller.rb b/app/controllers/api/v1/purposes_controller.rb index 3976268cb6..2db9bb1408 100644 --- a/app/controllers/api/v1/purposes_controller.rb +++ b/app/controllers/api/v1/purposes_controller.rb @@ -1,6 +1,6 @@ class Api::V1::PurposesController < ApplicationController caches_action :index, :cache_path => Proc.new { |c| - {:locale => "en"}.merge(c.params.select{|k, v| !v.blank? && "locale" == k}) + {:locale => "en"}.merge(c.params.select{ |k, v| !v.blank? && "locale" == k }) } def index @purposes = Purpose.all(:order => "code") diff --git a/app/controllers/api/v1/sources_controller.rb b/app/controllers/api/v1/sources_controller.rb index cd3c298da4..33b16488e9 100644 --- a/app/controllers/api/v1/sources_controller.rb +++ b/app/controllers/api/v1/sources_controller.rb @@ -1,6 +1,6 @@ class Api::V1::SourcesController < ApplicationController caches_action :index, :cache_path => Proc.new { |c| - {:locale => "en"}.merge(c.params.select{|k, v| !v.blank? && "locale" == k}) + {:locale => "en"}.merge(c.params.select{ |k, v| !v.blank? && "locale" == k }) } def index @sources = Source.all(:order => "code") diff --git a/app/controllers/api/v1/terms_controller.rb b/app/controllers/api/v1/terms_controller.rb index 23c94d2ef0..8160804593 100644 --- a/app/controllers/api/v1/terms_controller.rb +++ b/app/controllers/api/v1/terms_controller.rb @@ -1,6 +1,6 @@ class Api::V1::TermsController < ApplicationController caches_action :index, :cache_path => Proc.new { |c| - {:locale => "en"}.merge(c.params.select{|k, v| !v.blank? && "locale" == k}) + {:locale => "en"}.merge(c.params.select{ |k, v| !v.blank? && "locale" == k }) } def index @terms = Term.all(:order => "code") diff --git a/app/controllers/api/v1/units_controller.rb b/app/controllers/api/v1/units_controller.rb index 3250bac2ab..f8edd6b896 100644 --- a/app/controllers/api/v1/units_controller.rb +++ b/app/controllers/api/v1/units_controller.rb @@ -1,6 +1,6 @@ class Api::V1::UnitsController < ApplicationController caches_action :index, :cache_path => Proc.new { |c| - {:locale => "en"}.merge(c.params.select{|k, v| !v.blank? && "locale" == k}) + {:locale => "en"}.merge(c.params.select{ |k, v| !v.blank? && "locale" == k }) } def index @units = Unit.all(:order => "code") diff --git a/app/controllers/species/ember_controller.rb b/app/controllers/species/ember_controller.rb index 1ceab13c29..f1f5aad891 100644 --- a/app/controllers/species/ember_controller.rb +++ b/app/controllers/species/ember_controller.rb @@ -2,7 +2,7 @@ class Species::EmberController < ApplicationController layout 'species' def start respond_to do |format| - format.html { } + format.html {} end end end diff --git a/app/helpers/admin/nomenclature_changes_helper.rb b/app/helpers/admin/nomenclature_changes_helper.rb index b819ed7182..12ffd0e014 100644 --- a/app/helpers/admin/nomenclature_changes_helper.rb +++ b/app/helpers/admin/nomenclature_changes_helper.rb @@ -342,7 +342,7 @@ def name_reassignment_label(reassignment) end def select_taxonomy - select("taxonomy", "taxonomy_id", Taxonomy.all.collect {|t| [t.name, t.id]}) + select("taxonomy", "taxonomy_id", Taxonomy.all.collect { |t| [t.name, t.id] }) end def select_rank @@ -350,11 +350,11 @@ def select_rank end def ranks_collection - Rank.all.collect {|r| [r.name, r.id]} + Rank.all.collect { |r| [r.name, r.id] } end def taxon_concepts_collection - TaxonConcept.where(:taxonomy_id => 1).collect {|t| [t.full_name, t.id]} + TaxonConcept.where(:taxonomy_id => 1).collect { |t| [t.full_name, t.id] } end def new_name_scientific_name_hint diff --git a/app/helpers/admin_helper.rb b/app/helpers/admin_helper.rb index 7de6b70e13..bfb05d421e 100644 --- a/app/helpers/admin_helper.rb +++ b/app/helpers/admin_helper.rb @@ -70,7 +70,7 @@ def true_false_icon(bool_value) end def tag_list(tags_ary) - tags_ary.map{ |t| content_tag(:span, :class => 'myMinTag'){t} }.join(', ').html_safe + tags_ary.map{ |t| content_tag(:span, :class => 'myMinTag'){ t } }.join(', ').html_safe end def error_messages_for(resource) @@ -135,10 +135,10 @@ def admin_new_modal(options = {}) button_tag( :type => "button", :class => "close", :"data-dismiss" => "modal", :"aria-hidden" => true - ){'×'} + + ){ '×' } + content_tag(:h3, :id => "#{id}-label" - ){title} + ){ title } end + content_tag( :div, :id => "admin-#{id}-form", :class => "modal-body" #TODO @@ -153,18 +153,18 @@ def admin_new_modal(options = {}) button_tag( :type => "button", :class => "btn", :"data-dismiss" => "modal", :"aria-hidden" => "true" - ){'Close'} + + ){ 'Close' } + if options[:save_and_reopen] button_tag( :type => "button", :class => "btn btn-primary save-button save-and-reopen-button" - ){'Save changes'} + + ){ 'Save changes' } + button_tag( :type => "button", :class => "btn btn-primary save-button" - ){'Save changes & close'} + ){ 'Save changes & close' } else button_tag( :type => "button", :class => "btn btn-primary save-button" - ){'Save changes'} + ){ 'Save changes' } end end end diff --git a/app/models/change_type.rb b/app/models/change_type.rb index bf6695cb62..f8fc1e85b3 100644 --- a/app/models/change_type.rb +++ b/app/models/change_type.rb @@ -28,7 +28,7 @@ class ChangeType < ActiveRecord::Base def abbreviation self.name.split('_'). - map{|a| a[0..2]}.join('-') + map{ |a| a[0..2] }.join('-') end def print_name diff --git a/app/models/iucn_mapping_manager.rb b/app/models/iucn_mapping_manager.rb index d4ad959723..ab21edc092 100644 --- a/app/models/iucn_mapping_manager.rb +++ b/app/models/iucn_mapping_manager.rb @@ -75,7 +75,7 @@ def type_of_match(tc, match) def strip_authors(author) return '' unless author author.split(" "). - reject{|p| ["and", "&", "&", ","].include?(p)}. + reject{ |p| ["and", "&", "&", ","].include?(p) }. join(" ") end end diff --git a/app/models/m_taxon_concept_filter_by_id_with_descendants.rb b/app/models/m_taxon_concept_filter_by_id_with_descendants.rb index f21f8228fa..ea3945e57e 100644 --- a/app/models/m_taxon_concept_filter_by_id_with_descendants.rb +++ b/app/models/m_taxon_concept_filter_by_id_with_descendants.rb @@ -13,7 +13,7 @@ def relation(ancestor_ranks = nil) ] # TODO: SUBFAMILY is missing here. we don't have it in listings mviews. fields_to_check = ( [:id] + - ancestor_ranks.map { |r| "#{r.downcase}_id"} + ancestor_ranks.map { |r| "#{r.downcase}_id" } ).map{ |c| "#{@table}.#{c}" } @relation.where( <<-SQL diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index 8d0063207b..62e4286777 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -240,7 +240,7 @@ def self.fetch_taxons_full_name(taxon_ids) WHERE tc.id = ANY (ARRAY#{taxon_ids.map(&:to_i)}) ORDER BY tc.id SQL - ).map{ |row| row['full_name']} + ).map{ |row| row['full_name'] } end end diff --git a/app/models/trade/filter.rb b/app/models/trade/filter.rb index 16b8ba1528..c2e9f51c84 100644 --- a/app/models/trade/filter.rb +++ b/app/models/trade/filter.rb @@ -53,7 +53,7 @@ def initialize_query [:"#{tc.rank_name.downcase}_id", tc.id] end @query = @query.where( - taxon_concepts_conditions.map{ |c| "taxon_concept_#{c[0]} = #{c[1]}"}.join(' OR ') + taxon_concepts_conditions.map{ |c| "taxon_concept_#{c[0]} = #{c[1]}" }.join(' OR ') ) end @@ -69,7 +69,7 @@ def initialize_query [:"#{tc.rank_name.downcase}_id", tc.id] end @query = @query.where( - reported_taxon_concepts_conditions.map{ |c| "reported_taxon_concept_#{c[0]} = #{c[1]}"}.join(' OR ') + reported_taxon_concepts_conditions.map{ |c| "reported_taxon_concept_#{c[0]} = #{c[1]}" }.join(' OR ') ) end diff --git a/app/models/trade/inclusion_validation_rule.rb b/app/models/trade/inclusion_validation_rule.rb index c65fb0ced2..d67831f22b 100644 --- a/app/models/trade/inclusion_validation_rule.rb +++ b/app/models/trade/inclusion_validation_rule.rb @@ -90,7 +90,7 @@ def matching_records_grouped(table_name) ['COUNT(*) AS error_count', 'ARRAY_AGG(id) AS matching_records_ids'] ).from(Arel.sql("(#{matching_records_arel(table_name).to_sql}) AS matching_records")). group(column_names_for_display).having( - required_column_names.map{ |cn| "#{cn} IS NOT NULL"}.join(' AND ') + required_column_names.map{ |cn| "#{cn} IS NOT NULL" }.join(' AND ') ) end diff --git a/app/models/trade/shipments_gross_exports_export.rb b/app/models/trade/shipments_gross_exports_export.rb index 2f0750d954..386305149c 100644 --- a/app/models/trade/shipments_gross_exports_export.rb +++ b/app/models/trade/shipments_gross_exports_export.rb @@ -107,8 +107,8 @@ def ct_subquery_sql(options) categories_sql = ActiveRecord::Base.send(:sanitize_sql_array, [categories_sql, years.map(&:to_i)]) ct_columns = [ 'row_name TEXT[]', - report_crosstab_columns.map.each_with_index{ |c, i| "#{sql_crosstab_columns[i]} #{crosstab_columns[c][:pg_type]}"}, - years_columns.map{ |y| "#{y} numeric"} + report_crosstab_columns.map.each_with_index{ |c, i| "#{sql_crosstab_columns[i]} #{crosstab_columns[c][:pg_type]}" }, + years_columns.map{ |y| "#{y} numeric" } ].flatten.join(', ') # a set returning query requires that output columns are specified <<-SQL diff --git a/app/models/trade/taxon_concept_source_validation_rule.rb b/app/models/trade/taxon_concept_source_validation_rule.rb index ac11ca8521..9af586b6fe 100644 --- a/app/models/trade/taxon_concept_source_validation_rule.rb +++ b/app/models/trade/taxon_concept_source_validation_rule.rb @@ -49,11 +49,11 @@ def matching_records_grouped(table_name) ).where(<<-SQL ( UPPER(taxon_concepts.data->'kingdom_name') = 'ANIMALIA' - AND source_code IN (#{INVALID_KINGDOM_SOURCE['ANIMALIA'].map{|c| "'#{c}'"}.join(',')}) + AND source_code IN (#{INVALID_KINGDOM_SOURCE['ANIMALIA'].map{ |c| "'#{c}'" }.join(',')}) ) OR ( UPPER(taxon_concepts.data->'kingdom_name') = 'PLANTAE' - AND source_code IN (#{INVALID_KINGDOM_SOURCE['PLANTAE'].map{|c| "'#{c}'"}.join(',')}) + AND source_code IN (#{INVALID_KINGDOM_SOURCE['PLANTAE'].map{ |c| "'#{c}'" }.join(',')}) ) SQL ). diff --git a/db/seeds.rb b/db/seeds.rb index 26c13e9a6a..68f707806a 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -79,7 +79,7 @@ "PC review and categorization [k]", "PC review and categorization (m)", "PC review (e)", "Research of species [j]", "Selection of species (b)", "Selection of species [b]", "Species selection (b)", "Species selection [b]" -].each {|tag| DocumentTag::ProcessStage.create(name: tag) } +].each { |tag| DocumentTag::ProcessStage.create(name: tag) } [ "Accepted", "Cancelled", "Deferred", diff --git a/lib/modules/dictionary.rb b/lib/modules/dictionary.rb index c9d2d65a0d..0d6d4c834f 100644 --- a/lib/modules/dictionary.rb +++ b/lib/modules/dictionary.rb @@ -24,7 +24,7 @@ def build_basic_dictionary(*keys) key end end - define_singleton_method("dict") { keys.map{|k| k.to_s.upcase } } + define_singleton_method("dict") { keys.map{ |k| k.to_s.upcase } } end end end diff --git a/lib/tasks/elibrary/import.rake b/lib/tasks/elibrary/import.rake index 1e22541000..eff8775136 100644 --- a/lib/tasks/elibrary/import.rake +++ b/lib/tasks/elibrary/import.rake @@ -34,7 +34,7 @@ namespace :elibrary do "PC review and categorization [k]", "PC review and categorization (m)", "PC review (e)", "Research of species [j]", "Selection of species (b)", "Selection of species [b]", "Species selection (b)", "Species selection [b]" - ].each {|tag| DocumentTag::ProcessStage.find_or_create_by_name(name: tag) } + ].each { |tag| DocumentTag::ProcessStage.find_or_create_by_name(name: tag) } [ "Accepted", "Cancelled", "Deferred", diff --git a/lib/tasks/helpers_for_import.rb b/lib/tasks/helpers_for_import.rb index 31b94ec439..68f8ca22d9 100644 --- a/lib/tasks/helpers_for_import.rb +++ b/lib/tasks/helpers_for_import.rb @@ -368,7 +368,7 @@ def db_columns_from_csv_headers(path_to_file, table_name, include_data_type = tr #work out the db columns to create csv_columns = csv_headers(path_to_file) db_columns = csv_columns.map{ |col| m.csv_to_db(table_name, col) } - db_columns = db_columns.map{ |col| col.sub(/\s\w+$/, '')} unless include_data_type + db_columns = db_columns.map{ |col| col.sub(/\s\w+$/, '') } unless include_data_type puts csv_columns.inspect puts db_columns.inspect db_columns diff --git a/lib/tasks/import_cites_parties.rake b/lib/tasks/import_cites_parties.rake index 0784daed98..df81e71a90 100644 --- a/lib/tasks/import_cites_parties.rake +++ b/lib/tasks/import_cites_parties.rake @@ -2,7 +2,7 @@ namespace :import do desc 'Import CITES parties' task :cites_parties => [:environment] do parties_iso_codes = %w( AF AL DZ AG AR AM AU AT AZ BS BH BD BB BY BE BZ BJ BT BO BA BW BR BN BG BF BI KH CM CA CV CF TD CL CN CO KM CG CR CI HR CU CY CZ CD DK DJ DM DO EC EG SV GQ ER EE ET FJ FI FR GA GM GE DE GH GR GD GT GN GW GY HN HU IS IN ID IR IE IL IT JM JP JO KZ KE KW KG LA LV LB LS LR LY LI LT LU MG MW MY MV ML MT MR MU MX MC MN ME MA MZ MM NA NP NL NZ NI NE NG NO OM PK PW PA PG PY PE PH PL PT QA KR MD RO RU RW KN LC VC WS SM ST SA SN RS SC SL SG SK SI SB SO ZA ES LK SD SR SZ SE CH SY TH MK TG TT TN TR UG UA AE GB TZ US UY UZ VU VE VN YE ZM ZW) - parties_iso_codes_pg_ary = parties_iso_codes.map{ |ic| "'#{ic}'"}.join(',') + parties_iso_codes_pg_ary = parties_iso_codes.map{ |ic| "'#{ic}'" }.join(',') sql =<<-SQL INSERT INTO designation_geo_entities (designation_id, geo_entity_id, created_at, updated_at) SELECT subquery.*, NOW(), NOW() diff --git a/lib/tasks/import_trade_names.rake b/lib/tasks/import_trade_names.rake index ed17ff4417..a3a0627d2b 100644 --- a/lib/tasks/import_trade_names.rake +++ b/lib/tasks/import_trade_names.rake @@ -139,7 +139,7 @@ namespace :import do count_trade_relationships = TaxonRelationship.where(:taxon_relationship_type_id => has_trade_name).count count_synonym_relationships = TaxonRelationship.where(:taxon_relationship_type_id => has_synonym).count taxon_concept_ids = ActiveRecord::Base.connection.execute("SELECT cites_taxon_code, species_plus_id AS id FROM #{TMP_TABLE}"). - map {|h| [h["cites_taxon_code"], h["id"]]} + map { |h| [h["cites_taxon_code"], h["id"]] } taxon_concept_ids.each do |cites_code, id| tc = TaxonConcept.find id next if tc.name_status != "S" diff --git a/lib/tasks/update_eu_decisions_with_missing_source.rake b/lib/tasks/update_eu_decisions_with_missing_source.rake index 08901928b8..dbbc9de353 100644 --- a/lib/tasks/update_eu_decisions_with_missing_source.rake +++ b/lib/tasks/update_eu_decisions_with_missing_source.rake @@ -4,7 +4,7 @@ namespace :update do file = "lib/files/eu_decisions_with_missing_source.csv" drop_table(TMP_TABLE) db_columns = ['full_name', 'rank_name', 'start_date', 'party_name', 'decision_type', 'source_code', 'term_code', 'notes'] - create_table_from_column_array(TMP_TABLE, db_columns.map{ |c| "#{c} TEXT"}) + create_table_from_column_array(TMP_TABLE, db_columns.map{ |c| "#{c} TEXT" }) #Full Name Rank Date of Decision Party EU Decision Source Term Notes copy_data_into_table(file, TMP_TABLE, db_columns) diff --git a/spec/controllers/admin/ahoy_visits_controller_spec.rb b/spec/controllers/admin/ahoy_visits_controller_spec.rb index ace830bc75..ac1ac218c9 100644 --- a/spec/controllers/admin/ahoy_visits_controller_spec.rb +++ b/spec/controllers/admin/ahoy_visits_controller_spec.rb @@ -5,8 +5,8 @@ login_admin describe "index" do - let!(:ahoy_visit1) {FactoryGirl.create(:ahoy_visit, :browser => "Safari", :device_type => "Desktop")} - let!(:ahoy_visit2) {FactoryGirl.create(:ahoy_visit, :browser => "Firefox", :device_type => "Desktop")} + let!(:ahoy_visit1) { FactoryGirl.create(:ahoy_visit, :browser => "Safari", :device_type => "Desktop") } + let!(:ahoy_visit2) { FactoryGirl.create(:ahoy_visit, :browser => "Firefox", :device_type => "Desktop") } describe "GET index" do it "assigns to @ahoy_events sorted by time DESC" do diff --git a/spec/controllers/admin/instruments_controller_spec.rb b/spec/controllers/admin/instruments_controller_spec.rb index 24edc1a094..32d90ca4e0 100644 --- a/spec/controllers/admin/instruments_controller_spec.rb +++ b/spec/controllers/admin/instruments_controller_spec.rb @@ -60,7 +60,7 @@ response.should redirect_to(admin_instruments_url) end let(:instrument2){ create(:instrument) } - let!(:taxon_instrument){ create(:taxon_instrument, :instrument_id => instrument2.id)} + let!(:taxon_instrument){ create(:taxon_instrument, :instrument_id => instrument2.id) } it "fails to delete instrument because there are dependent objects" do delete :destroy, :id => instrument2.id flash[:notice].should be_nil diff --git a/spec/controllers/api/taxon_concepts_controller_spec.rb b/spec/controllers/api/taxon_concepts_controller_spec.rb index df1b1ab778..a9beaa4d16 100644 --- a/spec/controllers/api/taxon_concepts_controller_spec.rb +++ b/spec/controllers/api/taxon_concepts_controller_spec.rb @@ -10,7 +10,7 @@ :geo_entity_scope => 'cites', :page => 1 } - }.to change{Ahoy::Event.count}.by(1) + }.to change{ Ahoy::Event.count }.by(1) expect(Ahoy::Event.last.visit_id).to_not be(nil) expect { @@ -20,7 +20,7 @@ :geo_entity_scope => 'cites', :page => 1 } - }.to change{Ahoy::Event.count}.by(1) + }.to change{ Ahoy::Event.count }.by(1) expect(@ahoy_event1).to eq(@ahoy_event2) end end diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb index 644693ab94..6319e075ce 100644 --- a/spec/controllers/registrations_controller_spec.rb +++ b/spec/controllers/registrations_controller_spec.rb @@ -52,7 +52,7 @@ :email => @u3.email, :name => @u3.name, :organisation => 'WCMC', :password => '22222222', :password_confirmation => '22222222' } - }.to change{User.count}.by(1) + }.to change{ User.count }.by(1) u = User.last expect(u.role).to eq 'api' end diff --git a/spec/factories.rb b/spec/factories.rb index 05322a51d2..4519a55b17 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -3,7 +3,7 @@ FactoryGirl.define do factory :user do - sequence(:name) {|n| "user#{n}"} + sequence(:name) { |n| "user#{n}" } email { "#{name}@test.pl" } password 'asdfasdf' password_confirmation { password } @@ -13,16 +13,16 @@ end factory :taxonomy do - sequence(:name) {|n| "WILDLIFE#{n}"} + sequence(:name) { |n| "WILDLIFE#{n}" } end factory :designation do - sequence(:name) {|n| "CITES#{n}"} + sequence(:name) { |n| "CITES#{n}" } taxonomy end factory :instrument do - sequence(:name) {|n| "ACAP#{n}"} + sequence(:name) { |n| "ACAP#{n}" } designation end @@ -32,7 +32,7 @@ end factory :event do - sequence(:name) {|n| "CoP#{n}"} + sequence(:name) { |n| "CoP#{n}" } effective_at '2011-01-01' published_at '2011-02-01' designation @@ -56,7 +56,7 @@ end factory :taxon_name do - sequence(:scientific_name) {|n| "Lupus#{n}"} + sequence(:scientific_name) { |n| "Lupus#{n}" } end factory :cites_suspension do @@ -98,7 +98,7 @@ end factory :eu_decision_type do - sequence(:name) {|n| "Opinion#{n}"} + sequence(:name) { |n| "Opinion#{n}" } decision_type "NO_OPINION" end diff --git a/spec/factories/common_names.rb b/spec/factories/common_names.rb index b3dfa3e422..f75701c9ff 100644 --- a/spec/factories/common_names.rb +++ b/spec/factories/common_names.rb @@ -13,7 +13,7 @@ factory :common_name do language - sequence(:name){|n| "Honey badger #{n}"} + sequence(:name){ |n| "Honey badger #{n}" } end end diff --git a/spec/factories/listings.rb b/spec/factories/listings.rb index 9029f66083..b873f138fe 100644 --- a/spec/factories/listings.rb +++ b/spec/factories/listings.rb @@ -1,13 +1,13 @@ FactoryGirl.define do factory :species_listing do - sequence(:name) {|n| "Appendix #{n}"} - sequence(:abbreviation) {|n| "#{n}"} + sequence(:name) { |n| "Appendix #{n}" } + sequence(:abbreviation) { |n| "#{n}" } designation end factory :change_type do - sequence(:name) {|n| "change#{n}"} + sequence(:name) { |n| "change#{n}" } display_name_en { name } designation end diff --git a/spec/models/checklist/timeline_spec.rb b/spec/models/checklist/timeline_spec.rb index 5349ee5bd7..10ec1d96cf 100644 --- a/spec/models/checklist/timeline_spec.rb +++ b/spec/models/checklist/timeline_spec.rb @@ -17,7 +17,7 @@ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings MTaxonConcept.find(tc.id) } - let(:ttc){ Checklist::TimelinesForTaxonConcept.new(tc)} + let(:ttc){ Checklist::TimelinesForTaxonConcept.new(tc) } let(:subject){ ttc.timelines.first } specify{ subject.timeline_intervals.count.should == 1 } @@ -77,7 +77,7 @@ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings MTaxonConcept.find(tc.id) } - let(:ttc){ Checklist::TimelinesForTaxonConcept.new(tc)} + let(:ttc){ Checklist::TimelinesForTaxonConcept.new(tc) } let(:subject){ ttc.timelines.last } specify{ subject.timeline_intervals.count.should == 3 } @@ -106,7 +106,7 @@ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings MTaxonConcept.find(tc.id) } - let(:ttc){ Checklist::TimelinesForTaxonConcept.new(tc)} + let(:ttc){ Checklist::TimelinesForTaxonConcept.new(tc) } let(:subject){ ttc.timelines.first } specify{ subject.timeline_intervals.count.should == 2 } @@ -148,7 +148,7 @@ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings MTaxonConcept.find(tc.id) } - let(:ttc){ Checklist::TimelinesForTaxonConcept.new(tc)} + let(:ttc){ Checklist::TimelinesForTaxonConcept.new(tc) } let(:subject){ ttc.timelines.first.timelines.first } specify{ puts subject.timeline_events.inspect; puts subject.timeline_intervals.inspect; subject.timeline_intervals.count.should == 1 } @@ -196,7 +196,7 @@ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings MTaxonConcept.find(tc.id) } - let(:ttc){ Checklist::TimelinesForTaxonConcept.new(tc)} + let(:ttc){ Checklist::TimelinesForTaxonConcept.new(tc) } let(:subject){ ttc.timelines.last.timelines.first } specify{ subject.timeline_intervals.count.should == 2 } @@ -221,7 +221,7 @@ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings MTaxonConcept.find(tc.id) } - let(:ttc){ Checklist::TimelinesForTaxonConcept.new(tc)} + let(:ttc){ Checklist::TimelinesForTaxonConcept.new(tc) } let(:subject){ ttc.timelines.first } specify{ @@ -250,7 +250,7 @@ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings MTaxonConcept.find(tc.id) } - let(:ttc){ Checklist::TimelinesForTaxonConcept.new(tc)} + let(:ttc){ Checklist::TimelinesForTaxonConcept.new(tc) } let(:subject){ ttc.timelines.first } specify{ diff --git a/spec/models/cites_cop_spec.rb b/spec/models/cites_cop_spec.rb index 09733600ba..38f12258bf 100644 --- a/spec/models/cites_cop_spec.rb +++ b/spec/models/cites_cop_spec.rb @@ -34,7 +34,7 @@ :designation => eu ) } - specify { cites_cop.should be_invalid} + specify { cites_cop.should be_invalid } specify { cites_cop.should have(1).error_on(:designation_id) } end context "when effective_at is blank" do @@ -44,7 +44,7 @@ :effective_at => nil ) } - specify { cites_cop.should be_invalid} + specify { cites_cop.should be_invalid } specify { cites_cop.should have(1).error_on(:effective_at) } end end diff --git a/spec/models/cites_suspension_notification_spec.rb b/spec/models/cites_suspension_notification_spec.rb index 0d9175f38f..af42a61f82 100644 --- a/spec/models/cites_suspension_notification_spec.rb +++ b/spec/models/cites_suspension_notification_spec.rb @@ -34,7 +34,7 @@ :designation => eu ) } - specify { cites_suspension_notification.should be_invalid} + specify { cites_suspension_notification.should be_invalid } specify { cites_suspension_notification.should have(1).error_on(:designation_id) } end context "when effective_at is blank" do @@ -44,7 +44,7 @@ :effective_at => nil ) } - specify { cites_suspension_notification.should be_invalid} + specify { cites_suspension_notification.should be_invalid } specify { cites_suspension_notification.should have(1).error_on(:effective_at) } end end diff --git a/spec/models/cites_suspension_spec.rb b/spec/models/cites_suspension_spec.rb index 11da30a30e..a3e194db21 100644 --- a/spec/models/cites_suspension_spec.rb +++ b/spec/models/cites_suspension_spec.rb @@ -78,7 +78,7 @@ ) } specify{ - expect{subject.save}.to change{@taxon_concept.reload.dependents_updated_at} + expect{ subject.save }.to change{ @taxon_concept.reload.dependents_updated_at } } end context "when global suspension" do @@ -91,7 +91,7 @@ ) } specify{ - expect{subject.save}.to change{@taxon_concept.reload.dependents_updated_at} + expect{ subject.save }.to change{ @taxon_concept.reload.dependents_updated_at } } end context "when suspension at higher taxonomic level" do @@ -103,7 +103,7 @@ ) } specify{ - expect{subject.save}.to change{@taxon_concept.reload.dependents_updated_at} + expect{ subject.save }.to change{ @taxon_concept.reload.dependents_updated_at } } end end @@ -117,8 +117,8 @@ ) } specify{ - expect{subject.update_attribute(:taxon_concept_id, @another_taxon_concept.id)}. - to change{@taxon_concept.reload.dependents_updated_at} + expect{ subject.update_attribute(:taxon_concept_id, @another_taxon_concept.id) }. + to change{ @taxon_concept.reload.dependents_updated_at } } end context "when global suspension" do @@ -131,12 +131,12 @@ ) } specify{ - expect{subject.update_attribute(:geo_entity_id, rwanda.id)}. - to change{@taxon_concept.reload.dependents_updated_at} + expect{ subject.update_attribute(:geo_entity_id, rwanda.id) }. + to change{ @taxon_concept.reload.dependents_updated_at } } specify{ - expect{subject.update_attribute(:geo_entity_id, rwanda.id)}. - to change{@another_taxon_concept.reload.dependents_updated_at} + expect{ subject.update_attribute(:geo_entity_id, rwanda.id) }. + to change{ @another_taxon_concept.reload.dependents_updated_at } } end context "when suspension at higher taxonomic level" do @@ -148,8 +148,8 @@ ) } specify{ - expect{subject.update_attribute(:geo_entity_id, rwanda.id)}. - to change{@taxon_concept.reload.dependents_updated_at} + expect{ subject.update_attribute(:geo_entity_id, rwanda.id) }. + to change{ @taxon_concept.reload.dependents_updated_at } } end end @@ -163,7 +163,7 @@ ) } specify{ - expect{subject.destroy}.to change{@taxon_concept.reload.dependents_updated_at} + expect{ subject.destroy }.to change{ @taxon_concept.reload.dependents_updated_at } } end context "when global suspension" do @@ -176,8 +176,8 @@ ) } specify{ - expect{subject.destroy}. - to change{@taxon_concept.reload.dependents_updated_at} + expect{ subject.destroy }. + to change{ @taxon_concept.reload.dependents_updated_at } } end context "when suspension at higher taxonomic level" do @@ -189,8 +189,8 @@ ) } specify{ - expect{subject.destroy}. - to change{@taxon_concept.reload.dependents_updated_at} + expect{ subject.destroy }. + to change{ @taxon_concept.reload.dependents_updated_at } } end end diff --git a/spec/models/designation_spec.rb b/spec/models/designation_spec.rb index 65294cf735..ce9f939261 100644 --- a/spec/models/designation_spec.rb +++ b/spec/models/designation_spec.rb @@ -15,11 +15,11 @@ describe :create do context "when valid" do let(:designation){ build(:designation, :name => 'GALACTIC REGULATIONS') } - specify {designation.should be_valid} + specify { designation.should be_valid } end context "when name missing" do let(:designation){ build(:designation, :name => nil) } - specify { designation.should be_invalid} + specify { designation.should be_invalid } specify { designation.should have(1).error_on(:name) } end context "when name duplicated" do @@ -52,7 +52,7 @@ end context "when updating taxonomy with dependent objects attached" do let(:designation){ create(:designation) } - let!(:change_type){ create(:change_type, :designation => designation)} + let!(:change_type){ create(:change_type, :designation => designation) } let(:taxonomy){ create(:taxonomy) } specify{ designation.update_attributes(:taxonomy_id => taxonomy.id).should be_false } end @@ -64,7 +64,7 @@ end context "when dependent objects attached" do let(:designation){ create(:designation, :name => 'GALACTIC REGULATIONS') } - let!(:change_type){ create(:change_type, :designation => designation)} + let!(:change_type){ create(:change_type, :designation => designation) } specify { designation.destroy.should be_false } end context "when protected name" do diff --git a/spec/models/document_batch_spec.rb b/spec/models/document_batch_spec.rb index 2e8174ff5d..c5910187a4 100644 --- a/spec/models/document_batch_spec.rb +++ b/spec/models/document_batch_spec.rb @@ -15,7 +15,7 @@ ) } specify{ expect(subject.save).to be_false } - specify{ expect{subject.save}.not_to change{Document.count} } + specify{ expect{ subject.save }.not_to change{ Document.count } } end context "when valid" do subject { @@ -30,7 +30,7 @@ ) } specify{ expect(subject.save).to be_true } - specify{ expect{subject.save}.to change{Document.count}.by(1) } + specify{ expect{ subject.save }.to change{ Document.count }.by(1) } end end end \ No newline at end of file diff --git a/spec/models/eu_regulation_spec.rb b/spec/models/eu_regulation_spec.rb index 2fc781bca3..c9808c9cde 100644 --- a/spec/models/eu_regulation_spec.rb +++ b/spec/models/eu_regulation_spec.rb @@ -42,7 +42,7 @@ :designation => cites ) } - specify { eu_regulation.should be_invalid} + specify { eu_regulation.should be_invalid } specify { eu_regulation.should have(1).error_on(:designation_id) } end context "when effective_at is blank" do @@ -52,7 +52,7 @@ :effective_at => nil ) } - specify { eu_regulation.should be_invalid} + specify { eu_regulation.should be_invalid } specify { eu_regulation.should have(1).error_on(:effective_at) } end end diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb index 7c2446da57..c6682f4ccd 100644 --- a/spec/models/event_spec.rb +++ b/spec/models/event_spec.rb @@ -29,11 +29,11 @@ describe :create do context "when valid" do let(:event){ build(:event, :name => 'CoPX') } - specify {event.should be_valid} + specify { event.should be_valid } end context "when name missing" do let(:event){ build(:event, :name => nil) } - specify { event.should be_invalid} + specify { event.should be_invalid } specify { event.should have(1).error_on(:name) } end context "when name duplicated" do @@ -44,13 +44,13 @@ end context "when url invalid" do let(:event){ build(:event, :url => 'www.google.com') } - specify { event.should be_invalid} + specify { event.should be_invalid } specify { event.should have(1).error_on(:url) } end end describe :effective_at_formatted do let(:event){ create(:event, :effective_at => '2012-05-10') } - specify {event.effective_at_formatted.should == '10/05/2012' } + specify { event.effective_at_formatted.should == '10/05/2012' } end end diff --git a/spec/models/listing_change_spec.rb b/spec/models/listing_change_spec.rb index 73a724c6cf..4d6c9ac3ab 100644 --- a/spec/models/listing_change_spec.rb +++ b/spec/models/listing_change_spec.rb @@ -54,11 +54,11 @@ inclusion_taxon_concept_id: inclusion.id ) } - specify{listing_change.should have(1).error_on(:inclusion_taxon_concept_id)} + specify{ listing_change.should have(1).error_on(:inclusion_taxon_concept_id) } end context "species listing designation mismatch" do - let(:designation1){ create(:designation)} - let(:designation2){ create(:designation)} + let(:designation1){ create(:designation) } + let(:designation2){ create(:designation) } let(:listing_change){ build( :listing_change, @@ -66,11 +66,11 @@ :change_type => create(:change_type, :designation => designation2) ) } - specify{listing_change.should have(1).error_on(:species_listing_id)} + specify{ listing_change.should have(1).error_on(:species_listing_id) } end context "event designation mismatch" do - let(:designation1){ create(:designation)} - let(:designation2){ create(:designation)} + let(:designation1){ create(:designation) } + let(:designation2){ create(:designation) } let(:listing_change){ build( :listing_change, @@ -78,13 +78,13 @@ :change_type => create(:change_type, :designation => designation2) ) } - specify{listing_change.should have(1).error_on(:event_id)} + specify{ listing_change.should have(1).error_on(:event_id) } end end end describe :effective_at_formatted do let(:listing_change){ create_cites_I_addition(:effective_at => '2012-05-10') } - specify {listing_change.effective_at_formatted.should == '10/05/2012' } + specify { listing_change.effective_at_formatted.should == '10/05/2012' } end describe :duplicates do diff --git a/spec/models/nomenclature_change/lump/constructor_spec.rb b/spec/models/nomenclature_change/lump/constructor_spec.rb index 4c4bc45253..12f8b2852b 100644 --- a/spec/models/nomenclature_change/lump/constructor_spec.rb +++ b/spec/models/nomenclature_change/lump/constructor_spec.rb @@ -31,7 +31,7 @@ end end context :reassignments do - let(:lump){lump_with_inputs_and_output } + let(:lump){ lump_with_inputs_and_output } let(:nc){ lump } let(:input){ nc.inputs[0] } describe :build_input_and_output_notes do diff --git a/spec/models/preset_tag_spec.rb b/spec/models/preset_tag_spec.rb index eb64b31080..9af813c973 100644 --- a/spec/models/preset_tag_spec.rb +++ b/spec/models/preset_tag_spec.rb @@ -15,16 +15,16 @@ describe :create do context "when valid" do let(:preset_tag){ build(:preset_tag, :name => 'Test Tag', :model => 'TaxonConcept') } - specify {preset_tag.should be_valid} + specify { preset_tag.should be_valid } end context "when name missing" do let(:preset_tag){ build(:preset_tag, :name => nil, :model => 'TaxonConcept') } - specify { preset_tag.should be_invalid} + specify { preset_tag.should be_invalid } specify { preset_tag.should have(1).error_on(:name) } end context "when model (type) incorrect" do let(:preset_tag){ build(:preset_tag, :name => 'Test Tag', :model => 'Nope') } - specify { preset_tag.should be_invalid} + specify { preset_tag.should be_invalid } specify { preset_tag.should have(1).error_on(:model) } end end diff --git a/spec/models/quota_spec.rb b/spec/models/quota_spec.rb index b3a08604aa..15040ec040 100644 --- a/spec/models/quota_spec.rb +++ b/spec/models/quota_spec.rb @@ -79,7 +79,7 @@ ) } - specify {quota.should be_valid} + specify { quota.should be_valid } end context "when quota missing" do @@ -134,7 +134,7 @@ ) } - specify {quota.should_not be_valid} + specify { quota.should_not be_valid } specify { quota.should have(1).error_on(:unit) } end end diff --git a/spec/models/rank_spec.rb b/spec/models/rank_spec.rb index a3718a0b4d..b430c04479 100644 --- a/spec/models/rank_spec.rb +++ b/spec/models/rank_spec.rb @@ -19,7 +19,7 @@ describe :parent_rank_lower_bound do context "obligatory rank" do let(:rank) { create(:rank, name: Rank::KINGDOM) } - specify { rank.parent_rank_lower_bound.should == '0'} + specify { rank.parent_rank_lower_bound.should == '0' } end context "optional rank" do let(:rank) { create(:rank, name: Rank::SUBFAMILY) } diff --git a/spec/models/source_spec.rb b/spec/models/source_spec.rb index 5678339571..9c9da9a240 100644 --- a/spec/models/source_spec.rb +++ b/spec/models/source_spec.rb @@ -34,7 +34,7 @@ end context "when CITES quota" do let(:geo_entity) { create(:geo_entity) } - let!(:quota){ create(:quota, :sources => [source], :geo_entity_id => geo_entity.id)} + let!(:quota){ create(:quota, :sources => [source], :geo_entity_id => geo_entity.id) } specify { source.destroy.should be_false } end context "when shipments" do diff --git a/spec/models/species/invisible_subspecies_search_spec.rb b/spec/models/species/invisible_subspecies_search_spec.rb index 079e964db0..a19a132f4e 100644 --- a/spec/models/species/invisible_subspecies_search_spec.rb +++ b/spec/models/species/invisible_subspecies_search_spec.rb @@ -5,8 +5,8 @@ context "when searching by scientific name" do context "when subspecies never listed" do subject { Species::Search.new({:taxon_concept_query => 'amazona festiva festiva'}).results } - specify { subject.should_not include(@subspecies2_2_2_1)} - specify { subject.should include(@species2_2_2)} + specify { subject.should_not include(@subspecies2_2_2_1) } + specify { subject.should include(@species2_2_2) } end end end diff --git a/spec/models/species/listings_export_spec.rb b/spec/models/species/listings_export_spec.rb index beb12fc548..b19ed91fde 100644 --- a/spec/models/species/listings_export_spec.rb +++ b/spec/models/species/listings_export_spec.rb @@ -7,7 +7,7 @@ :designation_id => cites.id }) } - specify {subject.path.should == "public/downloads/cites_listings/" } + specify { subject.path.should == "public/downloads/cites_listings/" } end describe :export do context "when no results" do diff --git a/spec/models/species/search_spec.rb b/spec/models/species/search_spec.rb index 9baf7da9e5..5d2a8be71b 100644 --- a/spec/models/species/search_spec.rb +++ b/spec/models/species/search_spec.rb @@ -5,19 +5,19 @@ context "when searching by scientific name" do context "when regular query" do subject { Species::Search.new({:taxon_concept_query => 'canis'}).results } - specify { subject.should include(@species)} + specify { subject.should include(@species) } end context "when malicious query" do subject { Species::Search.new({:taxon_concept_query => 'canis\''}).results } - specify { subject.should be_empty} + specify { subject.should be_empty } end context "when leading whitespace" do subject { Species::Search.new({:taxon_concept_query => ' canis'}).results } - specify { subject.should include(@species)} + specify { subject.should include(@species) } end context "when trailing whitespace" do subject { Species::Search.new({:taxon_concept_query => 'canis '}).results } - specify { subject.should include(@species)} + specify { subject.should include(@species) } end end end diff --git a/spec/models/species/taxon_concept_prefix_matcher_spec.rb b/spec/models/species/taxon_concept_prefix_matcher_spec.rb index 42b3b37d25..3099428047 100644 --- a/spec/models/species/taxon_concept_prefix_matcher_spec.rb +++ b/spec/models/species/taxon_concept_prefix_matcher_spec.rb @@ -11,7 +11,7 @@ :ranks => [] }) } - specify { subject.results.should include(@species_ac)} + specify { subject.results.should include(@species_ac) } end context "when searching by hyphenated common name without hyphens" do subject { @@ -20,7 +20,7 @@ :ranks => [] }) } - specify { subject.results.should include(@species_ac)} + specify { subject.results.should include(@species_ac) } end context "when searching by part of hyphenated common name" do subject { @@ -29,7 +29,7 @@ :ranks => [] }) } - specify { subject.results.should include(@species_ac)} + specify { subject.results.should include(@species_ac) } end end context "when searching by scientific name" do @@ -40,7 +40,7 @@ :ranks => [] }) } - specify { subject.results.should include(@species_ac)} + specify { subject.results.should include(@species_ac) } end context "when malicious query" do subject { @@ -49,7 +49,7 @@ :ranks => [] }) } - specify { subject.results.should be_empty} + specify { subject.results.should be_empty } end context "when leading whitespace" do subject { @@ -58,7 +58,7 @@ :ranks => [] }) } - specify { subject.results.should include(@species_ac)} + specify { subject.results.should include(@species_ac) } end context "when trailing whitespace" do subject { @@ -67,7 +67,7 @@ :ranks => [] }) } - specify { subject.results.should include(@species_ac)} + specify { subject.results.should include(@species_ac) } end context "when implicitly listed subspecies" do subject { @@ -76,7 +76,7 @@ :ranks => [] }) } - specify { subject.results.should_not include(@subspecies2_ac)} + specify { subject.results.should_not include(@subspecies2_ac) } end context "when explicitly listed subspecies" do subject { @@ -85,7 +85,7 @@ :ranks => [] }) } - specify { subject.results.should include(@subspecies1_ac)} + specify { subject.results.should include(@subspecies1_ac) } end context "when implicitly listed higher taxon (without an explicitly listed ancestor)" do subject { @@ -94,7 +94,7 @@ :ranks => [] }) } - specify { subject.results.should include(@order_ac)} + specify { subject.results.should include(@order_ac) } end context "when explicitly listed higher taxon" do subject { @@ -103,7 +103,7 @@ :ranks => [] }) } - specify { subject.results.should include(@family_ac)} + specify { subject.results.should include(@family_ac) } end #check ranks filtering context "when explicitly listed higher taxon but ranks expected FAMILY" do @@ -114,7 +114,7 @@ :visibility => :trade }) } - specify { subject.results.should include(@family_ac)} + specify { subject.results.should include(@family_ac) } end context "when explicitly listed higher taxon but ranks expected SPECIES" do subject { diff --git a/spec/models/species/visible_subspecies_search_spec.rb b/spec/models/species/visible_subspecies_search_spec.rb index 73fd4205c6..97bcb091eb 100644 --- a/spec/models/species/visible_subspecies_search_spec.rb +++ b/spec/models/species/visible_subspecies_search_spec.rb @@ -5,7 +5,7 @@ context "when searching by scientific name" do context "when subspecies previously listed " do subject { Species::Search.new({:taxon_concept_query => 'canis lupus'}).results } - specify { subject.should include(@subspecies)} + specify { subject.should include(@subspecies) } end end end diff --git a/spec/models/taxon_concept/colophon_spec.rb b/spec/models/taxon_concept/colophon_spec.rb index 52d3d132ea..a7f4c1bf30 100644 --- a/spec/models/taxon_concept/colophon_spec.rb +++ b/spec/models/taxon_concept/colophon_spec.rb @@ -26,7 +26,7 @@ describe :cites_listed do context "for genus Colophon" do - specify { @genus.cites_listed.should == true} + specify { @genus.cites_listed.should == true } end context "for species Colophon barnardi" do specify { @species.cites_listed.should == false } @@ -35,7 +35,7 @@ describe :eu_listed do context "for genus Colophon" do - specify { @genus.eu_listed.should == true} + specify { @genus.eu_listed.should == true } end context "for species Colophon barnardi" do specify { @species.eu_listed.should == false } diff --git a/spec/models/taxon_concept/destroy_spec.rb b/spec/models/taxon_concept/destroy_spec.rb index 45efd6fc9a..fd29bd25df 100644 --- a/spec/models/taxon_concept/destroy_spec.rb +++ b/spec/models/taxon_concept/destroy_spec.rb @@ -9,45 +9,45 @@ specify { @taxon_concept.destroy.should be_true } end context "when distributions" do - before(:each){ create(:distribution, :taxon_concept => @taxon_concept)} - specify { @taxon_concept.destroy.should be_true} + before(:each){ create(:distribution, :taxon_concept => @taxon_concept) } + specify { @taxon_concept.destroy.should be_true } end context "when common names" do - before(:each){ create(:taxon_common, :taxon_concept => @taxon_concept)} + before(:each){ create(:taxon_common, :taxon_concept => @taxon_concept) } specify { @taxon_concept.destroy.should be_true } end context "when references" do - before(:each){ create(:taxon_concept_reference, :taxon_concept => @taxon_concept)} + before(:each){ create(:taxon_concept_reference, :taxon_concept => @taxon_concept) } specify { @taxon_concept.destroy.should be_true } end end context "CMS" do before(:each){ @taxon_concept = create_cms_species } context "when taxon instruments" do - before(:each){ create(:taxon_instrument, :taxon_concept => @taxon_concept)} + before(:each){ create(:taxon_instrument, :taxon_concept => @taxon_concept) } specify { @taxon_concept.destroy.should be_false } end end context "CITES / EU" do before(:each){ @taxon_concept = create_cites_eu_species } context "when listing changes" do - before(:each){ create_cites_I_addition(:taxon_concept => @taxon_concept)} + before(:each){ create_cites_I_addition(:taxon_concept => @taxon_concept) } specify { @taxon_concept.destroy.should be_false } end context "when CITES quotas" do - before(:each){ create(:quota, :taxon_concept => @taxon_concept, :geo_entity => create(:geo_entity))} + before(:each){ create(:quota, :taxon_concept => @taxon_concept, :geo_entity => create(:geo_entity)) } specify { @taxon_concept.destroy.should be_false } end context "when CITES suspensions" do - before(:each){ create(:cites_suspension, :taxon_concept => @taxon_concept, :start_notification => create(:cites_suspension_notification, :designation => cites))} + before(:each){ create(:cites_suspension, :taxon_concept => @taxon_concept, :start_notification => create(:cites_suspension_notification, :designation => cites)) } specify { @taxon_concept.destroy.should be_false } end context "when EU opinions" do - before(:each){ create(:eu_opinion, :taxon_concept => @taxon_concept)} + before(:each){ create(:eu_opinion, :taxon_concept => @taxon_concept) } specify { @taxon_concept.destroy.should be_false } end context "when EU suspensions" do - before(:each){ create(:eu_suspension, :taxon_concept => @taxon_concept)} + before(:each){ create(:eu_suspension, :taxon_concept => @taxon_concept) } specify { @taxon_concept.destroy.should be_false } end context "when shipments" do diff --git a/spec/models/taxon_concept/validation_spec.rb b/spec/models/taxon_concept/validation_spec.rb index 5aa9b7c67f..917b261e57 100644 --- a/spec/models/taxon_concept/validation_spec.rb +++ b/spec/models/taxon_concept/validation_spec.rb @@ -16,7 +16,7 @@ :parent_id => kingdom_tc.id ) } - specify{ tc.valid? should be_true} + specify{ tc.valid? should be_true } end context "taxonomy does not match parent" do let(:tc) { diff --git a/spec/models/taxon_concept_prefix_matcher_spec.rb b/spec/models/taxon_concept_prefix_matcher_spec.rb index 9e7d3802e6..6ad9a277a8 100644 --- a/spec/models/taxon_concept_prefix_matcher_spec.rb +++ b/spec/models/taxon_concept_prefix_matcher_spec.rb @@ -50,8 +50,8 @@ SearchParams.new(:taxonomy => {:id => taxonomy.id}, :scientific_name => 'Ab') } let(:matcher){ TaxonConceptPrefixMatcher.new matcher_params } - specify{ matcher.taxon_concepts.should include(taxon_concept4)} - specify{ matcher.taxon_concepts.should_not include(hybrid)} + specify{ matcher.taxon_concepts.should include(taxon_concept4) } + specify{ matcher.taxon_concepts.should_not include(hybrid) } end context "when name status H" do @@ -59,8 +59,8 @@ SearchParams.new(:taxonomy => {:id => taxonomy.id}, :scientific_name => 'Ab', :name_status => 'H') } let(:matcher){ TaxonConceptPrefixMatcher.new matcher_params } - specify{ matcher.taxon_concepts.should_not include(taxon_concept4)} - specify{ matcher.taxon_concepts.should include(hybrid)} + specify{ matcher.taxon_concepts.should_not include(taxon_concept4) } + specify{ matcher.taxon_concepts.should include(hybrid) } end context "when rank scope applied" do diff --git a/spec/models/taxon_relationship_spec.rb b/spec/models/taxon_relationship_spec.rb index dd5f860076..33843d4a49 100644 --- a/spec/models/taxon_relationship_spec.rb +++ b/spec/models/taxon_relationship_spec.rb @@ -17,12 +17,12 @@ describe TaxonRelationship do describe :has_opposite? do context 'a relationship with no opposite' do - let(:taxon_relationship_type) {create(:taxon_relationship_type, :is_bidirectional => false)} + let(:taxon_relationship_type) { create(:taxon_relationship_type, :is_bidirectional => false) } let!(:taxon_relationship) { create(:taxon_relationship, :taxon_relationship_type_id => taxon_relationship_type.id) } specify { taxon_relationship.has_opposite?.should == false } end context 'with an opposite' do - let(:taxon_relationship_type) {create(:taxon_relationship_type, :is_bidirectional => true)} + let(:taxon_relationship_type) { create(:taxon_relationship_type, :is_bidirectional => true) } let(:taxon_relationship) { create(:taxon_relationship, :taxon_relationship_type_id => taxon_relationship_type.id) } specify { taxon_relationship.has_opposite?.should == true } end @@ -30,13 +30,13 @@ describe :after_create_create_opposite do context 'when creating a bidirectional relationship' do - let(:taxon_relationship_type) {create(:taxon_relationship_type, :is_bidirectional => true)} + let(:taxon_relationship_type) { create(:taxon_relationship_type, :is_bidirectional => true) } let!(:taxon_relationship) { create(:taxon_relationship, :taxon_relationship_type_id => taxon_relationship_type.id) } specify { taxon_relationship.has_opposite?.should == true } end context 'when creating a non bidirectional relationship' do - let(:taxon_relationship_type) {create(:taxon_relationship_type, :is_bidirectional => false)} + let(:taxon_relationship_type) { create(:taxon_relationship_type, :is_bidirectional => false) } let!(:taxon_relationship) { create(:taxon_relationship, :taxon_relationship_type_id => taxon_relationship_type.id) } specify { taxon_relationship.has_opposite?.should == false } end diff --git a/spec/models/taxonomy_spec.rb b/spec/models/taxonomy_spec.rb index 3894f01f2d..a57ea985cb 100644 --- a/spec/models/taxonomy_spec.rb +++ b/spec/models/taxonomy_spec.rb @@ -14,11 +14,11 @@ describe :create do context "when valid" do let(:taxonomy){ build(:taxonomy, :name => 'WILDLIFE') } - specify {taxonomy.should be_valid} + specify { taxonomy.should be_valid } end context "when name missing" do let(:taxonomy){ build(:taxonomy, :name => nil) } - specify { taxonomy.should be_invalid} + specify { taxonomy.should be_invalid } specify { taxonomy.should have(1).error_on(:name) } end context "when name duplicated" do @@ -44,7 +44,7 @@ end context "when dependent objects attached" do let(:taxonomy){ create(:taxonomy, :name => 'WILDLIFE') } - let!(:designation){ create(:designation, :taxonomy => taxonomy)} + let!(:designation){ create(:designation, :taxonomy => taxonomy) } specify { taxonomy.destroy.should be_false } end context "when protected name" do diff --git a/spec/models/term_spec.rb b/spec/models/term_spec.rb index 927f5a3fa4..fb79a814e5 100644 --- a/spec/models/term_spec.rb +++ b/spec/models/term_spec.rb @@ -34,7 +34,7 @@ end context "when CITES quota" do let(:geo_entity) { create(:geo_entity) } - let!(:quota){ create(:quota, :terms => [term], :geo_entity_id => geo_entity.id)} + let!(:quota){ create(:quota, :terms => [term], :geo_entity_id => geo_entity.id) } specify { term.destroy.should be_false } end context "when shipments" do diff --git a/spec/models/trade/annual_report_upload_spec.rb b/spec/models/trade/annual_report_upload_spec.rb index ff5af97392..272002dd3a 100644 --- a/spec/models/trade/annual_report_upload_spec.rb +++ b/spec/models/trade/annual_report_upload_spec.rb @@ -51,7 +51,7 @@ def invalid_file :csv_source_file => exporter_file ) } - specify {subject.should be_valid} + specify { subject.should be_valid } end context "when uploaded file as importer with exporter column headers" do subject{ @@ -61,7 +61,7 @@ def invalid_file :csv_source_file => exporter_file ) } - specify {subject.should_not be_valid} + specify { subject.should_not be_valid } end context "when uploaded file as importer with importer column headers" do subject{ @@ -71,7 +71,7 @@ def invalid_file :csv_source_file => importer_file ) } - specify {subject.should be_valid} + specify { subject.should be_valid } end context "when uploaded file as exporter with importer column headers" do subject{ @@ -81,7 +81,7 @@ def invalid_file :csv_source_file => importer_file ) } - specify {subject.should_not be_valid} + specify { subject.should_not be_valid } end end @@ -174,10 +174,10 @@ def invalid_file aru } specify { - expect{subject.submit}.to change{Trade::Shipment.count}.by(1) + expect{ subject.submit }.to change{ Trade::Shipment.count }.by(1) } specify { - expect{subject.submit}.to change{Trade::Permit.count}.by(3) + expect{ subject.submit }.to change{ Trade::Permit.count }.by(3) } specify { #make sure leading space is stripped subject.submit; Trade::Permit.find_by_number('BBB').should_not be_nil @@ -185,7 +185,7 @@ def invalid_file context "when permit previously reported" do before(:each) { create(:permit, :number => 'xxx') } specify { - expect{subject.submit}.to change{Trade::Permit.count}.by(2) + expect{ subject.submit }.to change{ Trade::Permit.count }.by(2) } end end @@ -205,7 +205,7 @@ def invalid_file aru } specify { - expect{subject.submit}.not_to change{Trade::Shipment.count} + expect{ subject.submit }.not_to change{ Trade::Shipment.count } } end context "when reported under a synonym" do @@ -239,7 +239,7 @@ def invalid_file aru } specify { - expect{subject.submit}.to change{Trade::Shipment.count}.by(1) + expect{ subject.submit }.to change{ Trade::Shipment.count }.by(1) } specify { subject.submit diff --git a/spec/models/trade/permit_matcher_spec.rb b/spec/models/trade/permit_matcher_spec.rb index a2d6808a40..a5840abdf6 100644 --- a/spec/models/trade/permit_matcher_spec.rb +++ b/spec/models/trade/permit_matcher_spec.rb @@ -7,23 +7,23 @@ end context "when regular query" do subject { Trade::PermitMatcher.new({:permit_query => '006'}).results } - specify { subject.should include(@permit)} + specify { subject.should include(@permit) } end context "when wildcard query" do subject { Trade::PermitMatcher.new({:permit_query => '%AA'}).results } - specify { subject.should include(@permit)} + specify { subject.should include(@permit) } end context "when malicious query" do subject { Trade::PermitMatcher.new({:permit_query => '006\''}).results } - specify { subject.should be_empty} + specify { subject.should be_empty } end context "when leading whitespace" do subject { Trade::PermitMatcher.new({:permit_query => ' 006'}).results } - specify { subject.should include(@permit)} + specify { subject.should include(@permit) } end context "when trailing whitespace" do subject { Trade::PermitMatcher.new({:permit_query => '006AAA '}).results } - specify { subject.should include(@permit)} + specify { subject.should include(@permit) } end end end diff --git a/spec/models/unit_spec.rb b/spec/models/unit_spec.rb index 02629f5248..7a391f5fad 100644 --- a/spec/models/unit_spec.rb +++ b/spec/models/unit_spec.rb @@ -24,7 +24,7 @@ let(:unit){ create(:unit) } context "when quotas" do let(:geo_entity){ create(:geo_entity) } - let!(:quota){ create(:quota, :unit => unit, :geo_entity_id => geo_entity.id)} + let!(:quota){ create(:quota, :unit => unit, :geo_entity_id => geo_entity.id) } specify { unit.destroy.should be_false } end context "when shipments" do diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 900992d4aa..e38d099729 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -30,7 +30,7 @@ describe :create do context "when organisation not given" do let(:user){ build(:user, organisation: nil) } - specify{ expect(user).to_not be_valid} + specify{ expect(user).to_not be_valid } end end describe :destroy do @@ -58,8 +58,8 @@ context "when is a Data Contributor" do let(:user){ create(:user, role: User::CONTRIBUTOR) } - it{ should be_able_to(:create, TaxonConcept)} - it{ should_not be_able_to(:destroy, TaxonConcept)} + it{ should be_able_to(:create, TaxonConcept) } + it{ should_not be_able_to(:destroy, TaxonConcept) } end context "when is a E-library Viewer" do diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 0cfc18425f..27cb0a2ce7 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -21,9 +21,9 @@ # Requires supporting ruby files with custom matchers and macros, etc, # in spec/support/ and its subdirectories. -Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f} -Dir[Rails.root.join("spec/shared/*.rb")].each {|f| require f} -Dir[Rails.root.join("spec/models/nomenclature_change/shared/*.rb")].each {|f| require f} +Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f } +Dir[Rails.root.join("spec/shared/*.rb")].each { |f| require f } +Dir[Rails.root.join("spec/models/nomenclature_change/shared/*.rb")].each { |f| require f } RSpec.configure do |config| # ## Mock Framework # diff --git a/spec/workers/quotas_copy_worker_spec.rb b/spec/workers/quotas_copy_worker_spec.rb index b8d0979367..1819a398ca 100644 --- a/spec/workers/quotas_copy_worker_spec.rb +++ b/spec/workers/quotas_copy_worker_spec.rb @@ -44,10 +44,10 @@ before(:each) do QuotasCopyWorker.new.perform(job_defaults) end - specify { Quota.count(true).should == 2} - specify { Quota.where(:is_current => true).count(true).should == 1} - specify { Quota.where(:is_current => false).count(true).should == 1} - specify { Quota.where(:is_current => false).first.id.should == quota.id} + specify { Quota.count(true).should == 2 } + specify { Quota.where(:is_current => true).count(true).should == 1 } + specify { Quota.where(:is_current => false).count(true).should == 1 } + specify { Quota.where(:is_current => false).first.id.should == quota.id } end describe "Try to copy quota from wrong year" do @@ -56,9 +56,9 @@ "from_year" => quota.start_date.year+1 })) end - specify { Quota.count(true).should == 1} - specify { Quota.where(:is_current => true).count(true).should == 1} - specify { Quota.where(:is_current => false).count(true).should == 0} + specify { Quota.count(true).should == 1 } + specify { Quota.where(:is_current => true).count(true).should == 1 } + specify { Quota.where(:is_current => false).count(true).should == 0 } end describe "Copy quota when there are no current quotas" do @@ -67,9 +67,9 @@ quota.save QuotasCopyWorker.new.perform(job_defaults) end - specify { Quota.count(true).should == 1} - specify { Quota.where(:is_current => true).count(true).should == 0} - specify { Quota.where(:is_current => false).count(true).should == 1} + specify { Quota.count(true).should == 1 } + specify { Quota.where(:is_current => true).count(true).should == 0 } + specify { Quota.where(:is_current => false).count(true).should == 1 } end describe "When multiple quotas copy quota for given country" do @@ -87,10 +87,10 @@ "included_geo_entities_ids" => [geo_entity.id] })) end - specify { Quota.count(true).should == 3} - specify { Quota.where(:is_current => true).count(true).should == 2} + specify { Quota.count(true).should == 3 } + specify { Quota.where(:is_current => true).count(true).should == 2 } specify { Quota.where(:is_current => true).map(&:id).should include(@quota2.id) } - specify { Quota.where(:is_current => false).count(true).should == 1} + specify { Quota.where(:is_current => false).count(true).should == 1 } specify { Quota.where(:is_current => false).first.id.should == quota.id } end @@ -109,9 +109,9 @@ "included_geo_entities_ids" => [geo_entity.id.to_s, geo_entity2.id.to_s] })) end - specify { Quota.count(true).should == 4} - specify { Quota.where(:is_current => true).count(true).should == 2} - specify { Quota.where(:is_current => false).count(true).should == 2} + specify { Quota.count(true).should == 4 } + specify { Quota.where(:is_current => true).count(true).should == 2 } + specify { Quota.where(:is_current => false).count(true).should == 2 } specify { Quota.where(:is_current => false).map(&:id).should include(quota.id) } specify { Quota.where(:is_current => false).map(&:id).should include(@quota2.id) } end @@ -131,10 +131,10 @@ "excluded_geo_entities_ids" => [geo_entity2.id.to_s] })) end - specify { Quota.count(true).should == 3} - specify { Quota.where(:is_current => true).count(true).should == 2} + specify { Quota.count(true).should == 3 } + specify { Quota.where(:is_current => true).count(true).should == 2 } specify { Quota.where(:is_current => true).map(&:id).should include(@quota2.id) } - specify { Quota.where(:is_current => false).count(true).should == 1} + specify { Quota.where(:is_current => false).count(true).should == 1 } specify { Quota.where(:is_current => false).first.id.should == quota.id } end @@ -152,10 +152,10 @@ "included_taxon_concepts_ids" => quota.taxon_concept_id.to_s })) end - specify { Quota.count(true).should == 3} - specify { Quota.where(:is_current => true).count(true).should == 2} + specify { Quota.count(true).should == 3 } + specify { Quota.where(:is_current => true).count(true).should == 2 } specify { Quota.where(:is_current => true).map(&:id).should include(@quota2.id) } - specify { Quota.where(:is_current => false).count(true).should == 1} + specify { Quota.where(:is_current => false).count(true).should == 1 } specify { Quota.where(:is_current => false).map(&:id).should include(quota.id) } end @@ -174,10 +174,10 @@ "included_taxon_concepts_ids" => "#{taxon_concept.id},#{tc.id}" })) end - specify { Quota.count(true).should == 4} - specify { Quota.where(:is_current => true).count(true).should == 2} + specify { Quota.count(true).should == 4 } + specify { Quota.where(:is_current => true).count(true).should == 2 } specify { Quota.where(:is_current => true).map(&:id).should_not include(@quota2.id) } - specify { Quota.where(:is_current => false).count(true).should == 2} + specify { Quota.where(:is_current => false).count(true).should == 2 } specify { Quota.where(:is_current => false).map(&:id).should include(quota.id) } end @@ -195,10 +195,10 @@ "excluded_taxon_concepts_ids" => tc.id.to_s })) end - specify { Quota.count(true).should == 3} - specify { Quota.where(:is_current => true).count(true).should == 2} + specify { Quota.count(true).should == 3 } + specify { Quota.where(:is_current => true).count(true).should == 2 } specify { Quota.where(:is_current => true).map(&:id).should include(@quota2.id) } - specify { Quota.where(:is_current => false).count(true).should == 1} + specify { Quota.where(:is_current => false).count(true).should == 1 } specify { Quota.where(:is_current => false).first.id.should == quota.id } end @@ -219,14 +219,14 @@ })) end - specify { Quota.count(true).should == 4} - specify { Quota.where(:is_current => true).count(true).should == 2} + specify { Quota.count(true).should == 4 } + specify { Quota.where(:is_current => true).count(true).should == 2 } specify { Quota.where(:is_current => true).map(&:id).should_not include(@quota2.id) } specify { Quota.where(:is_current => true).map(&:id).should_not include(quota.id) } - specify { Quota.where(:is_current => false).count(true).should == 2} - specify { Quota.where(:is_current => true).map(&:notes).should include(@quota2.notes)} - specify { Quota.where(:is_current => true).map(&:notes).should_not include(quota.notes)} - specify { Quota.where(:is_current => true).map(&:notes).should include('Le Salmon is my favourite fish')} + specify { Quota.where(:is_current => false).count(true).should == 2 } + specify { Quota.where(:is_current => true).map(&:notes).should include(@quota2.notes) } + specify { Quota.where(:is_current => true).map(&:notes).should_not include(quota.notes) } + specify { Quota.where(:is_current => true).map(&:notes).should include('Le Salmon is my favourite fish') } end describe "When url passed, should be replaced" do @@ -242,11 +242,11 @@ :notes => "Derp di doo wildlife") QuotasCopyWorker.new.perform(job_defaults.merge({"url" => 'http://myurl.co.uk'})) end - specify { Quota.count(true).should == 4} - specify { Quota.where(:is_current => true).count(true).should == 2} + specify { Quota.count(true).should == 4 } + specify { Quota.where(:is_current => true).count(true).should == 2 } specify { Quota.where(:is_current => true).map(&:id).should_not include(@quota2.id) } specify { Quota.where(:is_current => true).map(&:id).should_not include(quota.id) } - specify { Quota.where(:is_current => false).count(true).should == 2} - specify { Quota.where(:is_current => true).map(&:url).should include('http://myurl.co.uk')} + specify { Quota.where(:is_current => false).count(true).should == 2 } + specify { Quota.where(:is_current => true).map(&:url).should include('http://myurl.co.uk') } end end From 0f36ae734fb69372190828b09d7226ee522ad58c Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 1 Jul 2016 09:34:44 +0100 Subject: [PATCH 322/365] enabled Style/SpaceAfterNot --- .rubocop_todo.yml | 9 --------- app/models/checklist/csv/history_content.rb | 2 +- app/models/checklist/csv/index_content.rb | 2 +- app/models/checklist/pdf/history_content.rb | 2 +- app/models/checklist/pdf/index_content.rb | 2 +- 5 files changed, 4 insertions(+), 13 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 2db576da08..65df80dcc0 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -605,15 +605,6 @@ Style/SignalException: Style/SingleLineMethods: Enabled: false -# Offense count: 4 -# Cop supports --auto-correct. -Style/SpaceAfterNot: - Exclude: - - 'app/models/checklist/csv/history_content.rb' - - 'app/models/checklist/csv/index_content.rb' - - 'app/models/checklist/pdf/history_content.rb' - - 'app/models/checklist/pdf/index_content.rb' - # Offense count: 93 # Cop supports --auto-correct. # Configuration parameters: AllowForAlignment. diff --git a/app/models/checklist/csv/history_content.rb b/app/models/checklist/csv/history_content.rb index 8deffdb480..11d30cfa3e 100644 --- a/app/models/checklist/csv/history_content.rb +++ b/app/models/checklist/csv/history_content.rb @@ -15,7 +15,7 @@ def kingdom(csv, fetcher) csv << taxon_concepts_csv_columns.map { |c| tc.send(c) } + listing_changes_csv_columns.map { |c| tc[c] } end - end while not kingdom.empty? + end while !kingdom.empty? end end \ No newline at end of file diff --git a/app/models/checklist/csv/index_content.rb b/app/models/checklist/csv/index_content.rb index 9f618217a8..b20de5301f 100644 --- a/app/models/checklist/csv/index_content.rb +++ b/app/models/checklist/csv/index_content.rb @@ -21,7 +21,7 @@ def kingdom(csv, fetcher) end csv << entry end - end while not kingdom.empty? + end while !kingdom.empty? end end \ No newline at end of file diff --git a/app/models/checklist/pdf/history_content.rb b/app/models/checklist/pdf/history_content.rb index 7088e02c06..4905a8b642 100644 --- a/app/models/checklist/pdf/history_content.rb +++ b/app/models/checklist/pdf/history_content.rb @@ -45,7 +45,7 @@ def kingdom(tex, fetcher, kingdom_name) listed_taxa_ary = [] end kingdom = fetcher.next - end while not kingdom.empty? + end while !kingdom.empty? end def listed_taxa(tex, listed_taxa_ary, kingdom_name = 'FAUNA') diff --git a/app/models/checklist/pdf/index_content.rb b/app/models/checklist/pdf/index_content.rb index 0ad7fb5197..fc8bb2d382 100644 --- a/app/models/checklist/pdf/index_content.rb +++ b/app/models/checklist/pdf/index_content.rb @@ -29,7 +29,7 @@ def kingdom(tex, fetcher, kingdom_name) end tex << entries.join("\n\n") kingdom = fetcher.next - end while not kingdom.empty? + end while !kingdom.empty? tex << '}\\end{multicols}' #end multicols end From ae56c4edf1dcd8d9d5b65d9cae2599939dbece2d Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 1 Jul 2016 09:36:37 +0100 Subject: [PATCH 323/365] enabled Style/SpaceInsideBrackets --- .rubocop_todo.yml | 9 --------- app/models/country_dictionary.rb | 2 +- .../trade/taxon_concept_appendix_year_validation_rule.rb | 2 +- config/initializers/devise.rb | 4 ++-- config/routes.rb | 2 +- 5 files changed, 5 insertions(+), 14 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 65df80dcc0..c7102d4a85 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -618,15 +618,6 @@ Style/SpaceAroundOperators: Style/SpaceBeforeBlockBraces: Enabled: false -# Offense count: 9 -# Cop supports --auto-correct. -Style/SpaceInsideBrackets: - Exclude: - - 'app/models/country_dictionary.rb' - - 'app/models/trade/taxon_concept_appendix_year_validation_rule.rb' - - 'config/initializers/devise.rb' - - 'config/routes.rb' - # Offense count: 697 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SupportedStyles. diff --git a/app/models/country_dictionary.rb b/app/models/country_dictionary.rb index 49a59e8ba7..d096f571e0 100644 --- a/app/models/country_dictionary.rb +++ b/app/models/country_dictionary.rb @@ -11,7 +11,7 @@ def initialize where(:"geo_entity_types.name" => [GeoEntityType::COUNTRY, GeoEntityType::TERRITORY]). all @dictionary = Hash[ - @collection.map { |c| [c.id, [c.name, c.iso_code2] ] } + @collection.map { |c| [c.id, [c.name, c.iso_code2]] } ] end diff --git a/app/models/trade/taxon_concept_appendix_year_validation_rule.rb b/app/models/trade/taxon_concept_appendix_year_validation_rule.rb index ecbe9450ef..e6517590bc 100644 --- a/app/models/trade/taxon_concept_appendix_year_validation_rule.rb +++ b/app/models/trade/taxon_concept_appendix_year_validation_rule.rb @@ -34,7 +34,7 @@ def validation_errors_for_shipment(shipment) private def year_join_node(s, v) - sandbox_year = Arel::Nodes::NamedFunction.new "CAST", [ s['year'].as('INT') ] + sandbox_year = Arel::Nodes::NamedFunction.new "CAST", [s['year'].as('INT')] effective_from = Arel::Nodes::NamedFunction.new "DATE_PART", ["year", v['effective_from']] effective_to = Arel::Nodes::NamedFunction.new "DATE_PART", ["year", v['effective_to']] effective_from.lteq(sandbox_year).and(effective_to.gteq(sandbox_year).or(effective_to.eq(nil))) diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index a9d6a1f8bd..c3d3e19fac 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -41,12 +41,12 @@ # Configure which authentication keys should be case-insensitive. # These keys will be downcased upon creating or modifying a user and when used # to authenticate or find a user. Default is :email. - config.case_insensitive_keys = [ :email ] + config.case_insensitive_keys = [:email] # Configure which authentication keys should have whitespace stripped. # These keys will have whitespace before and after removed upon creating or # modifying a user and when used to authenticate or find a user. Default is :email. - config.strip_whitespace_keys = [ :email ] + config.strip_whitespace_keys = [:email] # Tell if authentication through request.params is enabled. True by default. # It can be set to an array that will enable params authentication only for the diff --git a/config/routes.rb b/config/routes.rb index bfa86e9e09..b3b56d3b8c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -145,7 +145,7 @@ resources :taxon_cites_suspensions, :only => [:index, :new, :create, :edit, :update, :destroy], :as => :cites_suspensions - resources :taxon_instruments, :only => [ :index, :new, :create, :edit, :update, :destroy ] + resources :taxon_instruments, :only => [:index, :new, :create, :edit, :update, :destroy] end resources :nomenclature_changes do resources :split, controller: 'nomenclature_changes/split' From bfee3be4b9206cccb71c929cefdd565c74f63784 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 1 Jul 2016 09:43:54 +0100 Subject: [PATCH 324/365] enabled Style/SpaceInsideHashLiteralBraces --- .rubocop.yml | 6 +++ .rubocop_todo.yml | 7 --- .../admin/cites_suspensions_controller.rb | 2 +- .../admin/cms_mappings_controller.rb | 2 +- .../admin/designations_controller.rb | 2 +- .../admin/distributions_controller.rb | 2 +- app/controllers/admin/documents_controller.rb | 2 +- .../admin/eu_opinions_controller.rb | 2 +- app/controllers/admin/events_controller.rb | 2 +- .../admin/geo_entities_controller.rb | 2 +- .../admin/geo_relationships_controller.rb | 4 +- .../admin/instruments_controller.rb | 2 +- app/controllers/admin/quotas_controller.rb | 2 +- .../admin/references_controller.rb | 2 +- .../taxon_cites_suspensions_controller.rb | 2 +- .../taxon_concept_term_pairs_controller.rb | 2 +- .../admin/taxon_eu_suspensions_controller.rb | 2 +- .../admin/taxon_instruments_controller.rb | 2 +- .../admin/taxon_listing_changes_controller.rb | 2 +- .../admin/taxon_quotas_controller.rb | 2 +- .../admin/taxonomies_controller.rb | 2 +- .../term_trade_codes_pairs_controller.rb | 4 +- .../api/geo_relationships_controller.rb | 2 +- app/controllers/api/ranks_controller.rb | 2 +- .../v1/document_geo_entities_controller.rb | 2 +- .../api/v1/document_tags_controller.rb | 2 +- app/controllers/api/v1/events_controller.rb | 2 +- .../api/v1/geo_entities_controller.rb | 2 +- app/controllers/api/v1/purposes_controller.rb | 4 +- app/controllers/api/v1/sources_controller.rb | 4 +- .../api/v1/taxon_concepts_controller.rb | 2 +- app/controllers/api/v1/terms_controller.rb | 4 +- app/controllers/api/v1/units_controller.rb | 4 +- .../checklist/downloads_controller.rb | 6 +-- app/controllers/cites_trade_controller.rb | 18 +++---- app/controllers/species/exports_controller.rb | 2 +- .../trade/annual_report_uploads_controller.rb | 2 +- app/controllers/trade/shipments_controller.rb | 4 +- app/controllers/trade_controller.rb | 22 ++++---- .../admin/nomenclature_changes_helper.rb | 20 ++++---- app/helpers/admin_helper.rb | 2 +- app/helpers/taxon_concept_helper.rb | 2 +- app/models/change_type.rb | 4 +- app/models/checklist/checklist.rb | 2 +- app/models/checklist/index.rb | 2 +- app/models/common_name.rb | 2 +- app/models/designation.rb | 2 +- app/models/distribution_reference.rb | 2 +- app/models/document.rb | 2 +- app/models/document_collection_order.rb | 2 +- app/models/geo_entity.rb | 4 +- app/models/instrument.rb | 2 +- app/models/language.rb | 4 +- app/models/listing_change.rb | 4 +- app/models/m_taxon_concept.rb | 8 +-- .../nomenclature_change/full_reassignment.rb | 2 +- .../reassignment_processor.rb | 4 +- .../status_change_helpers.rb | 4 +- .../trade_shipments_resolver.rb | 2 +- app/models/purpose.rb | 2 +- app/models/source.rb | 2 +- app/models/species/csv_copy_export.rb | 2 +- app/models/species/search.rb | 2 +- app/models/species_listing.rb | 4 +- app/models/taxon_concept.rb | 8 +-- app/models/taxonomy.rb | 2 +- app/models/term.rb | 2 +- app/models/term_trade_codes_pair.rb | 2 +- app/models/trade/sandbox_template.rb | 2 +- app/models/trade/shipments_comptab_export.rb | 6 +-- app/models/trade/shipments_export.rb | 36 ++++++------- app/models/trade/shipments_export_factory.rb | 2 +- .../trade/shipments_gross_exports_export.rb | 22 ++++---- app/models/trade_code.rb | 2 +- app/models/trade_restriction.rb | 2 +- app/models/unit.rb | 2 +- .../species/cites_suspension_serializer.rb | 2 +- .../species/document_serializer.rb | 2 +- .../species/eu_decision_serializer.rb | 4 +- app/serializers/species/quota_serializer.rb | 2 +- lib/modules/dashboard_stats_cache.rb | 4 +- lib/modules/sapi/summary.rb | 24 ++++----- lib/modules/statistics.rb | 4 +- lib/tasks/elibrary/importable.rb | 2 +- lib/tasks/import_cites_listings.rake | 18 +++---- lib/tasks/import_cites_regions.rake | 4 +- lib/tasks/import_cms_listings.rake | 18 +++---- lib/tasks/import_countries.rake | 8 +-- lib/tasks/import_eu_listings.rake | 16 +++--- lib/tasks/import_trade_permits.rake | 8 +-- lib/tasks/import_trade_shipments.rake | 4 +- .../admin/documents_controller_spec.rb | 8 +-- .../admin/exports_controller_spec.rb | 16 +++--- .../lump_controller_spec.rb | 6 +-- .../split_controller_spec.rb | 4 +- .../controllers/admin/tags_controller_spec.rb | 2 +- .../admin/taxon_commons_controller_spec.rb | 2 +- .../taxon_concept_comments_controller_spec.rb | 2 +- ...axon_concept_references_controller_spec.rb | 6 +-- .../admin/taxon_concepts_controller_spec.rb | 14 +++--- .../taxon_listing_changes_controller_spec.rb | 2 +- .../cites_trade/exports_controller_spec.rb | 6 +-- .../species/exports_controller_spec.rb | 4 +- .../trade/exports_controller_spec.rb | 4 +- .../sandbox_shipments_controller_spec.rb | 6 +-- spec/integration/login_spec.rb | 8 +-- spec/models/api_request_spec.rb | 4 +- spec/models/checklist/checklist_spec.rb | 4 +- .../checklist/higher_taxa_injector_spec.rb | 12 ++--- spec/models/checklist/order_spec.rb | 6 +-- spec/models/dashboard_stats_species_spec.rb | 4 +- spec/models/designation_spec.rb | 4 +- spec/models/geo_entity_search_spec.rb | 14 +++--- spec/models/nomenclature_change/lump_spec.rb | 2 +- .../shared/split_definitions.rb | 6 +-- spec/models/nomenclature_change/split_spec.rb | 2 +- .../invisible_subspecies_search_spec.rb | 2 +- spec/models/species/search_spec.rb | 8 +-- .../species/visible_subspecies_search_spec.rb | 2 +- .../taxon_concept_prefix_matcher_spec.rb | 24 ++++----- spec/models/taxonomy_spec.rb | 4 +- spec/models/trade/filter_spec.rb | 50 +++++++++---------- spec/models/trade/permit_matcher_spec.rb | 10 ++-- spec/models/trade/sandbox_template_spec.rb | 2 +- spec/models/trade_restriction_spec.rb | 8 +-- spec/shared/uroplatus.rb | 2 +- spec/spec_helper.rb | 4 +- spec/support/sapi_helpers.rb | 16 +++--- spec/workers/quotas_copy_worker_spec.rb | 2 +- 129 files changed, 359 insertions(+), 360 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 9b24992118..47a5276e11 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -71,3 +71,9 @@ Style/FirstParameterIndentation: Style/IndentationWidth: Exclude: - 'db/migrate/*' + +# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SupportedStyles. +# SupportedStyles: space, no_space +Style/SpaceInsideHashLiteralBraces: + EnforcedStyle: space + EnforcedStyleForEmptyBraces: no_space diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index c7102d4a85..b512db593f 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -618,13 +618,6 @@ Style/SpaceAroundOperators: Style/SpaceBeforeBlockBraces: Enabled: false -# Offense count: 697 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SupportedStyles. -# SupportedStyles: space, no_space -Style/SpaceInsideHashLiteralBraces: - Enabled: false - # Offense count: 33 # Cop supports --auto-correct. Style/SpaceInsideParens: diff --git a/app/controllers/admin/cites_suspensions_controller.rb b/app/controllers/admin/cites_suspensions_controller.rb index 3d7791f177..da0e7af9be 100644 --- a/app/controllers/admin/cites_suspensions_controller.rb +++ b/app/controllers/admin/cites_suspensions_controller.rb @@ -39,7 +39,7 @@ def load_lib_objects @purposes = Purpose.order(:code) @geo_entities = GeoEntity.order(:name_en).joins(:geo_entity_type). where(:is_current => true, - :geo_entity_types => {:name => GeoEntityType::SETS[GeoEntityType::DEFAULT_SET]}) + :geo_entity_types => { :name => GeoEntityType::SETS[GeoEntityType::DEFAULT_SET] }) @suspension_notifications = CitesSuspensionNotification. select([:id, :name]). order('effective_at DESC') diff --git a/app/controllers/admin/cms_mappings_controller.rb b/app/controllers/admin/cms_mappings_controller.rb index 37a1e27374..4eac7c0187 100644 --- a/app/controllers/admin/cms_mappings_controller.rb +++ b/app/controllers/admin/cms_mappings_controller.rb @@ -3,7 +3,7 @@ class Admin::CmsMappingsController < Admin::SimpleCrudController def index @totals = { :species_plus => TaxonConcept.joins(:taxonomy). - where(:taxonomies => {:name => Taxonomy::CMS}). + where(:taxonomies => { :name => Taxonomy::CMS }). where(:name_status => 'A').count, :cms_mapped => CmsMapping.all.count, :matches => CmsMapping.filter('MATCHES').count, diff --git a/app/controllers/admin/designations_controller.rb b/app/controllers/admin/designations_controller.rb index 327d13dd87..3eaaf387a5 100644 --- a/app/controllers/admin/designations_controller.rb +++ b/app/controllers/admin/designations_controller.rb @@ -7,7 +7,7 @@ def index index! do |format| format.json { render :text => end_of_association_chain.order(:name). - select([:id, :name]).map{ |d| {:value => d.id, :text => d.name} }.to_json + select([:id, :name]).map{ |d| { :value => d.id, :text => d.name } }.to_json } end end diff --git a/app/controllers/admin/distributions_controller.rb b/app/controllers/admin/distributions_controller.rb index 0f5fc269e6..20b3930bde 100644 --- a/app/controllers/admin/distributions_controller.rb +++ b/app/controllers/admin/distributions_controller.rb @@ -64,7 +64,7 @@ def destroy def load_tags_and_geo_entities @geo_entities = GeoEntity.order(:name_en).joins(:geo_entity_type). where(:is_current => true, - :geo_entity_types => {:name => GeoEntityType::SETS[GeoEntityType::DEFAULT_SET]}) + :geo_entity_types => { :name => GeoEntityType::SETS[GeoEntityType::DEFAULT_SET] }) @tags = PresetTag.where(:model => PresetTag::TYPES[:Distribution]) end diff --git a/app/controllers/admin/documents_controller.rb b/app/controllers/admin/documents_controller.rb index 1378ec379c..bbb85b30a8 100644 --- a/app/controllers/admin/documents_controller.rb +++ b/app/controllers/admin/documents_controller.rb @@ -87,7 +87,7 @@ def load_associations @designations = Designation.where(name: ['CITES', 'EU']).select([:id, :name]).order(:name) @event_types = if @document && @document.event - [{id: @document.event.type}] + [{ id: @document.event.type }] else Event.event_types_with_names end diff --git a/app/controllers/admin/eu_opinions_controller.rb b/app/controllers/admin/eu_opinions_controller.rb index a213b3737a..1d88873d39 100644 --- a/app/controllers/admin/eu_opinions_controller.rb +++ b/app/controllers/admin/eu_opinions_controller.rb @@ -38,7 +38,7 @@ def load_lib_objects @terms = Term.order(:code) @sources = Source.order(:code) @geo_entities = GeoEntity.order(:name_en).joins(:geo_entity_type). - where(:geo_entity_types => {:name => GeoEntityType::SETS[GeoEntityType::DEFAULT_SET]}) + where(:geo_entity_types => { :name => GeoEntityType::SETS[GeoEntityType::DEFAULT_SET] }) @eu_decision_types = EuDecisionType.opinions @ec_srgs = Event.where("type = 'EcSrg' OR type = 'EuRegulation' AND name IN ('No 338/97', 'No 938/97', 'No 750/2013')" diff --git a/app/controllers/admin/events_controller.rb b/app/controllers/admin/events_controller.rb index f1367304a0..c7e442ff71 100644 --- a/app/controllers/admin/events_controller.rb +++ b/app/controllers/admin/events_controller.rb @@ -7,7 +7,7 @@ def index index! do |format| format.json { render :text => end_of_association_chain.order(:effective_at, :name). - select([:id, :name]).map{ |d| {:value => d.id, :text => d.name} }.to_json + select([:id, :name]).map{ |d| { :value => d.id, :text => d.name } }.to_json } end end diff --git a/app/controllers/admin/geo_entities_controller.rb b/app/controllers/admin/geo_entities_controller.rb index a9532c2b21..9d38052faf 100644 --- a/app/controllers/admin/geo_entities_controller.rb +++ b/app/controllers/admin/geo_entities_controller.rb @@ -16,7 +16,7 @@ def load_geo_entity_types ) @geo_entity_types = GeoEntityType.order(:name) @geo_entity_types_for_dropdown = @geo_entity_types.map do |t| - {:value => t.id, :text => t.name} + { :value => t.id, :text => t.name } end end diff --git a/app/controllers/admin/geo_relationships_controller.rb b/app/controllers/admin/geo_relationships_controller.rb index e36650cc35..750a72bf31 100644 --- a/app/controllers/admin/geo_relationships_controller.rb +++ b/app/controllers/admin/geo_relationships_controller.rb @@ -18,14 +18,14 @@ def load_geo_relationship_types ) @geo_relationship_types = GeoRelationshipType.order(:name) @geo_relationship_types_for_dropdown = @geo_relationship_types.map do |t| - {:value => t.id, :text => t.name} + { :value => t.id, :text => t.name } end end def load_geo_entities @geo_entities = GeoEntity.order(:geo_entity_type_id, :name_en) @geo_entities_for_dropdown = @geo_entities.map do |t| - {:value => t.id, :text => t.name} + { :value => t.id, :text => t.name } end end diff --git a/app/controllers/admin/instruments_controller.rb b/app/controllers/admin/instruments_controller.rb index a69b0a9188..5cda7408f7 100644 --- a/app/controllers/admin/instruments_controller.rb +++ b/app/controllers/admin/instruments_controller.rb @@ -6,7 +6,7 @@ def index index! do |format| format.json { render :text => end_of_association_chain.order(:name). - select([:id, :name]).map{ |d| {:value => d.id, :text => d.name} }.to_json + select([:id, :name]).map{ |d| { :value => d.id, :text => d.name } }.to_json } end end diff --git a/app/controllers/admin/quotas_controller.rb b/app/controllers/admin/quotas_controller.rb index cbb2eea702..adf6c7cdac 100644 --- a/app/controllers/admin/quotas_controller.rb +++ b/app/controllers/admin/quotas_controller.rb @@ -18,7 +18,7 @@ def duplication def duplicate quota_params = params[:quotas].merge(:current_user_id => current_user.id) QuotasCopyWorker.perform_async(quota_params) - redirect_to admin_quotas_path({:year => params[:quotas][:start_date].split("/")[2]}), + redirect_to admin_quotas_path({ :year => params[:quotas][:start_date].split("/")[2] }), :notice => "Your quotas are being duplicated in the background. They will be available from this page in a few seconds (please refresh it)" end diff --git a/app/controllers/admin/references_controller.rb b/app/controllers/admin/references_controller.rb index 69a6c2b7b2..16c990a558 100644 --- a/app/controllers/admin/references_controller.rb +++ b/app/controllers/admin/references_controller.rb @@ -5,7 +5,7 @@ def index index! do |format| format.json { render :text => end_of_association_chain.order(:citation). - select([:id, :citation]).map{ |d| {:value => d.id, :text => d.citation} }.to_json + select([:id, :citation]).map{ |d| { :value => d.id, :text => d.citation } }.to_json } end end diff --git a/app/controllers/admin/taxon_cites_suspensions_controller.rb b/app/controllers/admin/taxon_cites_suspensions_controller.rb index 83622c5e89..ff38b97473 100644 --- a/app/controllers/admin/taxon_cites_suspensions_controller.rb +++ b/app/controllers/admin/taxon_cites_suspensions_controller.rb @@ -51,7 +51,7 @@ def load_lib_objects @purposes = Purpose.order(:code) @geo_entities = GeoEntity.order(:name_en).joins(:geo_entity_type). where(:is_current => true, - :geo_entity_types => {:name => GeoEntityType::SETS[GeoEntityType::DEFAULT_SET]}) + :geo_entity_types => { :name => GeoEntityType::SETS[GeoEntityType::DEFAULT_SET] }) @suspension_notifications = CitesSuspensionNotification. select([:id, :name]). order('effective_at DESC') diff --git a/app/controllers/admin/taxon_concept_term_pairs_controller.rb b/app/controllers/admin/taxon_concept_term_pairs_controller.rb index bb77871e76..03d2642717 100644 --- a/app/controllers/admin/taxon_concept_term_pairs_controller.rb +++ b/app/controllers/admin/taxon_concept_term_pairs_controller.rb @@ -10,7 +10,7 @@ class Admin::TaxonConceptTermPairsController < Admin::SimpleCrudController def load_term_codes @term_codes_obj = Term.select([:id, :code]). - map { |c| {"id" => c.id, "code" => c.code} }.to_json + map { |c| { "id" => c.id, "code" => c.code } }.to_json end def collection diff --git a/app/controllers/admin/taxon_eu_suspensions_controller.rb b/app/controllers/admin/taxon_eu_suspensions_controller.rb index 53e4806766..2d61c9aa2d 100644 --- a/app/controllers/admin/taxon_eu_suspensions_controller.rb +++ b/app/controllers/admin/taxon_eu_suspensions_controller.rb @@ -63,7 +63,7 @@ def load_lib_objects @terms = Term.order(:code) @sources = Source.order(:code) @geo_entities = GeoEntity.order(:name_en).joins(:geo_entity_type). - where(:geo_entity_types => {:name => GeoEntityType::SETS[GeoEntityType::DEFAULT_SET]}) + where(:geo_entity_types => { :name => GeoEntityType::SETS[GeoEntityType::DEFAULT_SET] }) @eu_regulations = EuSuspensionRegulation.order("effective_at DESC") @eu_decision_types = EuDecisionType.suspensions end diff --git a/app/controllers/admin/taxon_instruments_controller.rb b/app/controllers/admin/taxon_instruments_controller.rb index be97f0e4e3..8313c0e7df 100644 --- a/app/controllers/admin/taxon_instruments_controller.rb +++ b/app/controllers/admin/taxon_instruments_controller.rb @@ -54,7 +54,7 @@ def destroy def load_instruments @taxon_instrument = TaxonInstrument.new(:taxon_concept_id => @taxon_concept.id) @instruments = Instrument.joins(:designation => :taxonomy). - where(:taxonomies => {:id => @taxon_concept.taxonomy_id}). + where(:taxonomies => { :id => @taxon_concept.taxonomy_id }). order(:name) end diff --git a/app/controllers/admin/taxon_listing_changes_controller.rb b/app/controllers/admin/taxon_listing_changes_controller.rb index 629fe5b638..a8b9dcf0d1 100644 --- a/app/controllers/admin/taxon_listing_changes_controller.rb +++ b/app/controllers/admin/taxon_listing_changes_controller.rb @@ -95,7 +95,7 @@ def load_change_types find_by_name(ChangeType::EXCEPTION) @species_listings = @designation.species_listings.order(:abbreviation) @geo_entities = GeoEntity.order(:name_en).joins(:geo_entity_type). - where(:is_current => true, :geo_entity_types => {:name => 'COUNTRY'}) + where(:is_current => true, :geo_entity_types => { :name => 'COUNTRY' }) @hash_annotations = if @designation.is_eu? Annotation.for_eu diff --git a/app/controllers/admin/taxon_quotas_controller.rb b/app/controllers/admin/taxon_quotas_controller.rb index 478fbbb110..bac429999b 100644 --- a/app/controllers/admin/taxon_quotas_controller.rb +++ b/app/controllers/admin/taxon_quotas_controller.rb @@ -56,7 +56,7 @@ def load_lib_objects @purposes = Purpose.order(:code) @geo_entities = GeoEntity.order(:name_en).joins(:geo_entity_type). where(:is_current => true, - :geo_entity_types => {:name => GeoEntityType::SETS[GeoEntityType::DEFAULT_SET]}) + :geo_entity_types => { :name => GeoEntityType::SETS[GeoEntityType::DEFAULT_SET] }) end def collection diff --git a/app/controllers/admin/taxonomies_controller.rb b/app/controllers/admin/taxonomies_controller.rb index 74cfc4bf34..dbd827788f 100644 --- a/app/controllers/admin/taxonomies_controller.rb +++ b/app/controllers/admin/taxonomies_controller.rb @@ -5,7 +5,7 @@ def index index! do |format| format.json { render :text =>end_of_association_chain.order(:name). - select([:id, :name]).map{ |d| {:value => d.id, :text => d.name} }.to_json + select([:id, :name]).map{ |d| { :value => d.id, :text => d.name } }.to_json } end end diff --git a/app/controllers/admin/term_trade_codes_pairs_controller.rb b/app/controllers/admin/term_trade_codes_pairs_controller.rb index ddace3d3f7..a4de66fd5b 100644 --- a/app/controllers/admin/term_trade_codes_pairs_controller.rb +++ b/app/controllers/admin/term_trade_codes_pairs_controller.rb @@ -32,7 +32,7 @@ def custom_title def load_term_codes @term_codes_obj = Term.select([:id, :code]). - map { |c| {"id" => c.id, "code" => c.code} }.to_json + map { |c| { "id" => c.id, "code" => c.code } }.to_json end def load_trade_code_types @@ -41,7 +41,7 @@ def load_trade_code_types 'Unit' @trade_code_codes = TradeCode.where(:type => @trade_code_type). select([:id, :code]).order('code') - @trade_code_codes_obj = @trade_code_codes.map { |c| {"value" => c.id, "text" => c.code} }.to_json + @trade_code_codes_obj = @trade_code_codes.map { |c| { "value" => c.id, "text" => c.code } }.to_json end def collection diff --git a/app/controllers/api/geo_relationships_controller.rb b/app/controllers/api/geo_relationships_controller.rb index daa6ecaabc..3ce2be7f48 100644 --- a/app/controllers/api/geo_relationships_controller.rb +++ b/app/controllers/api/geo_relationships_controller.rb @@ -7,6 +7,6 @@ class Api::GeoRelationshipsController < ApplicationController def collection @geo_relationship_types ||= end_of_association_chain.order(:name). select([:id, :name]). - map{ |d| {:value => d.id, :text => d.name} } + map{ |d| { :value => d.id, :text => d.name } } end end \ No newline at end of file diff --git a/app/controllers/api/ranks_controller.rb b/app/controllers/api/ranks_controller.rb index 9dbe4ad5b9..f299483faf 100644 --- a/app/controllers/api/ranks_controller.rb +++ b/app/controllers/api/ranks_controller.rb @@ -7,6 +7,6 @@ class Api::RanksController < ApplicationController def collection @ranks ||= end_of_association_chain. select([:id, :name]). - map{ |d| {:value => d.id, :text => d.name} } + map{ |d| { :value => d.id, :text => d.name } } end end diff --git a/app/controllers/api/v1/document_geo_entities_controller.rb b/app/controllers/api/v1/document_geo_entities_controller.rb index ae693a7f36..04ed30c27f 100644 --- a/app/controllers/api/v1/document_geo_entities_controller.rb +++ b/app/controllers/api/v1/document_geo_entities_controller.rb @@ -24,7 +24,7 @@ def index render :json => @geo_entities, each_serializer: Species::GeoEntitySerializer, - meta: {total: @geo_entities.count} + meta: { total: @geo_entities.count } end private diff --git a/app/controllers/api/v1/document_tags_controller.rb b/app/controllers/api/v1/document_tags_controller.rb index 8582067ba8..b408186a0a 100644 --- a/app/controllers/api/v1/document_tags_controller.rb +++ b/app/controllers/api/v1/document_tags_controller.rb @@ -7,7 +7,7 @@ def index order([:type, :name]) render :json => @document_tags, :each_serializer => Species::DocumentTagSerializer, - :meta => {:total => @document_tags.count} + :meta => { :total => @document_tags.count } end end diff --git a/app/controllers/api/v1/events_controller.rb b/app/controllers/api/v1/events_controller.rb index 54f08b7325..d3500217b9 100644 --- a/app/controllers/api/v1/events_controller.rb +++ b/app/controllers/api/v1/events_controller.rb @@ -7,7 +7,7 @@ def index order('type, published_at DESC') render :json => @events, :each_serializer => Species::EventSerializer, - :meta => {:total => @events.count} + :meta => { :total => @events.count } end end diff --git a/app/controllers/api/v1/geo_entities_controller.rb b/app/controllers/api/v1/geo_entities_controller.rb index adbfa37495..4da3cdb069 100644 --- a/app/controllers/api/v1/geo_entities_controller.rb +++ b/app/controllers/api/v1/geo_entities_controller.rb @@ -6,7 +6,7 @@ def index ).cached_results render :json => @geo_entities, :each_serializer => Species::GeoEntitySerializer, - :meta => {:total => @geo_entities.count} + :meta => { :total => @geo_entities.count } end end diff --git a/app/controllers/api/v1/purposes_controller.rb b/app/controllers/api/v1/purposes_controller.rb index 2db9bb1408..76f257bea8 100644 --- a/app/controllers/api/v1/purposes_controller.rb +++ b/app/controllers/api/v1/purposes_controller.rb @@ -1,11 +1,11 @@ class Api::V1::PurposesController < ApplicationController caches_action :index, :cache_path => Proc.new { |c| - {:locale => "en"}.merge(c.params.select{ |k, v| !v.blank? && "locale" == k }) + { :locale => "en" }.merge(c.params.select{ |k, v| !v.blank? && "locale" == k }) } def index @purposes = Purpose.all(:order => "code") render :json => @purposes, :each_serializer => Species::PurposeSerializer, - :meta => {:total => @purposes.count} + :meta => { :total => @purposes.count } end end diff --git a/app/controllers/api/v1/sources_controller.rb b/app/controllers/api/v1/sources_controller.rb index 33b16488e9..c0b5cbf392 100644 --- a/app/controllers/api/v1/sources_controller.rb +++ b/app/controllers/api/v1/sources_controller.rb @@ -1,11 +1,11 @@ class Api::V1::SourcesController < ApplicationController caches_action :index, :cache_path => Proc.new { |c| - {:locale => "en"}.merge(c.params.select{ |k, v| !v.blank? && "locale" == k }) + { :locale => "en" }.merge(c.params.select{ |k, v| !v.blank? && "locale" == k }) } def index @sources = Source.all(:order => "code") render :json => @sources, :each_serializer => Species::SourceSerializer, - :meta => {:total => @sources.count} + :meta => { :total => @sources.count } end end diff --git a/app/controllers/api/v1/taxon_concepts_controller.rb b/app/controllers/api/v1/taxon_concepts_controller.rb index a7fcc4aa17..aee1538473 100644 --- a/app/controllers/api/v1/taxon_concepts_controller.rb +++ b/app/controllers/api/v1/taxon_concepts_controller.rb @@ -41,6 +41,6 @@ def track_index end def track_show - ahoy.track "Taxon Concept", {:id => @taxon_concept.id, :full_name => @taxon_concept.full_name, :taxonomy_name => @taxon_concept.taxonomy.name, :rank_name => @taxon_concept.rank_name, :family_name => @taxon_concept.data['family_name']} + ahoy.track "Taxon Concept", { :id => @taxon_concept.id, :full_name => @taxon_concept.full_name, :taxonomy_name => @taxon_concept.taxonomy.name, :rank_name => @taxon_concept.rank_name, :family_name => @taxon_concept.data['family_name'] } end end diff --git a/app/controllers/api/v1/terms_controller.rb b/app/controllers/api/v1/terms_controller.rb index 8160804593..719866ca5a 100644 --- a/app/controllers/api/v1/terms_controller.rb +++ b/app/controllers/api/v1/terms_controller.rb @@ -1,11 +1,11 @@ class Api::V1::TermsController < ApplicationController caches_action :index, :cache_path => Proc.new { |c| - {:locale => "en"}.merge(c.params.select{ |k, v| !v.blank? && "locale" == k }) + { :locale => "en" }.merge(c.params.select{ |k, v| !v.blank? && "locale" == k }) } def index @terms = Term.all(:order => "code") render :json => @terms, :each_serializer => Species::TermSerializer, - :meta => {:total => @terms.count} + :meta => { :total => @terms.count } end end diff --git a/app/controllers/api/v1/units_controller.rb b/app/controllers/api/v1/units_controller.rb index f8edd6b896..1bb48692d1 100644 --- a/app/controllers/api/v1/units_controller.rb +++ b/app/controllers/api/v1/units_controller.rb @@ -1,11 +1,11 @@ class Api::V1::UnitsController < ApplicationController caches_action :index, :cache_path => Proc.new { |c| - {:locale => "en"}.merge(c.params.select{ |k, v| !v.blank? && "locale" == k }) + { :locale => "en" }.merge(c.params.select{ |k, v| !v.blank? && "locale" == k }) } def index @units = Unit.all(:order => "code") render :json => @units, :each_serializer => Species::UnitSerializer, - :meta => {:total => @units.count} + :meta => { :total => @units.count } end end diff --git a/app/controllers/checklist/downloads_controller.rb b/app/controllers/checklist/downloads_controller.rb index afe58631cb..57bb479edf 100644 --- a/app/controllers/checklist/downloads_controller.rb +++ b/app/controllers/checklist/downloads_controller.rb @@ -30,7 +30,7 @@ def create def show @download = Download.find(params[:id]) - render :text => {status: @download.status}.to_json + render :text => { status: @download.status }.to_json end # GET downloads/:id/download @@ -48,7 +48,7 @@ def download :filename => @download.filename, :type => @download.format) else - render :text => {error: "Download not processed"}.to_json + render :text => { error: "Download not processed" }.to_json end end @@ -85,7 +85,7 @@ def send_download end def not_found - render :text => {error: "No downloads available"}.to_json + render :text => { error: "No downloads available" }.to_json end end diff --git a/app/controllers/cites_trade_controller.rb b/app/controllers/cites_trade_controller.rb index 57e5c36edc..202f1bea4c 100644 --- a/app/controllers/cites_trade_controller.rb +++ b/app/controllers/cites_trade_controller.rb @@ -4,15 +4,15 @@ class CitesTradeController < ApplicationController def search_params (params[:filters] || params).permit( - {:taxon_concepts_ids => []}, - {:appendices => []}, - {:terms_ids => []}, - {:units_ids => []}, - {:purposes_ids => []}, - {:sources_ids => []}, - {:importers_ids => []}, - {:exporters_ids => []}, - {:countries_of_origin_ids => []}, + { :taxon_concepts_ids => [] }, + { :appendices => [] }, + { :terms_ids => [] }, + { :units_ids => [] }, + { :purposes_ids => [] }, + { :sources_ids => [] }, + { :importers_ids => [] }, + { :exporters_ids => [] }, + { :countries_of_origin_ids => [] }, :time_range_start, :time_range_end, :report_type, diff --git a/app/controllers/species/exports_controller.rb b/app/controllers/species/exports_controller.rb index 02137a4a9d..cc83073f9b 100644 --- a/app/controllers/species/exports_controller.rb +++ b/app/controllers/species/exports_controller.rb @@ -30,7 +30,7 @@ def download end } format.json { - render :json => {:total => result.is_a?(Array) ? 1 : 0} + render :json => { :total => result.is_a?(Array) ? 1 : 0 } } end end diff --git a/app/controllers/trade/annual_report_uploads_controller.rb b/app/controllers/trade/annual_report_uploads_controller.rb index b4c0917189..db31b925cc 100644 --- a/app/controllers/trade/annual_report_uploads_controller.rb +++ b/app/controllers/trade/annual_report_uploads_controller.rb @@ -21,7 +21,7 @@ def create @annual_report_upload = Trade::AnnualReportUpload.create( annual_report_upload_params ) - render :json => {:files => [@annual_report_upload.to_jq_upload]} + render :json => { :files => [@annual_report_upload.to_jq_upload] } end def submit diff --git a/app/controllers/trade/shipments_controller.rb b/app/controllers/trade/shipments_controller.rb index 074cb80e78..2aa8d485fd 100644 --- a/app/controllers/trade/shipments_controller.rb +++ b/app/controllers/trade/shipments_controller.rb @@ -32,7 +32,7 @@ def update_batch affected_rows = @batch_update.execute( populate_accepted_taxon_concept(batch_update_params) ) - render :json => {rows: affected_rows}, :status => :ok + render :json => { rows: affected_rows }, :status => :ok end def destroy @@ -49,7 +49,7 @@ def destroy_batch end.flatten.uniq @search.query.destroy_all PermitCleanupWorker.perform_async(disconnected_permits_ids) - render :json => {rows: cnt}, :status => :ok + render :json => { rows: cnt }, :status => :ok end def accepted_taxa_for_reported_taxon_concept diff --git a/app/controllers/trade_controller.rb b/app/controllers/trade_controller.rb index b0cf5fea85..3e93682203 100644 --- a/app/controllers/trade_controller.rb +++ b/app/controllers/trade_controller.rb @@ -13,17 +13,17 @@ def verify_manager def search_params (params[:filters] || params).permit( - {:taxon_concepts_ids => []}, - {:reported_taxon_concepts_ids => []}, - {:appendices => []}, - {:terms_ids => []}, - {:units_ids => []}, - {:purposes_ids => []}, - {:sources_ids => []}, - {:importers_ids => []}, - {:exporters_ids => []}, - {:countries_of_origin_ids => []}, - {:permits_ids => []}, + { :taxon_concepts_ids => [] }, + { :reported_taxon_concepts_ids => [] }, + { :appendices => [] }, + { :terms_ids => [] }, + { :units_ids => [] }, + { :purposes_ids => [] }, + { :sources_ids => [] }, + { :importers_ids => [] }, + { :exporters_ids => [] }, + { :countries_of_origin_ids => [] }, + { :permits_ids => [] }, :reporter_type, :time_range_start, :time_range_end, diff --git a/app/helpers/admin/nomenclature_changes_helper.rb b/app/helpers/admin/nomenclature_changes_helper.rb index 12ffd0e014..cd228b35f0 100644 --- a/app/helpers/admin/nomenclature_changes_helper.rb +++ b/app/helpers/admin/nomenclature_changes_helper.rb @@ -2,7 +2,7 @@ module Admin::NomenclatureChangesHelper def nomenclature_change_form(submit_label = 'Next', &block) nested_form_for @nomenclature_change, url: wizard_path, method: :put, - html: {class: 'form-horizontal'} do |f| + html: { class: 'form-horizontal' } do |f| html = error_messages_for(@nomenclature_change) html += capture { block.yield(f) } if block_given? html += nomenclature_change_form_buttons(f, submit_label) @@ -133,7 +133,7 @@ def global_selection(checked = true) "Select a taxon below to populate all fields with that taxon.") @nomenclature_change.outputs.map do |output| html += content_tag(:div, class: 'species-checkbox') do - tag("input", {type: "checkbox", class: 'select-partial-checkbox', checked: checked}) + + tag("input", { type: "checkbox", class: 'select-partial-checkbox', checked: checked }) + content_tag(:span, output.display_full_name, class: 'species-name') end end @@ -159,7 +159,7 @@ def outputs_selection(ff) ff.radio_button( :output_type, opt_val, - {class: 'output-radio'} + { class: 'output-radio' } ) + ' ' + opt ) end @@ -220,10 +220,10 @@ def lump_inputs_content tc = input.taxon_concept if idx == 0 concat content_tag(:div, inner_content(input, tc), - {id: "#{tc.full_name.downcase.tr(" ", "_")}", class: "tab-pane fade in active"}) + { id: "#{tc.full_name.downcase.tr(" ", "_")}", class: "tab-pane fade in active" }) else concat content_tag(:div, inner_content(input, tc), - {id: "#{tc.full_name.downcase.tr(" ", "_")}", class: "tab-pane fade"}) + { id: "#{tc.full_name.downcase.tr(" ", "_")}", class: "tab-pane fade" }) end end end @@ -242,7 +242,7 @@ def lump_output_content tc = @nc.output.new_taxon_concept || @nc.output.taxon_concept content_tag(:div, class: 'tab-content') do content_tag(:div, inner_content(@nc.output, tc), - {id: "output_#{tc.full_name.downcase.tr(" ", "_")}", class: 'tab-pane fade in active'}) + { id: "output_#{tc.full_name.downcase.tr(" ", "_")}", class: 'tab-pane fade in active' }) end end @@ -268,8 +268,8 @@ def split_input_tag def split_input_content content_tag(:div, class: 'tab-content') do content_tag(:div, inner_content(@nc.input, @nc.input.taxon_concept), - {id: "input_#{@nc.input.taxon_concept.full_name.downcase.tr(" ", "_")}", - class: 'tab-pane fade in active'}) + { id: "input_#{@nc.input.taxon_concept.full_name.downcase.tr(" ", "_")}", + class: 'tab-pane fade in active' }) end end @@ -290,10 +290,10 @@ def outputs_content tc = output.new_taxon_concept || output.taxon_concept if idx == 0 concat content_tag(:div, inner_content(output, tc), - {id: "#{tc.full_name.downcase.tr(" ", "_")}", class: "tab-pane fade in active"}) + { id: "#{tc.full_name.downcase.tr(" ", "_")}", class: "tab-pane fade in active" }) else concat content_tag(:div, inner_content(output, tc), - {id: "#{tc.full_name.downcase.tr(" ", "_")}", class: "tab-pane fade"}) + { id: "#{tc.full_name.downcase.tr(" ", "_")}", class: "tab-pane fade" }) end end end diff --git a/app/helpers/admin_helper.rb b/app/helpers/admin_helper.rb index bfb05d421e..2370f977cb 100644 --- a/app/helpers/admin_helper.rb +++ b/app/helpers/admin_helper.rb @@ -180,7 +180,7 @@ def admin_table if block_given? yield else - render :partial => 'list', :locals => {:collection => collection} + render :partial => 'list', :locals => { :collection => collection } end end end diff --git a/app/helpers/taxon_concept_helper.rb b/app/helpers/taxon_concept_helper.rb index f8a3b38d46..2280ade85e 100644 --- a/app/helpers/taxon_concept_helper.rb +++ b/app/helpers/taxon_concept_helper.rb @@ -262,7 +262,7 @@ def taxon_concept_internal_note_display(comment) def taxon_concept_internal_note_tab_display(comment) if comment && comment.note.present? - content_tag(:div, {class: 'alert alert-info'}) do + content_tag(:div, { class: 'alert alert-info' }) do taxon_concept_internal_note_display(comment) end end diff --git a/app/models/change_type.rb b/app/models/change_type.rb index f8fc1e85b3..79164133a4 100644 --- a/app/models/change_type.rb +++ b/app/models/change_type.rb @@ -23,8 +23,8 @@ class ChangeType < ActiveRecord::Base belongs_to :designation has_many :listing_changes - validates :name, :presence => true, :uniqueness => {:scope => :designation_id} - validates :display_name_en, :presence => true, :uniqueness => {:scope => :designation_id} + validates :name, :presence => true, :uniqueness => { :scope => :designation_id } + validates :display_name_en, :presence => true, :uniqueness => { :scope => :designation_id } def abbreviation self.name.split('_'). diff --git a/app/models/checklist/checklist.rb b/app/models/checklist/checklist.rb index 90216d93f0..28c1830bd0 100644 --- a/app/models/checklist/checklist.rb +++ b/app/models/checklist/checklist.rb @@ -46,7 +46,7 @@ def initialize_query @taxon_concepts_rel = @taxon_concepts_rel. by_name( @scientific_name, - {:synonyms => true, :common_names => true, :subspecies => false} + { :synonyms => true, :common_names => true, :subspecies => false } ) end diff --git a/app/models/checklist/index.rb b/app/models/checklist/index.rb index c754752777..247022e6b5 100644 --- a/app/models/checklist/index.rb +++ b/app/models/checklist/index.rb @@ -2,7 +2,7 @@ class Checklist::Index < Checklist::Checklist attr_reader :download_name def initialize(options = {}) - params = options.merge({:output_layout => :alphabetical}) + params = options.merge({ :output_layout => :alphabetical }) @download_path = download_location(params, "index", ext) # If a cached download exists, only initialize the params for the # helper methods, otherwise run the generation queries. diff --git a/app/models/common_name.rb b/app/models/common_name.rb index 91f23ee4c4..b0bd66c2a8 100644 --- a/app/models/common_name.rb +++ b/app/models/common_name.rb @@ -17,7 +17,7 @@ class CommonName < ActiveRecord::Base :created_by_id, :updated_by_id belongs_to :language validates :name, :presence => true, - :uniqueness => {:scope => :language_id} + :uniqueness => { :scope => :language_id } def self.english_to_pdf(common_name) words = common_name.split diff --git a/app/models/designation.rb b/app/models/designation.rb index f877809ee7..702ea4dec1 100644 --- a/app/models/designation.rb +++ b/app/models/designation.rb @@ -16,7 +16,7 @@ class Designation < ActiveRecord::Base validates :name, :presence => true, :uniqueness => true validates :name, - :inclusion => {:in => self.dict, :message => 'cannot change protected name'}, + :inclusion => { :in => self.dict, :message => 'cannot change protected name' }, :if => lambda { |t| t.name_changed? && t.class.dict.include?(t.name_was) }, :on => :update validate :taxonomy_cannot_be_changed_if_dependent_objects_present diff --git a/app/models/distribution_reference.rb b/app/models/distribution_reference.rb index 1959ffc8b1..5010c832d0 100644 --- a/app/models/distribution_reference.rb +++ b/app/models/distribution_reference.rb @@ -19,5 +19,5 @@ class DistributionReference < ActiveRecord::Base belongs_to :reference belongs_to :distribution, :touch => true - validates :distribution_id, :uniqueness => {:scope => :reference_id} + validates :distribution_id, :uniqueness => { :scope => :reference_id } end diff --git a/app/models/document.rb b/app/models/document.rb index 749288e2cf..23b058a400 100644 --- a/app/models/document.rb +++ b/app/models/document.rb @@ -28,7 +28,7 @@ class Document < ActiveRecord::Base include PgSearch include PgArrayParser pg_search_scope :search_by_title, :against => :title, - :using => {:tsearch => {:prefix => true}}, + :using => { :tsearch => { :prefix => true } }, :order_within_rank => "documents.date, documents.title, documents.id" track_who_does_it attr_accessible :event_id, :filename, :date, :type, :title, :is_public, diff --git a/app/models/document_collection_order.rb b/app/models/document_collection_order.rb index 63440403d6..0ee1f0ae86 100644 --- a/app/models/document_collection_order.rb +++ b/app/models/document_collection_order.rb @@ -24,7 +24,7 @@ def show def update(id_sort_index_hash) id_sort_index_hash.each do |id, sort_index| Document.update_all( - {sort_index: sort_index, updated_at: DateTime.now}, + { sort_index: sort_index, updated_at: DateTime.now }, ['id = :id OR primary_language_document_id = :id', id: id] ) diff --git a/app/models/geo_entity.rb b/app/models/geo_entity.rb index b2c193c9b7..817ae90ba9 100644 --- a/app/models/geo_entity.rb +++ b/app/models/geo_entity.rb @@ -40,9 +40,9 @@ class GeoEntity < ActiveRecord::Base has_many :users validates :geo_entity_type_id, :presence => true validates :iso_code2, :uniqueness => true, :allow_blank => true - validates :iso_code2, :presence => true, :length => {:is => 2}, + validates :iso_code2, :presence => true, :length => { :is => 2 }, :if => :is_country? - validates :iso_code3, :uniqueness => true, :length => {:is => 3}, + validates :iso_code3, :uniqueness => true, :length => { :is => 3 }, :allow_blank => true, :if => :is_country? # geo entities containing those given by ids diff --git a/app/models/instrument.rb b/app/models/instrument.rb index a709adfe54..9cee6f0747 100644 --- a/app/models/instrument.rb +++ b/app/models/instrument.rb @@ -12,7 +12,7 @@ class Instrument < ActiveRecord::Base attr_accessible :designation_id, :name - validates :name, :presence => true, :uniqueness => { :scope => :designation_id} + validates :name, :presence => true, :uniqueness => { :scope => :designation_id } belongs_to :designation has_many :taxon_instruments diff --git a/app/models/language.rb b/app/models/language.rb index d3d085287a..d901317ccb 100644 --- a/app/models/language.rb +++ b/app/models/language.rb @@ -18,8 +18,8 @@ class Language < ActiveRecord::Base has_many :common_names - validates :iso_code1, :uniqueness => true, :length => {:is => 2}, :allow_blank => true - validates :iso_code3, :presence => true, :uniqueness => true, :length => {:is => 3} + validates :iso_code1, :uniqueness => true, :length => { :is => 2 }, :allow_blank => true + validates :iso_code3, :presence => true, :uniqueness => true, :length => { :is => 3 } def self.search(query) if query.present? diff --git a/app/models/listing_change.rb b/app/models/listing_change.rb index ebb5b6287d..950222cbaf 100644 --- a/app/models/listing_change.rb +++ b/app/models/listing_change.rb @@ -44,9 +44,9 @@ class ListingChange < ActiveRecord::Base belongs_to :species_listing belongs_to :taxon_concept belongs_to :change_type - has_many :listing_distributions, :conditions => {:is_party => false}, :dependent => :destroy + has_many :listing_distributions, :conditions => { :is_party => false }, :dependent => :destroy has_one :party_listing_distribution, :class_name => 'ListingDistribution', - :conditions => {:is_party => true}, :dependent => :destroy + :conditions => { :is_party => true }, :dependent => :destroy has_many :geo_entities, :through => :listing_distributions has_one :party_geo_entity, :class_name => 'GeoEntity', :through => :party_listing_distribution, :source => :geo_entity diff --git a/app/models/m_taxon_concept.rb b/app/models/m_taxon_concept.rb index 75d7a70f1a..0e5e1b7cd0 100644 --- a/app/models/m_taxon_concept.rb +++ b/app/models/m_taxon_concept.rb @@ -113,7 +113,7 @@ class MTaxonConcept < ActiveRecord::Base has_many :cites_listing_changes, :foreign_key => :taxon_concept_id, :class_name => MCitesListingChange has_many :historic_cites_listing_changes_for_downloads, :foreign_key => :taxon_concept_id, :class_name => MCitesListingChange, - :conditions => {:show_in_downloads => true}, + :conditions => { :show_in_downloads => true }, :order => <<-SQL effective_at, CASE @@ -125,11 +125,11 @@ class MTaxonConcept < ActiveRecord::Base SQL has_many :current_cites_additions, :foreign_key => :taxon_concept_id, :class_name => MCitesListingChange, - :conditions => {:is_current => true, :change_type_name => ChangeType::ADDITION}, + :conditions => { :is_current => true, :change_type_name => ChangeType::ADDITION }, :order => 'effective_at DESC, species_listing_name ASC' has_many :current_cms_additions, :foreign_key => :taxon_concept_id, :class_name => MCmsListingChange, - :conditions => {:is_current => true, :change_type_name => ChangeType::ADDITION}, + :conditions => { :is_current => true, :change_type_name => ChangeType::ADDITION }, :order => 'effective_at DESC, species_listing_name ASC' scope :by_cites_eu_taxonomy, where(:taxonomy_is_cites_eu => true) scope :by_cms_taxonomy, where(:taxonomy_is_cites_eu => false) @@ -148,7 +148,7 @@ class MTaxonConcept < ActiveRecord::Base MTaxonConceptFilterByScientificNameWithDescendants.new( self, scientific_name, - {:synonyms => true, :common_names => true, :subspecies => false} + { :synonyms => true, :common_names => true, :subspecies => false } ).relation } diff --git a/app/models/nomenclature_change/full_reassignment.rb b/app/models/nomenclature_change/full_reassignment.rb index f02a917a49..61b922909c 100644 --- a/app/models/nomenclature_change/full_reassignment.rb +++ b/app/models/nomenclature_change/full_reassignment.rb @@ -41,7 +41,7 @@ def process Rails.logger.debug "FULL REASSIGNMENT Shipments" Trade::Shipment.update_all( update_attrs, - {taxon_concept_id: @old_taxon_concept.id} + { taxon_concept_id: @old_taxon_concept.id } ) @old_taxon_concept.update_attributes(dependents_updated_at: update_timestamp) @old_taxon_concept.reload diff --git a/app/models/nomenclature_change/reassignment_processor.rb b/app/models/nomenclature_change/reassignment_processor.rb index 8c205a5d39..56ac384b86 100644 --- a/app/models/nomenclature_change/reassignment_processor.rb +++ b/app/models/nomenclature_change/reassignment_processor.rb @@ -35,8 +35,8 @@ def process_reassignment_of_anonymous_reassignable(reassignment) if reassignment.reassignable_type == 'Trade::Shipment' new_taxon_concept = @output.new_taxon_concept || @output.taxon_concept Trade::Shipment.update_all( - {taxon_concept_id: new_taxon_concept.id}, - {taxon_concept_id: @input.taxon_concept_id} + { taxon_concept_id: new_taxon_concept.id }, + { taxon_concept_id: @input.taxon_concept_id } ) else @input.reassignables_by_class(reassignment.reassignable_type).each do |reassignable| diff --git a/app/models/nomenclature_change/status_change_helpers.rb b/app/models/nomenclature_change/status_change_helpers.rb index fb0f2cd8ff..39277d3182 100644 --- a/app/models/nomenclature_change/status_change_helpers.rb +++ b/app/models/nomenclature_change/status_change_helpers.rb @@ -11,12 +11,12 @@ def self.included(base) has_one :primary_output, :inverse_of => :nomenclature_change, :class_name => NomenclatureChange::Output, :foreign_key => :nomenclature_change_id, - :conditions => {:is_primary_output => true}, + :conditions => { :is_primary_output => true }, :dependent => :destroy, autosave: true has_one :secondary_output, :inverse_of => :nomenclature_change, :class_name => NomenclatureChange::Output, :foreign_key => :nomenclature_change_id, - :conditions => {:is_primary_output => false}, + :conditions => { :is_primary_output => false }, :dependent => :destroy, autosave: true accepts_nested_attributes_for :input, :allow_destroy => true diff --git a/app/models/nomenclature_change/trade_shipments_resolver.rb b/app/models/nomenclature_change/trade_shipments_resolver.rb index 660274da7c..ed210fbef8 100644 --- a/app/models/nomenclature_change/trade_shipments_resolver.rb +++ b/app/models/nomenclature_change/trade_shipments_resolver.rb @@ -8,7 +8,7 @@ def initialize(taxon_relationship, old_taxon_relationship) # update all shipments where reported name now resolves to a new accepted name def process Trade::Shipment.update_all( - {taxon_concept_id: @taxon_relationship.taxon_concept_id}, + { taxon_concept_id: @taxon_relationship.taxon_concept_id }, { taxon_concept_id: @old_taxon_relationship.taxon_concept_id, reported_taxon_concept_id: @taxon_relationship.other_taxon_concept_id diff --git a/app/models/purpose.rb b/app/models/purpose.rb index 04cdeeeeee..bf4aef4b6e 100644 --- a/app/models/purpose.rb +++ b/app/models/purpose.rb @@ -13,7 +13,7 @@ # class Purpose < TradeCode - validates :code, :length => {:is => 1} + validates :code, :length => { :is => 1 } has_many :trade_restriction_purposes has_many :shipments, :class_name => 'Trade::Shipment' diff --git a/app/models/source.rb b/app/models/source.rb index 885e78f8e3..0013fa240f 100644 --- a/app/models/source.rb +++ b/app/models/source.rb @@ -13,7 +13,7 @@ # class Source < TradeCode - validates :code, :length => {:is => 1} + validates :code, :length => { :is => 1 } has_many :trade_restriction_sources has_many :eu_decisions diff --git a/app/models/species/csv_copy_export.rb b/app/models/species/csv_copy_export.rb index 0e568208f0..405628f77b 100644 --- a/app/models/species/csv_copy_export.rb +++ b/app/models/species/csv_copy_export.rb @@ -23,7 +23,7 @@ def export @public_file_name = "#{resource_name}_#{ctime}_#{@csv_separator}_separated.csv" [ @file_name, - {:filename => public_file_name, :type => 'text/csv'} + { :filename => public_file_name, :type => 'text/csv' } ] end diff --git a/app/models/species/search.rb b/app/models/species/search.rb index c510153763..793032fdd3 100644 --- a/app/models/species/search.rb +++ b/app/models/species/search.rb @@ -69,7 +69,7 @@ def initialize_query unless @scientific_name.blank? @query = @query. - by_name(@scientific_name, {:synonyms => true, :subspecies => true, :common_names => true}). + by_name(@scientific_name, { :synonyms => true, :subspecies => true, :common_names => true }). select( "taxon_concepts_mview.*, matching_names.matched_names_ary AS synonyms_ary" ) diff --git a/app/models/species_listing.rb b/app/models/species_listing.rb index af6e8ce98c..cd790e1ec6 100644 --- a/app/models/species_listing.rb +++ b/app/models/species_listing.rb @@ -16,8 +16,8 @@ class SpeciesListing < ActiveRecord::Base belongs_to :designation has_many :listing_changes - validates :name, :presence => true, :uniqueness => {:scope => :designation_id} - validates :abbreviation, :presence => true, :uniqueness => {:scope => :designation_id} + validates :name, :presence => true, :uniqueness => { :scope => :designation_id } + validates :abbreviation, :presence => true, :uniqueness => { :scope => :designation_id } def self.search(query) if query.present? diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index 62e4286777..abe6f9f328 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -63,7 +63,7 @@ class TaxonConcept < ActiveRecord::Base belongs_to :dependents_updater, foreign_key: :dependents_updated_by_id, class_name: User belongs_to :parent, :class_name => 'TaxonConcept' - has_many :children, class_name: 'TaxonConcept', foreign_key: :parent_id, conditions: {name_status: ['A', 'N']} + has_many :children, class_name: 'TaxonConcept', foreign_key: :parent_id, conditions: { name_status: ['A', 'N'] } belongs_to :rank belongs_to :taxonomy has_many :designations, :through => :taxonomy @@ -157,11 +157,11 @@ class TaxonConcept < ActiveRecord::Base :foreign_key => :reported_taxon_concept_id has_many :comments, as: 'commentable' has_one :general_comment, class_name: 'Comment', as: 'commentable', - conditions: {comment_type: 'General'} + conditions: { comment_type: 'General' } has_one :nomenclature_comment, class_name: 'Comment', as: 'commentable', - conditions: {comment_type: 'Nomenclature'} + conditions: { comment_type: 'Nomenclature' } has_one :distribution_comment, class_name: 'Comment', as: 'commentable', - conditions: {comment_type: 'Distribution'} + conditions: { comment_type: 'Distribution' } has_many :parent_reassignments, class_name: 'NomenclatureChange::ParentReassignment', as: :reassignable, diff --git a/app/models/taxonomy.rb b/app/models/taxonomy.rb index 004b68a052..c681cdbe63 100644 --- a/app/models/taxonomy.rb +++ b/app/models/taxonomy.rb @@ -18,7 +18,7 @@ class Taxonomy < ActiveRecord::Base validates :name, :presence => true, :uniqueness => true validates :name, - :inclusion => {:in => self.dict, :message => 'cannot change protected name'}, + :inclusion => { :in => self.dict, :message => 'cannot change protected name' }, :if => lambda { |t| t.name_changed? && t.class.dict.include?(t.name_was) }, :on => :update diff --git a/app/models/term.rb b/app/models/term.rb index 2eed4f2799..9f5cc7326a 100644 --- a/app/models/term.rb +++ b/app/models/term.rb @@ -13,7 +13,7 @@ # class Term < TradeCode - validates :code, :length => {:is => 3} + validates :code, :length => { :is => 3 } has_many :trade_restriction_terms has_many :eu_decisions diff --git a/app/models/term_trade_codes_pair.rb b/app/models/term_trade_codes_pair.rb index 56cf75b029..977e68f6fd 100644 --- a/app/models/term_trade_codes_pair.rb +++ b/app/models/term_trade_codes_pair.rb @@ -16,7 +16,7 @@ class TermTradeCodesPair < ActiveRecord::Base belongs_to :term, :class_name => "TradeCode" belongs_to :trade_code - validates :term_id, :presence => true, :uniqueness => {:scope => :trade_code_id} + validates :term_id, :presence => true, :uniqueness => { :scope => :trade_code_id } def self.search(query) if query.present? diff --git a/app/models/trade/sandbox_template.rb b/app/models/trade/sandbox_template.rb index 252ddab312..bb2573fdb0 100644 --- a/app/models/trade/sandbox_template.rb +++ b/app/models/trade/sandbox_template.rb @@ -79,7 +79,7 @@ def self.sanitize(id = nil) export_permit = UPPER(SQUISH_NULL(export_permit)), origin_permit = UPPER(SQUISH_NULL(origin_permit)) ', - id.blank? ? nil : {:id => id} + id.blank? ? nil : { :id => id } ) # resolve reported & accepted taxon connection.execute( diff --git a/app/models/trade/shipments_comptab_export.rb b/app/models/trade/shipments_comptab_export.rb index cdec8f7737..5ee1148713 100644 --- a/app/models/trade/shipments_comptab_export.rb +++ b/app/models/trade/shipments_comptab_export.rb @@ -32,7 +32,7 @@ def available_columns :year => {}, :appendix => {}, :taxon => {}, - :taxon_concept_id => {:internal => true}, + :taxon_concept_id => { :internal => true }, :class_name => {}, :order_name => {}, :family_name => {}, @@ -42,8 +42,8 @@ def available_columns :country_of_origin => {}, :importer_quantity => {}, :exporter_quantity => {}, - :term => {:en => :term_name_en, :es => :term_name_es, :fr => :term_name_fr}, - :unit => {:en => :unit_name_en, :es => :unit_name_es, :fr => :unit_name_fr}, + :term => { :en => :term_name_en, :es => :term_name_es, :fr => :term_name_fr }, + :unit => { :en => :unit_name_en, :es => :unit_name_es, :fr => :unit_name_fr }, :purpose => {}, :source => {} } diff --git a/app/models/trade/shipments_export.rb b/app/models/trade/shipments_export.rb index c519eaecb8..e8f62c92a9 100644 --- a/app/models/trade/shipments_export.rb +++ b/app/models/trade/shipments_export.rb @@ -28,7 +28,7 @@ def export @public_file_name = "#{resource_name}_#{ctime}_#{@csv_separator}_separated.csv" [ @file_name, - {:filename => public_file_name, :type => 'text/csv'} + { :filename => public_file_name, :type => 'text/csv' } ] end @@ -94,32 +94,32 @@ def to_csv def available_columns { - :id => {:internal => true}, + :id => { :internal => true }, :year => {}, :appendix => {}, :taxon => {}, - :taxon_concept_id => {:internal => true}, - :class_name => {:internal => true}, - :order_name => {:internal => true}, - :family_name => {:internal => true}, - :genus_name => {:internal => true}, - :reported_taxon => {:internal => true}, - :reported_taxon_concept_id => {:internal => true}, - :term => {:en => :term_name_en, :es => :term_name_es, :fr => :term_name_fr}, + :taxon_concept_id => { :internal => true }, + :class_name => { :internal => true }, + :order_name => { :internal => true }, + :family_name => { :internal => true }, + :genus_name => { :internal => true }, + :reported_taxon => { :internal => true }, + :reported_taxon_concept_id => { :internal => true }, + :term => { :en => :term_name_en, :es => :term_name_es, :fr => :term_name_fr }, :quantity => {}, - :unit => {:en => :unit_name_en, :es => :unit_name_es, :fr => :unit_name_fr}, + :unit => { :en => :unit_name_en, :es => :unit_name_es, :fr => :unit_name_fr }, :importer => {}, :exporter => {}, :country_of_origin => {}, :purpose => {}, :source => {}, - :reporter_type => {:internal => true}, - :import_permit_number => {:internal => true}, - :export_permit_number => {:internal => true}, - :origin_permit_number => {:internal => true}, - :legacy_shipment_number => {:internal => true}, - :created_by => {:internal => true}, - :updated_by => {:internal => true} + :reporter_type => { :internal => true }, + :import_permit_number => { :internal => true }, + :export_permit_number => { :internal => true }, + :origin_permit_number => { :internal => true }, + :legacy_shipment_number => { :internal => true }, + :created_by => { :internal => true }, + :updated_by => { :internal => true } } end diff --git a/app/models/trade/shipments_export_factory.rb b/app/models/trade/shipments_export_factory.rb index 695c5dac25..e577766938 100644 --- a/app/models/trade/shipments_export_factory.rb +++ b/app/models/trade/shipments_export_factory.rb @@ -1,7 +1,7 @@ class Trade::ShipmentsExportFactory def self.new(filters) filters ||= {} - filters = filters.merge({:locale => I18n.locale}) + filters = filters.merge({ :locale => I18n.locale }) @report_type = filters[:report_type] unless report_types.include? @report_type @report_type = :comptab diff --git a/app/models/trade/shipments_gross_exports_export.rb b/app/models/trade/shipments_gross_exports_export.rb index 386305149c..739cb5bc5a 100644 --- a/app/models/trade/shipments_gross_exports_export.rb +++ b/app/models/trade/shipments_gross_exports_export.rb @@ -48,12 +48,12 @@ def available_columns { :appendix => {}, :taxon => {}, - :taxon_concept_id => {:internal => true}, - :term => {:en => :term_name_en, :es => :term_name_es, :fr => :term_name_fr}, - :unit => {:en => :unit_name_en, :es => :unit_name_es, :fr => :unit_name_fr}, + :taxon_concept_id => { :internal => true }, + :term => { :en => :term_name_en, :es => :term_name_es, :fr => :term_name_fr }, + :unit => { :en => :unit_name_en, :es => :unit_name_es, :fr => :unit_name_fr }, :country => {}, - :year => {:subquery => true}, - :gross_quantity => {:subquery => true} + :year => { :subquery => true }, + :gross_quantity => { :subquery => true } } end @@ -64,12 +64,12 @@ def row_name_columns def crosstab_columns { - :appendix => {:pg_type => 'TEXT'}, - :taxon_concept_id => {:pg_type => 'INT'}, - :taxon => {:pg_type => 'TEXT'}, - :term => {:pg_type => 'TEXT'}, - :unit => {:pg_type => 'TEXT'}, - :country => {:pg_type => 'TEXT'} + :appendix => { :pg_type => 'TEXT' }, + :taxon_concept_id => { :pg_type => 'INT' }, + :taxon => { :pg_type => 'TEXT' }, + :term => { :pg_type => 'TEXT' }, + :unit => { :pg_type => 'TEXT' }, + :country => { :pg_type => 'TEXT' } } end diff --git a/app/models/trade_code.rb b/app/models/trade_code.rb index a2452e78f1..83f5c6bade 100644 --- a/app/models/trade_code.rb +++ b/app/models/trade_code.rb @@ -17,7 +17,7 @@ class TradeCode < ActiveRecord::Base :name_en, :name_es, :name_fr translates :name - validates :code, :presence => true, :uniqueness => {:scope => :type} + validates :code, :presence => true, :uniqueness => { :scope => :type } def self.search(query) if query.present? diff --git a/app/models/trade_restriction.rb b/app/models/trade_restriction.rb index 16b16e0e6a..b7fb1e94cc 100644 --- a/app/models/trade_restriction.rb +++ b/app/models/trade_restriction.rb @@ -135,7 +135,7 @@ def self.to_csv(file_path, filters) when :semicolon then ';' else ',' end - CSV.open(file_path, 'wb', {:col_sep => csv_separator_char}) do |csv| + CSV.open(file_path, 'wb', { :col_sep => csv_separator_char }) do |csv| csv << Species::RestrictionsExport::TAXONOMY_COLUMN_NAMES + ['Remarks'] + self.csv_columns_headers ids = [] diff --git a/app/models/unit.rb b/app/models/unit.rb index bb4e418e1f..702c8efea5 100644 --- a/app/models/unit.rb +++ b/app/models/unit.rb @@ -13,7 +13,7 @@ # class Unit < TradeCode - validates :code, :length => {:is => 3} + validates :code, :length => { :is => 3 } has_many :term_trade_codes_pairs, :as => :trade_code has_many :quotas diff --git a/app/serializers/species/cites_suspension_serializer.rb b/app/serializers/species/cites_suspension_serializer.rb index e47cce26e5..d45f20d011 100644 --- a/app/serializers/species/cites_suspension_serializer.rb +++ b/app/serializers/species/cites_suspension_serializer.rb @@ -1,5 +1,5 @@ class Species::CitesSuspensionSerializer < ActiveModel::Serializer - attributes :notes, {:start_date_formatted => :start_date}, + attributes :notes, { :start_date_formatted => :start_date }, :is_current, :subspecies_info, :nomenclature_note_en, :nomenclature_note_fr, :nomenclature_note_es, :geo_entity, diff --git a/app/serializers/species/document_serializer.rb b/app/serializers/species/document_serializer.rb index b5613c8331..0034328048 100644 --- a/app/serializers/species/document_serializer.rb +++ b/app/serializers/species/document_serializer.rb @@ -1,5 +1,5 @@ class Species::DocumentSerializer < ActiveModel::Serializer - attributes :event_type, :event_name, {date_formatted: :date}, :is_public, + attributes :event_type, :event_name, { date_formatted: :date }, :is_public, :document_type, :proposal_number, :primary_document_id, :taxon_names, :geo_entity_names, :taxon_names, :geo_entity_names, diff --git a/app/serializers/species/eu_decision_serializer.rb b/app/serializers/species/eu_decision_serializer.rb index b7dd12233a..5107e7b6a5 100644 --- a/app/serializers/species/eu_decision_serializer.rb +++ b/app/serializers/species/eu_decision_serializer.rb @@ -1,5 +1,5 @@ class Species::EuDecisionSerializer < ActiveModel::Serializer - attributes :notes, {:start_date_formatted => :start_date}, + attributes :notes, { :start_date_formatted => :start_date }, :is_current, :subspecies_info, :nomenclature_note_en, :nomenclature_note_fr, :nomenclature_note_es, :eu_decision_type, @@ -7,7 +7,7 @@ class Species::EuDecisionSerializer < ActiveModel::Serializer :start_event, :source, :term, - {:original_start_date_formatted => :original_start_date} + { :original_start_date_formatted => :original_start_date } def eu_decision_type object['eu_decision_type'] && JSON.parse(object['eu_decision_type']) diff --git a/app/serializers/species/quota_serializer.rb b/app/serializers/species/quota_serializer.rb index 3556983fe7..7ce893cd8b 100644 --- a/app/serializers/species/quota_serializer.rb +++ b/app/serializers/species/quota_serializer.rb @@ -1,5 +1,5 @@ class Species::QuotaSerializer < ActiveModel::Serializer - attributes :quota, :year, {:publication_date_formatted => :publication_date}, + attributes :quota, :year, { :publication_date_formatted => :publication_date }, :notes, :url, :public_display, :is_current, :subspecies_info, :nomenclature_note_en, :nomenclature_note_fr, :nomenclature_note_es, :geo_entity, diff --git a/lib/modules/dashboard_stats_cache.rb b/lib/modules/dashboard_stats_cache.rb index 44e65b7ec3..15cc9c52f2 100644 --- a/lib/modules/dashboard_stats_cache.rb +++ b/lib/modules/dashboard_stats_cache.rb @@ -7,8 +7,8 @@ def self.update_dashboard_stats where("geo_entity_types.name in ('COUNTRY','TERRITORY')") countries.each do |country| puts "Warming up #{country.name_en}" - stats = DashboardStats.new(country, {:kingdom => 'Animalia', :trade_limit => 6, - :time_range_start => Time.now.year-7, :time_range_end => Time.now.year-2}) + stats = DashboardStats.new(country, { :kingdom => 'Animalia', :trade_limit => 6, + :time_range_start => Time.now.year-7, :time_range_end => Time.now.year-2 }) DashboardStatsSerializer.new(stats).serializable_hash end end diff --git a/lib/modules/sapi/summary.rb b/lib/modules/sapi/summary.rb index 99ae6e4f83..1c75c2892e 100644 --- a/lib/modules/sapi/summary.rb +++ b/lib/modules/sapi/summary.rb @@ -31,9 +31,9 @@ def self.taxonomic_stats taxonomic[:taxon_names] = TaxonName.count taxonomic[:taxon_concepts] = TaxonConcept.count taxonomic[:common_names] = CommonName.count - taxonomic[:common_names_en] = CommonName.joins(:language).where(:languages => {:name_en => 'English'}).count - taxonomic[:common_names_fr] = CommonName.joins(:language).where(:languages => {:name_en => 'French'}).count - taxonomic[:common_names_es] = CommonName.joins(:language).where(:languages => {:name_en => 'Spanish'}).count + taxonomic[:common_names_en] = CommonName.joins(:language).where(:languages => { :name_en => 'English' }).count + taxonomic[:common_names_fr] = CommonName.joins(:language).where(:languages => { :name_en => 'French' }).count + taxonomic[:common_names_es] = CommonName.joins(:language).where(:languages => { :name_en => 'Spanish' }).count taxonomic end @@ -41,9 +41,9 @@ def self.geo_stats geo = {} geo[:geo_entity_types] = GeoEntityType.count geo[:geo_entities] = GeoEntity.count - geo[:countries] = GeoEntity.joins(:geo_entity_type).where(:geo_entity_types => {:name => GeoEntityType::COUNTRY}).count - geo[:cites_regions] = GeoEntity.joins(:geo_entity_type).where(:geo_entity_types => {:name => GeoEntityType::CITES_REGION}).count - geo[:territories] = GeoEntity.joins(:geo_entity_type).where(:geo_entity_types => {:name => GeoEntityType::TERRITORY}).count + geo[:countries] = GeoEntity.joins(:geo_entity_type).where(:geo_entity_types => { :name => GeoEntityType::COUNTRY }).count + geo[:cites_regions] = GeoEntity.joins(:geo_entity_type).where(:geo_entity_types => { :name => GeoEntityType::CITES_REGION }).count + geo[:territories] = GeoEntity.joins(:geo_entity_type).where(:geo_entity_types => { :name => GeoEntityType::TERRITORY }).count geo end @@ -90,10 +90,10 @@ def self.taxonomy_kingdom_stats(taxonomy, kingdom) ).where(["(data->'kingdom_id')::INT = ?", k.id]). where("name_status NOT IN ('A', 'S')").count stats[:listing_changes] = ListingChange.joins(:taxon_concept). - where(:taxon_concepts => {:taxonomy_id => t.id }). + where(:taxon_concepts => { :taxonomy_id => t.id }). where(["(data->'kingdom_id')::INT = ?", k.id]).count distributions = Distribution.joins(:taxon_concept). - where(:taxon_concepts => {:taxonomy_id => t.id }). + where(:taxon_concepts => { :taxonomy_id => t.id }). where(["(data->'kingdom_id')::INT = ?", k.id]) stats[:distributions] = distributions.count stats[:distribution_tags] = ActiveRecord::Base.connection.execute(<<-SQL @@ -109,16 +109,16 @@ def self.taxonomy_kingdom_stats(taxonomy, kingdom) ).values.flatten[0] stats[:distribution_references] = DistributionReference. joins(:distribution => :taxon_concept). - where(:taxon_concepts => {:taxonomy_id => t.id }). + where(:taxon_concepts => { :taxonomy_id => t.id }). where(["(data->'kingdom_id')::INT = ?", k.id]).count stats[:taxon_references] = TaxonConceptReference.joins(:taxon_concept). - where(:taxon_concepts => {:taxonomy_id => t.id }). + where(:taxon_concepts => { :taxonomy_id => t.id }). where(["(data->'kingdom_id')::INT = ?", k.id]).count stats[:taxon_standard_references] = TaxonConceptReference.joins(:taxon_concept). - where(:taxon_concepts => {:taxonomy_id => t.id }, :taxon_concept_references => {:is_standard => true}). + where(:taxon_concepts => { :taxonomy_id => t.id }, :taxon_concept_references => { :is_standard => true }). where(["(data->'kingdom_id')::INT = ?", k.id]).count stats[:common_names] = TaxonCommon.joins(:taxon_concept). - where(:taxon_concepts => {:taxonomy_id => t.id }). + where(:taxon_concepts => { :taxonomy_id => t.id }). where(["(data->'kingdom_id')::INT = ?", k.id]).count stats end diff --git a/lib/modules/statistics.rb b/lib/modules/statistics.rb index 432b48af06..41467b7124 100644 --- a/lib/modules/statistics.rb +++ b/lib/modules/statistics.rb @@ -10,9 +10,9 @@ def self.get_total_transactions_per_year reported_by_importer = Trade::Shipment.where(:year => y, :reported_by_exporter => false).count total_transactions = Trade::Shipment.where(:year => y).count - trade_transactions[y] = {:total => total_transactions, + trade_transactions[y] = { :total => total_transactions, :reported_by_exporter => reported_by_exporter, - :reported_by_importer => reported_by_importer} + :reported_by_importer => reported_by_importer } end } trade_transactions[:total] = {} diff --git a/lib/tasks/elibrary/importable.rb b/lib/tasks/elibrary/importable.rb index 22091733a9..ace112f700 100644 --- a/lib/tasks/elibrary/importable.rb +++ b/lib/tasks/elibrary/importable.rb @@ -42,7 +42,7 @@ def copy_from_csv(path_to_file, table_name, db_columns) end def print_query_counts - queries = {'rows_in_import_file' => "SELECT COUNT(*) FROM #{table_name}"} + queries = { 'rows_in_import_file' => "SELECT COUNT(*) FROM #{table_name}" } queries['rows_to_insert'] = "SELECT COUNT(*) FROM (#{rows_to_insert_sql}) t" queries.each do |q_name, q| res = ActiveRecord::Base.connection.execute(q) diff --git a/lib/tasks/import_cites_listings.rake b/lib/tasks/import_cites_listings.rake index 857c198bb6..585e562c76 100644 --- a/lib/tasks/import_cites_listings.rake +++ b/lib/tasks/import_cites_listings.rake @@ -6,9 +6,9 @@ namespace :import do designation = Designation.find_by_name(Designation::CITES) taxonomy = Taxonomy.find_by_name(Taxonomy::CITES_EU) puts "There are #{ListingChange.joins(:species_listing). - where(:species_listings => {:designation_id => designation.id}).count} CITES listings in the database" + where(:species_listings => { :designation_id => designation.id }).count} CITES listings in the database" puts "There are #{ListingDistribution.joins(:listing_change => :species_listing). - where(:species_listings => {:designation_id => designation.id}).count} CITES listing distributions in the database" + where(:species_listings => { :designation_id => designation.id }).count} CITES listing distributions in the database" appendix_1 = SpeciesListing.find_by_designation_id_and_abbreviation(designation.id, 'I') appendix_2 = SpeciesListing.find_by_designation_id_and_abbreviation(designation.id, 'II') appendix_3 = SpeciesListing.find_by_designation_id_and_abbreviation(designation.id, 'III') @@ -19,9 +19,9 @@ namespace :import do rw = ChangeType.find_by_name_and_designation_id(ChangeType::RESERVATION_WITHDRAWAL, designation.id) english = Language.find_by_name_en('English') listings_count = ListingChange.joins(:species_listing). - where(:species_listings => {:designation_id => designation.id}).count + where(:species_listings => { :designation_id => designation.id }).count listings_d_count = ListingDistribution.joins(:listing_change => :species_listing). - where(:species_listings => {:designation_id => designation.id}).count + where(:species_listings => { :designation_id => designation.id }).count files = files_from_args(t, args) files.each do |file| @@ -225,9 +225,9 @@ namespace :import do ActiveRecord::Base.connection.execute("DROP VIEW cites_listings_import_view") new_listings_count = ListingChange.joins(:species_listing). - where(:species_listings => {:designation_id => designation.id}).count + where(:species_listings => { :designation_id => designation.id }).count new_listings_d_count = ListingDistribution.joins(:listing_change => :species_listing). - where(:species_listings => {:designation_id => designation.id}).count + where(:species_listings => { :designation_id => designation.id }).count puts "#{new_listings_count - listings_count} CITES listings were added to the database" puts "#{new_listings_d_count - listings_d_count} CITES listing distributions were added to the database" @@ -272,11 +272,11 @@ namespace :import do task :delete_all => :environment do designation = Designation.find_by_name("CITES") AnnotationTranslation.joins(:annotation => :event). - where(:events => {:designation_id => designation.id}).delete_all + where(:events => { :designation_id => designation.id }).delete_all Annotation.joins(:event). - where(:events => {:designation_id => designation.id}).delete_all + where(:events => { :designation_id => designation.id }).delete_all ListingDistribution.joins(:listing_change). - where(:listing_changes => {:desigantion_id => designation.id}).delete_all + where(:listing_changes => { :desigantion_id => designation.id }).delete_all ListingChange.where(:designation_id => designation.id).delete_all end end diff --git a/lib/tasks/import_cites_regions.rake b/lib/tasks/import_cites_regions.rake index e1c26f75fa..34d55ae35e 100644 --- a/lib/tasks/import_cites_regions.rake +++ b/lib/tasks/import_cites_regions.rake @@ -4,7 +4,7 @@ namespace :import do task :cites_regions, 10.times.map { |i| "file_#{i}".to_sym } => [:environment] do |t, args| tmp_table = 'cites_regions_import' regions_type = GeoEntityType.find_by_name(GeoEntityType::CITES_REGION) - puts "There are #{GeoEntity.count(conditions: {geo_entity_type_id: regions_type.id})} CITES Regions in the database." + puts "There are #{GeoEntity.count(conditions: { geo_entity_type_id: regions_type.id })} CITES Regions in the database." files = files_from_args(t, args) files.each do |file| drop_table(tmp_table) @@ -21,7 +21,7 @@ namespace :import do SQL ActiveRecord::Base.connection.execute(sql) end - puts "There are now #{GeoEntity.count(conditions: {geo_entity_type_id: regions_type.id})} CITES Regions in the database" + puts "There are now #{GeoEntity.count(conditions: { geo_entity_type_id: regions_type.id })} CITES Regions in the database" end task :cites_regions_translations => :environment do diff --git a/lib/tasks/import_cms_listings.rake b/lib/tasks/import_cms_listings.rake index cfe6b2de6d..f36593987b 100644 --- a/lib/tasks/import_cms_listings.rake +++ b/lib/tasks/import_cms_listings.rake @@ -6,9 +6,9 @@ namespace :import do designation = Designation.find_by_name(Designation::CMS) taxonomy = Taxonomy.find_by_name(Taxonomy::CMS) puts "There are #{ListingChange.joins(:species_listing). - where(:species_listings => {:designation_id => designation.id}).count} CMS listings in the database" + where(:species_listings => { :designation_id => designation.id }).count} CMS listings in the database" puts "There are #{ListingDistribution.joins(:listing_change => :species_listing). - where(:species_listings => {:designation_id => designation.id}).count} CMS listing distributions in the database" + where(:species_listings => { :designation_id => designation.id }).count} CMS listing distributions in the database" appendix_1 = SpeciesListing.find_by_designation_id_and_abbreviation(designation.id, 'I') appendix_2 = SpeciesListing.find_by_designation_id_and_abbreviation(designation.id, 'II') a = ChangeType.find_by_name_and_designation_id(ChangeType::ADDITION, designation.id) @@ -16,9 +16,9 @@ namespace :import do e = ChangeType.find_by_name_and_designation_id(ChangeType::EXCEPTION, designation.id) english = Language.find_by_name_en('English') listings_count = ListingChange.joins(:species_listing). - where(:species_listings => {:designation_id => designation.id}).count + where(:species_listings => { :designation_id => designation.id }).count listings_d_count = ListingDistribution.joins(:listing_change => :species_listing). - where(:species_listings => {:designation_id => designation.id}).count + where(:species_listings => { :designation_id => designation.id }).count files = files_from_args(t, args) files.each do |file| @@ -234,9 +234,9 @@ namespace :import do # ActiveRecord::Base.connection.execute("DROP VIEW cms_listings_import_view") new_listings_count = ListingChange.joins(:species_listing). - where(:species_listings => {:designation_id => designation.id}).count + where(:species_listings => { :designation_id => designation.id }).count new_listings_d_count = ListingDistribution.joins(:listing_change => :species_listing). - where(:species_listings => {:designation_id => designation.id}).count + where(:species_listings => { :designation_id => designation.id }).count puts "#{new_listings_count - listings_count} CMS listings were added to the database" puts "#{new_listings_d_count - listings_d_count} CMS listing distributions were added to the database" @@ -260,11 +260,11 @@ namespace :import do task :delete_all => :environment do designation = Designation.find_by_name("CMS") AnnotationTranslation.joins(:annotation => :event). - where(:events => {:designation_id => designation.id}).delete_all + where(:events => { :designation_id => designation.id }).delete_all Annotation.joins(:event). - where(:events => {:designation_id => designation.id}).delete_all + where(:events => { :designation_id => designation.id }).delete_all ListingDistribution.joins(:listing_change). - where(:listing_changes => {:desigantion_id => designation.id}).delete_all + where(:listing_changes => { :desigantion_id => designation.id }).delete_all ListingChange.where(:designation_id => designation.id).delete_all end end diff --git a/lib/tasks/import_countries.rake b/lib/tasks/import_countries.rake index 48a1ea464d..cc706f9600 100644 --- a/lib/tasks/import_countries.rake +++ b/lib/tasks/import_countries.rake @@ -10,8 +10,8 @@ namespace :import do TMP_TABLE = 'countries_import' country_type = GeoEntityType.find_by_name(GeoEntityType::COUNTRY) territory_type = GeoEntityType.find_by_name(GeoEntityType::TERRITORY) - puts "There are #{GeoEntity.count(conditions: {geo_entity_type_id: country_type.id})} countries in the database." - puts "There are #{GeoEntity.count(conditions: {geo_entity_type_id: territory_type.id})} territories in the database." + puts "There are #{GeoEntity.count(conditions: { geo_entity_type_id: country_type.id })} countries in the database." + puts "There are #{GeoEntity.count(conditions: { geo_entity_type_id: territory_type.id })} territories in the database." files = files_from_args(t, args) files.each do |file| drop_table(TMP_TABLE) @@ -35,8 +35,8 @@ namespace :import do ActiveRecord::Base.connection.execute(sql) link_countries end - puts "There are now #{GeoEntity.count(conditions: {geo_entity_type_id: country_type.id})} countries in the database" - puts "There are now #{GeoEntity.count(conditions: {geo_entity_type_id: territory_type.id})} territories in the database." + puts "There are now #{GeoEntity.count(conditions: { geo_entity_type_id: country_type.id })} countries in the database" + puts "There are now #{GeoEntity.count(conditions: { geo_entity_type_id: territory_type.id })} territories in the database." end desc "Add country names in spanish and french" diff --git a/lib/tasks/import_eu_listings.rake b/lib/tasks/import_eu_listings.rake index aa0b79d6ff..ee4fa72a49 100644 --- a/lib/tasks/import_eu_listings.rake +++ b/lib/tasks/import_eu_listings.rake @@ -6,9 +6,9 @@ namespace :import do designation = Designation.find_by_name(Designation::EU) taxonomy = Taxonomy.find_by_name(Taxonomy::CITES_EU) puts "There are #{ListingChange.joins(:species_listing). - where(:species_listings => {:designation_id => designation.id}).count} EU listings in the database" + where(:species_listings => { :designation_id => designation.id }).count} EU listings in the database" puts "There are #{ListingDistribution.joins(:listing_change => :species_listing). - where(:species_listings => {:designation_id => designation.id}).count} EU listing distributions in the database" + where(:species_listings => { :designation_id => designation.id }).count} EU listing distributions in the database" annex_A = SpeciesListing.find_by_designation_id_and_abbreviation(designation.id, 'A') annex_B = SpeciesListing.find_by_designation_id_and_abbreviation(designation.id, 'B') annex_C = SpeciesListing.find_by_designation_id_and_abbreviation(designation.id, 'C') @@ -18,9 +18,9 @@ namespace :import do e = ChangeType.find_by_name_and_designation_id(ChangeType::EXCEPTION, designation.id) english = Language.find_by_name_en('English') listings_count = ListingChange.joins(:species_listing). - where(:species_listings => {:designation_id => designation.id}).count + where(:species_listings => { :designation_id => designation.id }).count listings_d_count = ListingDistribution.joins(:listing_change => :species_listing). - where(:species_listings => {:designation_id => designation.id}).count + where(:species_listings => { :designation_id => designation.id }).count files = files_from_args(t, args) files.each do |file| @@ -215,9 +215,9 @@ namespace :import do ActiveRecord::Base.connection.execute("DROP VIEW eu_listings_import_view") new_listings_count = ListingChange.joins(:species_listing). - where(:species_listings => {:designation_id => designation.id}).count + where(:species_listings => { :designation_id => designation.id }).count new_listings_d_count = ListingDistribution.joins(:listing_change => :species_listing). - where(:species_listings => {:designation_id => designation.id}).count + where(:species_listings => { :designation_id => designation.id }).count puts "#{new_listings_count - listings_count} EU listings were added to the database" puts "#{new_listings_d_count - listings_d_count} EU listing distributions were added to the database" @@ -241,9 +241,9 @@ namespace :import do task :delete_all => :environment do designation = Designation.find_by_name("EU") Annotation.joins(:event). - where(:events => {:designation_id => designation.id}).delete_all + where(:events => { :designation_id => designation.id }).delete_all ListingDistribution.joins(:listing_change). - where(:listing_changes => {:desigantion_id => designation.id}).delete_all + where(:listing_changes => { :desigantion_id => designation.id }).delete_all ListingChange.where(:designation_id => designation.id).delete_all end end diff --git a/lib/tasks/import_trade_permits.rake b/lib/tasks/import_trade_permits.rake index 5f88515375..1ad5d06488 100644 --- a/lib/tasks/import_trade_permits.rake +++ b/lib/tasks/import_trade_permits.rake @@ -3,9 +3,9 @@ namespace :import do task :trade_permits, 10.times.map { |i| "file_#{i}".to_sym } => [:environment] do |t, args| TMP_TABLE = "permits_import" - permits_import_to_index = {"permits_import" => ["permit_number", "shipment_number", "permit_reporter_type"]} - trade_shipments_indexed = {"trade_shipments" => ["export_permits_ids", "import_permits_ids", "origin_permits_ids"]} - trade_shipments_to_index = {"trade_shipments" => ["legacy_shipment_number"]} + permits_import_to_index = { "permits_import" => ["permit_number", "shipment_number", "permit_reporter_type"] } + trade_shipments_indexed = { "trade_shipments" => ["export_permits_ids", "import_permits_ids", "origin_permits_ids"] } + trade_shipments_to_index = { "trade_shipments" => ["legacy_shipment_number"] } files = files_from_args(t, args) files.each do |file| @@ -80,7 +80,7 @@ def populate_trade_permits end def insert_into_trade_shipments - permits_entity = {"import" => "I", "export" => 'E', "origin" => 'O'} + permits_entity = { "import" => "I", "export" => 'E', "origin" => 'O' } permits_entity.each do |k, v| sql = <<-SQL WITH grouped_permits AS ( diff --git a/lib/tasks/import_trade_shipments.rake b/lib/tasks/import_trade_shipments.rake index 69e4df44b1..c40c2bdc52 100644 --- a/lib/tasks/import_trade_shipments.rake +++ b/lib/tasks/import_trade_shipments.rake @@ -31,7 +31,7 @@ namespace :import do DELETE FROM shipments_import WHERE shipment_number = 8122168; SQL ActiveRecord::Base.connection.execute(sql) - fix_term_codes = {12227624 => "LIV", 12225022 => "DER", 12224783 => "DER"} + fix_term_codes = { 12227624 => "LIV", 12225022 => "DER", 12224783 => "DER" } fix_term_codes.each do |shipment_number, term_code| sql = <<-SQL UPDATE shipments_import SET term_code_1 = '#{term_code}' WHERE shipment_number = #{shipment_number}; @@ -59,7 +59,7 @@ namespace :import do DELETE FROM shipments_import WHERE shipment_number = 8122168; SQL ActiveRecord::Base.connection.execute(sql) - fix_term_codes = {12227624 => "LIV", 12225022 => "DER", 12224783 => "DER"} + fix_term_codes = { 12227624 => "LIV", 12225022 => "DER", 12224783 => "DER" } fix_term_codes.each do |shipment_number, term_code| sql = <<-SQL UPDATE shipments_import SET term_code_1 = '#{term_code}' WHERE shipment_number = #{shipment_number}; diff --git a/spec/controllers/admin/documents_controller_spec.rb b/spec/controllers/admin/documents_controller_spec.rb index edad38cefd..05b86d05a6 100644 --- a/spec/controllers/admin/documents_controller_spec.rb +++ b/spec/controllers/admin/documents_controller_spec.rb @@ -157,7 +157,7 @@ it "assign review phase to Review" do put :update, id: document.id, document: { - date: Date.today, review_details_attributes: {review_phase_id: review_phase.id} + date: Date.today, review_details_attributes: { review_phase_id: review_phase.id } } response.should redirect_to(admin_documents_url) @@ -166,7 +166,7 @@ it "assign process stage to Review" do put :update, id: document.id, document: { - date: Date.today, review_details_attributes: {process_stage_id: process_stage.id} + date: Date.today, review_details_attributes: { process_stage_id: process_stage.id } } response.should redirect_to(admin_documents_url) @@ -175,7 +175,7 @@ it "assign recommended category to Review" do put :update, id: document.id, document: { - date: Date.today, review_details_attributes: {recommended_category: recommended_category} + date: Date.today, review_details_attributes: { recommended_category: recommended_category } } response.should redirect_to(admin_documents_url) @@ -189,7 +189,7 @@ it "assign outcome to Proposal" do put :update, id: document.id, document: { - date: Date.today, proposal_details_attributes: {proposal_outcome_id: proposal_outcome.id} + date: Date.today, proposal_details_attributes: { proposal_outcome_id: proposal_outcome.id } } response.should redirect_to(admin_documents_url) diff --git a/spec/controllers/admin/exports_controller_spec.rb b/spec/controllers/admin/exports_controller_spec.rb index 1a32f6471d..62ecc38bdf 100644 --- a/spec/controllers/admin/exports_controller_spec.rb +++ b/spec/controllers/admin/exports_controller_spec.rb @@ -31,12 +31,12 @@ it "returns CITES_EU taxon concepts names file" do create_cites_eu_species Species::TaxonConceptsNamesExport.any_instance.stub(:public_file_name).and_return('taxon_concepts_names.csv') - get :download, :data_type => "Names", :filters => {:taxonomy => 'CITES_EU'} + get :download, :data_type => "Names", :filters => { :taxonomy => 'CITES_EU' } response.content_type.should eq("text/csv") response.headers["Content-Disposition"].should eq("attachment; filename=\"taxon_concepts_names.csv\"") end it "redirects when no results" do - get :download, :data_type => "Names", :filters => {:taxonomy => 'CITES_EU'} + get :download, :data_type => "Names", :filters => { :taxonomy => 'CITES_EU' } response.should redirect_to(admin_exports_path) end end @@ -44,12 +44,12 @@ it "returns CMS taxon concepts names file" do create_cms_species Species::TaxonConceptsNamesExport.any_instance.stub(:public_file_name).and_return('taxon_concepts_names.csv') - get :download, :data_type => "Names", :filters => {:taxonomy => 'CMS'} + get :download, :data_type => "Names", :filters => { :taxonomy => 'CMS' } response.content_type.should eq("text/csv") response.headers["Content-Disposition"].should eq("attachment; filename=\"taxon_concepts_names.csv\"") end it "redirects when no results" do - get :download, :data_type => "Names", :filters => {:taxonomy => 'CMS'} + get :download, :data_type => "Names", :filters => { :taxonomy => 'CMS' } response.should redirect_to(admin_exports_path) end end @@ -77,12 +77,12 @@ tc = create_cites_eu_species create(:distribution, :taxon_concept_id => tc.id) Species::TaxonConceptsDistributionsExport.any_instance.stub(:public_file_name).and_return('taxon_concepts_distributions.csv') - get :download, :data_type => "Distributions", :filters => {:taxonomy => 'CITES_EU'} + get :download, :data_type => "Distributions", :filters => { :taxonomy => 'CITES_EU' } response.content_type.should eq("text/csv") response.headers["Content-Disposition"].should eq("attachment; filename=\"taxon_concepts_distributions.csv\"") end it "redirects when no results" do - get :download, :data_type => "Distributions", :filters => {:taxonomy => 'CITES_EU'} + get :download, :data_type => "Distributions", :filters => { :taxonomy => 'CITES_EU' } response.should redirect_to(admin_exports_path) end end @@ -91,12 +91,12 @@ tc = create_cms_species create(:distribution, :taxon_concept_id => tc.id) Species::TaxonConceptsDistributionsExport.any_instance.stub(:public_file_name).and_return('taxon_concepts_distributions.csv') - get :download, :data_type => "Distributions", :filters => {:taxonomy => 'CMS'} + get :download, :data_type => "Distributions", :filters => { :taxonomy => 'CMS' } response.content_type.should eq("text/csv") response.headers["Content-Disposition"].should eq("attachment; filename=\"taxon_concepts_distributions.csv\"") end it "redirects when no results" do - get :download, :data_type => "Distributions", :filters => {:taxonomy => 'CMS'} + get :download, :data_type => "Distributions", :filters => { :taxonomy => 'CMS' } response.should redirect_to(admin_exports_path) end end diff --git a/spec/controllers/admin/nomenclature_changes/lump_controller_spec.rb b/spec/controllers/admin/nomenclature_changes/lump_controller_spec.rb index ad63893842..b59311963a 100644 --- a/spec/controllers/admin/nomenclature_changes/lump_controller_spec.rb +++ b/spec/controllers/admin/nomenclature_changes/lump_controller_spec.rb @@ -79,8 +79,8 @@ it 'redirects to next step' do put :update, nomenclature_change_lump: { inputs_attributes: { - 0 => {taxon_concept_id: create_cites_eu_species.id}, - 1 => {taxon_concept_id: create_cites_eu_species.id} + 0 => { taxon_concept_id: create_cites_eu_species.id }, + 1 => { taxon_concept_id: create_cites_eu_species.id } } }, nomenclature_change_id: @lump.id, id: 'inputs' response.should redirect_to( @@ -95,7 +95,7 @@ put :update, nomenclature_change_lump: { inputs_attributes: { - 0 => {taxon_concept_id: nil} + 0 => { taxon_concept_id: nil } } }, nomenclature_change_id: @lump.id, id: 'inputs' response.should render_template('inputs') diff --git a/spec/controllers/admin/nomenclature_changes/split_controller_spec.rb b/spec/controllers/admin/nomenclature_changes/split_controller_spec.rb index c3a85b1943..b87cbe5c43 100644 --- a/spec/controllers/admin/nomenclature_changes/split_controller_spec.rb +++ b/spec/controllers/admin/nomenclature_changes/split_controller_spec.rb @@ -136,7 +136,7 @@ context 'when successful' do it 'redirects to next step' do put :update, nomenclature_change_split: { - input_attributes: {taxon_concept_id: create_cites_eu_species.id} + input_attributes: { taxon_concept_id: create_cites_eu_species.id } }, nomenclature_change_id: @split.id, id: 'inputs' response.should redirect_to( admin_nomenclature_change_split_url( @@ -149,7 +149,7 @@ it 're-renders step' do put :update, nomenclature_change_split: { - input_attributes: {taxon_concept_id: nil} + input_attributes: { taxon_concept_id: nil } }, nomenclature_change_id: @split.id, id: 'inputs' response.should render_template('inputs') end diff --git a/spec/controllers/admin/tags_controller_spec.rb b/spec/controllers/admin/tags_controller_spec.rb index edc1956c93..162a40d9ae 100644 --- a/spec/controllers/admin/tags_controller_spec.rb +++ b/spec/controllers/admin/tags_controller_spec.rb @@ -28,7 +28,7 @@ context "when JSON" do it "responds with 200 when successful" do xhr :put, :update, :format => 'json', :id => preset_tag.id, - :preset_tag => { } + :preset_tag => {} response.should be_success end it "responds with json error when not successful" do diff --git a/spec/controllers/admin/taxon_commons_controller_spec.rb b/spec/controllers/admin/taxon_commons_controller_spec.rb index 7f994ed937..30b05ed69f 100644 --- a/spec/controllers/admin/taxon_commons_controller_spec.rb +++ b/spec/controllers/admin/taxon_commons_controller_spec.rb @@ -10,7 +10,7 @@ describe "XHR GET 'new'" do it "returns http success and renders the new template" do - xhr :get, :new, {:taxon_concept_id => @taxon_concept.id, :format => 'js'} + xhr :get, :new, { :taxon_concept_id => @taxon_concept.id, :format => 'js' } response.should be_success response.should render_template('new') end diff --git a/spec/controllers/admin/taxon_concept_comments_controller_spec.rb b/spec/controllers/admin/taxon_concept_comments_controller_spec.rb index b1e4406634..62e3f630bf 100644 --- a/spec/controllers/admin/taxon_concept_comments_controller_spec.rb +++ b/spec/controllers/admin/taxon_concept_comments_controller_spec.rb @@ -27,7 +27,7 @@ end describe 'PUT update' do - let(:comment){ @taxon_concept.comments.create({note: 'bleh'}) } + let(:comment){ @taxon_concept.comments.create({ note: 'bleh' }) } it 'redirects to index with notice when success' do put :update, id: comment.id, diff --git a/spec/controllers/admin/taxon_concept_references_controller_spec.rb b/spec/controllers/admin/taxon_concept_references_controller_spec.rb index aad177053f..a63aa8d539 100644 --- a/spec/controllers/admin/taxon_concept_references_controller_spec.rb +++ b/spec/controllers/admin/taxon_concept_references_controller_spec.rb @@ -14,7 +14,7 @@ :taxon_concept_id => @taxon_concept.id, :taxon_concept_reference => { :reference_attributes => - {:citation => "My nice literature"} + { :citation => "My nice literature" } } response.should render_template("create") end @@ -62,7 +62,7 @@ :id => @taxon_concept_reference.id, :taxon_concept_reference => { :reference_attributes => - {:citation => "My nice literature"} + { :citation => "My nice literature" } } response.should render_template("create") end @@ -79,7 +79,7 @@ describe "XHR GET 'new'" do it "returns http success and renders the new template" do - xhr :get, :new, {:taxon_concept_id => @taxon_concept.id, :format => 'js'} + xhr :get, :new, { :taxon_concept_id => @taxon_concept.id, :format => 'js' } response.should be_success response.should render_template('new') end diff --git a/spec/controllers/admin/taxon_concepts_controller_spec.rb b/spec/controllers/admin/taxon_concepts_controller_spec.rb index e9dd6d0ef9..6874498f67 100644 --- a/spec/controllers/admin/taxon_concepts_controller_spec.rb +++ b/spec/controllers/admin/taxon_concepts_controller_spec.rb @@ -21,13 +21,13 @@ end it "redirects if 1 result" do get :index, search_params: { - taxonomy: {id: cites_eu.id}, scientific_name: 'Foobarus i' + taxonomy: { id: cites_eu.id }, scientific_name: 'Foobarus i' } response.should redirect_to(admin_taxon_concept_names_path(@taxon)) end it "assigns taxa in taxonomic order" do get :index, search_params: { - taxonomy: {id: cites_eu.id}, scientific_name: 'Foobarus' + taxonomy: { id: cites_eu.id }, scientific_name: 'Foobarus' } assigns(:taxon_concepts).should eq([@taxon.parent, @taxon]) end @@ -50,15 +50,15 @@ response.should render_template("new") end it "renders new_synonym when not successful S" do - xhr :post, :create, taxon_concept: {name_status: 'S'} + xhr :post, :create, taxon_concept: { name_status: 'S' } response.should render_template("new_synonym") end it "renders new_hybrid when not successful H" do - xhr :post, :create, taxon_concept: {name_status: 'H'} + xhr :post, :create, taxon_concept: { name_status: 'H' } response.should render_template("new_hybrid") end it "renders new_synonym when not successful N" do - xhr :post, :create, taxon_concept: {name_status: 'N'} + xhr :post, :create, taxon_concept: { name_status: 'N' } response.should render_template("new_n_name") end end @@ -68,7 +68,7 @@ context "when JSON" do it "responds with 200 when successful" do xhr :put, :update, :format => 'json', :id => taxon_concept.id, - :taxon_concept => { } + :taxon_concept => {} response.should be_success end it "responds with json error when not successful" do @@ -134,7 +134,7 @@ } it "returns properly formatted json" do xhr :get, :autocomplete, :format => 'json', - :search_params => {:scientific_name => 'AAA'} + :search_params => { :scientific_name => 'AAA' } response.body.should have_json_size(1) parse_json(response.body, "0/full_name").should == 'Aaa' end diff --git a/spec/controllers/admin/taxon_listing_changes_controller_spec.rb b/spec/controllers/admin/taxon_listing_changes_controller_spec.rb index b0eb490658..53f7662e93 100644 --- a/spec/controllers/admin/taxon_listing_changes_controller_spec.rb +++ b/spec/controllers/admin/taxon_listing_changes_controller_spec.rb @@ -185,7 +185,7 @@ end end it "renders edit when not successful" do - put :update, :listing_change => {:effective_at => nil}, + put :update, :listing_change => { :effective_at => nil }, :id => @listing_change.id, :taxon_concept_id => @taxon_concept.id, :designation_id => @designation.id diff --git a/spec/controllers/cites_trade/exports_controller_spec.rb b/spec/controllers/cites_trade/exports_controller_spec.rb index 1a0e0a314b..b82475bbd2 100644 --- a/spec/controllers/cites_trade/exports_controller_spec.rb +++ b/spec/controllers/cites_trade/exports_controller_spec.rb @@ -6,7 +6,7 @@ context "raw format" do it "returns count of shipments" do create(:shipment) - get :download, :filters => {:report_type => 'raw'}, :format => :json + get :download, :filters => { :report_type => 'raw' }, :format => :json parse_json(response.body)['total'].should == 1 end end @@ -16,7 +16,7 @@ Trade::ShipmentsExport.any_instance.stub(:public_file_name).and_return('shipments.csv') Trade::TradeDataDownloadLogger.stub(:city_country_from).and_return(["Cambridge", "United Kingdom"]) Trade::TradeDataDownloadLogger.stub(:organization_from).and_return("UNEP-WCMC") - get :download, :filters => {:report_type => :comptab} + get :download, :filters => { :report_type => :comptab } response.content_type.should eq("text/csv") response.headers["Content-Disposition"].should eq("attachment; filename=\"shipments.csv\"") end @@ -40,7 +40,7 @@ Trade::ShipmentsExport.any_instance.stub(:export).and_return(false) end it "redirects to home page" do - get :download, :filters => {:report_type => :comptab} + get :download, :filters => { :report_type => :comptab } expect(response).to redirect_to(cites_trade_root_url) end end diff --git a/spec/controllers/species/exports_controller_spec.rb b/spec/controllers/species/exports_controller_spec.rb index 4d582f165c..b95931b438 100644 --- a/spec/controllers/species/exports_controller_spec.rb +++ b/spec/controllers/species/exports_controller_spec.rb @@ -21,7 +21,7 @@ it 'sets separator to comma with UK ip address' do ActionDispatch::Request.any_instance.stub(:remote_ip).and_return("194.59.188.126") - Sapi::GeoIP.any_instance.stub(:country_and_city).and_return({:country=>"GB", :city=>"Cambridge"}) + Sapi::GeoIP.any_instance.stub(:country_and_city).and_return({ :country=>"GB", :city=>"Cambridge" }) get :download, data_type: 'EuDecisions', :filters => { 'set' => 'current', 'decision_types' => {}, :csv_separator => '' } @@ -32,7 +32,7 @@ it 'sets separator to semicolon with AF ip address' do ActionDispatch::Request.any_instance.stub(:remote_ip).and_return("175.106.59.78") - Sapi::GeoIP.any_instance.stub(:country_and_city).and_return({:country=>"AF", :city=>"Kabul"}) + Sapi::GeoIP.any_instance.stub(:country_and_city).and_return({ :country=>"AF", :city=>"Kabul" }) get :download, data_type: 'EuDecisions', :filters => { 'set' => 'current', 'decision_types' => {}, :csv_separator => '' } diff --git a/spec/controllers/trade/exports_controller_spec.rb b/spec/controllers/trade/exports_controller_spec.rb index 648084245e..b0aebd6af2 100644 --- a/spec/controllers/trade/exports_controller_spec.rb +++ b/spec/controllers/trade/exports_controller_spec.rb @@ -7,7 +7,7 @@ context "raw format" do it "returns count of shipments" do create(:shipment) - get :download, :filters => {:report_type => 'raw'}, :format => :json + get :download, :filters => { :report_type => 'raw' }, :format => :json parse_json(response.body)['total'].should == 1 end it "does not log download information from the admin interface" do @@ -28,7 +28,7 @@ Trade::ShipmentsExport.any_instance.stub(:export).and_return(false) end it "redirects to home page" do - get :download, :filters => {:report_type => :comptab} + get :download, :filters => { :report_type => :comptab } expect(response).to redirect_to(trade_root_url) end end diff --git a/spec/controllers/trade/sandbox_shipments_controller_spec.rb b/spec/controllers/trade/sandbox_shipments_controller_spec.rb index cae77e1442..60f3c55f60 100644 --- a/spec/controllers/trade/sandbox_shipments_controller_spec.rb +++ b/spec/controllers/trade/sandbox_shipments_controller_spec.rb @@ -25,14 +25,14 @@ it "should return success when taxon_name not set" do put :update, :annual_report_upload_id => annual_report_upload.id, :id => @shipment.id, - :sandbox_shipment => {:taxon_name => nil, :accepted_taxon_name => nil}, + :sandbox_shipment => { :taxon_name => nil, :accepted_taxon_name => nil }, :format => :json response.body.should be_blank end it "should return success when taxon_name does not exist" do put :update, :annual_report_upload_id => annual_report_upload.id, :id => @shipment.id, - :sandbox_shipment => {:taxon_name => 'Acipenser foobarus'}, + :sandbox_shipment => { :taxon_name => 'Acipenser foobarus' }, :format => :json response.body.should be_blank end @@ -51,7 +51,7 @@ it "should return success" do post :update_batch, :annual_report_upload_id => annual_report_upload.id, :sandbox_shipments_ids => [@shipment.id], - :updates => {:taxon_name => @genus.full_name}, + :updates => { :taxon_name => @genus.full_name }, :format => :json response.body.should be_blank sandbox_klass.where(:taxon_name => @species.full_name).count(true).should == 0 diff --git a/spec/integration/login_spec.rb b/spec/integration/login_spec.rb index e86f8c69b4..5b39af5304 100644 --- a/spec/integration/login_spec.rb +++ b/spec/integration/login_spec.rb @@ -3,22 +3,22 @@ RSpec.describe "Home page", type: :request do it "redirects Data Manager to admin root path" do user = create(:user, role: User::MANAGER) - post "/users/sign_in", user: {email: user.email, password: user.password} + post "/users/sign_in", user: { email: user.email, password: user.password } assert_redirected_to admin_root_path end it "redirects Data Contributor to admin root path" do user = create(:user, role: User::CONTRIBUTOR) - post "/users/sign_in", user: {email: user.email, password: user.password} + post "/users/sign_in", user: { email: user.email, password: user.password } assert_redirected_to admin_root_path end it "redirects E-library Viewer to public root path" do user = create(:user, role: User::ELIBRARY_USER) - post "/users/sign_in", user: {email: user.email, password: user.password} + post "/users/sign_in", user: { email: user.email, password: user.password } assert_redirected_to root_path end it "redirects API User to public root path" do user = create(:user, role: User::API_USER) - post "/users/sign_in", user: {email: user.email, password: user.password} + post "/users/sign_in", user: { email: user.email, password: user.password } assert_redirected_to root_path end end diff --git a/spec/models/api_request_spec.rb b/spec/models/api_request_spec.rb index 87b60aa649..1a63bdfa60 100644 --- a/spec/models/api_request_spec.rb +++ b/spec/models/api_request_spec.rb @@ -28,7 +28,7 @@ user_id: api_user.id, controller: 'taxon_concepts', action: 'index', - params: {'name' => 'Mammalia'}, + params: { 'name' => 'Mammalia' }, format: 'json', ip: '127.0.0.1', response_status: 200, @@ -39,7 +39,7 @@ user_id: api_user.id, controller: 'taxon_concepts', action: 'index', - params: {'name' => 'Mammalia'}, + params: { 'name' => 'Mammalia' }, format: 'json', ip: '127.0.0.1', response_status: 500, diff --git a/spec/models/checklist/checklist_spec.rb b/spec/models/checklist/checklist_spec.rb index d66bfddfc4..0600d26a88 100644 --- a/spec/models/checklist/checklist_spec.rb +++ b/spec/models/checklist/checklist_spec.rb @@ -20,7 +20,7 @@ :geo_entity_type_id => region_type.id) } let(:summary) { - Checklist::Checklist.summarise_filters({:cites_region_ids => [region.id]}) + Checklist::Checklist.summarise_filters({ :cites_region_ids => [region.id] }) } specify { summary.should == "Results from 1 region" @@ -37,7 +37,7 @@ [region.id, region2.id] } let(:summary) { - Checklist::Checklist.summarise_filters({:cites_region_ids => regions}) + Checklist::Checklist.summarise_filters({ :cites_region_ids => regions }) } specify { summary.should == "Results from 2 regions" diff --git a/spec/models/checklist/higher_taxa_injector_spec.rb b/spec/models/checklist/higher_taxa_injector_spec.rb index 1389b01a23..49bf7afd75 100644 --- a/spec/models/checklist/higher_taxa_injector_spec.rb +++ b/spec/models/checklist/higher_taxa_injector_spec.rb @@ -133,7 +133,7 @@ [ @species1_1_1, @species2_1_1_1_1 - ], {:expand_headers => true} + ], { :expand_headers => true } ) } specify{ @@ -165,7 +165,7 @@ [ @species1_1_1, @species2_1_1 - ], {:skip_ancestor_ids => [@family1.id]} + ], { :skip_ancestor_ids => [@family1.id] } ) } specify{ @@ -195,7 +195,7 @@ Checklist::HigherTaxaInjector.new( [ @species1_1_1 - ], {:skip_ancestor_ids => [@family1.id]} + ], { :skip_ancestor_ids => [@family1.id] } ) } specify{ @@ -207,7 +207,7 @@ Checklist::HigherTaxaInjector.new( [ @species1_1_1 - ], {:expand_headers => true} + ], { :expand_headers => true } ) } specify{ @@ -280,7 +280,7 @@ [ @species1_1_1, @species2_1_1 - ], {:expand_headers => true} + ], { :expand_headers => true } ) } specify{ @@ -342,7 +342,7 @@ [ @order2, @genus2_1 - ], {:expand_headers => true} + ], { :expand_headers => true } ) } specify{ diff --git a/spec/models/checklist/order_spec.rb b/spec/models/checklist/order_spec.rb index dc5a1941fc..c884d115dc 100644 --- a/spec/models/checklist/order_spec.rb +++ b/spec/models/checklist/order_spec.rb @@ -10,7 +10,7 @@ context "when taxonomic order" do context("Plantae") do before(:all) do - @checklist = Checklist::Checklist.new({:output_layout => :taxonomic, :per_page => 100}) + @checklist = Checklist::Checklist.new({ :output_layout => :taxonomic, :per_page => 100 }) @checklist.generate @taxon_concepts = @checklist.plantae end @@ -21,7 +21,7 @@ end context("Animalia") do before(:all) do - @checklist = Checklist::Checklist.new({:output_layout => :taxonomic, :per_page => 100}) + @checklist = Checklist::Checklist.new({ :output_layout => :taxonomic, :per_page => 100 }) @checklist.generate @taxon_concepts = @checklist.animalia end @@ -55,7 +55,7 @@ end context "when alphabetical order" do before(:all) do - @checklist = Checklist::Checklist.new({:output_layout => :alphabetical, :per_page => 100}) + @checklist = Checklist::Checklist.new({ :output_layout => :alphabetical, :per_page => 100 }) @taxon_concepts = @checklist.results end it "should include Falconiformes (Aves) before Psittaciformes (Aves)" do diff --git a/spec/models/dashboard_stats_species_spec.rb b/spec/models/dashboard_stats_species_spec.rb index 1efde04df4..e0d946d658 100644 --- a/spec/models/dashboard_stats_species_spec.rb +++ b/spec/models/dashboard_stats_species_spec.rb @@ -19,10 +19,10 @@ ) } let(:ds_ar){ - DashboardStats.new argentina, {:kingdom => 'Animalia', :trade_limit => 5} + DashboardStats.new argentina, { :kingdom => 'Animalia', :trade_limit => 5 } } let(:ds_gh){ - DashboardStats.new ghana, {:kingdom => 'Animalia', :trade_limit => 5} + DashboardStats.new ghana, { :kingdom => 'Animalia', :trade_limit => 5 } } describe "#new" do diff --git a/spec/models/designation_spec.rb b/spec/models/designation_spec.rb index ce9f939261..45153d87b1 100644 --- a/spec/models/designation_spec.rb +++ b/spec/models/designation_spec.rb @@ -34,14 +34,14 @@ let(:designation){ create(:designation) } specify{ designation.update_attributes( - {:name => 'RULES OF INTERGALACTIC TRADE'} + { :name => 'RULES OF INTERGALACTIC TRADE' } ).should be_true } end context "when updating a protected name" do specify{ cites.update_attributes( - {:name => 'RULES OF INTERGALACTIC TRADE'} + { :name => 'RULES OF INTERGALACTIC TRADE' } ).should be_false } end diff --git a/spec/models/geo_entity_search_spec.rb b/spec/models/geo_entity_search_spec.rb index d769c8878b..478bfcb5c4 100644 --- a/spec/models/geo_entity_search_spec.rb +++ b/spec/models/geo_entity_search_spec.rb @@ -53,12 +53,12 @@ end end context "Checklist regions (1)" do - subject { GeoEntitySearch.new({geo_entity_types_set: '1'}).results } + subject { GeoEntitySearch.new({ geo_entity_types_set: '1' }).results } specify { expect(subject).to include(@asia) } specify { expect(subject.length).to eq(1) } end context "Checklist countries & territories (2)" do - subject { GeoEntitySearch.new({geo_entity_types_set: '2'}).results } + subject { GeoEntitySearch.new({ geo_entity_types_set: '2' }).results } specify { expect(subject).not_to include(@asia) } specify { expect(subject).to include(@burma) } specify { expect(subject).to include(@myanmar) } @@ -67,7 +67,7 @@ end context "Species+ regions, countries & territories (3)" do context "English locale" do - subject { GeoEntitySearch.new({geo_entity_types_set: '3', locale: 'EN'}).results } + subject { GeoEntitySearch.new({ geo_entity_types_set: '3', locale: 'EN' }).results } specify { expect(subject).to include(@asia) } specify { expect(subject).not_to include(@burma) } specify { expect(subject).to include(@myanmar) } @@ -76,7 +76,7 @@ specify { expect(subject.index(@myanmar)).to eq(2) } end context "Spanish locale" do - subject { GeoEntitySearch.new({geo_entity_types_set: '3', locale: 'ES'}).results } + subject { GeoEntitySearch.new({ geo_entity_types_set: '3', locale: 'ES' }).results } specify { expect(subject).to include(@asia) } specify { expect(subject).not_to include(@burma) } specify { expect(subject).to include(@myanmar) } @@ -86,7 +86,7 @@ end end context "Trade countries, territories and trade entities (4)" do - subject { GeoEntitySearch.new({geo_entity_types_set: '4'}).results } + subject { GeoEntitySearch.new({ geo_entity_types_set: '4' }).results } specify { expect(subject).not_to include(@asia) } specify { expect(subject).to include(@burma) } specify { expect(subject).to include(@myanmar) } @@ -105,10 +105,10 @@ iso_code2: 'BU' ) end - subject{ GeoEntitySearch.new({geo_entity_types_set: '3'}) } + subject{ GeoEntitySearch.new({ geo_entity_types_set: '3' }) } specify do subject.cached_results - @burma.update_attributes({is_current: false}) + @burma.update_attributes({ is_current: false }) expect(subject.cached_results).not_to include(@burma) end end diff --git a/spec/models/nomenclature_change/lump_spec.rb b/spec/models/nomenclature_change/lump_spec.rb index 098995b6d6..3af9748621 100644 --- a/spec/models/nomenclature_change/lump_spec.rb +++ b/spec/models/nomenclature_change/lump_spec.rb @@ -55,7 +55,7 @@ let(:lump){ build( :nomenclature_change_lump, :status => NomenclatureChange::Lump::SUBMITTED, - :inputs_attributes => {0 => {:taxon_concept_id => create_cites_eu_subspecies.id}} + :inputs_attributes => { 0 => { :taxon_concept_id => create_cites_eu_subspecies.id } } ) } specify { expect(lump).to have(1).errors_on(:inputs) } diff --git a/spec/models/nomenclature_change/shared/split_definitions.rb b/spec/models/nomenclature_change/shared/split_definitions.rb index 52a9619716..597baa77e3 100644 --- a/spec/models/nomenclature_change/shared/split_definitions.rb +++ b/spec/models/nomenclature_change/shared/split_definitions.rb @@ -71,7 +71,7 @@ } let(:split_with_input_and_outputs_status_change){ create(:nomenclature_change_split, - input_attributes: {taxon_concept_id: input_species.id}, + input_attributes: { taxon_concept_id: input_species.id }, outputs_attributes: { 0 => { taxon_concept_id: output_species1.id }, 1 => { @@ -85,7 +85,7 @@ } let(:split_with_input_and_outputs_name_change){ create(:nomenclature_change_split, - input_attributes: {taxon_concept_id: input_species.id}, + input_attributes: { taxon_concept_id: input_species.id }, outputs_attributes: { 0 => { taxon_concept_id: output_species1.id }, 1 => { @@ -121,7 +121,7 @@ ) nc = create(:nomenclature_change_split, - input_attributes: {taxon_concept_id: input_species.id}, + input_attributes: { taxon_concept_id: input_species.id }, outputs_attributes: { 0 => { taxon_concept_id: output_species1.id }, 1 => { taxon_concept_id: input_species.id } diff --git a/spec/models/nomenclature_change/split_spec.rb b/spec/models/nomenclature_change/split_spec.rb index b226ef1a4c..40fad079f5 100644 --- a/spec/models/nomenclature_change/split_spec.rb +++ b/spec/models/nomenclature_change/split_spec.rb @@ -56,7 +56,7 @@ let(:split){ build(:nomenclature_change_split, :status => NomenclatureChange::Split::OUTPUTS, - :input_attributes => {:taxon_concept_id => create_cites_eu_species.id}, + :input_attributes => { :taxon_concept_id => create_cites_eu_species.id }, :outputs_attributes => { 0 => { :taxon_concept_id => create_cites_eu_subspecies.id, diff --git a/spec/models/species/invisible_subspecies_search_spec.rb b/spec/models/species/invisible_subspecies_search_spec.rb index a19a132f4e..faaf3952e1 100644 --- a/spec/models/species/invisible_subspecies_search_spec.rb +++ b/spec/models/species/invisible_subspecies_search_spec.rb @@ -4,7 +4,7 @@ describe :results do context "when searching by scientific name" do context "when subspecies never listed" do - subject { Species::Search.new({:taxon_concept_query => 'amazona festiva festiva'}).results } + subject { Species::Search.new({ :taxon_concept_query => 'amazona festiva festiva' }).results } specify { subject.should_not include(@subspecies2_2_2_1) } specify { subject.should include(@species2_2_2) } end diff --git a/spec/models/species/search_spec.rb b/spec/models/species/search_spec.rb index 5d2a8be71b..d1a8519c4b 100644 --- a/spec/models/species/search_spec.rb +++ b/spec/models/species/search_spec.rb @@ -4,19 +4,19 @@ describe :results do context "when searching by scientific name" do context "when regular query" do - subject { Species::Search.new({:taxon_concept_query => 'canis'}).results } + subject { Species::Search.new({ :taxon_concept_query => 'canis' }).results } specify { subject.should include(@species) } end context "when malicious query" do - subject { Species::Search.new({:taxon_concept_query => 'canis\''}).results } + subject { Species::Search.new({ :taxon_concept_query => 'canis\'' }).results } specify { subject.should be_empty } end context "when leading whitespace" do - subject { Species::Search.new({:taxon_concept_query => ' canis'}).results } + subject { Species::Search.new({ :taxon_concept_query => ' canis' }).results } specify { subject.should include(@species) } end context "when trailing whitespace" do - subject { Species::Search.new({:taxon_concept_query => 'canis '}).results } + subject { Species::Search.new({ :taxon_concept_query => 'canis ' }).results } specify { subject.should include(@species) } end end diff --git a/spec/models/species/visible_subspecies_search_spec.rb b/spec/models/species/visible_subspecies_search_spec.rb index 97bcb091eb..524f456f52 100644 --- a/spec/models/species/visible_subspecies_search_spec.rb +++ b/spec/models/species/visible_subspecies_search_spec.rb @@ -4,7 +4,7 @@ describe :results do context "when searching by scientific name" do context "when subspecies previously listed " do - subject { Species::Search.new({:taxon_concept_query => 'canis lupus'}).results } + subject { Species::Search.new({ :taxon_concept_query => 'canis lupus' }).results } specify { subject.should include(@subspecies) } end end diff --git a/spec/models/taxon_concept_prefix_matcher_spec.rb b/spec/models/taxon_concept_prefix_matcher_spec.rb index 6ad9a277a8..83c5ae29c9 100644 --- a/spec/models/taxon_concept_prefix_matcher_spec.rb +++ b/spec/models/taxon_concept_prefix_matcher_spec.rb @@ -47,7 +47,7 @@ } context "when name status not specified" do let(:matcher_params){ - SearchParams.new(:taxonomy => {:id => taxonomy.id}, :scientific_name => 'Ab') + SearchParams.new(:taxonomy => { :id => taxonomy.id }, :scientific_name => 'Ab') } let(:matcher){ TaxonConceptPrefixMatcher.new matcher_params } specify{ matcher.taxon_concepts.should include(taxon_concept4) } @@ -56,7 +56,7 @@ context "when name status H" do let(:matcher_params){ - SearchParams.new(:taxonomy => {:id => taxonomy.id}, :scientific_name => 'Ab', :name_status => 'H') + SearchParams.new(:taxonomy => { :id => taxonomy.id }, :scientific_name => 'Ab', :name_status => 'H') } let(:matcher){ TaxonConceptPrefixMatcher.new matcher_params } specify{ matcher.taxon_concepts.should_not include(taxon_concept4) } @@ -66,8 +66,8 @@ context "when rank scope applied" do let(:parent_matcher_params){ SearchParams.new( - :taxonomy => {:id => taxonomy.id}, - :rank => {:id => taxon_concept4.rank_id, :scope => :parent}, + :taxonomy => { :id => taxonomy.id }, + :rank => { :id => taxon_concept4.rank_id, :scope => :parent }, :scientific_name => 'A' ) } @@ -82,8 +82,8 @@ let(:ancestor_matcher_params){ SearchParams.new( - :taxonomy => {:id => taxonomy.id}, - :rank => {:id => taxon_concept4.rank_id, :scope => :ancestors}, + :taxonomy => { :id => taxonomy.id }, + :rank => { :id => taxon_concept4.rank_id, :scope => :ancestors }, :scientific_name => 'AAA' ) } @@ -98,8 +98,8 @@ let(:self_and_ancestor_matcher_params){ SearchParams.new( - :taxonomy => {:id => taxonomy.id}, - :rank => {:id => taxon_concept4.rank_id, :scope => :self_and_ancestors}, + :taxonomy => { :id => taxonomy.id }, + :rank => { :id => taxon_concept4.rank_id, :scope => :self_and_ancestors }, :scientific_name => 'AAA' ) } @@ -116,8 +116,8 @@ context "when taxon concept scope applied" do let(:ancestor_matcher_params){ SearchParams.new( - :taxonomy => {:id => taxonomy.id}, - :taxon_concept => {:id => taxon_concept4.id, :scope => :ancestors}, + :taxonomy => { :id => taxonomy.id }, + :taxon_concept => { :id => taxon_concept4.id, :scope => :ancestors }, :scientific_name => 'A' ) } @@ -132,8 +132,8 @@ let(:descendant_matcher_params){ SearchParams.new( - :taxonomy => {:id => taxonomy.id}, - :taxon_concept => {:id => taxon_concept2.id, :scope => :descendants}, + :taxonomy => { :id => taxonomy.id }, + :taxon_concept => { :id => taxon_concept2.id, :scope => :descendants }, :scientific_name => 'A' ) } diff --git a/spec/models/taxonomy_spec.rb b/spec/models/taxonomy_spec.rb index a57ea985cb..3d53e0577d 100644 --- a/spec/models/taxonomy_spec.rb +++ b/spec/models/taxonomy_spec.rb @@ -31,10 +31,10 @@ describe :update do context "when updating a non-protected name" do let(:taxonomy){ create(:taxonomy) } - specify{ taxonomy.update_attributes({:name => 'WORLD OF LOLCATS'}).should be_true } + specify{ taxonomy.update_attributes({ :name => 'WORLD OF LOLCATS' }).should be_true } end context "when updating a protected name" do - specify{ cites_eu.update_attributes({:name => 'WORLD OF LOLCATS'}).should be_false } + specify{ cites_eu.update_attributes({ :name => 'WORLD OF LOLCATS' }).should be_false } end end describe :destroy do diff --git a/spec/models/trade/filter_spec.rb b/spec/models/trade/filter_spec.rb index 8ae8bd3913..2d766a7888 100644 --- a/spec/models/trade/filter_spec.rb +++ b/spec/models/trade/filter_spec.rb @@ -123,47 +123,47 @@ end end context "when searching by appendices" do - subject { Trade::Filter.new({:appendices => ['I']}).results } + subject { Trade::Filter.new({ :appendices => ['I'] }).results } specify { subject.should include(@shipment1) } specify { subject.length.should == 1 } end context "when searching for terms_ids" do - subject { Trade::Filter.new({:terms_ids => [@term_cav.id]}).results } + subject { Trade::Filter.new({ :terms_ids => [@term_cav.id] }).results } specify { subject.should include(@shipment1) } specify { subject.length.should == 2 } end context "when searching for units_ids" do - subject { Trade::Filter.new({:units_ids => [@unit.id]}).results } + subject { Trade::Filter.new({ :units_ids => [@unit.id] }).results } specify { subject.should include(@shipment1) } specify { subject.length.should == 2 } end context "when searching for purposes_ids" do - subject { Trade::Filter.new({:purposes_ids => [@purpose.id]}).results } + subject { Trade::Filter.new({ :purposes_ids => [@purpose.id] }).results } specify { subject.should include(@shipment1) } specify { subject.length.should == 6 } end context "when searching for sources_ids" do context "when code" do - subject { Trade::Filter.new({:sources_ids => [@source.id]}).results } + subject { Trade::Filter.new({ :sources_ids => [@source.id] }).results } specify { subject.should include(@shipment1) } specify { subject.length.should == 1 } end context "when blank" do - subject { Trade::Filter.new({:source_blank => true}).results } + subject { Trade::Filter.new({ :source_blank => true }).results } specify { subject.should include(@shipment6) } specify { subject.length.should == 1 } end context "when both code and blank" do - subject { Trade::Filter.new({:sources_ids => [@source.id], :source_blank => true}).results } + subject { Trade::Filter.new({ :sources_ids => [@source.id], :source_blank => true }).results } specify { subject.should include(@shipment1) } specify { subject.length.should == 2 } end context "when wild" do - subject { Trade::Filter.new({:sources_ids => [@source_wild.id], :source_blank => true}).results } + subject { Trade::Filter.new({ :sources_ids => [@source_wild.id], :source_blank => true }).results } specify { subject.should include(@shipment3) } specify { subject.length.should == 5 } end @@ -177,40 +177,40 @@ end context "when searching for importers_ids" do - subject { Trade::Filter.new({:importers_ids => [@argentina.id]}).results } + subject { Trade::Filter.new({ :importers_ids => [@argentina.id] }).results } specify { subject.should include(@shipment1) } specify { subject.length.should == 1 } end context "when searching for exporters_ids" do - subject { Trade::Filter.new({:exporters_ids => [@argentina.id]}).results } + subject { Trade::Filter.new({ :exporters_ids => [@argentina.id] }).results } specify { subject.should include(@shipment2) } specify { subject.length.should == 5 } end context "when searching for countries_of_origin_ids" do - subject { Trade::Filter.new({:countries_of_origin_ids => [@argentina.id]}).results } + subject { Trade::Filter.new({ :countries_of_origin_ids => [@argentina.id] }).results } specify { subject.should include(@shipment1) } specify { subject.length.should == 1 } end context "when searching by year" do context "when time range specified" do - subject { Trade::Filter.new({:time_range_start => 2013, :time_range_end => 2015}).results } + subject { Trade::Filter.new({ :time_range_start => 2013, :time_range_end => 2015 }).results } specify { subject.should include(@shipment2) } specify { subject.length.should == 5 } end context "when time range specified incorrectly" do - subject { Trade::Filter.new({:time_range_start => 2013, :time_range_end => 2012}).results } + subject { Trade::Filter.new({ :time_range_start => 2013, :time_range_end => 2012 }).results } specify { subject.length.should == 0 } end context "when time range start specified" do - subject { Trade::Filter.new({:time_range_start => 2012}).results } + subject { Trade::Filter.new({ :time_range_start => 2012 }).results } specify { subject.should include(@shipment1) } specify { subject.length.should == 6 } end context "when time range end specified" do - subject { Trade::Filter.new({:time_range_end => 2012}).results } + subject { Trade::Filter.new({ :time_range_end => 2012 }).results } specify { subject.should include(@shipment1) } specify { subject.length.should == 1 } end @@ -218,18 +218,18 @@ context "when searching by reporter_type" do context "when reporter type is not I or E" do - subject { Trade::Filter.new({:internal => true, :reporter_type => 'K'}).results } + subject { Trade::Filter.new({ :internal => true, :reporter_type => 'K' }).results } specify { subject.length.should == 6 } end context "when reporter type is I" do - subject { Trade::Filter.new({:internal => true, :reporter_type => 'I'}).results } + subject { Trade::Filter.new({ :internal => true, :reporter_type => 'I' }).results } specify { subject.should include(@shipment2) } specify { subject.length.should == 5 } end context "when reporter type is E" do - subject { Trade::Filter.new({:internal => true, :reporter_type => 'E'}).results } + subject { Trade::Filter.new({ :internal => true, :reporter_type => 'E' }).results } specify { subject.should include(@shipment1) } specify { subject.length.should == 1 } end @@ -237,23 +237,23 @@ context "when searching by permit" do context "when permit number" do - subject { Trade::Filter.new({:internal => true, :permits_ids => [@export_permit1.id]}).results } + subject { Trade::Filter.new({ :internal => true, :permits_ids => [@export_permit1.id] }).results } specify { subject.should include(@shipment1) } specify { subject.length.should == 1 } end context "when blank" do - subject { Trade::Filter.new({:internal => true, :permit_blank => true}).results } + subject { Trade::Filter.new({ :internal => true, :permit_blank => true }).results } specify { subject.should include(@shipment2) } specify { subject.length.should == 5 } end context "when both permit number and blank" do - subject { Trade::Filter.new({:internal => true, :permits_ids => [@export_permit1.id], :permit_blank => true}).results } + subject { Trade::Filter.new({ :internal => true, :permits_ids => [@export_permit1.id], :permit_blank => true }).results } specify { subject.length.should == 6 } end end context "when searching by quantity" do - subject { Trade::Filter.new({:internal => true, :quantity => 20}).results } + subject { Trade::Filter.new({ :internal => true, :quantity => 20 }).results } specify { subject.should include(@shipment1) } specify { subject.length.should == 1 } end @@ -261,17 +261,17 @@ describe :total_cnt do context "when none matches" do - subject { Trade::Filter.new({:appendices => ['III']}) } + subject { Trade::Filter.new({ :appendices => ['III'] }) } specify { subject.total_cnt.should == 0 } end context "when one matches" do - subject { Trade::Filter.new({:appendices => ['I']}) } + subject { Trade::Filter.new({ :appendices => ['I'] }) } specify { subject.total_cnt.should == 1 } end context "when two match" do - subject { Trade::Filter.new({:purposes_ids => [@purpose.id]}) } + subject { Trade::Filter.new({ :purposes_ids => [@purpose.id] }) } specify { subject.total_cnt.should == 6 } end diff --git a/spec/models/trade/permit_matcher_spec.rb b/spec/models/trade/permit_matcher_spec.rb index a5840abdf6..221e04ad07 100644 --- a/spec/models/trade/permit_matcher_spec.rb +++ b/spec/models/trade/permit_matcher_spec.rb @@ -6,23 +6,23 @@ @permit = create(:permit, :number => '006AAA') end context "when regular query" do - subject { Trade::PermitMatcher.new({:permit_query => '006'}).results } + subject { Trade::PermitMatcher.new({ :permit_query => '006' }).results } specify { subject.should include(@permit) } end context "when wildcard query" do - subject { Trade::PermitMatcher.new({:permit_query => '%AA'}).results } + subject { Trade::PermitMatcher.new({ :permit_query => '%AA' }).results } specify { subject.should include(@permit) } end context "when malicious query" do - subject { Trade::PermitMatcher.new({:permit_query => '006\''}).results } + subject { Trade::PermitMatcher.new({ :permit_query => '006\'' }).results } specify { subject.should be_empty } end context "when leading whitespace" do - subject { Trade::PermitMatcher.new({:permit_query => ' 006'}).results } + subject { Trade::PermitMatcher.new({ :permit_query => ' 006' }).results } specify { subject.should include(@permit) } end context "when trailing whitespace" do - subject { Trade::PermitMatcher.new({:permit_query => '006AAA '}).results } + subject { Trade::PermitMatcher.new({ :permit_query => '006AAA ' }).results } specify { subject.should include(@permit) } end end diff --git a/spec/models/trade/sandbox_template_spec.rb b/spec/models/trade/sandbox_template_spec.rb index 9ccc0843f9..e2341c4eb8 100644 --- a/spec/models/trade/sandbox_template_spec.rb +++ b/spec/models/trade/sandbox_template_spec.rb @@ -66,7 +66,7 @@ end specify { sandbox_klass.update_batch( - {:taxon_name => 'Canis aureus'}, + { :taxon_name => 'Canis aureus' }, [@shipment1.id] ) @shipment1.reload.taxon_concept_id.should == canis_aureus.id diff --git a/spec/models/trade_restriction_spec.rb b/spec/models/trade_restriction_spec.rb index 8dbca23e72..f2b0b23afe 100644 --- a/spec/models/trade_restriction_spec.rb +++ b/spec/models/trade_restriction_spec.rb @@ -70,11 +70,11 @@ result.should =~ [@quota1, @quota2, @quota3, @quota4] end it 'should return quota1 and quota3 if geo_entities filter set to @geo_entity1' do - result = Quota.filter_geo_entities({"geo_entities_ids" => [@geo_entity1.id]}) + result = Quota.filter_geo_entities({ "geo_entities_ids" => [@geo_entity1.id] }) result.should =~ [@quota1, @quota3] end it 'should return quota1, quota3, and quota4 if geo_entities filter set to @geo_entity1 and @geo_entity3' do - result = Quota.filter_geo_entities({"geo_entities_ids" => [@geo_entity1.id, @geo_entity3.id]}) + result = Quota.filter_geo_entities({ "geo_entities_ids" => [@geo_entity1.id, @geo_entity3.id] }) result.should =~ [@quota1, @quota3, @quota4] end end @@ -92,11 +92,11 @@ result.should =~ [@quota1, @quota2, @quota3, @quota4] end it 'should return quota1 and quota3 if years filter set to 2012' do - result = Quota.filter_years({"years" => [2012]}) + result = Quota.filter_years({ "years" => [2012] }) result.should =~ [@quota1, @quota3] end it 'should return quota1, quota3, and quota4 if years filter set to 2012 and 2013' do - result = Quota.filter_years({"years" => [2012, 2013]}) + result = Quota.filter_years({ "years" => [2012, 2013] }) result.should =~ [@quota1, @quota3, @quota4] end end diff --git a/spec/shared/uroplatus.rb b/spec/shared/uroplatus.rb index fa00c69f9d..2768227460 100644 --- a/spec/shared/uroplatus.rb +++ b/spec/shared/uroplatus.rb @@ -12,7 +12,7 @@ @genus = create_cites_eu_genus( :taxon_name => create(:taxon_name, :scientific_name => 'Uroplatus'), :parent => @family, - :data => {:usr_no_std_ref => true} + :data => { :usr_no_std_ref => true } ) @species1 = create_cites_eu_species( :taxon_name => create(:taxon_name, :scientific_name => 'Alluaudi'), diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 27cb0a2ce7..4b187004eb 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -54,7 +54,7 @@ config.include SapiSpec::Helpers config.before(:all) do - DatabaseCleaner.clean_with(:deletion, {:cache_tables => false}) + DatabaseCleaner.clean_with(:deletion, { :cache_tables => false }) @user = create(:user) @user.make_current end @@ -64,7 +64,7 @@ end config.before(:each, :drops_tables => true) do - DatabaseCleaner.strategy = :deletion, {:cache_tables => false} + DatabaseCleaner.strategy = :deletion, { :cache_tables => false } ActiveRecord::Base.connection.execute('SELECT * FROM drop_trade_sandboxes()') end diff --git a/spec/support/sapi_helpers.rb b/spec/support/sapi_helpers.rb index 1ae71be178..d51fe57bdc 100644 --- a/spec/support/sapi_helpers.rb +++ b/spec/support/sapi_helpers.rb @@ -248,7 +248,7 @@ def create_cites_eu_animal_species(options = {}) create_cites_eu_species( parent: create_cites_eu_genus( parent: create_cites_eu_family( - parent: create_cites_eu_order(options.merge({parent: cites_eu_mammalia})) + parent: create_cites_eu_order(options.merge({ parent: cites_eu_mammalia })) ) ) ) @@ -258,7 +258,7 @@ def create_cites_eu_plant_species(options = {}) create_cites_eu_species( parent: create_cites_eu_genus( parent: create_cites_eu_family( - parent: create_cites_eu_order(options.merge({parent: cites_eu_plantae})) + parent: create_cites_eu_order(options.merge({ parent: cites_eu_plantae })) ) ) ) @@ -268,13 +268,13 @@ def create_cites_eu_plant_species(options = {}) define_method "create_#{rank.downcase}" do |options = {}| create( :taxon_concept, - options.merge({rank: create(:rank, name: rank)}) + options.merge({ rank: create(:rank, name: rank) }) ) end define_method "build_#{rank.downcase}" do |options = {}| build( :taxon_concept, - options.merge({rank: create(:rank, name: rank)}) + options.merge({ rank: create(:rank, name: rank) }) ) end define_method "create_cites_eu_#{rank.downcase}" do |options = {}| @@ -320,13 +320,13 @@ def create_cites_eu_plant_species(options = {}) define_method "create_#{cites_event_type}" do |options = {}| create( cites_event_type, - options.merge({:designation => cites}) + options.merge({ :designation => cites }) ) end define_method "build_#{cites_event_type}" do |options = {}| build( cites_event_type, - options.merge({:designation => cites}) + options.merge({ :designation => cites }) ) end end @@ -335,13 +335,13 @@ def create_cites_eu_plant_species(options = {}) define_method "create_#{eu_event_type}" do |options = {}| create( eu_event_type, - options.merge({:designation => eu}) + options.merge({ :designation => eu }) ) end define_method "build_#{eu_event_type}" do |options = {}| build( eu_event_type, - options.merge({:designation => eu}) + options.merge({ :designation => eu }) ) end end diff --git a/spec/workers/quotas_copy_worker_spec.rb b/spec/workers/quotas_copy_worker_spec.rb index 1819a398ca..a1811c45c6 100644 --- a/spec/workers/quotas_copy_worker_spec.rb +++ b/spec/workers/quotas_copy_worker_spec.rb @@ -240,7 +240,7 @@ :geo_entity_id => geo_entity2.id, :taxon_concept_id => tc.id, :notes => "Derp di doo wildlife") - QuotasCopyWorker.new.perform(job_defaults.merge({"url" => 'http://myurl.co.uk'})) + QuotasCopyWorker.new.perform(job_defaults.merge({ "url" => 'http://myurl.co.uk' })) end specify { Quota.count(true).should == 4 } specify { Quota.where(:is_current => true).count(true).should == 2 } From 4d0f0f3bfe4e97d33d4933f68be30d8258cd9f7e Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 1 Jul 2016 09:47:56 +0100 Subject: [PATCH 325/365] enabled Style/SpaceAroundOperators --- .rubocop.yml | 4 ++++ .rubocop_todo.yml | 6 ------ app/controllers/admin/iucn_mappings_controller.rb | 2 +- app/controllers/admin/taxonomies_controller.rb | 2 +- app/controllers/checklist/timelines_controller.rb | 2 +- .../trade/annual_report_uploads_controller.rb | 2 +- app/helpers/admin/trade_codes_helper.rb | 2 +- app/models/checklist/column_display_name_mapping.rb | 2 +- app/models/checklist/higher_taxa_injector.rb | 4 ++-- app/models/cms_mapping_manager.rb | 2 +- app/models/common_name.rb | 2 +- app/models/dashboard_stats.rb | 4 ++-- app/models/document.rb | 4 ++-- app/models/geo_entity.rb | 4 ++-- app/models/m_taxon_concept.rb | 2 +- ...ept_filter_by_scientific_name_with_descendants.rb | 2 +- .../nomenclature_change/cascading_notes_processor.rb | 2 +- app/models/nomenclature_change/output.rb | 2 +- app/models/rank.rb | 2 +- app/models/species/restrictions_export.rb | 2 +- app/models/taxon_concept_reference.rb | 2 +- app/models/trade/shipments_gross_exports_export.rb | 4 ++-- app/models/trade_restriction.rb | 6 +++--- ...738_change_multi_permit_number_columns_to_text.rb | 2 +- ...reate_unique_index_on_taxon_concept_references.rb | 2 +- .../20150820121520_add_indexes_to_document_tables.rb | 4 ++-- lib/capistrano/tasks/config.rake | 2 +- lib/modules/csv_exportable.rb | 2 +- lib/modules/dashboard_stats_cache.rb | 2 +- lib/modules/latex_to_pdf.rb | 12 ++++++------ lib/scripts/get_listed_species_per_country.rb | 6 +++--- lib/tasks/elibrary/citations_cop_importer.rb | 2 +- lib/tasks/import_checklist_translations.rake | 4 ++-- lib/tasks/import_cites_listings.rake | 2 +- lib/tasks/import_cites_parties.rake | 2 +- lib/tasks/import_cites_regions.rake | 2 +- lib/tasks/import_cms_listings.rake | 2 +- lib/tasks/import_eu_listings.rake | 2 +- lib/tasks/import_events.rake | 2 +- lib/tasks/import_hash_annotations.rake | 2 +- lib/tasks/import_trade_names.rake | 10 +++++----- old_cap/deploy/production.rb | 2 +- old_cap/deploy/staging.rb | 2 +- .../admin/taxon_listing_changes_controller_spec.rb | 8 ++++---- spec/controllers/species/exports_controller_spec.rb | 4 ++-- spec/factories/common_names.rb | 4 ++-- spec/factories/distributions.rb | 2 +- spec/factories/trade.rb | 8 ++++---- spec/workers/quotas_copy_worker_spec.rb | 2 +- 49 files changed, 79 insertions(+), 81 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 47a5276e11..fbe558eada 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -77,3 +77,7 @@ Style/IndentationWidth: Style/SpaceInsideHashLiteralBraces: EnforcedStyle: space EnforcedStyleForEmptyBraces: no_space + +# Configuration parameters: AllowForAlignment. +Style/SpaceAroundOperators: + AllowForAlignment: true diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index b512db593f..a85416fc7d 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -605,12 +605,6 @@ Style/SignalException: Style/SingleLineMethods: Enabled: false -# Offense count: 93 -# Cop supports --auto-correct. -# Configuration parameters: AllowForAlignment. -Style/SpaceAroundOperators: - Enabled: false - # Offense count: 1018 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. diff --git a/app/controllers/admin/iucn_mappings_controller.rb b/app/controllers/admin/iucn_mappings_controller.rb index a32b5ca22a..8d6f41d4f5 100644 --- a/app/controllers/admin/iucn_mappings_controller.rb +++ b/app/controllers/admin/iucn_mappings_controller.rb @@ -19,7 +19,7 @@ def index def collection @iucn_mappings ||= end_of_association_chain.order(:taxon_concept_id). - page(params[:page]).filter(params[:show]||"ALL").includes(:taxon_concept). + page(params[:page]).filter(params[:show] || "ALL").includes(:taxon_concept). includes(:accepted_name) end end diff --git a/app/controllers/admin/taxonomies_controller.rb b/app/controllers/admin/taxonomies_controller.rb index dbd827788f..4f30a36493 100644 --- a/app/controllers/admin/taxonomies_controller.rb +++ b/app/controllers/admin/taxonomies_controller.rb @@ -4,7 +4,7 @@ class Admin::TaxonomiesController < Admin::StandardAuthorizationController def index index! do |format| format.json { - render :text =>end_of_association_chain.order(:name). + render :text => end_of_association_chain.order(:name). select([:id, :name]).map{ |d| { :value => d.id, :text => d.name } }.to_json } end diff --git a/app/controllers/checklist/timelines_controller.rb b/app/controllers/checklist/timelines_controller.rb index f7464cef8f..c9fff35a4e 100644 --- a/app/controllers/checklist/timelines_controller.rb +++ b/app/controllers/checklist/timelines_controller.rb @@ -7,7 +7,7 @@ def index tc = MTaxonConcept.find_by_id(tc_id) Checklist::TimelinesForTaxonConcept.new(tc) unless tc.nil? end - render :json => res, :each_serializer => Checklist::TimelinesForTaxonConceptSerializer + render :json => res, :each_serializer => Checklist::TimelinesForTaxonConceptSerializer end private diff --git a/app/controllers/trade/annual_report_uploads_controller.rb b/app/controllers/trade/annual_report_uploads_controller.rb index db31b925cc..de0bf4df04 100644 --- a/app/controllers/trade/annual_report_uploads_controller.rb +++ b/app/controllers/trade/annual_report_uploads_controller.rb @@ -27,7 +27,7 @@ def create def submit @annual_report_upload = Trade::AnnualReportUpload.find(params[:id]) if @annual_report_upload.submit - render :json => @annual_report_upload, :status =>:ok, + render :json => @annual_report_upload, :status => :ok, :serializer => Trade::ShowAnnualReportUploadSerializer else render :json => { "errors" => @annual_report_upload.errors }, diff --git a/app/helpers/admin/trade_codes_helper.rb b/app/helpers/admin/trade_codes_helper.rb index 4133d62c1c..f62d45abb7 100644 --- a/app/helpers/admin/trade_codes_helper.rb +++ b/app/helpers/admin/trade_codes_helper.rb @@ -2,7 +2,7 @@ module Admin::TradeCodesHelper def sub_nav content_tag(:ul, :class => "nav nav-pills") do ["purposes", "sources", "terms", "units"].each do |subclass| - concat(content_tag(:li, :class=> "#{ controller_name == subclass ? 'active' : '' }") do + concat(content_tag(:li, :class => "#{ controller_name == subclass ? 'active' : '' }") do link_to subclass.titleize, send("admin_#{subclass}_path") end) end diff --git a/app/models/checklist/column_display_name_mapping.rb b/app/models/checklist/column_display_name_mapping.rb index e6bf461217..9c84022baf 100644 --- a/app/models/checklist/column_display_name_mapping.rb +++ b/app/models/checklist/column_display_name_mapping.rb @@ -31,7 +31,7 @@ module Checklist::ColumnDisplayNameMapping :all_distribution => 'All_DistributionFullNames', :native_distribution => 'NativeDistributionFullNames', :introduced_distribution => 'Introduced_Distribution', - :introduced_uncertain_distribution =>'Introduced(?)_Distribution', + :introduced_uncertain_distribution => 'Introduced(?)_Distribution', :reintroduced_distribution => 'Reintroduced_Distribution', :extinct_distribution => 'Extinct_Distribution', :extinct_uncertain_distribution => 'Extinct(?)_Distribution', diff --git a/app/models/checklist/higher_taxa_injector.rb b/app/models/checklist/higher_taxa_injector.rb index 7e6fd131f8..8958bd6bef 100644 --- a/app/models/checklist/higher_taxa_injector.rb +++ b/app/models/checklist/higher_taxa_injector.rb @@ -26,7 +26,7 @@ def initialize(taxon_concepts, options = {}) def run res = [] @taxon_concepts.each_with_index do |tc, i| - prev_item = (i > 0 ? @taxon_concepts[i-1] : nil) + prev_item = (i > 0 ? @taxon_concepts[i - 1] : nil) res += higher_taxa_headers(prev_item, tc).map do |ht| Checklist::HigherTaxaItem.new(ht) end @@ -42,7 +42,7 @@ def run_summary current_higher_taxon = nil current_higher_taxon_children_ids = [] @taxon_concepts.each_with_index do |tc, i| - prev_item = (i > 0 ? @taxon_concepts[i-1] : nil) + prev_item = (i > 0 ? @taxon_concepts[i - 1] : nil) higher_taxon = higher_taxa_headers(prev_item, tc).first if higher_taxon res.push({ diff --git a/app/models/cms_mapping_manager.rb b/app/models/cms_mapping_manager.rb index c1cce8d7d3..083ee3ce33 100644 --- a/app/models/cms_mapping_manager.rb +++ b/app/models/cms_mapping_manager.rb @@ -22,7 +22,7 @@ def sync end def analyse(mapping) - url = URI.escape(@show_url+mapping.cms_taxon_name) + url = URI.escape(@show_url + mapping.cms_taxon_name) species = JSON.parse(RestClient.get(url)).first if species puts "setting mapping details for #{mapping.cms_taxon_name}" diff --git a/app/models/common_name.rb b/app/models/common_name.rb index b0bd66c2a8..c68375dc55 100644 --- a/app/models/common_name.rb +++ b/app/models/common_name.rb @@ -22,7 +22,7 @@ class CommonName < ActiveRecord::Base def self.english_to_pdf(common_name) words = common_name.split return common_name if words.size == 1 - words.last + ", " + common_name.chomp(" "+words.last) + words.last + ", " + common_name.chomp(" " + words.last) end #attribute_accessor to convert postgresql "t" or "f" to a Ruby boolean diff --git a/app/models/dashboard_stats.rb b/app/models/dashboard_stats.rb index 2991335f2e..3702ca194a 100644 --- a/app/models/dashboard_stats.rb +++ b/app/models/dashboard_stats.rb @@ -9,8 +9,8 @@ def initialize(geo_entity, options) @geo_entity = geo_entity @kingdom = options[:kingdom] || 'Animalia' @trade_limit = options[:trade_limit] - @time_range_start = options[:time_range_start] || (Time.now.year-7) #2007 - @time_range_end = options[:time_range_end] || (Time.now.year-2) #2012 + @time_range_start = options[:time_range_start] || (Time.now.year - 7) #2007 + @time_range_end = options[:time_range_end] || (Time.now.year - 2) #2012 end def species diff --git a/app/models/document.rb b/app/models/document.rb index 23b058a400..1978dfdb4a 100644 --- a/app/models/document.rb +++ b/app/models/document.rb @@ -98,11 +98,11 @@ def date_formatted end def taxon_names - parse_pg_array(read_attribute(:taxon_names)||"").compact + parse_pg_array(read_attribute(:taxon_names) || "").compact end def geo_entity_names - parse_pg_array(read_attribute(:geo_entity_names)||"").compact + parse_pg_array(read_attribute(:geo_entity_names) || "").compact end end diff --git a/app/models/geo_entity.rb b/app/models/geo_entity.rb index 817ae90ba9..359b52f7ec 100644 --- a/app/models/geo_entity.rb +++ b/app/models/geo_entity.rb @@ -102,7 +102,7 @@ def contained_geo_entities end def as_json(options = {}) - super(:only =>[:id, :iso_code2, :is_current], :methods => [:name]) + super(:only => [:id, :iso_code2, :is_current], :methods => [:name]) end def self.search(query) @@ -130,7 +130,7 @@ def dependent_objects_map 'EU opinions' => eu_opinions, 'shipments (exporter)' => exported_shipments, 'shipments (importer)' => imported_shipments, - 'shipments (origin)' =>originated_shipments + 'shipments (origin)' => originated_shipments } end diff --git a/app/models/m_taxon_concept.rb b/app/models/m_taxon_concept.rb index 0e5e1b7cd0..adb08f9ade 100644 --- a/app/models/m_taxon_concept.rb +++ b/app/models/m_taxon_concept.rb @@ -196,7 +196,7 @@ def synonyms_with_authors def db_ary_to_array(ary) if respond_to?(ary) - parse_pg_array( send(ary)|| '').compact.map do |e| + parse_pg_array( send(ary) || '').compact.map do |e| e.force_encoding('utf-8') end else diff --git a/app/models/m_taxon_concept_filter_by_scientific_name_with_descendants.rb b/app/models/m_taxon_concept_filter_by_scientific_name_with_descendants.rb index c0d69a1f21..787b2024f8 100644 --- a/app/models/m_taxon_concept_filter_by_scientific_name_with_descendants.rb +++ b/app/models/m_taxon_concept_filter_by_scientific_name_with_descendants.rb @@ -32,7 +32,7 @@ def relation conditions = [] - cond =<<-SQL + cond = <<-SQL EXISTS ( SELECT * FROM UNNEST(ARRAY[kingdom_name, phylum_name, class_name, order_name, family_name, subfamily_name]) name WHERE UPPER(name) LIKE :sci_name_prefix diff --git a/app/models/nomenclature_change/cascading_notes_processor.rb b/app/models/nomenclature_change/cascading_notes_processor.rb index f8d2fe69d9..c0677d8a0d 100644 --- a/app/models/nomenclature_change/cascading_notes_processor.rb +++ b/app/models/nomenclature_change/cascading_notes_processor.rb @@ -37,7 +37,7 @@ def descendents_for_note_cascading(taxon_concept) end # if it is a genus or a species, we want taxon-level nomenclature notes, # both public and private, to cascade to descendents - subquery =<<-SQL + subquery = <<-SQL WITH RECURSIVE descendents AS ( SELECT id, full_name, diff --git a/app/models/nomenclature_change/output.rb b/app/models/nomenclature_change/output.rb index 2bdbe21464..e62e79e3ed 100644 --- a/app/models/nomenclature_change/output.rb +++ b/app/models/nomenclature_change/output.rb @@ -85,7 +85,7 @@ class NomenclatureChange::Output < ActiveRecord::Base :if => Proc.new { |c| (c.new_record? || c.taxon_concept_id_changed?) && c.taxon_concept } def tag_list - parse_pg_array(read_attribute(:tag_list)||"").compact + parse_pg_array(read_attribute(:tag_list) || "").compact end def tag_list=(ary) diff --git a/app/models/rank.rb b/app/models/rank.rb index b9d08ff166..736e767b8d 100644 --- a/app/models/rank.rb +++ b/app/models/rank.rb @@ -53,7 +53,7 @@ def parent_rank_name Rank::SPECIES elsif name != Rank::KINGDOM rank_index = self.class.dict.index(name) - self.class.dict[rank_index-1] + self.class.dict[rank_index - 1] else nil end diff --git a/app/models/species/restrictions_export.rb b/app/models/species/restrictions_export.rb index 57be48b78c..17981ae2bb 100644 --- a/app/models/species/restrictions_export.rb +++ b/app/models/species/restrictions_export.rb @@ -34,7 +34,7 @@ def self.fill_taxon_columns(restriction) else taxon = nil end - return [""]*(TAXONOMY_COLUMNS.size+1) unless taxon #return array with empty strings + return [""] * (TAXONOMY_COLUMNS.size + 1) unless taxon #return array with empty strings TAXONOMY_COLUMNS.each do |c| columns << taxon.send(c) end diff --git a/app/models/taxon_concept_reference.rb b/app/models/taxon_concept_reference.rb index 152c793f4a..4b1bd24e7c 100644 --- a/app/models/taxon_concept_reference.rb +++ b/app/models/taxon_concept_reference.rb @@ -36,7 +36,7 @@ def excluded_taxon_concepts end def excluded_taxon_concepts_ids - parse_pg_array(read_attribute(:excluded_taxon_concepts_ids)||"").compact + parse_pg_array(read_attribute(:excluded_taxon_concepts_ids) || "").compact end def excluded_taxon_concepts_ids=(ary) diff --git a/app/models/trade/shipments_gross_exports_export.rb b/app/models/trade/shipments_gross_exports_export.rb index 739cb5bc5a..fef9de2efc 100644 --- a/app/models/trade/shipments_gross_exports_export.rb +++ b/app/models/trade/shipments_gross_exports_export.rb @@ -68,8 +68,8 @@ def crosstab_columns :taxon_concept_id => { :pg_type => 'INT' }, :taxon => { :pg_type => 'TEXT' }, :term => { :pg_type => 'TEXT' }, - :unit => { :pg_type => 'TEXT' }, - :country => { :pg_type => 'TEXT' } + :unit => { :pg_type => 'TEXT' }, + :country => { :pg_type => 'TEXT' } } end diff --git a/app/models/trade_restriction.rb b/app/models/trade_restriction.rb index b7fb1e94cc..71c26bcf58 100644 --- a/app/models/trade_restriction.rb +++ b/app/models/trade_restriction.rb @@ -91,9 +91,9 @@ def self.export(filters) to_hash. symbolize_keys!.sort. to_s - )+"_cites_#{self.to_s.downcase}s.csv" - if !File.file?(path+file_name) - self.to_csv(path+file_name, filters) + ) + "_cites_#{self.to_s.downcase}s.csv" + if !File.file?(path + file_name) + self.to_csv(path + file_name, filters) end [ path + file_name, diff --git a/db/migrate/20141014125738_change_multi_permit_number_columns_to_text.rb b/db/migrate/20141014125738_change_multi_permit_number_columns_to_text.rb index cfba6c0ad0..0dbc584587 100644 --- a/db/migrate/20141014125738_change_multi_permit_number_columns_to_text.rb +++ b/db/migrate/20141014125738_change_multi_permit_number_columns_to_text.rb @@ -1,6 +1,6 @@ class ChangeMultiPermitNumberColumnsToText < ActiveRecord::Migration def up - sql =<<-SQL + sql = <<-SQL CREATE OR REPLACE FUNCTION drop_trade_sandbox_views() RETURNS void LANGUAGE plpgsql AS $$ diff --git a/db/migrate/20150421112808_create_unique_index_on_taxon_concept_references.rb b/db/migrate/20150421112808_create_unique_index_on_taxon_concept_references.rb index 0bc2109913..99f37b3ee6 100644 --- a/db/migrate/20150421112808_create_unique_index_on_taxon_concept_references.rb +++ b/db/migrate/20150421112808_create_unique_index_on_taxon_concept_references.rb @@ -1,6 +1,6 @@ class CreateUniqueIndexOnTaxonConceptReferences < ActiveRecord::Migration def up - sql =<<-SQL + sql = <<-SQL WITH duplicated_taxon_concept_references AS ( SELECT primary_id, cnt, UNNEST(ids) AS id FROM ( SELECT MIN(id) AS primary_id, COUNT(*) AS cnt, ARRAY_AGG_NOTNULL(id) AS ids diff --git a/db/migrate/20150820121520_add_indexes_to_document_tables.rb b/db/migrate/20150820121520_add_indexes_to_document_tables.rb index 2d8e08a7e7..8d201f925b 100644 --- a/db/migrate/20150820121520_add_indexes_to_document_tables.rb +++ b/db/migrate/20150820121520_add_indexes_to_document_tables.rb @@ -1,6 +1,6 @@ class AddIndexesToDocumentTables < ActiveRecord::Migration def change - sql =<<-SQL + sql = <<-SQL WITH duplicated_document_citation_taxon_concepts AS ( SELECT primary_id, cnt, UNNEST(ids) AS id FROM ( SELECT MIN(id) AS primary_id, COUNT(*) AS cnt, ARRAY_AGG_NOTNULL(id) AS ids @@ -23,7 +23,7 @@ def change add_index "document_citation_taxon_concepts", ["taxon_concept_id", "document_citation_id"], name: "index_citation_taxon_concepts_on_taxon_concept_id_citation_id", unique: true - sql =<<-SQL + sql = <<-SQL WITH duplicated_document_citation_geo_entities AS ( SELECT primary_id, cnt, UNNEST(ids) AS id FROM ( SELECT MIN(id) AS primary_id, COUNT(*) AS cnt, ARRAY_AGG_NOTNULL(id) AS ids diff --git a/lib/capistrano/tasks/config.rake b/lib/capistrano/tasks/config.rake index 5cf27ea732..f81d44a5df 100644 --- a/lib/capistrano/tasks/config.rake +++ b/lib/capistrano/tasks/config.rake @@ -51,7 +51,7 @@ end namespace :config do task :setup do - vhost_config =<<-EOF + vhost_config = <<-EOF server { listen 80; diff --git a/lib/modules/csv_exportable.rb b/lib/modules/csv_exportable.rb index f5171cb639..5544415d32 100644 --- a/lib/modules/csv_exportable.rb +++ b/lib/modules/csv_exportable.rb @@ -10,7 +10,7 @@ def export_to_csv(options) def copy_stmt(options) basic_query = query_sql(options[:query], options[:csv_columns]) # escape quotes around attributes for psql - sql =<<-PSQL + sql = <<-PSQL \\COPY (#{basic_query.gsub(/"/, "\\\"")}) TO :file_name WITH DELIMITER :delimiter diff --git a/lib/modules/dashboard_stats_cache.rb b/lib/modules/dashboard_stats_cache.rb index 15cc9c52f2..c6684c6414 100644 --- a/lib/modules/dashboard_stats_cache.rb +++ b/lib/modules/dashboard_stats_cache.rb @@ -8,7 +8,7 @@ def self.update_dashboard_stats countries.each do |country| puts "Warming up #{country.name_en}" stats = DashboardStats.new(country, { :kingdom => 'Animalia', :trade_limit => 6, - :time_range_start => Time.now.year-7, :time_range_end => Time.now.year-2 }) + :time_range_start => Time.now.year - 7, :time_range_end => Time.now.year - 2 }) DashboardStatsSerializer.new(stats).serializable_hash end end diff --git a/lib/modules/latex_to_pdf.rb b/lib/modules/latex_to_pdf.rb index 269cb302f8..1fb0be8ebb 100644 --- a/lib/modules/latex_to_pdf.rb +++ b/lib/modules/latex_to_pdf.rb @@ -20,7 +20,7 @@ def self.generate_pdf_from_file(dir, input) Dir.chdir dir original_stdout, original_stderr = $stdout, $stderr $stderr = $stdout = File.open("#{input}.log", "a") - args=config[:arguments] + %w[-shell-escape -interaction batchmode] + ["#{input}.tex"] + args = config[:arguments] + %w[-shell-escape -interaction batchmode] + ["#{input}.tex"] exec config[:command], *args rescue File.open("#{input}.log", 'a') {|io| @@ -31,7 +31,7 @@ def self.generate_pdf_from_file(dir, input) Process.exit! 1 end end) - if File.exist?(pdf_file=[dir, "/#{input}.pdf"].join) + if File.exist?(pdf_file = [dir, "/#{input}.pdf"].join) pdf_file else raise "pdflatex failed: See #{[dir, "/#{input}.log"].join} for details" @@ -45,13 +45,13 @@ def self.escape_latex(text) # :stopdoc: unless @latex_escaper if defined?(RedCloth::Formatters::LATEX) - class << (@latex_escaper=RedCloth.new('')) + class << (@latex_escaper = RedCloth.new('')) include RedCloth::Formatters::LATEX end else - class << (@latex_escaper=Object.new) - ESCAPE_RE=/([{}_$&%#\r])|([\\^~|<>])/ - ESC_MAP={ + class << (@latex_escaper = Object.new) + ESCAPE_RE = /([{}_$&%#\r])|([\\^~|<>])/ + ESC_MAP = { '\\' => 'backslash', '^' => 'asciicircum', '~' => 'asciitilde', diff --git a/lib/scripts/get_listed_species_per_country.rb b/lib/scripts/get_listed_species_per_country.rb index 65b0cd0c5b..de8f4c4cbe 100644 --- a/lib/scripts/get_listed_species_per_country.rb +++ b/lib/scripts/get_listed_species_per_country.rb @@ -3,14 +3,14 @@ require 'json' require '../../config/environment.rb' -results = { :cites_eu=>[], :cms=>[] } +results = { :cites_eu => [], :cms => [] } countries = GeoEntity.where("geo_entity_type_id = 1") #.limit(2) countries.each do |country| [:cites_eu, :cms].each do |taxonomy| params = { - :taxonomy=>taxonomy.to_s, :taxon_concept_query=>"", - :geo_entities_ids=>["#{country.id}"], :page=>"1" + :taxonomy => taxonomy.to_s, :taxon_concept_query => "", + :geo_entities_ids => ["#{country.id}"], :page => "1" } search = Species::Search.new(params) result = { diff --git a/lib/tasks/elibrary/citations_cop_importer.rb b/lib/tasks/elibrary/citations_cop_importer.rb index c716771831..a9bb1fa965 100644 --- a/lib/tasks/elibrary/citations_cop_importer.rb +++ b/lib/tasks/elibrary/citations_cop_importer.rb @@ -22,7 +22,7 @@ def run_preparatory_queries ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET ProposalRepresentation = NULL WHERE ProposalRepresentation='NULL'" ) # revert any previous CoP document duplication - sql =<<-SQL + sql = <<-SQL WITH new_docs AS ( SELECT id, original_id FROM documents WHERE type = 'Document::Proposal' AND original_id IS NOT NULL diff --git a/lib/tasks/import_checklist_translations.rake b/lib/tasks/import_checklist_translations.rake index 1ee18e3d1e..f9c8ef1c3d 100644 --- a/lib/tasks/import_checklist_translations.rake +++ b/lib/tasks/import_checklist_translations.rake @@ -11,7 +11,7 @@ namespace :import do drop_table(TMP_TABLE) create_table_from_csv_headers(file, TMP_TABLE) copy_data(file, TMP_TABLE) - sql =<<-SQL + sql = <<-SQL UPDATE ranks SET display_name_fr = t.display_name_fr, display_name_es = t.display_name_es FROM #{TMP_TABLE} t @@ -26,7 +26,7 @@ namespace :import do drop_table(TMP_TABLE) create_table_from_csv_headers(file, TMP_TABLE) copy_data(file, TMP_TABLE) - sql =<<-SQL + sql = <<-SQL UPDATE change_types SET display_name_fr = t.display_name_fr, display_name_es = t.display_name_es FROM #{TMP_TABLE} t diff --git a/lib/tasks/import_cites_listings.rake b/lib/tasks/import_cites_listings.rake index 585e562c76..c36b44b440 100644 --- a/lib/tasks/import_cites_listings.rake +++ b/lib/tasks/import_cites_listings.rake @@ -158,7 +158,7 @@ namespace :import do ActiveRecord::Base.connection.execute(sql) #add population exceptions - sql =<<-SQL + sql = <<-SQL WITH exceptions AS ( -- first insert the exception records -- there's just one / listing change INSERT INTO listing_changes (parent_id, taxon_concept_id, species_listing_id, change_type_id, effective_at, is_current, created_at, updated_at) diff --git a/lib/tasks/import_cites_parties.rake b/lib/tasks/import_cites_parties.rake index df81e71a90..269ba84f00 100644 --- a/lib/tasks/import_cites_parties.rake +++ b/lib/tasks/import_cites_parties.rake @@ -3,7 +3,7 @@ namespace :import do task :cites_parties => [:environment] do parties_iso_codes = %w( AF AL DZ AG AR AM AU AT AZ BS BH BD BB BY BE BZ BJ BT BO BA BW BR BN BG BF BI KH CM CA CV CF TD CL CN CO KM CG CR CI HR CU CY CZ CD DK DJ DM DO EC EG SV GQ ER EE ET FJ FI FR GA GM GE DE GH GR GD GT GN GW GY HN HU IS IN ID IR IE IL IT JM JP JO KZ KE KW KG LA LV LB LS LR LY LI LT LU MG MW MY MV ML MT MR MU MX MC MN ME MA MZ MM NA NP NL NZ NI NE NG NO OM PK PW PA PG PY PE PH PL PT QA KR MD RO RU RW KN LC VC WS SM ST SA SN RS SC SL SG SK SI SB SO ZA ES LK SD SR SZ SE CH SY TH MK TG TT TN TR UG UA AE GB TZ US UY UZ VU VE VN YE ZM ZW) parties_iso_codes_pg_ary = parties_iso_codes.map{ |ic| "'#{ic}'" }.join(',') - sql =<<-SQL + sql = <<-SQL INSERT INTO designation_geo_entities (designation_id, geo_entity_id, created_at, updated_at) SELECT subquery.*, NOW(), NOW() FROM ( diff --git a/lib/tasks/import_cites_regions.rake b/lib/tasks/import_cites_regions.rake index 34d55ae35e..d8f1bece85 100644 --- a/lib/tasks/import_cites_regions.rake +++ b/lib/tasks/import_cites_regions.rake @@ -31,7 +31,7 @@ namespace :import do create_table_from_csv_headers(file, TMP_TABLE) copy_data(file, TMP_TABLE) regions_type = GeoEntityType.find_by_name(GeoEntityType::CITES_REGION) - sql =<<-SQL + sql = <<-SQL UPDATE geo_entities SET name_fr = t.name_fr, name_es = t.name_es FROM #{TMP_TABLE} t, geo_entity_types diff --git a/lib/tasks/import_cms_listings.rake b/lib/tasks/import_cms_listings.rake index f36593987b..59fc383100 100644 --- a/lib/tasks/import_cms_listings.rake +++ b/lib/tasks/import_cms_listings.rake @@ -146,7 +146,7 @@ namespace :import do ActiveRecord::Base.connection.execute(sql) #add population exceptions - sql =<<-SQL + sql = <<-SQL WITH exceptions AS ( -- first insert the exception records -- there's just one / listing change INSERT INTO listing_changes (parent_id, taxon_concept_id, species_listing_id, change_type_id, effective_at, is_current, created_at, updated_at) diff --git a/lib/tasks/import_eu_listings.rake b/lib/tasks/import_eu_listings.rake index ee4fa72a49..a01ea28bd0 100644 --- a/lib/tasks/import_eu_listings.rake +++ b/lib/tasks/import_eu_listings.rake @@ -148,7 +148,7 @@ namespace :import do ActiveRecord::Base.connection.execute(sql) #add population exceptions - sql =<<-SQL + sql = <<-SQL WITH exceptions AS ( -- first insert the exception records -- there's just one / listing change INSERT INTO listing_changes (parent_id, taxon_concept_id, species_listing_id, change_type_id, effective_at, is_current, created_at, updated_at) diff --git a/lib/tasks/import_events.rake b/lib/tasks/import_events.rake index 12027cc465..3613ba828f 100644 --- a/lib/tasks/import_events.rake +++ b/lib/tasks/import_events.rake @@ -34,7 +34,7 @@ namespace :import do puts "There are now #{Event.count} events in the database" end - task :ec_srg => [:environment] do + task :ec_srg => [:environment] do file = 'lib/files/SRG_meetings_and_SoCs_for_IT_CSV.csv' copy_data_into_table(file, 'events', %w(name effective_at url created_at updated_at type)) puts "There are now #{EcSrg.count} EcSrg events in the database" diff --git a/lib/tasks/import_hash_annotations.rake b/lib/tasks/import_hash_annotations.rake index 8cb71b1db6..3257e7e487 100644 --- a/lib/tasks/import_hash_annotations.rake +++ b/lib/tasks/import_hash_annotations.rake @@ -44,7 +44,7 @@ namespace :import do res = ActiveRecord::Base.connection.execute("SELECT COUNT(*) FROM #{TMP_TABLE}") puts "Attempting to import #{res[0]['count']} rows" - sql =<<-SQL + sql = <<-SQL WITH translated_annotations AS ( SELECT annotations.id, diff --git a/lib/tasks/import_trade_names.rake b/lib/tasks/import_trade_names.rake index a3a0627d2b..cad0f9641e 100644 --- a/lib/tasks/import_trade_names.rake +++ b/lib/tasks/import_trade_names.rake @@ -210,15 +210,15 @@ namespace :import do puts "############# SUMMARY ###################" puts "Pre-Existing trade_names: #{count_trade_names}; Final count trade_names: #{final_count_trade_names};\ - Diff: #{final_count_trade_names-count_trade_names}" + Diff: #{final_count_trade_names - count_trade_names}" puts "Pre-Existing synonyms: #{count_synonyms}; Final count synonyms: #{final_count_synonyms};\ - Diff: #{final_count_synonyms-count_synonyms}" + Diff: #{final_count_synonyms - count_synonyms}" puts "Pre-Existing taxon_names: #{count_taxon_names}; Final count taxon_names: #{final_count_taxon_names};\ - Diff: #{final_count_taxon_names-count_taxon_names}" + Diff: #{final_count_taxon_names - count_taxon_names}" puts "Pre-Existing trade_relationships: #{count_trade_relationships}; Final count trade_relationships: #{final_count_trade_relationships};\ - Diff: #{final_count_trade_relationships-count_trade_relationships}" + Diff: #{final_count_trade_relationships - count_trade_relationships}" puts "Pre-Existing synonym_relationships: #{count_synonym_relationships}; Final count synonym_relationships: #{final_count_synonym_relationships};\ - Diff: #{final_count_synonym_relationships-count_synonym_relationships}" + Diff: #{final_count_synonym_relationships - count_synonym_relationships}" Sapi::Indexes.create_indexes_on_trade_names end end diff --git a/old_cap/deploy/production.rb b/old_cap/deploy/production.rb index aeb5de4f19..fa92d904ea 100644 --- a/old_cap/deploy/production.rb +++ b/old_cap/deploy/production.rb @@ -18,7 +18,7 @@ desc "Configure VHost" task :config_vhost do - vhost_config =<<-EOF + vhost_config = <<-EOF server { listen 80; client_max_body_size 4G; diff --git a/old_cap/deploy/staging.rb b/old_cap/deploy/staging.rb index a906d1707b..f777105930 100644 --- a/old_cap/deploy/staging.rb +++ b/old_cap/deploy/staging.rb @@ -13,7 +13,7 @@ desc "Configure VHost" task :config_vhost do - vhost_config =<<-EOF + vhost_config = <<-EOF server { listen 80; client_max_body_size 4G; diff --git a/spec/controllers/admin/taxon_listing_changes_controller_spec.rb b/spec/controllers/admin/taxon_listing_changes_controller_spec.rb index 53f7662e93..f124f4162a 100644 --- a/spec/controllers/admin/taxon_listing_changes_controller_spec.rb +++ b/spec/controllers/admin/taxon_listing_changes_controller_spec.rb @@ -199,10 +199,10 @@ :designation_id => @designation.id, :listing_change => { :annotation_attributes => { - "short_note_en"=>"", "short_note_es"=>"", - "short_note_fr"=>"", "full_note_en"=>"", - "full_note_es"=>"", "full_note_fr"=>"", - "id"=> @annotation.id + "short_note_en" => "", "short_note_es" => "", + "short_note_fr" => "", "full_note_en" => "", + "full_note_es" => "", "full_note_fr" => "", + "id" => @annotation.id } } response.should redirect_to( diff --git a/spec/controllers/species/exports_controller_spec.rb b/spec/controllers/species/exports_controller_spec.rb index b95931b438..edef05d280 100644 --- a/spec/controllers/species/exports_controller_spec.rb +++ b/spec/controllers/species/exports_controller_spec.rb @@ -21,7 +21,7 @@ it 'sets separator to comma with UK ip address' do ActionDispatch::Request.any_instance.stub(:remote_ip).and_return("194.59.188.126") - Sapi::GeoIP.any_instance.stub(:country_and_city).and_return({ :country=>"GB", :city=>"Cambridge" }) + Sapi::GeoIP.any_instance.stub(:country_and_city).and_return({ :country => "GB", :city => "Cambridge" }) get :download, data_type: 'EuDecisions', :filters => { 'set' => 'current', 'decision_types' => {}, :csv_separator => '' } @@ -32,7 +32,7 @@ it 'sets separator to semicolon with AF ip address' do ActionDispatch::Request.any_instance.stub(:remote_ip).and_return("175.106.59.78") - Sapi::GeoIP.any_instance.stub(:country_and_city).and_return({ :country=>"AF", :city=>"Kabul" }) + Sapi::GeoIP.any_instance.stub(:country_and_city).and_return({ :country => "AF", :city => "Kabul" }) get :download, data_type: 'EuDecisions', :filters => { 'set' => 'current', 'decision_types' => {}, :csv_separator => '' } diff --git a/spec/factories/common_names.rb b/spec/factories/common_names.rb index f75701c9ff..3ae9fba09e 100644 --- a/spec/factories/common_names.rb +++ b/spec/factories/common_names.rb @@ -2,8 +2,8 @@ factory :language do sequence(:name_en) { |n| "lng#{n}" } - sequence(:iso_code1) { |n| [n, n+1].map{ |i| (65 + i%26).chr }.join } - sequence(:iso_code3) { |n| [n, n+1, n+2].map{ |i| (65 + i%26).chr }.join } + sequence(:iso_code1) { |n| [n, n + 1].map{ |i| (65 + i % 26).chr }.join } + sequence(:iso_code3) { |n| [n, n + 1, n + 2].map{ |i| (65 + i % 26).chr }.join } end factory :taxon_common do diff --git a/spec/factories/distributions.rb b/spec/factories/distributions.rb index da9c2402fc..4bc48e8b97 100644 --- a/spec/factories/distributions.rb +++ b/spec/factories/distributions.rb @@ -17,7 +17,7 @@ factory :geo_entity, :aliases => [:related_geo_entity, :trading_country, :importer, :exporter] do geo_entity_type name_en 'Wonderland' - sequence(:iso_code2) { |n| [n, n+1].map{ |i| (65 + i%26).chr }.join } + sequence(:iso_code2) { |n| [n, n + 1].map{ |i| (65 + i % 26).chr }.join } is_current true end diff --git a/spec/factories/trade.rb b/spec/factories/trade.rb index 4705dede93..7b9f50214c 100644 --- a/spec/factories/trade.rb +++ b/spec/factories/trade.rb @@ -2,22 +2,22 @@ factory :trade_code do factory :source, :class => Source do - sequence(:code) { |n| (97 + n%26).chr } + sequence(:code) { |n| (97 + n % 26).chr } sequence(:name_en) { |n| "Source @{n}" } end factory :purpose, :class => Purpose do - sequence(:code) { |n| (97 + n%26).chr } + sequence(:code) { |n| (97 + n % 26).chr } sequence(:name_en) { |n| "Purpose @{n}" } end factory :term, :class => Term do - sequence(:code) { |n| [n, n+1, n+2].map{ |i| (97 + i%26).chr }.join } + sequence(:code) { |n| [n, n + 1, n + 2].map{ |i| (97 + i % 26).chr }.join } sequence(:name_en) { |n| "Term @{n}" } end factory :unit, :class => Unit do - sequence(:code) { |n| [n, n+1, n+2].map{ |i| (97 + i%26).chr }.join } + sequence(:code) { |n| [n, n + 1, n + 2].map{ |i| (97 + i % 26).chr }.join } sequence(:name_en) { |n| "Unit @{n}" } end end diff --git a/spec/workers/quotas_copy_worker_spec.rb b/spec/workers/quotas_copy_worker_spec.rb index a1811c45c6..996be3e8b8 100644 --- a/spec/workers/quotas_copy_worker_spec.rb +++ b/spec/workers/quotas_copy_worker_spec.rb @@ -53,7 +53,7 @@ describe "Try to copy quota from wrong year" do before(:each) do QuotasCopyWorker.new.perform(job_defaults.merge({ - "from_year" => quota.start_date.year+1 + "from_year" => quota.start_date.year + 1 })) end specify { Quota.count(true).should == 1 } From 497d58b4bcc96fa76336626da0b6d36b3c8b1e14 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 1 Jul 2016 09:49:44 +0100 Subject: [PATCH 326/365] enabled Style/SpaceInsideParens --- .rubocop_todo.yml | 19 ------------------- app/helpers/taxon_concept_helper.rb | 2 +- app/models/eu_suspension.rb | 2 +- app/models/events_by_type_stats.rb | 2 +- app/models/m_taxon_concept.rb | 2 +- app/models/taxon_concept_reference.rb | 2 +- .../trade/csv_source_file_uploader.rb | 8 ++++---- lib/capistrano/tasks/smoke_test.rake | 2 +- lib/tasks/elibrary/citations_cop_importer.rb | 6 +++--- lib/tasks/elibrary/citations_importer.rb | 8 ++++---- lib/tasks/elibrary/citations_rst_importer.rb | 6 +++--- .../elibrary/document_discussions_importer.rb | 2 +- lib/tasks/elibrary/documents_importer.rb | 8 ++++---- .../taxon_eu_suspensions_controller_spec.rb | 2 +- .../taxon_listing_changes_controller_spec.rb | 2 +- 15 files changed, 27 insertions(+), 46 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index a85416fc7d..84362f807c 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -612,25 +612,6 @@ Style/SingleLineMethods: Style/SpaceBeforeBlockBraces: Enabled: false -# Offense count: 33 -# Cop supports --auto-correct. -Style/SpaceInsideParens: - Exclude: - - 'app/helpers/taxon_concept_helper.rb' - - 'app/models/eu_suspension.rb' - - 'app/models/events_by_type_stats.rb' - - 'app/models/m_taxon_concept.rb' - - 'app/models/taxon_concept_reference.rb' - - 'app/uploaders/trade/csv_source_file_uploader.rb' - - 'lib/capistrano/tasks/smoke_test.rake' - - 'lib/tasks/elibrary/citations_cop_importer.rb' - - 'lib/tasks/elibrary/citations_importer.rb' - - 'lib/tasks/elibrary/citations_rst_importer.rb' - - 'lib/tasks/elibrary/document_discussions_importer.rb' - - 'lib/tasks/elibrary/documents_importer.rb' - - 'spec/controllers/admin/taxon_eu_suspensions_controller_spec.rb' - - 'spec/controllers/admin/taxon_listing_changes_controller_spec.rb' - # Offense count: 6 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. diff --git a/app/helpers/taxon_concept_helper.rb b/app/helpers/taxon_concept_helper.rb index 2280ade85e..f49156df90 100644 --- a/app/helpers/taxon_concept_helper.rb +++ b/app/helpers/taxon_concept_helper.rb @@ -131,7 +131,7 @@ def admin_add_new_cites_suspension_button ) end - def admin_new_distribution_modal( nested = false) + def admin_new_distribution_modal(nested = false) admin_new_modal( :resource => 'distribution' ){ nested ? '' : render('admin/distributions/form') } diff --git a/app/models/eu_suspension.rb b/app/models/eu_suspension.rb index d44dd04d79..6e9e4909e4 100644 --- a/app/models/eu_suspension.rb +++ b/app/models/eu_suspension.rb @@ -52,6 +52,6 @@ def end_date_formatted def is_current return false if !start_event return start_event.effective_at <= Date.today && start_event.is_current && - ( !end_event || end_event.effective_at > Date.today ) + (!end_event || end_event.effective_at > Date.today) end end diff --git a/app/models/events_by_type_stats.rb b/app/models/events_by_type_stats.rb index 105863c0bf..fe531553dc 100644 --- a/app/models/events_by_type_stats.rb +++ b/app/models/events_by_type_stats.rb @@ -6,7 +6,7 @@ def initialize(start_date, end_date) end def data - Ahoy::Event.from( <<-SQL + Ahoy::Event.from(<<-SQL ( WITH weeks_as_timestamps AS ( SELECT * FROM generate_series( diff --git a/app/models/m_taxon_concept.rb b/app/models/m_taxon_concept.rb index adb08f9ade..d125ae7c9c 100644 --- a/app/models/m_taxon_concept.rb +++ b/app/models/m_taxon_concept.rb @@ -196,7 +196,7 @@ def synonyms_with_authors def db_ary_to_array(ary) if respond_to?(ary) - parse_pg_array( send(ary) || '').compact.map do |e| + parse_pg_array(send(ary) || '').compact.map do |e| e.force_encoding('utf-8') end else diff --git a/app/models/taxon_concept_reference.rb b/app/models/taxon_concept_reference.rb index 4b1bd24e7c..fc9ad6b2f1 100644 --- a/app/models/taxon_concept_reference.rb +++ b/app/models/taxon_concept_reference.rb @@ -40,7 +40,7 @@ def excluded_taxon_concepts_ids end def excluded_taxon_concepts_ids=(ary) - write_attribute(:excluded_taxon_concepts_ids, '{' + ary + '}' ) + write_attribute(:excluded_taxon_concepts_ids, '{' + ary + '}') end end diff --git a/app/uploaders/trade/csv_source_file_uploader.rb b/app/uploaders/trade/csv_source_file_uploader.rb index 992afbc41f..193ec51c0a 100644 --- a/app/uploaders/trade/csv_source_file_uploader.rb +++ b/app/uploaders/trade/csv_source_file_uploader.rb @@ -41,8 +41,8 @@ def store_dir def remove_blank_lines cache_stored_file! if !cached? - directory = File.dirname( current_path ) - tmp_path = File.join( directory, "tmpfile" ) + directory = File.dirname(current_path) + tmp_path = File.join(directory, "tmpfile") if system("cat #{current_path} | sed 's/\r//g' | grep -v -E '^(\"?[[:blank:]]*\"?,)*$' > #{tmp_path}") FileUtils.mv(tmp_path, current_path) else @@ -56,12 +56,12 @@ def convert_to_utf8 # Try it as UTF-8 directly cleaned = content.dup.force_encoding('UTF-8') unless cleaned.valid_encoding? - cleaned = content.encode( 'UTF-8', 'iso-8859-1' ) + cleaned = content.encode('UTF-8', 'iso-8859-1') end content = cleaned rescue EncodingError # Force it to UTF-8, throwing out invalid bits - content.encode!( 'UTF-8', invalid: :replace, undef: :replace ) + content.encode!('UTF-8', invalid: :replace, undef: :replace) end File.open(current_path, 'w') { |file| file.write(content) } end diff --git a/lib/capistrano/tasks/smoke_test.rake b/lib/capistrano/tasks/smoke_test.rake index 9e5e4b5e96..e5d59a40ad 100644 --- a/lib/capistrano/tasks/smoke_test.rake +++ b/lib/capistrano/tasks/smoke_test.rake @@ -47,7 +47,7 @@ namespace :smoke_test do response = nil request = Net::HTTP::Post.new(uri.request_uri) - request.set_form_data({ :payload => JSON.generate( payload ) }) + request.set_form_data({ :payload => JSON.generate(payload) }) http = Net::HTTP.new(uri.host, uri.port) http.use_ssl = true diff --git a/lib/tasks/elibrary/citations_cop_importer.rb b/lib/tasks/elibrary/citations_cop_importer.rb index a9bb1fa965..0689355556 100644 --- a/lib/tasks/elibrary/citations_cop_importer.rb +++ b/lib/tasks/elibrary/citations_cop_importer.rb @@ -17,9 +17,9 @@ def columns_with_type def run_preparatory_queries super() - ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET ProposalNature = NULL WHERE ProposalNature='NULL'" ) - ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET ProposalOutcome = NULL WHERE ProposalOutcome='NULL'" ) - ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET ProposalRepresentation = NULL WHERE ProposalRepresentation='NULL'" ) + ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET ProposalNature = NULL WHERE ProposalNature='NULL'") + ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET ProposalOutcome = NULL WHERE ProposalOutcome='NULL'") + ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET ProposalRepresentation = NULL WHERE ProposalRepresentation='NULL'") # revert any previous CoP document duplication sql = <<-SQL diff --git a/lib/tasks/elibrary/citations_importer.rb b/lib/tasks/elibrary/citations_importer.rb index 998656f295..2a6c4cab4c 100644 --- a/lib/tasks/elibrary/citations_importer.rb +++ b/lib/tasks/elibrary/citations_importer.rb @@ -50,10 +50,10 @@ def columns_with_type end def run_preparatory_queries - ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET splus_taxon_concept_id = NULL WHERE splus_taxon_concept_id LIKE '%N/A%'" ) - ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET CtyISO2 = NULL WHERE CtyISO2='NULL'" ) - ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET EventID = NULL WHERE EventID='NULL'" ) - ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET DocumentID = NULL WHERE DocumentID='NULL'" ) + ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET splus_taxon_concept_id = NULL WHERE splus_taxon_concept_id LIKE '%N/A%'") + ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET CtyISO2 = NULL WHERE CtyISO2='NULL'") + ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET EventID = NULL WHERE EventID='NULL'") + ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET DocumentID = NULL WHERE DocumentID='NULL'") end def run_queries diff --git a/lib/tasks/elibrary/citations_rst_importer.rb b/lib/tasks/elibrary/citations_rst_importer.rb index f007f841c4..1ac2e09c3d 100644 --- a/lib/tasks/elibrary/citations_rst_importer.rb +++ b/lib/tasks/elibrary/citations_rst_importer.rb @@ -36,9 +36,9 @@ def columns_with_type def run_preparatory_queries super() - ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET SigTradePhase = NULL WHERE SigTradePhase='NULL'" ) - ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET SigTradeProcessStage = NULL WHERE SigTradeProcessStage='NULL'" ) - ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET SigTradeRecommendedCategory = NULL WHERE SigTradeRecommendedCategory='NULL'" ) + ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET SigTradePhase = NULL WHERE SigTradePhase='NULL'") + ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET SigTradeProcessStage = NULL WHERE SigTradeProcessStage='NULL'") + ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET SigTradeRecommendedCategory = NULL WHERE SigTradeRecommendedCategory='NULL'") end def run_queries diff --git a/lib/tasks/elibrary/document_discussions_importer.rb b/lib/tasks/elibrary/document_discussions_importer.rb index 8c4460326d..0bff2a7e0e 100644 --- a/lib/tasks/elibrary/document_discussions_importer.rb +++ b/lib/tasks/elibrary/document_discussions_importer.rb @@ -27,7 +27,7 @@ def columns_with_type end def run_preparatory_queries - ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET DocumentOrder = NULL WHERE DocumentOrder='NULL'" ) + ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET DocumentOrder = NULL WHERE DocumentOrder='NULL'") end def run_queries diff --git a/lib/tasks/elibrary/documents_importer.rb b/lib/tasks/elibrary/documents_importer.rb index 89d8a2474e..cdb9e6fe86 100644 --- a/lib/tasks/elibrary/documents_importer.rb +++ b/lib/tasks/elibrary/documents_importer.rb @@ -43,10 +43,10 @@ def columns_with_type def run_preparatory_queries ActiveRecord::Base.connection.execute("DELETE FROM #{table_name} WHERE DocumentTypeName LIKE 'CoP Proceedings%'") - ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET DocumentTitle = NULL WHERE DocumentTitle='NULL'" ) - ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET DocumentDate = NULL WHERE DocumentDate='NULL'" ) - ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET EventDate = NULL WHERE EventDate='NULL'" ) - ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET DocumentFileName = NULL WHERE DocumentFileName='NULL'" ) + ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET DocumentTitle = NULL WHERE DocumentTitle='NULL'") + ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET DocumentDate = NULL WHERE DocumentDate='NULL'") + ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET EventDate = NULL WHERE EventDate='NULL'") + ActiveRecord::Base.connection.execute("UPDATE #{table_name} SET DocumentFileName = NULL WHERE DocumentFileName='NULL'") end def run_queries diff --git a/spec/controllers/admin/taxon_eu_suspensions_controller_spec.rb b/spec/controllers/admin/taxon_eu_suspensions_controller_spec.rb index 8249254c39..97fa305256 100644 --- a/spec/controllers/admin/taxon_eu_suspensions_controller_spec.rb +++ b/spec/controllers/admin/taxon_eu_suspensions_controller_spec.rb @@ -134,7 +134,7 @@ describe "Authorization for contributors" do login_contributor - let!(:eu_suspension ) { + let!(:eu_suspension) { create( :eu_suspension, :taxon_concept_id => @taxon_concept.id diff --git a/spec/controllers/admin/taxon_listing_changes_controller_spec.rb b/spec/controllers/admin/taxon_listing_changes_controller_spec.rb index f124f4162a..0d7a87c46d 100644 --- a/spec/controllers/admin/taxon_listing_changes_controller_spec.rb +++ b/spec/controllers/admin/taxon_listing_changes_controller_spec.rb @@ -234,7 +234,7 @@ end describe "Authorization for contributors" do login_contributor - let!(:listing_change ) { + let!(:listing_change) { create( :listing_change, :taxon_concept_id => @taxon_concept.id, From 07668bf12dab160b76b7a5ee31a7675c6358ff02 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 1 Jul 2016 09:51:45 +0100 Subject: [PATCH 327/365] enabled Style/SpaceInsideStringInterpolation --- .rubocop_todo.yml | 11 ----------- app/helpers/admin/trade_codes_helper.rb | 2 +- lib/tasks/import_distribution_tags.rake | 11 +++++------ lib/tasks/import_distributions.rake | 8 ++++---- lib/tasks/import_synonyms.rake | 23 +++++++++-------------- 5 files changed, 19 insertions(+), 36 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 84362f807c..fadc26f960 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -612,17 +612,6 @@ Style/SingleLineMethods: Style/SpaceBeforeBlockBraces: Enabled: false -# Offense count: 6 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: space, no_space -Style/SpaceInsideStringInterpolation: - Exclude: - - 'app/helpers/admin/trade_codes_helper.rb' - - 'lib/tasks/import_distribution_tags.rake' - - 'lib/tasks/import_distributions.rake' - - 'lib/tasks/import_synonyms.rake' - # Offense count: 4 # Cop supports --auto-correct. # Configuration parameters: SupportedStyles. diff --git a/app/helpers/admin/trade_codes_helper.rb b/app/helpers/admin/trade_codes_helper.rb index f62d45abb7..40d23353ea 100644 --- a/app/helpers/admin/trade_codes_helper.rb +++ b/app/helpers/admin/trade_codes_helper.rb @@ -2,7 +2,7 @@ module Admin::TradeCodesHelper def sub_nav content_tag(:ul, :class => "nav nav-pills") do ["purposes", "sources", "terms", "units"].each do |subclass| - concat(content_tag(:li, :class => "#{ controller_name == subclass ? 'active' : '' }") do + concat(content_tag(:li, :class => "#{controller_name == subclass ? 'active' : ''}") do link_to subclass.titleize, send("admin_#{subclass}_path") end) end diff --git a/lib/tasks/import_distribution_tags.rake b/lib/tasks/import_distribution_tags.rake index 602a8b8ae2..2157a72081 100644 --- a/lib/tasks/import_distribution_tags.rake +++ b/lib/tasks/import_distribution_tags.rake @@ -50,12 +50,11 @@ namespace :import do SELECT DISTINCT legacy_id, rank, geo_entity_type, iso_code2, regexp_split_to_table(#{TMP_TABLE}.tags, E',') AS tag FROM #{TMP_TABLE} WHERE - #{ if taxonomy_name == Taxonomy::CITES_EU - "( UPPER(BTRIM(#{TMP_TABLE}.designation)) like '%CITES%' OR UPPER(BTRIM(#{TMP_TABLE}.designation)) like '%EU%')" - else - "UPPER(BTRIM(#{TMP_TABLE}.designation)) like '%CMS%'" - end - } + #{if taxonomy_name == Taxonomy::CITES_EU + "( UPPER(BTRIM(#{TMP_TABLE}.designation)) like '%CITES%' OR UPPER(BTRIM(#{TMP_TABLE}.designation)) like '%EU%')" + else + "UPPER(BTRIM(#{TMP_TABLE}.designation)) like '%CMS%'" + end} ) INSERT INTO taggings(tag_id, taggable_id, taggable_type, context, created_at) SELECT subquery.*, NOW() diff --git a/lib/tasks/import_distributions.rake b/lib/tasks/import_distributions.rake index ac6639342c..02742319a7 100644 --- a/lib/tasks/import_distributions.rake +++ b/lib/tasks/import_distributions.rake @@ -28,10 +28,10 @@ namespace :import do INNER JOIN taxonomies ON taxonomies.id = taxon_concepts.taxonomy_id WHERE taxon_concepts.id IS NOT NULL AND geo_entities.id IS NOT NULL AND - #{ if taxonomy_name == Taxonomy::CITES_EU - "( UPPER(BTRIM(#{TMP_TABLE}.designation)) like '%CITES%' OR UPPER(BTRIM(#{TMP_TABLE}.designation)) like '%EU%')" - else - "UPPER(BTRIM(#{TMP_TABLE}.designation)) like '%CMS%'" + #{if taxonomy_name == Taxonomy::CITES_EU + "( UPPER(BTRIM(#{TMP_TABLE}.designation)) like '%CITES%' OR UPPER(BTRIM(#{TMP_TABLE}.designation)) like '%EU%')" + else + "UPPER(BTRIM(#{TMP_TABLE}.designation)) like '%CMS%'" end} AND taxonomies.id = #{taxonomy.id} diff --git a/lib/tasks/import_synonyms.rake b/lib/tasks/import_synonyms.rake index df12c86b3f..b1c585279a 100644 --- a/lib/tasks/import_synonyms.rake +++ b/lib/tasks/import_synonyms.rake @@ -3,13 +3,11 @@ namespace :import do desc 'Import synonyms from csv file (usage: rake import:synonyms[path/to/file,path/to/another])' task :synonyms, 10.times.map { |i| "file_#{i}".to_sym } => [:environment] do |t, args| TMP_TABLE = 'synonym_import' - puts "There are #{ - TaxonRelationship. + puts "There are #{TaxonRelationship. joins(:taxon_relationship_type). where( "taxon_relationship_types.name" => TaxonRelationshipType::HAS_SYNONYM - ).count - } synonyms in the database." + ).count} synonyms in the database." rel = TaxonRelationshipType. find_by_name(TaxonRelationshipType::HAS_SYNONYM) @@ -56,12 +54,11 @@ namespace :import do LEFT JOIN taxonomies ON taxonomies.id = accepted.taxonomy_id AND taxonomies.id = synonym.taxonomy_id WHERE taxonomies.id = #{taxonomy.id} AND - #{ if taxonomy_name == Taxonomy::CITES_EU - "( UPPER(BTRIM(#{TMP_TABLE}.taxonomy)) like '%CITES%' OR UPPER(BTRIM(#{TMP_TABLE}.taxonomy)) like '%EU%')" - else - "UPPER(BTRIM(#{TMP_TABLE}.taxonomy)) like '%CMS%'" - end - } + #{if taxonomy_name == Taxonomy::CITES_EU + "( UPPER(BTRIM(#{TMP_TABLE}.taxonomy)) like '%CITES%' OR UPPER(BTRIM(#{TMP_TABLE}.taxonomy)) like '%EU%')" + else + "UPPER(BTRIM(#{TMP_TABLE}.taxonomy)) like '%CMS%'" + end} EXCEPT @@ -86,13 +83,11 @@ namespace :import do ActiveRecord::Base.connection.execute(sql) end - puts "There are now #{ - TaxonRelationship. + puts "There are now #{TaxonRelationship. joins(:taxon_relationship_type). where( "taxon_relationship_types.name" => TaxonRelationshipType::HAS_SYNONYM - ).count - } synonyms in the database." + ).count} synonyms in the database." end end From 0c3d4c4be813c08cd3e1ee7593f2bf2057cc64c5 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 1 Jul 2016 10:04:46 +0100 Subject: [PATCH 328/365] enabled Style/SpaceBeforeBlockBraces --- .rubocop_todo.yml | 7 - .../admin/designations_controller.rb | 2 +- app/controllers/admin/documents_controller.rb | 2 +- app/controllers/admin/events_controller.rb | 4 +- .../admin/instruments_controller.rb | 2 +- app/controllers/admin/quotas_controller.rb | 2 +- .../admin/references_controller.rb | 2 +- .../admin/taxonomies_controller.rb | 2 +- .../api/geo_relationships_controller.rb | 2 +- app/controllers/api/ranks_controller.rb | 2 +- ...auto_complete_taxon_concepts_controller.rb | 2 +- app/controllers/api/v1/purposes_controller.rb | 2 +- app/controllers/api/v1/sources_controller.rb | 2 +- app/controllers/api/v1/terms_controller.rb | 2 +- app/controllers/api/v1/units_controller.rb | 2 +- .../admin/nomenclature_changes_helper.rb | 4 +- app/helpers/admin_helper.rb | 14 +- app/helpers/taxon_concept_helper.rb | 18 +-- app/models/change_type.rb | 2 +- app/models/checklist/checklist.rb | 2 +- app/models/checklist/higher_taxa_injector.rb | 2 +- app/models/iucn_mapping_manager.rb | 2 +- ..._taxon_concept_filter_by_appendix_query.rb | 2 +- ...n_concept_filter_by_id_with_descendants.rb | 2 +- .../delete_unreassigned_processor.rb | 8 +- app/models/nomenclature_change/lump.rb | 6 +- .../nomenclature_change/lump/processor.rb | 2 +- app/models/nomenclature_change/processor.rb | 2 +- app/models/nomenclature_change/split.rb | 4 +- .../nomenclature_change/split/processor.rb | 4 +- .../status_change/processor_helpers.rb | 2 +- app/models/taxon_concept.rb | 10 +- .../trade/distinct_values_validation_rule.rb | 2 +- app/models/trade/filter.rb | 4 +- app/models/trade/format_validation_rule.rb | 2 +- app/models/trade/inclusion_validation_rule.rb | 10 +- .../trade/numericality_validation_rule.rb | 4 +- app/models/trade/sandbox_template.rb | 4 +- app/models/trade/shipments_export.rb | 2 +- .../trade/shipments_gross_exports_export.rb | 10 +- ...n_concept_appendix_year_validation_rule.rb | 2 +- .../taxon_concept_source_validation_rule.rb | 4 +- app/models/trade/validation_rule.rb | 4 +- .../show_annual_report_upload_serializer.rb | 2 +- lib/modules/dictionary.rb | 4 +- lib/modules/sapi/stored_procedures.rb | 4 +- lib/modules/search_param_sanitiser.rb | 2 +- lib/modules/statistics.rb | 2 +- lib/tasks/db_migrate_plpgsql.rake | 2 +- lib/tasks/elibrary/importable.rb | 4 +- lib/tasks/helpers_for_import.rb | 8 +- lib/tasks/import_cites_parties.rake | 2 +- lib/tasks/resolve_host_to_country.rake | 2 +- ...date_eu_decisions_with_missing_source.rake | 2 +- .../admin/change_types_controller_spec.rb | 4 +- .../admin/designations_controller_spec.rb | 4 +- .../admin/document_batches_controller_spec.rb | 16 +-- .../admin/documents_controller_spec.rb | 36 +++--- .../admin/eu_regulations_controller_spec.rb | 2 +- ..._suspension_regulations_controller_spec.rb | 2 +- .../admin/event_documents_controller_spec.rb | 2 +- .../admin/events_controller_spec.rb | 6 +- .../admin/geo_entities_controller_spec.rb | 4 +- .../hybrid_relationships_controller_spec.rb | 8 +- .../admin/instruments_controller_spec.rb | 8 +- .../admin/languages_controller_spec.rb | 4 +- .../status_to_synonym_controller_spec.rb | 2 +- .../nomenclature_changes_controller_spec.rb | 2 +- .../admin/ranks_controller_spec.rb | 4 +- .../admin/references_controller_spec.rb | 4 +- .../admin/species_listings_controller_spec.rb | 4 +- .../synonym_relationships_controller_spec.rb | 8 +- .../controllers/admin/tags_controller_spec.rb | 4 +- .../taxon_concept_comments_controller_spec.rb | 2 +- .../admin/taxon_concepts_controller_spec.rb | 6 +- .../taxon_relationships_controller_spec.rb | 20 +-- .../admin/taxonomies_controller_spec.rb | 6 +- ...ade_names_relationships_controller_spec.rb | 8 +- .../admin/users_controller_spec.rb | 6 +- .../document_geo_entities_controller_spec.rb | 6 +- .../api/documents_controller_spec.rb | 6 +- .../api/geo_entities_controller_spec.rb | 8 +- .../api/taxon_concepts_controller_spec.rb | 4 +- .../checklist/geo_entities_controller_spec.rb | 8 +- .../cites_trade/shipments_controller_spec.rb | 2 +- .../registrations_controller_spec.rb | 4 +- .../annual_report_uploads_controller_spec.rb | 4 +- .../sandbox_shipments_controller_spec.rb | 4 +- .../trade/shipments_controller_spec.rb | 10 +- spec/factories/common_names.rb | 6 +- spec/factories/distributions.rb | 2 +- spec/factories/taxon_concepts.rb | 2 +- spec/factories/trade.rb | 4 +- .../admin/nomenclature_changes_helper_spec.rb | 16 +-- spec/helpers/listing_changes_helper_spec.rb | 20 +-- spec/models/annotation_spec.rb | 16 +-- spec/models/api_request_spec.rb | 2 +- spec/models/checklist/annotations_spec.rb | 4 +- .../appendix_population_and_region_spec.rb | 14 +- .../checklist/appendix_population_spec.rb | 32 ++--- spec/models/checklist/appendix_spec.rb | 4 +- spec/models/checklist/common_names_spec.rb | 6 +- .../checklist/higher_taxa_injector_spec.rb | 64 ++++----- .../models/checklist/higher_taxa_item_spec.rb | 4 +- spec/models/checklist/order_spec.rb | 46 +++---- .../pdf/history_annotations_key_spec.rb | 10 +- spec/models/checklist/pdf/history_spec.rb | 44 +++---- .../pdf/index_annotations_key_spec.rb | 14 +- .../checklist/pdf/index_fetcher_spec.rb | 28 ++-- spec/models/checklist/scientific_name_spec.rb | 4 +- spec/models/checklist/synonyms_spec.rb | 2 +- .../taxon_concept_prefix_matcher_spec.rb | 16 +-- spec/models/checklist/timeline_spec.rb | 86 ++++++------ .../timelines_for_taxon_concept_spec.rb | 36 +++--- spec/models/cites_cop_spec.rb | 8 +- .../cites_suspension_notification_spec.rb | 26 ++-- spec/models/cites_suspension_spec.rb | 80 ++++++------ spec/models/dashboard_stats_species_spec.rb | 8 +- spec/models/dashboard_stats_trade_spec.rb | 4 +- spec/models/designation_spec.rb | 34 ++--- spec/models/document_batch_spec.rb | 8 +- spec/models/document_search_spec.rb | 24 ++-- spec/models/document_spec.rb | 38 +++--- spec/models/eu_opinion_spec.rb | 8 +- spec/models/eu_regulation_spec.rb | 24 ++-- spec/models/eu_suspension_spec.rb | 6 +- spec/models/event_spec.rb | 12 +- spec/models/geo_entity_search_spec.rb | 2 +- spec/models/geo_entity_spec.rb | 28 ++-- spec/models/html_to_latex_spec.rb | 24 ++-- spec/models/hybrid_relationship_spec.rb | 16 +-- spec/models/listing_change_spec.rb | 42 +++--- .../delete_unreassigned_processor_spec.rb | 10 +- .../full_reassignment_spec.rb | 20 +-- spec/models/nomenclature_change/input_spec.rb | 4 +- .../lump/constructor_spec.rb | 70 +++++----- .../output_taxon_concept_processor_spec.rb | 24 ++-- .../lump/processor_spec.rb | 116 ++++++++--------- spec/models/nomenclature_change/lump_spec.rb | 14 +- .../output_reassignment_spec.rb | 4 +- .../models/nomenclature_change/output_spec.rb | 44 +++---- .../reassignment_copy_processor_spec.rb | 22 ++-- .../nomenclature_change/reassignment_spec.rb | 4 +- .../reassignment_target_spec.rb | 4 +- .../reassignment_transfer_processor_spec.rb | 34 ++--- ...name_reassignments_constructor_examples.rb | 12 +- ...n_name_reassignments_processor_examples.rb | 8 +- ...tion_reassignments_constructor_examples.rb | 12 +- ...bution_reassignments_processor_examples.rb | 22 ++-- ...tion_reassignments_constructor_examples.rb | 10 +- ...lation_reassignments_processor_examples.rb | 34 ++--- .../shared/lump_definitions.rb | 26 ++-- ...name_reassignments_constructor_examples.rb | 10 +- .../name_reassignments_processor_examples.rb | 10 +- ..._names_reassignments_processor_examples.rb | 6 +- ...bution_reassignments_processor_examples.rb | 12 +- ...lation_reassignments_processor_examples.rb | 38 +++--- ...t_name_reassignments_processor_examples.rb | 8 +- ...erence_reassignments_processor_examples.rb | 6 +- ...ipment_reassignments_processor_examples.rb | 4 +- ...rent_reassignments_constructor_examples.rb | 12 +- ...parent_reassignments_processor_examples.rb | 12 +- ...ence_reassignments_constructor_examples.rb | 12 +- ...erence_reassignments_processor_examples.rb | 8 +- ...ipment_reassignments_processor_examples.rb | 8 +- .../shared/split_definitions.rb | 30 ++--- .../shared/status_change_definitions.rb | 26 ++-- .../split/constructor_spec.rb | 70 +++++----- .../output_taxon_concept_processor_spec.rb | 26 ++-- .../split/processor_spec.rb | 122 +++++++++--------- spec/models/nomenclature_change/split_spec.rb | 10 +- .../status_swap/constructor_spec.rb | 36 +++--- .../status_swap/processor_spec.rb | 30 ++--- .../status_to_accepted/processor_spec.rb | 34 ++--- .../status_to_accepted_spec.rb | 8 +- .../status_to_synonym/constructor_spec.rb | 12 +- .../output_taxon_concept_processor_spec.rb | 10 +- .../status_to_synonym/processor_spec.rb | 48 +++---- .../status_to_synonym_spec.rb | 12 +- spec/models/nomenclature_change_spec.rb | 22 ++-- spec/models/preset_tag_spec.rb | 6 +- spec/models/purpose_spec.rb | 8 +- spec/models/quota_spec.rb | 10 +- spec/models/rank_spec.rb | 22 ++-- spec/models/sapi/geoip_spec.rb | 4 +- spec/models/source_spec.rb | 8 +- .../species/common_names_export_spec.rb | 4 +- spec/models/species/documents_export_spec.rb | 4 +- spec/models/species/listings_export_spec.rb | 4 +- .../orphaned_taxon_concepts_export_spec.rb | 4 +- .../species/species_reference_output_spec.rb | 4 +- .../species/standard_reference_output_spec.rb | 4 +- .../synonyms_and_trade_names_export_spec.rb | 4 +- .../species/taxon_concepts_export_spec.rb | 4 +- spec/models/synonym_relationship_spec.rb | 16 +-- spec/models/taxon_common_spec.rb | 14 +- .../taxon_concept/boa_constrictor_spec.rb | 80 ++++++------ spec/models/taxon_concept/callback_spec.rb | 14 +- spec/models/taxon_concept/canis_lupus_spec.rb | 22 ++-- .../taxon_concept/caretta_caretta_cms_spec.rb | 8 +- .../taxon_concept/cervus_elaphus_cms_spec.rb | 10 +- spec/models/taxon_concept/destroy_spec.rb | 28 ++-- spec/models/taxon_concept/hybrids_spec.rb | 16 +-- .../loxodonta_africana_cms_spec.rb | 16 +-- .../taxon_concept/loxodonta_africana_spec.rb | 24 ++-- .../taxon_concept/natator_depressus_spec.rb | 4 +- .../taxon_concept/notomys_aquilo_spec.rb | 8 +- .../taxon_concept/pseudomys_fieldi_spec.rb | 12 +- spec/models/taxon_concept/synonyms_spec.rb | 16 +-- spec/models/taxon_concept/trade_names_spec.rb | 16 +-- spec/models/taxon_concept/validation_spec.rb | 12 +- spec/models/taxon_concept_data_spec.rb | 24 ++-- .../taxon_concept_prefix_matcher_spec.rb | 60 ++++----- spec/models/taxonomy_spec.rb | 20 +-- spec/models/term_spec.rb | 10 +- .../models/trade/annual_report_upload_spec.rb | 32 ++--- .../distinct_values_validation_rule_spec.rb | 16 +-- spec/models/trade/filter_spec.rb | 4 +- .../trade/inclusion_validation_rule_spec.rb | 32 ++--- .../pov_inclusion_validation_rule_spec.rb | 28 ++-- .../reported_taxon_concept_resolver_spec.rb | 12 +- spec/models/trade/sandbox_spec.rb | 2 +- spec/models/trade/sandbox_template_spec.rb | 10 +- .../scoped_inclusion_validation_rule_spec.rb | 10 +- spec/models/trade/shipment_spec.rb | 60 ++++----- .../trade/shipments_comptab_export_spec.rb | 8 +- spec/models/trade/shipments_export_spec.rb | 8 +- .../shipments_gross_exports_export_spec.rb | 10 +- .../shipments_gross_imports_export_spec.rb | 10 +- .../shipments_net_exports_export_spec.rb | 10 +- .../shipments_net_imports_export_spec.rb | 10 +- ...cept_appendix_year_validation_rule_spec.rb | 32 ++--- ...xon_concept_source_validation_rule_spec.rb | 14 +- spec/models/trade/validation_rule_spec.rb | 16 +-- spec/models/unit_spec.rb | 10 +- spec/models/user_spec.rb | 32 ++--- spec/shared/agave.rb | 6 +- spec/shared/arctocephalus.rb | 6 +- spec/shared/boa_constrictor.rb | 2 +- spec/shared/caiman_latirostris.rb | 6 +- spec/shared/canis_lupus.rb | 16 +-- spec/shared/colophon.rb | 2 +- spec/shared/dalbergia.rb | 10 +- spec/shared/diospyros.rb | 4 +- spec/shared/loxodonta_africana.rb | 10 +- spec/shared/mellivora_capensis.rb | 4 +- spec/shared/moschus.rb | 8 +- spec/shared/panax_ginseng.rb | 4 +- spec/shared/pecari_tajacu.rb | 12 +- spec/shared/psittaciformes.rb | 2 +- spec/support/sapi_helpers.rb | 70 +++++----- .../eu_regulation_activation_worker_spec.rb | 6 +- .../event_listing_changes_copy_worker_spec.rb | 18 +-- 253 files changed, 1754 insertions(+), 1761 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index fadc26f960..590d78a12e 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -605,13 +605,6 @@ Style/SignalException: Style/SingleLineMethods: Enabled: false -# Offense count: 1018 -# Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. -# SupportedStyles: space, no_space -Style/SpaceBeforeBlockBraces: - Enabled: false - # Offense count: 4 # Cop supports --auto-correct. # Configuration parameters: SupportedStyles. diff --git a/app/controllers/admin/designations_controller.rb b/app/controllers/admin/designations_controller.rb index 3eaaf387a5..6a2fe8a7db 100644 --- a/app/controllers/admin/designations_controller.rb +++ b/app/controllers/admin/designations_controller.rb @@ -7,7 +7,7 @@ def index index! do |format| format.json { render :text => end_of_association_chain.order(:name). - select([:id, :name]).map{ |d| { :value => d.id, :text => d.name } }.to_json + select([:id, :name]).map { |d| { :value => d.id, :text => d.name } }.to_json } end end diff --git a/app/controllers/admin/documents_controller.rb b/app/controllers/admin/documents_controller.rb index bbb85b30a8..2b0c97e2f4 100644 --- a/app/controllers/admin/documents_controller.rb +++ b/app/controllers/admin/documents_controller.rb @@ -91,7 +91,7 @@ def load_associations else Event.event_types_with_names end - @events = Event.where(type: @event_types.map{ |t| t[:id] }).order(:published_at).reverse_order + @events = Event.where(type: @event_types.map { |t| t[:id] }).order(:published_at).reverse_order @event = Event.find(params[:event_id]) if params[:event_id].present? @languages = Language.select([:id, :name_en, :name_es, :name_fr]). order(:name_en) diff --git a/app/controllers/admin/events_controller.rb b/app/controllers/admin/events_controller.rb index c7e442ff71..cc079c2a94 100644 --- a/app/controllers/admin/events_controller.rb +++ b/app/controllers/admin/events_controller.rb @@ -7,7 +7,7 @@ def index index! do |format| format.json { render :text => end_of_association_chain.order(:effective_at, :name). - select([:id, :name]).map{ |d| { :value => d.id, :text => d.name } }.to_json + select([:id, :name]).map { |d| { :value => d.id, :text => d.name } }.to_json } end end @@ -27,7 +27,7 @@ def edit def show show! do |format| - format.json{ render :json => resource, :serializer => Admin::EventSerializer } + format.json { render :json => resource, :serializer => Admin::EventSerializer } end end diff --git a/app/controllers/admin/instruments_controller.rb b/app/controllers/admin/instruments_controller.rb index 5cda7408f7..25c3c76326 100644 --- a/app/controllers/admin/instruments_controller.rb +++ b/app/controllers/admin/instruments_controller.rb @@ -6,7 +6,7 @@ def index index! do |format| format.json { render :text => end_of_association_chain.order(:name). - select([:id, :name]).map{ |d| { :value => d.id, :text => d.name } }.to_json + select([:id, :name]).map { |d| { :value => d.id, :text => d.name } }.to_json } end end diff --git a/app/controllers/admin/quotas_controller.rb b/app/controllers/admin/quotas_controller.rb index adf6c7cdac..f4b6f8bce0 100644 --- a/app/controllers/admin/quotas_controller.rb +++ b/app/controllers/admin/quotas_controller.rb @@ -3,7 +3,7 @@ class Admin::QuotasController < Admin::StandardAuthorizationController def index @years = Quota.years_array if params[:year] && !@years.include?(params[:year]) - @years = @years.push(params[:year]).sort{ |a, b| b <=> a } + @years = @years.push(params[:year]).sort { |a, b| b <=> a } end index! end diff --git a/app/controllers/admin/references_controller.rb b/app/controllers/admin/references_controller.rb index 16c990a558..f817d3ed67 100644 --- a/app/controllers/admin/references_controller.rb +++ b/app/controllers/admin/references_controller.rb @@ -5,7 +5,7 @@ def index index! do |format| format.json { render :text => end_of_association_chain.order(:citation). - select([:id, :citation]).map{ |d| { :value => d.id, :text => d.citation } }.to_json + select([:id, :citation]).map { |d| { :value => d.id, :text => d.citation } }.to_json } end end diff --git a/app/controllers/admin/taxonomies_controller.rb b/app/controllers/admin/taxonomies_controller.rb index 4f30a36493..d16cc989c9 100644 --- a/app/controllers/admin/taxonomies_controller.rb +++ b/app/controllers/admin/taxonomies_controller.rb @@ -5,7 +5,7 @@ def index index! do |format| format.json { render :text => end_of_association_chain.order(:name). - select([:id, :name]).map{ |d| { :value => d.id, :text => d.name } }.to_json + select([:id, :name]).map { |d| { :value => d.id, :text => d.name } }.to_json } end end diff --git a/app/controllers/api/geo_relationships_controller.rb b/app/controllers/api/geo_relationships_controller.rb index 3ce2be7f48..ca6658bc00 100644 --- a/app/controllers/api/geo_relationships_controller.rb +++ b/app/controllers/api/geo_relationships_controller.rb @@ -7,6 +7,6 @@ class Api::GeoRelationshipsController < ApplicationController def collection @geo_relationship_types ||= end_of_association_chain.order(:name). select([:id, :name]). - map{ |d| { :value => d.id, :text => d.name } } + map { |d| { :value => d.id, :text => d.name } } end end \ No newline at end of file diff --git a/app/controllers/api/ranks_controller.rb b/app/controllers/api/ranks_controller.rb index f299483faf..4e6b4b5607 100644 --- a/app/controllers/api/ranks_controller.rb +++ b/app/controllers/api/ranks_controller.rb @@ -7,6 +7,6 @@ class Api::RanksController < ApplicationController def collection @ranks ||= end_of_association_chain. select([:id, :name]). - map{ |d| { :value => d.id, :text => d.name } } + map { |d| { :value => d.id, :text => d.name } } end end diff --git a/app/controllers/api/v1/auto_complete_taxon_concepts_controller.rb b/app/controllers/api/v1/auto_complete_taxon_concepts_controller.rb index 03ddbe8518..5851b8a111 100644 --- a/app/controllers/api/v1/auto_complete_taxon_concepts_controller.rb +++ b/app/controllers/api/v1/auto_complete_taxon_concepts_controller.rb @@ -11,7 +11,7 @@ def index :rank_headers => @taxon_concepts.map(&:rank_display_name).uniq.map do |r| { :rank_name => r, - :taxon_concept_ids => @taxon_concepts.select{ |tc| tc.rank_display_name == r }.map(&:id) + :taxon_concept_ids => @taxon_concepts.select { |tc| tc.rank_display_name == r }.map(&:id) } end } diff --git a/app/controllers/api/v1/purposes_controller.rb b/app/controllers/api/v1/purposes_controller.rb index 76f257bea8..1920ae1f19 100644 --- a/app/controllers/api/v1/purposes_controller.rb +++ b/app/controllers/api/v1/purposes_controller.rb @@ -1,6 +1,6 @@ class Api::V1::PurposesController < ApplicationController caches_action :index, :cache_path => Proc.new { |c| - { :locale => "en" }.merge(c.params.select{ |k, v| !v.blank? && "locale" == k }) + { :locale => "en" }.merge(c.params.select { |k, v| !v.blank? && "locale" == k }) } def index @purposes = Purpose.all(:order => "code") diff --git a/app/controllers/api/v1/sources_controller.rb b/app/controllers/api/v1/sources_controller.rb index c0b5cbf392..dae664fb61 100644 --- a/app/controllers/api/v1/sources_controller.rb +++ b/app/controllers/api/v1/sources_controller.rb @@ -1,6 +1,6 @@ class Api::V1::SourcesController < ApplicationController caches_action :index, :cache_path => Proc.new { |c| - { :locale => "en" }.merge(c.params.select{ |k, v| !v.blank? && "locale" == k }) + { :locale => "en" }.merge(c.params.select { |k, v| !v.blank? && "locale" == k }) } def index @sources = Source.all(:order => "code") diff --git a/app/controllers/api/v1/terms_controller.rb b/app/controllers/api/v1/terms_controller.rb index 719866ca5a..66686cac9d 100644 --- a/app/controllers/api/v1/terms_controller.rb +++ b/app/controllers/api/v1/terms_controller.rb @@ -1,6 +1,6 @@ class Api::V1::TermsController < ApplicationController caches_action :index, :cache_path => Proc.new { |c| - { :locale => "en" }.merge(c.params.select{ |k, v| !v.blank? && "locale" == k }) + { :locale => "en" }.merge(c.params.select { |k, v| !v.blank? && "locale" == k }) } def index @terms = Term.all(:order => "code") diff --git a/app/controllers/api/v1/units_controller.rb b/app/controllers/api/v1/units_controller.rb index 1bb48692d1..c28094f81d 100644 --- a/app/controllers/api/v1/units_controller.rb +++ b/app/controllers/api/v1/units_controller.rb @@ -1,6 +1,6 @@ class Api::V1::UnitsController < ApplicationController caches_action :index, :cache_path => Proc.new { |c| - { :locale => "en" }.merge(c.params.select{ |k, v| !v.blank? && "locale" == k }) + { :locale => "en" }.merge(c.params.select { |k, v| !v.blank? && "locale" == k }) } def index @units = Unit.all(:order => "code") diff --git a/app/helpers/admin/nomenclature_changes_helper.rb b/app/helpers/admin/nomenclature_changes_helper.rb index cd228b35f0..6943d0e0f1 100644 --- a/app/helpers/admin/nomenclature_changes_helper.rb +++ b/app/helpers/admin/nomenclature_changes_helper.rb @@ -34,7 +34,7 @@ def progress_bar def print_summary(summary) if summary.kind_of?(Array) content_tag(:ul) do - summary.each{ |line| concat print_summary(line) } + summary.each { |line| concat print_summary(line) } end else content_tag(:li, summary) @@ -320,7 +320,7 @@ def select_outputs end def sorted_parent_reassignments(ff) - ff.object.parent_reassignments.sort_by{ |reassignment| reassignment.reassignable.full_name } + ff.object.parent_reassignments.sort_by { |reassignment| reassignment.reassignable.full_name } end def name_reassignment_label(reassignment) diff --git a/app/helpers/admin_helper.rb b/app/helpers/admin_helper.rb index 2370f977cb..3157f873bf 100644 --- a/app/helpers/admin_helper.rb +++ b/app/helpers/admin_helper.rb @@ -70,7 +70,7 @@ def true_false_icon(bool_value) end def tag_list(tags_ary) - tags_ary.map{ |t| content_tag(:span, :class => 'myMinTag'){ t } }.join(', ').html_safe + tags_ary.map { |t| content_tag(:span, :class => 'myMinTag') { t } }.join(', ').html_safe end def error_messages_for(resource) @@ -135,10 +135,10 @@ def admin_new_modal(options = {}) button_tag( :type => "button", :class => "close", :"data-dismiss" => "modal", :"aria-hidden" => true - ){ '×' } + + ) { '×' } + content_tag(:h3, :id => "#{id}-label" - ){ title } + ) { title } end + content_tag( :div, :id => "admin-#{id}-form", :class => "modal-body" #TODO @@ -153,18 +153,18 @@ def admin_new_modal(options = {}) button_tag( :type => "button", :class => "btn", :"data-dismiss" => "modal", :"aria-hidden" => "true" - ){ 'Close' } + + ) { 'Close' } + if options[:save_and_reopen] button_tag( :type => "button", :class => "btn btn-primary save-button save-and-reopen-button" - ){ 'Save changes' } + + ) { 'Save changes' } + button_tag( :type => "button", :class => "btn btn-primary save-button" - ){ 'Save changes & close' } + ) { 'Save changes & close' } else button_tag( :type => "button", :class => "btn btn-primary save-button" - ){ 'Save changes' } + ) { 'Save changes' } end end end diff --git a/app/helpers/taxon_concept_helper.rb b/app/helpers/taxon_concept_helper.rb index f49156df90..cf3be72bd7 100644 --- a/app/helpers/taxon_concept_helper.rb +++ b/app/helpers/taxon_concept_helper.rb @@ -73,7 +73,7 @@ def admin_new_synonym_modal(options = {}) admin_new_modal( resource: 'taxon_concept_synonym', title: options[:title] || nil - ){ nested ? '' : render('synonym_form') } + ) { nested ? '' : render('synonym_form') } end def admin_new_trade_name_modal(options = {}) @@ -81,7 +81,7 @@ def admin_new_trade_name_modal(options = {}) admin_new_modal( resource: 'taxon_concept_trade_name', title: options[:title] || nil - ){ nested ? '' : render('trade_name_form') } + ) { nested ? '' : render('trade_name_form') } end def admin_new_hybrid_modal(options = {}) @@ -89,7 +89,7 @@ def admin_new_hybrid_modal(options = {}) admin_new_modal( resource: 'taxon_concept_hybrid', title: options[:title] || nil - ){ nested ? '' : render('hybrid_form') } + ) { nested ? '' : render('hybrid_form') } end def admin_new_n_name_modal(options = {}) @@ -97,7 +97,7 @@ def admin_new_n_name_modal(options = {}) admin_new_modal( resource: 'taxon_concept_n_name', title: options[:title] || nil - ){ nested ? '' : render('n_name_form') } + ) { nested ? '' : render('n_name_form') } end def admin_new_taxon_concept_modal(options = {}) @@ -105,7 +105,7 @@ def admin_new_taxon_concept_modal(options = {}) admin_new_modal( resource: 'taxon_concept', title: options[:title] || nil - ){ nested ? '' : render('form') } + ) { nested ? '' : render('form') } end def admin_add_new_distribution_button @@ -134,7 +134,7 @@ def admin_add_new_cites_suspension_button def admin_new_distribution_modal(nested = false) admin_new_modal( :resource => 'distribution' - ){ nested ? '' : render('admin/distributions/form') } + ) { nested ? '' : render('admin/distributions/form') } end def admin_edit_distribution_modal(nested = false) @@ -142,7 +142,7 @@ def admin_edit_distribution_modal(nested = false) :resource => 'distribution', :id => 'edit-distribution', :title => 'Edit Distribution' - ){ nested ? '' : render('admin/distributions/form') } + ) { nested ? '' : render('admin/distributions/form') } end def admin_add_new_reference_button @@ -166,7 +166,7 @@ def admin_new_reference_modal(nested = false) def admin_new_cites_suspension_modal admin_new_modal( :resource => 'cites_suspension' - ){ '' } + ) { '' } end def admin_add_new_common_name_button @@ -182,7 +182,7 @@ def admin_add_new_common_name_button def admin_new_common_name_modal admin_new_modal( :resource => 'common_name', :save_and_reopen => true - ){ '' } + ) { '' } end def excluded_taxon_concepts_tooltip(obj) diff --git a/app/models/change_type.rb b/app/models/change_type.rb index 79164133a4..09c0c64aea 100644 --- a/app/models/change_type.rb +++ b/app/models/change_type.rb @@ -28,7 +28,7 @@ class ChangeType < ActiveRecord::Base def abbreviation self.name.split('_'). - map{ |a| a[0..2] }.join('-') + map { |a| a[0..2] }.join('-') end def print_name diff --git a/app/models/checklist/checklist.rb b/app/models/checklist/checklist.rb index 28c1830bd0..903d25070a 100644 --- a/app/models/checklist/checklist.rb +++ b/app/models/checklist/checklist.rb @@ -82,7 +82,7 @@ def prepare_kindom_queries; end # @return [Array] an array containing a hash of search results and # related metadata def generate - @animalia, @plantae = cached_results.partition{ |item| item.kingdom_position == 0 } + @animalia, @plantae = cached_results.partition { |item| item.kingdom_position == 0 } if @output_layout == :taxonomic injector = Checklist::HigherTaxaInjector.new(@animalia) @animalia = injector.run diff --git a/app/models/checklist/higher_taxa_injector.rb b/app/models/checklist/higher_taxa_injector.rb index 8958bd6bef..2b673716a2 100644 --- a/app/models/checklist/higher_taxa_injector.rb +++ b/app/models/checklist/higher_taxa_injector.rb @@ -86,7 +86,7 @@ def higher_taxa_headers(prev_item, curr_item) ranks = [ranks.last].compact unless @expand_headers res = [] - @last_ancestor_ids = @header_ranks.map{ |rank| curr_item.send("#{rank.downcase}_id") } + @last_ancestor_ids = @header_ranks.map { |rank| curr_item.send("#{rank.downcase}_id") } ranks.each_with_index do |rank, idx| higher_taxon_id = curr_item.send("#{rank.downcase}_id") diff --git a/app/models/iucn_mapping_manager.rb b/app/models/iucn_mapping_manager.rb index ab21edc092..8f75cf88dd 100644 --- a/app/models/iucn_mapping_manager.rb +++ b/app/models/iucn_mapping_manager.rb @@ -75,7 +75,7 @@ def type_of_match(tc, match) def strip_authors(author) return '' unless author author.split(" "). - reject{ |p| ["and", "&", "&", ","].include?(p) }. + reject { |p| ["and", "&", "&", ","].include?(p) }. join(" ") end end diff --git a/app/models/m_taxon_concept_filter_by_appendix_query.rb b/app/models/m_taxon_concept_filter_by_appendix_query.rb index 35a252fafc..6d6370bb95 100644 --- a/app/models/m_taxon_concept_filter_by_appendix_query.rb +++ b/app/models/m_taxon_concept_filter_by_appendix_query.rb @@ -13,7 +13,7 @@ def initialize_species_listings_conditions(designation_name = 'CITES') #{@table}.#{designation_name.downcase}_listing_original, '/' ) && - ARRAY[#{@appendix_abbreviations.map{ |e| "'#{e}'" }.join(',')}]::TEXT[] + ARRAY[#{@appendix_abbreviations.map { |e| "'#{e}'" }.join(',')}]::TEXT[] SQL end @species_listings_ids = SpeciesListing.where(:abbreviation => @appendix_abbreviations).map(&:id) diff --git a/app/models/m_taxon_concept_filter_by_id_with_descendants.rb b/app/models/m_taxon_concept_filter_by_id_with_descendants.rb index ea3945e57e..113f3c750a 100644 --- a/app/models/m_taxon_concept_filter_by_id_with_descendants.rb +++ b/app/models/m_taxon_concept_filter_by_id_with_descendants.rb @@ -14,7 +14,7 @@ def relation(ancestor_ranks = nil) fields_to_check = ( [:id] + ancestor_ranks.map { |r| "#{r.downcase}_id" } - ).map{ |c| "#{@table}.#{c}" } + ).map { |c| "#{@table}.#{c}" } @relation.where( <<-SQL ARRAY[#{fields_to_check.join(', ')}] && diff --git a/app/models/nomenclature_change/delete_unreassigned_processor.rb b/app/models/nomenclature_change/delete_unreassigned_processor.rb index 48736a06a3..29bccf02ad 100644 --- a/app/models/nomenclature_change/delete_unreassigned_processor.rb +++ b/app/models/nomenclature_change/delete_unreassigned_processor.rb @@ -10,24 +10,24 @@ def run end def process_unreassigned_distributions - distributions = @input.distribution_reassignments.map{ |dr| + distributions = @input.distribution_reassignments.map { |dr| dr.reassignable if _is_input_reassignment(dr) }.compact @input.taxon_concept.distributions.each do |distribution| - unless distributions.map{ |dr| dr.id }.include?(distribution.id) + unless distributions.map { |dr| dr.id }.include?(distribution.id) distribution.destroy end end end def process_unreassigned_names - names = @input.name_reassignments.map{ |nr| + names = @input.name_reassignments.map { |nr| nr.reassignable if _is_input_reassignment(nr) }.compact @input.taxon_concept.taxon_relationships.each do |taxon_relationship| - unless names.map{ |nr| nr.id }.include?(taxon_relationship.id) + unless names.map { |nr| nr.id }.include?(taxon_relationship.id) taxon_relationship.destroy end end diff --git a/app/models/nomenclature_change/lump.rb b/app/models/nomenclature_change/lump.rb index 00ff767d59..7e865f12a2 100644 --- a/app/models/nomenclature_change/lump.rb +++ b/app/models/nomenclature_change/lump.rb @@ -32,7 +32,7 @@ class NomenclatureChange::Lump < NomenclatureChange } validate :required_inputs, if: :inputs_or_submitting? validate :required_outputs, if: :outputs_or_submitting? - before_validation :set_output_name_status, if: Proc.new{ |nc| + before_validation :set_output_name_status, if: Proc.new { |nc| !nc.inputs.empty? && nc.output && nc.outputs_or_submitting? } before_save :build_auto_reassignments, if: :notes? @@ -71,11 +71,11 @@ def set_output_name_status end def inputs_except_outputs - inputs.reject{ |i| i.taxon_concept == output.try(:taxon_concept) } + inputs.reject { |i| i.taxon_concept == output.try(:taxon_concept) } end def inputs_intersect_outputs - inputs.select{ |o| o.taxon_concept == output.try(:taxon_concept) } + inputs.select { |o| o.taxon_concept == output.try(:taxon_concept) } end def new_output_rank diff --git a/app/models/nomenclature_change/lump/processor.rb b/app/models/nomenclature_change/lump/processor.rb index 506061629d..324412a014 100644 --- a/app/models/nomenclature_change/lump/processor.rb +++ b/app/models/nomenclature_change/lump/processor.rb @@ -6,7 +6,7 @@ def summary "The following taxa will be lumped into #{@nc.output.display_full_name}", @nc.inputs.map(&:taxon_concept).map(&:full_name) ]] - @subprocessors.each{ |processor| result << processor.summary } + @subprocessors.each { |processor| result << processor.summary } result.flatten(1) end diff --git a/app/models/nomenclature_change/processor.rb b/app/models/nomenclature_change/processor.rb index a0899d926b..fc435758e2 100644 --- a/app/models/nomenclature_change/processor.rb +++ b/app/models/nomenclature_change/processor.rb @@ -9,7 +9,7 @@ def initialize(nc) # Runs the subprocessors chain def run Rails.logger.warn("[#{@nc.type}] BEGIN") - @subprocessors.each{ |processor| processor.run } + @subprocessors.each { |processor| processor.run } Rails.logger.warn("[#{@nc.type}] END") DownloadsCache.clear end diff --git a/app/models/nomenclature_change/split.rb b/app/models/nomenclature_change/split.rb index baa19734ce..c8dc95f302 100644 --- a/app/models/nomenclature_change/split.rb +++ b/app/models/nomenclature_change/split.rb @@ -95,11 +95,11 @@ def set_outputs_rank_id end def outputs_except_inputs - outputs.reject{ |o| o.taxon_concept == input.try(:taxon_concept) } + outputs.reject { |o| o.taxon_concept == input.try(:taxon_concept) } end def outputs_intersect_inputs - outputs.select{ |o| o.taxon_concept == input.try(:taxon_concept) } + outputs.select { |o| o.taxon_concept == input.try(:taxon_concept) } end def new_output_rank diff --git a/app/models/nomenclature_change/split/processor.rb b/app/models/nomenclature_change/split/processor.rb index 7524717723..8e5c5cdf98 100644 --- a/app/models/nomenclature_change/split/processor.rb +++ b/app/models/nomenclature_change/split/processor.rb @@ -6,7 +6,7 @@ def summary "#{@nc.input.taxon_concept.full_name} will be split into:", @nc.outputs.map(&:display_full_name) ]] - @subprocessors.each{ |processor| result << processor.summary } + @subprocessors.each { |processor| result << processor.summary } result.flatten(1) end @@ -16,7 +16,7 @@ def summary # A subprocessor needs to respond to #run def prepare_chain chain = [] - input_is_one_of_outputs = @outputs.reject{ |o| o.will_create_taxon? }. + input_is_one_of_outputs = @outputs.reject { |o| o.will_create_taxon? }. map(&:taxon_concept_id).include?(@input.taxon_concept_id) chain << NomenclatureChange::InputTaxonConceptProcessor.new(@input) diff --git a/app/models/nomenclature_change/status_change/processor_helpers.rb b/app/models/nomenclature_change/status_change/processor_helpers.rb index 64da92cd92..8e1f3ca1dc 100644 --- a/app/models/nomenclature_change/status_change/processor_helpers.rb +++ b/app/models/nomenclature_change/status_change/processor_helpers.rb @@ -19,7 +19,7 @@ def reassignment_processor(output) # Generate a summary based on the subprocessors chain def summary result = [] - @subprocessors.each{ |processor| result << processor.summary } + @subprocessors.each { |processor| result << processor.summary } result.flatten(1).compact end diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index abe6f9f328..abf276ce3c 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -198,7 +198,7 @@ class TaxonConcept < ActiveRecord::Base translates :nomenclature_note - scope :at_parent_ranks, lambda{ |rank| + scope :at_parent_ranks, lambda { |rank| joins_sql = <<-SQL INNER JOIN ranks ON ranks.id = taxon_concepts.rank_id AND ranks.taxonomic_position >= ? @@ -211,7 +211,7 @@ class TaxonConcept < ActiveRecord::Base ) } - scope :at_ancestor_ranks, lambda{ |rank| + scope :at_ancestor_ranks, lambda { |rank| joins_sql = <<-SQL INNER JOIN ranks ON ranks.id = taxon_concepts.rank_id AND ranks.taxonomic_position < ? @@ -221,7 +221,7 @@ class TaxonConcept < ActiveRecord::Base ) } - scope :at_self_and_ancestor_ranks, lambda{ |rank| + scope :at_self_and_ancestor_ranks, lambda { |rank| joins_sql = <<-SQL INNER JOIN ranks ON ranks.id = taxon_concepts.rank_id AND ranks.taxonomic_position <= ? @@ -240,7 +240,7 @@ def self.fetch_taxons_full_name(taxon_ids) WHERE tc.id = ANY (ARRAY#{taxon_ids.map(&:to_i)}) ORDER BY tc.id SQL - ).map{ |row| row['full_name'] } + ).map { |row| row['full_name'] } end end @@ -349,7 +349,7 @@ def standard_taxon_concept_references def inherited_standard_taxon_concept_references ref_ids = taxon_concept_references.map(&:reference_id) - standard_taxon_concept_references.keep_if{ |ref| !ref_ids.include? ref.id } + standard_taxon_concept_references.keep_if { |ref| !ref_ids.include? ref.id } end def expected_full_name(parent) diff --git a/app/models/trade/distinct_values_validation_rule.rb b/app/models/trade/distinct_values_validation_rule.rb index 99a922e4d8..94e85c56a0 100644 --- a/app/models/trade/distinct_values_validation_rule.rb +++ b/app/models/trade/distinct_values_validation_rule.rb @@ -39,7 +39,7 @@ def validation_errors_for_shipment(shipment) # only the first two are taken into consideration. def matching_records_arel(table_name) s = Arel::Table.new("#{table_name}_view") - arel_columns = column_names.map{ |c| Arel::Attribute.new(s, c) } + arel_columns = column_names.map { |c| Arel::Attribute.new(s, c) } Trade::SandboxTemplate.select('*').from("#{table_name}_view").where( arel_columns.shift.eq(arel_columns.shift) ) diff --git a/app/models/trade/filter.rb b/app/models/trade/filter.rb index c2e9f51c84..de8db082e3 100644 --- a/app/models/trade/filter.rb +++ b/app/models/trade/filter.rb @@ -53,7 +53,7 @@ def initialize_query [:"#{tc.rank_name.downcase}_id", tc.id] end @query = @query.where( - taxon_concepts_conditions.map{ |c| "taxon_concept_#{c[0]} = #{c[1]}" }.join(' OR ') + taxon_concepts_conditions.map { |c| "taxon_concept_#{c[0]} = #{c[1]}" }.join(' OR ') ) end @@ -69,7 +69,7 @@ def initialize_query [:"#{tc.rank_name.downcase}_id", tc.id] end @query = @query.where( - reported_taxon_concepts_conditions.map{ |c| "reported_taxon_concept_#{c[0]} = #{c[1]}" }.join(' OR ') + reported_taxon_concepts_conditions.map { |c| "reported_taxon_concept_#{c[0]} = #{c[1]}" }.join(' OR ') ) end diff --git a/app/models/trade/format_validation_rule.rb b/app/models/trade/format_validation_rule.rb index 3bb0038bb9..0fd9151ef3 100644 --- a/app/models/trade/format_validation_rule.rb +++ b/app/models/trade/format_validation_rule.rb @@ -28,7 +28,7 @@ def error_message # specified in column_names. def matching_records(table_name) s = Arel::Table.new(table_name) - arel_nodes = column_names.map{ |c| "#{c} !~ '#{format_re}'" } + arel_nodes = column_names.map { |c| "#{c} !~ '#{format_re}'" } Trade::SandboxTemplate.select('*').from(table_name).where(arel_nodes.inject(&:or)) end end diff --git a/app/models/trade/inclusion_validation_rule.rb b/app/models/trade/inclusion_validation_rule.rb index d67831f22b..69294de490 100644 --- a/app/models/trade/inclusion_validation_rule.rb +++ b/app/models/trade/inclusion_validation_rule.rb @@ -46,7 +46,7 @@ def error_message(values_hash = nil) def validation_errors(annual_report_upload) matching_records_grouped(annual_report_upload.sandbox.table_name).map do |mr| - values_hash = Hash[column_names_for_display.map{ |cn| [cn, mr.send(cn)] }] + values_hash = Hash[column_names_for_display.map { |cn| [cn, mr.send(cn)] }] Trade::ValidationError.new( :error_message => error_message(values_hash), :annual_report_upload_id => annual_report_upload.id, @@ -90,7 +90,7 @@ def matching_records_grouped(table_name) ['COUNT(*) AS error_count', 'ARRAY_AGG(id) AS matching_records_ids'] ).from(Arel.sql("(#{matching_records_arel(table_name).to_sql}) AS matching_records")). group(column_names_for_display).having( - required_column_names.map{ |cn| "#{cn} IS NOT NULL" }.join(' AND ') + required_column_names.map { |cn| "#{cn} IS NOT NULL" }.join(' AND ') ) end @@ -102,16 +102,16 @@ def scoped_records_arel(s) s[c].not_eq(nil) end not_null_conds = not_null_nodes.shift - not_null_nodes.each{ |n| not_null_conds = not_null_conds.and(n) } + not_null_nodes.each { |n| not_null_conds = not_null_conds.and(n) } result = s.project('*').where(not_null_conds) scope_nodes = sanitized_sandbox_scope.map do |scope_column, scope_def| tmp = [] if scope_def['inclusion'] - inclusion_nodes = scope_def['inclusion'].map{ |value| s[scope_column].eq(value) } + inclusion_nodes = scope_def['inclusion'].map { |value| s[scope_column].eq(value) } tmp << inclusion_nodes.inject(&:or) end if scope_def['exclusion'] - exclusion_nodes = scope_def['exclusion'].map{ |value| s[scope_column].not_eq(value) } + exclusion_nodes = scope_def['exclusion'].map { |value| s[scope_column].not_eq(value) } tmp << exclusion_nodes.inject(&:or) end if scope_def['blank'] diff --git a/app/models/trade/numericality_validation_rule.rb b/app/models/trade/numericality_validation_rule.rb index 5d234b0a0e..ed34b53b61 100644 --- a/app/models/trade/numericality_validation_rule.rb +++ b/app/models/trade/numericality_validation_rule.rb @@ -27,11 +27,11 @@ def error_message # specified in column_names. def matching_records(table_name) s = Arel::Table.new(table_name) - arel_columns = column_names.map{ |c| Arel::Attribute.new(s, c) } + arel_columns = column_names.map { |c| Arel::Attribute.new(s, c) } isnumeric_columns = arel_columns.map do |a| Arel::Nodes::NamedFunction.new 'isnumeric', [a] end - arel_nodes = isnumeric_columns.map{ |c| c.eq(false) } + arel_nodes = isnumeric_columns.map { |c| c.eq(false) } Trade::SandboxTemplate.select('*').from(table_name).where(arel_nodes.inject(&:or)) end end diff --git a/app/models/trade/sandbox_template.rb b/app/models/trade/sandbox_template.rb index bb2573fdb0..4c61d81820 100644 --- a/app/models/trade/sandbox_template.rb +++ b/app/models/trade/sandbox_template.rb @@ -31,8 +31,8 @@ class Trade::SandboxTemplate < ActiveRecord::Base ] CSV_IMPORTER_COLUMNS = COLUMNS_IN_CSV_ORDER CSV_EXPORTER_COLUMNS = COLUMNS_IN_CSV_ORDER - ['import_permit'] - IMPORTER_COLUMNS = CSV_IMPORTER_COLUMNS.map{ |c| c == 'species_name' ? 'taxon_name' : c } - EXPORTER_COLUMNS = CSV_EXPORTER_COLUMNS.map{ |c| c == 'species_name' ? 'taxon_name' : c } + IMPORTER_COLUMNS = CSV_IMPORTER_COLUMNS.map { |c| c == 'species_name' ? 'taxon_name' : c } + EXPORTER_COLUMNS = CSV_EXPORTER_COLUMNS.map { |c| c == 'species_name' ? 'taxon_name' : c } # Dynamically define AR class for table_name # (unless one exists already) diff --git a/app/models/trade/shipments_export.rb b/app/models/trade/shipments_export.rb index e8f62c92a9..f6c0133684 100644 --- a/app/models/trade/shipments_export.rb +++ b/app/models/trade/shipments_export.rb @@ -131,7 +131,7 @@ def report_columns end def sql_columns - report_columns.map{ |column, properties| properties[I18n.locale] || column } + report_columns.map { |column, properties| properties[I18n.locale] || column } end end diff --git a/app/models/trade/shipments_gross_exports_export.rb b/app/models/trade/shipments_gross_exports_export.rb index fef9de2efc..b217532024 100644 --- a/app/models/trade/shipments_gross_exports_export.rb +++ b/app/models/trade/shipments_gross_exports_export.rb @@ -27,7 +27,7 @@ def outer_report_columns end def sql_columns - outer_report_columns.map{ |column, properties| properties[I18n.locale] || column } + outer_report_columns.map { |column, properties| properties[I18n.locale] || column } end def csv_column_headers @@ -41,7 +41,7 @@ def years end def years_columns - years.map{ |y| "\"#{y}\"" } + years.map { |y| "\"#{y}\"" } end def available_columns @@ -84,7 +84,7 @@ def report_crosstab_columns end def sql_crosstab_columns - report_crosstab_columns.map{ |c| available_columns[c][I18n.locale] || c } + report_crosstab_columns.map { |c| available_columns[c][I18n.locale] || c } end # the query before pivoting @@ -107,8 +107,8 @@ def ct_subquery_sql(options) categories_sql = ActiveRecord::Base.send(:sanitize_sql_array, [categories_sql, years.map(&:to_i)]) ct_columns = [ 'row_name TEXT[]', - report_crosstab_columns.map.each_with_index{ |c, i| "#{sql_crosstab_columns[i]} #{crosstab_columns[c][:pg_type]}" }, - years_columns.map{ |y| "#{y} numeric" } + report_crosstab_columns.map.each_with_index { |c, i| "#{sql_crosstab_columns[i]} #{crosstab_columns[c][:pg_type]}" }, + years_columns.map { |y| "#{y} numeric" } ].flatten.join(', ') # a set returning query requires that output columns are specified <<-SQL diff --git a/app/models/trade/taxon_concept_appendix_year_validation_rule.rb b/app/models/trade/taxon_concept_appendix_year_validation_rule.rb index e6517590bc..675b324ec0 100644 --- a/app/models/trade/taxon_concept_appendix_year_validation_rule.rb +++ b/app/models/trade/taxon_concept_appendix_year_validation_rule.rb @@ -61,7 +61,7 @@ def matching_records_arel(table_name) s[c].not_eq(nil) end not_null_conds = not_null_nodes.shift - not_null_nodes.each{ |n| not_null_conds = not_null_conds.and(n) } + not_null_nodes.each { |n| not_null_conds = not_null_conds.and(n) } s.project('*').where(not_null_conds).except(valid_values) end diff --git a/app/models/trade/taxon_concept_source_validation_rule.rb b/app/models/trade/taxon_concept_source_validation_rule.rb index 9af586b6fe..4be76c912a 100644 --- a/app/models/trade/taxon_concept_source_validation_rule.rb +++ b/app/models/trade/taxon_concept_source_validation_rule.rb @@ -49,11 +49,11 @@ def matching_records_grouped(table_name) ).where(<<-SQL ( UPPER(taxon_concepts.data->'kingdom_name') = 'ANIMALIA' - AND source_code IN (#{INVALID_KINGDOM_SOURCE['ANIMALIA'].map{ |c| "'#{c}'" }.join(',')}) + AND source_code IN (#{INVALID_KINGDOM_SOURCE['ANIMALIA'].map { |c| "'#{c}'" }.join(',')}) ) OR ( UPPER(taxon_concepts.data->'kingdom_name') = 'PLANTAE' - AND source_code IN (#{INVALID_KINGDOM_SOURCE['PLANTAE'].map{ |c| "'#{c}'" }.join(',')}) + AND source_code IN (#{INVALID_KINGDOM_SOURCE['PLANTAE'].map { |c| "'#{c}'" }.join(',')}) ) SQL ). diff --git a/app/models/trade/validation_rule.rb b/app/models/trade/validation_rule.rb index 4e9b916f08..e1da8a0c0c 100644 --- a/app/models/trade/validation_rule.rb +++ b/app/models/trade/validation_rule.rb @@ -110,14 +110,14 @@ def sanitized_shipments_scope when 'exporter', 'importer', 'country_of_origin' tmp_def = {} (scope_def.keys & ['inclusion', 'exclusion']).each do |k| - tmp_def[k] = scope_def[k].map{ |value| GeoEntity.find_by_iso_code2(value).id } + tmp_def[k] = scope_def[k].map { |value| GeoEntity.find_by_iso_code2(value).id } end tmp_def['blank'] = scope_def['blank'] if scope_def.key?('blank') res[scope_column + '_id'] = tmp_def when /(.+)_code$/ tmp_def = {} (scope_def.keys & ['inclusion', 'exclusion']).each do |k| - tmp_def[k] = scope_def[k].map{ |value| TradeCode.find_by_type_and_code($1.capitalize, value).id } + tmp_def[k] = scope_def[k].map { |value| TradeCode.find_by_type_and_code($1.capitalize, value).id } end tmp_def['blank'] = scope_def['blank'] if scope_def.key?('blank') res[$1 + '_id'] = tmp_def diff --git a/app/serializers/trade/show_annual_report_upload_serializer.rb b/app/serializers/trade/show_annual_report_upload_serializer.rb index cb51ed40e4..7d8d247bc9 100644 --- a/app/serializers/trade/show_annual_report_upload_serializer.rb +++ b/app/serializers/trade/show_annual_report_upload_serializer.rb @@ -14,7 +14,7 @@ def file_name end def has_primary_errors - !validation_errors.index{ |ve| ve.is_primary }.nil? + !validation_errors.index { |ve| ve.is_primary }.nil? end def created_at diff --git a/lib/modules/dictionary.rb b/lib/modules/dictionary.rb index 0d6d4c834f..07e1457185 100644 --- a/lib/modules/dictionary.rb +++ b/lib/modules/dictionary.rb @@ -12,7 +12,7 @@ def build_dictionary(*keys) # const_set key.to_s.upcase, key.to_s.upcase # end # define_singleton_method("dict") { keys.map{|k| k.to_s.upcase } } - build_basic_dictionary(*keys){ |key| key.to_s.upcase } + build_basic_dictionary(*keys) { |key| key.to_s.upcase } end def build_basic_dictionary(*keys) @@ -24,7 +24,7 @@ def build_basic_dictionary(*keys) key end end - define_singleton_method("dict") { keys.map{ |k| k.to_s.upcase } } + define_singleton_method("dict") { keys.map { |k| k.to_s.upcase } } end end end diff --git a/lib/modules/sapi/stored_procedures.rb b/lib/modules/sapi/stored_procedures.rb index b683a72a2c..177c48cbb6 100644 --- a/lib/modules/sapi/stored_procedures.rb +++ b/lib/modules/sapi/stored_procedures.rb @@ -18,7 +18,7 @@ def self.rebuild :touch_cites_taxon_concepts, :touch_eu_taxon_concepts, :touch_cms_taxon_concepts - ].each{ |p| + ].each { |p| puts "Procedure: #{p}" ActiveRecord::Base.connection.execute("SELECT * FROM rebuild_#{p}()") } @@ -83,7 +83,7 @@ def self.rebuild_eu_taxonomy_and_listings end def self.run_procedures(procedures) - procedures.each{ |p| + procedures.each { |p| puts "Procedure: #{p}" ActiveRecord::Base.connection.execute("SELECT * FROM rebuild_#{p}()") } diff --git a/lib/modules/search_param_sanitiser.rb b/lib/modules/search_param_sanitiser.rb index 506480d52b..05593ad8fc 100644 --- a/lib/modules/search_param_sanitiser.rb +++ b/lib/modules/search_param_sanitiser.rb @@ -43,7 +43,7 @@ def sanitise_float(f, default = nil) def sanitise_integer_array(ary) new_ary = ary.is_a?(String) ? ary.split(',') : ary return [] if new_ary.blank? || !new_ary.is_a?(Array) - new_ary.map!{ |e| sanitise_positive_integer(e) } + new_ary.map! { |e| sanitise_positive_integer(e) } new_ary.compact! new_ary.sort! new_ary diff --git a/lib/modules/statistics.rb b/lib/modules/statistics.rb index 41467b7124..ba7ca64fe1 100644 --- a/lib/modules/statistics.rb +++ b/lib/modules/statistics.rb @@ -3,7 +3,7 @@ module Statistics def self.get_total_transactions_per_year trade_transactions = {} years = Trade::Shipment.where("year is not null").uniq.pluck(:year) - years.each{ |y| + years.each { |y| unless y.nil? reported_by_exporter = Trade::Shipment.where(:year => y, :reported_by_exporter => true).count diff --git a/lib/tasks/db_migrate_plpgsql.rake b/lib/tasks/db_migrate_plpgsql.rake index 3092cedc55..42d1ccae00 100644 --- a/lib/tasks/db_migrate_plpgsql.rake +++ b/lib/tasks/db_migrate_plpgsql.rake @@ -40,7 +40,7 @@ namespace :db do puts "Deleting permits" ActiveRecord::Base.connection.execute('DELETE FROM trade_permits') puts "Deleting annual report uploads & dropping sandboxes" - Trade::AnnualReportUpload.all.each{ |aru| aru.destroy } + Trade::AnnualReportUpload.all.each { |aru| aru.destroy } end end diff --git a/lib/tasks/elibrary/importable.rb b/lib/tasks/elibrary/importable.rb index ace112f700..1cdaaa2b66 100644 --- a/lib/tasks/elibrary/importable.rb +++ b/lib/tasks/elibrary/importable.rb @@ -4,10 +4,10 @@ module Importable def run drop_table_if_exists(table_name) create_table_from_column_array( - table_name, columns_with_type.map{ |ct| ct.join(' ') } + table_name, columns_with_type.map { |ct| ct.join(' ') } ) copy_from_csv( - @file_name, table_name, columns_with_type.map{ |ct| ct.first } + @file_name, table_name, columns_with_type.map { |ct| ct.first } ) run_preparatory_queries print_pre_import_stats diff --git a/lib/tasks/helpers_for_import.rb b/lib/tasks/helpers_for_import.rb index 68f8ca22d9..ecfd04615d 100644 --- a/lib/tasks/helpers_for_import.rb +++ b/lib/tasks/helpers_for_import.rb @@ -340,7 +340,7 @@ def csv_to_db(table, field) end def files_from_args(t, args) - files = t.arg_names.map{ |a| args[a] }.compact + files = t.arg_names.map { |a| args[a] }.compact files = ['lib/files/animals.csv'] if files.empty? files.reject { |file| !file_ok?(file) } end @@ -357,7 +357,7 @@ def file_ok?(path_to_file) def csv_headers(path_to_file) res = nil CSV.foreach(path_to_file) do |row| - res = row.map{ |h| h && h.chomp.sub(/^\W/, '') }.compact + res = row.map { |h| h && h.chomp.sub(/^\W/, '') }.compact break end res @@ -367,8 +367,8 @@ def db_columns_from_csv_headers(path_to_file, table_name, include_data_type = tr m = CsvToDbMap.instance #work out the db columns to create csv_columns = csv_headers(path_to_file) - db_columns = csv_columns.map{ |col| m.csv_to_db(table_name, col) } - db_columns = db_columns.map{ |col| col.sub(/\s\w+$/, '') } unless include_data_type + db_columns = csv_columns.map { |col| m.csv_to_db(table_name, col) } + db_columns = db_columns.map { |col| col.sub(/\s\w+$/, '') } unless include_data_type puts csv_columns.inspect puts db_columns.inspect db_columns diff --git a/lib/tasks/import_cites_parties.rake b/lib/tasks/import_cites_parties.rake index 269ba84f00..9180b1878c 100644 --- a/lib/tasks/import_cites_parties.rake +++ b/lib/tasks/import_cites_parties.rake @@ -2,7 +2,7 @@ namespace :import do desc 'Import CITES parties' task :cites_parties => [:environment] do parties_iso_codes = %w( AF AL DZ AG AR AM AU AT AZ BS BH BD BB BY BE BZ BJ BT BO BA BW BR BN BG BF BI KH CM CA CV CF TD CL CN CO KM CG CR CI HR CU CY CZ CD DK DJ DM DO EC EG SV GQ ER EE ET FJ FI FR GA GM GE DE GH GR GD GT GN GW GY HN HU IS IN ID IR IE IL IT JM JP JO KZ KE KW KG LA LV LB LS LR LY LI LT LU MG MW MY MV ML MT MR MU MX MC MN ME MA MZ MM NA NP NL NZ NI NE NG NO OM PK PW PA PG PY PE PH PL PT QA KR MD RO RU RW KN LC VC WS SM ST SA SN RS SC SL SG SK SI SB SO ZA ES LK SD SR SZ SE CH SY TH MK TG TT TN TR UG UA AE GB TZ US UY UZ VU VE VN YE ZM ZW) - parties_iso_codes_pg_ary = parties_iso_codes.map{ |ic| "'#{ic}'" }.join(',') + parties_iso_codes_pg_ary = parties_iso_codes.map { |ic| "'#{ic}'" }.join(',') sql = <<-SQL INSERT INTO designation_geo_entities (designation_id, geo_entity_id, created_at, updated_at) SELECT subquery.*, NOW(), NOW() diff --git a/lib/tasks/resolve_host_to_country.rake b/lib/tasks/resolve_host_to_country.rake index 302b3a2d04..5605f89194 100644 --- a/lib/tasks/resolve_host_to_country.rake +++ b/lib/tasks/resolve_host_to_country.rake @@ -7,6 +7,6 @@ task :resolve_host_to_country => :environment do end CSV.open('/home/agnessa/Data/hosts_and_countries.csv', 'w') do |csv| csv << ['Host', 'Country'] - hosts_and_countries.each{ |row| csv << row } + hosts_and_countries.each { |row| csv << row } end end diff --git a/lib/tasks/update_eu_decisions_with_missing_source.rake b/lib/tasks/update_eu_decisions_with_missing_source.rake index dbbc9de353..4908d7fc99 100644 --- a/lib/tasks/update_eu_decisions_with_missing_source.rake +++ b/lib/tasks/update_eu_decisions_with_missing_source.rake @@ -4,7 +4,7 @@ namespace :update do file = "lib/files/eu_decisions_with_missing_source.csv" drop_table(TMP_TABLE) db_columns = ['full_name', 'rank_name', 'start_date', 'party_name', 'decision_type', 'source_code', 'term_code', 'notes'] - create_table_from_column_array(TMP_TABLE, db_columns.map{ |c| "#{c} TEXT" }) + create_table_from_column_array(TMP_TABLE, db_columns.map { |c| "#{c} TEXT" }) #Full Name Rank Date of Decision Party EU Decision Source Term Notes copy_data_into_table(file, TMP_TABLE, db_columns) diff --git a/spec/controllers/admin/change_types_controller_spec.rb b/spec/controllers/admin/change_types_controller_spec.rb index 2a5a0bc0fe..04bd95bc65 100644 --- a/spec/controllers/admin/change_types_controller_spec.rb +++ b/spec/controllers/admin/change_types_controller_spec.rb @@ -31,7 +31,7 @@ end describe "XHR PUT update" do - let(:change_type){ create(:change_type) } + let(:change_type) { create(:change_type) } it "responds with 200 when successful" do xhr :put, :update, :format => 'json', :id => change_type.id, :change_type => { :name => 'ZZ' } response.should be_success @@ -43,7 +43,7 @@ end describe "DELETE destroy" do - let(:change_type){ create(:change_type) } + let(:change_type) { create(:change_type) } it "redirects after delete" do delete :destroy, :id => change_type.id response.should redirect_to(admin_change_types_url) diff --git a/spec/controllers/admin/designations_controller_spec.rb b/spec/controllers/admin/designations_controller_spec.rb index 6e54ab4819..19add5d096 100644 --- a/spec/controllers/admin/designations_controller_spec.rb +++ b/spec/controllers/admin/designations_controller_spec.rb @@ -40,7 +40,7 @@ end describe "XHR PUT update" do - let(:designation){ create(:designation) } + let(:designation) { create(:designation) } it "responds with 200 when successful" do xhr :put, :update, :format => 'json', :id => designation.id, :designation => { :name => 'ZZ' } response.should be_success @@ -52,7 +52,7 @@ end describe "DELETE destroy" do - let(:designation){ create(:designation) } + let(:designation) { create(:designation) } it "redirects after delete" do delete :destroy, :id => designation.id response.should redirect_to(admin_designations_url) diff --git a/spec/controllers/admin/document_batches_controller_spec.rb b/spec/controllers/admin/document_batches_controller_spec.rb index 9ca2a3c120..4898efb69f 100644 --- a/spec/controllers/admin/document_batches_controller_spec.rb +++ b/spec/controllers/admin/document_batches_controller_spec.rb @@ -2,19 +2,19 @@ describe Admin::DocumentBatchesController, sidekiq: :inline do login_admin - let(:event){ create(:event) } - before(:each){ create(:language, iso_code1: 'EN') } + let(:event) { create(:event) } + before(:each) { create(:language, iso_code1: 'EN') } describe "GET new" do context "when no event" do - let(:document){ create(:document) } + let(:document) { create(:document) } it "renders the new template" do get :new response.should render_template('new') end end context "when event" do - let(:document){ create(:document, event_id: event.id) } + let(:document) { create(:document, event_id: event.id) } it "renders the new template" do get :new response.should render_template('new') @@ -23,15 +23,15 @@ end describe "POST create" do - let(:document_attrs){ + let(:document_attrs) { { 'type' => 'Document::Proposal' } } - let(:files){ + let(:files) { [Rack::Test::UploadedFile.new(File.join(Rails.root, 'spec', 'support', 'annual_report_upload_exporter.csv'))] } context "when no event" do - let(:document){ create(:document) } + let(:document) { create(:document) } it "creates a new Document" do expect { @@ -65,7 +65,7 @@ end context "when event" do - let(:document){ create(:document, event_id: event.id) } + let(:document) { create(:document, event_id: event.id) } it "redirects to index when successful" do post :create, event_id: event.id, document_batch: { diff --git a/spec/controllers/admin/documents_controller_spec.rb b/spec/controllers/admin/documents_controller_spec.rb index 05b86d05a6..1bd08881a1 100644 --- a/spec/controllers/admin/documents_controller_spec.rb +++ b/spec/controllers/admin/documents_controller_spec.rb @@ -2,12 +2,12 @@ describe Admin::DocumentsController, sidekiq: :inline do login_admin - let(:event){ create(:event, published_at: DateTime.new(2014, 12, 25)) } - let(:event2){ create(:event, published_at: DateTime.new(2015, 12, 12)) } - let(:taxon_concept){ create(:taxon_concept) } - let(:geo_entity){ create(:geo_entity) } - let(:proposal_outcome){ create(:proposal_outcome) } - let(:review_phase){ create(:review_phase) } + let(:event) { create(:event, published_at: DateTime.new(2014, 12, 25)) } + let(:event2) { create(:event, published_at: DateTime.new(2015, 12, 12)) } + let(:taxon_concept) { create(:taxon_concept) } + let(:geo_entity) { create(:geo_entity) } + let(:proposal_outcome) { create(:proposal_outcome) } + let(:review_phase) { create(:review_phase) } let(:process_stage) { create(:process_stage) } describe "index" do @@ -113,8 +113,8 @@ end describe "GET edit" do - let(:document_tags){ [create(:document_tag)] } - let(:document){ create(:document, tags: document_tags) } + let(:document_tags) { [create(:document_tag)] } + let(:document) { create(:document, tags: document_tags) } it "renders the edit template" do get :edit, id: document.id @@ -124,7 +124,7 @@ describe "PUT update" do context "when no event" do - let(:document){ create(:document) } + let(:document) { create(:document) } it "redirects to index when successful" do put :update, id: document.id, document: { date: Date.today } response.should redirect_to(admin_documents_url) @@ -137,7 +137,7 @@ end context "when event" do - let(:document){ create(:document, event_id: event.id) } + let(:document) { create(:document, event_id: event.id) } it "redirects to index when successful" do put :update, id: document.id, event_id: event.id, document: { date: Date.today } response.should redirect_to(admin_event_documents_url(event)) @@ -150,8 +150,8 @@ end context "with nested review_details attributes" do - let(:document){ create(:review_of_significant_trade) } - let(:review_phase){ create(:review_phase) } + let(:document) { create(:review_of_significant_trade) } + let(:review_phase) { create(:review_phase) } let(:process_stage) { create(:process_stage) } let(:recommended_category) { "A wonderful category" } @@ -184,8 +184,8 @@ end context "with nested proposal_details attributes" do - let(:document){ create(:proposal) } - let(:proposal_outcome){ create(:document_tag, type: 'DocumentTag::ProposalOutcome') } + let(:document) { create(:proposal) } + let(:proposal_outcome) { create(:document_tag, type: 'DocumentTag::ProposalOutcome') } it "assign outcome to Proposal" do put :update, id: document.id, document: { @@ -200,13 +200,13 @@ end describe "DELETE destroy" do - let(:poland){ + let(:poland) { create(:geo_entity, :name_en => 'Poland', :iso_code2 => 'PL', :geo_entity_type => country_geo_entity_type ) } - let(:document){ + let(:document) { document = create(:document) document.citations << DocumentCitation.new(geo_entity_ids: [poland.id]) document @@ -218,13 +218,13 @@ end describe "XHR GET JSON autocomplete" do - let!(:document){ + let!(:document) { create(:document, :title => 'Title', :event_id => event.id ) } - let!(:document2){ create(:document, :title => 'Title2') } + let!(:document2) { create(:document, :title => 'Title2') } context "When no event specified" do it "returns properly formatted json" do diff --git a/spec/controllers/admin/eu_regulations_controller_spec.rb b/spec/controllers/admin/eu_regulations_controller_spec.rb index 41cf41742b..263a953e3c 100644 --- a/spec/controllers/admin/eu_regulations_controller_spec.rb +++ b/spec/controllers/admin/eu_regulations_controller_spec.rb @@ -22,7 +22,7 @@ end describe "XHR POST activate" do - let(:eu_regulation){ create_eu_regulation } + let(:eu_regulation) { create_eu_regulation } it "renders create when successful" do xhr :post, :activate, :format => 'js', :id => eu_regulation.id response.should render_template("create") diff --git a/spec/controllers/admin/eu_suspension_regulations_controller_spec.rb b/spec/controllers/admin/eu_suspension_regulations_controller_spec.rb index 45c6e6246d..bcbf45e332 100644 --- a/spec/controllers/admin/eu_suspension_regulations_controller_spec.rb +++ b/spec/controllers/admin/eu_suspension_regulations_controller_spec.rb @@ -22,7 +22,7 @@ end describe "XHR POST activate" do - let(:eu_suspension_regulation){ create_eu_suspension_regulation(:is_current => true) } + let(:eu_suspension_regulation) { create_eu_suspension_regulation(:is_current => true) } it "renders create when successful" do xhr :post, :activate, :format => 'js', :id => eu_suspension_regulation.id response.should render_template("create") diff --git a/spec/controllers/admin/event_documents_controller_spec.rb b/spec/controllers/admin/event_documents_controller_spec.rb index e09dc70e16..6474d34abf 100644 --- a/spec/controllers/admin/event_documents_controller_spec.rb +++ b/spec/controllers/admin/event_documents_controller_spec.rb @@ -2,7 +2,7 @@ describe Admin::EventDocumentsController, sidekiq: :inline do login_admin - let(:event){ create(:event, published_at: DateTime.new(2014, 12, 25)) } + let(:event) { create(:event, published_at: DateTime.new(2014, 12, 25)) } describe "ordering" do before(:each) do diff --git a/spec/controllers/admin/events_controller_spec.rb b/spec/controllers/admin/events_controller_spec.rb index 5b26944433..6a4d00d483 100644 --- a/spec/controllers/admin/events_controller_spec.rb +++ b/spec/controllers/admin/events_controller_spec.rb @@ -44,7 +44,7 @@ end describe "XHR GET edit" do - let(:event){ create(:event) } + let(:event) { create(:event) } it "renders the edit template" do xhr :get, :edit, :id => event.id response.should render_template('new') @@ -56,7 +56,7 @@ end describe "XHR PUT update JSON" do - let(:event){ create(:event) } + let(:event) { create(:event) } it "responds with 200 when successful" do xhr :put, :update, :format => 'json', :id => event.id, :event => { :name => 'ZZ' } response.should be_success @@ -68,7 +68,7 @@ end describe "DELETE destroy" do - let(:event){ create(:event) } + let(:event) { create(:event) } it "redirects after delete" do delete :destroy, :id => event.id response.should redirect_to(admin_events_url) diff --git a/spec/controllers/admin/geo_entities_controller_spec.rb b/spec/controllers/admin/geo_entities_controller_spec.rb index 887f18d00d..dcbd651c30 100644 --- a/spec/controllers/admin/geo_entities_controller_spec.rb +++ b/spec/controllers/admin/geo_entities_controller_spec.rb @@ -50,7 +50,7 @@ end describe "XHR PUT update JSON" do - let(:geo_entity){ create(:geo_entity, geo_entity_type: country_geo_entity_type) } + let(:geo_entity) { create(:geo_entity, geo_entity_type: country_geo_entity_type) } it "responds with 200 when successful" do xhr :put, :update, format: 'json', id: geo_entity.id, geo_entity: { iso_code2: 'ZZ' } response.should be_success @@ -62,7 +62,7 @@ end describe "DELETE destroy" do - let(:geo_entity){ create(:geo_entity) } + let(:geo_entity) { create(:geo_entity) } it "redirects after delete" do delete :destroy, id: geo_entity.id response.should redirect_to(admin_geo_entities_url) diff --git a/spec/controllers/admin/hybrid_relationships_controller_spec.rb b/spec/controllers/admin/hybrid_relationships_controller_spec.rb index 175a37e38e..bb76659b5a 100644 --- a/spec/controllers/admin/hybrid_relationships_controller_spec.rb +++ b/spec/controllers/admin/hybrid_relationships_controller_spec.rb @@ -3,10 +3,10 @@ describe Admin::HybridRelationshipsController do login_admin - before(:each){ hybrid_relationship_type } - let(:taxon_concept){ create(:taxon_concept) } - let(:hybrid){ create(:taxon_concept, :name_status => 'H') } - let(:hybrid_relationship){ + before(:each) { hybrid_relationship_type } + let(:taxon_concept) { create(:taxon_concept) } + let(:hybrid) { create(:taxon_concept, :name_status => 'H') } + let(:hybrid_relationship) { create(:taxon_relationship, :taxon_relationship_type_id => hybrid_relationship_type.id, :taxon_concept => taxon_concept, diff --git a/spec/controllers/admin/instruments_controller_spec.rb b/spec/controllers/admin/instruments_controller_spec.rb index 32d90ca4e0..6014dcecab 100644 --- a/spec/controllers/admin/instruments_controller_spec.rb +++ b/spec/controllers/admin/instruments_controller_spec.rb @@ -40,7 +40,7 @@ end describe "XHR PUT update" do - let(:instrument){ create(:instrument) } + let(:instrument) { create(:instrument) } it "responds with 200 when successful" do xhr :put, :update, :format => 'json', :id => instrument.id, :instrument => { :name => 'ZZ' } response.should be_success @@ -52,15 +52,15 @@ end describe "DELETE destroy" do - let(:instrument){ create(:instrument) } + let(:instrument) { create(:instrument) } it "redirects after delete" do delete :destroy, :id => instrument.id flash[:notice].should_not be_nil flash[:alert].should be_nil response.should redirect_to(admin_instruments_url) end - let(:instrument2){ create(:instrument) } - let!(:taxon_instrument){ create(:taxon_instrument, :instrument_id => instrument2.id) } + let(:instrument2) { create(:instrument) } + let!(:taxon_instrument) { create(:taxon_instrument, :instrument_id => instrument2.id) } it "fails to delete instrument because there are dependent objects" do delete :destroy, :id => instrument2.id flash[:notice].should be_nil diff --git a/spec/controllers/admin/languages_controller_spec.rb b/spec/controllers/admin/languages_controller_spec.rb index e2054bce2c..5634b95779 100644 --- a/spec/controllers/admin/languages_controller_spec.rb +++ b/spec/controllers/admin/languages_controller_spec.rb @@ -28,7 +28,7 @@ end describe "XHR PUT update" do - let(:language){ create(:language) } + let(:language) { create(:language) } it "responds with 200 when successful" do xhr :put, :update, :format => 'json', :id => language.id, :language => { :iso_code1 => 'ZZ' } response.should be_success @@ -40,7 +40,7 @@ end describe "DELETE destroy" do - let(:language){ create(:language) } + let(:language) { create(:language) } it "redirects after delete" do delete :destroy, :id => language.id response.should redirect_to(admin_languages_url) diff --git a/spec/controllers/admin/nomenclature_changes/status_to_synonym_controller_spec.rb b/spec/controllers/admin/nomenclature_changes/status_to_synonym_controller_spec.rb index bbfac76a6a..92f97eccec 100644 --- a/spec/controllers/admin/nomenclature_changes/status_to_synonym_controller_spec.rb +++ b/spec/controllers/admin/nomenclature_changes/status_to_synonym_controller_spec.rb @@ -3,7 +3,7 @@ describe Admin::NomenclatureChanges::StatusToSynonymController do login_admin include_context 'status_change_definitions' - let(:input_species){ create_cites_eu_species(name_status: 'N') } + let(:input_species) { create_cites_eu_species(name_status: 'N') } describe 'GET show' do context :primary_output do diff --git a/spec/controllers/admin/nomenclature_changes_controller_spec.rb b/spec/controllers/admin/nomenclature_changes_controller_spec.rb index 9329693f88..959ec64f88 100644 --- a/spec/controllers/admin/nomenclature_changes_controller_spec.rb +++ b/spec/controllers/admin/nomenclature_changes_controller_spec.rb @@ -17,7 +17,7 @@ end describe "DELETE destroy" do - let(:nomenclature_change){ create(:nomenclature_change) } + let(:nomenclature_change) { create(:nomenclature_change) } it "redirects after delete" do delete :destroy, :id => nomenclature_change.id response.should redirect_to(admin_nomenclature_changes_url) diff --git a/spec/controllers/admin/ranks_controller_spec.rb b/spec/controllers/admin/ranks_controller_spec.rb index d484aea019..93961b14c3 100644 --- a/spec/controllers/admin/ranks_controller_spec.rb +++ b/spec/controllers/admin/ranks_controller_spec.rb @@ -28,7 +28,7 @@ end describe "XHR PUT update" do - let(:rank){ create(:rank) } + let(:rank) { create(:rank) } it "responds with 200 when successful" do xhr :put, :update, :format => 'json', :id => rank.id, :rank => { :name => 'ZZ' } response.should be_success @@ -40,7 +40,7 @@ end describe "DELETE destroy" do - let(:rank){ create(:rank) } + let(:rank) { create(:rank) } it "redirects after delete" do delete :destroy, :id => rank.id response.should redirect_to(admin_ranks_url) diff --git a/spec/controllers/admin/references_controller_spec.rb b/spec/controllers/admin/references_controller_spec.rb index 4aef6bab74..ee0207cbc5 100644 --- a/spec/controllers/admin/references_controller_spec.rb +++ b/spec/controllers/admin/references_controller_spec.rb @@ -40,7 +40,7 @@ end describe "XHR PUT update JSON" do - let(:reference){ create(:reference) } + let(:reference) { create(:reference) } it "responds with 200 when successful" do xhr :put, :update, :format => 'json', :id => reference.id, :reference => { :citation => 'ZZ' } response.should be_success @@ -52,7 +52,7 @@ end describe "DELETE destroy" do - let(:reference){ create(:reference) } + let(:reference) { create(:reference) } it "redirects after delete" do delete :destroy, :id => reference.id response.should redirect_to(admin_references_url) diff --git a/spec/controllers/admin/species_listings_controller_spec.rb b/spec/controllers/admin/species_listings_controller_spec.rb index 3931d3dd97..e9196e7ca9 100644 --- a/spec/controllers/admin/species_listings_controller_spec.rb +++ b/spec/controllers/admin/species_listings_controller_spec.rb @@ -31,7 +31,7 @@ end describe "XHR PUT update" do - let(:species_listing){ create(:species_listing) } + let(:species_listing) { create(:species_listing) } it "responds with 200 when successful" do xhr :put, :update, :format => 'json', :id => species_listing.id, :species_listing => { :name => 'ZZ' } response.should be_success @@ -43,7 +43,7 @@ end describe "DELETE destroy" do - let(:species_listing){ create(:species_listing) } + let(:species_listing) { create(:species_listing) } it "redirects after delete" do delete :destroy, :id => species_listing.id response.should redirect_to(admin_species_listings_url) diff --git a/spec/controllers/admin/synonym_relationships_controller_spec.rb b/spec/controllers/admin/synonym_relationships_controller_spec.rb index f00203f585..b6cb176324 100644 --- a/spec/controllers/admin/synonym_relationships_controller_spec.rb +++ b/spec/controllers/admin/synonym_relationships_controller_spec.rb @@ -3,10 +3,10 @@ describe Admin::SynonymRelationshipsController do login_admin - before(:each){ synonym_relationship_type } - let(:taxon_concept){ create(:taxon_concept) } - let(:synonym){ create(:taxon_concept, :name_status => 'S') } - let(:synonym_relationship){ + before(:each) { synonym_relationship_type } + let(:taxon_concept) { create(:taxon_concept) } + let(:synonym) { create(:taxon_concept, :name_status => 'S') } + let(:synonym_relationship) { create(:taxon_relationship, :taxon_relationship_type_id => synonym_relationship_type.id, :taxon_concept => taxon_concept, diff --git a/spec/controllers/admin/tags_controller_spec.rb b/spec/controllers/admin/tags_controller_spec.rb index 162a40d9ae..fbe3c6173c 100644 --- a/spec/controllers/admin/tags_controller_spec.rb +++ b/spec/controllers/admin/tags_controller_spec.rb @@ -24,7 +24,7 @@ end describe "XHR PUT update" do - let(:preset_tag){ create(:preset_tag) } + let(:preset_tag) { create(:preset_tag) } context "when JSON" do it "responds with 200 when successful" do xhr :put, :update, :format => 'json', :id => preset_tag.id, @@ -40,7 +40,7 @@ end describe "DELETE destroy" do - let(:preset_tag){ create(:preset_tag) } + let(:preset_tag) { create(:preset_tag) } it "redirects after delete" do delete :destroy, :id => preset_tag.id response.should redirect_to(admin_tags_url) diff --git a/spec/controllers/admin/taxon_concept_comments_controller_spec.rb b/spec/controllers/admin/taxon_concept_comments_controller_spec.rb index 62e3f630bf..2a248ec3c5 100644 --- a/spec/controllers/admin/taxon_concept_comments_controller_spec.rb +++ b/spec/controllers/admin/taxon_concept_comments_controller_spec.rb @@ -27,7 +27,7 @@ end describe 'PUT update' do - let(:comment){ @taxon_concept.comments.create({ note: 'bleh' }) } + let(:comment) { @taxon_concept.comments.create({ note: 'bleh' }) } it 'redirects to index with notice when success' do put :update, id: comment.id, diff --git a/spec/controllers/admin/taxon_concepts_controller_spec.rb b/spec/controllers/admin/taxon_concepts_controller_spec.rb index 6874498f67..f6bbb2eb9f 100644 --- a/spec/controllers/admin/taxon_concepts_controller_spec.rb +++ b/spec/controllers/admin/taxon_concepts_controller_spec.rb @@ -64,7 +64,7 @@ end describe "XHR PUT update" do - let(:taxon_concept){ create(:taxon_concept) } + let(:taxon_concept) { create(:taxon_concept) } context "when JSON" do it "responds with 200 when successful" do xhr :put, :update, :format => 'json', :id => taxon_concept.id, @@ -92,7 +92,7 @@ end describe "DELETE destroy" do - let(:taxon_concept){ create(:taxon_concept) } + let(:taxon_concept) { create(:taxon_concept) } it "redirects after delete" do delete :destroy, :id => taxon_concept.id response.should redirect_to(admin_taxon_concepts_url) @@ -127,7 +127,7 @@ end describe "XHR GET JSON autocomplete" do - let!(:taxon_concept){ + let!(:taxon_concept) { create_cites_eu_genus( :taxon_name => create(:taxon_name, :scientific_name => 'AAA') ) diff --git a/spec/controllers/admin/taxon_relationships_controller_spec.rb b/spec/controllers/admin/taxon_relationships_controller_spec.rb index 811fe85c7b..bb5f58b11f 100644 --- a/spec/controllers/admin/taxon_relationships_controller_spec.rb +++ b/spec/controllers/admin/taxon_relationships_controller_spec.rb @@ -3,10 +3,10 @@ describe Admin::TaxonRelationshipsController do login_admin - before(:each){ equal_relationship_type } - let(:taxon_concept){ create(:taxon_concept) } + before(:each) { equal_relationship_type } + let(:taxon_concept) { create(:taxon_concept) } describe "GET index" do - let(:taxon_relationship){ + let(:taxon_relationship) { create(:taxon_relationship, :taxon_concept_id => taxon_concept.id) } it "assigns @taxon_relationships" do @@ -25,7 +25,7 @@ end describe "XHR POST create" do - let(:taxon_relationship_attributes){ build_attributes(:taxon_relationship) } + let(:taxon_relationship_attributes) { build_attributes(:taxon_relationship) } before do TaxonRelationshipType.stub(:find).and_return(equal_relationship_type) end @@ -44,13 +44,13 @@ describe 'DELETE destroy' do context"when relationship is bidirectional" do - let(:taxon_concept){ + let(:taxon_concept) { create_cites_eu_species } - let(:other_taxon_concept){ + let(:other_taxon_concept) { create_cms_species } - let!(:rel){ + let!(:rel) { create(:taxon_relationship, taxon_relationship_type: equal_relationship_type, taxon_concept_id: taxon_concept.id, @@ -73,13 +73,13 @@ end end context"when relationship is not bidirectional" do - let(:taxon_concept){ + let(:taxon_concept) { create_cites_eu_species } - let(:other_taxon_concept){ + let(:other_taxon_concept) { create_cites_eu_species(name_status: 'S') } - let!(:rel){ + let!(:rel) { create(:taxon_relationship, taxon_relationship_type: synonym_relationship_type, taxon_concept_id: taxon_concept.id, diff --git a/spec/controllers/admin/taxonomies_controller_spec.rb b/spec/controllers/admin/taxonomies_controller_spec.rb index 16c509125a..bf2983da47 100644 --- a/spec/controllers/admin/taxonomies_controller_spec.rb +++ b/spec/controllers/admin/taxonomies_controller_spec.rb @@ -40,7 +40,7 @@ end describe "XHR PUT update JSON" do - let(:taxonomy){ create(:taxonomy) } + let(:taxonomy) { create(:taxonomy) } it "responds with 200 when successful" do xhr :put, :update, :format => 'json', :id => taxonomy.id, :taxonomy => { :name => 'ZZ' } response.should be_success @@ -52,7 +52,7 @@ end describe "DELETE destroy" do - let(:taxonomy){ create(:taxonomy) } + let(:taxonomy) { create(:taxonomy) } it "redirects after delete" do delete :destroy, :id => taxonomy.id response.should redirect_to(admin_taxonomies_url) @@ -68,7 +68,7 @@ end end describe "DELETE destroy" do - let(:taxonomy){ create(:taxonomy) } + let(:taxonomy) { create(:taxonomy) } it "fails to delete and redirects to admin_root_path" do delete :destroy, :id => taxonomy.id response.should redirect_to(admin_root_path) diff --git a/spec/controllers/admin/trade_names_relationships_controller_spec.rb b/spec/controllers/admin/trade_names_relationships_controller_spec.rb index 992960a332..8f7e1ca18a 100644 --- a/spec/controllers/admin/trade_names_relationships_controller_spec.rb +++ b/spec/controllers/admin/trade_names_relationships_controller_spec.rb @@ -3,10 +3,10 @@ describe Admin::TradeNameRelationshipsController do login_admin - before(:each){ trade_name_relationship_type } - let(:taxon_concept){ create(:taxon_concept) } - let(:trade_name){ create(:taxon_concept, :name_status => 'T') } - let(:trade_name_relationship){ + before(:each) { trade_name_relationship_type } + let(:taxon_concept) { create(:taxon_concept) } + let(:trade_name) { create(:taxon_concept, :name_status => 'T') } + let(:trade_name_relationship) { create(:taxon_relationship, :taxon_relationship_type_id => trade_name_relationship_type.id, :taxon_concept => taxon_concept, diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb index f5a0c47dab..968a5412bd 100644 --- a/spec/controllers/admin/users_controller_spec.rb +++ b/spec/controllers/admin/users_controller_spec.rb @@ -24,7 +24,7 @@ end describe "XHR GET edit" do - let(:user){ create(:user) } + let(:user) { create(:user) } it "renders the edit template" do xhr :get, :edit, :id => user.id response.should render_template('new') @@ -36,7 +36,7 @@ end describe "XHR PUT update JS" do - let(:user){ create(:user) } + let(:user) { create(:user) } it "responds with 200 when successful" do xhr :put, :update, :format => 'js', :id => user.id, :user => { :name => 'ZZ' } response.should be_success @@ -49,7 +49,7 @@ end describe "DELETE destroy" do - let(:user){ create(:user) } + let(:user) { create(:user) } it "redirects after delete" do delete :destroy, :id => user.id response.should redirect_to(admin_users_url) diff --git a/spec/controllers/api/document_geo_entities_controller_spec.rb b/spec/controllers/api/document_geo_entities_controller_spec.rb index 51bf003ba4..1645e074f7 100644 --- a/spec/controllers/api/document_geo_entities_controller_spec.rb +++ b/spec/controllers/api/document_geo_entities_controller_spec.rb @@ -3,20 +3,20 @@ describe Api::V1::DocumentGeoEntitiesController do context "when searching by taxon concept name" do include_context "Canis lupus" - let!(:document_about_wolf_in_poland){ + let!(:document_about_wolf_in_poland) { d = create(:document) c = create(:document_citation, document: d) create(:document_citation_taxon_concept, taxon_concept_id: @species.id, document_citation: c) create(:document_citation_geo_entity, geo_entity: poland, document_citation: c) d } - let!(:document_not_about_wolf_not_in_poland){ + let!(:document_not_about_wolf_not_in_poland) { d = create(:document) c = create(:document_citation, document: d) create(:document_citation_geo_entity, geo_entity: nepal, document_citation: c) d } - let!(:document_not_about_wolf_in_poland){ + let!(:document_not_about_wolf_in_poland) { d = create(:document) c = create(:document_citation, document: d) create(:document_citation_geo_entity, geo_entity: poland, document_citation: c) diff --git a/spec/controllers/api/documents_controller_spec.rb b/spec/controllers/api/documents_controller_spec.rb index 961a38af35..f2790ac533 100644 --- a/spec/controllers/api/documents_controller_spec.rb +++ b/spec/controllers/api/documents_controller_spec.rb @@ -69,7 +69,7 @@ def get_public_documents context "show action fails" do login_api_user it "should return 403 status when permission denied" do - controller.should_receive(:render_403){ controller.render nothing: true } + controller.should_receive(:render_403) { controller.render nothing: true } get :show, id: @document2.id end end @@ -85,7 +85,7 @@ def get_public_documents context "single document selected" do it "should return 404 if file is missing" do File.stub!(:exists?).and_return(false) - controller.should_receive(:render_404){ controller.render nothing: true } + controller.should_receive(:render_404) { controller.render nothing: true } get :download_zip, ids: @document2.id end it "should return zip file if file is found" do @@ -99,7 +99,7 @@ def get_public_documents context "multiple documents selected" do it "should return 404 if all files are missing" do File.stub!(:exists?).and_return(false) - controller.should_receive(:render_404){ controller.render nothing: true } + controller.should_receive(:render_404) { controller.render nothing: true } get :download_zip, ids: "#{@document.id},#{@document2.id}" end diff --git a/spec/controllers/api/geo_entities_controller_spec.rb b/spec/controllers/api/geo_entities_controller_spec.rb index 785791decf..8b94051373 100644 --- a/spec/controllers/api/geo_entities_controller_spec.rb +++ b/spec/controllers/api/geo_entities_controller_spec.rb @@ -1,14 +1,14 @@ require 'spec_helper' describe Api::V1::GeoEntitiesController do - let!(:europe){ + let!(:europe) { create( :geo_entity, :geo_entity_type => cites_region_geo_entity_type, :name => 'Europe' ) } - let!(:france){ + let!(:france) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -17,7 +17,7 @@ :designations => [cites] ) } - let!(:andorra){ + let!(:andorra) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -25,7 +25,7 @@ :iso_code2 => 'AD' ) } - let!(:french_guiana){ + let!(:french_guiana) { create( :geo_entity, :geo_entity_type => territory_geo_entity_type, diff --git a/spec/controllers/api/taxon_concepts_controller_spec.rb b/spec/controllers/api/taxon_concepts_controller_spec.rb index a9beaa4d16..5f60e875c3 100644 --- a/spec/controllers/api/taxon_concepts_controller_spec.rb +++ b/spec/controllers/api/taxon_concepts_controller_spec.rb @@ -10,7 +10,7 @@ :geo_entity_scope => 'cites', :page => 1 } - }.to change{ Ahoy::Event.count }.by(1) + }.to change { Ahoy::Event.count }.by(1) expect(Ahoy::Event.last.visit_id).to_not be(nil) expect { @@ -20,7 +20,7 @@ :geo_entity_scope => 'cites', :page => 1 } - }.to change{ Ahoy::Event.count }.by(1) + }.to change { Ahoy::Event.count }.by(1) expect(@ahoy_event1).to eq(@ahoy_event2) end end diff --git a/spec/controllers/checklist/geo_entities_controller_spec.rb b/spec/controllers/checklist/geo_entities_controller_spec.rb index 06f6017a24..78f42f0582 100644 --- a/spec/controllers/checklist/geo_entities_controller_spec.rb +++ b/spec/controllers/checklist/geo_entities_controller_spec.rb @@ -1,14 +1,14 @@ require 'spec_helper' describe Checklist::GeoEntitiesController do - let!(:europe){ + let!(:europe) { create( :geo_entity, :geo_entity_type => cites_region_geo_entity_type, :name => 'Europe' ) } - let!(:france){ + let!(:france) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -17,7 +17,7 @@ :designations => [cites] ) } - let!(:andorra){ + let!(:andorra) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -25,7 +25,7 @@ :iso_code2 => 'AD' ) } - let!(:french_guiana){ + let!(:french_guiana) { create( :geo_entity, :geo_entity_type => territory_geo_entity_type, diff --git a/spec/controllers/cites_trade/shipments_controller_spec.rb b/spec/controllers/cites_trade/shipments_controller_spec.rb index 3c24bb073d..a77c409c7c 100644 --- a/spec/controllers/cites_trade/shipments_controller_spec.rb +++ b/spec/controllers/cites_trade/shipments_controller_spec.rb @@ -4,7 +4,7 @@ include_context 'Shipments' describe "GET index" do - before(:each){ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings } + before(:each) { Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings } context "serializer" do it "should return comptab export when report_type invalid" do get :index, filters: { diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb index 6319e075ce..5c6e934ed3 100644 --- a/spec/controllers/registrations_controller_spec.rb +++ b/spec/controllers/registrations_controller_spec.rb @@ -47,12 +47,12 @@ context "when signing up" do it "should create an account with the role set to api" do - expect{ + expect { post :create, :user => { :email => @u3.email, :name => @u3.name, :organisation => 'WCMC', :password => '22222222', :password_confirmation => '22222222' } - }.to change{ User.count }.by(1) + }.to change { User.count }.by(1) u = User.last expect(u.role).to eq 'api' end diff --git a/spec/controllers/trade/annual_report_uploads_controller_spec.rb b/spec/controllers/trade/annual_report_uploads_controller_spec.rb index 70781994fa..34db8351b1 100644 --- a/spec/controllers/trade/annual_report_uploads_controller_spec.rb +++ b/spec/controllers/trade/annual_report_uploads_controller_spec.rb @@ -3,7 +3,7 @@ describe Trade::AnnualReportUploadsController do login_admin - let(:france){ + let(:france) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -15,7 +15,7 @@ def exporter_csv test_document = File.join(Rails.root, 'spec', 'support', 'annual_report_upload_exporter.csv') Rack::Test::UploadedFile.new(test_document, "text/csv") end - let(:annual_report_upload){ + let(:annual_report_upload) { create( :annual_report_upload, :point_of_view => 'E', diff --git a/spec/controllers/trade/sandbox_shipments_controller_spec.rb b/spec/controllers/trade/sandbox_shipments_controller_spec.rb index 60f3c55f60..1992dff7d7 100644 --- a/spec/controllers/trade/sandbox_shipments_controller_spec.rb +++ b/spec/controllers/trade/sandbox_shipments_controller_spec.rb @@ -3,12 +3,12 @@ describe Trade::SandboxShipmentsController do login_admin - let(:annual_report_upload){ + let(:annual_report_upload) { aru = build(:annual_report_upload) aru.save(:validate => false) aru } - let(:sandbox_klass){ + let(:sandbox_klass) { Trade::SandboxTemplate.ar_klass(annual_report_upload.sandbox.table_name) } before(:each) do diff --git a/spec/controllers/trade/shipments_controller_spec.rb b/spec/controllers/trade/shipments_controller_spec.rb index 97341e7073..fa0ac93e3d 100644 --- a/spec/controllers/trade/shipments_controller_spec.rb +++ b/spec/controllers/trade/shipments_controller_spec.rb @@ -6,7 +6,7 @@ include_context 'Shipments' describe "GET index" do - before(:each){ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings } + before(:each) { Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings } it "should return all shipments" do get :index, format: :json response.body.should have_json_size(6).at_path('shipments') @@ -24,7 +24,7 @@ end describe "PUT update" do - before(:each){ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings } + before(:each) { Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings } it "should auto resolve accepted taxon when blank" do put :update, id: @shipment1.id, shipment: { @@ -50,7 +50,7 @@ end describe "POST update_batch" do - before(:each){ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings } + before(:each) { Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings } it "should change reporter type from I to E" do post :update_batch, { filters: { # shipment2 @@ -157,7 +157,7 @@ end describe "POST destroy_batch" do - before(:each){ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings } + before(:each) { Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings } it "should delete 1 shipment" do post :destroy_batch, { time_range_start: @shipment1.year, @@ -237,7 +237,7 @@ end describe "DELETE destroy" do - before(:each){ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings } + before(:each) { Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings } it "should delete 1 shipment" do delete :destroy, id: @shipment1.id Trade::Shipment.where(id: @shipment1.id).should be_empty diff --git a/spec/factories/common_names.rb b/spec/factories/common_names.rb index 3ae9fba09e..941047a2c5 100644 --- a/spec/factories/common_names.rb +++ b/spec/factories/common_names.rb @@ -2,8 +2,8 @@ factory :language do sequence(:name_en) { |n| "lng#{n}" } - sequence(:iso_code1) { |n| [n, n + 1].map{ |i| (65 + i % 26).chr }.join } - sequence(:iso_code3) { |n| [n, n + 1, n + 2].map{ |i| (65 + i % 26).chr }.join } + sequence(:iso_code1) { |n| [n, n + 1].map { |i| (65 + i % 26).chr }.join } + sequence(:iso_code3) { |n| [n, n + 1, n + 2].map { |i| (65 + i % 26).chr }.join } end factory :taxon_common do @@ -13,7 +13,7 @@ factory :common_name do language - sequence(:name){ |n| "Honey badger #{n}" } + sequence(:name) { |n| "Honey badger #{n}" } end end diff --git a/spec/factories/distributions.rb b/spec/factories/distributions.rb index 4bc48e8b97..a5fec6d81f 100644 --- a/spec/factories/distributions.rb +++ b/spec/factories/distributions.rb @@ -17,7 +17,7 @@ factory :geo_entity, :aliases => [:related_geo_entity, :trading_country, :importer, :exporter] do geo_entity_type name_en 'Wonderland' - sequence(:iso_code2) { |n| [n, n + 1].map{ |i| (65 + i % 26).chr }.join } + sequence(:iso_code2) { |n| [n, n + 1].map { |i| (65 + i % 26).chr }.join } is_current true end diff --git a/spec/factories/taxon_concepts.rb b/spec/factories/taxon_concepts.rb index 10c33b63dd..c50f42db64 100644 --- a/spec/factories/taxon_concepts.rb +++ b/spec/factories/taxon_concepts.rb @@ -7,7 +7,7 @@ name_status 'A' data {} listing {} - before(:create){ |tc| + before(:create) { |tc| if tc.parent.nil? && ['A', 'N'].include?(tc.name_status) && tc.rank.try(:name) != 'KINGDOM' tc.parent = create( :taxon_concept, diff --git a/spec/factories/trade.rb b/spec/factories/trade.rb index 7b9f50214c..7a32afab9e 100644 --- a/spec/factories/trade.rb +++ b/spec/factories/trade.rb @@ -12,12 +12,12 @@ end factory :term, :class => Term do - sequence(:code) { |n| [n, n + 1, n + 2].map{ |i| (97 + i % 26).chr }.join } + sequence(:code) { |n| [n, n + 1, n + 2].map { |i| (97 + i % 26).chr }.join } sequence(:name_en) { |n| "Term @{n}" } end factory :unit, :class => Unit do - sequence(:code) { |n| [n, n + 1, n + 2].map{ |i| (97 + i % 26).chr }.join } + sequence(:code) { |n| [n, n + 1, n + 2].map { |i| (97 + i % 26).chr }.join } sequence(:name_en) { |n| "Unit @{n}" } end end diff --git a/spec/helpers/admin/nomenclature_changes_helper_spec.rb b/spec/helpers/admin/nomenclature_changes_helper_spec.rb index e1a46a08df..2c62ce711f 100644 --- a/spec/helpers/admin/nomenclature_changes_helper_spec.rb +++ b/spec/helpers/admin/nomenclature_changes_helper_spec.rb @@ -15,41 +15,41 @@ include_context 'split_definitions' context "split with input" do before(:each) { @nomenclature_change = split_with_input } - specify{ expect(helper.split_blurb).to match(@nomenclature_change.input.taxon_concept.full_name) } + specify { expect(helper.split_blurb).to match(@nomenclature_change.input.taxon_concept.full_name) } end context "split with outputs" do before(:each) { @nomenclature_change = split_with_input_and_output } - specify{ expect(helper.split_blurb).to match(@nomenclature_change.outputs.first.taxon_concept.full_name) } + specify { expect(helper.split_blurb).to match(@nomenclature_change.outputs.first.taxon_concept.full_name) } end context "split with output new taxon" do before(:each) { @nomenclature_change = split_with_input_and_output_new_taxon } - specify{ expect(helper.split_blurb).to match(@nomenclature_change.outputs.first.display_full_name) } + specify { expect(helper.split_blurb).to match(@nomenclature_change.outputs.first.display_full_name) } end end describe :lump_blurb do include_context 'lump_definitions' context "lump with inputs" do before(:each) { @nomenclature_change = lump_with_inputs } - specify{ expect(helper.lump_blurb).to match(@nomenclature_change.inputs.first.taxon_concept.full_name) } + specify { expect(helper.lump_blurb).to match(@nomenclature_change.inputs.first.taxon_concept.full_name) } end context "lump with output" do before(:each) { @nomenclature_change = lump_with_inputs_and_output } - specify{ expect(helper.lump_blurb).to match(@nomenclature_change.output.taxon_concept.full_name) } + specify { expect(helper.lump_blurb).to match(@nomenclature_change.output.taxon_concept.full_name) } end context "lump with output new taxon" do before(:each) { @nomenclature_change = lump_with_inputs_and_output_new_taxon } - specify{ expect(helper.lump_blurb).to match(@nomenclature_change.output.display_full_name) } + specify { expect(helper.lump_blurb).to match(@nomenclature_change.output.display_full_name) } end end describe :status_change_blurb do include_context 'status_change_definitions' context "status upgrade with primary output" do before(:each) { @nomenclature_change = t_to_a_with_primary_output } - specify{ expect(helper.status_change_blurb).to match(@nomenclature_change.primary_output.taxon_concept.full_name) } + specify { expect(helper.status_change_blurb).to match(@nomenclature_change.primary_output.taxon_concept.full_name) } end context "status upgrade with swap" do before(:each) { @nomenclature_change = a_to_s_with_swap } - specify{ expect(helper.status_change_blurb).to match(@nomenclature_change.secondary_output.taxon_concept.full_name) } + specify { expect(helper.status_change_blurb).to match(@nomenclature_change.secondary_output.taxon_concept.full_name) } end end diff --git a/spec/helpers/listing_changes_helper_spec.rb b/spec/helpers/listing_changes_helper_spec.rb index dfbf8e2d7d..53bc167c5b 100644 --- a/spec/helpers/listing_changes_helper_spec.rb +++ b/spec/helpers/listing_changes_helper_spec.rb @@ -11,22 +11,22 @@ # end # end describe ListingChangesHelper do - let(:poland){ + let(:poland) { GeoEntity.find_by_iso_code2('PL') || create(:geo_entity, :iso_code2 => 'PL', :name => 'Poland') } - let(:taxon_concept){ + let(:taxon_concept) { create_cites_eu_genus( :taxon_name => create(:taxon_name, :scientific_name => 'Foobarus') ) } - let(:annotation){ + let(:annotation) { create( :annotation, :short_note_en => 'Only population of PL', :full_note_en => 'Only population of Poland' ) } - let(:hash_annotation){ + let(:hash_annotation) { create( :annotation, :symbol => '#1', @@ -34,7 +34,7 @@ :full_note_en => 'Only seeds and roots.' ) } - let(:listing_change){ + let(:listing_change) { create_cites_I_addition( :taxon_concept_id => taxon_concept.id, :annotation_id => annotation.id, @@ -43,7 +43,7 @@ } describe :geo_entities_tooltip do - let!(:listing_distribution){ + let!(:listing_distribution) { create( :listing_distribution, :listing_change_id => listing_change.id, @@ -75,13 +75,13 @@ end context "geographic exclusion" do - let(:exclusion){ + let(:exclusion) { create_cites_I_exception( :parent_id => listing_change.id, :taxon_concept_id => listing_change.taxon_concept_id ) } - let!(:listing_distribution){ + let!(:listing_distribution) { create( :listing_distribution, :listing_change_id => exclusion.id, @@ -95,7 +95,7 @@ end end describe :excluded_taxon_concepts_tooltip do - let(:child_taxon_concept){ + let(:child_taxon_concept) { create_cites_eu_species( :parent_id => taxon_concept.id, :taxon_name => create(:taxon_name, :scientific_name => 'cracovianus') @@ -108,7 +108,7 @@ end context "taxonomic exclusion" do - let!(:exclusion){ + let!(:exclusion) { create_cites_I_exception( :taxon_concept_id => child_taxon_concept.id, :parent_id => listing_change.id diff --git a/spec/models/annotation_spec.rb b/spec/models/annotation_spec.rb index 819bfaf874..1905289dc8 100644 --- a/spec/models/annotation_spec.rb +++ b/spec/models/annotation_spec.rb @@ -27,31 +27,31 @@ describe Annotation do describe :full_name do context "when parent_symbol given" do - let(:annotation){ + let(:annotation) { create(:annotation, :parent_symbol => 'CoP1', :symbol => '#1') } - specify{ annotation.full_symbol == 'CoP1#1' } + specify { annotation.full_symbol == 'CoP1#1' } end context "when event given" do - let(:event){ create_cites_cop(:name => 'CoP1') } - let(:annotation){ + let(:event) { create_cites_cop(:name => 'CoP1') } + let(:annotation) { create(:annotation, :event_id => event.id, :symbol => '#1') } - specify{ annotation.full_symbol == 'CoP1#1' } + specify { annotation.full_symbol == 'CoP1#1' } end end describe :destroy do - let(:annotation){ create(:annotation) } + let(:annotation) { create(:annotation) } context "when no dependent objects attached" do specify { annotation.destroy.should be_true } end context "when dependent objects attached" do context "when listing changes" do - let!(:listing_change){ create_cites_I_addition(:annotation_id => annotation.id) } + let!(:listing_change) { create_cites_I_addition(:annotation_id => annotation.id) } specify { annotation.destroy.should be_false } end context "when hashed listing changes" do - let!(:listing_change){ create_cites_I_addition(:hash_annotation_id => annotation.id) } + let!(:listing_change) { create_cites_I_addition(:hash_annotation_id => annotation.id) } specify { annotation.destroy.should be_false } end end diff --git a/spec/models/api_request_spec.rb b/spec/models/api_request_spec.rb index 1a63bdfa60..1ff7edb046 100644 --- a/spec/models/api_request_spec.rb +++ b/spec/models/api_request_spec.rb @@ -18,7 +18,7 @@ require 'spec_helper' describe ApiRequest do - let(:api_user){ + let(:api_user) { create(:user, role: 'api') } diff --git a/spec/models/checklist/annotations_spec.rb b/spec/models/checklist/annotations_spec.rb index 205e463d71..49b6d7dbc0 100644 --- a/spec/models/checklist/annotations_spec.rb +++ b/spec/models/checklist/annotations_spec.rb @@ -13,11 +13,11 @@ @taxon_concepts = @checklist.results end context 'for species Caiman latirostris' do - subject { @taxon_concepts.select{ |e| e.full_name == 'Caiman latirostris' }.first } + subject { @taxon_concepts.select { |e| e.full_name == 'Caiman latirostris' }.first } specify { subject.ann_symbol.should == '1' } end context 'for species Panax ginseng' do - subject { @taxon_concepts.select{ |e| e.full_name == 'Panax ginseng' }.first } + subject { @taxon_concepts.select { |e| e.full_name == 'Panax ginseng' }.first } specify { subject.ann_symbol.should == '2' } end end diff --git a/spec/models/checklist/appendix_population_and_region_spec.rb b/spec/models/checklist/appendix_population_and_region_spec.rb index 33c7185295..a00fbdb631 100644 --- a/spec/models/checklist/appendix_population_and_region_spec.rb +++ b/spec/models/checklist/appendix_population_and_region_spec.rb @@ -6,7 +6,7 @@ context "search by cites populations" do context "when America" do - subject{ + subject { checklist = Checklist::Checklist.new({ :country_ids => [america.id] }) @@ -17,7 +17,7 @@ end end context "when Mexico" do - subject{ + subject { checklist = Checklist::Checklist.new({ :country_ids => [mexico.id] }) @@ -28,7 +28,7 @@ end end context "when Canada" do - subject{ + subject { checklist = Checklist::Checklist.new({ :country_ids => [canada.id] }) @@ -39,7 +39,7 @@ end end context "when Argentina" do - subject{ + subject { checklist = Checklist::Checklist.new({ :country_ids => [argentina.id] }) @@ -50,7 +50,7 @@ end end context "when South America" do - subject{ + subject { checklist = Checklist::Checklist.new({ :cites_region_ids => [south_america.id] }) @@ -61,7 +61,7 @@ end end context "when North America" do - subject{ + subject { checklist = Checklist::Checklist.new({ :cites_region_ids => [north_america.id] }) @@ -72,7 +72,7 @@ end end context "when North America and Argentina" do - subject{ + subject { checklist = Checklist::Checklist.new({ :cites_region_ids => [north_america.id], :country_ids => [argentina.id] diff --git a/spec/models/checklist/appendix_population_spec.rb b/spec/models/checklist/appendix_population_spec.rb index c649606717..eaed1732ac 100644 --- a/spec/models/checklist/appendix_population_spec.rb +++ b/spec/models/checklist/appendix_population_spec.rb @@ -5,9 +5,9 @@ include_context "Canis lupus" context "search by cites populations" do - before(:each){ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings } + before(:each) { Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings } context "when Nepal" do - subject{ + subject { checklist = Checklist::Checklist.new({ :country_ids => [nepal.id] }) @@ -18,7 +18,7 @@ end end context "when Poland" do - subject{ + subject { checklist = Checklist::Checklist.new({ :country_ids => [poland.id] }) @@ -30,9 +30,9 @@ end end context "search by cites appendices" do - before(:each){ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings } + before(:each) { Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings } context "when App I" do - subject{ + subject { checklist = Checklist::Checklist.new({ :cites_appendices => ['I'] }) @@ -43,7 +43,7 @@ end end context "when App II" do - subject{ + subject { checklist = Checklist::Checklist.new({ :cites_appendices => ['II'] }) @@ -54,7 +54,7 @@ end end context "when App III" do - subject{ + subject { checklist = Checklist::Checklist.new({ :cites_appendices => ['III'] }) @@ -66,10 +66,10 @@ end end context "search by cites populations and appendices" do - before(:each){ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings } + before(:each) { Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings } context "when Nepal" do context "when App I" do - subject{ + subject { checklist = Checklist::Checklist.new({ :cites_appendices => ['I'], :country_ids => [nepal.id] @@ -81,7 +81,7 @@ end end context "when App II" do - subject{ + subject { checklist = Checklist::Checklist.new({ :cites_appendices => ['II'], :country_ids => [nepal.id] @@ -95,7 +95,7 @@ end context "when Poland" do context "when App I" do - subject{ + subject { checklist = Checklist::Checklist.new({ :cites_appendices => ['I'], :country_ids => [poland.id] @@ -107,7 +107,7 @@ end end context "when App II" do - subject{ + subject { checklist = Checklist::Checklist.new({ :cites_appendices => ['II'], :country_ids => [poland.id] @@ -121,7 +121,7 @@ end context "when Poland or Nepal" do context "when App I" do - subject{ + subject { checklist = Checklist::Checklist.new({ :cites_appendices => ['I'], :country_ids => [poland.id, nepal.id] @@ -133,7 +133,7 @@ end end context "when App II" do - subject{ + subject { checklist = Checklist::Checklist.new({ :cites_appendices => ['II'], :country_ids => [poland.id, nepal.id] @@ -147,7 +147,7 @@ end context "when App I or II" do context "when Poland" do - subject{ + subject { checklist = Checklist::Checklist.new({ :cites_appendices => ['I', 'II'], :country_ids => [poland.id] @@ -159,7 +159,7 @@ end end context "when Nepal" do - subject{ + subject { checklist = Checklist::Checklist.new({ :cites_appendices => ['I', 'II'], :country_ids => [nepal.id] diff --git a/spec/models/checklist/appendix_spec.rb b/spec/models/checklist/appendix_spec.rb index 4f33676d90..3e1ff9a5a4 100644 --- a/spec/models/checklist/appendix_spec.rb +++ b/spec/models/checklist/appendix_spec.rb @@ -13,11 +13,11 @@ @taxon_concepts = @checklist.results end it "should return Cacatua goffiniana" do - @taxon_concepts.select{ |e| e.full_name == @species1_2_1.full_name }.first.should_not be_nil + @taxon_concepts.select { |e| e.full_name == @species1_2_1.full_name }.first.should_not be_nil end it "should not return Agapornis roseicollis" do - @taxon_concepts.select{ |e| e.full_name == @species2_1.full_name }.first.should be_nil + @taxon_concepts.select { |e| e.full_name == @species2_1.full_name }.first.should be_nil end end diff --git a/spec/models/checklist/common_names_spec.rb b/spec/models/checklist/common_names_spec.rb index 937a345ae6..f7534213cf 100644 --- a/spec/models/checklist/common_names_spec.rb +++ b/spec/models/checklist/common_names_spec.rb @@ -13,8 +13,8 @@ :show_french => '1' }) @taxon_concepts = @checklist.results - @australis = @taxon_concepts.select{ |e| e.full_name == @species1.full_name }.first - @arctocephalus = @taxon_concepts.select{ |e| e.full_name == @genus.full_name }.first + @australis = @taxon_concepts.select { |e| e.full_name == @species1.full_name }.first + @arctocephalus = @taxon_concepts.select { |e| e.full_name == @genus.full_name }.first end it "should return all English names for Arctocephalus australis: 'South American Fur Seal, Southern Fur Seal'" do @@ -42,7 +42,7 @@ end it "should include a species without any common names defined" do - @pusillus = @taxon_concepts.select{ |e| e.full_name == @species3.full_name }.first + @pusillus = @taxon_concepts.select { |e| e.full_name == @species3.full_name }.first @pusillus.should_not be_nil end diff --git a/spec/models/checklist/higher_taxa_injector_spec.rb b/spec/models/checklist/higher_taxa_injector_spec.rb index 49bf7afd75..7de45271f7 100644 --- a/spec/models/checklist/higher_taxa_injector_spec.rb +++ b/spec/models/checklist/higher_taxa_injector_spec.rb @@ -111,7 +111,7 @@ context "when same phylum" do context "when two species from different classes" do - let(:hti_different_class){ + let(:hti_different_class) { Checklist::HigherTaxaInjector.new( [ @species1_1_1, @@ -119,7 +119,7 @@ ] ) } - specify{ + specify { headers = hti_different_class.higher_taxa_headers( @species1_1_1, @species2_1_1_1_1 @@ -128,7 +128,7 @@ } end context "when two species from different classes and expand_headers set" do - let(:hti_different_class){ + let(:hti_different_class) { Checklist::HigherTaxaInjector.new( [ @species1_1_1, @@ -136,7 +136,7 @@ ], { :expand_headers => true } ) } - specify{ + specify { headers = hti_different_class.higher_taxa_headers( @species1_1_1, @species2_1_1_1_1 @@ -147,7 +147,7 @@ end context "when same order" do context "when two species from different families" do - let(:hti_different_family){ + let(:hti_different_family) { Checklist::HigherTaxaInjector.new( [ @species1_1_1, @@ -155,12 +155,12 @@ ] ) } - specify{ + specify { hti_different_family.run.size.should == 4 } end context "when two species from different families and skip family set" do - let(:hti_different_family){ + let(:hti_different_family) { Checklist::HigherTaxaInjector.new( [ @species1_1_1, @@ -168,7 +168,7 @@ ], { :skip_ancestor_ids => [@family1.id] } ) } - specify{ + specify { hti_different_family.run.size.should == 3 } end @@ -178,46 +178,46 @@ describe :higher_taxa_headers do context "when same genus" do context "when one species" do - let(:hti_one_species){ + let(:hti_one_species) { Checklist::HigherTaxaInjector.new( [ @species1_1_1 ] ) } - specify{ + specify { headers = hti_one_species.higher_taxa_headers(nil, @species1_1_1) headers.map(&:full_name).should == ['Lolcatidae'] } end context "when one species and skip family set" do - let(:hti_one_species_skip_family){ + let(:hti_one_species_skip_family) { Checklist::HigherTaxaInjector.new( [ @species1_1_1 ], { :skip_ancestor_ids => [@family1.id] } ) } - specify{ + specify { hti_one_species_skip_family.higher_taxa_headers(nil, @species1_1_1).should be_empty } end context "when one species and expand headers set" do - let(:hti_one_species_expand_headers){ + let(:hti_one_species_expand_headers) { Checklist::HigherTaxaInjector.new( [ @species1_1_1 ], { :expand_headers => true } ) } - specify{ + specify { headers = hti_one_species_expand_headers.higher_taxa_headers(nil, @species1_1_1) headers.map(&:full_name).should == ["Rotflata", "Forfiteria", "Lolcatiformes", "Lolcatidae"] } end context "when two species" do - let(:hti_same_genus){ + let(:hti_same_genus) { Checklist::HigherTaxaInjector.new( [ @species1_1_1, @@ -225,12 +225,12 @@ ] ) } - specify{ + specify { hti_same_genus.higher_taxa_headers(@species1_1_1, @species1_1_2).should be_empty } end context "when species and subspecies" do - let(:hti_species_subspecies){ + let(:hti_species_subspecies) { Checklist::HigherTaxaInjector.new( [ @species1_1_2, @@ -238,14 +238,14 @@ ] ) } - specify{ + specify { hti_species_subspecies.higher_taxa_headers(@species1_1_2, @subspecies1_1_1_1).should be_empty } end end context "when same family" do context "when two species from different genera" do - let(:hti_same_family){ + let(:hti_same_family) { Checklist::HigherTaxaInjector.new( [ @species1_1_1, @@ -253,14 +253,14 @@ ] ) } - specify{ + specify { hti_same_family.higher_taxa_headers(@species1_1_1, @species1_2_1).should be_empty } end end context "when same order" do context "when two species from different families" do - let(:hti_different_family){ + let(:hti_different_family) { Checklist::HigherTaxaInjector.new( [ @species1_1_1, @@ -268,14 +268,14 @@ ] ) } - specify{ + specify { headers = hti_different_family.higher_taxa_headers(@species1_1_1, @species2_1_1) headers.map(&:full_name).should == ['Foobaridae'] } end context "when two species from different families and expand headers set" do - let(:hti_different_family){ + let(:hti_different_family) { Checklist::HigherTaxaInjector.new( [ @species1_1_1, @@ -283,14 +283,14 @@ ], { :expand_headers => true } ) } - specify{ + specify { headers = hti_different_family.higher_taxa_headers(@species1_1_1, @species2_1_1) headers.map(&:full_name).should == ['Foobaridae'] } end context "when genus and different family" do - let(:hti_genus_family){ + let(:hti_genus_family) { Checklist::HigherTaxaInjector.new( [ @genus1_1, @@ -298,14 +298,14 @@ ] ) } - specify{ + specify { headers = hti_genus_family.higher_taxa_headers(@genus1_1, @family2) headers.map(&:full_name).should == ['Foobaridae'] } end context "when family and genus in different family" do - let(:hti_family_genus){ + let(:hti_family_genus) { Checklist::HigherTaxaInjector.new( [ @family1, @@ -313,7 +313,7 @@ ] ) } - specify{ + specify { headers = hti_family_genus.higher_taxa_headers(@family1, @genus2_1) headers.map(&:full_name).should == ['Foobaridae'] @@ -322,7 +322,7 @@ end context "when same class" do context "when order and genus from different order" do - let(:hti_different_orders){ + let(:hti_different_orders) { Checklist::HigherTaxaInjector.new( [ @order2, @@ -330,14 +330,14 @@ ] ) } - specify{ + specify { headers = hti_different_orders.higher_taxa_headers(@order2, @genus2_1) headers.map(&:full_name).should == ['Foobaridae'] } end context "when order and genus from different order and expand headers set" do - let(:hti_different_orders_expand){ + let(:hti_different_orders_expand) { Checklist::HigherTaxaInjector.new( [ @order2, @@ -345,7 +345,7 @@ ], { :expand_headers => true } ) } - specify{ + specify { headers = hti_different_orders_expand.higher_taxa_headers(@order2, @genus2_1) headers.map(&:full_name).should == ['Lolcatiformes', 'Foobaridae'] diff --git a/spec/models/checklist/higher_taxa_item_spec.rb b/spec/models/checklist/higher_taxa_item_spec.rb index 3fc7482bd7..e9a434f426 100644 --- a/spec/models/checklist/higher_taxa_item_spec.rb +++ b/spec/models/checklist/higher_taxa_item_spec.rb @@ -4,7 +4,7 @@ describe :ancestors_path do context "when animal" do - let(:taxon_concept){ + let(:taxon_concept) { obj = double('MTaxonConcept', :rank_name => 'FAMILY', :kingdom_name => 'Animalia', @@ -18,7 +18,7 @@ specify { subject.ancestors_path.should == 'Chordata,Reptilia,Crocodylia,Alligatoridae' } end context "when plant" do - let(:taxon_concept){ + let(:taxon_concept) { obj = double('MTaxonConcept', :rank_name => 'FAMILY', :kingdom_name => 'Plantae', diff --git a/spec/models/checklist/order_spec.rb b/spec/models/checklist/order_spec.rb index c884d115dc..7af3af8b27 100644 --- a/spec/models/checklist/order_spec.rb +++ b/spec/models/checklist/order_spec.rb @@ -15,8 +15,8 @@ @taxon_concepts = @checklist.plantae end it "should include Agave (Agavaceae) before Panax (Araliaceae)" do - @taxon_concepts.index{ |tc| tc.full_name == 'Agave parviflora' }.should < - @taxon_concepts.index{ |tc| tc.full_name == 'Panax ginseng' } + @taxon_concepts.index { |tc| tc.full_name == 'Agave parviflora' }.should < + @taxon_concepts.index { |tc| tc.full_name == 'Panax ginseng' } end end context("Animalia") do @@ -26,29 +26,29 @@ @taxon_concepts = @checklist.animalia end it "should include birds after last mammal" do - @taxon_concepts.index{ |tc| tc.full_name == 'Tapirus terrestris' }.should < - @taxon_concepts.index{ |tc| tc.full_name == 'Gymnogyps californianus' } + @taxon_concepts.index { |tc| tc.full_name == 'Tapirus terrestris' }.should < + @taxon_concepts.index { |tc| tc.full_name == 'Gymnogyps californianus' } end it "should include Falconiformes (Aves) before Psittaciformes (Aves)" do - @taxon_concepts.index{ |tc| tc.full_name == 'Falconiformes' }.should < - @taxon_concepts.index{ |tc| tc.full_name == 'Psittaciformes' } + @taxon_concepts.index { |tc| tc.full_name == 'Falconiformes' }.should < + @taxon_concepts.index { |tc| tc.full_name == 'Psittaciformes' } end it "should include Cathartidae within Falconiformes" do - @taxon_concepts.index{ |tc| tc.full_name == 'Cathartidae' }.should > - @taxon_concepts.index{ |tc| tc.full_name == 'Falconiformes' } - @taxon_concepts.index{ |tc| tc.full_name == 'Cathartidae' }.should < - @taxon_concepts.index{ |tc| tc.full_name == 'Psittaciformes' } + @taxon_concepts.index { |tc| tc.full_name == 'Cathartidae' }.should > + @taxon_concepts.index { |tc| tc.full_name == 'Falconiformes' } + @taxon_concepts.index { |tc| tc.full_name == 'Cathartidae' }.should < + @taxon_concepts.index { |tc| tc.full_name == 'Psittaciformes' } end it "should include Cathartidae (Falconiformes) before Falconidae (Falconiformes)" do - @taxon_concepts.index{ |tc| tc.full_name == 'Cathartidae' }.should < - @taxon_concepts.index{ |tc| tc.full_name == 'Falconidae' } + @taxon_concepts.index { |tc| tc.full_name == 'Cathartidae' }.should < + @taxon_concepts.index { |tc| tc.full_name == 'Falconidae' } end it "should include Cathartidae (Falconiformes) before Cacatuidae (Psittaciformes)" do - @taxon_concepts.index{ |tc| tc.full_name == 'Cathartidae' }.should < - @taxon_concepts.index{ |tc| tc.full_name == 'Cacatuidae' } + @taxon_concepts.index { |tc| tc.full_name == 'Cathartidae' }.should < + @taxon_concepts.index { |tc| tc.full_name == 'Cacatuidae' } end it "should include Hirudo medicinalis at the very end (after all Chordata)" do - @taxon_concepts.index{ |tc| tc.full_name == 'Hirudo medicinalis' }.should == + @taxon_concepts.index { |tc| tc.full_name == 'Hirudo medicinalis' }.should == @taxon_concepts.length - 1 end end @@ -59,20 +59,20 @@ @taxon_concepts = @checklist.results end it "should include Falconiformes (Aves) before Psittaciformes (Aves)" do - @taxon_concepts.index{ |tc| tc.full_name == 'Falconiformes' }.should < - @taxon_concepts.index{ |tc| tc.full_name == 'Psittaciformes' } + @taxon_concepts.index { |tc| tc.full_name == 'Falconiformes' }.should < + @taxon_concepts.index { |tc| tc.full_name == 'Psittaciformes' } end it "should include Cathartidae before Falconiformes" do - @taxon_concepts.index{ |tc| tc.full_name == 'Cathartidae' }.should < - @taxon_concepts.index{ |tc| tc.full_name == 'Falconiformes' } + @taxon_concepts.index { |tc| tc.full_name == 'Cathartidae' }.should < + @taxon_concepts.index { |tc| tc.full_name == 'Falconiformes' } end it "should include Cathartidae (Falconiformes) before Falconidae (Falconiformes)" do - @taxon_concepts.index{ |tc| tc.full_name == 'Cathartidae' }.should < - @taxon_concepts.index{ |tc| tc.full_name == 'Falconidae' } + @taxon_concepts.index { |tc| tc.full_name == 'Cathartidae' }.should < + @taxon_concepts.index { |tc| tc.full_name == 'Falconidae' } end it "should include Cathartidae (Falconiformes) after Cacatuidae (Psittaciformes)" do - @taxon_concepts.index{ |tc| tc.full_name == 'Cathartidae' }.should > - @taxon_concepts.index{ |tc| tc.full_name == 'Cacatuidae' } + @taxon_concepts.index { |tc| tc.full_name == 'Cathartidae' }.should > + @taxon_concepts.index { |tc| tc.full_name == 'Cacatuidae' } end end end diff --git a/spec/models/checklist/pdf/history_annotations_key_spec.rb b/spec/models/checklist/pdf/history_annotations_key_spec.rb index c187721c39..c747cfdcbd 100644 --- a/spec/models/checklist/pdf/history_annotations_key_spec.rb +++ b/spec/models/checklist/pdf/history_annotations_key_spec.rb @@ -2,11 +2,11 @@ require 'spec_helper' describe Checklist::Pdf::HistoryAnnotationsKey do - let(:en){ create(:language, :name => 'English', :iso_code1 => 'EN') } + let(:en) { create(:language, :name => 'English', :iso_code1 => 'EN') } describe :annotations_key do - subject{ Checklist::Pdf::HistoryAnnotationsKey.new } - specify{ + subject { Checklist::Pdf::HistoryAnnotationsKey.new } + specify { subject.stub(:non_hash_annotations_key).and_return('x') subject.stub(:hash_annotations_key).and_return('x') subject.annotations_key.should == "\\newpage\n\\parindent 0in\\cpart{\\historicalSummaryOfAnnotations}\nx\\parindent -0.1in" @@ -56,8 +56,8 @@ ) Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings end - subject{ Checklist::Pdf::HistoryAnnotationsKey.new } - specify{ + subject { Checklist::Pdf::HistoryAnnotationsKey.new } + specify { subject.hash_annotations_key.should == "\\hashAnnotationsHistoryInfo\n\n\\hashannotationstable{\n\\rowcolor{pale_aqua}\nCoP1 & \\validFrom \\hspace{2 pt} 01/07/2012\\\\\n\\#1 & Only trunks \\\\\n\n}\n\\hashannotationstable{\n\\rowcolor{pale_aqua}\nCoP2 & \\validFrom \\hspace{2 pt} 01/07/2013\\\\\n\\#1 & Only bark \\\\\n\n}\n" } end diff --git a/spec/models/checklist/pdf/history_spec.rb b/spec/models/checklist/pdf/history_spec.rb index 6dd1eaa66e..8fd11f18b0 100644 --- a/spec/models/checklist/pdf/history_spec.rb +++ b/spec/models/checklist/pdf/history_spec.rb @@ -2,17 +2,17 @@ require 'spec_helper' describe Checklist::Pdf::History do - let(:en){ create(:language, :name => 'English', :iso_code1 => 'EN') } - let!(:fr){ create(:language, :name => 'French', :iso_code1 => 'FR') } - let!(:es){ create(:language, :name => 'Spanish', :iso_code1 => 'ES') } - let(:family_tc){ + let(:en) { create(:language, :name => 'English', :iso_code1 => 'EN') } + let!(:fr) { create(:language, :name => 'French', :iso_code1 => 'FR') } + let!(:es) { create(:language, :name => 'Spanish', :iso_code1 => 'ES') } + let(:family_tc) { tc = create_cites_eu_family( :taxon_name => create(:taxon_name, :scientific_name => 'Foobaridae') ) Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings MTaxonConcept.find(tc.id) } - let(:genus_tc){ + let(:genus_tc) { tc = create_cites_eu_genus( :parent_id => family_tc.id, :taxon_name => create(:taxon_name, :scientific_name => 'Foobarus') @@ -22,8 +22,8 @@ } describe :higher_taxon_name do context "when family" do - let(:tc){ family_tc } - let!(:taxon_common){ + let(:tc) { family_tc } + let!(:taxon_common) { create( :taxon_common, :taxon_concept_id => tc.id, @@ -35,8 +35,8 @@ ) Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings } - subject{ Checklist::Pdf::History.new(:scientific_name => tc.full_name, :show_english => true) } - specify{ + subject { Checklist::Pdf::History.new(:scientific_name => tc.full_name, :show_english => true) } + specify { subject.higher_taxon_name(tc.reload).should == "\\subsection*{FOOBARIDAE (E) Foobars }\n" } end @@ -44,8 +44,8 @@ describe :listed_taxon_name do context "when family" do - let(:tc){ family_tc } - let!(:lc){ + let(:tc) { family_tc } + let!(:lc) { lc = create_cites_I_addition( :taxon_concept_id => tc.id, :is_current => true @@ -53,14 +53,14 @@ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings MCitesListingChange.find(lc.id) } - subject{ Checklist::Pdf::History.new(:scientific_name => tc.full_name) } - specify{ + subject { Checklist::Pdf::History.new(:scientific_name => tc.full_name) } + specify { subject.listed_taxon_name(tc).should == 'FOOBARIDAE spp.' } end context "when genus" do - let(:tc){ genus_tc } - let!(:lc){ + let(:tc) { genus_tc } + let!(:lc) { lc = create_cites_I_addition( :taxon_concept_id => tc.id, :is_current => true @@ -68,8 +68,8 @@ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings MCitesListingChange.find(lc.id) } - subject{ Checklist::Pdf::History.new(:scientific_name => tc.full_name) } - specify{ + subject { Checklist::Pdf::History.new(:scientific_name => tc.full_name) } + specify { subject.listed_taxon_name(tc).should == '\emph{Foobarus} spp.' } end @@ -77,7 +77,7 @@ describe :annotation_for_language do context "annotation with footnote" do - let(:annotation){ + let(:annotation) { create( :annotation, :short_note_en => 'Except Foobarus cracoviensis', @@ -85,8 +85,8 @@ :display_in_footnote => true ) } - let(:tc){ genus_tc } - let(:lc){ + let(:tc) { genus_tc } + let(:lc) { lc = create_cites_I_addition( :taxon_concept_id => tc.id, :annotation_id => annotation.id, @@ -96,8 +96,8 @@ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings MCitesListingChange.find(lc.id) } - subject{ Checklist::Pdf::History.new({}) } - specify{ + subject { Checklist::Pdf::History.new({}) } + specify { subject.annotation_for_language(lc, 'en').should == "Except \\textit{Foobarus cracoviensis}\n\nPreviously listed as \\textit{Foobarus polonicus}.\\footnote{...}" } end diff --git a/spec/models/checklist/pdf/index_annotations_key_spec.rb b/spec/models/checklist/pdf/index_annotations_key_spec.rb index 2acb44c4ac..701c8d3e8f 100644 --- a/spec/models/checklist/pdf/index_annotations_key_spec.rb +++ b/spec/models/checklist/pdf/index_annotations_key_spec.rb @@ -2,11 +2,11 @@ require 'spec_helper' describe Checklist::Pdf::IndexAnnotationsKey do - let(:en){ create(:language, :name => 'English', :iso_code1 => 'EN') } + let(:en) { create(:language, :name => 'English', :iso_code1 => 'EN') } describe :annotations_key do - subject{ Checklist::Pdf::IndexAnnotationsKey.new } - specify{ + subject { Checklist::Pdf::IndexAnnotationsKey.new } + specify { subject.stub(:non_hash_annotations_key).and_return('x') subject.stub(:hash_annotations_key).and_return('x') subject.annotations_key.should == "\\newpage\n\\parindent 0in\\cpart{\\annotationsKey}\nxx\\parindent -0.1in" @@ -43,8 +43,8 @@ ) Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings end - subject{ Checklist::Pdf::IndexAnnotationsKey.new } - specify{ + subject { Checklist::Pdf::IndexAnnotationsKey.new } + specify { subject.hash_annotations_key.should == "\\newpage\n\\section*{\\hashAnnotations}\n\\hashAnnotationsIndexInfo\n\n\\hashannotationstable{\n\\rowcolor{pale_aqua}\nCoP2 & \\validFrom \\hspace{2 pt} 01/07/2013\\\\\n\\#1 & Only bark \\\\\n\n}\n" } end @@ -99,8 +99,8 @@ ) Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings end - subject{ Checklist::Pdf::IndexAnnotationsKey.new } - specify{ + subject { Checklist::Pdf::IndexAnnotationsKey.new } + specify { LatexToPdf.stub(:html2latex).and_return('x') subject.non_hash_annotations_key.should == "\\section*{\\nonHashAnnotations}\n\\cfbox{orange}{\\superscript{1} \\textbf{\\textit{Foobarus bizarrus}}}\n\nx\n\n\\cfbox{green}{\\superscript{2} \\textbf{\\textit{Foobaria curiosa}}}\n\nx\n\n" } diff --git a/spec/models/checklist/pdf/index_fetcher_spec.rb b/spec/models/checklist/pdf/index_fetcher_spec.rb index 170c1e737f..df4833250c 100644 --- a/spec/models/checklist/pdf/index_fetcher_spec.rb +++ b/spec/models/checklist/pdf/index_fetcher_spec.rb @@ -1,30 +1,30 @@ require 'spec_helper' describe Checklist::Pdf::IndexFetcher do - let(:en){ + let(:en) { create(:language, :name_en => 'French', :iso_code1 => 'FR', :iso_code3 => 'FRA') create(:language, :name_en => 'Spanish', :iso_code1 => 'ES', :iso_code3 => 'SPA') create(:language, :name_en => 'English', :iso_code1 => 'EN', :iso_code3 => 'ENG') } - let(:es){ + let(:es) { Language.find_by_name_en("Spanish") } - let(:english_common_name){ + let(:english_common_name) { create( :common_name, :name => 'Domestic lolcat', :language => en ) } - let(:spanish_common_name){ + let(:spanish_common_name) { create( :common_name, :name => 'Lolgato domestico', :language => es ) } - let!(:tc){ + let!(:tc) { tc = create( :taxon_concept, :taxon_name => create(:taxon_name, :scientific_name => 'Lolcatus') @@ -34,10 +34,10 @@ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings tc } - let(:rel){ MTaxonConcept.by_scientific_name('Lolcatus') } + let(:rel) { MTaxonConcept.by_scientific_name('Lolcatus') } context "with common names" do - let(:query){ + let(:query) { Checklist::Pdf::IndexQuery.new( rel, { :english_common_names => true, @@ -45,18 +45,18 @@ } ) } - subject{ Checklist::Pdf::IndexFetcher.new(query) } - specify{ subject.next.first.sort_name.should == 'lolcat, Domestic' } + subject { Checklist::Pdf::IndexFetcher.new(query) } + specify { subject.next.first.sort_name.should == 'lolcat, Domestic' } end context "with synonyms and authors" do - let!(:synonym){ + let!(:synonym) { create( :taxon_concept, :name_status => 'S', scientific_name: 'Catus fluffianus' ) } - let!(:synonymy_rel){ + let!(:synonymy_rel) { create( :taxon_relationship, :taxon_relationship_type => synonym_relationship_type, @@ -65,7 +65,7 @@ ) Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings } - let(:query){ + let(:query) { Checklist::Pdf::IndexQuery.new( rel, { :synonyms => true, @@ -73,7 +73,7 @@ } ) } - subject{ Checklist::Pdf::IndexFetcher.new(query) } - specify{ subject.next.first.sort_name.should == 'Catus fluffianus' } + subject { Checklist::Pdf::IndexFetcher.new(query) } + specify { subject.next.first.sort_name.should == 'Catus fluffianus' } end end diff --git a/spec/models/checklist/scientific_name_spec.rb b/spec/models/checklist/scientific_name_spec.rb index afd1828be8..374b4f22ca 100644 --- a/spec/models/checklist/scientific_name_spec.rb +++ b/spec/models/checklist/scientific_name_spec.rb @@ -13,7 +13,7 @@ }) checklist.results } - specify{ + specify { subject.first.full_name.should == @species2.full_name subject.size.should == 1 } @@ -26,7 +26,7 @@ }) checklist.results } - specify{ + specify { subject.first.full_name.should == @species2.full_name subject.size.should == 1 } diff --git a/spec/models/checklist/synonyms_spec.rb b/spec/models/checklist/synonyms_spec.rb index 6013f7b283..3609c93d88 100644 --- a/spec/models/checklist/synonyms_spec.rb +++ b/spec/models/checklist/synonyms_spec.rb @@ -14,7 +14,7 @@ end it "should return Alligator cynocephalus as synonym for Caiman latirostris" do - @caiman_latirostris = @taxon_concepts.select{ |e| e.full_name == @species.full_name }.first + @caiman_latirostris = @taxon_concepts.select { |e| e.full_name == @species.full_name }.first @caiman_latirostris.synonyms.should == ['Alligator cynocephalus'] end diff --git a/spec/models/checklist/taxon_concept_prefix_matcher_spec.rb b/spec/models/checklist/taxon_concept_prefix_matcher_spec.rb index c932e72045..83e0e99d5a 100644 --- a/spec/models/checklist/taxon_concept_prefix_matcher_spec.rb +++ b/spec/models/checklist/taxon_concept_prefix_matcher_spec.rb @@ -4,40 +4,40 @@ include_context "Boa constrictor" describe :results do context "when query in capital letters" do - subject{ + subject { Species::TaxonConceptPrefixMatcher.new({ :taxon_concept_query => 'BOA', :ranks => [] }) } - specify{ subject.results.size.should == 3 } + specify { subject.results.size.should == 3 } end context "when match on accepted name" do - subject{ + subject { Species::TaxonConceptPrefixMatcher.new({ :taxon_concept_query => 'boa', :ranks => [] }) } - specify{ subject.results.size.should == 3 } + specify { subject.results.size.should == 3 } end context "when match on synonym" do - subject{ + subject { Species::TaxonConceptPrefixMatcher.new({ :taxon_concept_query => 'constrictor', :ranks => [] }) } - specify{ subject.results.size.should == 2 } + specify { subject.results.size.should == 2 } end context "when match on common name" do - subject{ + subject { Species::TaxonConceptPrefixMatcher.new({ :taxon_concept_query => 'red', :ranks => [] }) } - specify{ subject.results.size.should == 1 } + specify { subject.results.size.should == 1 } end end end \ No newline at end of file diff --git a/spec/models/checklist/timeline_spec.rb b/spec/models/checklist/timeline_spec.rb index 10ec1d96cf..43adc676bd 100644 --- a/spec/models/checklist/timeline_spec.rb +++ b/spec/models/checklist/timeline_spec.rb @@ -2,7 +2,7 @@ describe Checklist::Timeline do context "when deleted" do - let(:tc){ + let(:tc) { tc = create_cites_eu_species create_cites_I_addition( :taxon_concept => tc, @@ -17,16 +17,16 @@ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings MTaxonConcept.find(tc.id) } - let(:ttc){ Checklist::TimelinesForTaxonConcept.new(tc) } - let(:subject){ ttc.timelines.first } + let(:ttc) { Checklist::TimelinesForTaxonConcept.new(tc) } + let(:subject) { ttc.timelines.first } - specify{ subject.timeline_intervals.count.should == 1 } - specify{ subject.timeline_intervals.last.end_pos.should < 1 } - specify{ subject.timeline_events.count.should == 2 } + specify { subject.timeline_intervals.count.should == 1 } + specify { subject.timeline_intervals.last.end_pos.should < 1 } + specify { subject.timeline_events.count.should == 2 } end context "when deleted from III multiple times" do - let(:tc){ + let(:tc) { tc = create_cites_eu_species cnt1 = create(:geo_entity) cnt2 = create(:geo_entity) @@ -77,16 +77,16 @@ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings MTaxonConcept.find(tc.id) } - let(:ttc){ Checklist::TimelinesForTaxonConcept.new(tc) } - let(:subject){ ttc.timelines.last } + let(:ttc) { Checklist::TimelinesForTaxonConcept.new(tc) } + let(:subject) { ttc.timelines.last } - specify{ subject.timeline_intervals.count.should == 3 } - specify{ subject.timeline_intervals.last.end_pos.should < 1 } - specify{ subject.timeline_events.count.should == 4 } + specify { subject.timeline_intervals.count.should == 3 } + specify { subject.timeline_intervals.last.end_pos.should < 1 } + specify { subject.timeline_events.count.should == 4 } end context "when deleted and then readded" do - let(:tc){ + let(:tc) { tc = create_cites_eu_species create_cites_I_addition( :taxon_concept => tc, @@ -106,16 +106,16 @@ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings MTaxonConcept.find(tc.id) } - let(:ttc){ Checklist::TimelinesForTaxonConcept.new(tc) } - let(:subject){ ttc.timelines.first } + let(:ttc) { Checklist::TimelinesForTaxonConcept.new(tc) } + let(:subject) { ttc.timelines.first } - specify{ subject.timeline_intervals.count.should == 2 } - specify{ subject.timeline_events.count.should == 3 } - specify{ subject.timeline_intervals[0].end_pos.should == subject.timeline_intervals[1].start_pos } + specify { subject.timeline_intervals.count.should == 2 } + specify { subject.timeline_events.count.should == 3 } + specify { subject.timeline_intervals[0].end_pos.should == subject.timeline_intervals[1].start_pos } end context "when reservation withdrawn" do - let(:tc){ + let(:tc) { tc = create_cites_eu_species create_cites_I_addition( :taxon_concept => tc, @@ -148,16 +148,16 @@ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings MTaxonConcept.find(tc.id) } - let(:ttc){ Checklist::TimelinesForTaxonConcept.new(tc) } - let(:subject){ ttc.timelines.first.timelines.first } + let(:ttc) { Checklist::TimelinesForTaxonConcept.new(tc) } + let(:subject) { ttc.timelines.first.timelines.first } - specify{ puts subject.timeline_events.inspect; puts subject.timeline_intervals.inspect; subject.timeline_intervals.count.should == 1 } - specify{ subject.timeline_events.count.should == 2 } - specify{ subject.timeline_intervals[0].end_pos.should == subject.timeline_events[1].pos } + specify { puts subject.timeline_events.inspect; puts subject.timeline_intervals.inspect; subject.timeline_intervals.count.should == 1 } + specify { subject.timeline_events.count.should == 2 } + specify { subject.timeline_intervals[0].end_pos.should == subject.timeline_events[1].pos } end context "when reservation withdrawn and then readded" do - let(:tc){ + let(:tc) { tc = create_cites_eu_species cnt = create(:geo_entity, geo_entity_type: country_geo_entity_type) r1 = create_cites_III_reservation( @@ -196,17 +196,17 @@ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings MTaxonConcept.find(tc.id) } - let(:ttc){ Checklist::TimelinesForTaxonConcept.new(tc) } - let(:subject){ ttc.timelines.last.timelines.first } + let(:ttc) { Checklist::TimelinesForTaxonConcept.new(tc) } + let(:subject) { ttc.timelines.last.timelines.first } - specify{ subject.timeline_intervals.count.should == 2 } - specify{ subject.timeline_events.count.should == 3 } - specify{ subject.timeline_intervals[0].end_pos.should == subject.timeline_events[1].pos } - specify{ subject.timeline_intervals[1].end_pos.should == 1 } + specify { subject.timeline_intervals.count.should == 2 } + specify { subject.timeline_events.count.should == 3 } + specify { subject.timeline_intervals[0].end_pos.should == subject.timeline_events[1].pos } + specify { subject.timeline_intervals[1].end_pos.should == 1 } end context "when added multiple times" do - let(:tc){ + let(:tc) { tc = create_cites_eu_species create_cites_I_addition( :taxon_concept => tc, @@ -221,19 +221,19 @@ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings MTaxonConcept.find(tc.id) } - let(:ttc){ Checklist::TimelinesForTaxonConcept.new(tc) } - let(:subject){ ttc.timelines.first } + let(:ttc) { Checklist::TimelinesForTaxonConcept.new(tc) } + let(:subject) { ttc.timelines.first } - specify{ + specify { subject.timeline_events.map(&:change_type_name).should == ['ADDITION', 'AMENDMENT'] } - specify{ subject.timeline_intervals.count.should == 2 } - specify{ subject.timeline_intervals[1].end_pos.should == 1 } + specify { subject.timeline_intervals.count.should == 2 } + specify { subject.timeline_intervals[1].end_pos.should == 1 } end context "when automatic deletion from ancestor listing" do - let(:tc){ + let(:tc) { genus = create_cites_eu_genus tc = create_cites_eu_species(parent: genus) create_cites_I_addition( @@ -250,15 +250,15 @@ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings MTaxonConcept.find(tc.id) } - let(:ttc){ Checklist::TimelinesForTaxonConcept.new(tc) } - let(:subject){ ttc.timelines.first } + let(:ttc) { Checklist::TimelinesForTaxonConcept.new(tc) } + let(:subject) { ttc.timelines.first } - specify{ + specify { subject.timeline_events.map(&:change_type_name).should == ['ADDITION', 'DELETION'] } - specify{ subject.timeline_intervals.count.should == 1 } - specify{ subject.timeline_intervals[0].end_pos.should == subject.timeline_events[1].pos } + specify { subject.timeline_intervals.count.should == 1 } + specify { subject.timeline_intervals[0].end_pos.should == subject.timeline_events[1].pos } end end diff --git a/spec/models/checklist/timelines_for_taxon_concept_spec.rb b/spec/models/checklist/timelines_for_taxon_concept_spec.rb index ce901d6cc6..5072ccd499 100644 --- a/spec/models/checklist/timelines_for_taxon_concept_spec.rb +++ b/spec/models/checklist/timelines_for_taxon_concept_spec.rb @@ -11,7 +11,7 @@ describe :timelines do context "when Appendix I" do - let(:tc){ + let(:tc) { tc = create_cites_eu_species create_cites_I_addition( :taxon_concept => tc, @@ -21,12 +21,12 @@ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings MTaxonConcept.find(tc.id) } - subject{ Checklist::TimelinesForTaxonConcept.new(tc) } - specify{ subject.raw_timelines['I'].timeline_events.should_not be_empty } - specify{ subject.raw_timelines['II'].timeline_events.should be_empty } + subject { Checklist::TimelinesForTaxonConcept.new(tc) } + specify { subject.raw_timelines['I'].timeline_events.should_not be_empty } + specify { subject.raw_timelines['II'].timeline_events.should be_empty } end context "when Appendix III" do - let(:tc){ + let(:tc) { tc = create_cites_eu_species lc = create_cites_III_addition( :taxon_concept => tc, @@ -42,12 +42,12 @@ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings MTaxonConcept.find(tc.id) } - subject{ Checklist::TimelinesForTaxonConcept.new(tc) } - specify{ subject.raw_timelines['III'].timeline_events.should_not be_empty } - specify{ subject.raw_timelines['I'].timeline_events.should be_empty } + subject { Checklist::TimelinesForTaxonConcept.new(tc) } + specify { subject.raw_timelines['III'].timeline_events.should_not be_empty } + specify { subject.raw_timelines['I'].timeline_events.should be_empty } end context "when Appendix III reservation" do - let(:tc){ + let(:tc) { tc = create_cites_eu_species lc = create_cites_III_reservation( :taxon_concept => tc, @@ -63,24 +63,24 @@ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings MTaxonConcept.find(tc.id) } - subject{ Checklist::TimelinesForTaxonConcept.new(tc) } - specify{ subject.raw_timelines['III'].timeline_events.should be_empty } - specify{ subject.raw_timelines['III'].timelines.first.timeline_events.should_not be_empty } - specify{ subject.raw_timelines['I'].timeline_events.should be_empty } + subject { Checklist::TimelinesForTaxonConcept.new(tc) } + specify { subject.raw_timelines['III'].timeline_events.should be_empty } + specify { subject.raw_timelines['III'].timelines.first.timeline_events.should_not be_empty } + specify { subject.raw_timelines['I'].timeline_events.should be_empty } end end describe :timeline_years do context "when in 1990" do - let(:tc){ + let(:tc) { tc = create(:taxon_concept) Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings MTaxonConcept.find(tc.id) } - subject{ Checklist::TimelinesForTaxonConcept.new(tc).timeline_years } - specify{ subject.size.should == 5 } - specify{ subject.first.year.should == 1975 } - specify{ subject.last.year.should == 1995 } + subject { Checklist::TimelinesForTaxonConcept.new(tc).timeline_years } + specify { subject.size.should == 5 } + specify { subject.first.year.should == 1975 } + specify { subject.last.year.should == 1995 } end end diff --git a/spec/models/cites_cop_spec.rb b/spec/models/cites_cop_spec.rb index 38f12258bf..2a77ab7fd3 100644 --- a/spec/models/cites_cop_spec.rb +++ b/spec/models/cites_cop_spec.rb @@ -28,7 +28,7 @@ describe CitesCop do describe :create do context "when designation invalid" do - let(:cites_cop){ + let(:cites_cop) { build( :cites_cop, :designation => eu @@ -38,7 +38,7 @@ specify { cites_cop.should have(1).error_on(:designation_id) } end context "when effective_at is blank" do - let(:cites_cop){ + let(:cites_cop) { build( :cites_cop, :effective_at => nil @@ -50,13 +50,13 @@ end describe :destroy do - let(:cites_cop){ create_cites_cop } + let(:cites_cop) { create_cites_cop } context "when no dependent objects attached" do specify { cites_cop.destroy.should be_true } end context "when dependent objects attached" do context "when listing changes" do - let!(:listing_change){ create_cites_I_addition(:event => cites_cop) } + let!(:listing_change) { create_cites_I_addition(:event => cites_cop) } specify { cites_cop.destroy.should be_false } end end diff --git a/spec/models/cites_suspension_notification_spec.rb b/spec/models/cites_suspension_notification_spec.rb index af42a61f82..ff1407bda4 100644 --- a/spec/models/cites_suspension_notification_spec.rb +++ b/spec/models/cites_suspension_notification_spec.rb @@ -28,7 +28,7 @@ describe CitesSuspensionNotification do describe :create do context "when designation invalid" do - let(:cites_suspension_notification){ + let(:cites_suspension_notification) { build( :cites_suspension_notification, :designation => eu @@ -38,7 +38,7 @@ specify { cites_suspension_notification.should have(1).error_on(:designation_id) } end context "when effective_at is blank" do - let(:cites_suspension_notification){ + let(:cites_suspension_notification) { build( :cites_suspension_notification, :effective_at => nil @@ -50,13 +50,13 @@ end describe :destroy do - let(:cites_suspension_notification){ create_cites_suspension_notification } + let(:cites_suspension_notification) { create_cites_suspension_notification } context "when no dependent objects attached" do specify { cites_suspension_notification.destroy.should be_true } end context "when dependent objects attached" do context "when start notification" do - let!(:cites_suspension){ + let!(:cites_suspension) { create( :cites_suspension, :start_notification => cites_suspension_notification ) @@ -64,7 +64,7 @@ specify { cites_suspension_notification.destroy.should be_false } end context "when end notification" do - let!(:cites_suspension){ + let!(:cites_suspension) { create( :cites_suspension, :start_notification => create_cites_suspension_notification, @@ -74,7 +74,7 @@ specify { cites_suspension_notification.destroy.should be_false } end context "when confirmation notification, make sure it gets destroyed" do - let!(:cites_suspension){ + let!(:cites_suspension) { create( :cites_suspension, :start_notification => create_cites_suspension_notification, @@ -82,7 +82,7 @@ ) } subject { cites_suspension_notification.cites_suspension_confirmations } - specify{ + specify { cites_suspension_notification.destroy subject.reload.should be_empty } @@ -91,15 +91,15 @@ end describe :end_date_formatted do - let(:cites_suspension_notification){ create_cites_suspension_notification(:end_date => '2012-05-10') } + let(:cites_suspension_notification) { create_cites_suspension_notification(:end_date => '2012-05-10') } specify { cites_suspension_notification.end_date_formatted.should == '10/05/2012' } end describe :bases_for_suspension do - let!(:cites_suspension_notification1){ create_cites_suspension_notification(:subtype => 'A') } - let!(:cites_suspension_notification2){ create_cites_suspension_notification(:subtype => 'A') } - let!(:cites_suspension_notification3){ create_cites_suspension_notification(:subtype => 'B') } - subject{ CitesSuspensionNotification.bases_for_suspension } - specify{ subject.length == 2 } + let!(:cites_suspension_notification1) { create_cites_suspension_notification(:subtype => 'A') } + let!(:cites_suspension_notification2) { create_cites_suspension_notification(:subtype => 'A') } + let!(:cites_suspension_notification3) { create_cites_suspension_notification(:subtype => 'B') } + subject { CitesSuspensionNotification.bases_for_suspension } + specify { subject.length == 2 } end end diff --git a/spec/models/cites_suspension_spec.rb b/spec/models/cites_suspension_spec.rb index a3e194db21..ab12ebc0b6 100644 --- a/spec/models/cites_suspension_spec.rb +++ b/spec/models/cites_suspension_spec.rb @@ -33,7 +33,7 @@ require 'spec_helper' describe CitesSuspension, sidekiq: :inline do - let(:tanzania){ + let(:tanzania) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -41,7 +41,7 @@ :iso_code2 => 'TZ' ) } - let(:rwanda){ + let(:rwanda) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -70,19 +70,19 @@ context "touching taxa" do describe :create do context "when taxon specific suspension" do - subject{ + subject { build( :cites_suspension, :taxon_concept => @taxon_concept, :start_notification => create_cites_suspension_notification ) } - specify{ - expect{ subject.save }.to change{ @taxon_concept.reload.dependents_updated_at } + specify { + expect { subject.save }.to change { @taxon_concept.reload.dependents_updated_at } } end context "when global suspension" do - subject{ + subject { build( :cites_suspension, :taxon_concept_id => nil, @@ -90,39 +90,39 @@ :start_notification => create_cites_suspension_notification ) } - specify{ - expect{ subject.save }.to change{ @taxon_concept.reload.dependents_updated_at } + specify { + expect { subject.save }.to change { @taxon_concept.reload.dependents_updated_at } } end context "when suspension at higher taxonomic level" do - subject{ + subject { create( :cites_suspension, :taxon_concept => @genus, :start_notification => create_cites_suspension_notification ) } - specify{ - expect{ subject.save }.to change{ @taxon_concept.reload.dependents_updated_at } + specify { + expect { subject.save }.to change { @taxon_concept.reload.dependents_updated_at } } end end describe :update do context "when taxon specific suspension" do - subject{ + subject { create( :cites_suspension, :taxon_concept => @taxon_concept, :start_notification => create_cites_suspension_notification ) } - specify{ - expect{ subject.update_attribute(:taxon_concept_id, @another_taxon_concept.id) }. - to change{ @taxon_concept.reload.dependents_updated_at } + specify { + expect { subject.update_attribute(:taxon_concept_id, @another_taxon_concept.id) }. + to change { @taxon_concept.reload.dependents_updated_at } } end context "when global suspension" do - subject{ + subject { create( :cites_suspension, :taxon_concept_id => nil, @@ -130,44 +130,44 @@ :start_notification => create_cites_suspension_notification ) } - specify{ - expect{ subject.update_attribute(:geo_entity_id, rwanda.id) }. - to change{ @taxon_concept.reload.dependents_updated_at } + specify { + expect { subject.update_attribute(:geo_entity_id, rwanda.id) }. + to change { @taxon_concept.reload.dependents_updated_at } } - specify{ - expect{ subject.update_attribute(:geo_entity_id, rwanda.id) }. - to change{ @another_taxon_concept.reload.dependents_updated_at } + specify { + expect { subject.update_attribute(:geo_entity_id, rwanda.id) }. + to change { @another_taxon_concept.reload.dependents_updated_at } } end context "when suspension at higher taxonomic level" do - subject{ + subject { create( :cites_suspension, :taxon_concept => @genus, :start_notification => create_cites_suspension_notification ) } - specify{ - expect{ subject.update_attribute(:geo_entity_id, rwanda.id) }. - to change{ @taxon_concept.reload.dependents_updated_at } + specify { + expect { subject.update_attribute(:geo_entity_id, rwanda.id) }. + to change { @taxon_concept.reload.dependents_updated_at } } end end describe :destroy do context "when taxon specific suspension" do - subject{ + subject { create( :cites_suspension, :taxon_concept => @taxon_concept, :start_notification => create_cites_suspension_notification ) } - specify{ - expect{ subject.destroy }.to change{ @taxon_concept.reload.dependents_updated_at } + specify { + expect { subject.destroy }.to change { @taxon_concept.reload.dependents_updated_at } } end context "when global suspension" do - subject{ + subject { create( :cites_suspension, :taxon_concept_id => nil, @@ -175,22 +175,22 @@ :start_notification => create_cites_suspension_notification ) } - specify{ - expect{ subject.destroy }. - to change{ @taxon_concept.reload.dependents_updated_at } + specify { + expect { subject.destroy }. + to change { @taxon_concept.reload.dependents_updated_at } } end context "when suspension at higher taxonomic level" do - subject{ + subject { create( :cites_suspension, :taxon_concept => @genus, :start_notification => create_cites_suspension_notification ) } - specify{ - expect{ subject.destroy }. - to change{ @taxon_concept.reload.dependents_updated_at } + specify { + expect { subject.destroy }. + to change { @taxon_concept.reload.dependents_updated_at } } end end @@ -199,7 +199,7 @@ context "validations" do describe :create do context "when start notification missing" do - let(:cites_suspension){ + let(:cites_suspension) { build( :cites_suspension, :start_notification => nil, @@ -212,7 +212,7 @@ end context "when start date greater than end date" do - let(:cites_suspension){ + let(:cites_suspension) { build( :cites_suspension, :start_notification => create_cites_suspension_notification(:effective_at => 1.week.from_now), @@ -226,7 +226,7 @@ end context "when valid" do - let(:cites_suspension){ + let(:cites_suspension) { build( :cites_suspension, :taxon_concept => @taxon_concept, diff --git a/spec/models/dashboard_stats_species_spec.rb b/spec/models/dashboard_stats_species_spec.rb index e0d946d658..60e9b9b348 100644 --- a/spec/models/dashboard_stats_species_spec.rb +++ b/spec/models/dashboard_stats_species_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' describe DashboardStats do - let(:argentina){ + let(:argentina) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -10,7 +10,7 @@ :iso_code2 => 'AR' ) } - let(:ghana){ + let(:ghana) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -18,10 +18,10 @@ :iso_code2 => 'GH' ) } - let(:ds_ar){ + let(:ds_ar) { DashboardStats.new argentina, { :kingdom => 'Animalia', :trade_limit => 5 } } - let(:ds_gh){ + let(:ds_gh) { DashboardStats.new ghana, { :kingdom => 'Animalia', :trade_limit => 5 } } diff --git a/spec/models/dashboard_stats_trade_spec.rb b/spec/models/dashboard_stats_trade_spec.rb index bfd49dd60c..796de86bbc 100644 --- a/spec/models/dashboard_stats_trade_spec.rb +++ b/spec/models/dashboard_stats_trade_spec.rb @@ -38,7 +38,7 @@ ) end context "when no time range specified" do - subject{ + subject { DashboardStats.new(@argentina, { :kingdom => 'Animalia', :trade_limit => 5, :time_range_start => 2010, :time_range_end => 2013 @@ -51,7 +51,7 @@ end end context "when time range specified" do - subject{ + subject { DashboardStats.new(@argentina, { :kingdom => 'Animalia', :trade_limit => 5, diff --git a/spec/models/designation_spec.rb b/spec/models/designation_spec.rb index 45153d87b1..5d1e9040e0 100644 --- a/spec/models/designation_spec.rb +++ b/spec/models/designation_spec.rb @@ -14,57 +14,57 @@ describe Designation do describe :create do context "when valid" do - let(:designation){ build(:designation, :name => 'GALACTIC REGULATIONS') } + let(:designation) { build(:designation, :name => 'GALACTIC REGULATIONS') } specify { designation.should be_valid } end context "when name missing" do - let(:designation){ build(:designation, :name => nil) } + let(:designation) { build(:designation, :name => nil) } specify { designation.should be_invalid } specify { designation.should have(1).error_on(:name) } end context "when name duplicated" do - let!(:designation1){ create(:designation) } - let(:designation2){ build(:designation, :name => designation1.name) } + let!(:designation1) { create(:designation) } + let(:designation2) { build(:designation, :name => designation1.name) } specify { designation2.should be_invalid } specify { designation2.should have(1).error_on(:name) } end end describe :update do context "when updating a non-protected name" do - let(:designation){ create(:designation) } - specify{ + let(:designation) { create(:designation) } + specify { designation.update_attributes( { :name => 'RULES OF INTERGALACTIC TRADE' } ).should be_true } end context "when updating a protected name" do - specify{ + specify { cites.update_attributes( { :name => 'RULES OF INTERGALACTIC TRADE' } ).should be_false } end context "when updating taxonomy with no dependent objects attached" do - let(:designation){ create(:designation) } - let(:taxonomy){ create(:taxonomy) } - specify{ designation.update_attributes(:taxonomy_id => taxonomy.id).should be_true } + let(:designation) { create(:designation) } + let(:taxonomy) { create(:taxonomy) } + specify { designation.update_attributes(:taxonomy_id => taxonomy.id).should be_true } end context "when updating taxonomy with dependent objects attached" do - let(:designation){ create(:designation) } - let!(:change_type){ create(:change_type, :designation => designation) } - let(:taxonomy){ create(:taxonomy) } - specify{ designation.update_attributes(:taxonomy_id => taxonomy.id).should be_false } + let(:designation) { create(:designation) } + let!(:change_type) { create(:change_type, :designation => designation) } + let(:taxonomy) { create(:taxonomy) } + specify { designation.update_attributes(:taxonomy_id => taxonomy.id).should be_false } end end describe :destroy do context "when no dependent objects attached" do - let(:designation){ create(:designation, :name => 'GALACTIC REGULATIONS') } + let(:designation) { create(:designation, :name => 'GALACTIC REGULATIONS') } specify { designation.destroy.should be_true } end context "when dependent objects attached" do - let(:designation){ create(:designation, :name => 'GALACTIC REGULATIONS') } - let!(:change_type){ create(:change_type, :designation => designation) } + let(:designation) { create(:designation, :name => 'GALACTIC REGULATIONS') } + let!(:change_type) { create(:change_type, :designation => designation) } specify { designation.destroy.should be_false } end context "when protected name" do diff --git a/spec/models/document_batch_spec.rb b/spec/models/document_batch_spec.rb index c5910187a4..af4b4bb07c 100644 --- a/spec/models/document_batch_spec.rb +++ b/spec/models/document_batch_spec.rb @@ -14,8 +14,8 @@ ] ) } - specify{ expect(subject.save).to be_false } - specify{ expect{ subject.save }.not_to change{ Document.count } } + specify { expect(subject.save).to be_false } + specify { expect { subject.save }.not_to change { Document.count } } end context "when valid" do subject { @@ -29,8 +29,8 @@ ] ) } - specify{ expect(subject.save).to be_true } - specify{ expect{ subject.save }.to change{ Document.count }.by(1) } + specify { expect(subject.save).to be_true } + specify { expect { subject.save }.to change { Document.count }.by(1) } end end end \ No newline at end of file diff --git a/spec/models/document_search_spec.rb b/spec/models/document_search_spec.rb index bbd259b1e0..b44404c4dd 100644 --- a/spec/models/document_search_spec.rb +++ b/spec/models/document_search_spec.rb @@ -1,12 +1,12 @@ require 'spec_helper' describe DocumentSearch, sidekiq: :inline do describe :results do - let(:meliaceae){ + let(:meliaceae) { create_cites_eu_family( taxon_name: create(:taxon_name, scientific_name: 'Meliaceae') ) } - let(:swietenia_macrophylla){ + let(:swietenia_macrophylla) { create_cites_eu_species( taxon_name: create(:taxon_name, scientific_name: 'Swietenia macrophylla'), parent: create_cites_eu_genus( @@ -15,7 +15,7 @@ ) ) } - let(:cedrela_odorata){ + let(:cedrela_odorata) { create_cites_eu_species( taxon_name: create(:taxon_name, scientific_name: 'Cedrela odorata'), parent: create_cites_eu_genus( @@ -24,7 +24,7 @@ ) ) } - let(:belize){ + let(:belize) { create( :geo_entity, geo_entity_type: country_geo_entity_type, @@ -32,7 +32,7 @@ iso_code2: 'BZ' ) } - let(:brazil){ + let(:brazil) { create( :geo_entity, geo_entity_type: country_geo_entity_type, @@ -40,7 +40,7 @@ iso_code2: 'BR' ) } - let(:document_on_swietenia){ + let(:document_on_swietenia) { document = create( :proposal, is_public: true, @@ -58,7 +58,7 @@ ) document } - let(:document_on_swietenia_in_belize){ + let(:document_on_swietenia_in_belize) { document = create( :proposal, is_public: true, event: create(:cites_cop, designation: cites), @@ -80,7 +80,7 @@ ) document } - let(:document_on_swietenia_in_brazil){ + let(:document_on_swietenia_in_brazil) { document = create( :proposal, is_public: true, event: create(:cites_cop, designation: cites), @@ -102,7 +102,7 @@ ) document } - let(:document_on_swietenia_in_belize_and_brazil){ + let(:document_on_swietenia_in_belize_and_brazil) { document = create( :proposal, is_public: true, event: create(:cites_cop, designation: cites), @@ -129,7 +129,7 @@ ) document } - let(:document_on_swietenia_in_belize_and_cedrela_in_brazil){ + let(:document_on_swietenia_in_belize_and_cedrela_in_brazil) { document = create( :proposal, is_public: true, event: create(:cites_cop, designation: cites), @@ -164,7 +164,7 @@ ) document } - let(:document_on_brazil){ + let(:document_on_brazil) { document = create( :proposal, is_public: true, event: create(:cites_cop, designation: cites), @@ -181,7 +181,7 @@ ) document } - let(:document_without_citations){ + let(:document_without_citations) { document = create( :proposal, is_public: true, event: create(:cites_cop, designation: cites), diff --git a/spec/models/document_spec.rb b/spec/models/document_spec.rb index 4bb5befafd..01e6125421 100644 --- a/spec/models/document_spec.rb +++ b/spec/models/document_spec.rb @@ -30,7 +30,7 @@ describe :create do context "when date is blank" do - let(:document){ + let(:document) { build( :document, :date => nil @@ -40,40 +40,40 @@ specify { expect(document).to have(1).error_on(:date) } end context "setting title from filename" do - let(:document){ create(:document) } - specify{ expect(document.title).to eq('Annual report upload exporter') } + let(:document) { create(:document) } + specify { expect(document.title).to eq('Annual report upload exporter') } end context "when specified designation conflicts with event" do - let(:cites_cop){ create_cites_cop } - let(:document){ + let(:cites_cop) { create_cites_cop } + let(:document) { create(:document, event: cites_cop, designation: eu) } - specify{ expect(document.designation).to eq(cites) } + specify { expect(document.designation).to eq(cites) } end context "when documents with same language and same primary document" do - let(:language){ create(:language) } - let(:primary_document){ create(:document) } - let!(:document1){ create(:document, + let(:language) { create(:language) } + let(:primary_document) { create(:document) } + let!(:document1) { create(:document, language_id: language.id, primary_language_document_id: primary_document.id) } - let(:document2){ build(:document, + let(:document2) { build(:document, language_id: language.id, primary_language_document_id: primary_document.id) } - specify{ expect(document2).to be_invalid } - specify{ expect(document2).to have(1).error_on(:primary_language_document_id) } + specify { expect(document2).to be_invalid } + specify { expect(document2).to have(1).error_on(:primary_language_document_id) } end end describe :update do - let(:primary_document){ + let(:primary_document) { create(:proposal, sort_index: 1) } - let!(:secondary_document){ + let!(:secondary_document) { create(:proposal, sort_index: 2, primary_language_document_id: primary_document.id @@ -94,24 +94,24 @@ end describe :destroy do - let(:primary_document){ + let(:primary_document) { create(:proposal) } - let!(:secondary_document){ + let!(:secondary_document) { create(:proposal, primary_language_document_id: primary_document.id) } context "when secondary document destroyed" do specify "document count decreases by 1" do expect { secondary_document.destroy - }.to change{ Document.count }.by(-1) + }.to change { Document.count }.by(-1) end end context "when primary document destroyed" do specify "document count decreases by 1" do - expect{ + expect { primary_document.destroy - }.to change{ Document.count }.by(-1) + }.to change { Document.count }.by(-1) end specify "secondary document becomes primary" do primary_document.destroy diff --git a/spec/models/eu_opinion_spec.rb b/spec/models/eu_opinion_spec.rb index ca5e14f6f8..0b48b758bb 100644 --- a/spec/models/eu_opinion_spec.rb +++ b/spec/models/eu_opinion_spec.rb @@ -32,7 +32,7 @@ describe :create do context "when taxon concept missing" do - let(:eu_opinion){ + let(:eu_opinion) { build( :eu_opinion, taxon_concept: nil ) @@ -43,7 +43,7 @@ end context "when geo_entity missing" do - let(:eu_opinion){ + let(:eu_opinion) { build( :eu_opinion, geo_entity: nil ) @@ -54,7 +54,7 @@ end context "when start_date missing" do - let(:eu_opinion){ + let(:eu_opinion) { build(:eu_opinion, start_date: nil) } @@ -63,7 +63,7 @@ end context "when valid" do - let(:eu_opinion){ build(:eu_opinion) } + let(:eu_opinion) { build(:eu_opinion) } specify { eu_opinion.should be_valid } end diff --git a/spec/models/eu_regulation_spec.rb b/spec/models/eu_regulation_spec.rb index c9808c9cde..df356f9e59 100644 --- a/spec/models/eu_regulation_spec.rb +++ b/spec/models/eu_regulation_spec.rb @@ -28,15 +28,15 @@ describe EuRegulation do describe :create do context "when eu_regulation to copy from given" do - let(:eu_regulation1){ create_eu_regulation } + let(:eu_regulation1) { create_eu_regulation } before do EventListingChangesCopyWorker.jobs.clear create_eu_regulation(:listing_changes_event_id => eu_regulation1.id) end - specify{ EventListingChangesCopyWorker.jobs.size.should == 1 } + specify { EventListingChangesCopyWorker.jobs.size.should == 1 } end context "when designation invalid" do - let(:eu_regulation){ + let(:eu_regulation) { build( :eu_regulation, :designation => cites @@ -46,7 +46,7 @@ specify { eu_regulation.should have(1).error_on(:designation_id) } end context "when effective_at is blank" do - let(:eu_regulation){ + let(:eu_regulation) { build( :eu_regulation, :effective_at => nil @@ -57,33 +57,33 @@ end end describe :activate do - let(:eu_regulation){ create_eu_regulation(:name => 'REGULATION 2.0') } + let(:eu_regulation) { create_eu_regulation(:name => 'REGULATION 2.0') } before do EuRegulationActivationWorker.jobs.clear eu_regulation.activate! end - specify{ eu_regulation.is_current.should be_true } - specify{ EuRegulationActivationWorker.jobs.size.should == 1 } + specify { eu_regulation.is_current.should be_true } + specify { EuRegulationActivationWorker.jobs.size.should == 1 } end describe :deactivate do - let(:eu_regulation){ create_eu_regulation(:name => 'REGULATION 2.0', :is_current => true) } + let(:eu_regulation) { create_eu_regulation(:name => 'REGULATION 2.0', :is_current => true) } before do EuRegulationActivationWorker.jobs.clear eu_regulation.deactivate! end - specify{ eu_regulation.is_current.should be_false } - specify{ EuRegulationActivationWorker.jobs.size.should == 1 } + specify { eu_regulation.is_current.should be_false } + specify { EuRegulationActivationWorker.jobs.size.should == 1 } end describe :destroy do - let(:eu_regulation){ create_eu_regulation } + let(:eu_regulation) { create_eu_regulation } context "when no dependent objects attached" do specify { eu_regulation.destroy.should be_true } end context "when dependent objects attached" do context "when listing changes" do - let!(:listing_change){ create_eu_A_addition(:event => eu_regulation) } + let!(:listing_change) { create_eu_A_addition(:event => eu_regulation) } specify { eu_regulation.destroy.should be_true } end end diff --git a/spec/models/eu_suspension_spec.rb b/spec/models/eu_suspension_spec.rb index 593ea6e5de..97950cd714 100644 --- a/spec/models/eu_suspension_spec.rb +++ b/spec/models/eu_suspension_spec.rb @@ -32,7 +32,7 @@ describe :create do context "when taxon concept missing" do - let(:eu_suspension){ + let(:eu_suspension) { build( :eu_suspension, taxon_concept: nil ) @@ -43,7 +43,7 @@ end context "when geo_entity missing" do - let(:eu_suspension){ + let(:eu_suspension) { build( :eu_suspension, geo_entity: nil @@ -55,7 +55,7 @@ end context "when valid" do - let(:eu_suspension){ build(:eu_suspension) } + let(:eu_suspension) { build(:eu_suspension) } specify { eu_suspension.should be_valid } end diff --git a/spec/models/event_spec.rb b/spec/models/event_spec.rb index c6682f4ccd..38cb35a8a8 100644 --- a/spec/models/event_spec.rb +++ b/spec/models/event_spec.rb @@ -28,29 +28,29 @@ describe Event do describe :create do context "when valid" do - let(:event){ build(:event, :name => 'CoPX') } + let(:event) { build(:event, :name => 'CoPX') } specify { event.should be_valid } end context "when name missing" do - let(:event){ build(:event, :name => nil) } + let(:event) { build(:event, :name => nil) } specify { event.should be_invalid } specify { event.should have(1).error_on(:name) } end context "when name duplicated" do - let!(:event1){ create(:event) } - let(:event2){ build(:event, :name => event1.name) } + let!(:event1) { create(:event) } + let(:event2) { build(:event, :name => event1.name) } specify { event2.should be_invalid } specify { event2.should have(1).error_on(:name) } end context "when url invalid" do - let(:event){ build(:event, :url => 'www.google.com') } + let(:event) { build(:event, :url => 'www.google.com') } specify { event.should be_invalid } specify { event.should have(1).error_on(:url) } end end describe :effective_at_formatted do - let(:event){ create(:event, :effective_at => '2012-05-10') } + let(:event) { create(:event, :effective_at => '2012-05-10') } specify { event.effective_at_formatted.should == '10/05/2012' } end end diff --git a/spec/models/geo_entity_search_spec.rb b/spec/models/geo_entity_search_spec.rb index 478bfcb5c4..ccd96e2396 100644 --- a/spec/models/geo_entity_search_spec.rb +++ b/spec/models/geo_entity_search_spec.rb @@ -105,7 +105,7 @@ iso_code2: 'BU' ) end - subject{ GeoEntitySearch.new({ geo_entity_types_set: '3' }) } + subject { GeoEntitySearch.new({ geo_entity_types_set: '3' }) } specify do subject.cached_results @burma.update_attributes({ is_current: false }) diff --git a/spec/models/geo_entity_spec.rb b/spec/models/geo_entity_spec.rb index c065d483a3..5ee691c96b 100644 --- a/spec/models/geo_entity_spec.rb +++ b/spec/models/geo_entity_spec.rb @@ -21,14 +21,14 @@ describe GeoEntity do describe :nodes_and_descendants do - let(:europe){ + let(:europe) { create( :geo_entity, :geo_entity_type => cites_region_geo_entity_type, :name => 'Europe' ) } - let(:poland){ + let(:poland) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -36,7 +36,7 @@ :iso_code2 => 'PL' ) } - let(:wolin){ + let(:wolin) { create( :geo_entity, :geo_entity_type => territory_geo_entity_type, @@ -44,7 +44,7 @@ ) } context "Europe should contain Europe, Poland and Wolin" do - let!(:poland_contains_wolin){ + let!(:poland_contains_wolin) { create( :geo_relationship, :geo_relationship_type => contains_geo_relationship_type, @@ -52,7 +52,7 @@ :related_geo_entity => wolin ) } - let!(:europe_contains_poland){ + let!(:europe_contains_poland) { create( :geo_relationship, :geo_relationship_type => contains_geo_relationship_type, @@ -60,35 +60,35 @@ :related_geo_entity => poland ) } - subject{ GeoEntity.nodes_and_descendants([europe.id]) } - specify{ subject.map(&:id).should include(europe.id, poland.id, wolin.id) } - specify{ subject.size.should == 3 } + subject { GeoEntity.nodes_and_descendants([europe.id]) } + specify { subject.map(&:id).should include(europe.id, poland.id, wolin.id) } + specify { subject.size.should == 3 } end end describe :destroy do - let(:geo_entity){ create(:geo_entity) } + let(:geo_entity) { create(:geo_entity) } context "when no dependent objects attached" do specify { geo_entity.destroy.should be_true } end context "when dependent objects attached" do context "when distributions" do - before(:each){ create(:distribution, :geo_entity => geo_entity) } + before(:each) { create(:distribution, :geo_entity => geo_entity) } specify { geo_entity.destroy.should be_false } end context "when exported shipments" do - before(:each){ create(:shipment, :exporter => geo_entity) } + before(:each) { create(:shipment, :exporter => geo_entity) } specify { geo_entity.destroy.should be_false } end context "when imported shipments" do - before(:each){ create(:shipment, :importer => geo_entity) } + before(:each) { create(:shipment, :importer => geo_entity) } specify { geo_entity.destroy.should be_false } end context "when originated shipments" do - before(:each){ create(:shipment, :country_of_origin => geo_entity) } + before(:each) { create(:shipment, :country_of_origin => geo_entity) } specify { geo_entity.destroy.should be_false } end context "when connected geo entities" do - let(:child_geo_entity){ create(:geo_entity) } + let(:child_geo_entity) { create(:geo_entity) } before(:each) do create( :geo_relationship, diff --git a/spec/models/html_to_latex_spec.rb b/spec/models/html_to_latex_spec.rb index 75dd59a5a4..0ac8da7bd9 100644 --- a/spec/models/html_to_latex_spec.rb +++ b/spec/models/html_to_latex_spec.rb @@ -5,40 +5,40 @@ subject { HtmlToLatex.convert(input_str) } context "when italics" do context "when tag closed" do - let(:input_str){ "Text about Foobarus lolus and friends" } - specify{ + let(:input_str) { "Text about Foobarus lolus and friends" } + specify { subject.should == "Text about \\textit{Foobarus lolus} and friends" } end context "when tag not closed" do - let(:input_str){ "Text about Foobarus lolus and friends" } - specify{ + let(:input_str) { "Text about Foobarus lolus and friends" } + specify { subject.should == "Text about \\textit{Foobarus lolus and friends}" } end end context "when paragraph" do context "when tag closed" do - let(:input_str){ "Text,

paragraph

and some more text" } - specify{ + let(:input_str) { "Text,

paragraph

and some more text" } + specify { subject.should == "Text, \\newline paragraph\\newline and some more text" } end context "when tag not closed" do - let(:input_str){ "Text,

paragraph and some more text" } - specify{ + let(:input_str) { "Text,

paragraph and some more text" } + specify { subject.should == "Text, \\newline paragraph and some more text" } end end context "when latex special characters" do context "within tags" do - let(:input_str){ "Lolus & friends" } - specify{ subject.should == "\\textbf{Lolus \\& friends}" } + let(:input_str) { "Lolus & friends" } + specify { subject.should == "\\textbf{Lolus \\& friends}" } end context "outside of tags" do - let(:input_str){ "Lolus & friends" } - specify{ subject.should == "\\textbf{Lolus} \\& friends" } + let(:input_str) { "Lolus & friends" } + specify { subject.should == "\\textbf{Lolus} \\& friends" } end end end diff --git a/spec/models/hybrid_relationship_spec.rb b/spec/models/hybrid_relationship_spec.rb index fec65538b0..828bb22633 100644 --- a/spec/models/hybrid_relationship_spec.rb +++ b/spec/models/hybrid_relationship_spec.rb @@ -2,39 +2,39 @@ describe TaxonRelationship do context "when hybrid" do - let(:parent){ + let(:parent) { create_cites_eu_genus( :taxon_name => create(:taxon_name, :scientific_name => 'Lolcatus') ) } - let!(:tc){ + let!(:tc) { create_cites_eu_species( :parent_id => parent.id, :taxon_name => create(:taxon_name, :scientific_name => 'lolatus') ) } - let!(:another_tc){ + let!(:another_tc) { create_cites_eu_species( :parent_id => parent.id, :taxon_name => create(:taxon_name, :scientific_name => 'lolcatus') ) } - let(:hybrid){ + let(:hybrid) { create_cites_eu_species( name_status: 'H', author_year: 'Hemulen 2013', scientific_name: 'Lolcatus lolatus x lolcatus' ) } - let(:another_hybrid){ + let(:another_hybrid) { create_cites_eu_species( name_status: 'H', author_year: 'Hemulen 2013', scientific_name: 'Lolcatus lolcatus x ?' ) } - let(:hybrid_rel){ + let(:hybrid_rel) { build( :taxon_relationship, taxon_relationship_type: hybrid_relationship_type, @@ -42,7 +42,7 @@ other_taxon_concept_id: hybrid.id ) } - let(:another_hybrid_rel){ + let(:another_hybrid_rel) { build( :taxon_relationship, taxon_relationship_type: hybrid_relationship_type, @@ -54,7 +54,7 @@ hybrid_rel.save tc.hybrids.map(&:full_name).should include('Lolcatus lolatus x lolcatus') } - specify{ + specify { hybrid_rel.save another_hybrid_rel.save hybrid_rel.other_taxon_concept = another_hybrid diff --git a/spec/models/listing_change_spec.rb b/spec/models/listing_change_spec.rb index 4d6c9ac3ab..188285ae85 100644 --- a/spec/models/listing_change_spec.rb +++ b/spec/models/listing_change_spec.rb @@ -32,68 +32,68 @@ context "validations" do describe :create do context "all fine with exception" do - let(:designation){ create(:designation) } - let!(:exception_type){ cites_exception } - let(:taxon_concept){ create(:taxon_concept) } - let(:excluded_taxon_concept){ create(:taxon_concept, :parent_id => taxon_concept) } - let(:listing_change){ + let(:designation) { create(:designation) } + let!(:exception_type) { cites_exception } + let(:taxon_concept) { create(:taxon_concept) } + let(:excluded_taxon_concept) { create(:taxon_concept, :parent_id => taxon_concept) } + let(:listing_change) { create_cites_I_addition( :taxon_concept => taxon_concept, :excluded_taxon_concepts_ids => "#{excluded_taxon_concept.id}" ) } - specify{ listing_change.exclusions.size == 0 } + specify { listing_change.exclusions.size == 0 } end context "inclusion taxon concept is lower rank" do - let(:inclusion){ create_cites_eu_subspecies } - let(:taxon_concept){ create_cites_eu_species } - let(:listing_change){ + let(:inclusion) { create_cites_eu_subspecies } + let(:taxon_concept) { create_cites_eu_species } + let(:listing_change) { build( :listing_change, taxon_concept: taxon_concept, inclusion_taxon_concept_id: inclusion.id ) } - specify{ listing_change.should have(1).error_on(:inclusion_taxon_concept_id) } + specify { listing_change.should have(1).error_on(:inclusion_taxon_concept_id) } end context "species listing designation mismatch" do - let(:designation1){ create(:designation) } - let(:designation2){ create(:designation) } - let(:listing_change){ + let(:designation1) { create(:designation) } + let(:designation2) { create(:designation) } + let(:listing_change) { build( :listing_change, :species_listing => create(:species_listing, :designation => designation1), :change_type => create(:change_type, :designation => designation2) ) } - specify{ listing_change.should have(1).error_on(:species_listing_id) } + specify { listing_change.should have(1).error_on(:species_listing_id) } end context "event designation mismatch" do - let(:designation1){ create(:designation) } - let(:designation2){ create(:designation) } - let(:listing_change){ + let(:designation1) { create(:designation) } + let(:designation2) { create(:designation) } + let(:listing_change) { build( :listing_change, :event_id => create(:event, :designation => designation1).id, :change_type => create(:change_type, :designation => designation2) ) } - specify{ listing_change.should have(1).error_on(:event_id) } + specify { listing_change.should have(1).error_on(:event_id) } end end end describe :effective_at_formatted do - let(:listing_change){ create_cites_I_addition(:effective_at => '2012-05-10') } + let(:listing_change) { create_cites_I_addition(:effective_at => '2012-05-10') } specify { listing_change.effective_at_formatted.should == '10/05/2012' } end describe :duplicates do - let(:lc1){ + let(:lc1) { lc = create_cites_I_addition(effective_at: '2014-11-17') lc.annotation = create(:annotation, full_note_en: ' ') lc } - let(:lc2){ + let(:lc2) { lc = create_cites_I_addition(effective_at: '2014-11-17') lc.annotation = create(:annotation, full_note_en: nil) lc diff --git a/spec/models/nomenclature_change/delete_unreassigned_processor_spec.rb b/spec/models/nomenclature_change/delete_unreassigned_processor_spec.rb index f41befca6b..4feddb6bf0 100644 --- a/spec/models/nomenclature_change/delete_unreassigned_processor_spec.rb +++ b/spec/models/nomenclature_change/delete_unreassigned_processor_spec.rb @@ -8,15 +8,15 @@ end describe :run do - let(:split){ split_with_input_with_reassignments } - let(:input){ split.input } - let(:processor){ + let(:split) { split_with_input_with_reassignments } + let(:input) { split.input } + let(:processor) { NomenclatureChange::DeleteUnreassignedProcessor.new(input) } context "delete unreassigned" do - specify{ expect(input_species.distributions.count).to eq(1) } - specify{ expect(input_species.taxon_relationships.count).to eq(2) } + specify { expect(input_species.distributions.count).to eq(1) } + specify { expect(input_species.taxon_relationships.count).to eq(2) } end end diff --git a/spec/models/nomenclature_change/full_reassignment_spec.rb b/spec/models/nomenclature_change/full_reassignment_spec.rb index e24cd9253b..5043bf9686 100644 --- a/spec/models/nomenclature_change/full_reassignment_spec.rb +++ b/spec/models/nomenclature_change/full_reassignment_spec.rb @@ -3,8 +3,8 @@ describe NomenclatureChange::FullReassignment do describe 'process' do - let(:old_tc){ create_cites_eu_species } - let(:new_tc){ create_cites_eu_species } + let(:old_tc) { create_cites_eu_species } + let(:new_tc) { create_cites_eu_species } subject { NomenclatureChange::FullReassignment.new(old_tc, new_tc) } context 'when distributions present' do @@ -12,7 +12,7 @@ create(:distribution, taxon_concept: old_tc) subject.process end - specify{ expect(new_tc.distributions.count).to eq(1) } + specify { expect(new_tc.distributions.count).to eq(1) } end context 'when references present' do @@ -20,7 +20,7 @@ create(:taxon_concept_reference, taxon_concept: old_tc) subject.process end - specify{ expect(new_tc.taxon_concept_references.count).to eq(1) } + specify { expect(new_tc.taxon_concept_references.count).to eq(1) } end context 'when listing changes present' do @@ -28,7 +28,7 @@ create_cites_I_addition(taxon_concept: old_tc) subject.process end - specify{ expect(new_tc.listing_changes.count).to eq(1) } + specify { expect(new_tc.listing_changes.count).to eq(1) } end context 'when EU Opinions present' do @@ -36,7 +36,7 @@ create(:eu_opinion, taxon_concept: old_tc) subject.process end - specify{ expect(new_tc.eu_opinions.count).to eq(1) } + specify { expect(new_tc.eu_opinions.count).to eq(1) } end context 'when EU Suspensions present' do @@ -44,7 +44,7 @@ create(:eu_suspension, taxon_concept: old_tc) subject.process end - specify{ expect(new_tc.eu_suspensions.count).to eq(1) } + specify { expect(new_tc.eu_suspensions.count).to eq(1) } end context 'when CITES Quotas present' do @@ -52,7 +52,7 @@ create(:quota, taxon_concept: old_tc, geo_entity: create(:geo_entity)) subject.process end - specify{ expect(new_tc.quotas.count).to eq(1) } + specify { expect(new_tc.quotas.count).to eq(1) } end context 'when CITES Suspensions present' do @@ -62,7 +62,7 @@ ) subject.process end - specify{ expect(new_tc.cites_suspensions.count).to eq(1) } + specify { expect(new_tc.cites_suspensions.count).to eq(1) } end context 'when common names present' do @@ -70,7 +70,7 @@ create(:taxon_common, taxon_concept: old_tc) subject.process end - specify{ expect(new_tc.taxon_commons.count).to eq(1) } + specify { expect(new_tc.taxon_commons.count).to eq(1) } end end diff --git a/spec/models/nomenclature_change/input_spec.rb b/spec/models/nomenclature_change/input_spec.rb index bba06995b2..0f3cc097ca 100644 --- a/spec/models/nomenclature_change/input_spec.rb +++ b/spec/models/nomenclature_change/input_spec.rb @@ -20,13 +20,13 @@ describe NomenclatureChange::Input do describe :validate do context "when nomenclature change not specified" do - let(:input){ + let(:input) { build(:nomenclature_change_input, :nomenclature_change_id => nil) } specify { expect(input).not_to be_valid } end context "when taxon concept not specified" do - let(:input){ + let(:input) { build(:nomenclature_change_input, :taxon_concept_id => nil) } specify { expect(input).not_to be_valid } diff --git a/spec/models/nomenclature_change/lump/constructor_spec.rb b/spec/models/nomenclature_change/lump/constructor_spec.rb index 12f8b2852b..0e152abcb4 100644 --- a/spec/models/nomenclature_change/lump/constructor_spec.rb +++ b/spec/models/nomenclature_change/lump/constructor_spec.rb @@ -3,46 +3,46 @@ describe NomenclatureChange::Lump::Constructor do include_context 'lump_definitions' - let(:constructor){ NomenclatureChange::Lump::Constructor.new(lump) } + let(:constructor) { NomenclatureChange::Lump::Constructor.new(lump) } context :inputs do describe :build_inputs do - let(:lump){ create(:nomenclature_change_lump) } - before(:each){ @old_inputs = lump.inputs; constructor.build_inputs } + let(:lump) { create(:nomenclature_change_lump) } + before(:each) { @old_inputs = lump.inputs; constructor.build_inputs } context "when previously no inputs in place" do - specify{ expect(lump.inputs.size).not_to eq(0) } + specify { expect(lump.inputs.size).not_to eq(0) } end context "when previously inputs in place" do - let(:lump){ lump_with_inputs } - specify{ expect(lump.inputs).to eq(@old_inputs) } + let(:lump) { lump_with_inputs } + specify { expect(lump.inputs).to eq(@old_inputs) } end end end context :outputs do describe :build_output do - let(:lump){ lump_with_inputs } - before(:each){ @old_output = lump.output; constructor.build_output } + let(:lump) { lump_with_inputs } + before(:each) { @old_output = lump.output; constructor.build_output } context "when previously no output in place" do - specify{ expect(lump.output).not_to be_nil } + specify { expect(lump.output).not_to be_nil } end context "when previously output in place" do - let(:lump){ lump_with_inputs_and_output } - specify{ expect(lump.output).to eq(@old_output) } + let(:lump) { lump_with_inputs_and_output } + specify { expect(lump.output).to eq(@old_output) } end end end context :reassignments do - let(:lump){ lump_with_inputs_and_output } - let(:nc){ lump } - let(:input){ nc.inputs[0] } + let(:lump) { lump_with_inputs_and_output } + let(:nc) { lump } + let(:input) { nc.inputs[0] } describe :build_input_and_output_notes do - let(:output){ lump.output } + let(:output) { lump.output } before(:each) do @old_input_note = input.note_en @old_output_note = output.note_en constructor.build_input_and_output_notes end context "when previously no notes in place" do - let(:lump){ + let(:lump) { create(:nomenclature_change_lump, inputs_attributes: { 0 => { taxon_concept_id: input_species1.id }, @@ -51,10 +51,10 @@ output_attributes: { taxon_concept_id: output_species.id } ) } - specify{ expect(input.note_en).not_to be_blank } - specify{ expect(output.note_en).not_to be_blank } + specify { expect(input.note_en).not_to be_blank } + specify { expect(output.note_en).not_to be_blank } context "when output = input" do - let(:lump){ + let(:lump) { create(:nomenclature_change_lump, inputs_attributes: { 0 => { taxon_concept_id: input_species1.id }, @@ -63,18 +63,18 @@ output_attributes: { taxon_concept_id: input_species1.id } ) } - specify{ expect(input.note_en).to be_blank } + specify { expect(input.note_en).to be_blank } end end context "when previously notes in place" do - let(:input){ + let(:input) { create(:nomenclature_change_input, nomenclature_change: lump, note_en: 'blah') } - let(:output){ + let(:output) { create(:nomenclature_change_output, nomenclature_change: lump, note_en: 'blah') } - specify{ expect(input.note_en).to eq(@old_input_note) } - specify{ expect(output.note_en).to eq(@old_output_note) } + specify { expect(input.note_en).to eq(@old_input_note) } + specify { expect(output.note_en).to eq(@old_output_note) } end end describe :build_parent_reassignments do @@ -85,27 +85,27 @@ include_context 'parent_reassignments_constructor_examples' context "when output = input" do - let(:input_species){ + let(:input_species) { s = create_cites_eu_species - 2.times{ create_cites_eu_subspecies(parent: s) } + 2.times { create_cites_eu_subspecies(parent: s) } s } - let(:lump_with_inputs_and_output){ lump_with_inputs_and_same_output } + let(:lump_with_inputs_and_output) { lump_with_inputs_and_same_output } let(:input) { lump.inputs_intersect_outputs.first } - let(:default_output){ lump.output } - specify{ + let(:default_output) { lump.output } + specify { reassignment_targets = input.parent_reassignments.map(&:reassignment_target) expect(reassignment_targets.map(&:output).uniq).to(eq([default_output])) } end context "when previously reassignments in place" do - let(:input){ + let(:input) { i = create(:nomenclature_change_input, nomenclature_change: lump, taxon_concept: input_species) create(:nomenclature_change_parent_reassignment, input: i) i } - specify{ expect(input.parent_reassignments).to eq(@old_reassignments) } + specify { expect(input.parent_reassignments).to eq(@old_reassignments) } end end describe :build_name_reassignments do @@ -116,7 +116,7 @@ include_context 'name_reassignments_constructor_examples' context "when output = input" do - let(:input_species){ + let(:input_species) { s = create_cites_eu_species 2.times do create(:taxon_relationship, @@ -127,10 +127,10 @@ end s } - let(:lump_with_inputs_and_output){ lump_with_inputs_and_same_output } + let(:lump_with_inputs_and_output) { lump_with_inputs_and_same_output } let(:input) { lump.inputs_intersect_outputs.first } - let(:default_output){ lump.output } - specify{ + let(:default_output) { lump.output } + specify { reassignment_targets = input.name_reassignments.map do |reassignment| reassignment.reassignment_targets end.flatten diff --git a/spec/models/nomenclature_change/lump/output_taxon_concept_processor_spec.rb b/spec/models/nomenclature_change/lump/output_taxon_concept_processor_spec.rb index 29970cd5f4..694dbe52d1 100644 --- a/spec/models/nomenclature_change/lump/output_taxon_concept_processor_spec.rb +++ b/spec/models/nomenclature_change/lump/output_taxon_concept_processor_spec.rb @@ -4,30 +4,30 @@ include_context 'lump_definitions' describe :run do - let(:processor){ + let(:processor) { NomenclatureChange::OutputTaxonConceptProcessor.new(output) } before(:each) do processor.run end context "when output is existing taxon" do - let(:output){ lump_with_inputs_and_output_existing_taxon.output } - specify{ expect(output.new_taxon_concept).to be_nil } + let(:output) { lump_with_inputs_and_output_existing_taxon.output } + specify { expect(output.new_taxon_concept).to be_nil } end context "when output is new taxon" do - let(:output){ lump_with_inputs_and_output_new_taxon.output } - specify{ expect(output.new_taxon_concept.full_name).to eq('Errorus fatalus') } + let(:output) { lump_with_inputs_and_output_new_taxon.output } + specify { expect(output.new_taxon_concept.full_name).to eq('Errorus fatalus') } end context "when output is existing taxon with new status" do - let(:output){ lump_with_inputs_and_output_status_change.output } - specify{ expect(output.new_taxon_concept).to be_nil } - specify{ expect(output.taxon_concept.name_status).to eq('A') } + let(:output) { lump_with_inputs_and_output_status_change.output } + specify { expect(output.new_taxon_concept).to be_nil } + specify { expect(output.taxon_concept.name_status).to eq('A') } end context "when output is existing taxon with new name" do - let(:output){ lump_with_inputs_and_output_name_change.output } - specify{ expect(output.taxon_concept.full_name).to eq('Errorus fatalus fatalus') } - specify{ expect(output.new_taxon_concept.name_status).to eq('A') } - specify{ expect(output.new_taxon_concept.full_name).to eq('Errorus lolcatus') } + let(:output) { lump_with_inputs_and_output_name_change.output } + specify { expect(output.taxon_concept.full_name).to eq('Errorus fatalus fatalus') } + specify { expect(output.new_taxon_concept.name_status).to eq('A') } + specify { expect(output.new_taxon_concept.full_name).to eq('Errorus lolcatus') } end end end diff --git a/spec/models/nomenclature_change/lump/processor_spec.rb b/spec/models/nomenclature_change/lump/processor_spec.rb index 41a44bff92..ac5f084972 100644 --- a/spec/models/nomenclature_change/lump/processor_spec.rb +++ b/spec/models/nomenclature_change/lump/processor_spec.rb @@ -3,74 +3,74 @@ describe NomenclatureChange::Lump::Processor do include_context 'lump_definitions' - before(:each){ + before(:each) { synonym_relationship_type @shipment = create(:shipment, taxon_concept: input_species1, reported_taxon_concept: input_species1 ) } - let(:processor){ NomenclatureChange::Lump::Processor.new(lump) } + let(:processor) { NomenclatureChange::Lump::Processor.new(lump) } describe :run do context "when outputs are existing taxa" do - let!(:lump){ lump_with_inputs_and_output_existing_taxon } - specify { expect{ processor.run }.not_to change(TaxonConcept, :count) } - specify { expect{ processor.run }.not_to change(output_species, :full_name) } + let!(:lump) { lump_with_inputs_and_output_existing_taxon } + specify { expect { processor.run }.not_to change(TaxonConcept, :count) } + specify { expect { processor.run }.not_to change(output_species, :full_name) } context "relationships and trade" do - before(:each){ processor.run } - specify{ expect(input_species1.reload).to be_is_synonym } - specify{ expect(input_species1.accepted_names).to include(output_species) } - specify{ expect(input_species1.shipments).to be_empty } - specify{ expect(input_species1.reported_shipments).to include(@shipment) } - specify{ expect(output_species.shipments).to include(@shipment) } + before(:each) { processor.run } + specify { expect(input_species1.reload).to be_is_synonym } + specify { expect(input_species1.accepted_names).to include(output_species) } + specify { expect(input_species1.shipments).to be_empty } + specify { expect(input_species1.reported_shipments).to include(@shipment) } + specify { expect(output_species.shipments).to include(@shipment) } end end context "when output is new taxon" do - let!(:lump){ lump_with_inputs_and_output_new_taxon } - specify { expect{ processor.run }.to change(TaxonConcept, :count).by(1) } + let!(:lump) { lump_with_inputs_and_output_new_taxon } + specify { expect { processor.run }.to change(TaxonConcept, :count).by(1) } context "relationships and trade" do - before(:each){ processor.run } - specify{ expect(input_species1.reload).to be_is_synonym } - specify{ expect(input_species1.accepted_names).to include(lump.output.new_taxon_concept) } - specify{ expect(lump.output.new_taxon_concept.shipments).to include(@shipment) } + before(:each) { processor.run } + specify { expect(input_species1.reload).to be_is_synonym } + specify { expect(input_species1.accepted_names).to include(lump.output.new_taxon_concept) } + specify { expect(lump.output.new_taxon_concept.shipments).to include(@shipment) } end end context "when output is existing taxon with new status" do - let(:output_species2){ create_cites_eu_species(:name_status => 'S') } - let!(:lump){ lump_with_inputs_and_output_status_change } - specify { expect{ processor.run }.not_to change(TaxonConcept, :count) } - specify { expect{ processor.run }.not_to change(output_species, :full_name) } + let(:output_species2) { create_cites_eu_species(:name_status => 'S') } + let!(:lump) { lump_with_inputs_and_output_status_change } + specify { expect { processor.run }.not_to change(TaxonConcept, :count) } + specify { expect { processor.run }.not_to change(output_species, :full_name) } context "relationships and trade" do - before(:each){ processor.run } - specify{ expect(input_species1.reload).to be_is_synonym } - specify{ expect(input_species1.accepted_names).to include(output_species) } - specify{ expect(output_species.shipments).to include(@shipment) } + before(:each) { processor.run } + specify { expect(input_species1.reload).to be_is_synonym } + specify { expect(input_species1.accepted_names).to include(output_species) } + specify { expect(output_species.shipments).to include(@shipment) } end end context "when output is existing taxon with new name" do - let(:input_genus1){ create_cites_eu_genus } - let(:input_species1){ create_cites_eu_species(parent: input_genus1) } - let(:output_species2){ create_cites_eu_subspecies } - let!(:lump){ lump_with_inputs_and_output_name_change } - specify { expect{ processor.run }.to change(TaxonConcept, :count).by(1) } - specify { expect{ processor.run }.not_to change(output_species, :full_name) } + let(:input_genus1) { create_cites_eu_genus } + let(:input_species1) { create_cites_eu_species(parent: input_genus1) } + let(:output_species2) { create_cites_eu_subspecies } + let!(:lump) { lump_with_inputs_and_output_name_change } + specify { expect { processor.run }.to change(TaxonConcept, :count).by(1) } + specify { expect { processor.run }.not_to change(output_species, :full_name) } context "relationships and trade" do - before(:each){ processor.run } - specify{ expect(input_species1.reload).to be_is_synonym } - specify{ expect(input_species1.reload.parent).to eq(input_genus1) } - specify{ expect(input_species1.accepted_names).to include(lump.output.new_taxon_concept) } - specify{ expect(lump.output.new_taxon_concept.shipments).to include(@shipment) } + before(:each) { processor.run } + specify { expect(input_species1.reload).to be_is_synonym } + specify { expect(input_species1.reload.parent).to eq(input_genus1) } + specify { expect(input_species1.accepted_names).to include(lump.output.new_taxon_concept) } + specify { expect(lump.output.new_taxon_concept.shipments).to include(@shipment) } end end context "when input with children that don't change name" do - let!(:input_species1_child){ + let!(:input_species1_child) { create_cites_eu_subspecies(parent: input_species1) } - let!(:input_species1_child_listing){ + let!(:input_species1_child_listing) { create_cites_I_addition(taxon_concept: input_species1_child) } - let(:lump){ + let(:lump) { create(:nomenclature_change_lump, inputs_attributes: { 0 => { @@ -90,7 +90,7 @@ status: NomenclatureChange::Lump::LEGISLATION ) } - before(:each){ processor.run } + before(:each) { processor.run } specify "input / output species has public nomenclature note set" do expect(input_species1.reload.nomenclature_note_en).to eq(' input species 1 was lumped from input species 1 and input species 2') end @@ -115,16 +115,16 @@ end context "when input with children that change name" do - let!(:input_species1_child){ + let!(:input_species1_child) { create_cites_eu_subspecies(parent: input_species1) } - let!(:input_species1_child_listing){ + let!(:input_species1_child_listing) { create_cites_I_addition(taxon_concept: input_species1_child) } - let!(:output_species_child){ + let!(:output_species_child) { create_cites_eu_subspecies(parent: output_species) } - let(:lump){ + let(:lump) { create(:nomenclature_change_lump, inputs_attributes: { 0 => { @@ -142,25 +142,25 @@ status: NomenclatureChange::Lump::LEGISLATION ) } - let(:input){ lump.inputs.first } - let(:output){ lump.output } - let(:reassignment){ + let(:input) { lump.inputs.first } + let(:output) { lump.output } + let(:reassignment) { create(:nomenclature_change_parent_reassignment, input: input, reassignable_id: input_species1_child.id ) } - let!(:reassignment_target){ + let!(:reassignment_target) { create(:nomenclature_change_reassignment_target, reassignment: reassignment, output: output ) } - let(:output_species_children){ output_species.children } - let(:output_species1_child){ + let(:output_species_children) { output_species.children } + let(:output_species1_child) { output_species_children.where('id != ?', output_species_child.id).first } - before(:each){ processor.run } + before(:each) { processor.run } specify "input species has public nomenclature note set" do expect(input_species1.reload.nomenclature_note_en).to eq(' input species 1 has been lumped into output species') end @@ -201,7 +201,7 @@ output_species1_child.listing_changes.first.nomenclature_note_en ).to eq(input_species1.reload.nomenclature_note_en) end - let(:output_species_genus_name){ output_species.parent.full_name } + let(:output_species_genus_name) { output_species.parent.full_name } specify "original output species child retains higher taxa intact" do expect(output_species_child.data['genus_name']).to eq(output_species_genus_name) end @@ -234,13 +234,13 @@ taxon_name: create(:taxon_name, scientific_name: 'unicolor') ) end - let!(:quota){ create(:quota, taxon_concept: input_genus_child, geo_entity: create(:geo_entity)) } + let!(:quota) { create(:quota, taxon_concept: input_genus_child, geo_entity: create(:geo_entity)) } let(:output_genus) do create_cites_eu_genus( taxon_name: create(:taxon_name, scientific_name: 'Paracrotalus') ) end - let(:lump){ + let(:lump) { create(:nomenclature_change_lump, inputs_attributes: { 0 => { taxon_concept_id: input_genus.id }, @@ -250,19 +250,19 @@ status: NomenclatureChange::Lump::LEGISLATION ) } - let(:reassignment){ + let(:reassignment) { create(:nomenclature_change_parent_reassignment, input: lump.inputs.first, reassignable_id: input_genus_child.id ) } - let!(:reassignment_target){ + let!(:reassignment_target) { create(:nomenclature_change_reassignment_target, reassignment: reassignment, output: lump.output ) } - before(:each){ processor.run } + before(:each) { processor.run } specify "input genus child is a synonym" do expect(input_genus_child.reload.name_status).to eq('S') end @@ -296,7 +296,7 @@ end end describe :summary do - let(:lump){ lump_with_inputs_and_output_existing_taxon } + let(:lump) { lump_with_inputs_and_output_existing_taxon } specify { expect(processor.summary).to be_kind_of(Array) } end end diff --git a/spec/models/nomenclature_change/lump_spec.rb b/spec/models/nomenclature_change/lump_spec.rb index 3af9748621..7f15942a8e 100644 --- a/spec/models/nomenclature_change/lump_spec.rb +++ b/spec/models/nomenclature_change/lump_spec.rb @@ -18,7 +18,7 @@ describe :validate do context "when required inputs missing" do context "when inputs" do - let(:lump){ + let(:lump) { build( :nomenclature_change_lump, :status => NomenclatureChange::Lump::INPUTS ) @@ -26,7 +26,7 @@ specify { expect(lump).to have(1).errors_on(:inputs) } end context "when submitting" do - let(:lump){ + let(:lump) { build( :nomenclature_change_lump, :status => NomenclatureChange::Lump::SUBMITTED ) @@ -36,7 +36,7 @@ end context "when required outputs missing" do context "when outputs" do - let(:lump){ + let(:lump) { build( :nomenclature_change_lump, :status => NomenclatureChange::Lump::OUTPUTS ) @@ -44,7 +44,7 @@ specify { expect(lump).to have(1).errors_on(:output) } end context "when submitting" do - let(:lump){ + let(:lump) { build( :nomenclature_change_lump, :status => NomenclatureChange::Lump::SUBMITTED ) @@ -52,7 +52,7 @@ specify { expect(lump).to have(1).errors_on(:output) } end context "when only 1 input" do - let(:lump){ + let(:lump) { build( :nomenclature_change_lump, :status => NomenclatureChange::Lump::SUBMITTED, :inputs_attributes => { 0 => { :taxon_concept_id => create_cites_eu_subspecies.id } } @@ -63,7 +63,7 @@ end end describe :new_output_rank do - let(:lump){ + let(:lump) { build( :nomenclature_change_lump, inputs_attributes: { @@ -73,6 +73,6 @@ status: NomenclatureChange::Lump::INPUTS ) } - specify{ expect(lump.new_output_rank.name).to eq(Rank::SPECIES) } + specify { expect(lump.new_output_rank.name).to eq(Rank::SPECIES) } end end diff --git a/spec/models/nomenclature_change/output_reassignment_spec.rb b/spec/models/nomenclature_change/output_reassignment_spec.rb index 25b08a985a..40329c4d27 100644 --- a/spec/models/nomenclature_change/output_reassignment_spec.rb +++ b/spec/models/nomenclature_change/output_reassignment_spec.rb @@ -22,7 +22,7 @@ describe NomenclatureChange::OutputReassignment do describe :validate do context "when output not specified" do - let(:reassignment){ + let(:reassignment) { build( :nomenclature_change_output_reassignment, :nomenclature_change_output_id => nil @@ -31,7 +31,7 @@ specify { expect(reassignment).not_to be_valid } end context "when reassignable_type not specified" do - let(:reassignment){ + let(:reassignment) { build( :nomenclature_change_output_reassignment, :reassignable_type => nil ) diff --git a/spec/models/nomenclature_change/output_spec.rb b/spec/models/nomenclature_change/output_spec.rb index 486f875b20..62831282cc 100644 --- a/spec/models/nomenclature_change/output_spec.rb +++ b/spec/models/nomenclature_change/output_spec.rb @@ -32,16 +32,16 @@ require 'spec_helper' describe NomenclatureChange::Output do - before(:each){ cites_eu } + before(:each) { cites_eu } describe :validate do context "when nomenclature change not specified" do - let(:output){ + let(:output) { build(:nomenclature_change_output, :nomenclature_change_id => nil) } specify { expect(output).not_to be_valid } end context "when taxon concept not specified and new taxon concept attributes not specified" do - let(:output){ + let(:output) { build( :nomenclature_change_output, :taxon_concept_id => nil, :new_scientific_name => nil, @@ -56,7 +56,7 @@ specify { expect(output).to have(1).errors_on(:new_name_status) } end context "when new taxon concept invalid" do - let(:output){ + let(:output) { build( :nomenclature_change_output, :taxon_concept_id => nil, :new_scientific_name => 'xxx', @@ -68,69 +68,69 @@ specify { expect(output).to have(1).error_on(:new_parent_id) } end context "when taxon concept specified" do - let(:tc){ create_cites_eu_species } - let(:output){ + let(:tc) { create_cites_eu_species } + let(:output) { create(:nomenclature_change_output, :taxon_concept_id => tc.id) } - specify{ expect(output.parent_id).to eq(tc.parent_id) } - specify{ expect(output.rank_id).to eq(tc.rank_id) } - specify{ expect(output.scientific_name).to eq(tc.full_name) } - specify{ expect(output.author_year).to eq(tc.author_year) } - specify{ expect(output.name_status).to eq(tc.name_status) } + specify { expect(output.parent_id).to eq(tc.parent_id) } + specify { expect(output.rank_id).to eq(tc.rank_id) } + specify { expect(output.scientific_name).to eq(tc.full_name) } + specify { expect(output.author_year).to eq(tc.author_year) } + specify { expect(output.name_status).to eq(tc.name_status) } end end describe :expected_parent_name do - let(:output){ + let(:output) { create(:nomenclature_change_output, :taxon_concept_id => tc.id) } - let(:canis_genus){ + let(:canis_genus) { create_cites_eu_genus( taxon_name: create(:taxon_name, scientific_name: 'Canis') ) } - let(:canis_species){ + let(:canis_species) { create_cites_eu_species( taxon_name: create(:taxon_name, scientific_name: 'lupus'), parent: canis_genus ) } - let(:canis_subspecies){ + let(:canis_subspecies) { create_cites_eu_subspecies( taxon_name: create(:taxon_name, scientific_name: 'dingo'), parent: canis_species ) } - let(:magnolia_genus){ + let(:magnolia_genus) { create_cites_eu_genus( taxon_name: create(:taxon_name, scientific_name: 'Magnolia') ) } - let(:magnolia_species){ + let(:magnolia_species) { create_cites_eu_species( taxon_name: create(:taxon_name, scientific_name: 'liliifera'), parent: magnolia_genus ) } - let(:magnolia_variety){ + let(:magnolia_variety) { create_cites_eu_variety( taxon_name: create(:taxon_name, scientific_name: 'var. obovata'), parent: magnolia_species ) } context "when genus" do - let(:tc){ canis_genus } + let(:tc) { canis_genus } specify { expect(output.expected_parent_name).to be_nil } end context "when species" do - let(:tc){ canis_species } + let(:tc) { canis_species } specify { expect(output.expected_parent_name).to eq('Canis') } end context "when subspecies" do - let(:tc){ canis_subspecies } + let(:tc) { canis_subspecies } specify { expect(output.expected_parent_name).to eq('Canis lupus') } end context "when variety" do - let(:tc){ magnolia_variety } + let(:tc) { magnolia_variety } specify { expect(output.expected_parent_name).to eq('Magnolia liliifera') } end end diff --git a/spec/models/nomenclature_change/reassignment_copy_processor_spec.rb b/spec/models/nomenclature_change/reassignment_copy_processor_spec.rb index d09a9c16d2..dfdcfffe5e 100644 --- a/spec/models/nomenclature_change/reassignment_copy_processor_spec.rb +++ b/spec/models/nomenclature_change/reassignment_copy_processor_spec.rb @@ -3,10 +3,10 @@ describe NomenclatureChange::ReassignmentCopyProcessor do include_context 'split_definitions' describe :run do - let(:split){ split_with_input_and_same_output } - let(:input){ split.input } - let(:output){ split.outputs.first } - let(:processor){ + let(:split) { split_with_input_and_same_output } + let(:input) { split.input } + let(:output) { split.outputs.first } + let(:processor) { NomenclatureChange::ReassignmentCopyProcessor.new(input, output) } @@ -15,25 +15,25 @@ end context "when names" do include_context 'name_reassignments_processor_examples' - specify{ expect(input_species.synonyms).to include(input_species_synonym) } + specify { expect(input_species.synonyms).to include(input_species_synonym) } end context "when distribution" do include_context 'distribution_reassignments_processor_examples' - specify{ expect(input_species.distributions.count).to eq(4) } + specify { expect(input_species.distributions.count).to eq(4) } end context "when legislation" do include_context 'legislation_reassignments_processor_examples' - specify{ expect(input_species.listing_changes.count).to eq(2) } - specify{ expect(input_species.quotas.count).to eq(2) } - specify{ expect(input_species.cites_suspensions.count).to eq(2) } + specify { expect(input_species.listing_changes.count).to eq(2) } + specify { expect(input_species.quotas.count).to eq(2) } + specify { expect(input_species.cites_suspensions.count).to eq(2) } end context "when common names" do include_context 'common_name_reassignments_processor_examples' - specify{ expect(input_species.common_names.count).to eq(2) } + specify { expect(input_species.common_names.count).to eq(2) } end context "when references" do include_context 'reference_reassignments_processor_examples' - specify{ expect(input_species.taxon_concept_references.count).to eq(2) } + specify { expect(input_species.taxon_concept_references.count).to eq(2) } end context "when shipments" do include_context 'shipment_reassignments_processor_examples' diff --git a/spec/models/nomenclature_change/reassignment_spec.rb b/spec/models/nomenclature_change/reassignment_spec.rb index 187d3922fb..d7414d4c98 100644 --- a/spec/models/nomenclature_change/reassignment_spec.rb +++ b/spec/models/nomenclature_change/reassignment_spec.rb @@ -22,7 +22,7 @@ describe NomenclatureChange::Reassignment do describe :validate do context "when input not specified" do - let(:reassignment){ + let(:reassignment) { build( :nomenclature_change_reassignment, :nomenclature_change_input_id => nil @@ -31,7 +31,7 @@ specify { expect(reassignment).not_to be_valid } end context "when reassignable_type not specified" do - let(:reassignment){ + let(:reassignment) { build( :nomenclature_change_reassignment, :reassignable_type => nil ) diff --git a/spec/models/nomenclature_change/reassignment_target_spec.rb b/spec/models/nomenclature_change/reassignment_target_spec.rb index a7e3b63421..13f45c1009 100644 --- a/spec/models/nomenclature_change/reassignment_target_spec.rb +++ b/spec/models/nomenclature_change/reassignment_target_spec.rb @@ -16,7 +16,7 @@ describe NomenclatureChange::ReassignmentTarget do describe :validate do context "when reassignment not specified" do - let(:reassignment_target){ + let(:reassignment_target) { build( :nomenclature_change_reassignment_target, :nomenclature_change_reassignment_id => nil @@ -25,7 +25,7 @@ specify { expect(reassignment_target).not_to be_valid } end context "when output not specified" do - let(:reassignment_target){ + let(:reassignment_target) { build( :nomenclature_change_reassignment_target, :nomenclature_change_output_id => nil diff --git a/spec/models/nomenclature_change/reassignment_transfer_processor_spec.rb b/spec/models/nomenclature_change/reassignment_transfer_processor_spec.rb index 98c889687b..e0687b6162 100644 --- a/spec/models/nomenclature_change/reassignment_transfer_processor_spec.rb +++ b/spec/models/nomenclature_change/reassignment_transfer_processor_spec.rb @@ -4,10 +4,10 @@ include_context 'split_definitions' describe :run do context "input reassignments" do - let(:split){ split_with_input_and_output } - let(:input){ split.input } - let(:output){ split.outputs.first } - let(:processor){ + let(:split) { split_with_input_and_output } + let(:input) { split.input } + let(:output) { split.outputs.first } + let(:processor) { NomenclatureChange::ReassignmentTransferProcessor.new(input, output) } context "when children" do @@ -15,25 +15,25 @@ end context "when names" do include_context 'name_reassignments_processor_examples' - specify{ expect(input_species.synonyms).to be_empty } + specify { expect(input_species.synonyms).to be_empty } end context "when distribution" do include_context 'distribution_reassignments_processor_examples' - specify{ expect(input_species.distributions).to be_empty } + specify { expect(input_species.distributions).to be_empty } end context "when legislation" do include_context 'legislation_reassignments_processor_examples' - specify{ expect(input_species.listing_changes).to be_empty } - specify{ expect(input_species.quotas).to be_empty } - specify{ expect(input_species.cites_suspensions).to be_empty } + specify { expect(input_species.listing_changes).to be_empty } + specify { expect(input_species.quotas).to be_empty } + specify { expect(input_species.cites_suspensions).to be_empty } end context "when common names" do include_context 'common_name_reassignments_processor_examples' - specify{ expect(input_species.common_names).to be_empty } + specify { expect(input_species.common_names).to be_empty } end context "when references" do include_context 'reference_reassignments_processor_examples' - specify{ expect(input_species.taxon_concept_references).to be_empty } + specify { expect(input_species.taxon_concept_references).to be_empty } end context "when shipments" do include_context 'shipment_reassignments_processor_examples' @@ -41,14 +41,14 @@ end context "output reassignments" do - let(:split){ split_with_input_and_outputs_name_change } - let(:output){ split.outputs.last } - let(:old_output_subspecies){ output.taxon_concept } - let(:new_output_species){ output.new_taxon_concept } - let(:output_processor){ + let(:split) { split_with_input_and_outputs_name_change } + let(:output) { split.outputs.last } + let(:old_output_subspecies) { output.taxon_concept } + let(:new_output_species) { output.new_taxon_concept } + let(:output_processor) { NomenclatureChange::OutputTaxonConceptProcessor.new(output) } - let(:processor){ + let(:processor) { NomenclatureChange::ReassignmentTransferProcessor.new(output, output) } context "when names" do diff --git a/spec/models/nomenclature_change/shared/common_name_reassignments_constructor_examples.rb b/spec/models/nomenclature_change/shared/common_name_reassignments_constructor_examples.rb index f7ada634dd..0a3ffaeeaf 100644 --- a/spec/models/nomenclature_change/shared/common_name_reassignments_constructor_examples.rb +++ b/spec/models/nomenclature_change/shared/common_name_reassignments_constructor_examples.rb @@ -1,23 +1,23 @@ shared_context 'common_name_reassignments_constructor_examples' do context "when previously no reassignments in place" do context "when no common names" do - specify{ expect(input.reassignments.size).to eq(0) } + specify { expect(input.reassignments.size).to eq(0) } end context "when common names" do - let(:input_species){ + let(:input_species) { s = create_cites_eu_species - 2.times{ create(:taxon_common, taxon_concept: s) } + 2.times { create(:taxon_common, taxon_concept: s) } s } - specify{ expect(input.reassignments.size).to eq(1) } + specify { expect(input.reassignments.size).to eq(1) } end end context "when previously reassignments in place" do - let(:input){ + let(:input) { i = create(:nomenclature_change_input, nomenclature_change: nc, taxon_concept: input_species) create(:nomenclature_change_reassignment, input: i) i } - specify{ expect(input.reassignments).to eq(@old_reassignments) } + specify { expect(input.reassignments).to eq(@old_reassignments) } end end diff --git a/spec/models/nomenclature_change/shared/common_name_reassignments_processor_examples.rb b/spec/models/nomenclature_change/shared/common_name_reassignments_processor_examples.rb index 0385bec1ff..0381877125 100644 --- a/spec/models/nomenclature_change/shared/common_name_reassignments_processor_examples.rb +++ b/spec/models/nomenclature_change/shared/common_name_reassignments_processor_examples.rb @@ -1,19 +1,19 @@ shared_context 'common_name_reassignments_processor_examples' do - let(:reassignment){ + let(:reassignment) { create(:nomenclature_change_reassignment, input: input, reassignable_type: 'TaxonCommon' ) } - let!(:reassignment_target){ + let!(:reassignment_target) { create(:nomenclature_change_reassignment_target, reassignment: reassignment, output: output ) } before(:each) do - 2.times{ create(:taxon_common, taxon_concept: input_species) } + 2.times { create(:taxon_common, taxon_concept: input_species) } processor.run end - specify{ expect(output_species1.common_names.count).to eq(2) } + specify { expect(output_species1.common_names.count).to eq(2) } end diff --git a/spec/models/nomenclature_change/shared/distribution_reassignments_constructor_examples.rb b/spec/models/nomenclature_change/shared/distribution_reassignments_constructor_examples.rb index 640699701c..90d110659b 100644 --- a/spec/models/nomenclature_change/shared/distribution_reassignments_constructor_examples.rb +++ b/spec/models/nomenclature_change/shared/distribution_reassignments_constructor_examples.rb @@ -1,23 +1,23 @@ shared_context 'distribution_reassignments_constructor_examples' do context "when previously no reassignments in place" do context "when no distibutions" do - specify{ expect(input.distribution_reassignments.size).to eq(0) } + specify { expect(input.distribution_reassignments.size).to eq(0) } end context "when distributions" do - let(:input_species){ + let(:input_species) { s = create_cites_eu_species - 2.times{ create(:distribution, taxon_concept: s) } + 2.times { create(:distribution, taxon_concept: s) } s } - specify{ expect(input.distribution_reassignments.size).to eq(2) } + specify { expect(input.distribution_reassignments.size).to eq(2) } end end context "when previously reassignments in place" do - let(:input){ + let(:input) { i = create(:nomenclature_change_input, nomenclature_change: nc, taxon_concept: input_species) create(:nomenclature_change_distribution_reassignment, input: i) i } - specify{ expect(input.distribution_reassignments).to eq(@old_reassignments) } + specify { expect(input.distribution_reassignments).to eq(@old_reassignments) } end end \ No newline at end of file diff --git a/spec/models/nomenclature_change/shared/distribution_reassignments_processor_examples.rb b/spec/models/nomenclature_change/shared/distribution_reassignments_processor_examples.rb index 9c25f9afcf..30215e5d55 100644 --- a/spec/models/nomenclature_change/shared/distribution_reassignments_processor_examples.rb +++ b/spec/models/nomenclature_change/shared/distribution_reassignments_processor_examples.rb @@ -1,31 +1,31 @@ shared_context 'distribution_reassignments_processor_examples' do - let(:reassignment){ + let(:reassignment) { create(:nomenclature_change_distribution_reassignment, input: input, reassignable_type: 'Distribution' ) } - let!(:reassignment_target){ + let!(:reassignment_target) { create(:nomenclature_change_reassignment_target, reassignment: reassignment, output: output ) } - let(:poland){ + let(:poland) { create( :geo_entity, geo_entity_type_id: country_geo_entity_type.id, iso_code2: 'PL' ) } - let(:italy){ + let(:italy) { create( :geo_entity, geo_entity_type_id: country_geo_entity_type.id, iso_code2: 'IT' ) } - let(:united_kingdom){ + let(:united_kingdom) { create( :geo_entity, geo_entity_type_id: country_geo_entity_type.id, @@ -73,10 +73,10 @@ create(:distribution, taxon_concept: input_species) processor.run end - specify{ expect(output_species1.distributions.count).to eq(4) } - specify{ expect(output_species1.distributions.find_by_geo_entity_id(poland.id)).not_to be_nil } - specify{ expect(output_species1.distributions.find_by_geo_entity_id(poland.id).tag_list).to eq([]) } - specify{ expect(output_species1.distributions.find_by_geo_entity_id(italy.id).tag_list).to match_array(['extinct', 'reintroduced']) } - specify{ expect(output_species1.distributions.find_by_geo_entity_id(united_kingdom.id).tag_list).to eq([]) } - specify{ expect(output_species1.distributions.find_by_geo_entity_id(poland.id).distribution_references.count).to eq(2) } + specify { expect(output_species1.distributions.count).to eq(4) } + specify { expect(output_species1.distributions.find_by_geo_entity_id(poland.id)).not_to be_nil } + specify { expect(output_species1.distributions.find_by_geo_entity_id(poland.id).tag_list).to eq([]) } + specify { expect(output_species1.distributions.find_by_geo_entity_id(italy.id).tag_list).to match_array(['extinct', 'reintroduced']) } + specify { expect(output_species1.distributions.find_by_geo_entity_id(united_kingdom.id).tag_list).to eq([]) } + specify { expect(output_species1.distributions.find_by_geo_entity_id(poland.id).distribution_references.count).to eq(2) } end diff --git a/spec/models/nomenclature_change/shared/legislation_reassignments_constructor_examples.rb b/spec/models/nomenclature_change/shared/legislation_reassignments_constructor_examples.rb index ca480066a2..ec84768515 100644 --- a/spec/models/nomenclature_change/shared/legislation_reassignments_constructor_examples.rb +++ b/spec/models/nomenclature_change/shared/legislation_reassignments_constructor_examples.rb @@ -1,24 +1,24 @@ shared_context 'legislation_reassignments_constructor_examples' do context "when previously no reassignments in place" do context "when no CITES listings" do - specify{ expect(input.legislation_reassignments.size).to eq(0) } + specify { expect(input.legislation_reassignments.size).to eq(0) } end context "when CITES listings" do - let(:input_species){ + let(:input_species) { s = create_cites_eu_species create_cites_I_addition(taxon_concept: s) create_cites_II_addition(taxon_concept: s) s } - specify{ expect(input.legislation_reassignments.size).to eq(1) } + specify { expect(input.legislation_reassignments.size).to eq(1) } end end context "when previously reassignments in place" do - let(:input){ + let(:input) { i = create(:nomenclature_change_input, nomenclature_change: nc, taxon_concept: input_species) create(:nomenclature_change_legislation_reassignment, input: i) i } - specify{ expect(input.legislation_reassignments).to eq(@old_reassignments) } + specify { expect(input.legislation_reassignments).to eq(@old_reassignments) } end end diff --git a/spec/models/nomenclature_change/shared/legislation_reassignments_processor_examples.rb b/spec/models/nomenclature_change/shared/legislation_reassignments_processor_examples.rb index 4cbad93acc..9ac715d0fa 100644 --- a/spec/models/nomenclature_change/shared/legislation_reassignments_processor_examples.rb +++ b/spec/models/nomenclature_change/shared/legislation_reassignments_processor_examples.rb @@ -1,12 +1,12 @@ shared_context 'legislation_reassignments_processor_examples' do - let(:poland){ + let(:poland) { create( :geo_entity, geo_entity_type_id: country_geo_entity_type.id, iso_code2: 'PL' ) } - let(:portugal){ + let(:portugal) { create( :geo_entity, geo_entity_type_id: country_geo_entity_type.id, @@ -70,7 +70,7 @@ quota.purposes << create(:purpose) quota = create(:quota, taxon_concept: input_species, geo_entity: portugal) - 2.times{ create(:cites_suspension, taxon_concept: input_species) } + 2.times { create(:cites_suspension, taxon_concept: input_species) } create(:nomenclature_change_reassignment_target, reassignment: create( @@ -98,81 +98,81 @@ ) processor.run end - specify{ expect(output_species1.listing_changes.count).to eq(2) } - specify{ + specify { expect(output_species1.listing_changes.count).to eq(2) } + specify { expect( output_species1.listing_changes. find_by_effective_at_and_change_type_id('2013-01-01', cites_addition.id) ).not_to be_nil } - specify{ + specify { expect( output_species1.listing_changes. find_by_effective_at_and_change_type_id('2013-01-01', cites_addition.id). party_listing_distribution.geo_entity ).to eq(poland) } - specify{ + specify { expect( output_species1.listing_changes. find_by_effective_at_and_change_type_id('2013-01-01', cites_addition.id). listing_distributions.count ).to eq(2) } - specify{ + specify { expect( output_species1.listing_changes. find_by_effective_at_and_change_type_id('2013-01-01', cites_addition.id). annotation ).not_to be_nil } - specify{ + specify { expect( output_species1.listing_changes. find_by_effective_at_and_change_type_id('2013-01-01', cites_addition.id). exclusions ).not_to be_empty } - specify{ + specify { expect( output_species1.listing_changes. find_by_effective_at_and_change_type_id('2013-01-02', cites_addition.id) ).not_to be_nil } - specify{ + specify { expect( output_species1.listing_changes. find_by_effective_at_and_change_type_id('2013-01-02', cites_addition.id). party_listing_distribution.geo_entity ).to eq(portugal) } - specify{ expect(output_species1.quotas.count).to eq(2) } - specify{ + specify { expect(output_species1.quotas.count).to eq(2) } + specify { expect( output_species1.quotas. find_by_geo_entity_id(poland.id) ).not_to be_nil } - specify{ + specify { expect( output_species1.quotas. find_by_geo_entity_id(poland.id). terms ).not_to be_empty } - specify{ + specify { expect( output_species1.quotas. find_by_geo_entity_id(poland.id). sources ).not_to be_empty } - specify{ + specify { expect( output_species1.quotas. find_by_geo_entity_id(poland.id). purposes ).not_to be_empty } - specify{ expect(output_species1.cites_suspensions.count).to eq(2) } + specify { expect(output_species1.cites_suspensions.count).to eq(2) } end diff --git a/spec/models/nomenclature_change/shared/lump_definitions.rb b/spec/models/nomenclature_change/shared/lump_definitions.rb index 0ea067cb87..45bed53bef 100644 --- a/spec/models/nomenclature_change/shared/lump_definitions.rb +++ b/spec/models/nomenclature_change/shared/lump_definitions.rb @@ -1,14 +1,14 @@ shared_context 'lump_definitions' do - let(:input_species){ create_cites_eu_species } - let(:input_species1){ input_species } - let(:input_species2){ create_cites_eu_species } - let(:output_species){ create_cites_eu_species } - let(:errorus_genus){ + let(:input_species) { create_cites_eu_species } + let(:input_species1) { input_species } + let(:input_species2) { create_cites_eu_species } + let(:output_species) { create_cites_eu_species } + let(:errorus_genus) { create_cites_eu_genus( taxon_name: create(:taxon_name, scientific_name: 'Errorus') ) } - let(:output_subspecies){ + let(:output_subspecies) { create_cites_eu_subspecies( taxon_name: create(:taxon_name, scientific_name: 'fatalus'), parent: create_cites_eu_species( @@ -17,7 +17,7 @@ ) ) } - let(:lump_with_inputs){ + let(:lump_with_inputs) { create(:nomenclature_change_lump, inputs_attributes: { 0 => { taxon_concept_id: input_species1.id }, @@ -25,10 +25,10 @@ } ) } - let(:lump_with_inputs_and_output){ + let(:lump_with_inputs_and_output) { lump_with_inputs_and_output_existing_taxon } - let(:lump_with_inputs_and_same_output){ + let(:lump_with_inputs_and_same_output) { create(:nomenclature_change_lump, inputs_attributes: { 0 => { taxon_concept_id: input_species1.id }, @@ -40,7 +40,7 @@ status: NomenclatureChange::Lump::OUTPUTS ) } - let(:lump_with_inputs_and_output_existing_taxon){ + let(:lump_with_inputs_and_output_existing_taxon) { create(:nomenclature_change_lump, inputs_attributes: { 0 => { taxon_concept_id: input_species1.id }, @@ -52,7 +52,7 @@ status: NomenclatureChange::Lump::OUTPUTS ) } - let(:lump_with_inputs_and_output_new_taxon){ + let(:lump_with_inputs_and_output_new_taxon) { create(:nomenclature_change_lump, inputs_attributes: { 0 => { taxon_concept_id: input_species1.id }, @@ -66,7 +66,7 @@ status: NomenclatureChange::Lump::OUTPUTS ) } - let(:lump_with_inputs_and_output_status_change){ + let(:lump_with_inputs_and_output_status_change) { create(:nomenclature_change_lump, inputs_attributes: { 0 => { taxon_concept_id: input_species1.id }, @@ -78,7 +78,7 @@ status: NomenclatureChange::Lump::OUTPUTS ) } - let(:lump_with_inputs_and_output_name_change){ + let(:lump_with_inputs_and_output_name_change) { create(:nomenclature_change_lump, inputs_attributes: { 0 => { taxon_concept_id: input_species1.id }, diff --git a/spec/models/nomenclature_change/shared/name_reassignments_constructor_examples.rb b/spec/models/nomenclature_change/shared/name_reassignments_constructor_examples.rb index 75e8d07b5d..554dbd7c71 100644 --- a/spec/models/nomenclature_change/shared/name_reassignments_constructor_examples.rb +++ b/spec/models/nomenclature_change/shared/name_reassignments_constructor_examples.rb @@ -1,10 +1,10 @@ shared_context 'name_reassignments_constructor_examples' do context "when previously no reassignments in place" do context "when no names" do - specify{ expect(input.name_reassignments.size).to eq(0) } + specify { expect(input.name_reassignments.size).to eq(0) } end context "when names" do - let(:input_species){ + let(:input_species) { s = create_cites_eu_species 2.times do create(:taxon_relationship, @@ -15,15 +15,15 @@ end s } - specify{ expect(input.name_reassignments.size).to eq(2) } + specify { expect(input.name_reassignments.size).to eq(2) } end end context "when previously reassignments in place" do - let(:input){ + let(:input) { i = create(:nomenclature_change_input, nomenclature_change: nc, taxon_concept: input_species) create(:nomenclature_change_name_reassignment, input: i) i } - specify{ expect(input.name_reassignments).to eq(@old_reassignments) } + specify { expect(input.name_reassignments).to eq(@old_reassignments) } end end \ No newline at end of file diff --git a/spec/models/nomenclature_change/shared/name_reassignments_processor_examples.rb b/spec/models/nomenclature_change/shared/name_reassignments_processor_examples.rb index ee9521666e..477e717c21 100644 --- a/spec/models/nomenclature_change/shared/name_reassignments_processor_examples.rb +++ b/spec/models/nomenclature_change/shared/name_reassignments_processor_examples.rb @@ -1,21 +1,21 @@ shared_context 'name_reassignments_processor_examples' do - let(:input_species_synonym){ + let(:input_species_synonym) { create_cites_eu_species(name_status: 'S') } - let(:input_species_synonym_rel){ + let(:input_species_synonym_rel) { create(:taxon_relationship, taxon_relationship_type_id: synonym_relationship_type.id, taxon_concept: input_species, other_taxon_concept: input_species_synonym ) } - let(:reassignment){ + let(:reassignment) { create(:nomenclature_change_name_reassignment, input: input, reassignable_id: input_species_synonym_rel.id ) } - let!(:reassignment_target){ + let!(:reassignment_target) { create(:nomenclature_change_reassignment_target, reassignment: reassignment, output: output @@ -24,5 +24,5 @@ before(:each) do processor.run end - specify{ expect(output_species1.synonyms).to include(input_species_synonym) } + specify { expect(output_species1.synonyms).to include(input_species_synonym) } end diff --git a/spec/models/nomenclature_change/shared/output_common_names_reassignments_processor_examples.rb b/spec/models/nomenclature_change/shared/output_common_names_reassignments_processor_examples.rb index f45f015fc8..c92b759c16 100644 --- a/spec/models/nomenclature_change/shared/output_common_names_reassignments_processor_examples.rb +++ b/spec/models/nomenclature_change/shared/output_common_names_reassignments_processor_examples.rb @@ -4,10 +4,10 @@ output: output, reassignable_type: 'TaxonCommon' ) - 2.times{ create(:taxon_common, taxon_concept: old_output_subspecies) } + 2.times { create(:taxon_common, taxon_concept: old_output_subspecies) } output_processor.run processor.run end - specify{ expect(new_output_species.common_names.count).to eq(2) } - specify{ expect(old_output_subspecies.common_names).to be_empty } + specify { expect(new_output_species.common_names.count).to eq(2) } + specify { expect(old_output_subspecies.common_names).to be_empty } end diff --git a/spec/models/nomenclature_change/shared/output_distribution_reassignments_processor_examples.rb b/spec/models/nomenclature_change/shared/output_distribution_reassignments_processor_examples.rb index dcad86c834..a627f2dc1e 100644 --- a/spec/models/nomenclature_change/shared/output_distribution_reassignments_processor_examples.rb +++ b/spec/models/nomenclature_change/shared/output_distribution_reassignments_processor_examples.rb @@ -1,5 +1,5 @@ shared_context 'output_distribution_reassignments_processor_examples' do - let(:poland){ + let(:poland) { create( :geo_entity, geo_entity_type_id: country_geo_entity_type.id, @@ -23,9 +23,9 @@ output_processor.run processor.run end - specify{ expect(new_output_species.distributions.reload.count).to eq(2) } - specify{ expect(new_output_species.distributions.find_by_geo_entity_id(poland.id)).not_to be_nil } - specify{ expect(new_output_species.distributions.find_by_geo_entity_id(poland.id).tag_list).to eq(['extinct']) } - specify{ expect(new_output_species.distributions.find_by_geo_entity_id(poland.id).distribution_references.count).to eq(1) } - specify{ expect(old_output_subspecies.distributions).to be_empty } + specify { expect(new_output_species.distributions.reload.count).to eq(2) } + specify { expect(new_output_species.distributions.find_by_geo_entity_id(poland.id)).not_to be_nil } + specify { expect(new_output_species.distributions.find_by_geo_entity_id(poland.id).tag_list).to eq(['extinct']) } + specify { expect(new_output_species.distributions.find_by_geo_entity_id(poland.id).distribution_references.count).to eq(1) } + specify { expect(old_output_subspecies.distributions).to be_empty } end diff --git a/spec/models/nomenclature_change/shared/output_legislation_reassignments_processor_examples.rb b/spec/models/nomenclature_change/shared/output_legislation_reassignments_processor_examples.rb index 55d377dfea..70325d90ad 100644 --- a/spec/models/nomenclature_change/shared/output_legislation_reassignments_processor_examples.rb +++ b/spec/models/nomenclature_change/shared/output_legislation_reassignments_processor_examples.rb @@ -1,12 +1,12 @@ shared_context 'output_legislation_reassignments_processor_examples' do - let(:poland){ + let(:poland) { create( :geo_entity, geo_entity_type_id: country_geo_entity_type.id, iso_code2: 'PL' ) } - let(:portugal){ + let(:portugal) { create( :geo_entity, geo_entity_type_id: country_geo_entity_type.id, @@ -48,7 +48,7 @@ quota.purposes << create(:purpose) quota = create(:quota, taxon_concept: old_output_subspecies, geo_entity: portugal) - 2.times{ create(:cites_suspension, taxon_concept: old_output_subspecies) } + 2.times { create(:cites_suspension, taxon_concept: old_output_subspecies) } create( :nomenclature_change_output_legislation_reassignment, output: output, @@ -67,77 +67,77 @@ output_processor.run processor.run end - specify{ expect(new_output_species.listing_changes.count).to eq(2) } - specify{ + specify { expect(new_output_species.listing_changes.count).to eq(2) } + specify { expect( new_output_species.listing_changes. find_by_effective_at_and_change_type_id('2013-01-01', cites_addition.id) ).not_to be_nil } - specify{ + specify { expect( new_output_species.listing_changes. find_by_effective_at_and_change_type_id('2013-01-01', cites_addition.id). party_listing_distribution.geo_entity ).to eq(poland) } - specify{ + specify { expect( new_output_species.listing_changes. find_by_effective_at_and_change_type_id('2013-01-01', cites_addition.id). listing_distributions ).to_not be_empty } - specify{ + specify { expect( new_output_species.listing_changes. find_by_effective_at_and_change_type_id('2013-01-01', cites_addition.id). annotation ).not_to be_nil } - specify{ + specify { expect( new_output_species.listing_changes. find_by_effective_at_and_change_type_id('2013-01-02', cites_addition.id) ).not_to be_nil } - specify{ + specify { expect( new_output_species.listing_changes. find_by_effective_at_and_change_type_id('2013-01-02', cites_addition.id). party_listing_distribution.geo_entity ).to eq(portugal) } - specify{ expect(new_output_species.quotas.count).to eq(2) } - specify{ + specify { expect(new_output_species.quotas.count).to eq(2) } + specify { expect( new_output_species.quotas. find_by_geo_entity_id(poland.id) ).not_to be_nil } - specify{ + specify { expect( new_output_species.quotas. find_by_geo_entity_id(poland.id). terms ).not_to be_empty } - specify{ + specify { expect( new_output_species.quotas. find_by_geo_entity_id(poland.id). sources ).not_to be_empty } - specify{ + specify { expect( new_output_species.quotas. find_by_geo_entity_id(poland.id). purposes ).not_to be_empty } - specify{ expect(new_output_species.cites_suspensions.count).to eq(2) } - specify{ expect(old_output_subspecies.listing_changes).to be_empty } - specify{ expect(old_output_subspecies.quotas).to be_empty } - specify{ expect(old_output_subspecies.cites_suspensions).to be_empty } + specify { expect(new_output_species.cites_suspensions.count).to eq(2) } + specify { expect(old_output_subspecies.listing_changes).to be_empty } + specify { expect(old_output_subspecies.quotas).to be_empty } + specify { expect(old_output_subspecies.cites_suspensions).to be_empty } end diff --git a/spec/models/nomenclature_change/shared/output_name_reassignments_processor_examples.rb b/spec/models/nomenclature_change/shared/output_name_reassignments_processor_examples.rb index 6d68aaebf5..d27c63548a 100644 --- a/spec/models/nomenclature_change/shared/output_name_reassignments_processor_examples.rb +++ b/spec/models/nomenclature_change/shared/output_name_reassignments_processor_examples.rb @@ -1,8 +1,8 @@ shared_context 'output_name_reassignments_processor_examples' do - let(:output_subspecies2_synonym){ + let(:output_subspecies2_synonym) { create_cites_eu_subspecies(name_status: 'S') } - let(:output_subspecies2_synonym_rel){ + let(:output_subspecies2_synonym_rel) { create(:taxon_relationship, taxon_relationship_type_id: synonym_relationship_type.id, taxon_concept: output_subspecies2, @@ -17,6 +17,6 @@ output_processor.run processor.run end - specify{ expect(new_output_species.synonyms).to include(output_subspecies2_synonym) } - specify{ expect(old_output_subspecies.synonyms).to be_empty } + specify { expect(new_output_species.synonyms).to include(output_subspecies2_synonym) } + specify { expect(old_output_subspecies.synonyms).to be_empty } end diff --git a/spec/models/nomenclature_change/shared/output_reference_reassignments_processor_examples.rb b/spec/models/nomenclature_change/shared/output_reference_reassignments_processor_examples.rb index c2a11daf6f..52eb3f5d55 100644 --- a/spec/models/nomenclature_change/shared/output_reference_reassignments_processor_examples.rb +++ b/spec/models/nomenclature_change/shared/output_reference_reassignments_processor_examples.rb @@ -4,10 +4,10 @@ output: output, reassignable_type: 'TaxonConceptReference' ) - 2.times{ create(:taxon_concept_reference, taxon_concept: old_output_subspecies) } + 2.times { create(:taxon_concept_reference, taxon_concept: old_output_subspecies) } output_processor.run processor.run end - specify{ expect(new_output_species.taxon_concept_references.count).to eq(2) } - specify{ expect(old_output_subspecies.taxon_concept_references).to be_empty } + specify { expect(new_output_species.taxon_concept_references.count).to eq(2) } + specify { expect(old_output_subspecies.taxon_concept_references).to be_empty } end diff --git a/spec/models/nomenclature_change/shared/output_shipment_reassignments_processor_examples.rb b/spec/models/nomenclature_change/shared/output_shipment_reassignments_processor_examples.rb index b7db3bee04..6f4f0ccb4e 100644 --- a/spec/models/nomenclature_change/shared/output_shipment_reassignments_processor_examples.rb +++ b/spec/models/nomenclature_change/shared/output_shipment_reassignments_processor_examples.rb @@ -8,6 +8,6 @@ output_processor.run processor.run end - specify{ expect(new_output_species.shipments.count).to eq(2) } - specify{ expect(old_output_subspecies.shipments).to be_empty } + specify { expect(new_output_species.shipments.count).to eq(2) } + specify { expect(old_output_subspecies.shipments).to be_empty } end diff --git a/spec/models/nomenclature_change/shared/parent_reassignments_constructor_examples.rb b/spec/models/nomenclature_change/shared/parent_reassignments_constructor_examples.rb index 437aaf4a3a..2ab86feeee 100644 --- a/spec/models/nomenclature_change/shared/parent_reassignments_constructor_examples.rb +++ b/spec/models/nomenclature_change/shared/parent_reassignments_constructor_examples.rb @@ -1,23 +1,23 @@ shared_context 'parent_reassignments_constructor_examples' do context "when previously no reassignments in place" do context "when no children" do - specify{ expect(input.parent_reassignments.size).to eq(0) } + specify { expect(input.parent_reassignments.size).to eq(0) } end context "when children" do - let(:input_species){ + let(:input_species) { s = create_cites_eu_species - 2.times{ create_cites_eu_subspecies(parent: s) } + 2.times { create_cites_eu_subspecies(parent: s) } s } - specify{ expect(input.parent_reassignments.size).to eq(2) } + specify { expect(input.parent_reassignments.size).to eq(2) } end end context "when previously reassignments in place" do - let(:input){ + let(:input) { i = create(:nomenclature_change_input, nomenclature_change: nc, taxon_concept: input_species) create(:nomenclature_change_parent_reassignment, input: i) i } - specify{ expect(input.parent_reassignments).to eq(@old_reassignments) } + specify { expect(input.parent_reassignments).to eq(@old_reassignments) } end end diff --git a/spec/models/nomenclature_change/shared/parent_reassignments_processor_examples.rb b/spec/models/nomenclature_change/shared/parent_reassignments_processor_examples.rb index 6b10cab07e..01975a614a 100644 --- a/spec/models/nomenclature_change/shared/parent_reassignments_processor_examples.rb +++ b/spec/models/nomenclature_change/shared/parent_reassignments_processor_examples.rb @@ -1,14 +1,14 @@ shared_context 'parent_reassignments_processor_examples' do - let(:input_species_child){ + let(:input_species_child) { create_cites_eu_subspecies(parent: input_species) } - let(:reassignment){ + let(:reassignment) { create(:nomenclature_change_parent_reassignment, input: input, reassignable_id: input_species_child.id ) } - let!(:reassignment_target){ + let!(:reassignment_target) { create(:nomenclature_change_reassignment_target, reassignment: reassignment, output: output @@ -19,9 +19,9 @@ processor.run input_species_child.reload end - specify{ expect(input_species_child.parent).to eq(input_species) } - specify{ expect(input_species_child.name_status).to eq('S') } - specify{ expect(input_species.children.count).to eq(0) } + specify { expect(input_species_child.parent).to eq(input_species) } + specify { expect(input_species_child.name_status).to eq('S') } + specify { expect(input_species.children.count).to eq(0) } specify do old_subspecies = input_species_child.reload new_subspecies = output.taxon_concept.children.first diff --git a/spec/models/nomenclature_change/shared/reference_reassignments_constructor_examples.rb b/spec/models/nomenclature_change/shared/reference_reassignments_constructor_examples.rb index 47a4caabfe..2c114d1af2 100644 --- a/spec/models/nomenclature_change/shared/reference_reassignments_constructor_examples.rb +++ b/spec/models/nomenclature_change/shared/reference_reassignments_constructor_examples.rb @@ -1,23 +1,23 @@ shared_context 'reference_reassignments_constructor_examples' do context "when previously no reassignments in place" do context "when no references" do - specify{ expect(input.reassignments.size).to eq(0) } + specify { expect(input.reassignments.size).to eq(0) } end context "when references" do - let(:input_species){ + let(:input_species) { s = create_cites_eu_species - 2.times{ create(:taxon_concept_reference, taxon_concept: s) } + 2.times { create(:taxon_concept_reference, taxon_concept: s) } s } - specify{ expect(input.reassignments.size).to eq(1) } + specify { expect(input.reassignments.size).to eq(1) } end end context "when previously reassignments in place" do - let(:input){ + let(:input) { i = create(:nomenclature_change_input, nomenclature_change: nc, taxon_concept: input_species) create(:nomenclature_change_reassignment, input: i) i } - specify{ expect(input.reassignments).to eq(@old_reassignments) } + specify { expect(input.reassignments).to eq(@old_reassignments) } end end diff --git a/spec/models/nomenclature_change/shared/reference_reassignments_processor_examples.rb b/spec/models/nomenclature_change/shared/reference_reassignments_processor_examples.rb index c3563716ca..2fe6b0bc86 100644 --- a/spec/models/nomenclature_change/shared/reference_reassignments_processor_examples.rb +++ b/spec/models/nomenclature_change/shared/reference_reassignments_processor_examples.rb @@ -1,19 +1,19 @@ shared_context 'reference_reassignments_processor_examples' do - let(:reassignment){ + let(:reassignment) { create(:nomenclature_change_reassignment, input: input, reassignable_type: 'TaxonConceptReference' ) } - let!(:reassignment_target){ + let!(:reassignment_target) { create(:nomenclature_change_reassignment_target, reassignment: reassignment, output: output ) } before(:each) do - 2.times{ create(:taxon_concept_reference, taxon_concept: input_species) } + 2.times { create(:taxon_concept_reference, taxon_concept: input_species) } processor.run end - specify{ expect(output_species1.taxon_concept_references.count).to eq(2) } + specify { expect(output_species1.taxon_concept_references.count).to eq(2) } end diff --git a/spec/models/nomenclature_change/shared/shipment_reassignments_processor_examples.rb b/spec/models/nomenclature_change/shared/shipment_reassignments_processor_examples.rb index f2f91fa8fa..a6a557c0fc 100644 --- a/spec/models/nomenclature_change/shared/shipment_reassignments_processor_examples.rb +++ b/spec/models/nomenclature_change/shared/shipment_reassignments_processor_examples.rb @@ -1,11 +1,11 @@ shared_context 'shipment_reassignments_processor_examples' do - let(:reassignment){ + let(:reassignment) { create(:nomenclature_change_reassignment, input: input, reassignable_type: 'Trade::Shipment' ) } - let!(:reassignment_target){ + let!(:reassignment_target) { create(:nomenclature_change_reassignment_target, reassignment: reassignment, output: output @@ -15,6 +15,6 @@ 2.times { create(:shipment, taxon_concept: input_species) } processor.run end - specify{ expect(output_species1.shipments.count).to eq(2) } - specify{ expect(input_species.shipments).to be_empty } + specify { expect(output_species1.shipments.count).to eq(2) } + specify { expect(input_species.shipments).to be_empty } end diff --git a/spec/models/nomenclature_change/shared/split_definitions.rb b/spec/models/nomenclature_change/shared/split_definitions.rb index 597baa77e3..227bf14789 100644 --- a/spec/models/nomenclature_change/shared/split_definitions.rb +++ b/spec/models/nomenclature_change/shared/split_definitions.rb @@ -1,23 +1,23 @@ shared_context 'split_definitions' do - let(:genus1){ + let(:genus1) { create_cites_eu_genus( taxon_name: create(:taxon_name, scientific_name: 'Genus1') ) } - let(:genus2){ + let(:genus2) { create_cites_eu_genus( taxon_name: create(:taxon_name, scientific_name: 'Genus2') ) } - let(:input_species){ create_cites_eu_species(parent: genus1) } - let(:output_species1){ create_cites_eu_species(parent: genus1) } - let(:output_species2){ create_cites_eu_species(parent: genus2) } - let(:errorus_genus){ + let(:input_species) { create_cites_eu_species(parent: genus1) } + let(:output_species1) { create_cites_eu_species(parent: genus1) } + let(:output_species2) { create_cites_eu_species(parent: genus2) } + let(:errorus_genus) { create_cites_eu_genus( taxon_name: create(:taxon_name, scientific_name: 'Errorus') ) } - let(:output_subspecies2){ + let(:output_subspecies2) { create_cites_eu_subspecies( taxon_name: create(:taxon_name, scientific_name: 'fatalus'), parent: create_cites_eu_species( @@ -26,15 +26,15 @@ ) ) } - let(:split_with_input){ + let(:split_with_input) { create(:nomenclature_change_split, input_attributes: { taxon_concept_id: input_species.id } ) } - let(:split_with_input_and_output){ + let(:split_with_input_and_output) { split_with_input_and_output_existing_taxon } - let(:split_with_input_and_same_output){ + let(:split_with_input_and_same_output) { create(:nomenclature_change_split, input_attributes: { taxon_concept_id: input_species.id }, outputs_attributes: { @@ -44,7 +44,7 @@ status: NomenclatureChange::Split::OUTPUTS ) } - let(:split_with_input_and_output_existing_taxon){ + let(:split_with_input_and_output_existing_taxon) { create(:nomenclature_change_split, input_attributes: { taxon_concept_id: input_species.id }, outputs_attributes: { @@ -54,7 +54,7 @@ status: NomenclatureChange::Split::OUTPUTS ) } - let(:split_with_input_and_output_new_taxon){ + let(:split_with_input_and_output_new_taxon) { create(:nomenclature_change_split, input_attributes: { taxon_concept_id: input_species.id }, outputs_attributes: { @@ -69,7 +69,7 @@ status: NomenclatureChange::Split::OUTPUTS ) } - let(:split_with_input_and_outputs_status_change){ + let(:split_with_input_and_outputs_status_change) { create(:nomenclature_change_split, input_attributes: { taxon_concept_id: input_species.id }, outputs_attributes: { @@ -83,7 +83,7 @@ status: NomenclatureChange::Split::OUTPUTS ) } - let(:split_with_input_and_outputs_name_change){ + let(:split_with_input_and_outputs_name_change) { create(:nomenclature_change_split, input_attributes: { taxon_concept_id: input_species.id }, outputs_attributes: { @@ -99,7 +99,7 @@ status: NomenclatureChange::Split::OUTPUTS ) } - let(:split_with_input_with_reassignments){ + let(:split_with_input_with_reassignments) { 3.times { create(:distribution, taxon_concept: input_species) } distribution = create(:distribution, taxon_concept: input_species) diff --git a/spec/models/nomenclature_change/shared/status_change_definitions.rb b/spec/models/nomenclature_change/shared/status_change_definitions.rb index 3255e63bf1..c2f29c9874 100644 --- a/spec/models/nomenclature_change/shared/status_change_definitions.rb +++ b/spec/models/nomenclature_change/shared/status_change_definitions.rb @@ -1,7 +1,7 @@ shared_context 'status_change_definitions' do - let(:input_species){ create_cites_eu_species } - let(:accepted_name){ create_cites_eu_species } - let(:input_trade_name){ + let(:input_species) { create_cites_eu_species } + let(:accepted_name) { create_cites_eu_species } + let(:input_trade_name) { tc = create_cites_eu_species(name_status: 'T', taxon_name: create(:taxon_name, scientific_name: 'Ridiculus fatalus') ) @@ -12,12 +12,12 @@ ) tc } - let(:input_trade_name_genus){ + let(:input_trade_name_genus) { create_cites_eu_genus( taxon_name: create(:taxon_name, scientific_name: 'Ridiculus') ) } - let(:input_synonym){ + let(:input_synonym) { tc = create_cites_eu_species(name_status: 'S', taxon_name: create(:taxon_name, scientific_name: 'Confundus totalus') ) @@ -28,12 +28,12 @@ ) tc } - let(:input_synonym_genus){ + let(:input_synonym_genus) { create_cites_eu_genus( taxon_name: create(:taxon_name, scientific_name: 'Confundus') ) } - let(:n_to_s_with_primary_output){ + let(:n_to_s_with_primary_output) { create(:nomenclature_change_status_to_synonym, primary_output_attributes: { is_primary_output: true, @@ -43,7 +43,7 @@ status: NomenclatureChange::StatusToSynonym::PRIMARY_OUTPUT ).reload } - let(:t_to_a_with_primary_output){ + let(:t_to_a_with_primary_output) { create(:nomenclature_change_status_to_accepted, primary_output_attributes: { is_primary_output: true, @@ -54,7 +54,7 @@ status: NomenclatureChange::StatusToAccepted::PRIMARY_OUTPUT ).reload } - let(:t_to_s_with_primary_and_secondary_output){ + let(:t_to_s_with_primary_and_secondary_output) { create(:nomenclature_change_status_to_synonym, primary_output_attributes: { is_primary_output: true, @@ -68,7 +68,7 @@ status: NomenclatureChange::StatusToSynonym::RELAY ).reload } - let(:n_to_s_with_input_and_secondary_output){ + let(:n_to_s_with_input_and_secondary_output) { create(:nomenclature_change_status_to_synonym, primary_output_attributes: { is_primary_output: true, @@ -83,7 +83,7 @@ status: NomenclatureChange::StatusToSynonym::RELAY ).reload } - let(:a_to_s_with_swap_with_primary_output){ + let(:a_to_s_with_swap_with_primary_output) { create(:nomenclature_change_status_swap, primary_output_attributes: { is_primary_output: true, @@ -93,7 +93,7 @@ status: NomenclatureChange::StatusSwap::PRIMARY_OUTPUT ).reload } - let(:a_to_s_with_swap){ + let(:a_to_s_with_swap) { create(:nomenclature_change_status_swap, primary_output_attributes: { is_primary_output: true, @@ -112,7 +112,7 @@ status: NomenclatureChange::StatusSwap::SECONDARY_OUTPUT ).reload } - let(:t_to_a_with_input){ + let(:t_to_a_with_input) { create(:nomenclature_change_status_to_accepted, primary_output_attributes: { is_primary_output: true, diff --git a/spec/models/nomenclature_change/split/constructor_spec.rb b/spec/models/nomenclature_change/split/constructor_spec.rb index 4fea53a935..4f1aba00d9 100644 --- a/spec/models/nomenclature_change/split/constructor_spec.rb +++ b/spec/models/nomenclature_change/split/constructor_spec.rb @@ -3,72 +3,72 @@ describe NomenclatureChange::Split::Constructor do include_context 'split_definitions' - let(:constructor){ NomenclatureChange::Split::Constructor.new(split) } + let(:constructor) { NomenclatureChange::Split::Constructor.new(split) } context :inputs do describe :build_input do - let(:split){ create(:nomenclature_change_split) } - before(:each){ @old_input = split.input; constructor.build_input } + let(:split) { create(:nomenclature_change_split) } + before(:each) { @old_input = split.input; constructor.build_input } context "when previously no input in place" do - specify{ expect(split.input).not_to be_nil } + specify { expect(split.input).not_to be_nil } end context "when previously input in place" do - let(:split){ split_with_input } - specify{ expect(split.input).to eq(@old_input) } + let(:split) { split_with_input } + specify { expect(split.input).to eq(@old_input) } end end end context :outputs do describe :build_outputs do - let(:split){ split_with_input } - before(:each){ @old_outputs = split.outputs; constructor.build_outputs } + let(:split) { split_with_input } + before(:each) { @old_outputs = split.outputs; constructor.build_outputs } context "when previously no outputs in place" do - specify{ expect(split.outputs.size).not_to eq(0) } + specify { expect(split.outputs.size).not_to eq(0) } end context "when previously output in place" do - let(:split){ split_with_input_and_output } - specify{ expect(split.outputs).to eq(@old_outputs) } + let(:split) { split_with_input_and_output } + specify { expect(split.outputs).to eq(@old_outputs) } end end end context :reassignments do - let(:split){ split_with_input_and_output } - let(:nc){ split } - let(:input){ nc.input } + let(:split) { split_with_input_and_output } + let(:nc) { split } + let(:input) { nc.input } describe :build_input_and_output_notes do - let(:output){ split.outputs[0] } + let(:output) { split.outputs[0] } before(:each) do @old_input_note = input.note_en @old_output_note = output.note_en constructor.build_input_and_output_notes end context "when previously no notes in place" do - let(:split){ + let(:split) { s = create(:nomenclature_change_split) create(:nomenclature_change_input, nomenclature_change: s) create(:nomenclature_change_output, nomenclature_change: s) s } - specify{ expect(input.note_en).not_to be_blank } - specify{ expect(output.note_en).not_to be_blank } + specify { expect(input.note_en).not_to be_blank } + specify { expect(output.note_en).not_to be_blank } context "when output = input" do - let(:split){ + let(:split) { s = create(:nomenclature_change_split) create(:nomenclature_change_input, nomenclature_change: s, taxon_concept: input_species) create(:nomenclature_change_output, nomenclature_change: s, taxon_concept: input_species) s } - specify{ expect(output.note_en).to be_blank } + specify { expect(output.note_en).to be_blank } end end context "when previously notes in place" do - let(:input){ + let(:input) { create(:nomenclature_change_input, nomenclature_change: split, note_en: 'blah') } - let(:output){ + let(:output) { create(:nomenclature_change_output, nomenclature_change: split, note_en: 'blah') } - specify{ expect(input.note_en).to eq(@old_input_note) } - specify{ expect(output.note_en).to eq(@old_output_note) } + specify { expect(input.note_en).to eq(@old_input_note) } + specify { expect(output.note_en).to eq(@old_output_note) } end end describe :build_parent_reassignments do @@ -79,26 +79,26 @@ include_context 'parent_reassignments_constructor_examples' context "when output = input" do - let(:input_species){ + let(:input_species) { s = create_cites_eu_species - 2.times{ create_cites_eu_subspecies(parent: s) } + 2.times { create_cites_eu_subspecies(parent: s) } s } - let(:split_with_input_and_output){ split_with_input_and_same_output } - let(:default_output){ split.outputs_intersect_inputs.first } - specify{ + let(:split_with_input_and_output) { split_with_input_and_same_output } + let(:default_output) { split.outputs_intersect_inputs.first } + specify { reassignment_targets = input.parent_reassignments.map(&:reassignment_target) expect(reassignment_targets.map(&:output).uniq).to(eq([default_output])) } end context "when previously reassignments in place" do - let(:input){ + let(:input) { i = create(:nomenclature_change_input, nomenclature_change: split, taxon_concept: input_species) create(:nomenclature_change_parent_reassignment, input: i) i } - specify{ expect(input.parent_reassignments).to eq(@old_reassignments) } + specify { expect(input.parent_reassignments).to eq(@old_reassignments) } end end describe :build_name_reassignments do @@ -109,7 +109,7 @@ include_context 'name_reassignments_constructor_examples' context "when output = input" do - let(:input_species){ + let(:input_species) { s = create_cites_eu_species 2.times do create(:taxon_relationship, @@ -120,9 +120,9 @@ end s } - let(:split_with_input_and_output){ split_with_input_and_same_output } - let(:default_output){ split.outputs_intersect_inputs.first } - specify{ + let(:split_with_input_and_output) { split_with_input_and_same_output } + let(:default_output) { split.outputs_intersect_inputs.first } + specify { reassignment_targets = input.name_reassignments.map do |reassignment| reassignment.reassignment_targets end.flatten diff --git a/spec/models/nomenclature_change/split/output_taxon_concept_processor_spec.rb b/spec/models/nomenclature_change/split/output_taxon_concept_processor_spec.rb index 55329fb6f3..6fdd43ac42 100644 --- a/spec/models/nomenclature_change/split/output_taxon_concept_processor_spec.rb +++ b/spec/models/nomenclature_change/split/output_taxon_concept_processor_spec.rb @@ -3,32 +3,32 @@ describe NomenclatureChange::OutputTaxonConceptProcessor do include_context 'split_definitions' - before(:each){ synonym_relationship_type } + before(:each) { synonym_relationship_type } describe :run do - let(:processor){ + let(:processor) { NomenclatureChange::OutputTaxonConceptProcessor.new(output) } before(:each) do processor.run end context "when output is existing taxon" do - let(:output){ split_with_input_and_output_existing_taxon.outputs.last } - specify{ expect(output.new_taxon_concept).to be_nil } + let(:output) { split_with_input_and_output_existing_taxon.outputs.last } + specify { expect(output.new_taxon_concept).to be_nil } end context "when output is new taxon" do - let(:output){ split_with_input_and_output_new_taxon.outputs.last } - specify{ expect(output.new_taxon_concept.full_name).to eq('Errorus fatalus') } + let(:output) { split_with_input_and_output_new_taxon.outputs.last } + specify { expect(output.new_taxon_concept.full_name).to eq('Errorus fatalus') } end context "when output is existing taxon with new status" do - let(:output){ split_with_input_and_outputs_status_change.outputs.last } - specify{ expect(output.new_taxon_concept).to be_nil } - specify{ expect(output.taxon_concept.name_status).to eq('A') } + let(:output) { split_with_input_and_outputs_status_change.outputs.last } + specify { expect(output.new_taxon_concept).to be_nil } + specify { expect(output.taxon_concept.name_status).to eq('A') } end context "when output is existing taxon with new name" do - let(:output){ split_with_input_and_outputs_name_change.outputs.last } - specify{ expect(output.taxon_concept.full_name).to eq('Errorus fatalus fatalus') } - specify{ expect(output.new_taxon_concept.name_status).to eq('A') } - specify{ expect(output.new_taxon_concept.full_name).to eq('Errorus lolcatus') } + let(:output) { split_with_input_and_outputs_name_change.outputs.last } + specify { expect(output.taxon_concept.full_name).to eq('Errorus fatalus fatalus') } + specify { expect(output.new_taxon_concept.name_status).to eq('A') } + specify { expect(output.new_taxon_concept.full_name).to eq('Errorus lolcatus') } end end end \ No newline at end of file diff --git a/spec/models/nomenclature_change/split/processor_spec.rb b/spec/models/nomenclature_change/split/processor_spec.rb index 399591e44b..b3e3100ed4 100644 --- a/spec/models/nomenclature_change/split/processor_spec.rb +++ b/spec/models/nomenclature_change/split/processor_spec.rb @@ -3,87 +3,87 @@ describe NomenclatureChange::Split::Processor do include_context 'split_definitions' - before(:each){ + before(:each) { synonym_relationship_type @shipment = create(:shipment, taxon_concept: input_species, reported_taxon_concept: input_species ) } - let(:processor){ NomenclatureChange::Split::Processor.new(split) } + let(:processor) { NomenclatureChange::Split::Processor.new(split) } describe :run do context "when outputs are existing taxa" do - let!(:split){ split_with_input_and_output_existing_taxon } - specify { expect{ processor.run }.not_to change(TaxonConcept, :count) } - specify { expect{ processor.run }.not_to change(output_species1, :full_name) } - specify { expect{ processor.run }.not_to change(output_species2, :full_name) } + let!(:split) { split_with_input_and_output_existing_taxon } + specify { expect { processor.run }.not_to change(TaxonConcept, :count) } + specify { expect { processor.run }.not_to change(output_species1, :full_name) } + specify { expect { processor.run }.not_to change(output_species2, :full_name) } context "relationships and trade" do - before(:each){ processor.run } - specify{ expect(input_species.reload).to be_is_synonym } - specify{ expect(input_species.accepted_names).to include(output_species1) } - specify{ expect(input_species.shipments).to be_empty } - specify{ expect(input_species.reported_shipments).to include(@shipment) } - specify{ expect(output_species1.shipments).to include(@shipment) } + before(:each) { processor.run } + specify { expect(input_species.reload).to be_is_synonym } + specify { expect(input_species.accepted_names).to include(output_species1) } + specify { expect(input_species.shipments).to be_empty } + specify { expect(input_species.reported_shipments).to include(@shipment) } + specify { expect(output_species1.shipments).to include(@shipment) } end end context "when output is new taxon" do - let!(:split){ split_with_input_and_output_new_taxon } - specify { expect{ processor.run }.to change(TaxonConcept, :count).by(1) } + let!(:split) { split_with_input_and_output_new_taxon } + specify { expect { processor.run }.to change(TaxonConcept, :count).by(1) } context "relationships and trade" do - before(:each){ processor.run } - specify{ expect(input_species.reload).to be_is_synonym } - specify{ expect(input_species.accepted_names).to include(split.outputs.last.new_taxon_concept) } - specify{ expect(input_species.shipments).to be_empty } - specify{ expect(input_species.reported_shipments).to include(@shipment) } - specify{ expect(output_species1.shipments).to include(@shipment) } + before(:each) { processor.run } + specify { expect(input_species.reload).to be_is_synonym } + specify { expect(input_species.accepted_names).to include(split.outputs.last.new_taxon_concept) } + specify { expect(input_species.shipments).to be_empty } + specify { expect(input_species.reported_shipments).to include(@shipment) } + specify { expect(output_species1.shipments).to include(@shipment) } end end context "when output is existing taxon with new status" do - let(:output_species2){ + let(:output_species2) { create_cites_eu_species( name_status: 'S', taxon_name: create(:taxon_name, scientific_name: 'Notio mirabilis') ) } - let(:genus2){ + let(:genus2) { create_cites_eu_genus( taxon_name: create(:taxon_name, scientific_name: 'Notio') ) } - let!(:split){ split_with_input_and_outputs_status_change } - specify { expect{ processor.run }.not_to change(TaxonConcept, :count) } - specify { expect{ processor.run }.not_to change(output_species1, :full_name) } - specify { expect{ processor.run }.not_to change(output_species2, :full_name) } + let!(:split) { split_with_input_and_outputs_status_change } + specify { expect { processor.run }.not_to change(TaxonConcept, :count) } + specify { expect { processor.run }.not_to change(output_species1, :full_name) } + specify { expect { processor.run }.not_to change(output_species2, :full_name) } context "relationships and trade" do - before(:each){ processor.run } - specify{ expect(input_species.reload).to be_is_synonym } - specify{ expect(input_species.accepted_names).to include(output_species1) } - specify{ expect(output_species1.shipments).to include(@shipment) } + before(:each) { processor.run } + specify { expect(input_species.reload).to be_is_synonym } + specify { expect(input_species.accepted_names).to include(output_species1) } + specify { expect(output_species1.shipments).to include(@shipment) } end end context "when output is existing taxon with new name" do - let(:output_species2){ create_cites_eu_subspecies } - let!(:split){ split_with_input_and_outputs_name_change } - specify { expect{ processor.run }.to change(TaxonConcept, :count).by(1) } - specify { expect{ processor.run }.not_to change(output_species1, :full_name) } - specify { expect{ processor.run }.not_to change(output_species2, :full_name) } + let(:output_species2) { create_cites_eu_subspecies } + let!(:split) { split_with_input_and_outputs_name_change } + specify { expect { processor.run }.to change(TaxonConcept, :count).by(1) } + specify { expect { processor.run }.not_to change(output_species1, :full_name) } + specify { expect { processor.run }.not_to change(output_species2, :full_name) } context "relationships and trade" do - before(:each){ processor.run } - specify{ expect(input_species.reload).to be_is_synonym } - specify{ expect(input_species.reload.parent).to eq(genus1) } - specify{ expect(input_species.accepted_names).to include(split.outputs.last.new_taxon_concept) } - specify{ expect(output_species1.shipments).to include(@shipment) } + before(:each) { processor.run } + specify { expect(input_species.reload).to be_is_synonym } + specify { expect(input_species.reload.parent).to eq(genus1) } + specify { expect(input_species.accepted_names).to include(split.outputs.last.new_taxon_concept) } + specify { expect(output_species1.shipments).to include(@shipment) } end end context "when input with children that don't change name" do - let!(:input_species_child){ + let!(:input_species_child) { create_cites_eu_subspecies(parent: input_species) } - let!(:input_species_child_listing){ + let!(:input_species_child_listing) { create_cites_I_addition(taxon_concept: input_species_child) } - let(:split){ + let(:split) { create(:nomenclature_change_split, input_attributes: { taxon_concept_id: input_species.id, @@ -103,7 +103,7 @@ status: NomenclatureChange::Split::LEGISLATION ) } - before(:each){ processor.run } + before(:each) { processor.run } specify "input / output species has public nomenclature note set" do expect(input_species.reload.nomenclature_note_en).to eq(' input species was split into input species and output species 2') end @@ -128,16 +128,16 @@ end context "when input with children that change name" do - let!(:input_species_child){ + let!(:input_species_child) { create_cites_eu_subspecies(parent: input_species) } - let!(:input_species_child_listing){ + let!(:input_species_child_listing) { create_cites_I_addition(taxon_concept: input_species_child) } - let!(:output_species1_child){ + let!(:output_species1_child) { create_cites_eu_subspecies(parent: output_species1) } - let(:split){ + let(:split) { create(:nomenclature_change_split, input_attributes: { taxon_concept_id: input_species.id, @@ -155,25 +155,25 @@ status: NomenclatureChange::Split::LEGISLATION ) } - let(:input){ split.input } - let(:output){ split.outputs.first } - let(:reassignment){ + let(:input) { split.input } + let(:output) { split.outputs.first } + let(:reassignment) { create(:nomenclature_change_parent_reassignment, input: input, reassignable_id: input_species_child.id ) } - let!(:reassignment_target){ + let!(:reassignment_target) { create(:nomenclature_change_reassignment_target, reassignment: reassignment, output: output ) } - let(:output_species){ output.taxon_concept.reload } + let(:output_species) { output.taxon_concept.reload } let(:output_species_child) do output.taxon_concept.children.where(['id != ?', output_species1_child.id]).first end - before(:each){ processor.run } + before(:each) { processor.run } specify "input species has public nomenclature note set" do expect(input_species.reload.nomenclature_note_en).to eq(' input species was split into output species 1 and output species 2') end @@ -214,7 +214,7 @@ output_species_child.listing_changes.first.nomenclature_note_en ).to eq(output_species.nomenclature_note_en) end - let(:output_species1_genus_name){ output_species1.parent.full_name } + let(:output_species1_genus_name) { output_species1.parent.full_name } specify "original output species child retains higher taxa intact" do expect(output_species_child.data['genus_name']).to eq(output_species1_genus_name) end @@ -247,13 +247,13 @@ taxon_name: create(:taxon_name, scientific_name: 'unicolor') ) end - let!(:quota){ create(:quota, taxon_concept: input_genus_child, geo_entity: create(:geo_entity)) } + let!(:quota) { create(:quota, taxon_concept: input_genus_child, geo_entity: create(:geo_entity)) } let(:output_genus) do create_cites_eu_genus( taxon_name: create(:taxon_name, scientific_name: 'Paracrotalus') ) end - let(:split){ + let(:split) { create(:nomenclature_change_split, input_attributes: { taxon_concept_id: input_genus.id }, outputs_attributes: { @@ -263,19 +263,19 @@ status: NomenclatureChange::Split::LEGISLATION ) } - let(:reassignment){ + let(:reassignment) { create(:nomenclature_change_parent_reassignment, input: split.input, reassignable_id: input_genus_child.id ) } - let!(:reassignment_target){ + let!(:reassignment_target) { create(:nomenclature_change_reassignment_target, reassignment: reassignment, output: split.outputs.last ) } - before(:each){ processor.run } + before(:each) { processor.run } specify "input genus child is a synonym" do expect(input_genus_child.reload.name_status).to eq('S') end @@ -309,7 +309,7 @@ end end describe :summary do - let(:split){ split_with_input_and_output_existing_taxon } + let(:split) { split_with_input_and_output_existing_taxon } specify { expect(processor.summary).to be_kind_of(Array) } end end \ No newline at end of file diff --git a/spec/models/nomenclature_change/split_spec.rb b/spec/models/nomenclature_change/split_spec.rb index 40fad079f5..81249a0cab 100644 --- a/spec/models/nomenclature_change/split_spec.rb +++ b/spec/models/nomenclature_change/split_spec.rb @@ -18,7 +18,7 @@ describe :validate do context "when required inputs missing" do context "when inputs" do - let(:split){ + let(:split) { build( :nomenclature_change_split, :status => NomenclatureChange::Split::INPUTS ) @@ -26,7 +26,7 @@ specify { expect(split).to have(1).errors_on(:input) } end context "when submitting" do - let(:split){ + let(:split) { build( :nomenclature_change_split, :status => NomenclatureChange::Split::SUBMITTED ) @@ -36,7 +36,7 @@ end context "when required outputs missing" do context "when outputs" do - let(:split){ + let(:split) { build( :nomenclature_change_split, :status => NomenclatureChange::Split::OUTPUTS ) @@ -44,7 +44,7 @@ specify { expect(split).to have(1).errors_on(:outputs) } end context "when submitting" do - let(:split){ + let(:split) { build( :nomenclature_change_split, :status => NomenclatureChange::Split::SUBMITTED ) @@ -53,7 +53,7 @@ end end context "when output has different rank than input" do - let(:split){ + let(:split) { build(:nomenclature_change_split, :status => NomenclatureChange::Split::OUTPUTS, :input_attributes => { :taxon_concept_id => create_cites_eu_species.id }, diff --git a/spec/models/nomenclature_change/status_swap/constructor_spec.rb b/spec/models/nomenclature_change/status_swap/constructor_spec.rb index bdf7560641..b2805d3a0f 100644 --- a/spec/models/nomenclature_change/status_swap/constructor_spec.rb +++ b/spec/models/nomenclature_change/status_swap/constructor_spec.rb @@ -3,61 +3,61 @@ describe NomenclatureChange::StatusSwap::Constructor do include_context 'status_change_definitions' - let(:constructor){ NomenclatureChange::StatusSwap::Constructor.new(status_change) } + let(:constructor) { NomenclatureChange::StatusSwap::Constructor.new(status_change) } describe :build_primary_output do - let(:status_change){ create(:nomenclature_change_status_swap) } + let(:status_change) { create(:nomenclature_change_status_swap) } before(:each) do @old_output = status_change.primary_output constructor.build_primary_output end context "when previously no primary output in place" do - specify{ expect(status_change.primary_output).not_to be_nil } + specify { expect(status_change.primary_output).not_to be_nil } end context "when previously primary output in place" do - let(:status_change){ a_to_s_with_swap } - specify{ expect(status_change.primary_output).to eq(@old_output) } + let(:status_change) { a_to_s_with_swap } + specify { expect(status_change.primary_output).to eq(@old_output) } end end describe :build_secondary_output do context :downgrade do - let(:status_change){ a_to_s_with_swap_with_primary_output } + let(:status_change) { a_to_s_with_swap_with_primary_output } before(:each) do @old_output = status_change.secondary_output constructor.build_secondary_output end context "when previously no secondary output in place" do - specify{ expect(status_change.secondary_output).not_to be_nil } + specify { expect(status_change.secondary_output).not_to be_nil } end context "when previously secondary output in place" do - let(:status_change){ a_to_s_with_swap } - specify{ expect(status_change.secondary_output).to eq(@old_output) } + let(:status_change) { a_to_s_with_swap } + specify { expect(status_change.secondary_output).to eq(@old_output) } end end end describe :build_secondary_output_note do - let(:primary_output){ status_change.primary_output } - let(:secondary_output){ status_change.secondary_output } + let(:primary_output) { status_change.primary_output } + let(:secondary_output) { status_change.secondary_output } before(:each) do @old_primary_output_note = primary_output.internal_note @old_secondary_output_note = secondary_output.note_en constructor.build_secondary_output_note end - let(:status_change){ a_to_s_with_swap } + let(:status_change) { a_to_s_with_swap } context "when previously no notes in place" do - specify{ expect(primary_output.internal_note).to be_blank } - specify{ expect(secondary_output.note_en).not_to be_blank } + specify { expect(primary_output.internal_note).to be_blank } + specify { expect(secondary_output.note_en).not_to be_blank } end context "when previously notes in place" do - let(:primary_output){ + let(:primary_output) { create(:nomenclature_change_output, nomenclature_change: status_change, internal_note: 'blah') } - let(:secondary_output){ + let(:secondary_output) { create(:nomenclature_change_output, nomenclature_change: status_change, note_en: 'blah') } - specify{ expect(primary_output.internal_note).to eq(@old_primary_output_note) } - specify{ expect(secondary_output.note_en).to eq(@old_secondary_output_note) } + specify { expect(primary_output.internal_note).to eq(@old_primary_output_note) } + specify { expect(secondary_output.note_en).to eq(@old_secondary_output_note) } end end diff --git a/spec/models/nomenclature_change/status_swap/processor_spec.rb b/spec/models/nomenclature_change/status_swap/processor_spec.rb index 9d6ea8ff94..39556dc342 100644 --- a/spec/models/nomenclature_change/status_swap/processor_spec.rb +++ b/spec/models/nomenclature_change/status_swap/processor_spec.rb @@ -3,9 +3,9 @@ describe NomenclatureChange::StatusSwap::Processor do include_context 'status_change_definitions' - let(:accepted_name){ create_cites_eu_species } + let(:accepted_name) { create_cites_eu_species } - let(:synonym){ + let(:synonym) { tc = create_cites_eu_species(name_status: 'S') create(:taxon_relationship, taxon_concept: accepted_name, @@ -15,17 +15,17 @@ tc } - before(:each){ synonym_relationship_type } - let(:processor){ NomenclatureChange::StatusSwap::Processor.new(status_change) } - let(:primary_output_taxon_concept){ status_change.primary_output.taxon_concept } - let(:secondary_output_taxon_concept){ status_change.secondary_output.taxon_concept } + before(:each) { synonym_relationship_type } + let(:processor) { NomenclatureChange::StatusSwap::Processor.new(status_change) } + let(:primary_output_taxon_concept) { status_change.primary_output.taxon_concept } + let(:secondary_output_taxon_concept) { status_change.secondary_output.taxon_concept } describe :run do context "from accepted name" do - let(:accepted_name_parent){ create_cites_eu_genus } - let(:accepted_name){ create_cites_eu_species(parent: accepted_name_parent) } - let(:status_change){ a_to_s_with_swap } - before(:each){ + let(:accepted_name_parent) { create_cites_eu_genus } + let(:accepted_name) { create_cites_eu_species(parent: accepted_name_parent) } + let(:status_change) { a_to_s_with_swap } + before(:each) { @shipment = create(:shipment, taxon_concept: primary_output_taxon_concept, reported_taxon_concept: primary_output_taxon_concept @@ -33,10 +33,10 @@ secondary_output_taxon_concept.create_nomenclature_comment processor.run } - specify{ expect(primary_output_taxon_concept).to be_is_synonym } - specify{ expect(primary_output_taxon_concept.parent).to eq(accepted_name_parent) } - specify{ expect(secondary_output_taxon_concept.name_status).to eq('A') } - specify{ expect(primary_output_taxon_concept.accepted_names).to include(secondary_output_taxon_concept) } + specify { expect(primary_output_taxon_concept).to be_is_synonym } + specify { expect(primary_output_taxon_concept.parent).to eq(accepted_name_parent) } + specify { expect(secondary_output_taxon_concept.name_status).to eq('A') } + specify { expect(primary_output_taxon_concept.accepted_names).to include(secondary_output_taxon_concept) } specify "public nomenclature note is set" do expect(secondary_output_taxon_concept.nomenclature_note_en).to eq(' public') end @@ -47,7 +47,7 @@ end describe :summary do - let(:status_change){ a_to_s_with_swap } + let(:status_change) { a_to_s_with_swap } specify { expect(processor.summary).to be_kind_of(Array) } end end diff --git a/spec/models/nomenclature_change/status_to_accepted/processor_spec.rb b/spec/models/nomenclature_change/status_to_accepted/processor_spec.rb index 41a2f9c3df..d9a4ba6e65 100644 --- a/spec/models/nomenclature_change/status_to_accepted/processor_spec.rb +++ b/spec/models/nomenclature_change/status_to_accepted/processor_spec.rb @@ -3,9 +3,9 @@ describe NomenclatureChange::StatusToAccepted::Processor do include_context 'status_change_definitions' - let(:accepted_name){ create_cites_eu_species } + let(:accepted_name) { create_cites_eu_species } - let(:trade_name){ + let(:trade_name) { tc = create_cites_eu_species( name_status: 'T', taxon_name: create(:taxon_name, scientific_name: 'Lolcatus nonsensus') @@ -17,12 +17,12 @@ ) tc } - let(:trade_name_genus){ + let(:trade_name_genus) { create_cites_eu_genus( taxon_name: create(:taxon_name, scientific_name: 'Lolcatus') ) } - let(:synonym){ + let(:synonym) { tc = create_cites_eu_species( name_status: 'S', taxon_name: create(:taxon_name, scientific_name: 'Foobarus ridiculus') @@ -34,32 +34,32 @@ ) tc } - let(:synonym_genus){ + let(:synonym_genus) { create_cites_eu_genus( taxon_name: create(:taxon_name, scientific_name: 'Foobarus') ) } - before(:each){ synonym_relationship_type } - let(:processor){ NomenclatureChange::StatusToAccepted::Processor.new(status_change) } - let(:primary_output_taxon_concept){ status_change.primary_output.taxon_concept } - let(:secondary_output_taxon_concept){ status_change.secondary_output.taxon_concept } + before(:each) { synonym_relationship_type } + let(:processor) { NomenclatureChange::StatusToAccepted::Processor.new(status_change) } + let(:primary_output_taxon_concept) { status_change.primary_output.taxon_concept } + let(:secondary_output_taxon_concept) { status_change.secondary_output.taxon_concept } describe :run do context "from trade name" do - let(:output_species){ secondary_output_taxon_concept } - let(:status_change){ t_to_a_with_input } - before(:each){ + let(:output_species) { secondary_output_taxon_concept } + let(:status_change) { t_to_a_with_input } + before(:each) { @shipment = create(:shipment, taxon_concept: accepted_name, reported_taxon_concept: primary_output_taxon_concept ) processor.run } - specify{ expect(primary_output_taxon_concept.name_status).to eq('A') } - specify{ expect(primary_output_taxon_concept.accepted_names_for_trade_name).to be_empty } - specify{ expect(primary_output_taxon_concept.shipments).to include(@shipment) } - specify{ expect(primary_output_taxon_concept.reported_shipments).to include(@shipment) } - specify{ expect(accepted_name.shipments).to be_empty } + specify { expect(primary_output_taxon_concept.name_status).to eq('A') } + specify { expect(primary_output_taxon_concept.accepted_names_for_trade_name).to be_empty } + specify { expect(primary_output_taxon_concept.shipments).to include(@shipment) } + specify { expect(primary_output_taxon_concept.reported_shipments).to include(@shipment) } + specify { expect(accepted_name.shipments).to be_empty } end end diff --git a/spec/models/nomenclature_change/status_to_accepted_spec.rb b/spec/models/nomenclature_change/status_to_accepted_spec.rb index daeb467759..5f6c0c28de 100644 --- a/spec/models/nomenclature_change/status_to_accepted_spec.rb +++ b/spec/models/nomenclature_change/status_to_accepted_spec.rb @@ -18,7 +18,7 @@ describe :validate do context "when required primary output missing" do context "when primary_output" do - let(:status_change){ + let(:status_change) { build( :nomenclature_change_status_to_accepted, status: NomenclatureChange::StatusToAccepted::PRIMARY_OUTPUT @@ -27,7 +27,7 @@ specify { expect(status_change).to have(1).error_on(:primary_output) } end context "when submitting" do - let(:status_change){ + let(:status_change) { build( :nomenclature_change_status_to_accepted, status: NomenclatureChange::StatusToAccepted::SUBMITTED @@ -38,7 +38,7 @@ end context "when primary output has invalid name status" do context "when primary_output" do - let(:status_change){ + let(:status_change) { build( :nomenclature_change_status_to_accepted, :primary_output_attributes => { @@ -52,7 +52,7 @@ end context "when primary output has valid name status" do context "when primary_output" do - let(:status_change){ + let(:status_change) { build( :nomenclature_change_status_to_accepted, :primary_output_attributes => { diff --git a/spec/models/nomenclature_change/status_to_synonym/constructor_spec.rb b/spec/models/nomenclature_change/status_to_synonym/constructor_spec.rb index 41b23879fb..166151c719 100644 --- a/spec/models/nomenclature_change/status_to_synonym/constructor_spec.rb +++ b/spec/models/nomenclature_change/status_to_synonym/constructor_spec.rb @@ -3,21 +3,21 @@ describe NomenclatureChange::StatusToSynonym::Constructor do include_context 'status_change_definitions' - let(:constructor){ NomenclatureChange::StatusToSynonym::Constructor.new(status_change) } - let(:input_species){ create_cites_eu_species(name_status: 'N') } + let(:constructor) { NomenclatureChange::StatusToSynonym::Constructor.new(status_change) } + let(:input_species) { create_cites_eu_species(name_status: 'N') } describe :build_input do - let(:status_change){ n_to_s_with_primary_output } + let(:status_change) { n_to_s_with_primary_output } before(:each) do @old_input = status_change.input constructor.build_input end context "when previously no input in place" do - specify{ expect(status_change.input).not_to be_nil } + specify { expect(status_change.input).not_to be_nil } end context "when previously input in place" do - let(:status_change){ n_to_s_with_input_and_secondary_output } - specify{ expect(status_change.input).to eq(@old_input) } + let(:status_change) { n_to_s_with_input_and_secondary_output } + specify { expect(status_change.input).to eq(@old_input) } end end diff --git a/spec/models/nomenclature_change/status_to_synonym/output_taxon_concept_processor_spec.rb b/spec/models/nomenclature_change/status_to_synonym/output_taxon_concept_processor_spec.rb index f90cc99964..649ab5ce5f 100644 --- a/spec/models/nomenclature_change/status_to_synonym/output_taxon_concept_processor_spec.rb +++ b/spec/models/nomenclature_change/status_to_synonym/output_taxon_concept_processor_spec.rb @@ -3,19 +3,19 @@ describe NomenclatureChange::OutputTaxonConceptProcessor do include_context 'status_change_definitions' - before(:each){ synonym_relationship_type } - let(:input_species){ create_cites_eu_species(name_status: 'N') } + before(:each) { synonym_relationship_type } + let(:input_species) { create_cites_eu_species(name_status: 'N') } describe :run do - let(:processor){ + let(:processor) { NomenclatureChange::OutputTaxonConceptProcessor.new(primary_output) } before(:each) do processor.run end context "when output is existing taxon" do - let(:primary_output){ n_to_s_with_input_and_secondary_output.primary_output } - specify{ expect(primary_output.new_taxon_concept).to be_nil } + let(:primary_output) { n_to_s_with_input_and_secondary_output.primary_output } + specify { expect(primary_output.new_taxon_concept).to be_nil } end end end \ No newline at end of file diff --git a/spec/models/nomenclature_change/status_to_synonym/processor_spec.rb b/spec/models/nomenclature_change/status_to_synonym/processor_spec.rb index 25bec4e83a..3c1769964c 100644 --- a/spec/models/nomenclature_change/status_to_synonym/processor_spec.rb +++ b/spec/models/nomenclature_change/status_to_synonym/processor_spec.rb @@ -3,47 +3,47 @@ describe NomenclatureChange::StatusToSynonym::Processor do include_context 'status_change_definitions' - before(:each){ synonym_relationship_type } - let(:processor){ NomenclatureChange::StatusToSynonym::Processor.new(status_change) } - let(:input_species){ create_cites_eu_species(name_status: 'N') } - let(:primary_output_taxon_concept){ status_change.primary_output.taxon_concept } - let(:secondary_output_taxon_concept){ status_change.secondary_output.taxon_concept } + before(:each) { synonym_relationship_type } + let(:processor) { NomenclatureChange::StatusToSynonym::Processor.new(status_change) } + let(:input_species) { create_cites_eu_species(name_status: 'N') } + let(:primary_output_taxon_concept) { status_change.primary_output.taxon_concept } + let(:secondary_output_taxon_concept) { status_change.secondary_output.taxon_concept } describe :run do context "from N name" do - let(:input_species_parent){ create_cites_eu_genus } - let(:input_species){ create_cites_eu_species(parent: input_species_parent) } - let(:status_change){ n_to_s_with_input_and_secondary_output } - before(:each){ + let(:input_species_parent) { create_cites_eu_genus } + let(:input_species) { create_cites_eu_species(parent: input_species_parent) } + let(:status_change) { n_to_s_with_input_and_secondary_output } + before(:each) { @shipment = create(:shipment, taxon_concept: primary_output_taxon_concept, reported_taxon_concept: primary_output_taxon_concept ) processor.run } - specify{ expect(primary_output_taxon_concept).to be_is_synonym } - specify{ expect(primary_output_taxon_concept.parent).to eq(input_species_parent) } - specify{ expect(primary_output_taxon_concept.accepted_names).to include(secondary_output_taxon_concept) } - specify{ expect(primary_output_taxon_concept.shipments).to be_empty } - specify{ expect(primary_output_taxon_concept.reported_shipments).to include(@shipment) } - specify{ expect(secondary_output_taxon_concept.shipments).to include(@shipment) } + specify { expect(primary_output_taxon_concept).to be_is_synonym } + specify { expect(primary_output_taxon_concept.parent).to eq(input_species_parent) } + specify { expect(primary_output_taxon_concept.accepted_names).to include(secondary_output_taxon_concept) } + specify { expect(primary_output_taxon_concept.shipments).to be_empty } + specify { expect(primary_output_taxon_concept.reported_shipments).to include(@shipment) } + specify { expect(secondary_output_taxon_concept.shipments).to include(@shipment) } end context "from trade name" do - let(:input_species){ trade_name } - let(:status_change){ t_to_s_with_primary_and_secondary_output } - before(:each){ + let(:input_species) { trade_name } + let(:status_change) { t_to_s_with_primary_and_secondary_output } + before(:each) { @shipment = create(:shipment, taxon_concept: accepted_name, reported_taxon_concept: primary_output_taxon_concept ) processor.run } - specify{ expect(primary_output_taxon_concept).to be_is_synonym } - specify{ expect(primary_output_taxon_concept.accepted_names).to include(secondary_output_taxon_concept) } - specify{ expect(primary_output_taxon_concept.accepted_names_for_trade_name).to be_empty } - specify{ expect(primary_output_taxon_concept.shipments).to be_empty } - specify{ expect(primary_output_taxon_concept.reported_shipments).to include(@shipment) } - specify{ expect(secondary_output_taxon_concept.shipments).to include(@shipment) } + specify { expect(primary_output_taxon_concept).to be_is_synonym } + specify { expect(primary_output_taxon_concept.accepted_names).to include(secondary_output_taxon_concept) } + specify { expect(primary_output_taxon_concept.accepted_names_for_trade_name).to be_empty } + specify { expect(primary_output_taxon_concept.shipments).to be_empty } + specify { expect(primary_output_taxon_concept.reported_shipments).to include(@shipment) } + specify { expect(secondary_output_taxon_concept.shipments).to include(@shipment) } end end diff --git a/spec/models/nomenclature_change/status_to_synonym_spec.rb b/spec/models/nomenclature_change/status_to_synonym_spec.rb index 10231bcdd9..560a317859 100644 --- a/spec/models/nomenclature_change/status_to_synonym_spec.rb +++ b/spec/models/nomenclature_change/status_to_synonym_spec.rb @@ -18,7 +18,7 @@ describe :validate do context "when required primary output missing" do context "when primary_output" do - let(:status_change){ + let(:status_change) { build( :nomenclature_change_status_to_synonym, status: NomenclatureChange::StatusToSynonym::PRIMARY_OUTPUT @@ -27,7 +27,7 @@ specify { expect(status_change).to have(1).error_on(:primary_output) } end context "when submitting" do - let(:status_change){ + let(:status_change) { build( :nomenclature_change_status_to_synonym, status: NomenclatureChange::StatusToSynonym::SUBMITTED @@ -38,7 +38,7 @@ end context "when primary output has invalid name status" do context "when primary_output" do - let(:status_change){ + let(:status_change) { build( :nomenclature_change_status_to_synonym, :primary_output_attributes => { @@ -52,7 +52,7 @@ end context "when primary output has valid name status" do context "when primary_output" do - let(:status_change){ + let(:status_change) { build( :nomenclature_change_status_to_synonym, :primary_output_attributes => { @@ -66,7 +66,7 @@ end context "when required secondary output missing" do context "when relay" do - let(:status_change){ + let(:status_change) { build( :nomenclature_change_status_to_synonym, primary_output_attributes: { taxon_concept_id: create_cites_eu_species(name_status: 'N').id }, @@ -76,7 +76,7 @@ specify { expect(status_change).to have(1).error_on(:secondary_output) } end context "when submitting" do - let(:status_change){ + let(:status_change) { build( :nomenclature_change_status_to_synonym, primary_output_attributes: { taxon_concept_id: create_cites_eu_species(name_status: 'N').id }, diff --git a/spec/models/nomenclature_change_spec.rb b/spec/models/nomenclature_change_spec.rb index 4f676bc131..e494fad335 100644 --- a/spec/models/nomenclature_change_spec.rb +++ b/spec/models/nomenclature_change_spec.rb @@ -17,13 +17,13 @@ describe NomenclatureChange do describe :validate do context "when status not specified" do - let(:nomenclature_change){ + let(:nomenclature_change) { build(:nomenclature_change, :status => nil) } specify { expect(nomenclature_change).not_to be_valid } end context "when previous status=submitted" do - let(:nomenclature_change){ + let(:nomenclature_change) { nc = create(:nomenclature_change, :status => NomenclatureChange::SUBMITTED) nc.status = NomenclatureChange::NEW nc @@ -31,7 +31,7 @@ specify { expect(nomenclature_change).not_to be_valid } end context "when previous status=closed" do - let(:nomenclature_change){ + let(:nomenclature_change) { nc = create(:nomenclature_change, :status => NomenclatureChange::CLOSED) nc.status = NomenclatureChange::SUBMITTED nc @@ -41,34 +41,34 @@ end describe :submitting? do context "when new object with status=submitted" do - let(:nomenclature_change){ + let(:nomenclature_change) { build(:nomenclature_change, :status => NomenclatureChange::SUBMITTED) } - specify{ expect(nomenclature_change).to be_submitting } + specify { expect(nomenclature_change).to be_submitting } end context "when updating object with status new -> submitted" do - let(:nomenclature_change){ + let(:nomenclature_change) { nc = create(:nomenclature_change, :status => NomenclatureChange::NEW) nc.status = NomenclatureChange::SUBMITTED nc } - specify{ expect(nomenclature_change).to be_submitting } + specify { expect(nomenclature_change).to be_submitting } end context "when updating object with status submitted -> closed" do - let(:nomenclature_change){ + let(:nomenclature_change) { nc = create(:nomenclature_change, :status => NomenclatureChange::SUBMITTED) nc.status = NomenclatureChange::CLOSED nc } - specify{ expect(nomenclature_change).not_to be_submitting } + specify { expect(nomenclature_change).not_to be_submitting } end context "when updating object with status closed -> submitted" do - let(:nomenclature_change){ + let(:nomenclature_change) { nc = create(:nomenclature_change, :status => NomenclatureChange::CLOSED) nc.status = NomenclatureChange::SUBMITTED nc } - specify{ expect(nomenclature_change).not_to be_submitting } + specify { expect(nomenclature_change).not_to be_submitting } end end end diff --git a/spec/models/preset_tag_spec.rb b/spec/models/preset_tag_spec.rb index 9af813c973..15f521fba9 100644 --- a/spec/models/preset_tag_spec.rb +++ b/spec/models/preset_tag_spec.rb @@ -14,16 +14,16 @@ describe PresetTag do describe :create do context "when valid" do - let(:preset_tag){ build(:preset_tag, :name => 'Test Tag', :model => 'TaxonConcept') } + let(:preset_tag) { build(:preset_tag, :name => 'Test Tag', :model => 'TaxonConcept') } specify { preset_tag.should be_valid } end context "when name missing" do - let(:preset_tag){ build(:preset_tag, :name => nil, :model => 'TaxonConcept') } + let(:preset_tag) { build(:preset_tag, :name => nil, :model => 'TaxonConcept') } specify { preset_tag.should be_invalid } specify { preset_tag.should have(1).error_on(:name) } end context "when model (type) incorrect" do - let(:preset_tag){ build(:preset_tag, :name => 'Test Tag', :model => 'Nope') } + let(:preset_tag) { build(:preset_tag, :name => 'Test Tag', :model => 'Nope') } specify { preset_tag.should be_invalid } specify { preset_tag.should have(1).error_on(:model) } end diff --git a/spec/models/purpose_spec.rb b/spec/models/purpose_spec.rb index aed80360d3..89987b3533 100644 --- a/spec/models/purpose_spec.rb +++ b/spec/models/purpose_spec.rb @@ -17,13 +17,13 @@ describe Purpose do describe :destroy do context "when no dependent objects attached" do - let(:purpose){ create(:purpose) } + let(:purpose) { create(:purpose) } specify { purpose.destroy.should be_true } end context "when dependent objects attached" do - let(:purpose){ create(:purpose) } + let(:purpose) { create(:purpose) } context "when CITES suspension" do - let!(:cites_suspension){ + let!(:cites_suspension) { create( :cites_suspension, :purposes => [purpose], @@ -33,7 +33,7 @@ specify { purpose.destroy.should be_false } end context "when shipments" do - before(:each){ create(:shipment, :purpose => purpose) } + before(:each) { create(:shipment, :purpose => purpose) } specify { purpose.destroy.should be_false } end end diff --git a/spec/models/quota_spec.rb b/spec/models/quota_spec.rb index 15040ec040..3a9a42592a 100644 --- a/spec/models/quota_spec.rb +++ b/spec/models/quota_spec.rb @@ -70,7 +70,7 @@ end context "when valid" do - let(:quota){ + let(:quota) { build( :quota, :unit => @unit, @@ -83,7 +83,7 @@ end context "when quota missing" do - let(:quota1){ + let(:quota1) { build( :quota, :quota => nil, @@ -97,7 +97,7 @@ end context "when publication date missing" do - let(:quota){ + let(:quota) { build( :quota, :publication_date => nil, @@ -111,7 +111,7 @@ end context "when start date greater than end date" do - let(:quota){ + let(:quota) { build( :quota, :start_date => 1.week.from_now, @@ -126,7 +126,7 @@ end pending "doesn't save a quota without a unit" do - let(:quota){ + let(:quota) { build( :quota, :unit => nil, diff --git a/spec/models/rank_spec.rb b/spec/models/rank_spec.rb index b430c04479..a9aabc8d71 100644 --- a/spec/models/rank_spec.rb +++ b/spec/models/rank_spec.rb @@ -28,13 +28,13 @@ end describe :create do context "when taxonomic position malformed" do - let(:rank){ build(:rank, name: Rank::PHYLUM, taxonomic_position: '1.a.b') } + let(:rank) { build(:rank, name: Rank::PHYLUM, taxonomic_position: '1.a.b') } specify { rank.should have(1).error_on(:taxonomic_position) } end end describe :destroy do context "when no dependent objects attached" do - let(:rank){ + let(:rank) { r = create(:rank, name: Rank::PHYLUM, taxonomic_position: '1.1') r.update_attribute(:name, 'SUPER PHYLUM') r @@ -42,27 +42,27 @@ specify { rank.destroy.should be_true } end context "when dependent objects attached" do - let(:rank){ create(:rank, name: Rank::PHYLUM, taxonomic_position: '1.1') } - let!(:taxon_concept){ create(:taxon_concept, :rank => rank) } + let(:rank) { create(:rank, name: Rank::PHYLUM, taxonomic_position: '1.1') } + let!(:taxon_concept) { create(:taxon_concept, :rank => rank) } specify { rank.destroy.should be_false } end context "when protected name" do - let(:rank){ create(:rank, name: Rank::PHYLUM, taxonomic_position: '1.1') } + let(:rank) { create(:rank, name: Rank::PHYLUM, taxonomic_position: '1.1') } specify { rank.destroy.should be_false } end end describe :in_range do context "when no bounds specified" do - subject{ Rank.in_range(nil, nil) } - specify{ subject.should == Rank.dict } + subject { Rank.in_range(nil, nil) } + specify { subject.should == Rank.dict } end context "when lower bound specified" do - subject{ Rank.in_range(Rank::CLASS, nil) } - specify{ subject.should == [Rank::KINGDOM, Rank::PHYLUM, Rank::CLASS] } + subject { Rank.in_range(Rank::CLASS, nil) } + specify { subject.should == [Rank::KINGDOM, Rank::PHYLUM, Rank::CLASS] } end context "when lower and upper bound specified" do - subject{ Rank.in_range(Rank::GENUS, Rank::FAMILY) } - specify{ subject.should == [Rank::FAMILY, Rank::SUBFAMILY, Rank::GENUS] } + subject { Rank.in_range(Rank::GENUS, Rank::FAMILY) } + specify { subject.should == [Rank::FAMILY, Rank::SUBFAMILY, Rank::GENUS] } end end end diff --git a/spec/models/sapi/geoip_spec.rb b/spec/models/sapi/geoip_spec.rb index 948c60fe2c..2ac1e05243 100644 --- a/spec/models/sapi/geoip_spec.rb +++ b/spec/models/sapi/geoip_spec.rb @@ -2,7 +2,7 @@ describe Sapi::GeoIP do describe :resolve do - subject{ Sapi::GeoIP.instance } + subject { Sapi::GeoIP.instance } before(:each) do bogota_latin1 = "Bogotá".encode('ISO-8859-1', 'UTF-8') subject.stub(:country_and_city).and_return( @@ -12,6 +12,6 @@ } ) end - specify{ subject.resolve('1.1.1.1')[:city].should == 'Bogotá' } + specify { subject.resolve('1.1.1.1')[:city].should == 'Bogotá' } end end diff --git a/spec/models/source_spec.rb b/spec/models/source_spec.rb index 9c9da9a240..aa3b90d265 100644 --- a/spec/models/source_spec.rb +++ b/spec/models/source_spec.rb @@ -17,13 +17,13 @@ describe Source do describe :destroy do context "when no dependent objects attached" do - let(:source){ create(:source) } + let(:source) { create(:source) } specify { source.destroy.should be_true } end context "when dependent objects attached" do - let(:source){ create(:source) } + let(:source) { create(:source) } context "when CITES suspension" do - let!(:cites_suspension){ + let!(:cites_suspension) { create( :cites_suspension, :sources => [source], @@ -34,7 +34,7 @@ end context "when CITES quota" do let(:geo_entity) { create(:geo_entity) } - let!(:quota){ create(:quota, :sources => [source], :geo_entity_id => geo_entity.id) } + let!(:quota) { create(:quota, :sources => [source], :geo_entity_id => geo_entity.id) } specify { source.destroy.should be_false } end context "when shipments" do diff --git a/spec/models/species/common_names_export_spec.rb b/spec/models/species/common_names_export_spec.rb index ba133190fe..cfc1b1857e 100644 --- a/spec/models/species/common_names_export_spec.rb +++ b/spec/models/species/common_names_export_spec.rb @@ -14,7 +14,7 @@ specify { subject.export.should be_false } end context "when results" do - before(:each){ + before(:each) { species = create_cites_eu_species FileUtils.mkpath( File.expand_path("spec/public/downloads/common_names") @@ -22,7 +22,7 @@ Species::CommonNamesExport.any_instance.stub(:path). and_return("spec/public/downloads/common_names/") } - after(:each){ + after(:each) { FileUtils.remove_dir("spec/public/downloads/common_names", true) } subject { diff --git a/spec/models/species/documents_export_spec.rb b/spec/models/species/documents_export_spec.rb index bb172e3d8c..48d9273b55 100644 --- a/spec/models/species/documents_export_spec.rb +++ b/spec/models/species/documents_export_spec.rb @@ -19,7 +19,7 @@ FileUtils.remove_dir("#{SPEC_DOCUMENTS_DOWNLOAD_PATH}", true) end context "when no results" do - before(:each){ + before(:each) { FileUtils.rm_rf(Dir.glob("#{SPEC_DOCUMENTS_DOWNLOAD_PATH}/*")) } subject { @@ -30,7 +30,7 @@ end end context "when results" do - before(:each){ + before(:each) { ActiveRecord::Relation.any_instance.stub(:any?).and_return(true) } subject { diff --git a/spec/models/species/listings_export_spec.rb b/spec/models/species/listings_export_spec.rb index b19ed91fde..346a54b8d5 100644 --- a/spec/models/species/listings_export_spec.rb +++ b/spec/models/species/listings_export_spec.rb @@ -21,14 +21,14 @@ specify { subject.export.should be_false } end context "when results" do - before(:each){ + before(:each) { FileUtils.mkpath( File.expand_path("spec/public/downloads/cites_listings") ) Species::ListingsExport.any_instance.stub(:path). and_return("spec/public/downloads/cites_listings/") } - after(:each){ + after(:each) { FileUtils.remove_dir("spec/public/downloads/cites_listings", true) } subject { diff --git a/spec/models/species/orphaned_taxon_concepts_export_spec.rb b/spec/models/species/orphaned_taxon_concepts_export_spec.rb index 5643104881..aa394cd69b 100644 --- a/spec/models/species/orphaned_taxon_concepts_export_spec.rb +++ b/spec/models/species/orphaned_taxon_concepts_export_spec.rb @@ -14,7 +14,7 @@ specify { subject.export.should be_false } end context "when results" do - before(:each){ + before(:each) { tc = create(:taxon_concept) tc.update_attribute(:parent_id, nil) #skipping validations FileUtils.mkpath( @@ -23,7 +23,7 @@ Species::OrphanedTaxonConceptsExport.any_instance.stub(:path). and_return("spec/public/downloads/orphaned_taxon_concepts/") } - after(:each){ + after(:each) { FileUtils.remove_dir("spec/public/downloads/orphaned_taxon_concepts", true) } subject { diff --git a/spec/models/species/species_reference_output_spec.rb b/spec/models/species/species_reference_output_spec.rb index 9ca763873f..3d8385c828 100644 --- a/spec/models/species/species_reference_output_spec.rb +++ b/spec/models/species/species_reference_output_spec.rb @@ -14,7 +14,7 @@ specify { subject.export.should be_false } end context "when results" do - before(:each){ + before(:each) { species = create_cites_eu_species FileUtils.mkpath( File.expand_path("spec/public/downloads/species_reference_output") @@ -22,7 +22,7 @@ Species::SpeciesReferenceOutputExport.any_instance.stub(:path). and_return("spec/public/downloads/species_reference_output/") } - after(:each){ + after(:each) { FileUtils.remove_dir("spec/public/downloads/species_reference_output", true) } subject { diff --git a/spec/models/species/standard_reference_output_spec.rb b/spec/models/species/standard_reference_output_spec.rb index 257ce05b23..440e14eb5c 100644 --- a/spec/models/species/standard_reference_output_spec.rb +++ b/spec/models/species/standard_reference_output_spec.rb @@ -14,7 +14,7 @@ specify { subject.export.should be_false } end context "when results" do - before(:each){ + before(:each) { species = create_cites_eu_species FileUtils.mkpath( File.expand_path("spec/public/downloads/standard_reference_output") @@ -22,7 +22,7 @@ Species::StandardReferenceOutputExport.any_instance.stub(:path). and_return("spec/public/downloads/standard_reference_output/") } - after(:each){ + after(:each) { FileUtils.remove_dir("spec/public/downloads/standard_reference_output", true) } subject { diff --git a/spec/models/species/synonyms_and_trade_names_export_spec.rb b/spec/models/species/synonyms_and_trade_names_export_spec.rb index 53667d23ae..3610e45a2c 100644 --- a/spec/models/species/synonyms_and_trade_names_export_spec.rb +++ b/spec/models/species/synonyms_and_trade_names_export_spec.rb @@ -14,7 +14,7 @@ specify { subject.export.should be_false } end context "when results" do - before(:each){ + before(:each) { species = create_cites_eu_species synonym = create_cites_eu_species(:name_status => 'S') create(:taxon_relationship, @@ -28,7 +28,7 @@ Species::SynonymsAndTradeNamesExport.any_instance.stub(:path). and_return("spec/public/downloads/synonyms_and_trade_names/") } - after(:each){ + after(:each) { FileUtils.remove_dir("spec/public/downloads/synonyms_and_trade_names", true) } subject { diff --git a/spec/models/species/taxon_concepts_export_spec.rb b/spec/models/species/taxon_concepts_export_spec.rb index c76b1fc2cf..5cb03d82c0 100644 --- a/spec/models/species/taxon_concepts_export_spec.rb +++ b/spec/models/species/taxon_concepts_export_spec.rb @@ -14,7 +14,7 @@ specify { subject.export.should be_false } end context "when results" do - before(:each){ + before(:each) { create(:taxon_concept) FileUtils.mkpath( File.expand_path("spec/public/downloads/taxon_concepts_names") @@ -22,7 +22,7 @@ Species::TaxonConceptsNamesExport.any_instance.stub(:path). and_return("spec/public/downloads/taxon_concepts_names/") } - after(:each){ + after(:each) { FileUtils.remove_dir("spec/public/downloads/taxon_concepts_names", true) } subject { diff --git a/spec/models/synonym_relationship_spec.rb b/spec/models/synonym_relationship_spec.rb index c1f618035b..53b8390ee0 100644 --- a/spec/models/synonym_relationship_spec.rb +++ b/spec/models/synonym_relationship_spec.rb @@ -2,38 +2,38 @@ describe TaxonRelationship do context "when synonymy" do - let(:parent){ + let(:parent) { create_cites_eu_genus( :taxon_name => create(:taxon_name, :scientific_name => 'Lolcatus') ) } - let!(:tc){ + let!(:tc) { create_cites_eu_species( :parent_id => parent.id, :taxon_name => create(:taxon_name, :scientific_name => 'lolatus') ) } - let!(:another_tc){ + let!(:another_tc) { create_cites_eu_species( :parent_id => parent.id, :taxon_name => create(:taxon_name, :scientific_name => 'lolcatus') ) } - let(:synonym){ + let(:synonym) { create_cites_eu_species( name_status: 'S', author_year: 'Hemulen 2013', scientific_name: 'Lolcatus lolus' ) } - let(:another_synonym){ + let(:another_synonym) { create_cites_eu_species( name_status: 'S', author_year: 'Hemulen 2013', scientific_name: 'Lolcatus lolatus' ) } - let(:synonymy_rel){ + let(:synonymy_rel) { build( :taxon_relationship, taxon_relationship_type: synonym_relationship_type, @@ -41,7 +41,7 @@ other_taxon_concept_id: synonym.id ) } - let(:another_synonymy_rel){ + let(:another_synonymy_rel) { build( :taxon_relationship, taxon_relationship_type: synonym_relationship_type, @@ -53,7 +53,7 @@ synonymy_rel.save tc.synonyms.map(&:full_name).should include('Lolcatus lolus') } - specify{ + specify { synonymy_rel.save another_synonymy_rel.save synonymy_rel.other_taxon_concept = another_synonym diff --git a/spec/models/taxon_common_spec.rb b/spec/models/taxon_common_spec.rb index 30bd671425..8ad96fce02 100644 --- a/spec/models/taxon_common_spec.rb +++ b/spec/models/taxon_common_spec.rb @@ -15,27 +15,27 @@ describe TaxonCommon do describe :update do - let(:language){ + let(:language) { create(:language) } - let(:parent){ + let(:parent) { create_cites_eu_genus( :taxon_name => create(:taxon_name, :scientific_name => 'Lolcatus') ) } - let!(:tc){ + let!(:tc) { create_cites_eu_species( :parent_id => parent.id, :taxon_name => create(:taxon_name, :scientific_name => 'lolatus') ) } - let!(:another_tc){ + let!(:another_tc) { create_cites_eu_species( :parent_id => parent.id, :taxon_name => create(:taxon_name, :scientific_name => 'lolcatus') ) } - let(:tc_common){ + let(:tc_common) { build( :taxon_common, :taxon_concept_id => tc.id, @@ -44,7 +44,7 @@ ) } context "when common name changed" do - let(:another_tc_common){ + let(:another_tc_common) { build( :taxon_common, :taxon_concept_id => another_tc.id, @@ -52,7 +52,7 @@ :language_id => language.id ) } - specify{ + specify { tc_common.save another_tc_common.save tc_common.name = "Black lolcat" diff --git a/spec/models/taxon_concept/boa_constrictor_spec.rb b/spec/models/taxon_concept/boa_constrictor_spec.rb index 25d0bd981a..b9af29d4ff 100644 --- a/spec/models/taxon_concept/boa_constrictor_spec.rb +++ b/spec/models/taxon_concept/boa_constrictor_spec.rb @@ -6,25 +6,25 @@ context "TAXONOMY" do describe :full_name do context "for subspecies Boa constrictor occidentalis" do - specify{ @subspecies1.full_name.should == 'Boa constrictor occidentalis' } + specify { @subspecies1.full_name.should == 'Boa constrictor occidentalis' } end context "for species Boa constrictor" do - specify{ @species.full_name.should == 'Boa constrictor' } + specify { @species.full_name.should == 'Boa constrictor' } end context "for genus Boa" do - specify{ @genus.full_name.should == 'Boa' } + specify { @genus.full_name.should == 'Boa' } end end describe :ancestors do context "family" do - specify{ @species.family_name.should == 'Boidae' } + specify { @species.family_name.should == 'Boidae' } end context "order" do - specify{ @species.order_name.should == 'Serpentes' } + specify { @species.order_name.should == 'Serpentes' } end context "class" do - specify{ @species.class_name.should == 'Reptilia' } + specify { @species.class_name.should == 'Reptilia' } end end end @@ -32,127 +32,127 @@ context "LISTING" do describe :cites_listing do context "for subspecies Boa constrictor occidentalis" do - specify{ @subspecies1.cites_listing.should == 'I' } + specify { @subspecies1.cites_listing.should == 'I' } end context "for subspecies Boa constrictor constrictor" do - specify{ @subspecies2.cites_listing.should == 'II' } + specify { @subspecies2.cites_listing.should == 'II' } end context "for species Boa constrictor" do - specify{ @species.cites_listing.should == 'I/II' } + specify { @species.cites_listing.should == 'I/II' } end end describe :eu_listing do context "for subspecies Boa constrictor occidentalis" do - specify{ @subspecies1.eu_listing.should == 'A' } + specify { @subspecies1.eu_listing.should == 'A' } end context "for subspecies Boa constrictor constrictor" do - specify{ @subspecies2.eu_listing.should == 'B' } + specify { @subspecies2.eu_listing.should == 'B' } end context "for species Boa constrictor" do - specify{ @species.eu_listing.should == 'A/B' } + specify { @species.eu_listing.should == 'A/B' } end end describe :cites_listed do context "for family Boidae" do - specify{ @family.cites_listed.should be_true } + specify { @family.cites_listed.should be_true } end context "for genus Boa" do - specify{ @genus.cites_listed.should == false } + specify { @genus.cites_listed.should == false } end context "for species Boa constrictor (inclusion in higher taxa listing)" do - specify{ @species.cites_listed.should == false } + specify { @species.cites_listed.should == false } end context "for subspecies Boa constrictor occidentalis" do - specify{ @subspecies1.cites_listed.should be_true } + specify { @subspecies1.cites_listed.should be_true } end context "for subspecies Boa constrictor constrictor" do - specify{ @subspecies2.cites_listed.should be_false } + specify { @subspecies2.cites_listed.should be_false } end end describe :cites_show do context "for family Boidae" do - specify{ @family.cites_show.should be_true } + specify { @family.cites_show.should be_true } end context "for genus Boa" do - specify{ @genus.cites_show.should be_true } + specify { @genus.cites_show.should be_true } end context "for species Boa constrictor (inclusion in higher taxa listing)" do - specify{ @species.cites_show.should be_true } + specify { @species.cites_show.should be_true } end context "for subspecies Boa constrictor occidentalis" do - specify{ @subspecies1.cites_show.should be_true } + specify { @subspecies1.cites_show.should be_true } end context "for subspecies Boa constrictor constrictor" do - specify{ @subspecies2.cites_show.should be_false } + specify { @subspecies2.cites_show.should be_false } end end describe :cites_listed_descendants do context "for family Boidae" do - specify{ @family.cites_listed_descendants.should be_true } + specify { @family.cites_listed_descendants.should be_true } end context "for genus Boa" do - specify{ @genus.cites_listed_descendants.should be_true } + specify { @genus.cites_listed_descendants.should be_true } end context "for species Boa constrictor (inclusion in higher taxa listing)" do - specify{ @species.cites_listed_descendants.should be_true } + specify { @species.cites_listed_descendants.should be_true } end context "for subspecies Boa constrictor occidentalis" do - specify{ @subspecies1.cites_listed_descendants.should be_false } + specify { @subspecies1.cites_listed_descendants.should be_false } end end describe :eu_listed do context "for family Boidae" do - specify{ @family.eu_listed.should be_true } + specify { @family.eu_listed.should be_true } end context "for genus Boa" do - specify{ @genus.eu_listed.should == false } + specify { @genus.eu_listed.should == false } end context "for species Boa constrictor (inclusion in higher taxa listing)" do - specify{ @species.eu_listed.should == false } + specify { @species.eu_listed.should == false } end context "for subspecies Boa constrictor occidentalis" do - specify{ @subspecies1.eu_listed.should be_true } + specify { @subspecies1.eu_listed.should be_true } end end describe :show_in_species_plus_ac do context "for family Boidae" do - specify{ @family_ac.show_in_species_plus_ac.should be_true } + specify { @family_ac.show_in_species_plus_ac.should be_true } end context "for genus Boa" do - specify{ @genus_ac.show_in_species_plus_ac.should be_true } + specify { @genus_ac.show_in_species_plus_ac.should be_true } end context "for species Boa constrictor (inclusion in higher taxa listing)" do - specify{ @species_ac.show_in_species_plus_ac.should be_true } + specify { @species_ac.show_in_species_plus_ac.should be_true } end context "for subspecies Boa constrictor occidentalis" do - specify{ @subspecies1_ac.show_in_species_plus_ac.should be_true } + specify { @subspecies1_ac.show_in_species_plus_ac.should be_true } end context "for subspecies Boa constrictor constrictor" do - specify{ @subspecies2_ac.show_in_species_plus_ac.should be_false } + specify { @subspecies2_ac.show_in_species_plus_ac.should be_false } end end describe :show_in_checklist_ac do context "for family Boidae" do - specify{ @family_ac.show_in_checklist_ac.should be_true } + specify { @family_ac.show_in_checklist_ac.should be_true } end context "for genus Boa" do - specify{ @genus_ac.show_in_checklist_ac.should be_true } + specify { @genus_ac.show_in_checklist_ac.should be_true } end context "for species Boa constrictor (inclusion in higher taxa listing)" do - specify{ @species_ac.show_in_checklist_ac.should be_true } + specify { @species_ac.show_in_checklist_ac.should be_true } end context "for subspecies Boa constrictor occidentalis" do - specify{ @subspecies1_ac.show_in_checklist_ac.should be_true } + specify { @subspecies1_ac.show_in_checklist_ac.should be_true } end context "for subspecies Boa constrictor constrictor" do - specify{ @subspecies2_ac.show_in_checklist_ac.should be_false } + specify { @subspecies2_ac.show_in_checklist_ac.should be_false } end end diff --git a/spec/models/taxon_concept/callback_spec.rb b/spec/models/taxon_concept/callback_spec.rb index c9be1e7d72..ba30719aa6 100644 --- a/spec/models/taxon_concept/callback_spec.rb +++ b/spec/models/taxon_concept/callback_spec.rb @@ -2,37 +2,37 @@ describe TaxonConcept do context 'before validate' do - let(:kingdom_tc){ + let(:kingdom_tc) { create_cites_eu_kingdom( taxonomic_position: '1' ) } context 'taxonomic position not given for fixed order rank' do - let(:tc){ + let(:tc) { create_cites_eu_phylum( parent_id: kingdom_tc.id, taxonomic_position: nil ) } - specify{ expect(tc.taxonomic_position).to eq('1.1') } + specify { expect(tc.taxonomic_position).to eq('1.1') } end context 'taxonomic position given for fixed order rank' do - let(:tc){ + let(:tc) { create_cites_eu_phylum( parent_id: kingdom_tc.id, taxonomic_position: '1.2' ) } - specify{ expect(tc.taxonomic_position).to eq('1.2') } + specify { expect(tc.taxonomic_position).to eq('1.2') } end context 'taxonomic position not given for fixed order root rank' do - let(:tc){ + let(:tc) { create_cites_eu_kingdom( taxonomic_position: nil ) } - specify{ expect(tc.taxonomic_position).to eq('1') } + specify { expect(tc.taxonomic_position).to eq('1') } end end diff --git a/spec/models/taxon_concept/canis_lupus_spec.rb b/spec/models/taxon_concept/canis_lupus_spec.rb index e2a260a06b..1989717e6c 100644 --- a/spec/models/taxon_concept/canis_lupus_spec.rb +++ b/spec/models/taxon_concept/canis_lupus_spec.rb @@ -6,55 +6,55 @@ context "LISTING" do describe :cites_listing do context "for species Canis lupus (population split listing)" do - specify{ @species.cites_listing.should == 'I/II' } + specify { @species.cites_listing.should == 'I/II' } end end describe :eu_listing do context "for species Canis lupus (population split listing)" do - specify{ @species.eu_listing.should == 'A/B' } + specify { @species.eu_listing.should == 'A/B' } end end describe :cites_listed do context "for species Canis lupus" do - specify{ @species.cites_listed.should be_true } + specify { @species.cites_listed.should be_true } end context "for subspecies Canis lupus crassodon" do - specify{ @subspecies.cites_listed.should be_blank } + specify { @subspecies.cites_listed.should be_blank } end end describe :eu_listed do context "for species Canis lupus" do - specify{ @species.eu_listed.should be_true } + specify { @species.eu_listed.should be_true } end end describe :show_in_species_plus_ac do context "for species Canis lupus" do - specify{ @species_ac.show_in_species_plus_ac.should be_true } + specify { @species_ac.show_in_species_plus_ac.should be_true } end context "for subspecies Canis lupus crassodon" do - specify{ @subspecies_ac.show_in_species_plus_ac.should be_true } + specify { @subspecies_ac.show_in_species_plus_ac.should be_true } end end describe :show_in_checklist_ac do context "for species Canis lupus" do - specify{ @species_ac.show_in_checklist_ac.should be_true } + specify { @species_ac.show_in_checklist_ac.should be_true } end context "for subspecies Canis lupus crassodon" do - specify{ @subspecies_ac.show_in_checklist_ac.should be_false } + specify { @subspecies_ac.show_in_checklist_ac.should be_false } end end describe :show_in_species_plus do context "for species Canis lupus" do - specify{ @species.show_in_species_plus.should be_true } + specify { @species.show_in_species_plus.should be_true } end context "for subspecies Canis lupus crassodon" do - specify{ @subspecies.show_in_species_plus.should be_true } + specify { @subspecies.show_in_species_plus.should be_true } end end diff --git a/spec/models/taxon_concept/caretta_caretta_cms_spec.rb b/spec/models/taxon_concept/caretta_caretta_cms_spec.rb index 8bc0826385..9dd14b22e2 100644 --- a/spec/models/taxon_concept/caretta_caretta_cms_spec.rb +++ b/spec/models/taxon_concept/caretta_caretta_cms_spec.rb @@ -7,19 +7,19 @@ context "LISTING" do describe :cms_listing do context "for family Cheloniidae" do - specify{ @family.cms_listing.should == 'I/II' } + specify { @family.cms_listing.should == 'I/II' } end context "for species Caretta caretta" do - specify{ @species.cms_listing.should == 'I/II' } + specify { @species.cms_listing.should == 'I/II' } end end describe :cms_listed do context "for family Cheloniidae" do - specify{ @family.cms_listed.should be_true } + specify { @family.cms_listed.should be_true } end context "for species Caretta caretta" do - specify{ @species.cms_listed.should be_true } + specify { @species.cms_listed.should be_true } end end end diff --git a/spec/models/taxon_concept/cervus_elaphus_cms_spec.rb b/spec/models/taxon_concept/cervus_elaphus_cms_spec.rb index 6b3cb132b3..cbc98cc4b8 100644 --- a/spec/models/taxon_concept/cervus_elaphus_cms_spec.rb +++ b/spec/models/taxon_concept/cervus_elaphus_cms_spec.rb @@ -7,7 +7,7 @@ context "LISTING" do describe :cms_listing do context "for species Cervus elaphus" do - specify{ @species.cms_listing.should == 'I/II' } + specify { @species.cms_listing.should == 'I/II' } end context "for subspecies Cervus elaphus bactrianus" do specify { @subspecies1.cms_listing.should == 'I/II' } @@ -19,19 +19,19 @@ describe :show_in_species_plus_ac do context "for subspecies Cervus elaphus bactrianus (instrument)" do - specify{ @subspecies1_ac.show_in_species_plus_ac.should be_true } + specify { @subspecies1_ac.show_in_species_plus_ac.should be_true } end context "for subspecies Cervus elaphus barbarus (listing)" do - specify{ @subspecies2_ac.show_in_species_plus_ac.should be_true } + specify { @subspecies2_ac.show_in_species_plus_ac.should be_true } end end describe :show_in_species_plus do context "for subspecies Cervus elaphus bactrianus (instrument)" do - specify{ @subspecies1.show_in_species_plus.should be_true } + specify { @subspecies1.show_in_species_plus.should be_true } end context "for subspecies Cervus elaphus barbarus (listing)" do - specify{ @subspecies2.show_in_species_plus.should be_true } + specify { @subspecies2.show_in_species_plus.should be_true } end end diff --git a/spec/models/taxon_concept/destroy_spec.rb b/spec/models/taxon_concept/destroy_spec.rb index fd29bd25df..91427f20f5 100644 --- a/spec/models/taxon_concept/destroy_spec.rb +++ b/spec/models/taxon_concept/destroy_spec.rb @@ -4,58 +4,58 @@ describe TaxonConcept do describe :destroy do context "general" do - before(:each){ @taxon_concept = create_cms_species } + before(:each) { @taxon_concept = create_cms_species } context "when no dependent objects attached" do specify { @taxon_concept.destroy.should be_true } end context "when distributions" do - before(:each){ create(:distribution, :taxon_concept => @taxon_concept) } + before(:each) { create(:distribution, :taxon_concept => @taxon_concept) } specify { @taxon_concept.destroy.should be_true } end context "when common names" do - before(:each){ create(:taxon_common, :taxon_concept => @taxon_concept) } + before(:each) { create(:taxon_common, :taxon_concept => @taxon_concept) } specify { @taxon_concept.destroy.should be_true } end context "when references" do - before(:each){ create(:taxon_concept_reference, :taxon_concept => @taxon_concept) } + before(:each) { create(:taxon_concept_reference, :taxon_concept => @taxon_concept) } specify { @taxon_concept.destroy.should be_true } end end context "CMS" do - before(:each){ @taxon_concept = create_cms_species } + before(:each) { @taxon_concept = create_cms_species } context "when taxon instruments" do - before(:each){ create(:taxon_instrument, :taxon_concept => @taxon_concept) } + before(:each) { create(:taxon_instrument, :taxon_concept => @taxon_concept) } specify { @taxon_concept.destroy.should be_false } end end context "CITES / EU" do - before(:each){ @taxon_concept = create_cites_eu_species } + before(:each) { @taxon_concept = create_cites_eu_species } context "when listing changes" do - before(:each){ create_cites_I_addition(:taxon_concept => @taxon_concept) } + before(:each) { create_cites_I_addition(:taxon_concept => @taxon_concept) } specify { @taxon_concept.destroy.should be_false } end context "when CITES quotas" do - before(:each){ create(:quota, :taxon_concept => @taxon_concept, :geo_entity => create(:geo_entity)) } + before(:each) { create(:quota, :taxon_concept => @taxon_concept, :geo_entity => create(:geo_entity)) } specify { @taxon_concept.destroy.should be_false } end context "when CITES suspensions" do - before(:each){ create(:cites_suspension, :taxon_concept => @taxon_concept, :start_notification => create(:cites_suspension_notification, :designation => cites)) } + before(:each) { create(:cites_suspension, :taxon_concept => @taxon_concept, :start_notification => create(:cites_suspension_notification, :designation => cites)) } specify { @taxon_concept.destroy.should be_false } end context "when EU opinions" do - before(:each){ create(:eu_opinion, :taxon_concept => @taxon_concept) } + before(:each) { create(:eu_opinion, :taxon_concept => @taxon_concept) } specify { @taxon_concept.destroy.should be_false } end context "when EU suspensions" do - before(:each){ create(:eu_suspension, :taxon_concept => @taxon_concept) } + before(:each) { create(:eu_suspension, :taxon_concept => @taxon_concept) } specify { @taxon_concept.destroy.should be_false } end context "when shipments" do - before(:each){ create(:shipment, :taxon_concept => @taxon_concept) } + before(:each) { create(:shipment, :taxon_concept => @taxon_concept) } specify { @taxon_concept.destroy.should be_false } end context "when reported shipments" do - before(:each){ create(:shipment, :reported_taxon_concept => @taxon_concept) } + before(:each) { create(:shipment, :reported_taxon_concept => @taxon_concept) } specify { @taxon_concept.destroy.should be_false } end end diff --git a/spec/models/taxon_concept/hybrids_spec.rb b/spec/models/taxon_concept/hybrids_spec.rb index 035ea1b6f5..41136da6b7 100644 --- a/spec/models/taxon_concept/hybrids_spec.rb +++ b/spec/models/taxon_concept/hybrids_spec.rb @@ -1,27 +1,27 @@ require 'spec_helper' describe TaxonConcept do - before(:each){ hybrid_relationship_type } + before(:each) { hybrid_relationship_type } describe :create do - let(:parent){ + let(:parent) { create_cites_eu_genus( :taxon_name => create(:taxon_name, :scientific_name => 'Lolcatus') ) } - let!(:tc){ + let!(:tc) { create_cites_eu_species( :parent_id => parent.id, :taxon_name => create(:taxon_name, :scientific_name => 'lolatus') ) } - let(:hybrid){ + let(:hybrid) { create_cites_eu_species( name_status: 'H', author_year: 'Taxonomus 2013', taxon_name: create(:taxon_name, :scientific_name => 'Lolcatus lolcatus x lolatus') ) } - let!(:hybrid_rel){ + let!(:hybrid_rel) { create(:taxon_relationship, taxon_relationship_type: hybrid_relationship_type, taxon_concept_id: tc.id, @@ -35,7 +35,7 @@ specify { hybrid.is_hybrid?.should be_true } - specify{ + specify { hybrid.has_hybrid_parents?.should be_true } specify { @@ -43,7 +43,7 @@ } end context "when duplicate" do - let(:duplicate){ + let(:duplicate) { hybrid.dup } specify { @@ -53,7 +53,7 @@ } end context "when duplicate but author name different" do - let(:duplicate){ + let(:duplicate) { res = hybrid.dup res.author_year = 'Hemulen 2013' res diff --git a/spec/models/taxon_concept/loxodonta_africana_cms_spec.rb b/spec/models/taxon_concept/loxodonta_africana_cms_spec.rb index 36f33b0494..77e381da98 100644 --- a/spec/models/taxon_concept/loxodonta_africana_cms_spec.rb +++ b/spec/models/taxon_concept/loxodonta_africana_cms_spec.rb @@ -6,26 +6,26 @@ context "TAXONOMY" do describe :full_name do context "for species Loxodonta africana" do - specify{ @species.full_name.should == 'Loxodonta africana' } + specify { @species.full_name.should == 'Loxodonta africana' } end context "for genus Loxodonta" do - specify{ @genus.full_name.should == 'Loxodonta' } + specify { @genus.full_name.should == 'Loxodonta' } end end describe :rank do context "for species Loxodonta africana" do - specify{ @species.rank_name.should == 'SPECIES' } + specify { @species.rank_name.should == 'SPECIES' } end end describe :ancestors do context "family" do - specify{ @species.family_name.should == 'Elephantidae' } + specify { @species.family_name.should == 'Elephantidae' } end context "order" do - specify{ @species.order_name.should == 'Proboscidea' } + specify { @species.order_name.should == 'Proboscidea' } end context "class" do - specify{ @species.class_name.should == 'Mammalia' } + specify { @species.class_name.should == 'Mammalia' } end end end @@ -33,13 +33,13 @@ context "LISTING" do describe :cms_listing do context "for species Loxodonta africana" do - specify{ @species.cms_listing.should == 'II' } + specify { @species.cms_listing.should == 'II' } end end describe :cms_listed do context "for species Loxodonta africana" do - specify{ @species.cms_listed.should be_true } + specify { @species.cms_listed.should be_true } end end end diff --git a/spec/models/taxon_concept/loxodonta_africana_spec.rb b/spec/models/taxon_concept/loxodonta_africana_spec.rb index d450a1fdfd..bbe8112290 100644 --- a/spec/models/taxon_concept/loxodonta_africana_spec.rb +++ b/spec/models/taxon_concept/loxodonta_africana_spec.rb @@ -6,26 +6,26 @@ context "TAXONOMY" do describe :full_name do context "for species Loxodonta africana" do - specify{ @species.full_name.should == 'Loxodonta africana' } + specify { @species.full_name.should == 'Loxodonta africana' } end context "for genus Loxodonta" do - specify{ @genus.full_name.should == 'Loxodonta' } + specify { @genus.full_name.should == 'Loxodonta' } end end describe :rank do context "for species Loxodonta africana" do - specify{ @species.rank_name.should == 'SPECIES' } + specify { @species.rank_name.should == 'SPECIES' } end end describe :ancestors do context "family" do - specify{ @species.family_name == 'Elephantidae' } + specify { @species.family_name == 'Elephantidae' } end context "order" do - specify{ @species.order_name == 'Proboscidea' } + specify { @species.order_name == 'Proboscidea' } end context "class" do - specify{ @species.class_name == 'Mammalia' } + specify { @species.class_name == 'Mammalia' } end end end @@ -33,31 +33,31 @@ context "LISTING" do describe :cites_listing do context "for species Loxodonta africana (population split listing)" do - specify{ @species.cites_listing.should == 'I/II' } + specify { @species.cites_listing.should == 'I/II' } end end describe :eu_listing do context "for species Loxodonta africana (population split listing)" do - specify{ @species.eu_listing.should == 'A/B' } + specify { @species.eu_listing.should == 'A/B' } end end describe :cites_listed do context "for species Loxodonta africana" do - specify{ @species.cites_listed.should be_true } + specify { @species.cites_listed.should be_true } end context "for family Elephantidae" do - specify{ @family.cites_listed.should == false } + specify { @family.cites_listed.should == false } end end describe :eu_listed do context "for species Loxodonta africana" do - specify{ @species.eu_listed.should be_true } + specify { @species.eu_listed.should be_true } end context "for family Elephantidae" do - specify{ @family.eu_listed.should == false } + specify { @family.eu_listed.should == false } end end diff --git a/spec/models/taxon_concept/natator_depressus_spec.rb b/spec/models/taxon_concept/natator_depressus_spec.rb index 893462ffa5..498c9a0e92 100644 --- a/spec/models/taxon_concept/natator_depressus_spec.rb +++ b/spec/models/taxon_concept/natator_depressus_spec.rb @@ -7,10 +7,10 @@ context "LISTING" do describe :cites_listing do context "for family Cheloniidae" do - specify{ @family.cites_listing.should == 'I' } + specify { @family.cites_listing.should == 'I' } end context "for species Natator depressus" do - specify{ @species.cites_listing.should == 'I' } + specify { @species.cites_listing.should == 'I' } end end diff --git a/spec/models/taxon_concept/notomys_aquilo_spec.rb b/spec/models/taxon_concept/notomys_aquilo_spec.rb index 8b5cf748ab..4b15a183ce 100644 --- a/spec/models/taxon_concept/notomys_aquilo_spec.rb +++ b/spec/models/taxon_concept/notomys_aquilo_spec.rb @@ -7,19 +7,19 @@ context "LISTING" do describe :cites_listing do context "for genus Notomys" do - specify{ @genus.cites_listing.should == 'NC' } + specify { @genus.cites_listing.should == 'NC' } end context "for species Notomys aquilo" do - specify{ @species.cites_listing.should == 'NC' } + specify { @species.cites_listing.should == 'NC' } end end describe :cites_show do context "for genus Notomys" do - specify{ @genus.cites_show.should be_false } + specify { @genus.cites_show.should be_false } end context "for species Notomys aquilo" do - specify{ @species.cites_show.should be_false } + specify { @species.cites_show.should be_false } end end diff --git a/spec/models/taxon_concept/pseudomys_fieldi_spec.rb b/spec/models/taxon_concept/pseudomys_fieldi_spec.rb index dbb82079d6..6f1a12eaae 100644 --- a/spec/models/taxon_concept/pseudomys_fieldi_spec.rb +++ b/spec/models/taxon_concept/pseudomys_fieldi_spec.rb @@ -7,28 +7,28 @@ context "LISTING" do describe :cites_listing do context "for subspecies Pseudomys fieldi preaconis" do - specify{ @subspecies.cites_listing.should == 'I' } + specify { @subspecies.cites_listing.should == 'I' } end context "for species Pseudomys fieldi" do - specify{ @species.cites_listing.should == 'I/NC' } + specify { @species.cites_listing.should == 'I/NC' } end end describe :eu_listing do context "for subspecies Pseudomys fieldi preaconis" do - specify{ @subspecies.eu_listing.should == 'A' } + specify { @subspecies.eu_listing.should == 'A' } end context "for species Pseudomys fieldi" do - specify{ @species.eu_listing.should == 'A/NC' } + specify { @species.eu_listing.should == 'A/NC' } end end describe :cites_show do context "for subspecies Pseudomys fieldi preaconis" do - specify{ @subspecies.cites_show.should be_true } + specify { @subspecies.cites_show.should be_true } end context "for species Pseudomys fieldi" do - specify{ @species.cites_show.should be_true } + specify { @species.cites_show.should be_true } end end diff --git a/spec/models/taxon_concept/synonyms_spec.rb b/spec/models/taxon_concept/synonyms_spec.rb index f636f8dafa..62ab80a417 100644 --- a/spec/models/taxon_concept/synonyms_spec.rb +++ b/spec/models/taxon_concept/synonyms_spec.rb @@ -1,27 +1,27 @@ require 'spec_helper' describe TaxonConcept do - before(:each){ synonym_relationship_type } + before(:each) { synonym_relationship_type } describe :create do - let(:parent){ + let(:parent) { create_cites_eu_genus( :taxon_name => create(:taxon_name, :scientific_name => 'Lolcatus') ) } - let!(:tc){ + let!(:tc) { create_cites_eu_species( :parent_id => parent.id, :taxon_name => create(:taxon_name, :scientific_name => 'lolatus') ) } - let(:synonym){ + let(:synonym) { create_cites_eu_species( :name_status => 'S', :author_year => 'Taxonomus 2013', taxon_name: create(:taxon_name, scientific_name: 'Lolcatus lolus') ) } - let!(:synonym_rel){ + let!(:synonym_rel) { create(:taxon_relationship, taxon_relationship_type: synonym_relationship_type, taxon_concept_id: tc.id, @@ -35,7 +35,7 @@ specify { synonym.is_synonym?.should be_true } - specify{ + specify { synonym.has_accepted_names?.should be_true } specify { @@ -43,7 +43,7 @@ } end context "when duplicate" do - let(:duplicate){ + let(:duplicate) { synonym.dup } specify { @@ -53,7 +53,7 @@ } end context "when duplicate but author name different" do - let(:duplicate){ + let(:duplicate) { res = synonym.dup res.author_year = 'Hemulen 2013' res diff --git a/spec/models/taxon_concept/trade_names_spec.rb b/spec/models/taxon_concept/trade_names_spec.rb index 527114a158..c15fb7585f 100644 --- a/spec/models/taxon_concept/trade_names_spec.rb +++ b/spec/models/taxon_concept/trade_names_spec.rb @@ -1,27 +1,27 @@ require 'spec_helper' describe TaxonConcept do - before(:each){ trade_name_relationship_type } + before(:each) { trade_name_relationship_type } describe :create do - let(:parent){ + let(:parent) { create_cites_eu_genus( :taxon_name => create(:taxon_name, :scientific_name => 'Lolcatus') ) } - let!(:tc){ + let!(:tc) { create_cites_eu_species( :parent_id => parent.id, :taxon_name => create(:taxon_name, :scientific_name => 'lolatus') ) } - let(:trade_name){ + let(:trade_name) { create_cites_eu_species( :name_status => 'T', :author_year => 'Taxonomus 2014', taxon_name: create(:taxon_name, scientific_name: 'Lolcatus lolus') ) } - let!(:trade_name_rel){ + let!(:trade_name_rel) { create(:taxon_relationship, taxon_relationship_type: trade_name_relationship_type, taxon_concept_id: tc.id, @@ -35,7 +35,7 @@ specify { trade_name.is_trade_name?.should be_true } - specify{ + specify { trade_name.has_accepted_names_for_trade_name?.should be_true } specify { @@ -43,7 +43,7 @@ } end context "when duplicate" do - let(:duplicate){ + let(:duplicate) { trade_name.dup } specify { @@ -53,7 +53,7 @@ } end context "when duplicate but author name different" do - let(:duplicate){ + let(:duplicate) { res = trade_name.dup res.author_year = 'Hemulen 2013' res diff --git a/spec/models/taxon_concept/validation_spec.rb b/spec/models/taxon_concept/validation_spec.rb index 917b261e57..6252319c5a 100644 --- a/spec/models/taxon_concept/validation_spec.rb +++ b/spec/models/taxon_concept/validation_spec.rb @@ -2,7 +2,7 @@ describe TaxonConcept do context "create" do - let(:kingdom_tc){ + let(:kingdom_tc) { create_kingdom( :taxonomy_id => cites_eu.id, :taxonomic_position => '1', @@ -10,13 +10,13 @@ ) } context "all fine" do - let(:tc){ + let(:tc) { create_phylum( :taxonomy_id => cites_eu.id, :parent_id => kingdom_tc.id ) } - specify{ tc.valid? should be_true } + specify { tc.valid? should be_true } end context "taxonomy does not match parent" do let(:tc) { @@ -28,7 +28,7 @@ specify { tc.should have(1).error_on(:parent_id) } end context "parent is not an accepted name" do - let(:genus_tc){ + let(:genus_tc) { create_genus( :taxonomy_id => cites_eu.id, :name_status => 'S' @@ -77,7 +77,7 @@ specify { tc.should have(1).error_on(:taxon_name_id) } end context "when taxonomic position malformed" do - let(:tc){ + let(:tc) { build_phylum( :taxonomy_id => cites_eu.id, :parent_id => kingdom_tc.id, @@ -87,7 +87,7 @@ specify { tc.should have(1).error_on(:taxonomic_position) } end context "when full name is already given" do - let(:tc_parent){ create_cites_eu_species } + let(:tc_parent) { create_cites_eu_species } let!(:tc1) { create_cites_eu_subspecies( parent: tc_parent, diff --git a/spec/models/taxon_concept_data_spec.rb b/spec/models/taxon_concept_data_spec.rb index 0ab4de1a2e..25244e5a37 100644 --- a/spec/models/taxon_concept_data_spec.rb +++ b/spec/models/taxon_concept_data_spec.rb @@ -3,38 +3,38 @@ describe TaxonConceptData do describe :to_h do - let(:family){ + let(:family) { create_cites_eu_family( taxon_name: create(:taxon_name, scientific_name: 'Canidae') ) } - let(:genus){ + let(:genus) { create_cites_eu_genus( taxon_name: create(:taxon_name, scientific_name: 'Canis'), parent: family ) } - let(:accepted_species){ + let(:accepted_species) { create_cites_eu_species(parent: genus) } - let(:tcd_to_h){ TaxonConceptData.new(taxon_concept).to_h } + let(:tcd_to_h) { TaxonConceptData.new(taxon_concept).to_h } context "when regular accepted name" do - let(:taxon_concept){ + let(:taxon_concept) { create_cites_eu_subspecies(parent: accepted_species) } specify { expect(tcd_to_h["family_name"]).to eq('Canidae') } end context "when N accepted name" do - let(:taxon_concept){ + let(:taxon_concept) { create_cites_eu_subspecies(name_status: 'N', parent: accepted_species) } specify { expect(tcd_to_h["family_name"]).to eq('Canidae') } end context "when hybrid" do - let(:taxon_concept){ + let(:taxon_concept) { create_cites_eu_subspecies(name_status: 'H') } - let!(:hybrid_parent_relationship){ + let!(:hybrid_parent_relationship) { create(:taxon_relationship, taxon_relationship_type: hybrid_relationship_type, taxon_concept: accepted_species, @@ -44,10 +44,10 @@ specify { expect(tcd_to_h["family_name"]).to eq('Canidae') } end context "when synonym" do - let(:taxon_concept){ + let(:taxon_concept) { create_cites_eu_subspecies(name_status: 'S') } - let!(:hybrid_parent_relationship){ + let!(:hybrid_parent_relationship) { create(:taxon_relationship, taxon_relationship_type: synonym_relationship_type, taxon_concept: accepted_species, @@ -57,10 +57,10 @@ specify { expect(tcd_to_h["family_name"]).to eq('Canidae') } end context "when trade name" do - let(:taxon_concept){ + let(:taxon_concept) { create_cites_eu_subspecies(name_status: 'T') } - let!(:hybrid_parent_relationship){ + let!(:hybrid_parent_relationship) { create(:taxon_relationship, taxon_relationship_type: trade_name_relationship_type, taxon_concept: accepted_species, diff --git a/spec/models/taxon_concept_prefix_matcher_spec.rb b/spec/models/taxon_concept_prefix_matcher_spec.rb index 83c5ae29c9..709e3c75e5 100644 --- a/spec/models/taxon_concept_prefix_matcher_spec.rb +++ b/spec/models/taxon_concept_prefix_matcher_spec.rb @@ -1,38 +1,38 @@ require 'spec_helper' describe TaxonConceptPrefixMatcher do - let(:taxonomy){ cites_eu } + let(:taxonomy) { cites_eu } - let!(:taxon_concept1){ + let!(:taxon_concept1) { create_cites_eu_order( taxon_name: create(:taxon_name, scientific_name: 'Aaa') ) } - let!(:taxon_concept2){ + let!(:taxon_concept2) { create_cites_eu_family( taxon_name: create(:taxon_name, scientific_name: 'Aac'), parent: taxon_concept1 ) } - let!(:taxon_concept3){ + let!(:taxon_concept3) { create_cites_eu_subfamily( taxon_name: create(:taxon_name, scientific_name: 'Aab'), parent: taxon_concept2 ) } - let!(:taxon_concept4){ + let!(:taxon_concept4) { create_cites_eu_genus( taxon_name: create(:taxon_name, scientific_name: 'Abb'), parent: taxon_concept3 ) } - let!(:taxon_concept4_sibling){ + let!(:taxon_concept4_sibling) { create_cites_eu_genus( taxon_name: create(:taxon_name, scientific_name: 'Aaab'), parent: taxon_concept3 ) } - let!(:hybrid){ + let!(:hybrid) { tmp = create_cites_eu_genus( taxon_name: create(:taxon_name, scientific_name: 'Abc'), name_status: 'H' @@ -46,102 +46,102 @@ tmp } context "when name status not specified" do - let(:matcher_params){ + let(:matcher_params) { SearchParams.new(:taxonomy => { :id => taxonomy.id }, :scientific_name => 'Ab') } - let(:matcher){ TaxonConceptPrefixMatcher.new matcher_params } - specify{ matcher.taxon_concepts.should include(taxon_concept4) } - specify{ matcher.taxon_concepts.should_not include(hybrid) } + let(:matcher) { TaxonConceptPrefixMatcher.new matcher_params } + specify { matcher.taxon_concepts.should include(taxon_concept4) } + specify { matcher.taxon_concepts.should_not include(hybrid) } end context "when name status H" do - let(:matcher_params){ + let(:matcher_params) { SearchParams.new(:taxonomy => { :id => taxonomy.id }, :scientific_name => 'Ab', :name_status => 'H') } - let(:matcher){ TaxonConceptPrefixMatcher.new matcher_params } - specify{ matcher.taxon_concepts.should_not include(taxon_concept4) } - specify{ matcher.taxon_concepts.should include(hybrid) } + let(:matcher) { TaxonConceptPrefixMatcher.new matcher_params } + specify { matcher.taxon_concepts.should_not include(taxon_concept4) } + specify { matcher.taxon_concepts.should include(hybrid) } end context "when rank scope applied" do - let(:parent_matcher_params){ + let(:parent_matcher_params) { SearchParams.new( :taxonomy => { :id => taxonomy.id }, :rank => { :id => taxon_concept4.rank_id, :scope => :parent }, :scientific_name => 'A' ) } - let(:parent_matcher){ + let(:parent_matcher) { TaxonConceptPrefixMatcher.new parent_matcher_params } - specify{ + specify { parent_matcher.taxon_concepts.map(&:full_name).should == ['Aab', 'Aac'] } - let(:ancestor_matcher_params){ + let(:ancestor_matcher_params) { SearchParams.new( :taxonomy => { :id => taxonomy.id }, :rank => { :id => taxon_concept4.rank_id, :scope => :ancestors }, :scientific_name => 'AAA' ) } - let(:ancestor_matcher){ + let(:ancestor_matcher) { TaxonConceptPrefixMatcher.new ancestor_matcher_params } - specify{ + specify { ancestor_matcher.taxon_concepts.map(&:full_name).should == ['Aaa'] } - let(:self_and_ancestor_matcher_params){ + let(:self_and_ancestor_matcher_params) { SearchParams.new( :taxonomy => { :id => taxonomy.id }, :rank => { :id => taxon_concept4.rank_id, :scope => :self_and_ancestors }, :scientific_name => 'AAA' ) } - let(:self_and_ancestor_matcher){ + let(:self_and_ancestor_matcher) { TaxonConceptPrefixMatcher.new self_and_ancestor_matcher_params } - specify{ + specify { self_and_ancestor_matcher.taxon_concepts.map(&:full_name).should == ['Aaa', 'Aaab'] } end context "when taxon concept scope applied" do - let(:ancestor_matcher_params){ + let(:ancestor_matcher_params) { SearchParams.new( :taxonomy => { :id => taxonomy.id }, :taxon_concept => { :id => taxon_concept4.id, :scope => :ancestors }, :scientific_name => 'A' ) } - let(:ancestor_matcher){ + let(:ancestor_matcher) { TaxonConceptPrefixMatcher.new ancestor_matcher_params } - specify{ + specify { ancestor_matcher.taxon_concepts.map(&:full_name).should == ['Aaa', 'Aab', 'Aac'] } - let(:descendant_matcher_params){ + let(:descendant_matcher_params) { SearchParams.new( :taxonomy => { :id => taxonomy.id }, :taxon_concept => { :id => taxon_concept2.id, :scope => :descendants }, :scientific_name => 'A' ) } - let(:descendant_matcher){ + let(:descendant_matcher) { TaxonConceptPrefixMatcher.new descendant_matcher_params } - specify{ + specify { descendant_matcher.taxon_concepts.map(&:full_name).should == ['Aaab', 'Aab', 'Abb'] } diff --git a/spec/models/taxonomy_spec.rb b/spec/models/taxonomy_spec.rb index 3d53e0577d..b8adf359eb 100644 --- a/spec/models/taxonomy_spec.rb +++ b/spec/models/taxonomy_spec.rb @@ -13,38 +13,38 @@ describe Taxonomy do describe :create do context "when valid" do - let(:taxonomy){ build(:taxonomy, :name => 'WILDLIFE') } + let(:taxonomy) { build(:taxonomy, :name => 'WILDLIFE') } specify { taxonomy.should be_valid } end context "when name missing" do - let(:taxonomy){ build(:taxonomy, :name => nil) } + let(:taxonomy) { build(:taxonomy, :name => nil) } specify { taxonomy.should be_invalid } specify { taxonomy.should have(1).error_on(:name) } end context "when name duplicated" do - let!(:taxonomy1){ create(:taxonomy) } - let(:taxonomy2){ build(:taxonomy, :name => taxonomy1.name) } + let!(:taxonomy1) { create(:taxonomy) } + let(:taxonomy2) { build(:taxonomy, :name => taxonomy1.name) } specify { taxonomy2.should be_invalid } specify { taxonomy2.should have(1).error_on(:name) } end end describe :update do context "when updating a non-protected name" do - let(:taxonomy){ create(:taxonomy) } - specify{ taxonomy.update_attributes({ :name => 'WORLD OF LOLCATS' }).should be_true } + let(:taxonomy) { create(:taxonomy) } + specify { taxonomy.update_attributes({ :name => 'WORLD OF LOLCATS' }).should be_true } end context "when updating a protected name" do - specify{ cites_eu.update_attributes({ :name => 'WORLD OF LOLCATS' }).should be_false } + specify { cites_eu.update_attributes({ :name => 'WORLD OF LOLCATS' }).should be_false } end end describe :destroy do context "when no dependent objects attached" do - let(:taxonomy){ create(:taxonomy, :name => 'WILDLIFE') } + let(:taxonomy) { create(:taxonomy, :name => 'WILDLIFE') } specify { taxonomy.destroy.should be_true } end context "when dependent objects attached" do - let(:taxonomy){ create(:taxonomy, :name => 'WILDLIFE') } - let!(:designation){ create(:designation, :taxonomy => taxonomy) } + let(:taxonomy) { create(:taxonomy, :name => 'WILDLIFE') } + let!(:designation) { create(:designation, :taxonomy => taxonomy) } specify { taxonomy.destroy.should be_false } end context "when protected name" do diff --git a/spec/models/term_spec.rb b/spec/models/term_spec.rb index fb79a814e5..a633dbd3c2 100644 --- a/spec/models/term_spec.rb +++ b/spec/models/term_spec.rb @@ -17,13 +17,13 @@ describe Term do describe :destroy do context "when no dependent objects attached" do - let(:term){ create(:term) } + let(:term) { create(:term) } specify { term.destroy.should be_true } end context "when dependent objects attached" do - let(:term){ create(:term) } + let(:term) { create(:term) } context "when CITES suspension" do - let!(:cites_suspension){ + let!(:cites_suspension) { create( :cites_suspension, :terms => [term], @@ -34,11 +34,11 @@ end context "when CITES quota" do let(:geo_entity) { create(:geo_entity) } - let!(:quota){ create(:quota, :terms => [term], :geo_entity_id => geo_entity.id) } + let!(:quota) { create(:quota, :terms => [term], :geo_entity_id => geo_entity.id) } specify { term.destroy.should be_false } end context "when shipments" do - before(:each){ create(:shipment, :term => term) } + before(:each) { create(:shipment, :term => term) } specify { term.destroy.should be_false } end end diff --git a/spec/models/trade/annual_report_upload_spec.rb b/spec/models/trade/annual_report_upload_spec.rb index 272002dd3a..6a8377a7f5 100644 --- a/spec/models/trade/annual_report_upload_spec.rb +++ b/spec/models/trade/annual_report_upload_spec.rb @@ -44,7 +44,7 @@ def invalid_file end describe :valid? do context "when uploaded file as exporter with exporter column headers" do - subject{ + subject { build( :annual_report_upload, :point_of_view => 'E', @@ -54,7 +54,7 @@ def invalid_file specify { subject.should be_valid } end context "when uploaded file as importer with exporter column headers" do - subject{ + subject { build( :annual_report_upload, :point_of_view => 'I', @@ -64,7 +64,7 @@ def invalid_file specify { subject.should_not be_valid } end context "when uploaded file as importer with importer column headers" do - subject{ + subject { build( :annual_report_upload, :point_of_view => 'I', @@ -74,7 +74,7 @@ def invalid_file specify { subject.should be_valid } end context "when uploaded file as exporter with importer column headers" do - subject{ + subject { build( :annual_report_upload, :point_of_view => 'E', @@ -86,23 +86,23 @@ def invalid_file end describe :validation_errors do - let!(:format_validation_rule){ + let!(:format_validation_rule) { create_year_format_validation } - subject{ + subject { create( :annual_report_upload, :point_of_view => 'I', :csv_source_file => importer_file ) } - specify{ subject.validation_errors.should be_empty } + specify { subject.validation_errors.should be_empty } end describe :create do - before(:each){ Trade::CsvSourceFileUploader.enable_processing = true } + before(:each) { Trade::CsvSourceFileUploader.enable_processing = true } context "when blank lines in import file" do - subject{ + subject { create( :annual_report_upload, :point_of_view => 'I', @@ -117,14 +117,14 @@ def invalid_file end describe :destroy do - subject{ + subject { create( :annual_report_upload, :point_of_view => 'I', :csv_source_file => importer_file ) } - specify{ + specify { subject.sandbox.should_receive(:destroy) subject.destroy } @@ -174,10 +174,10 @@ def invalid_file aru } specify { - expect{ subject.submit }.to change{ Trade::Shipment.count }.by(1) + expect { subject.submit }.to change { Trade::Shipment.count }.by(1) } specify { - expect{ subject.submit }.to change{ Trade::Permit.count }.by(3) + expect { subject.submit }.to change { Trade::Permit.count }.by(3) } specify { #make sure leading space is stripped subject.submit; Trade::Permit.find_by_number('BBB').should_not be_nil @@ -185,7 +185,7 @@ def invalid_file context "when permit previously reported" do before(:each) { create(:permit, :number => 'xxx') } specify { - expect{ subject.submit }.to change{ Trade::Permit.count }.by(2) + expect { subject.submit }.to change { Trade::Permit.count }.by(2) } end end @@ -205,7 +205,7 @@ def invalid_file aru } specify { - expect{ subject.submit }.not_to change{ Trade::Shipment.count } + expect { subject.submit }.not_to change { Trade::Shipment.count } } end context "when reported under a synonym" do @@ -239,7 +239,7 @@ def invalid_file aru } specify { - expect{ subject.submit }.to change{ Trade::Shipment.count }.by(1) + expect { subject.submit }.to change { Trade::Shipment.count }.by(1) } specify { subject.submit diff --git a/spec/models/trade/distinct_values_validation_rule_spec.rb b/spec/models/trade/distinct_values_validation_rule_spec.rb index da1783efa9..c8c66267c1 100644 --- a/spec/models/trade/distinct_values_validation_rule_spec.rb +++ b/spec/models/trade/distinct_values_validation_rule_spec.rb @@ -18,7 +18,7 @@ require 'spec_helper' describe Trade::DistinctValuesValidationRule, :drops_tables => true do - let(:canada){ + let(:canada) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -26,7 +26,7 @@ :iso_code2 => 'CA' ) } - let(:argentina){ + let(:argentina) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -46,10 +46,10 @@ @sandbox_klass.create(:trading_partner => argentina.iso_code2) @sandbox_klass.create(:trading_partner => canada.iso_code2) end - subject{ + subject { create_exporter_importer_validation } - specify{ + specify { subject.validation_errors(@aru).size.should == 1 } end @@ -62,10 +62,10 @@ @sandbox_klass.create(:trading_partner => argentina.iso_code2) @sandbox_klass.create(:trading_partner => canada.iso_code2) end - subject{ + subject { create_exporter_importer_validation } - specify{ + specify { subject.validation_errors(@aru).size.should == 1 } end @@ -74,10 +74,10 @@ @sandbox_klass.create(:country_of_origin => argentina.iso_code2) @sandbox_klass.create(:country_of_origin => canada.iso_code2) end - subject{ + subject { create_exporter_country_of_origin_validation } - specify{ + specify { subject.validation_errors(@aru).size.should == 1 } end diff --git a/spec/models/trade/filter_spec.rb b/spec/models/trade/filter_spec.rb index 2d766a7888..e11dd46883 100644 --- a/spec/models/trade/filter_spec.rb +++ b/spec/models/trade/filter_spec.rb @@ -4,7 +4,7 @@ describe :results do context "when searching by taxon concepts ids" do - before(:each){ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings } + before(:each) { Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings } context "in the public interface" do context "at GENUS rank" do subject { Trade::Filter.new({ @@ -105,7 +105,7 @@ end end context "when searching by reported taxon concepts ids" do - before(:each){ Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings } + before(:each) { Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings } context "when trade names shipments present" do before(:each) do @shipment_of_trade_name = create( diff --git a/spec/models/trade/inclusion_validation_rule_spec.rb b/spec/models/trade/inclusion_validation_rule_spec.rb index 7e5d10df1b..6db4957804 100644 --- a/spec/models/trade/inclusion_validation_rule_spec.rb +++ b/spec/models/trade/inclusion_validation_rule_spec.rb @@ -18,7 +18,7 @@ require 'spec_helper' describe Trade::InclusionValidationRule, :drops_tables => true do - let(:annual_report_upload){ + let(:annual_report_upload) { annual_report = build( :annual_report_upload, :point_of_view => 'E' @@ -26,7 +26,7 @@ annual_report.save(:validate => false) annual_report } - let(:sandbox_klass){ + let(:sandbox_klass) { Trade::SandboxTemplate.ar_klass(annual_report_upload.sandbox.table_name) } describe :validation_errors do @@ -40,7 +40,7 @@ :parent => genus ) end - subject{ + subject { create( :inclusion_validation_rule, :column_names => ['taxon_name'], @@ -48,7 +48,7 @@ :is_strict => true ) } - specify{ + specify { subject.validation_errors(annual_report_upload).should be_empty } end @@ -58,7 +58,7 @@ sandbox_klass.create(:trading_partner => '') sandbox_klass.create(:trading_partner => nil) end - let!(:france){ + let!(:france) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -66,7 +66,7 @@ :iso_code2 => 'FR' ) } - subject{ + subject { create( :inclusion_validation_rule, :column_names => ['trading_partner'], @@ -74,7 +74,7 @@ :is_strict => true ) } - specify{ + specify { subject.validation_errors(annual_report_upload).size.should == 1 } end @@ -97,10 +97,10 @@ before(:each) do sandbox_klass.create(:term_code => 'CAP', :unit_code => 'BAG') end - subject{ + subject { create_term_unit_validation } - specify{ + specify { subject.validation_errors(annual_report_upload).size.should == 1 } end @@ -108,10 +108,10 @@ before(:each) do sandbox_klass.create(:term_code => 'CAP', :unit_code => '') end - subject{ + subject { create_term_unit_validation } - specify{ + specify { subject.validation_errors(annual_report_upload).size.should == 1 } end @@ -127,10 +127,10 @@ sandbox_klass.create(:term_code => 'CAV', :purpose_code => 'P') sandbox_klass.create(:term_code => 'CAV', :purpose_code => '') end - subject{ + subject { create_term_purpose_validation } - specify{ + specify { subject.validation_errors(annual_report_upload).size.should == 2 } end @@ -141,7 +141,7 @@ create(:term, :code => "BAL") @pair = create(:trade_taxon_concept_term_pair, :term_id => cav.id, :taxon_concept_id => @genus.id) end - subject{ + subject { create_taxon_concept_term_validation } context "when accepted name" do @@ -150,7 +150,7 @@ sandbox_klass.create(:term_code => 'CAV', :taxon_name => @species.full_name) sandbox_klass.create(:term_code => 'BAL', :taxon_name => @species.full_name) end - specify{ + specify { subject.validation_errors(annual_report_upload).size.should == 1 } end @@ -166,7 +166,7 @@ sandbox_klass.create(:term_code => 'CAV', :taxon_name => @hybrid.full_name) sandbox_klass.create(:term_code => 'BAL', :taxon_name => @hybrid.full_name) end - specify{ + specify { subject.validation_errors(annual_report_upload).size.should == 1 } end diff --git a/spec/models/trade/pov_inclusion_validation_rule_spec.rb b/spec/models/trade/pov_inclusion_validation_rule_spec.rb index a5f66d76c6..19610240eb 100644 --- a/spec/models/trade/pov_inclusion_validation_rule_spec.rb +++ b/spec/models/trade/pov_inclusion_validation_rule_spec.rb @@ -17,7 +17,7 @@ require 'spec_helper' describe Trade::InclusionValidationRule, :drops_tables => true do - let(:canada){ + let(:canada) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -25,7 +25,7 @@ :iso_code2 => 'CA' ) } - let(:argentina){ + let(:argentina) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -33,7 +33,7 @@ :iso_code2 => 'AR' ) } - let(:xx){ + let(:xx) { create( :geo_entity, :geo_entity_type => trade_geo_entity_type, @@ -68,10 +68,10 @@ :taxon_name => 'Pecari tajacu', :source_code => 'W', :country_of_origin => argentina.iso_code2 ) end - subject{ + subject { create_taxon_concept_exporter_validation } - specify{ + specify { subject.validation_errors(@aru).size.should == 1 } end @@ -90,10 +90,10 @@ :country_of_origin => argentina.iso_code2 ) end - subject{ + subject { create_taxon_concept_exporter_validation } - specify{ + specify { subject.validation_errors(@aru).size.should == 1 } end @@ -112,10 +112,10 @@ :country_of_origin => argentina.iso_code2 ) end - subject{ + subject { create_taxon_concept_exporter_validation } - specify{ + specify { subject.validation_errors(@aru).should be_empty } end @@ -134,10 +134,10 @@ :country_of_origin => canada.iso_code2 ) end - subject{ + subject { create_taxon_concept_exporter_validation } - specify{ + specify { subject.validation_errors(@aru).should be_empty } end @@ -150,11 +150,11 @@ :taxon_name => 'Pecari tajacu', :source_code => 'W', :country_of_origin => argentina.iso_code2 ) end - subject{ + subject { create_taxon_concept_exporter_validation } - specify{ - expect{ subject.validation_errors(@aru) }.to_not raise_error(ActiveRecord::StatementInvalid) + specify { + expect { subject.validation_errors(@aru) }.to_not raise_error(ActiveRecord::StatementInvalid) } end end diff --git a/spec/models/trade/reported_taxon_concept_resolver_spec.rb b/spec/models/trade/reported_taxon_concept_resolver_spec.rb index e2e1c9a160..2b12a97e4c 100644 --- a/spec/models/trade/reported_taxon_concept_resolver_spec.rb +++ b/spec/models/trade/reported_taxon_concept_resolver_spec.rb @@ -14,10 +14,10 @@ :taxon_relationship_type => trade_name_relationship_type ) end - let(:resolver){ + let(:resolver) { Trade::ReportedTaxonConceptResolver.new(@trade_name.id) } - specify{ expect(resolver.accepted_taxa).to include(@accepted_name) } + specify { expect(resolver.accepted_taxa).to include(@accepted_name) } end context "resolving synonyms" do @@ -33,20 +33,20 @@ :taxon_relationship_type => synonym_relationship_type ) end - let(:resolver){ + let(:resolver) { Trade::ReportedTaxonConceptResolver.new(@synonym.id) } - specify{ expect(resolver.accepted_taxa).to include(@accepted_name) } + specify { expect(resolver.accepted_taxa).to include(@accepted_name) } end context "resolving accepted names" do before(:each) do @accepted_name = create_cites_eu_species end - let(:resolver){ + let(:resolver) { Trade::ReportedTaxonConceptResolver.new(@accepted_name.id) } - specify{ expect(resolver.accepted_taxa).to include(@accepted_name) } + specify { expect(resolver.accepted_taxa).to include(@accepted_name) } end end diff --git a/spec/models/trade/sandbox_spec.rb b/spec/models/trade/sandbox_spec.rb index 67bc762720..90f5267ceb 100644 --- a/spec/models/trade/sandbox_spec.rb +++ b/spec/models/trade/sandbox_spec.rb @@ -24,7 +24,7 @@ :iso_code2 => 'PT' ) end - let(:annual_report_upload){ + let(:annual_report_upload) { aru = build(:annual_report_upload, :trading_country_id => @argentina.id, :point_of_view => 'I') aru.save(:validate => false) sandbox_klass = Trade::SandboxTemplate.ar_klass(aru.sandbox.table_name) diff --git a/spec/models/trade/sandbox_template_spec.rb b/spec/models/trade/sandbox_template_spec.rb index e2341c4eb8..77d1a40874 100644 --- a/spec/models/trade/sandbox_template_spec.rb +++ b/spec/models/trade/sandbox_template_spec.rb @@ -23,26 +23,26 @@ require 'spec_helper' describe Trade::SandboxTemplate, :drops_tables => true do - let(:annual_report_upload){ + let(:annual_report_upload) { aru = build(:annual_report_upload) aru.save(:validate => false) aru } - let(:sandbox_klass){ + let(:sandbox_klass) { Trade::SandboxTemplate.ar_klass(annual_report_upload.sandbox.table_name) } - let(:canis){ + let(:canis) { create_cites_eu_genus( :taxon_name => create(:taxon_name, :scientific_name => 'Canis') ) } - let(:canis_lupus){ + let(:canis_lupus) { create_cites_eu_species( :taxon_name => create(:taxon_name, :scientific_name => 'lupus'), :parent => canis ) } - let(:canis_aureus){ + let(:canis_aureus) { create_cites_eu_species( :taxon_name => create(:taxon_name, :scientific_name => 'aureus'), :parent => canis diff --git a/spec/models/trade/scoped_inclusion_validation_rule_spec.rb b/spec/models/trade/scoped_inclusion_validation_rule_spec.rb index c2b0f1dbdb..1d9b324a38 100644 --- a/spec/models/trade/scoped_inclusion_validation_rule_spec.rb +++ b/spec/models/trade/scoped_inclusion_validation_rule_spec.rb @@ -15,10 +15,10 @@ :taxon_name => 'Pecari tajacu', :source_code => 'W', :country_of_origin => 'AR' ) end - subject{ + subject { create_taxon_concept_country_of_origin_validation } - specify{ + specify { subject.validation_errors(@aru).size.should == 0 } end @@ -30,7 +30,7 @@ :taxon_name => 'Pecari tajacu', :source_code => 'W', :country_of_origin => 'PL' ) end - subject{ + subject { create_taxon_concept_country_of_origin_validation } end @@ -42,10 +42,10 @@ :taxon_name => 'Pecari tajacu', :source_code => 'W', :country_of_origin => nil ) end - subject{ + subject { create_taxon_concept_country_of_origin_validation } - specify{ + specify { subject.validation_errors(@aru).size.should == 0 } end diff --git a/spec/models/trade/shipment_spec.rb b/spec/models/trade/shipment_spec.rb index 3154d4069e..db17cf86e7 100644 --- a/spec/models/trade/shipment_spec.rb +++ b/spec/models/trade/shipment_spec.rb @@ -113,31 +113,31 @@ create_taxon_concept_appendix_year_validation end context "invalid" do - subject{ + subject { create( :shipment, :taxon_concept => @taxon_concept, :appendix => 'II', :year => 2013 ) } - specify{ subject.warnings.should_not be_empty } + specify { subject.warnings.should_not be_empty } end context "invalid" do - subject{ + subject { create( :shipment, :taxon_concept => @taxon_concept, :appendix => 'N', :year => 2013 ) } - specify{ subject.warnings.should_not be_empty } + specify { subject.warnings.should_not be_empty } end context "valid" do - subject{ + subject { create( :shipment, :taxon_concept => @taxon_concept, :appendix => 'I', :year => 2013 ) } - specify{ subject.warnings.should be_empty } + specify { subject.warnings.should be_empty } end end @@ -153,13 +153,13 @@ create_taxon_concept_appendix_year_validation end context "valid" do - subject{ + subject { create( :shipment, :taxon_concept => @taxon_concept, :appendix => 'N', :year => 2013 ) } - specify{ subject.warnings.should be_empty } + specify { subject.warnings.should be_empty } end end @@ -173,13 +173,13 @@ create_taxon_concept_appendix_year_validation end context "not CITES listed and not EU listed" do - subject{ + subject { create( :shipment, :taxon_concept => @taxon_concept, :appendix => 'N', :year => 2013 ) } - specify{ subject.warnings.should_not be_empty } + specify { subject.warnings.should_not be_empty } end end @@ -198,7 +198,7 @@ create_term_unit_validation end context "invalid" do - subject{ + subject { create( :shipment, :term => @cav, :unit => @bag @@ -207,7 +207,7 @@ specify { subject.warnings.should_not be_empty } end context "valid" do - subject{ + subject { create( :shipment, :term => @cav, :unit => @kil @@ -216,7 +216,7 @@ specify { subject.warnings.should be_empty } end context "blank unit is valid" do - subject{ + subject { create( :shipment, :term => @cav, :unit => nil @@ -225,7 +225,7 @@ specify { subject.warnings.should be_empty } end context "blank unit is invalid" do - subject{ + subject { create( :shipment, :term => @cap, :unit => nil @@ -244,7 +244,7 @@ create_term_purpose_validation end context "invalid" do - subject{ + subject { create( :shipment, :term => @cav, :purpose => @b @@ -253,7 +253,7 @@ specify { subject.warnings.should_not be_empty } end context "valid" do - subject{ + subject { create( :shipment, :term => @cav, :purpose => @p @@ -272,7 +272,7 @@ create_taxon_concept_term_validation end context "invalid" do - subject{ + subject { create( :shipment, :taxon_concept => @taxon_concept, :term => @cav @@ -281,7 +281,7 @@ specify { subject.warnings.should_not be_empty } end context "valid" do - subject{ + subject { create( :shipment, :taxon_concept => @taxon_concept, :term => @bal @@ -295,7 +295,7 @@ create_taxon_concept_country_of_origin_validation end context "invalid" do - subject{ + subject { create( :shipment, :source => @wild, @@ -306,7 +306,7 @@ specify { subject.warnings.should_not be_empty } end context "valid" do - subject{ + subject { create( :shipment, :source => @wild, @@ -317,7 +317,7 @@ specify { subject.warnings.should be_empty } end context "blank" do - subject{ + subject { create( :shipment, :source => @wild, @@ -333,7 +333,7 @@ create_taxon_concept_exporter_validation end context "invalid" do - subject{ + subject { create( :shipment, :source => @wild, @@ -345,7 +345,7 @@ specify { subject.warnings.should_not be_empty } end context "valid" do - subject{ + subject { create( :shipment, :source => @wild, @@ -357,7 +357,7 @@ specify { subject.warnings.should be_empty } end context "valid with XX" do - subject{ + subject { create( :shipment, :source => @wild, @@ -374,7 +374,7 @@ create_exporter_country_of_origin_validation end context "invalid" do - subject{ + subject { create( :shipment, :taxon_concept => @taxon_concept, @@ -385,7 +385,7 @@ specify { subject.warnings.should_not be_empty } end context "valid" do - subject{ + subject { create( :shipment, :taxon_concept => @taxon_concept, @@ -401,7 +401,7 @@ create_exporter_importer_validation end context "invalid" do - subject{ + subject { create( :shipment, :taxon_concept => @taxon_concept, @@ -412,7 +412,7 @@ specify { subject.warnings.should_not be_empty } end context "valid" do - subject{ + subject { create( :shipment, :taxon_concept => @taxon_concept, @@ -433,7 +433,7 @@ @taxon_concept.reload end context "invalid" do - subject{ + subject { create( :shipment, :taxon_concept => @taxon_concept, @@ -443,7 +443,7 @@ specify { subject.warnings.should_not be_empty } end context "valid" do - subject{ + subject { create( :shipment, :taxon_concept => @taxon_concept, diff --git a/spec/models/trade/shipments_comptab_export_spec.rb b/spec/models/trade/shipments_comptab_export_spec.rb index 05aa76c3cd..ecc44ff46e 100644 --- a/spec/models/trade/shipments_comptab_export_spec.rb +++ b/spec/models/trade/shipments_comptab_export_spec.rb @@ -9,22 +9,22 @@ describe :total_cnt do context "when internal" do subject { Trade::ShipmentsComptabExport.new(:internal => true, :per_page => 4) } - specify{ subject.total_cnt.should == 4 } + specify { subject.total_cnt.should == 4 } end context "when public" do subject { Trade::ShipmentsComptabExport.new(:internal => false, :per_page => 3) } - specify{ subject.total_cnt.should == 4 } + specify { subject.total_cnt.should == 4 } end end describe :query do context "when internal" do subject { Trade::ShipmentsComptabExport.new(:internal => true, :per_page => 4) } - specify{ subject.query.ntuples.should == 4 } + specify { subject.query.ntuples.should == 4 } end context "when public" do subject { Trade::ShipmentsComptabExport.new(:internal => false, :per_page => 3) } - specify{ subject.query.ntuples.should == 3 } + specify { subject.query.ntuples.should == 3 } end end diff --git a/spec/models/trade/shipments_export_spec.rb b/spec/models/trade/shipments_export_spec.rb index d44b2e30df..22c1c896a0 100644 --- a/spec/models/trade/shipments_export_spec.rb +++ b/spec/models/trade/shipments_export_spec.rb @@ -9,22 +9,22 @@ describe :total_cnt do context "when internal" do subject { Trade::ShipmentsExport.new(:internal => true, :per_page => 4) } - specify{ subject.total_cnt.should == 4 } + specify { subject.total_cnt.should == 4 } end context "when public" do subject { Trade::ShipmentsExport.new(:internal => false, :per_page => 3) } - specify{ subject.total_cnt.should == 4 } + specify { subject.total_cnt.should == 4 } end end describe :query do context "when internal" do subject { Trade::ShipmentsExport.new(:internal => true, :per_page => 4) } - specify{ subject.query.ntuples.should == 4 } + specify { subject.query.ntuples.should == 4 } end context "when public" do subject { Trade::ShipmentsExport.new(:internal => false, :per_page => 3) } - specify{ subject.query.ntuples.should == 3 } + specify { subject.query.ntuples.should == 3 } end end diff --git a/spec/models/trade/shipments_gross_exports_export_spec.rb b/spec/models/trade/shipments_gross_exports_export_spec.rb index 15a4b71b68..a257f66f79 100644 --- a/spec/models/trade/shipments_gross_exports_export_spec.rb +++ b/spec/models/trade/shipments_gross_exports_export_spec.rb @@ -9,26 +9,26 @@ describe :total_cnt do context "when internal" do subject { Trade::ShipmentsGrossExportsExport.new(:internal => true, :per_page => 4) } - specify{ subject.total_cnt.should == 4 } + specify { subject.total_cnt.should == 4 } end context "when public" do subject { Trade::ShipmentsGrossExportsExport.new(:internal => false, :per_page => 3) } - specify{ subject.total_cnt.should == 4 } + specify { subject.total_cnt.should == 4 } end end describe :query do context "when internal" do subject { Trade::ShipmentsGrossExportsExport.new(:internal => true, :per_page => 4) } - specify{ subject.query.ntuples.should == 4 } + specify { subject.query.ntuples.should == 4 } end context "when public" do subject { Trade::ShipmentsGrossExportsExport.new(:internal => false, :per_page => 3) } - specify{ subject.query.ntuples.should == 3 } + specify { subject.query.ntuples.should == 3 } end context "when invalid date range" do subject { Trade::ShipmentsGrossExportsExport.new(:internal => false, :time_range_start => 2015, :time_range_end => 2014) } - specify{ subject.query.ntuples.should == 0 } + specify { subject.query.ntuples.should == 0 } end end diff --git a/spec/models/trade/shipments_gross_imports_export_spec.rb b/spec/models/trade/shipments_gross_imports_export_spec.rb index 4adbc8ba59..d38ad887cf 100644 --- a/spec/models/trade/shipments_gross_imports_export_spec.rb +++ b/spec/models/trade/shipments_gross_imports_export_spec.rb @@ -9,26 +9,26 @@ describe :total_cnt do context "when internal" do subject { Trade::ShipmentsGrossImportsExport.new(:internal => true, :per_page => 4) } - specify{ subject.total_cnt.should == 4 } + specify { subject.total_cnt.should == 4 } end context "when public" do subject { Trade::ShipmentsGrossImportsExport.new(:internal => false, :per_page => 3) } - specify{ subject.total_cnt.should == 4 } + specify { subject.total_cnt.should == 4 } end end describe :query do context "when internal" do subject { Trade::ShipmentsGrossImportsExport.new(:internal => true, :per_page => 4) } - specify{ subject.query.ntuples.should == 4 } + specify { subject.query.ntuples.should == 4 } end context "when public" do subject { Trade::ShipmentsGrossImportsExport.new(:internal => false, :per_page => 3) } - specify{ subject.query.ntuples.should == 3 } + specify { subject.query.ntuples.should == 3 } end context "when invalid date range" do subject { Trade::ShipmentsGrossImportsExport.new(:internal => false, :time_range_start => 2015, :time_range_end => 2014) } - specify{ subject.query.ntuples.should == 0 } + specify { subject.query.ntuples.should == 0 } end end diff --git a/spec/models/trade/shipments_net_exports_export_spec.rb b/spec/models/trade/shipments_net_exports_export_spec.rb index 6427a9a56b..fa1430b372 100644 --- a/spec/models/trade/shipments_net_exports_export_spec.rb +++ b/spec/models/trade/shipments_net_exports_export_spec.rb @@ -9,26 +9,26 @@ describe :total_cnt do context "when internal" do subject { Trade::ShipmentsNetExportsExport.new(:internal => true, :per_page => 4) } - specify{ subject.total_cnt.should == 4 } + specify { subject.total_cnt.should == 4 } end context "when public" do subject { Trade::ShipmentsNetExportsExport.new(:internal => false, :per_page => 3) } - specify{ subject.total_cnt.should == 4 } + specify { subject.total_cnt.should == 4 } end end describe :query do context "when internal" do subject { Trade::ShipmentsNetExportsExport.new(:internal => true, :per_page => 4) } - specify{ subject.query.ntuples.should == 4 } + specify { subject.query.ntuples.should == 4 } end context "when public" do subject { Trade::ShipmentsNetExportsExport.new(:internal => false, :per_page => 3) } - specify{ subject.query.ntuples.should == 3 } + specify { subject.query.ntuples.should == 3 } end context "when invalid date range" do subject { Trade::ShipmentsNetExportsExport.new(:internal => false, :time_range_start => 2015, :time_range_end => 2014) } - specify{ subject.query.ntuples.should == 0 } + specify { subject.query.ntuples.should == 0 } end end diff --git a/spec/models/trade/shipments_net_imports_export_spec.rb b/spec/models/trade/shipments_net_imports_export_spec.rb index 6db232d21f..6776e12625 100644 --- a/spec/models/trade/shipments_net_imports_export_spec.rb +++ b/spec/models/trade/shipments_net_imports_export_spec.rb @@ -9,26 +9,26 @@ describe :total_cnt do context "when internal" do subject { Trade::ShipmentsNetImportsExport.new(:internal => true, :per_page => 4) } - specify{ subject.total_cnt.should == 4 } + specify { subject.total_cnt.should == 4 } end context "when public" do subject { Trade::ShipmentsNetImportsExport.new(:internal => false, :per_page => 3) } - specify{ subject.total_cnt.should == 4 } + specify { subject.total_cnt.should == 4 } end end describe :query do context "when internal" do subject { Trade::ShipmentsNetImportsExport.new(:internal => true, :per_page => 4) } - specify{ subject.query.ntuples.should == 4 } + specify { subject.query.ntuples.should == 4 } end context "when public" do subject { Trade::ShipmentsNetImportsExport.new(:internal => false, :per_page => 3) } - specify{ subject.query.ntuples.should == 3 } + specify { subject.query.ntuples.should == 3 } end context "when invalid date range" do subject { Trade::ShipmentsNetImportsExport.new(:internal => false, :time_range_start => 2015, :time_range_end => 2014) } - specify{ subject.query.ntuples.should == 0 } + specify { subject.query.ntuples.should == 0 } end end diff --git a/spec/models/trade/taxon_concept_appendix_year_validation_rule_spec.rb b/spec/models/trade/taxon_concept_appendix_year_validation_rule_spec.rb index 3396d31bc2..36ec73fb8a 100644 --- a/spec/models/trade/taxon_concept_appendix_year_validation_rule_spec.rb +++ b/spec/models/trade/taxon_concept_appendix_year_validation_rule_spec.rb @@ -71,10 +71,10 @@ :taxon_name => 'Loxodonta africana', :appendix => 'II', :year => '1997' ) end - subject{ + subject { create_taxon_concept_appendix_year_validation } - specify{ + specify { subject.validation_errors(@aru).size.should == 0 } end @@ -87,13 +87,13 @@ :taxon_name => 'Loxodonta africana', :appendix => 'I', :year => '1996' ) end - subject{ + subject { create_taxon_concept_appendix_year_validation } - specify{ + specify { subject.validation_errors(@aru).size.should == 1 } - specify{ + specify { ve = subject.validation_errors(@aru).first ve.error_message.should == 'taxon_name Loxodonta africana with appendix II with year 1996 is invalid' } @@ -104,13 +104,13 @@ :taxon_name => 'Loxodonta africana', :appendix => 'N', :year => '1996' ) end - subject{ + subject { create_taxon_concept_appendix_year_validation } - specify{ + specify { subject.validation_errors(@aru).size.should == 1 } - specify{ + specify { ve = subject.validation_errors(@aru).first ve.error_message.should == 'taxon_name Loxodonta africana with appendix N with year 1996 is invalid' } @@ -121,10 +121,10 @@ :taxon_name => 'Loxodonta cyclotis', :appendix => 'I', :year => '2013' ) end - subject{ + subject { create_taxon_concept_appendix_year_validation } - specify{ + specify { subject.validation_errors(@aru).size.should == 0 } end @@ -157,10 +157,10 @@ :taxon_name => 'Falco hybrid', :appendix => 'II', :year => '2012' ) end - subject{ + subject { create_taxon_concept_appendix_year_validation } - specify{ + specify { subject.validation_errors(@aru).size.should == 0 } end @@ -172,10 +172,10 @@ :taxon_name => 'Cedrela montana', :appendix => 'N', :year => '2013' ) end - subject{ + subject { create_taxon_concept_appendix_year_validation } - specify{ + specify { subject.validation_errors(@aru).size.should == 0 } end @@ -186,10 +186,10 @@ :taxon_name => 'Agave arizonica', :appendix => 'N', :year => '2013' ) end - subject{ + subject { create_taxon_concept_appendix_year_validation } - specify{ + specify { subject.validation_errors(@aru).size.should == 1 } end diff --git a/spec/models/trade/taxon_concept_source_validation_rule_spec.rb b/spec/models/trade/taxon_concept_source_validation_rule_spec.rb index 3563b2f94f..4eaee047f9 100644 --- a/spec/models/trade/taxon_concept_source_validation_rule_spec.rb +++ b/spec/models/trade/taxon_concept_source_validation_rule_spec.rb @@ -18,7 +18,7 @@ require 'spec_helper' describe Trade::TaxonConceptSourceValidationRule, :drops_tables => true do - let(:annual_report_upload){ + let(:annual_report_upload) { annual_report = build( :annual_report_upload, :point_of_view => 'E' @@ -26,7 +26,7 @@ annual_report.save(:validate => false) annual_report } - let(:sandbox_klass){ + let(:sandbox_klass) { Trade::SandboxTemplate.ar_klass(annual_report_upload.sandbox.table_name) } describe :validation_errors do @@ -36,13 +36,13 @@ sandbox_klass.create(:source_code => 'A', :taxon_name => @animal.full_name) sandbox_klass.create(:source_code => 'B', :taxon_name => @animal.full_name) end - subject{ + subject { create_taxon_concept_source_validation } - specify{ + specify { subject.validation_errors(annual_report_upload).size.should == 1 } - specify{ + specify { ve = subject.validation_errors(annual_report_upload).first ve.error_message.should == "taxon_name #{@animal.full_name} with source_code A is invalid" } @@ -55,10 +55,10 @@ sandbox_klass.create(:source_code => 'A', :taxon_name => @plant.full_name) sandbox_klass.create(:source_code => 'B', :taxon_name => @plant.full_name) end - subject{ + subject { create_taxon_concept_source_validation } - specify{ + specify { subject.validation_errors(annual_report_upload).size.should == 2 } end diff --git a/spec/models/trade/validation_rule_spec.rb b/spec/models/trade/validation_rule_spec.rb index 10546fa215..b84a6b2a51 100644 --- a/spec/models/trade/validation_rule_spec.rb +++ b/spec/models/trade/validation_rule_spec.rb @@ -18,7 +18,7 @@ require 'spec_helper' describe Trade::ValidationRule, :drops_tables => true do - let(:annual_report_upload){ + let(:annual_report_upload) { annual_report = build( :annual_report_upload, :point_of_view => 'E' @@ -26,7 +26,7 @@ annual_report.save(:validate => false) annual_report } - let(:sandbox_klass){ + let(:sandbox_klass) { Trade::SandboxTemplate.ar_klass(annual_report_upload.sandbox.table_name) } @@ -36,13 +36,13 @@ sandbox_klass.create(:trading_partner => nil) end context 'trading_partner should not be blank' do - subject{ + subject { create( :presence_validation_rule, :column_names => ['trading_partner'] ) } - specify{ + specify { subject.validation_errors(annual_report_upload).size.should == 1 } end @@ -55,14 +55,14 @@ sandbox_klass.create(:quantity => 'www') end context 'quantity should be a number' do - subject{ + subject { create( :numericality_validation_rule, :column_names => ['quantity'], :is_strict => true ) } - specify{ + specify { subject.validation_errors(annual_report_upload).size.should == 1 } end @@ -75,10 +75,10 @@ sandbox_klass.create(:year => '33333') end context 'year should be a 4 digit value' do - subject{ + subject { create_year_format_validation } - specify{ + specify { subject.validation_errors(annual_report_upload).size.should == 1 } end diff --git a/spec/models/unit_spec.rb b/spec/models/unit_spec.rb index 7a391f5fad..ed5ef633a1 100644 --- a/spec/models/unit_spec.rb +++ b/spec/models/unit_spec.rb @@ -17,18 +17,18 @@ describe Unit do describe :destroy do context "when no dependent objects attached" do - let(:unit){ create(:unit) } + let(:unit) { create(:unit) } specify { unit.destroy.should be_true } end context "when dependent objects attached" do - let(:unit){ create(:unit) } + let(:unit) { create(:unit) } context "when quotas" do - let(:geo_entity){ create(:geo_entity) } - let!(:quota){ create(:quota, :unit => unit, :geo_entity_id => geo_entity.id) } + let(:geo_entity) { create(:geo_entity) } + let!(:quota) { create(:quota, :unit => unit, :geo_entity_id => geo_entity.id) } specify { unit.destroy.should be_false } end context "when shipments" do - before(:each){ create(:shipment, :unit => unit) } + before(:each) { create(:shipment, :unit => unit) } specify { unit.destroy.should be_false } end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index e38d099729..2464a185b1 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -29,47 +29,47 @@ describe User do describe :create do context "when organisation not given" do - let(:user){ build(:user, organisation: nil) } - specify{ expect(user).to_not be_valid } + let(:user) { build(:user, organisation: nil) } + specify { expect(user).to_not be_valid } end end describe :destroy do context "when no dependent objects attached" do - let(:user){ create(:user) } + let(:user) { create(:user) } specify { user.destroy.should be_true } end context "when dependent objects attached" do - let(:user){ create(:user) } - before(:each){ user.make_current; create(:shipment) } + let(:user) { create(:user) } + before(:each) { user.make_current; create(:shipment) } specify { user.destroy.should be_false } end end describe "abilities" do - subject(:ability){ Ability.new(user) } - let(:user){ nil } + subject(:ability) { Ability.new(user) } + let(:user) { nil } context "when is a Data Manager" do - let(:user){ create(:user, role: User::MANAGER) } + let(:user) { create(:user, role: User::MANAGER) } - it{ should be_able_to(:manage, :all) } + it { should be_able_to(:manage, :all) } end context "when is a Data Contributor" do - let(:user){ create(:user, role: User::CONTRIBUTOR) } + let(:user) { create(:user, role: User::CONTRIBUTOR) } - it{ should be_able_to(:create, TaxonConcept) } - it{ should_not be_able_to(:destroy, TaxonConcept) } + it { should be_able_to(:create, TaxonConcept) } + it { should_not be_able_to(:destroy, TaxonConcept) } end context "when is a E-library Viewer" do - let(:user){ create(:user, role: User::ELIBRARY_USER) } - it{ should_not be_able_to(:manage, TaxonConcept) } + let(:user) { create(:user, role: User::ELIBRARY_USER) } + it { should_not be_able_to(:manage, TaxonConcept) } end context "when is an API User" do - let(:user){ create(:user, role: User::API_USER) } - it{ should_not be_able_to(:manage, TaxonConcept) } + let(:user) { create(:user, role: User::API_USER) } + it { should_not be_able_to(:manage, TaxonConcept) } end end end diff --git a/spec/shared/agave.rb b/spec/shared/agave.rb index de71dee9a6..a914713984 100644 --- a/spec/shared/agave.rb +++ b/spec/shared/agave.rb @@ -1,7 +1,7 @@ shared_context "Agave" do - let(:en){ create(:language, :name => 'English', :iso_code1 => 'EN', :iso_code3 => 'ENG') } - let(:es){ create(:language, :name => 'Spanish', :iso_code1 => 'ES', :iso_code3 => 'SPA') } - let(:fr){ create(:language, :name => 'French', :iso_code1 => 'FR', :iso_code3 => 'FRA') } + let(:en) { create(:language, :name => 'English', :iso_code1 => 'EN', :iso_code3 => 'ENG') } + let(:es) { create(:language, :name => 'Spanish', :iso_code1 => 'ES', :iso_code3 => 'SPA') } + let(:fr) { create(:language, :name => 'French', :iso_code1 => 'FR', :iso_code3 => 'FRA') } before(:all) do @order = create_cites_eu_order( :taxon_name => create(:taxon_name, :scientific_name => 'Liliales'), diff --git a/spec/shared/arctocephalus.rb b/spec/shared/arctocephalus.rb index bd2db54b84..94a6253909 100644 --- a/spec/shared/arctocephalus.rb +++ b/spec/shared/arctocephalus.rb @@ -1,8 +1,8 @@ #Encoding: UTF-8 shared_context "Arctocephalus" do - let(:en){ create(:language, :name => 'English', :iso_code1 => 'EN', :iso_code3 => 'ENG') } - let(:es){ create(:language, :name => 'Spanish', :iso_code1 => 'ES', :iso_code3 => 'SPA') } - let(:fr){ create(:language, :name => 'French', :iso_code1 => 'FR', :iso_code3 => 'FRA') } + let(:en) { create(:language, :name => 'English', :iso_code1 => 'EN', :iso_code3 => 'ENG') } + let(:es) { create(:language, :name => 'Spanish', :iso_code1 => 'ES', :iso_code3 => 'SPA') } + let(:fr) { create(:language, :name => 'French', :iso_code1 => 'FR', :iso_code3 => 'FRA') } before(:all) do @order = create_cites_eu_order( :taxon_name => create(:taxon_name, :scientific_name => 'Carnivora'), diff --git a/spec/shared/boa_constrictor.rb b/spec/shared/boa_constrictor.rb index 97c9050230..e417c5cea9 100644 --- a/spec/shared/boa_constrictor.rb +++ b/spec/shared/boa_constrictor.rb @@ -1,5 +1,5 @@ shared_context "Boa constrictor" do - let(:en){ + let(:en) { create(:language, :name => 'Spanish', :iso_code1 => 'ES', :iso_code3 => 'SPA') create(:language, :name => 'French', :iso_code1 => 'FR', :iso_code3 => 'FRA') create(:language, :name => 'English', :iso_code1 => 'EN', :iso_code3 => 'ENG') diff --git a/spec/shared/caiman_latirostris.rb b/spec/shared/caiman_latirostris.rb index c06394418d..f8ec7e9272 100644 --- a/spec/shared/caiman_latirostris.rb +++ b/spec/shared/caiman_latirostris.rb @@ -1,12 +1,12 @@ #Encoding: utf-8 shared_context "Caiman latirostris" do - let(:en){ + let(:en) { create(:language, :name => 'Spanish', :iso_code1 => 'ES', :iso_code3 => 'SPA') create(:language, :name => 'French', :iso_code1 => 'FR', :iso_code3 => 'FRA') create(:language, :name => 'English', :iso_code1 => 'EN', :iso_code3 => 'ENG') } - let(:argentina){ + let(:argentina) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -14,7 +14,7 @@ :iso_code2 => 'AR' ) } - let(:brazil){ + let(:brazil) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, diff --git a/spec/shared/canis_lupus.rb b/spec/shared/canis_lupus.rb index 5f5f07df20..a92c284cbf 100644 --- a/spec/shared/canis_lupus.rb +++ b/spec/shared/canis_lupus.rb @@ -1,5 +1,5 @@ shared_context "Canis lupus" do - let(:bhutan){ + let(:bhutan) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -7,7 +7,7 @@ :iso_code2 => 'BT' ) } - let(:india){ + let(:india) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -15,7 +15,7 @@ :iso_code2 => 'IN' ) } - let(:nepal){ + let(:nepal) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -23,7 +23,7 @@ :iso_code2 => 'NP' ) } - let(:pakistan){ + let(:pakistan) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -31,7 +31,7 @@ :iso_code2 => 'PK' ) } - let(:poland){ + let(:poland) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -39,7 +39,7 @@ :iso_code2 => 'PL' ) } - let(:argentina){ + let(:argentina) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -47,7 +47,7 @@ :iso_code2 => 'AR' ) } - let(:spain){ + let(:spain) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -55,7 +55,7 @@ :iso_code2 => 'ES' ) } - let(:greece){ + let(:greece) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, diff --git a/spec/shared/colophon.rb b/spec/shared/colophon.rb index c8918ca39c..bab52817e8 100644 --- a/spec/shared/colophon.rb +++ b/spec/shared/colophon.rb @@ -1,6 +1,6 @@ #Encoding: utf-8 shared_context 'Colophon' do - let(:south_africa){ + let(:south_africa) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, diff --git a/spec/shared/dalbergia.rb b/spec/shared/dalbergia.rb index e5520ada82..bfe95b5505 100644 --- a/spec/shared/dalbergia.rb +++ b/spec/shared/dalbergia.rb @@ -1,8 +1,8 @@ shared_context "Dalbergia" do - let(:en){ create(:language, :name => 'English', :iso_code1 => 'EN', :iso_code3 => 'ENG') } - let(:es){ create(:language, :name => 'Spanish', :iso_code1 => 'ES', :iso_code3 => 'SPA') } - let(:fr){ create(:language, :name => 'French', :iso_code1 => 'FR', :iso_code3 => 'FRA') } - let(:madagascar){ + let(:en) { create(:language, :name => 'English', :iso_code1 => 'EN', :iso_code3 => 'ENG') } + let(:es) { create(:language, :name => 'Spanish', :iso_code1 => 'ES', :iso_code3 => 'SPA') } + let(:fr) { create(:language, :name => 'French', :iso_code1 => 'FR', :iso_code3 => 'FRA') } + let(:madagascar) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -10,7 +10,7 @@ :iso_code2 => 'MG' ) } - let(:thailand){ + let(:thailand) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, diff --git a/spec/shared/diospyros.rb b/spec/shared/diospyros.rb index d16965fe0d..974b0c2ba0 100644 --- a/spec/shared/diospyros.rb +++ b/spec/shared/diospyros.rb @@ -1,5 +1,5 @@ shared_context "Diospyros" do - let(:madagascar){ + let(:madagascar) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -7,7 +7,7 @@ :iso_code2 => 'MG' ) } - let(:sri_lanka){ + let(:sri_lanka) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, diff --git a/spec/shared/loxodonta_africana.rb b/spec/shared/loxodonta_africana.rb index 6cf3c4a355..66b942c6e9 100644 --- a/spec/shared/loxodonta_africana.rb +++ b/spec/shared/loxodonta_africana.rb @@ -1,5 +1,5 @@ shared_context "Loxodonta africana" do - let(:ghana){ + let(:ghana) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -7,7 +7,7 @@ :iso_code2 => 'GH' ) } - let(:botswana){ + let(:botswana) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -15,7 +15,7 @@ :iso_code2 => 'BW' ) } - let(:namibia){ + let(:namibia) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -23,7 +23,7 @@ :iso_code2 => 'NA' ) } - let(:zambia){ + let(:zambia) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -31,7 +31,7 @@ :iso_code2 => 'ZA' ) } - let(:zimbabwe){ + let(:zimbabwe) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, diff --git a/spec/shared/mellivora_capensis.rb b/spec/shared/mellivora_capensis.rb index 2fe2bd97c9..e762647307 100644 --- a/spec/shared/mellivora_capensis.rb +++ b/spec/shared/mellivora_capensis.rb @@ -1,5 +1,5 @@ shared_context "Mellivora capensis" do - let(:ghana){ + let(:ghana) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -7,7 +7,7 @@ :iso_code2 => 'GH' ) } - let(:botswana){ + let(:botswana) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, diff --git a/spec/shared/moschus.rb b/spec/shared/moschus.rb index e10d46f58f..f54e2c02e9 100644 --- a/spec/shared/moschus.rb +++ b/spec/shared/moschus.rb @@ -1,5 +1,5 @@ shared_context "Moschus" do - let(:bhutan){ + let(:bhutan) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -7,7 +7,7 @@ :iso_code2 => 'BT' ) } - let(:india){ + let(:india) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -15,7 +15,7 @@ :iso_code2 => 'IN' ) } - let(:nepal){ + let(:nepal) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -23,7 +23,7 @@ :iso_code2 => 'NP' ) } - let(:china){ + let(:china) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, diff --git a/spec/shared/panax_ginseng.rb b/spec/shared/panax_ginseng.rb index 1e6ef60767..6c1b423533 100644 --- a/spec/shared/panax_ginseng.rb +++ b/spec/shared/panax_ginseng.rb @@ -1,5 +1,5 @@ shared_context "Panax ginseng" do - let(:russia){ + let(:russia) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -7,7 +7,7 @@ :iso_code2 => 'RU' ) } - let(:china){ + let(:china) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, diff --git a/spec/shared/pecari_tajacu.rb b/spec/shared/pecari_tajacu.rb index 94e1e69dd6..7a69363d05 100644 --- a/spec/shared/pecari_tajacu.rb +++ b/spec/shared/pecari_tajacu.rb @@ -1,19 +1,19 @@ shared_context "Pecari tajacu" do - let(:north_america){ + let(:north_america) { create( :geo_entity, :geo_entity_type => cites_region_geo_entity_type, :name => "5- North America" ) } - let(:south_america){ + let(:south_america) { create( :geo_entity, :geo_entity_type => cites_region_geo_entity_type, :name => "3- Central and South America and the Caribbean" ) } - let(:america){ + let(:america) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -21,7 +21,7 @@ :iso_code2 => 'US' ) } - let(:mexico){ + let(:mexico) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -29,7 +29,7 @@ :iso_code2 => 'MX' ) } - let(:canada){ + let(:canada) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, @@ -37,7 +37,7 @@ :iso_code2 => 'CA' ) } - let(:argentina){ + let(:argentina) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, diff --git a/spec/shared/psittaciformes.rb b/spec/shared/psittaciformes.rb index 9d3fb3d5f3..001a51df33 100644 --- a/spec/shared/psittaciformes.rb +++ b/spec/shared/psittaciformes.rb @@ -1,5 +1,5 @@ shared_context "Psittaciformes" do - let(:ghana){ + let(:ghana) { create( :geo_entity, :geo_entity_type => country_geo_entity_type, diff --git a/spec/support/sapi_helpers.rb b/spec/support/sapi_helpers.rb index d51fe57bdc..c6b94eb41a 100644 --- a/spec/support/sapi_helpers.rb +++ b/spec/support/sapi_helpers.rb @@ -1,14 +1,14 @@ shared_context :sapi do - let(:cites_eu){ + let(:cites_eu) { create(:taxonomy, :name => Taxonomy::CITES_EU) } - let(:cms){ + let(:cms) { create(:taxonomy, :name => Taxonomy::CMS) } - let(:cites){ + let(:cites) { d = Designation.find_by_taxonomy_id_and_name(cites_eu.id, Designation::CITES) unless d d = create(:designation, :name => Designation::CITES, :taxonomy => cites_eu) @@ -30,7 +30,7 @@ d } - let(:eu){ + let(:eu) { d = Designation.find_by_taxonomy_id_and_name(cites_eu.id, Designation::EU) unless d d = create(:designation, :name => Designation::EU, :taxonomy => cites_eu) @@ -51,7 +51,7 @@ d } - let(:cms_designation){ + let(:cms_designation) { d = Designation.find_by_taxonomy_id_and_name(cms.id, Designation::CMS) unless d d = create(:designation, :name => Designation::CMS, :taxonomy => cms) @@ -134,110 +134,110 @@ end end - let(:cites_eu_animalia){ + let(:cites_eu_animalia) { create_cites_eu_kingdom( :taxonomic_position => '1', :taxon_name => create(:taxon_name, :scientific_name => 'Animalia') ) } - let(:cms_animalia){ + let(:cms_animalia) { create_cms_kingdom( :taxonomic_position => '1', :taxon_name => create(:taxon_name, :scientific_name => 'Animalia') ) } - let(:cites_eu_chordata){ + let(:cites_eu_chordata) { create_cites_eu_phylum( :taxonomic_position => '1.1', :taxon_name => create(:taxon_name, :scientific_name => 'Chordata'), :parent => cites_eu_animalia ) } - let(:cms_chordata){ + let(:cms_chordata) { create_cms_phylum( :taxonomic_position => '1.1', :taxon_name => create(:taxon_name, :scientific_name => 'Chordata'), :parent => cms_animalia ) } - let(:cites_eu_mammalia){ + let(:cites_eu_mammalia) { create_cites_eu_class( :taxonomic_position => '1.1.1', :taxon_name => create(:taxon_name, :scientific_name => 'Mammalia'), :parent => cites_eu_chordata ) } - let(:cms_mammalia){ + let(:cms_mammalia) { create_cms_class( :taxonomic_position => '1.1.1', :taxon_name => create(:taxon_name, :scientific_name => 'Mammalia'), :parent => cms_chordata ) } - let(:cites_eu_aves){ + let(:cites_eu_aves) { create_cites_eu_class( :taxonomic_position => '1.1.2', :taxon_name => create(:taxon_name, :scientific_name => 'Aves'), :parent => cites_eu_chordata ) } - let(:cites_eu_reptilia){ + let(:cites_eu_reptilia) { create_cites_eu_class( :taxonomic_position => '1.1.3', :taxon_name => create(:taxon_name, :scientific_name => 'Reptilia'), :parent => cites_eu_chordata ) } - let(:cms_reptilia){ + let(:cms_reptilia) { create_cms_class( :taxonomic_position => '1.1.3', :taxon_name => create(:taxon_name, :scientific_name => 'Reptilia'), :parent => cms_chordata ) } - let(:cites_eu_amphibia){ + let(:cites_eu_amphibia) { create_cites_eu_class( :taxonomic_position => '1.1.4', :taxon_name => create(:taxon_name, :scientific_name => 'Amphibia'), :parent => cites_eu_chordata ) } - let(:cites_eu_elasmobranchii){ + let(:cites_eu_elasmobranchii) { create_cites_eu_class( :taxonomic_position => '1.1.5', :taxon_name => create(:taxon_name, :scientific_name => 'Elasmobranchii'), :parent => cites_eu_chordata ) } - let(:cites_eu_arthropoda){ + let(:cites_eu_arthropoda) { create_cites_eu_phylum( :taxonomic_position => '1.3', :taxon_name => create(:taxon_name, :scientific_name => 'Arthropoda'), :parent => cites_eu_animalia ) } - let(:cites_eu_insecta){ + let(:cites_eu_insecta) { create_cites_eu_class( :taxonomic_position => '1.3.2', :taxon_name => create(:taxon_name, :scientific_name => 'Insecta'), :parent => cites_eu_arthropoda ) } - let(:cites_eu_annelida){ + let(:cites_eu_annelida) { create_cites_eu_phylum( :taxonomic_position => '1.4', :taxon_name => create(:taxon_name, :scientific_name => 'Annelida'), :parent => cites_eu_animalia ) } - let(:cites_eu_hirudinoidea){ + let(:cites_eu_hirudinoidea) { create_cites_eu_class( :taxonomic_position => '1.4.1', :taxon_name => create(:taxon_name, :scientific_name => 'Hirudinoidea'), :parent => cites_eu_annelida ) } - let(:cites_eu_plantae){ + let(:cites_eu_plantae) { create_cites_eu_kingdom( :taxonomic_position => '2', :taxon_name => create(:taxon_name, :scientific_name => 'Plantae') @@ -440,43 +440,43 @@ def create_taxon_concept_source_validation ) end - let(:reg1997){ + let(:reg1997) { create(:eu_regulation, :name => 'No 938/97', :designation => eu, :effective_at => '1997-06-01', :end_date => '2000-12-18') } - let(:reg2005){ + let(:reg2005) { create(:eu_regulation, :name => 'No 1332/2005', :designation => eu, :effective_at => '2005-08-22', :end_date => '2008-04-11') } - let(:reg2008){ + let(:reg2008) { create(:eu_regulation, :name => 'No 318/2008', :designation => eu, :effective_at => '2008-04-11', :end_date => '2009-05-22') } - let(:reg2012){ + let(:reg2012) { create(:eu_regulation, :name => 'No 1158/2012', :designation => eu, :effective_at => '2012-12-15', :end_date => '2013-08-10') } - let(:reg2013){ + let(:reg2013) { create(:eu_regulation, :name => 'No 750/2013', :designation => eu, :effective_at => '2013-08-10', :end_date => nil, :is_current => true) } - let(:contains_geo_relationship_type){ + let(:contains_geo_relationship_type) { create(:geo_relationship_type, :name => GeoRelationshipType::CONTAINS) } - let(:territory_geo_entity_type){ + let(:territory_geo_entity_type) { create(:geo_entity_type, :name => GeoEntityType::TERRITORY) } - let(:country_geo_entity_type){ + let(:country_geo_entity_type) { create(:geo_entity_type, :name => GeoEntityType::COUNTRY) } - let(:cites_region_geo_entity_type){ + let(:cites_region_geo_entity_type) { create(:geo_entity_type, :name => GeoEntityType::CITES_REGION) } - let(:trade_geo_entity_type){ + let(:trade_geo_entity_type) { create(:geo_entity_type, :name => GeoEntityType::TRADE_ENTITY) } - let(:synonym_relationship_type){ + let(:synonym_relationship_type) { create( :taxon_relationship_type, :name => TaxonRelationshipType::HAS_SYNONYM, @@ -484,7 +484,7 @@ def create_taxon_concept_source_validation :is_bidirectional => false ) } - let(:trade_name_relationship_type){ + let(:trade_name_relationship_type) { create( :taxon_relationship_type, :name => TaxonRelationshipType::HAS_TRADE_NAME, @@ -492,7 +492,7 @@ def create_taxon_concept_source_validation :is_bidirectional => false ) } - let(:hybrid_relationship_type){ + let(:hybrid_relationship_type) { create( :taxon_relationship_type, :name => TaxonRelationshipType::HAS_HYBRID, @@ -500,7 +500,7 @@ def create_taxon_concept_source_validation :is_bidirectional => false ) } - let(:equal_relationship_type){ + let(:equal_relationship_type) { create( :taxon_relationship_type, :name => TaxonRelationshipType::EQUAL_TO, diff --git a/spec/workers/eu_regulation_activation_worker_spec.rb b/spec/workers/eu_regulation_activation_worker_spec.rb index 08046b21c2..04b0576159 100644 --- a/spec/workers/eu_regulation_activation_worker_spec.rb +++ b/spec/workers/eu_regulation_activation_worker_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe EuRegulationActivationWorker do - let(:prev_eu_regulation){ + let(:prev_eu_regulation) { create( :eu_regulation, :name => 'REGULATION 1.0', @@ -9,13 +9,13 @@ :is_current => true ) } - let!(:listing_change){ + let!(:listing_change) { create_eu_A_addition( :event_id => prev_eu_regulation.id, :is_current => true ) } - let!(:eu_regulation){ + let!(:eu_regulation) { create_eu_regulation( :name => 'REGULATION 2.0', :listing_changes_event_id => prev_eu_regulation.id, diff --git a/spec/workers/event_listing_changes_copy_worker_spec.rb b/spec/workers/event_listing_changes_copy_worker_spec.rb index 55be32e2e8..1faf1592a8 100644 --- a/spec/workers/event_listing_changes_copy_worker_spec.rb +++ b/spec/workers/event_listing_changes_copy_worker_spec.rb @@ -1,14 +1,14 @@ require 'spec_helper' describe EventListingChangesCopyWorker do - let(:prev_eu_regulation){ + let(:prev_eu_regulation) { create_eu_regulation( :name => 'REGULATION 1.0', :designation => eu, :is_current => true ) } - let(:eu_regulation){ + let(:eu_regulation) { create_eu_regulation( :name => 'REGULATION 2.0', :listing_changes_event_id => prev_eu_regulation.id, @@ -16,13 +16,13 @@ :is_current => true ) } - let(:species){ + let(:species) { create_cites_eu_species } - let(:subspecies){ + let(:subspecies) { create_cites_eu_subspecies(parent: species) } - let!(:listing_change){ + let!(:listing_change) { create_eu_A_addition( :event_id => prev_eu_regulation.id, :taxon_concept_id => species.id @@ -30,7 +30,7 @@ } context "when copy into non-current regulation" do - let(:eu_regulation){ + let(:eu_regulation) { create_eu_regulation( :name => 'REGULATION 2.0', :listing_changes_event_id => prev_eu_regulation.id, @@ -50,19 +50,19 @@ end context "when exclusion" do - let!(:taxonomic_exclusion){ + let!(:taxonomic_exclusion) { create_eu_A_exception( :parent_id => listing_change.id, :taxon_concept_id => subspecies.id ) } - let!(:geographic_exclusion){ + let!(:geographic_exclusion) { create_eu_A_exception( :parent_id => listing_change.id, :taxon_concept_id => species.id ) } - let!(:exclusion_distribution){ + let!(:exclusion_distribution) { create(:listing_distribution, listing_change_id: geographic_exclusion.id) } From e6f02a68b2b15857196dacb8a0c17fc77b46bfd3 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 1 Jul 2016 10:20:34 +0100 Subject: [PATCH 329/365] enabled Style/LeadingCommentSpace --- .rubocop_todo.yml | 5 ----- Capfile | 2 +- Gemfile | 6 +++--- app/controllers/admin/cites_acs_controller.rb | 2 +- app/controllers/admin/cites_cops_controller.rb | 2 +- .../admin/cites_extraordinary_meetings_controller.rb | 2 +- app/controllers/admin/cites_pcs_controller.rb | 2 +- .../admin/cites_suspension_notifications_controller.rb | 2 +- app/controllers/admin/cites_tcs_controller.rb | 2 +- app/controllers/admin/ec_srgs_controller.rb | 2 +- .../admin/eu_council_regulations_controller.rb | 2 +- .../admin/eu_implementing_regulations_controller.rb | 2 +- app/controllers/admin/eu_regulations_controller.rb | 2 +- .../admin/eu_suspension_regulations_controller.rb | 2 +- app/controllers/admin/taxon_listing_changes_controller.rb | 2 +- app/controllers/admin/taxon_relationships_controller.rb | 4 ++-- app/controllers/api/v1/taxon_concepts_controller.rb | 2 +- app/helpers/admin_helper.rb | 2 +- app/models/checklist/checklist.rb | 6 +++--- app/models/checklist/checklist_params.rb | 8 ++++---- app/models/checklist/higher_taxa_injector.rb | 6 +++--- app/models/checklist/higher_taxa_item.rb | 2 +- app/models/checklist/pdf/document.rb | 2 +- app/models/checklist/pdf/history_content.rb | 4 ++-- app/models/checklist/pdf/index_content.rb | 4 ++-- app/models/checklist/pdf/index_query.rb | 4 ++-- app/models/checklist/timeline.rb | 4 ++-- app/models/checklist/timeline_event.rb | 2 +- app/models/checklist/timeline_interval.rb | 2 +- app/models/checklist/timeline_year.rb | 2 +- app/models/cites_suspension.rb | 4 ++-- app/models/common_name.rb | 8 ++++---- app/models/dashboard_stats.rb | 4 ++-- app/models/listing_change_observer.rb | 6 +++--- app/models/quota.rb | 4 ++-- app/models/species/restrictions_export.rb | 2 +- app/models/species/search_params.rb | 6 +++--- app/models/taxon_concept.rb | 4 ++-- app/models/taxon_concept_prefix_matcher.rb | 6 +++--- app/models/taxon_relationship.rb | 2 +- app/models/trade/annual_report_upload.rb | 8 ++++---- app/models/trade/filter.rb | 2 +- app/models/trade/permit_matcher.rb | 4 ++-- app/models/trade/sandbox.rb | 2 +- app/models/trade/shipment.rb | 2 +- app/models/trade/shipments_gross_exports_export.rb | 2 +- app/models/trade/validation_rule.rb | 2 +- app/models/trade_restriction.rb | 2 +- app/serializers/checklist/checklist_serializer.rb | 2 +- app/serializers/checklist/taxon_concept_serializer.rb | 2 +- config/deploy.rb | 2 +- config/initializers/devise.rb | 4 ++-- config/routes.rb | 2 +- db/migrate/20141223141125_timestamp_view_definitions.rb | 2 +- lib/modules/dictionary.rb | 4 ++-- lib/modules/latex_to_pdf.rb | 2 +- lib/tasks/helpers_for_import.rb | 6 +++--- lib/tasks/import_cites_listings.rake | 4 ++-- lib/tasks/import_cites_quotas.rake | 2 +- lib/tasks/import_cms_listings.rake | 4 ++-- lib/tasks/import_distribution_tags.rake | 2 +- lib/tasks/import_distributions.rake | 2 +- lib/tasks/import_eu_listings.rake | 4 ++-- lib/tasks/import_species.rake | 2 +- lib/tasks/import_standard_reference_links.rake | 4 ++-- lib/tasks/import_synonyms.rake | 4 ++-- lib/tasks/import_trade_shipments.rake | 2 +- lib/tasks/update_eu_decisions_with_missing_source.rake | 2 +- spec/controllers/admin/taxon_commons_controller_spec.rb | 8 ++++---- .../models/species/orphaned_taxon_concepts_export_spec.rb | 2 +- spec/models/species/taxon_concept_prefix_matcher_spec.rb | 2 +- spec/models/trade/annual_report_upload_spec.rb | 8 ++++---- spec/shared/falconiformes.rb | 2 +- 73 files changed, 118 insertions(+), 123 deletions(-) diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 590d78a12e..359ae5695f 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -370,11 +370,6 @@ Style/Lambda: - 'app/models/taxon_concept.rb' - 'app/models/taxonomy.rb' -# Offense count: 167 -# Cop supports --auto-correct. -Style/LeadingCommentSpace: - Enabled: false - # Offense count: 1 # Cop supports --auto-correct. Style/LineEndConcatenation: diff --git a/Capfile b/Capfile index 59f216cf1d..aae35a3ee1 100644 --- a/Capfile +++ b/Capfile @@ -25,7 +25,7 @@ require 'capistrano/rvm' require 'capistrano/bundler' require 'capistrano/rails/assets' require 'capistrano/rails/migrations' -#require 'capistrano/slack' +# require 'capistrano/slack' require 'capistrano/sidekiq' require 'capistrano/passenger' # Load custom tasks from `lib/capistrano/tasks` if you have any defined diff --git a/Gemfile b/Gemfile index 454942f498..0d14ed494b 100644 --- a/Gemfile +++ b/Gemfile @@ -12,7 +12,7 @@ gem 'activerecord-postgres-hstore' gem 'nested-hstore' gem 'pg_search', '~> 0.5.7' gem 'foreigner' -gem 'oj' #optimised JSON (picked by multi_json) +gem 'oj' # optimised JSON (picked by multi_json) gem 'nokogiri', '>= 1.6.7.2' gem 'inherited_resources' gem 'traco', '~> 2.0.0' @@ -34,7 +34,7 @@ gem 'whenever', :require => false gem 'ember-rails' gem 'ember-source', '1.1.2' -gem 'jquery-rails', '2.1.4' #do not upgrade until https://github.com/jquery/jquery/pull/1142 isd pulled into jquery-rails +gem 'jquery-rails', '2.1.4' # do not upgrade until https://github.com/jquery/jquery/pull/1142 isd pulled into jquery-rails gem 'jquery-mousewheel-rails' gem 'jquery-cookie-rails' gem 'bootstrap-sass', '~> 2.3.1.0' @@ -140,7 +140,7 @@ gem 'jquery-ui-rails' gem 'geoip' -#track who created or edited a given object +# track who created or edited a given object gem 'clerk' gem 'paper_trail', '~> 4.0.0.beta' diff --git a/app/controllers/admin/cites_acs_controller.rb b/app/controllers/admin/cites_acs_controller.rb index e41df48599..6ea81d4247 100644 --- a/app/controllers/admin/cites_acs_controller.rb +++ b/app/controllers/admin/cites_acs_controller.rb @@ -1,5 +1,5 @@ class Admin::CitesAcsController < Admin::EventsController - #this needs to be specified, because otherwise defaults to 'event' + # this needs to be specified, because otherwise defaults to 'event' defaults :resource_class => CitesAc, :collection_name => 'cites_acs', :instance_name => 'cites_ac' diff --git a/app/controllers/admin/cites_cops_controller.rb b/app/controllers/admin/cites_cops_controller.rb index 830b3a9316..d20a8ab001 100644 --- a/app/controllers/admin/cites_cops_controller.rb +++ b/app/controllers/admin/cites_cops_controller.rb @@ -1,5 +1,5 @@ class Admin::CitesCopsController < Admin::EventsController - #this needs to be specified, because otherwise defaults to 'event' + # this needs to be specified, because otherwise defaults to 'event' defaults :resource_class => CitesCop, :collection_name => 'cites_cops', :instance_name => 'cites_cop' diff --git a/app/controllers/admin/cites_extraordinary_meetings_controller.rb b/app/controllers/admin/cites_extraordinary_meetings_controller.rb index f9ae43014c..66ee461d45 100644 --- a/app/controllers/admin/cites_extraordinary_meetings_controller.rb +++ b/app/controllers/admin/cites_extraordinary_meetings_controller.rb @@ -1,5 +1,5 @@ class Admin::CitesExtraordinaryMeetingsController < Admin::EventsController - #this needs to be specified, because otherwise defaults to 'event' + # this needs to be specified, because otherwise defaults to 'event' defaults :resource_class => CitesExtraordinaryMeeting, :collection_name => 'cites_extraordinary_meetings', :instance_name => 'cites_extraordinary_meeting' diff --git a/app/controllers/admin/cites_pcs_controller.rb b/app/controllers/admin/cites_pcs_controller.rb index 7f9d4e144b..8462087603 100644 --- a/app/controllers/admin/cites_pcs_controller.rb +++ b/app/controllers/admin/cites_pcs_controller.rb @@ -1,5 +1,5 @@ class Admin::CitesPcsController < Admin::EventsController - #this needs to be specified, because otherwise defaults to 'event' + # this needs to be specified, because otherwise defaults to 'event' defaults :resource_class => CitesPc, :collection_name => 'cites_pcs', :instance_name => 'cites_pc' diff --git a/app/controllers/admin/cites_suspension_notifications_controller.rb b/app/controllers/admin/cites_suspension_notifications_controller.rb index 0e9a65cdea..ff373999b8 100644 --- a/app/controllers/admin/cites_suspension_notifications_controller.rb +++ b/app/controllers/admin/cites_suspension_notifications_controller.rb @@ -1,5 +1,5 @@ class Admin::CitesSuspensionNotificationsController < Admin::EventsController - #this needs to be specified, because otherwise defaults to 'event' + # this needs to be specified, because otherwise defaults to 'event' defaults :resource_class => CitesSuspensionNotification, :collection_name => 'cites_suspension_notifications', :instance_name => 'cites_suspension_notification' diff --git a/app/controllers/admin/cites_tcs_controller.rb b/app/controllers/admin/cites_tcs_controller.rb index acb4655cba..005ecc6586 100644 --- a/app/controllers/admin/cites_tcs_controller.rb +++ b/app/controllers/admin/cites_tcs_controller.rb @@ -1,5 +1,5 @@ class Admin::CitesTcsController < Admin::EventsController - #this needs to be specified, because otherwise defaults to 'event' + # this needs to be specified, because otherwise defaults to 'event' defaults :resource_class => CitesTc, :collection_name => 'cites_tcs', :instance_name => 'cites_tc' diff --git a/app/controllers/admin/ec_srgs_controller.rb b/app/controllers/admin/ec_srgs_controller.rb index adda0b4356..9a057d3ac9 100644 --- a/app/controllers/admin/ec_srgs_controller.rb +++ b/app/controllers/admin/ec_srgs_controller.rb @@ -1,5 +1,5 @@ class Admin::EcSrgsController < Admin::EventsController - #this needs to be specified, because otherwise defaults to 'event' + # this needs to be specified, because otherwise defaults to 'event' defaults :resource_class => EcSrg, :collection_name => 'ec_srgs', :instance_name => 'ec_srg' diff --git a/app/controllers/admin/eu_council_regulations_controller.rb b/app/controllers/admin/eu_council_regulations_controller.rb index 2454da326f..7d602fea88 100644 --- a/app/controllers/admin/eu_council_regulations_controller.rb +++ b/app/controllers/admin/eu_council_regulations_controller.rb @@ -1,5 +1,5 @@ class Admin::EuCouncilRegulationsController < Admin::EventsController - #this needs to be specified, because otherwise defaults to 'event' + # this needs to be specified, because otherwise defaults to 'event' defaults :resource_class => EuCouncilRegulation, :collection_name => 'eu_council_regulations', :instance_name => 'eu_council_regulation' diff --git a/app/controllers/admin/eu_implementing_regulations_controller.rb b/app/controllers/admin/eu_implementing_regulations_controller.rb index 1dbbd30179..fcce342ef1 100644 --- a/app/controllers/admin/eu_implementing_regulations_controller.rb +++ b/app/controllers/admin/eu_implementing_regulations_controller.rb @@ -1,5 +1,5 @@ class Admin::EuImplementingRegulationsController < Admin::EventsController - #this needs to be specified, because otherwise defaults to 'event' + # this needs to be specified, because otherwise defaults to 'event' defaults :resource_class => EuImplementingRegulation, :collection_name => 'eu_implementing_regulations', :instance_name => 'eu_implementing_regulation' diff --git a/app/controllers/admin/eu_regulations_controller.rb b/app/controllers/admin/eu_regulations_controller.rb index 8a38ca275e..185c8cd963 100644 --- a/app/controllers/admin/eu_regulations_controller.rb +++ b/app/controllers/admin/eu_regulations_controller.rb @@ -1,5 +1,5 @@ class Admin::EuRegulationsController < Admin::EventsController - #this needs to be specified, because otherwise defaults to 'event' + # this needs to be specified, because otherwise defaults to 'event' defaults :resource_class => EuRegulation, :collection_name => 'eu_regulations', :instance_name => 'eu_regulation' diff --git a/app/controllers/admin/eu_suspension_regulations_controller.rb b/app/controllers/admin/eu_suspension_regulations_controller.rb index b3e599ccbd..2633250752 100644 --- a/app/controllers/admin/eu_suspension_regulations_controller.rb +++ b/app/controllers/admin/eu_suspension_regulations_controller.rb @@ -1,5 +1,5 @@ class Admin::EuSuspensionRegulationsController < Admin::EventsController - #this needs to be specified, because otherwise defaults to 'event' + # this needs to be specified, because otherwise defaults to 'event' defaults :resource_class => EuSuspensionRegulation, :collection_name => 'eu_suspension_regulations', :instance_name => 'eu_suspension_regulation' diff --git a/app/controllers/admin/taxon_listing_changes_controller.rb b/app/controllers/admin/taxon_listing_changes_controller.rb index a8b9dcf0d1..e4005aa29d 100644 --- a/app/controllers/admin/taxon_listing_changes_controller.rb +++ b/app/controllers/admin/taxon_listing_changes_controller.rb @@ -19,7 +19,7 @@ def new load_change_types @listing_change.change_type_id ||= @change_types.first.id @listing_change.is_current = true - @listing_change.event = @events && @events.first #ordered most recent first + @listing_change.event = @events && @events.first # ordered most recent first @listing_change.effective_at = @listing_change.event && @listing_change.event.effective_at build_dependants end diff --git a/app/controllers/admin/taxon_relationships_controller.rb b/app/controllers/admin/taxon_relationships_controller.rb index 1d64432dfc..cb2ff8bd42 100644 --- a/app/controllers/admin/taxon_relationships_controller.rb +++ b/app/controllers/admin/taxon_relationships_controller.rb @@ -7,7 +7,7 @@ class Admin::TaxonRelationshipsController < Admin::StandardAuthorizationControll def index index! do - @form_taxonomies = Taxonomy.order(:name). #for Inter-taxonomic relationships + @form_taxonomies = Taxonomy.order(:name). # for Inter-taxonomic relationships where('id <> ?', @taxon_concept.taxonomy_id) @inverse_taxon_relationships = TaxonRelationship. where(:other_taxon_concept_id => @taxon_concept.id, @@ -29,7 +29,7 @@ def create create! do |success, failure| success.js { render 'create' } failure.js { - @taxonomies = Taxonomy.order(:name). #for Inter-taxonomic relationships + @taxonomies = Taxonomy.order(:name). # for Inter-taxonomic relationships where('id <> ?', TaxonConcept.find(params[:taxon_relationship][:taxon_concept_id]). try(:taxonomy_id)) render 'admin/simple_crud/new' diff --git a/app/controllers/api/v1/taxon_concepts_controller.rb b/app/controllers/api/v1/taxon_concepts_controller.rb index aee1538473..aa7350f132 100644 --- a/app/controllers/api/v1/taxon_concepts_controller.rb +++ b/app/controllers/api/v1/taxon_concepts_controller.rb @@ -1,6 +1,6 @@ class Api::V1::TaxonConceptsController < ApplicationController - #makes params available to the ActiveModel::Serializers + # makes params available to the ActiveModel::Serializers serialization_scope :view_context after_filter :track_index, :only => :index after_filter :track_show, :only => :show diff --git a/app/helpers/admin_helper.rb b/app/helpers/admin_helper.rb index 3157f873bf..27ca369049 100644 --- a/app/helpers/admin_helper.rb +++ b/app/helpers/admin_helper.rb @@ -141,7 +141,7 @@ def admin_new_modal(options = {}) ) { title } end + content_tag( - :div, :id => "admin-#{id}-form", :class => "modal-body" #TODO + :div, :id => "admin-#{id}-form", :class => "modal-body" # TODO ) do if block_given? yield diff --git a/app/models/checklist/checklist.rb b/app/models/checklist/checklist.rb index 903d25070a..ee97238c3f 100644 --- a/app/models/checklist/checklist.rb +++ b/app/models/checklist/checklist.rb @@ -54,7 +54,7 @@ def initialize_query @taxon_concepts_rel = @taxon_concepts_rel.at_level_of_listing end - #order + # order @taxon_concepts_rel = if @output_layout == :taxonomic @taxon_concepts_rel.taxonomic_layout @@ -89,7 +89,7 @@ def generate injector = Checklist::HigherTaxaInjector.new(@plantae) @plantae = injector.run end - [self] #TODO: just for compatibility with frontend, no sensible reason for this + [self] # TODO: just for compatibility with frontend, no sensible reason for this end # Converts a list of search filters into a limited length @@ -166,7 +166,7 @@ def self.summarise_filters(params) end end - #TODO: common names, authors + # TODO: common names, authors if summary.length > 0 summary.join(" ") diff --git a/app/models/checklist/checklist_params.rb b/app/models/checklist/checklist_params.rb index cdd5a90875..50cfb0163d 100644 --- a/app/models/checklist/checklist_params.rb +++ b/app/models/checklist/checklist_params.rb @@ -6,16 +6,16 @@ class Checklist::ChecklistParams < Hash def initialize(params) sanitized_params = { - #possible output layouts are: - #taxonomic (hierarchic, taxonomic order) - #alphabetical (flat, alphabetical order) + # possible output layouts are: + # taxonomic (hierarchic, taxonomic order) + # alphabetical (flat, alphabetical order) output_layout: whitelist_param( sanitise_symbol(params[:output_layout]), [:taxonomic, :alphabetical, :appendix], :alphabetical ), level_of_listing: sanitise_boolean(params[:level_of_listing], false), - #filtering options + # filtering options scientific_name: sanitise_upcase_string(params[:scientific_name]), countries: sanitise_integer_array(params[:country_ids]), cites_regions: sanitise_integer_array(params[:cites_region_ids]), diff --git a/app/models/checklist/higher_taxa_injector.rb b/app/models/checklist/higher_taxa_injector.rb index 2b673716a2..58a82c4062 100644 --- a/app/models/checklist/higher_taxa_injector.rb +++ b/app/models/checklist/higher_taxa_injector.rb @@ -36,7 +36,7 @@ def run end def run_summary - @expand_headers = false #use this only for collapsed headers + @expand_headers = false # use this only for collapsed headers # such as the Checklist or Species+ website res = [] current_higher_taxon = nil @@ -62,8 +62,8 @@ def run_summary res end - #returns array of HigherTaxaItems that need to be inserted - #between prev_item and curr_item in the taxonomic layout + # returns array of HigherTaxaItems that need to be inserted + # between prev_item and curr_item in the taxonomic layout def higher_taxa_headers(prev_item, curr_item) ranks = if prev_item.nil? diff --git a/app/models/checklist/higher_taxa_item.rb b/app/models/checklist/higher_taxa_item.rb index 38a0aec219..507a268a0e 100644 --- a/app/models/checklist/higher_taxa_item.rb +++ b/app/models/checklist/higher_taxa_item.rb @@ -30,7 +30,7 @@ def ancestors_ids end.join(',') end - #use method_missing to delegate taxon concept methods + # use method_missing to delegate taxon concept methods def method_missing(method_sym, *arguments, &block) # the first argument is a Symbol, so you need to_s it if you want to pattern match if @taxon_concept.respond_to? method_sym diff --git a/app/models/checklist/pdf/document.rb b/app/models/checklist/pdf/document.rb index 0692c79853..bf41ed5f20 100644 --- a/app/models/checklist/pdf/document.rb +++ b/app/models/checklist/pdf/document.rb @@ -47,7 +47,7 @@ def document yield tex end output = LatexToPdf.generate_pdf_from_file(tmp_dir_path, @input_name) - #save output at download path + # save output at download path FileUtils.cp output, @download_path FileUtils.rm_rf(tmp_dir_path) end diff --git a/app/models/checklist/pdf/history_content.rb b/app/models/checklist/pdf/history_content.rb index 4905a8b642..0d208066b5 100644 --- a/app/models/checklist/pdf/history_content.rb +++ b/app/models/checklist/pdf/history_content.rb @@ -53,9 +53,9 @@ def listed_taxa(tex, listed_taxa_ary, kingdom_name = 'FAUNA') rows = [] listed_taxa_ary.each do |tc| listed_taxon_name = listed_taxon_name(tc) - is_tc_row = true #it is the first row per taxon concept + is_tc_row = true # it is the first row per taxon concept tc.historic_cites_listing_changes_for_downloads.each do |lc| - is_lc_row = true #it is the first row per listing change + is_lc_row = true # it is the first row per listing change ann = annotation_for_language(lc, I18n.locale) row = [] # tc fields diff --git a/app/models/checklist/pdf/index_content.rb b/app/models/checklist/pdf/index_content.rb index fc8bb2d382..e8141133d2 100644 --- a/app/models/checklist/pdf/index_content.rb +++ b/app/models/checklist/pdf/index_content.rb @@ -16,7 +16,7 @@ def kingdom(tex, fetcher, kingdom_name) kingdom = fetcher.next return if kingdom.empty? tex << "\\cpart{#{kingdom_name}}\n" - tex << "\\begin{multicols}{2}{" #start multicols + tex << "\\begin{multicols}{2}{" # start multicols begin entries = kingdom.map do |tc| if tc.read_attribute(:name_type) == 'synonym' @@ -30,7 +30,7 @@ def kingdom(tex, fetcher, kingdom_name) tex << entries.join("\n\n") kingdom = fetcher.next end while !kingdom.empty? - tex << '}\\end{multicols}' #end multicols + tex << '}\\end{multicols}' # end multicols end def synonym_entry(tc) diff --git a/app/models/checklist/pdf/index_query.rb b/app/models/checklist/pdf/index_query.rb index b50987f24a..a5daf45405 100644 --- a/app/models/checklist/pdf/index_query.rb +++ b/app/models/checklist/pdf/index_query.rb @@ -6,8 +6,8 @@ def initialize(rel, options) @french_common_names = options[:french_common_names] @synonyms = options[:synonyms] @authors = options[:authors] - #we want common names and synonyms returned as separate records - #and sorted alphabetically + # we want common names and synonyms returned as separate records + # and sorted alphabetically shared_columns = [:full_name, :rank_name, :family_name, :class_name, :cites_accepted, :cites_listing, :ann_symbol, :hash_ann_symbol] diff --git a/app/models/checklist/timeline.rb b/app/models/checklist/timeline.rb index ed9f3f8a4e..a5d29c6ea5 100644 --- a/app/models/checklist/timeline.rb +++ b/app/models/checklist/timeline.rb @@ -102,10 +102,10 @@ def add_intervals def get_party_timeline(party_id) unless (party_idx = @parties.index(party_id)).nil? - #fetch existing party timeline + # fetch existing party timeline @timelines[party_idx] else - #create party timeline + # create party timeline @parties << party_id party_timeline = Checklist::Timeline.new( :taxon_concept_id => @taxon_concept_id, diff --git a/app/models/checklist/timeline_event.rb b/app/models/checklist/timeline_event.rb index 888ca1a4c9..20f6c1b3f8 100644 --- a/app/models/checklist/timeline_event.rb +++ b/app/models/checklist/timeline_event.rb @@ -4,7 +4,7 @@ class Checklist::TimelineEvent :party_id, :is_current, :pos, :auto_note, :short_note, :full_note, :hash_full_note, :hash_ann_symbol, :hash_ann_parent_symbol, :inherited_short_note, :inherited_full_note, :nomenclature_note - #options to be passed: + # options to be passed: #:change_type_name #:effective_at #:is_current diff --git a/app/models/checklist/timeline_interval.rb b/app/models/checklist/timeline_interval.rb index 8b5ef1b85a..d5028cbe30 100644 --- a/app/models/checklist/timeline_interval.rb +++ b/app/models/checklist/timeline_interval.rb @@ -1,7 +1,7 @@ class Checklist::TimelineInterval include ActiveModel::SerializerSupport attr_accessor :id, :start_pos, :end_pos - #options to be passed: + # options to be passed: #:start_pos - start position (%) #:end_pos - end position (%) def initialize(options) diff --git a/app/models/checklist/timeline_year.rb b/app/models/checklist/timeline_year.rb index 76014bc53f..8f0fb5a1f2 100644 --- a/app/models/checklist/timeline_year.rb +++ b/app/models/checklist/timeline_year.rb @@ -1,7 +1,7 @@ class Checklist::TimelineYear include ActiveModel::SerializerSupport attr_accessor :id, :year, :pos - #options to be passed: + # options to be passed: #:year - year on the timeline #:pos - position (%) def initialize(options) diff --git a/app/models/cites_suspension.rb b/app/models/cites_suspension.rb index ad32f05db2..3d025acb6b 100644 --- a/app/models/cites_suspension.rb +++ b/app/models/cites_suspension.rb @@ -55,8 +55,8 @@ def handle_current_flag true end - #Each element of CSV columns can be either an array [display_text, method] - #or a single symbol if the display text and the method are the same + # Each element of CSV columns can be either an array [display_text, method] + # or a single symbol if the display text and the method are the same CSV_COLUMNS = [ [:start_date, :start_date_formatted], [:start_notification, :start_notification_name], [:end_date, :end_date_formatted], [:end_notification, :end_notification_name], diff --git a/app/models/common_name.rb b/app/models/common_name.rb index c68375dc55..d4b18a1de7 100644 --- a/app/models/common_name.rb +++ b/app/models/common_name.rb @@ -25,10 +25,10 @@ def self.english_to_pdf(common_name) words.last + ", " + common_name.chomp(" " + words.last) end - #attribute_accessor to convert postgresql "t" or "f" to a Ruby boolean - #used in app/serializeres/species/show_taxon_concept_serializer.rb - #for distinguishing between official CITES languages an non official languages - #might need to be reviewed: TODO + # attribute_accessor to convert postgresql "t" or "f" to a Ruby boolean + # used in app/serializeres/species/show_taxon_concept_serializer.rb + # for distinguishing between official CITES languages an non official languages + # might need to be reviewed: TODO def convention_language ActiveRecord::ConnectionAdapters::Column.value_to_boolean(self[:convention_language]) end diff --git a/app/models/dashboard_stats.rb b/app/models/dashboard_stats.rb index 3702ca194a..6c639ff7f5 100644 --- a/app/models/dashboard_stats.rb +++ b/app/models/dashboard_stats.rb @@ -9,8 +9,8 @@ def initialize(geo_entity, options) @geo_entity = geo_entity @kingdom = options[:kingdom] || 'Animalia' @trade_limit = options[:trade_limit] - @time_range_start = options[:time_range_start] || (Time.now.year - 7) #2007 - @time_range_end = options[:time_range_end] || (Time.now.year - 2) #2012 + @time_range_start = options[:time_range_start] || (Time.now.year - 7) # 2007 + @time_range_end = options[:time_range_end] || (Time.now.year - 2) # 2012 end def species diff --git a/app/models/listing_change_observer.rb b/app/models/listing_change_observer.rb index a6e87e4877..4fee64ffd4 100644 --- a/app/models/listing_change_observer.rb +++ b/app/models/listing_change_observer.rb @@ -1,7 +1,7 @@ class ListingChangeObserver < ActiveRecord::Observer def before_save(listing_change) - #check if annotation should be deleted + # check if annotation should be deleted if listing_change.annotation && listing_change.annotation.short_note_en.blank? && listing_change.annotation.short_note_fr.blank? && @@ -25,7 +25,7 @@ def before_save(listing_change) ChangeType::EXCEPTION, original_change_type.designation_id ) - #geographic exclusions + # geographic exclusions excluded_geo_entities_ids = listing_change.excluded_geo_entities_ids && listing_change.excluded_geo_entities_ids.reject(&:blank?) excluded_geo_entities = @@ -38,7 +38,7 @@ def before_save(listing_change) ) end - #taxonomic exclusions + # taxonomic exclusions excluded_taxon_concepts_ids = listing_change.excluded_taxon_concepts_ids && listing_change.excluded_taxon_concepts_ids.split(',').reject(&:blank?) excluded_taxon_concepts = diff --git a/app/models/quota.rb b/app/models/quota.rb index 7318e96888..a706d3b316 100644 --- a/app/models/quota.rb +++ b/app/models/quota.rb @@ -38,8 +38,8 @@ class Quota < TradeRestriction validates :quota, :numericality => { :greater_than_or_equal_to => -1.0 } validates :geo_entity_id, :presence => true - #Each element of CSV columns can be either an array [display_text, method] - #or a single symbol if the display text and the method are the same + # Each element of CSV columns can be either an array [display_text, method] + # or a single symbol if the display text and the method are the same CSV_COLUMNS = [ :year, :party, :quota, [:unit, :unit_name], :publication_date, diff --git a/app/models/species/restrictions_export.rb b/app/models/species/restrictions_export.rb index 17981ae2bb..7155c7722b 100644 --- a/app/models/species/restrictions_export.rb +++ b/app/models/species/restrictions_export.rb @@ -34,7 +34,7 @@ def self.fill_taxon_columns(restriction) else taxon = nil end - return [""] * (TAXONOMY_COLUMNS.size + 1) unless taxon #return array with empty strings + return [""] * (TAXONOMY_COLUMNS.size + 1) unless taxon # return array with empty strings TAXONOMY_COLUMNS.each do |c| columns << taxon.send(c) end diff --git a/app/models/species/search_params.rb b/app/models/species/search_params.rb index aa097ac6b4..3e2a38264a 100644 --- a/app/models/species/search_params.rb +++ b/app/models/species/search_params.rb @@ -6,19 +6,19 @@ class Species::SearchParams < Hash def initialize(params) sanitized_params = { - #possible taxonomies are cms and cites_eu + # possible taxonomies are cms and cites_eu taxonomy: whitelist_param( sanitise_symbol(params[:taxonomy]), [:cites_eu, :cms], :cites_eu ), - #possible geo_entity_scope values are: cites, eu, occurrences + # possible geo_entity_scope values are: cites, eu, occurrences geo_entity_scope: whitelist_param( sanitise_symbol(params[:geo_entity_scope]), [:cites, :eu, :cms], :cites ), - #filtering options + # filtering options taxon_concept_query: sanitise_upcase_string(params[:taxon_concept_query]), geo_entities: sanitise_integer_array(params[:geo_entities_ids]), higher_taxa_ids: sanitise_integer_array(params[:higher_taxa_ids]), diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index abf276ce3c..6d9e334515 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -454,11 +454,11 @@ def dependent_objects_map end def self.sanitize_full_name(some_full_name) - #strip ranks + # strip ranks if some_full_name =~ /\A(.+)\s+(#{Rank.dict.join('|')})\s*\Z/ some_full_name = $1 end - #strip redundant whitespace between words + # strip redundant whitespace between words some_full_name = some_full_name.split(/\s/).join(' ').capitalize end diff --git a/app/models/taxon_concept_prefix_matcher.rb b/app/models/taxon_concept_prefix_matcher.rb index 6734cd4ad2..c6c3e29486 100644 --- a/app/models/taxon_concept_prefix_matcher.rb +++ b/app/models/taxon_concept_prefix_matcher.rb @@ -34,13 +34,13 @@ def apply_rank_options_to_rel @rank_scope = @rank_options[:scope] || '' rank = Rank.find(@rank_id) if @rank_scope if @rank_scope.to_sym == :parent - #search at parent ranks. this includes optional ranks, e.g. subfamily + # search at parent ranks. this includes optional ranks, e.g. subfamily @taxon_concepts = @taxon_concepts.at_parent_ranks(rank) elsif @rank_scope.to_sym == :ancestors - #search at ancestor ranks + # search at ancestor ranks @taxon_concepts = @taxon_concepts.at_ancestor_ranks(rank) elsif @rank_scope.to_sym == :self_and_ancestors - #search at self and ancestor ranks + # search at self and ancestor ranks @taxon_concepts = @taxon_concepts.at_self_and_ancestor_ranks(rank) end end diff --git a/app/models/taxon_relationship.rb b/app/models/taxon_relationship.rb index 73c22404bc..636635b87e 100644 --- a/app/models/taxon_relationship.rb +++ b/app/models/taxon_relationship.rb @@ -75,7 +75,7 @@ def destroy_opposite delete_all end - #A taxon concept can only be related with another taxon concept through + # A taxon concept can only be related with another taxon concept through # ONE intertaxonomic Taxon Relationship. Unless the TaxonRelationships # share the same TaxonRelationshipType and this is bidirectional def intertaxonomic_relationship_uniqueness diff --git a/app/models/trade/annual_report_upload.rb b/app/models/trade/annual_report_upload.rb index 079d8b141a..bf436a3ab0 100644 --- a/app/models/trade/annual_report_upload.rb +++ b/app/models/trade/annual_report_upload.rb @@ -74,20 +74,20 @@ def submit return false end return false unless sandbox.copy_from_sandbox_to_shipments - #remove uploaded file + # remove uploaded file store_dir = csv_source_file.store_dir remove_csv_source_file! puts '### removing uploads dir ###' puts Rails.root.join('public', store_dir) FileUtils.remove_dir(Rails.root.join('public', store_dir), :force => true) - #remove sandbox table + # remove sandbox table sandbox.destroy - #clear downloads cache + # clear downloads cache DownloadsCacheCleanupWorker.perform_async(:shipments) - #flag as submitted + # flag as submitted update_attribute(:is_done, true) end diff --git a/app/models/trade/filter.rb b/app/models/trade/filter.rb index de8db082e3..d315c71b53 100644 --- a/app/models/trade/filter.rb +++ b/app/models/trade/filter.rb @@ -142,7 +142,7 @@ def initialize_query def initialize_internal_query if @report_type == :raw - #includes would override the select clause + # includes would override the select clause @query = @query.preload(:reported_taxon_concept) end diff --git a/app/models/trade/permit_matcher.rb b/app/models/trade/permit_matcher.rb index df779618fe..8faf85806d 100644 --- a/app/models/trade/permit_matcher.rb +++ b/app/models/trade/permit_matcher.rb @@ -33,10 +33,10 @@ def initialize_query end def sanitize_permit_query(query) - #negative limit does not suppress trailing nulls + # negative limit does not suppress trailing nulls query_parts = query.upcase.strip.split('%', -1).map do |qp| if qp.blank? - '%' #replace the wildcard + '%' # replace the wildcard else ActiveRecord::Base.connection.quote_string(qp) end diff --git a/app/models/trade/sandbox.rb b/app/models/trade/sandbox.rb index da76cc9ad8..026d88b352 100644 --- a/app/models/trade/sandbox.rb +++ b/app/models/trade/sandbox.rb @@ -44,7 +44,7 @@ def shipments end def shipments=(new_shipments) - #TODO: handle errors + # TODO: handle errors new_shipments.each do |shipment| s = @ar_klass.find_by_id(shipment.delete('id')) s.delete_or_update_attributes(shipment) diff --git a/app/models/trade/shipment.rb b/app/models/trade/shipment.rb index 5d4e6bbdaf..28c68d16ea 100644 --- a/app/models/trade/shipment.rb +++ b/app/models/trade/shipment.rb @@ -76,7 +76,7 @@ class Trade::Shipment < ActiveRecord::Base after_validation do unless self.errors.empty? && self.ignore_warnings - #inject warnings here + # inject warnings here warnings.each { |w| self.errors[:warnings] << w } end end diff --git a/app/models/trade/shipments_gross_exports_export.rb b/app/models/trade/shipments_gross_exports_export.rb index b217532024..f2b1638fb8 100644 --- a/app/models/trade/shipments_gross_exports_export.rb +++ b/app/models/trade/shipments_gross_exports_export.rb @@ -99,7 +99,7 @@ def ct_subquery_sql(options) source_sql = "SELECT ARRAY[#{sql_row_name_columns.join(', ')}], #{sql_crosstab_columns.join(', ')}, year, gross_quantity FROM (#{subquery_sql(options)}) subquery - ORDER BY 1, #{sql_crosstab_columns.length + 2}" #order by row_name and year + ORDER BY 1, #{sql_crosstab_columns.length + 2}" # order by row_name and year source_sql = ActiveRecord::Base.send(:sanitize_sql_array, [source_sql, years]) source_sql = ActiveRecord::Base.connection.quote_string(source_sql) # the categories query returns values by which to pivot (years) diff --git a/app/models/trade/validation_rule.rb b/app/models/trade/validation_rule.rb index e1da8a0c0c..5b64cce0d3 100644 --- a/app/models/trade/validation_rule.rb +++ b/app/models/trade/validation_rule.rb @@ -69,8 +69,8 @@ def validation_errors(annual_report_upload) end def validation_errors_for_shipment(shipment) - return nil if is_primary #primary validations are handled by AR #raise "Not implemented" + return nil if is_primary # primary validations are handled by AR 'shipment validation not implemented' end diff --git a/app/models/trade_restriction.rb b/app/models/trade_restriction.rb index 71c26bcf58..3e08e775bc 100644 --- a/app/models/trade_restriction.rb +++ b/app/models/trade_restriction.rb @@ -120,7 +120,7 @@ def self.export_query(filters) trade_restrictions.notes ASC') end - #Gets the display text for each CSV_COLUMNS + # Gets the display text for each CSV_COLUMNS def self.csv_columns_headers self::CSV_COLUMNS.map do |b| Array(b).first diff --git a/app/serializers/checklist/checklist_serializer.rb b/app/serializers/checklist/checklist_serializer.rb index 59c9e00414..fde998b946 100644 --- a/app/serializers/checklist/checklist_serializer.rb +++ b/app/serializers/checklist/checklist_serializer.rb @@ -1,6 +1,6 @@ class Checklist::ChecklistSerializer < ActiveModel::Serializer cached - attributes :result_cnt, :total_cnt #TODO: move this to a meta object for consistency with Species+ + attributes :result_cnt, :total_cnt # TODO: move this to a meta object for consistency with Species+ has_many :animalia, :serializer => Checklist::TaxonConceptSerializer has_many :plantae, :serializer => Checklist::TaxonConceptSerializer diff --git a/app/serializers/checklist/taxon_concept_serializer.rb b/app/serializers/checklist/taxon_concept_serializer.rb index 980878e229..7ca7eca5c1 100644 --- a/app/serializers/checklist/taxon_concept_serializer.rb +++ b/app/serializers/checklist/taxon_concept_serializer.rb @@ -12,7 +12,7 @@ class Checklist::TaxonConceptSerializer < ActiveModel::Serializer def id if object.is_a? Checklist::HigherTaxaItem - object.id + 1000000 #unless ids differ, Ember will create a single object + object.id + 1000000 # unless ids differ, Ember will create a single object else object.id end diff --git a/config/deploy.rb b/config/deploy.rb index 5ba1a35cd8..04166eebc4 100644 --- a/config/deploy.rb +++ b/config/deploy.rb @@ -102,7 +102,7 @@ class PrecompileRequired < StandardError; end set :slack_room, "#speciesplus" # the room to send the message to set :slack_subdomain, "wcmc" # if your subdomain is example.slack.com -#optional +# optional set :slack_application, "SAPI" # override Capistrano `application` deployment_animals = [ ["Loxodonta deployana", ":elephant:"], diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index c3d3e19fac..7b4608ec3b 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -254,7 +254,7 @@ # so you need to do it manually. For the users scope, it would be: # config.omniauth_path_prefix = '/my_engine/users/auth' - #use custom layouts for devise + # use custom layouts for devise Rails.application.config.to_prepare do Devise::RegistrationsController.layout "pages" Devise::PasswordsController.layout "pages" @@ -262,7 +262,7 @@ Devise::PasswordsController.after_filter :delete_email, only: [:update] end - #custom redirection when login fails + # custom redirection when login fails config.warden do |manager| manager.failure_app = CustomFailure end diff --git a/config/routes.rb b/config/routes.rb index b3b56d3b8c..8f3237503d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -202,7 +202,7 @@ end namespace :checklist do - resources :geo_entities, :only => [:index] #TODO: move to API + resources :geo_entities, :only => [:index] # TODO: move to API resources :downloads do member do get :download diff --git a/db/migrate/20141223141125_timestamp_view_definitions.rb b/db/migrate/20141223141125_timestamp_view_definitions.rb index 61590f4c76..cca0de98f6 100644 --- a/db/migrate/20141223141125_timestamp_view_definitions.rb +++ b/db/migrate/20141223141125_timestamp_view_definitions.rb @@ -33,7 +33,7 @@ def change execute "CREATE VIEW valid_taxon_concept_country_of_origin_view AS #{view_sql('20141223141125', 'valid_taxon_concept_country_of_origin_view')}" execute "DROP VIEW IF EXISTS valid_taxon_concept_exporter_view" execute "CREATE VIEW valid_taxon_concept_exporter_view AS #{view_sql('20141223141125', 'valid_taxon_concept_exporter_view')}" - execute "DROP VIEW IF EXISTS valid_taxon_concept_country_view" #obsolete view + execute "DROP VIEW IF EXISTS valid_taxon_concept_country_view" # obsolete view execute "DROP VIEW IF EXISTS valid_taxon_concept_term_view" execute "CREATE VIEW valid_taxon_concept_term_view AS #{view_sql('20141223141125', 'valid_taxon_concept_term_view')}" execute "DROP VIEW IF EXISTS valid_taxon_name_view" diff --git a/lib/modules/dictionary.rb b/lib/modules/dictionary.rb index 07e1457185..7223d3f9d6 100644 --- a/lib/modules/dictionary.rb +++ b/lib/modules/dictionary.rb @@ -5,8 +5,8 @@ def self.included(base) end module ClassMethods - #builds a set of constants like: KEY = 'KEY' - #as well as a method self.dict that returns all of those constants' values + # builds a set of constants like: KEY = 'KEY' + # as well as a method self.dict that returns all of those constants' values def build_dictionary(*keys) # keys.each do |key| # const_set key.to_s.upcase, key.to_s.upcase diff --git a/lib/modules/latex_to_pdf.rb b/lib/modules/latex_to_pdf.rb index 1fb0be8ebb..98c07d41d0 100644 --- a/lib/modules/latex_to_pdf.rb +++ b/lib/modules/latex_to_pdf.rb @@ -74,7 +74,7 @@ def latex_esc(text) # :nodoc: # :startdoc: end - @latex_escaper.latex_esc(text.to_s) #.html_safe + @latex_escaper.latex_esc(text.to_s) # .html_safe end def self.html2latex(text) diff --git a/lib/tasks/helpers_for_import.rb b/lib/tasks/helpers_for_import.rb index ecfd04615d..51789a8420 100644 --- a/lib/tasks/helpers_for_import.rb +++ b/lib/tasks/helpers_for_import.rb @@ -71,7 +71,7 @@ class CsvToDbMap 'name_es' => 'name_es varchar', 'name_fr' => 'name_fr varchar' }, - #TODO: legacy type for countries? + # TODO: legacy type for countries? 'countries_import' => { 'ISO2' => 'iso2 varchar', 'short_name' => 'name varchar', @@ -346,7 +346,7 @@ def files_from_args(t, args) end def file_ok?(path_to_file) - if !File.file?(Rails.root.join(path_to_file)) #if the file is not defined, explain and leave. + if !File.file?(Rails.root.join(path_to_file)) # if the file is not defined, explain and leave. puts "Please specify a valid csv file from which to import data" puts "Usage: rake import:XXX[path/to/file,path/to/another]" return false @@ -365,7 +365,7 @@ def csv_headers(path_to_file) def db_columns_from_csv_headers(path_to_file, table_name, include_data_type = true) m = CsvToDbMap.instance - #work out the db columns to create + # work out the db columns to create csv_columns = csv_headers(path_to_file) db_columns = csv_columns.map { |col| m.csv_to_db(table_name, col) } db_columns = db_columns.map { |col| col.sub(/\s\w+$/, '') } unless include_data_type diff --git a/lib/tasks/import_cites_listings.rake b/lib/tasks/import_cites_listings.rake index c36b44b440..800bc456a4 100644 --- a/lib/tasks/import_cites_listings.rake +++ b/lib/tasks/import_cites_listings.rake @@ -120,7 +120,7 @@ namespace :import do puts "INSERTING listing_changes" ActiveRecord::Base.connection.execute(sql) - #add taxonomic exceptions + # add taxonomic exceptions sql = <<-SQL INSERT INTO listing_changes (parent_id, taxon_concept_id, species_listing_id, change_type_id, effective_at, is_current, created_at, updated_at) SELECT * FROM ( @@ -157,7 +157,7 @@ namespace :import do puts "INSERTING taxonomic exceptions" ActiveRecord::Base.connection.execute(sql) - #add population exceptions + # add population exceptions sql = <<-SQL WITH exceptions AS ( -- first insert the exception records -- there's just one / listing change diff --git a/lib/tasks/import_cites_quotas.rake b/lib/tasks/import_cites_quotas.rake index f5afdc7169..ef51a38091 100644 --- a/lib/tasks/import_cites_quotas.rake +++ b/lib/tasks/import_cites_quotas.rake @@ -58,7 +58,7 @@ namespace :import do ActiveRecord::Base.connection.execute(sql) - #Add Terms & Sources Relationships + # Add Terms & Sources Relationships ["terms", "sources"].each do |code| sql = <<-SQL WITH #{code}_codes_per_quota AS ( diff --git a/lib/tasks/import_cms_listings.rake b/lib/tasks/import_cms_listings.rake index 59fc383100..5a253e5d44 100644 --- a/lib/tasks/import_cms_listings.rake +++ b/lib/tasks/import_cms_listings.rake @@ -110,7 +110,7 @@ namespace :import do puts "INSERTING listing_changes" ActiveRecord::Base.connection.execute(sql) - #add taxonomic exceptions + # add taxonomic exceptions sql = <<-SQL INSERT INTO listing_changes (parent_id, taxon_concept_id, species_listing_id, change_type_id, effective_at, is_current, created_at, updated_at) SELECT * FROM ( @@ -145,7 +145,7 @@ namespace :import do puts "INSERTING taxonomic exceptions" ActiveRecord::Base.connection.execute(sql) - #add population exceptions + # add population exceptions sql = <<-SQL WITH exceptions AS ( -- first insert the exception records -- there's just one / listing change diff --git a/lib/tasks/import_distribution_tags.rake b/lib/tasks/import_distribution_tags.rake index 2157a72081..54d491f9a2 100644 --- a/lib/tasks/import_distribution_tags.rake +++ b/lib/tasks/import_distribution_tags.rake @@ -11,7 +11,7 @@ namespace :import do kingdom = file.split('/').last.split('_')[0].titleize - #import all distinct tags to both PresetTags and Tags table + # import all distinct tags to both PresetTags and Tags table puts "There are #{PresetTag.where(:model => 'Distribution').count} distribution tags" puts "There are #{ActiveRecord::Base.connection.execute('SELECT COUNT(*) FROM tags').first["count"]} tags in the tags table" puts "ADDING: preset_tags and tags" diff --git a/lib/tasks/import_distributions.rake b/lib/tasks/import_distributions.rake index 02742319a7..2c5d5b99c1 100644 --- a/lib/tasks/import_distributions.rake +++ b/lib/tasks/import_distributions.rake @@ -41,7 +41,7 @@ namespace :import do ) AS subquery SQL - #TODO: do sth about those unknown distributions! + # TODO: do sth about those unknown distributions! ActiveRecord::Base.connection.execute(sql) end end diff --git a/lib/tasks/import_eu_listings.rake b/lib/tasks/import_eu_listings.rake index a01ea28bd0..d0e1b27eb7 100644 --- a/lib/tasks/import_eu_listings.rake +++ b/lib/tasks/import_eu_listings.rake @@ -110,7 +110,7 @@ namespace :import do puts "INSERTING listing_changes" ActiveRecord::Base.connection.execute(sql) - #add taxonomic exceptions + # add taxonomic exceptions sql = <<-SQL INSERT INTO listing_changes (parent_id, taxon_concept_id, species_listing_id, change_type_id, effective_at, is_current, created_at, updated_at) SELECT * FROM ( @@ -147,7 +147,7 @@ namespace :import do puts "INSERTING taxonomic exceptions" ActiveRecord::Base.connection.execute(sql) - #add population exceptions + # add population exceptions sql = <<-SQL WITH exceptions AS ( -- first insert the exception records -- there's just one / listing change diff --git a/lib/tasks/import_species.rake b/lib/tasks/import_species.rake index bf070bdb87..16255fb6e7 100644 --- a/lib/tasks/import_species.rake +++ b/lib/tasks/import_species.rake @@ -12,7 +12,7 @@ namespace :import do kingdom = file.split('/').last.split('_')[0].titleize - #import_data_for Rank::KINGDOM + # import_data_for Rank::KINGDOM import_data_for kingdom, Rank::PHYLUM import_data_for kingdom, Rank::CLASS import_data_for kingdom, Rank::ORDER diff --git a/lib/tasks/import_standard_reference_links.rake b/lib/tasks/import_standard_reference_links.rake index 2cdf32801b..4198b9a981 100644 --- a/lib/tasks/import_standard_reference_links.rake +++ b/lib/tasks/import_standard_reference_links.rake @@ -37,7 +37,7 @@ namespace :import do ActiveRecord::Base.connection.execute(sql) puts "inserting reference links" - #add taxon_concept_references where missing + # add taxon_concept_references where missing sql = <<-SQL INSERT INTO "taxon_concept_references" (taxon_concept_id, reference_id, created_at, updated_at) SELECT taxon_concepts.id, "references".id, NOW(), NOW() @@ -62,7 +62,7 @@ namespace :import do ActiveRecord::Base.connection.execute(sql) puts "updating standard reference links" - #update usr_std_ref flags + # update usr_std_ref flags sql = <<-SQL WITH standard_references_as_ids AS ( WITH standard_references_per_exclusion AS ( diff --git a/lib/tasks/import_synonyms.rake b/lib/tasks/import_synonyms.rake index b1c585279a..13f15778f0 100644 --- a/lib/tasks/import_synonyms.rake +++ b/lib/tasks/import_synonyms.rake @@ -20,7 +20,7 @@ namespace :import do kingdom = file.split('/').last.split('_')[0].titleize - #[BEGIN]copied over from import:species + # [BEGIN]copied over from import:species import_data_for kingdom, Rank::PHYLUM, true import_data_for kingdom, Rank::CLASS, true import_data_for kingdom, Rank::ORDER, true @@ -32,7 +32,7 @@ namespace :import do if kingdom == 'Plantae' import_data_for kingdom, Rank::VARIETY end - #[END]copied over from import:species + # [END]copied over from import:species [Taxonomy::CITES_EU, Taxonomy::CMS].each do |taxonomy_name| puts "Import #{taxonomy_name} taxa" diff --git a/lib/tasks/import_trade_shipments.rake b/lib/tasks/import_trade_shipments.rake index c40c2bdc52..2ae14b5c7a 100644 --- a/lib/tasks/import_trade_shipments.rake +++ b/lib/tasks/import_trade_shipments.rake @@ -67,7 +67,7 @@ namespace :import do ActiveRecord::Base.connection.execute(sql) end update_country_codes - #populate_shipments + # populate_shipments populate_shipments_for_trade_names Sapi::Indexes.create_indexes_on_shipments end diff --git a/lib/tasks/update_eu_decisions_with_missing_source.rake b/lib/tasks/update_eu_decisions_with_missing_source.rake index 4908d7fc99..ab43b42329 100644 --- a/lib/tasks/update_eu_decisions_with_missing_source.rake +++ b/lib/tasks/update_eu_decisions_with_missing_source.rake @@ -5,7 +5,7 @@ namespace :update do drop_table(TMP_TABLE) db_columns = ['full_name', 'rank_name', 'start_date', 'party_name', 'decision_type', 'source_code', 'term_code', 'notes'] create_table_from_column_array(TMP_TABLE, db_columns.map { |c| "#{c} TEXT" }) - #Full Name Rank Date of Decision Party EU Decision Source Term Notes + # Full Name Rank Date of Decision Party EU Decision Source Term Notes copy_data_into_table(file, TMP_TABLE, db_columns) wild_source = Source.find_by_code('W') diff --git a/spec/controllers/admin/taxon_commons_controller_spec.rb b/spec/controllers/admin/taxon_commons_controller_spec.rb index 30b05ed69f..61fe953185 100644 --- a/spec/controllers/admin/taxon_commons_controller_spec.rb +++ b/spec/controllers/admin/taxon_commons_controller_spec.rb @@ -118,8 +118,8 @@ @taxon_concept.dependents_updated_at.should be_nil - #it gets updated by the creation of the taxon_common - #but object needs to be reloaded + # it gets updated by the creation of the taxon_common + # but object needs to be reloaded @taxon_concept.reload.dependents_updated_at.should_not be_nil old_date = @taxon_concept.dependents_updated_at @@ -139,8 +139,8 @@ @taxon_concept.dependents_updated_at.should be_nil - #it gets updated by the creation of the taxon_common - #but object needs to be reloaded + # it gets updated by the creation of the taxon_common + # but object needs to be reloaded @taxon_concept.reload.dependents_updated_at.should_not be_nil old_date = @taxon_concept.dependents_updated_at diff --git a/spec/models/species/orphaned_taxon_concepts_export_spec.rb b/spec/models/species/orphaned_taxon_concepts_export_spec.rb index aa394cd69b..57b2854174 100644 --- a/spec/models/species/orphaned_taxon_concepts_export_spec.rb +++ b/spec/models/species/orphaned_taxon_concepts_export_spec.rb @@ -16,7 +16,7 @@ context "when results" do before(:each) { tc = create(:taxon_concept) - tc.update_attribute(:parent_id, nil) #skipping validations + tc.update_attribute(:parent_id, nil) # skipping validations FileUtils.mkpath( File.expand_path("spec/public/downloads/orphaned_taxon_concepts") ) diff --git a/spec/models/species/taxon_concept_prefix_matcher_spec.rb b/spec/models/species/taxon_concept_prefix_matcher_spec.rb index 3099428047..77070fb1ac 100644 --- a/spec/models/species/taxon_concept_prefix_matcher_spec.rb +++ b/spec/models/species/taxon_concept_prefix_matcher_spec.rb @@ -105,7 +105,7 @@ } specify { subject.results.should include(@family_ac) } end - #check ranks filtering + # check ranks filtering context "when explicitly listed higher taxon but ranks expected FAMILY" do subject { Species::TaxonConceptPrefixMatcher.new({ diff --git a/spec/models/trade/annual_report_upload_spec.rb b/spec/models/trade/annual_report_upload_spec.rb index 6a8377a7f5..0210f12be5 100644 --- a/spec/models/trade/annual_report_upload_spec.rb +++ b/spec/models/trade/annual_report_upload_spec.rb @@ -155,7 +155,7 @@ def invalid_file ) end context "when no primary errors" do - subject { #aru no primary errors + subject { # aru no primary errors aru = build(:annual_report_upload, :trading_country_id => @argentina.id, :point_of_view => 'I') aru.save(:validate => false) sandbox_klass = Trade::SandboxTemplate.ar_klass(aru.sandbox.table_name) @@ -179,7 +179,7 @@ def invalid_file specify { expect { subject.submit }.to change { Trade::Permit.count }.by(3) } - specify { #make sure leading space is stripped + specify { # make sure leading space is stripped subject.submit; Trade::Permit.find_by_number('BBB').should_not be_nil } context "when permit previously reported" do @@ -190,7 +190,7 @@ def invalid_file end end context "when primary errors present" do - subject { #aru with primary errors + subject { # aru with primary errors aru = build(:annual_report_upload) aru.save(:validate => false) sandbox_klass = Trade::SandboxTemplate.ar_klass(aru.sandbox.table_name) @@ -220,7 +220,7 @@ def invalid_file :other_taxon_concept => @synonym ) end - subject { #aru no primary errors + subject { # aru no primary errors aru = build(:annual_report_upload, :trading_country_id => @argentina.id, :point_of_view => 'I') aru.save(:validate => false) sandbox_klass = Trade::SandboxTemplate.ar_klass(aru.sandbox.table_name) diff --git a/spec/shared/falconiformes.rb b/spec/shared/falconiformes.rb index ddd69ae665..0349f5e08d 100644 --- a/spec/shared/falconiformes.rb +++ b/spec/shared/falconiformes.rb @@ -30,7 +30,7 @@ :taxon_name => create(:taxon_name, :scientific_name => 'Vultur'), :parent => @family1 ) - #this one is not listed + # this one is not listed @species1_3 = create_cites_eu_species( :taxon_name => create(:taxon_name, :scientific_name => 'Atratus'), :parent => @genus1_3, From 534201887306412dbb6511e6c6dac8f9b6f78151 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 1 Jul 2016 10:41:33 +0100 Subject: [PATCH 330/365] removed obsolete encoding comments --- app/helpers/admin_helper.rb | 1 - app/helpers/taxon_concept_helper.rb | 1 - app/models/checklist/checklist.rb | 1 - app/models/checklist/pdf/history.rb | 1 - app/models/checklist/pdf/index.rb | 1 - lib/modules/latex_to_pdf.rb | 1 - lib/tasks/fix_symbols.rake | 2 -- lib/tasks/import_standard_reference_links.rake | 2 -- spec/factories.rb | 2 -- spec/models/checklist/annotations_spec.rb | 1 - spec/models/checklist/appendix_population_and_region_spec.rb | 1 - spec/models/checklist/appendix_population_spec.rb | 1 - spec/models/checklist/appendix_spec.rb | 1 - spec/models/checklist/common_names_spec.rb | 1 - spec/models/checklist/pdf/history_annotations_key_spec.rb | 1 - spec/models/checklist/pdf/history_spec.rb | 1 - spec/models/checklist/pdf/index_annotations_key_spec.rb | 1 - spec/models/checklist/scientific_name_spec.rb | 1 - spec/models/checklist/synonyms_spec.rb | 1 - spec/models/dashboard_stats_species_spec.rb | 1 - spec/models/dashboard_stats_trade_spec.rb | 1 - spec/models/taxon_concept/agalychnis_spec.rb | 1 - spec/models/taxon_concept/colophon_spec.rb | 1 - spec/models/taxon_concept/destroy_spec.rb | 1 - spec/models/taxon_concept/uroplatus_spec.rb | 1 - spec/models/taxon_concept/varanidae_spec.rb | 1 - spec/shared/agalychnis.rb | 1 - spec/shared/ailuropoda.rb | 1 - spec/shared/arctocephalus.rb | 1 - spec/shared/caiman_latirostris.rb | 1 - spec/shared/colophon.rb | 1 - spec/shared/platysternon_megacephalum.rb | 1 - spec/shared/pristis_microdon.rb | 1 - spec/shared/shipments.rb | 1 - spec/shared/uroplatus.rb | 1 - spec/shared/varanidae.rb | 1 - 36 files changed, 39 deletions(-) diff --git a/app/helpers/admin_helper.rb b/app/helpers/admin_helper.rb index 27ca369049..f7eccc7d0c 100644 --- a/app/helpers/admin_helper.rb +++ b/app/helpers/admin_helper.rb @@ -1,4 +1,3 @@ -#encoding: utf-8 module AdminHelper def ancestors_path(taxon_concept) diff --git a/app/helpers/taxon_concept_helper.rb b/app/helpers/taxon_concept_helper.rb index cf3be72bd7..2b02399d54 100644 --- a/app/helpers/taxon_concept_helper.rb +++ b/app/helpers/taxon_concept_helper.rb @@ -1,4 +1,3 @@ -#encoding: utf-8 module TaxonConceptHelper def admin_taxon_concept_title content_tag(:div, :class => 'admin-header') do diff --git a/app/models/checklist/checklist.rb b/app/models/checklist/checklist.rb index ee97238c3f..ed77385bd3 100644 --- a/app/models/checklist/checklist.rb +++ b/app/models/checklist/checklist.rb @@ -1,4 +1,3 @@ -#Encoding: utf-8 class Checklist::Checklist include ActiveModel::SerializerSupport include CacheIterator diff --git a/app/models/checklist/pdf/history.rb b/app/models/checklist/pdf/history.rb index b53dd004b1..c43f0a8e0f 100644 --- a/app/models/checklist/pdf/history.rb +++ b/app/models/checklist/pdf/history.rb @@ -1,4 +1,3 @@ -#Encoding: utf-8 class Checklist::Pdf::History < Checklist::History include Checklist::Pdf::Document include Checklist::Pdf::Helpers diff --git a/app/models/checklist/pdf/index.rb b/app/models/checklist/pdf/index.rb index aa3fb8a2b3..617bfbf461 100644 --- a/app/models/checklist/pdf/index.rb +++ b/app/models/checklist/pdf/index.rb @@ -1,4 +1,3 @@ -#Encoding: utf-8 class Checklist::Pdf::Index < Checklist::Index include Checklist::Pdf::Document include Checklist::Pdf::Helpers diff --git a/lib/modules/latex_to_pdf.rb b/lib/modules/latex_to_pdf.rb index 98c07d41d0..00f84c75e0 100644 --- a/lib/modules/latex_to_pdf.rb +++ b/lib/modules/latex_to_pdf.rb @@ -1,4 +1,3 @@ -#Encoding: UTF-8 class LatexToPdf def self.config @config ||= { diff --git a/lib/tasks/fix_symbols.rake b/lib/tasks/fix_symbols.rake index 43d6aa7167..a42210cfb4 100644 --- a/lib/tasks/fix_symbols.rake +++ b/lib/tasks/fix_symbols.rake @@ -1,5 +1,3 @@ -#encoding: utf-8 - namespace :import do desc 'Fix symbols in the data files' diff --git a/lib/tasks/import_standard_reference_links.rake b/lib/tasks/import_standard_reference_links.rake index 4198b9a981..b9b71c7f44 100644 --- a/lib/tasks/import_standard_reference_links.rake +++ b/lib/tasks/import_standard_reference_links.rake @@ -1,5 +1,3 @@ -#Encoding: utf-8 - namespace :import do desc "Import standard reference links from csv file (usage: rake import:standard_references[path/to/file,path/to/another])" diff --git a/spec/factories.rb b/spec/factories.rb index 4519a55b17..a3ad92e8c6 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -1,5 +1,3 @@ -#Encoding: utf-8 - FactoryGirl.define do factory :user do diff --git a/spec/models/checklist/annotations_spec.rb b/spec/models/checklist/annotations_spec.rb index 49b6d7dbc0..4704fb44a3 100644 --- a/spec/models/checklist/annotations_spec.rb +++ b/spec/models/checklist/annotations_spec.rb @@ -1,4 +1,3 @@ -#Encoding: UTF-8 require 'spec_helper' describe Checklist do diff --git a/spec/models/checklist/appendix_population_and_region_spec.rb b/spec/models/checklist/appendix_population_and_region_spec.rb index a00fbdb631..13346aca3d 100644 --- a/spec/models/checklist/appendix_population_and_region_spec.rb +++ b/spec/models/checklist/appendix_population_and_region_spec.rb @@ -1,4 +1,3 @@ -#Encoding: UTF-8 require 'spec_helper' describe Checklist do diff --git a/spec/models/checklist/appendix_population_spec.rb b/spec/models/checklist/appendix_population_spec.rb index eaed1732ac..feb6c67976 100644 --- a/spec/models/checklist/appendix_population_spec.rb +++ b/spec/models/checklist/appendix_population_spec.rb @@ -1,4 +1,3 @@ -#Encoding: UTF-8 require 'spec_helper' describe Checklist do diff --git a/spec/models/checklist/appendix_spec.rb b/spec/models/checklist/appendix_spec.rb index 3e1ff9a5a4..9f2d746fe1 100644 --- a/spec/models/checklist/appendix_spec.rb +++ b/spec/models/checklist/appendix_spec.rb @@ -1,4 +1,3 @@ -#Encoding: UTF-8 require 'spec_helper' describe Checklist do diff --git a/spec/models/checklist/common_names_spec.rb b/spec/models/checklist/common_names_spec.rb index f7534213cf..a5f7709b07 100644 --- a/spec/models/checklist/common_names_spec.rb +++ b/spec/models/checklist/common_names_spec.rb @@ -1,4 +1,3 @@ -#Encoding: UTF-8 require 'spec_helper' describe Checklist do diff --git a/spec/models/checklist/pdf/history_annotations_key_spec.rb b/spec/models/checklist/pdf/history_annotations_key_spec.rb index c747cfdcbd..c7e017c25e 100644 --- a/spec/models/checklist/pdf/history_annotations_key_spec.rb +++ b/spec/models/checklist/pdf/history_annotations_key_spec.rb @@ -1,4 +1,3 @@ -#Encoding: UTF-8 require 'spec_helper' describe Checklist::Pdf::HistoryAnnotationsKey do diff --git a/spec/models/checklist/pdf/history_spec.rb b/spec/models/checklist/pdf/history_spec.rb index 8fd11f18b0..722dbc4f56 100644 --- a/spec/models/checklist/pdf/history_spec.rb +++ b/spec/models/checklist/pdf/history_spec.rb @@ -1,4 +1,3 @@ -#Encoding: UTF-8 require 'spec_helper' describe Checklist::Pdf::History do diff --git a/spec/models/checklist/pdf/index_annotations_key_spec.rb b/spec/models/checklist/pdf/index_annotations_key_spec.rb index 701c8d3e8f..1b944817db 100644 --- a/spec/models/checklist/pdf/index_annotations_key_spec.rb +++ b/spec/models/checklist/pdf/index_annotations_key_spec.rb @@ -1,4 +1,3 @@ -#Encoding: UTF-8 require 'spec_helper' describe Checklist::Pdf::IndexAnnotationsKey do diff --git a/spec/models/checklist/scientific_name_spec.rb b/spec/models/checklist/scientific_name_spec.rb index 374b4f22ca..d3ea7fde2e 100644 --- a/spec/models/checklist/scientific_name_spec.rb +++ b/spec/models/checklist/scientific_name_spec.rb @@ -1,4 +1,3 @@ -#Encoding: UTF-8 require 'spec_helper' describe Checklist do diff --git a/spec/models/checklist/synonyms_spec.rb b/spec/models/checklist/synonyms_spec.rb index 3609c93d88..ab166566db 100644 --- a/spec/models/checklist/synonyms_spec.rb +++ b/spec/models/checklist/synonyms_spec.rb @@ -1,4 +1,3 @@ -#Encoding: UTF-8 require 'spec_helper' describe Checklist do diff --git a/spec/models/dashboard_stats_species_spec.rb b/spec/models/dashboard_stats_species_spec.rb index 60e9b9b348..a9f839d3dd 100644 --- a/spec/models/dashboard_stats_species_spec.rb +++ b/spec/models/dashboard_stats_species_spec.rb @@ -1,4 +1,3 @@ -#Encoding: utf-8 require 'spec_helper' describe DashboardStats do diff --git a/spec/models/dashboard_stats_trade_spec.rb b/spec/models/dashboard_stats_trade_spec.rb index 796de86bbc..7deec6b0a4 100644 --- a/spec/models/dashboard_stats_trade_spec.rb +++ b/spec/models/dashboard_stats_trade_spec.rb @@ -1,4 +1,3 @@ -#Encoding: utf-8 require 'spec_helper' describe DashboardStats do diff --git a/spec/models/taxon_concept/agalychnis_spec.rb b/spec/models/taxon_concept/agalychnis_spec.rb index 5ab6bcd74a..e19ebb960e 100644 --- a/spec/models/taxon_concept/agalychnis_spec.rb +++ b/spec/models/taxon_concept/agalychnis_spec.rb @@ -1,4 +1,3 @@ -#Encoding: utf-8 require 'spec_helper' describe TaxonConcept do diff --git a/spec/models/taxon_concept/colophon_spec.rb b/spec/models/taxon_concept/colophon_spec.rb index a7f4c1bf30..dbeb7d4a4c 100644 --- a/spec/models/taxon_concept/colophon_spec.rb +++ b/spec/models/taxon_concept/colophon_spec.rb @@ -1,4 +1,3 @@ -#Encoding: utf-8 require 'spec_helper' describe TaxonConcept do diff --git a/spec/models/taxon_concept/destroy_spec.rb b/spec/models/taxon_concept/destroy_spec.rb index 91427f20f5..6df7fdbf92 100644 --- a/spec/models/taxon_concept/destroy_spec.rb +++ b/spec/models/taxon_concept/destroy_spec.rb @@ -1,4 +1,3 @@ -#Encoding: utf-8 require 'spec_helper' describe TaxonConcept do diff --git a/spec/models/taxon_concept/uroplatus_spec.rb b/spec/models/taxon_concept/uroplatus_spec.rb index 97f5c9f4a7..9b16ca31b6 100644 --- a/spec/models/taxon_concept/uroplatus_spec.rb +++ b/spec/models/taxon_concept/uroplatus_spec.rb @@ -1,4 +1,3 @@ -#Encoding: utf-8 require 'spec_helper' describe TaxonConcept do diff --git a/spec/models/taxon_concept/varanidae_spec.rb b/spec/models/taxon_concept/varanidae_spec.rb index 86ce1a7d28..594ac84c7b 100644 --- a/spec/models/taxon_concept/varanidae_spec.rb +++ b/spec/models/taxon_concept/varanidae_spec.rb @@ -1,4 +1,3 @@ -#Encoding: utf-8 require 'spec_helper' describe TaxonConcept do diff --git a/spec/shared/agalychnis.rb b/spec/shared/agalychnis.rb index f8cca602bd..ab4bedb6af 100644 --- a/spec/shared/agalychnis.rb +++ b/spec/shared/agalychnis.rb @@ -1,4 +1,3 @@ -#Encoding: utf-8 shared_context 'Agalychnis' do before(:all) do @klass = cites_eu_amphibia diff --git a/spec/shared/ailuropoda.rb b/spec/shared/ailuropoda.rb index 77f2bb8eec..7bbe2af541 100644 --- a/spec/shared/ailuropoda.rb +++ b/spec/shared/ailuropoda.rb @@ -1,4 +1,3 @@ -#Encoding: UTF-8 shared_context "Ailuropoda" do before(:all) do @order = create_cites_eu_order( diff --git a/spec/shared/arctocephalus.rb b/spec/shared/arctocephalus.rb index 94a6253909..89571cb84b 100644 --- a/spec/shared/arctocephalus.rb +++ b/spec/shared/arctocephalus.rb @@ -1,4 +1,3 @@ -#Encoding: UTF-8 shared_context "Arctocephalus" do let(:en) { create(:language, :name => 'English', :iso_code1 => 'EN', :iso_code3 => 'ENG') } let(:es) { create(:language, :name => 'Spanish', :iso_code1 => 'ES', :iso_code3 => 'SPA') } diff --git a/spec/shared/caiman_latirostris.rb b/spec/shared/caiman_latirostris.rb index f8ec7e9272..2186a5395b 100644 --- a/spec/shared/caiman_latirostris.rb +++ b/spec/shared/caiman_latirostris.rb @@ -1,4 +1,3 @@ -#Encoding: utf-8 shared_context "Caiman latirostris" do let(:en) { diff --git a/spec/shared/colophon.rb b/spec/shared/colophon.rb index bab52817e8..6ea4a5ba33 100644 --- a/spec/shared/colophon.rb +++ b/spec/shared/colophon.rb @@ -1,4 +1,3 @@ -#Encoding: utf-8 shared_context 'Colophon' do let(:south_africa) { create( diff --git a/spec/shared/platysternon_megacephalum.rb b/spec/shared/platysternon_megacephalum.rb index 9c60a6add9..b82ee21b02 100644 --- a/spec/shared/platysternon_megacephalum.rb +++ b/spec/shared/platysternon_megacephalum.rb @@ -1,4 +1,3 @@ -#Encoding: utf-8 shared_context 'Platysternon megacephalum' do before(:all) do @klass = cites_eu_reptilia diff --git a/spec/shared/pristis_microdon.rb b/spec/shared/pristis_microdon.rb index e9c68e1e7a..8a79172ada 100644 --- a/spec/shared/pristis_microdon.rb +++ b/spec/shared/pristis_microdon.rb @@ -1,4 +1,3 @@ -#Encoding: utf-8 shared_context 'Pristis microdon' do before(:all) do @klass = cites_eu_elasmobranchii diff --git a/spec/shared/shipments.rb b/spec/shared/shipments.rb index 6b97c2273a..a808d2cb5f 100644 --- a/spec/shared/shipments.rb +++ b/spec/shared/shipments.rb @@ -1,4 +1,3 @@ -#Encoding: utf-8 shared_context 'Shipments' do before(:each) do @animal_family = create_cites_eu_family( diff --git a/spec/shared/uroplatus.rb b/spec/shared/uroplatus.rb index 2768227460..b73d5c777c 100644 --- a/spec/shared/uroplatus.rb +++ b/spec/shared/uroplatus.rb @@ -1,4 +1,3 @@ -#Encoding: utf-8 shared_context 'Uroplatus' do before(:all) do @order = create_cites_eu_order( diff --git a/spec/shared/varanidae.rb b/spec/shared/varanidae.rb index 9f641ebbeb..3cb456570f 100644 --- a/spec/shared/varanidae.rb +++ b/spec/shared/varanidae.rb @@ -1,4 +1,3 @@ -#Encoding: utf-8 shared_context 'Varanidae' do before(:all) do @order = create_cites_eu_order( From 5fd4f0a47fe11b40f5fbaaa223f97900e88e18dc Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 1 Jul 2016 10:43:07 +0100 Subject: [PATCH 331/365] removed commented code --- Gemfile | 1 - app/models/search_params.rb | 1 - app/models/trade/presence_validation_rule.rb | 2 -- app/models/trade/validation_rule.rb | 1 - config/routes.rb | 3 --- lib/modules/downloads_cache.rb | 2 -- lib/scripts/get_listed_species_per_country.rb | 3 +-- lib/tasks/fix_symbols.rake | 1 - spec/factories/listings.rb | 2 -- 9 files changed, 1 insertion(+), 15 deletions(-) diff --git a/Gemfile b/Gemfile index 0d14ed494b..e3d4437e6b 100644 --- a/Gemfile +++ b/Gemfile @@ -134,7 +134,6 @@ gem 'slim' gem 'sinatra', '>= 1.3.0', :require => nil gem 'memcache-client' -#gem 'high_voltage' gem 'jquery-ui-rails' diff --git a/app/models/search_params.rb b/app/models/search_params.rb index ffacb33eca..9ac266c60a 100644 --- a/app/models/search_params.rb +++ b/app/models/search_params.rb @@ -9,7 +9,6 @@ class SearchParams def initialize(attributes = {}) attributes.each do |name, value| - #send("#{name}=", (value.is_a?(Hash) ? value.symbolize_keys : value)) send("#{name}=", value) end end diff --git a/app/models/trade/presence_validation_rule.rb b/app/models/trade/presence_validation_rule.rb index ffebff6e96..7d199d8882 100644 --- a/app/models/trade/presence_validation_rule.rb +++ b/app/models/trade/presence_validation_rule.rb @@ -16,8 +16,6 @@ # class Trade::PresenceValidationRule < Trade::ValidationRule - #validates :column_names, :uniqueness => true - def error_message column_names.join(', ') + ' cannot be blank' end diff --git a/app/models/trade/validation_rule.rb b/app/models/trade/validation_rule.rb index 5b64cce0d3..735f64018a 100644 --- a/app/models/trade/validation_rule.rb +++ b/app/models/trade/validation_rule.rb @@ -69,7 +69,6 @@ def validation_errors(annual_report_upload) end def validation_errors_for_shipment(shipment) - #raise "Not implemented" return nil if is_primary # primary validations are handled by AR 'shipment validation not implemented' end diff --git a/config/routes.rb b/config/routes.rb index 8f3237503d..90c3617384 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -45,7 +45,6 @@ resources :geo_relationship_types, :only => [:index] end namespace :admin do - #resources :api_usage, :only => [:index, :show] resources :taxonomies, :only => [:index, :create, :update, :destroy] resources :terms, :only => [:index, :create, :update, :destroy] resources :sources, :only => [:index, :create, :update, :destroy] @@ -194,7 +193,6 @@ end namespace :species do - #match 'about' => 'pages#about' match 'exports' => 'exports#index' match 'exports/download' => 'exports#download' get '*foo' => 'ember#start' @@ -224,7 +222,6 @@ # The priority is based upon order of creation: # first created -> highest priority. - #match '/:locale' => 'cites_trade#index' scope "(:locale)", :locale => /en|es|fr/ do namespace :cites_trade do resources :shipments, :only => [:index] diff --git a/lib/modules/downloads_cache.rb b/lib/modules/downloads_cache.rb index e6625e4713..0fb84e545d 100644 --- a/lib/modules/downloads_cache.rb +++ b/lib/modules/downloads_cache.rb @@ -105,8 +105,6 @@ def self.clear_eu_decisions class << self alias :clear_eu_opinions :clear_eu_decisions alias :clear_eu_suspensions :clear_eu_decisions - - #alias :clear_taxon_concepts_distributions :clear_distributions end # cleared after save & destroy diff --git a/lib/scripts/get_listed_species_per_country.rb b/lib/scripts/get_listed_species_per_country.rb index de8f4c4cbe..9ac2b3738f 100644 --- a/lib/scripts/get_listed_species_per_country.rb +++ b/lib/scripts/get_listed_species_per_country.rb @@ -4,7 +4,7 @@ require '../../config/environment.rb' results = { :cites_eu => [], :cms => [] } -countries = GeoEntity.where("geo_entity_type_id = 1") #.limit(2) +countries = GeoEntity.where("geo_entity_type_id = 1") countries.each do |country| [:cites_eu, :cms].each do |taxonomy| @@ -21,5 +21,4 @@ end end -#puts results.to_json puts JSON.pretty_generate(results) \ No newline at end of file diff --git a/lib/tasks/fix_symbols.rake b/lib/tasks/fix_symbols.rake index a42210cfb4..661f9ee00e 100644 --- a/lib/tasks/fix_symbols.rake +++ b/lib/tasks/fix_symbols.rake @@ -2,7 +2,6 @@ namespace :import do desc 'Fix symbols in the data files' task :fix_symbols => :environment do - #Rake::Task["import:fix_annotations_symbols"].invoke Rake::Task["import:fix_references_symbols"].invoke Rake::Task["import:fix_taxon_concepts_symbols"].invoke Rake::Task["import:fix_geo_entities_symbols"].invoke diff --git a/spec/factories/listings.rb b/spec/factories/listings.rb index b873f138fe..68059637da 100644 --- a/spec/factories/listings.rb +++ b/spec/factories/listings.rb @@ -17,8 +17,6 @@ change_type taxon_concept effective_at '2012-01-01' - #is_current false - #inclusion_taxon_concept_id nil parent_id nil end From 01476f8e79e02a6e7b55d19bbe49f9400be01bbb Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 1 Jul 2016 10:50:00 +0100 Subject: [PATCH 332/365] enabled Style/SingleLineMethods --- .rubocop.yml | 4 ++ .rubocop_todo.yml | 6 --- app/models/document.rb | 4 +- app/models/document/agenda_items.rb | 4 +- app/models/document/commission_notes.rb | 4 +- .../detailed_summary_of_conclusions.rb | 4 +- app/models/document/list_of_participants.rb | 4 +- app/models/document/meeting_agenda.rb | 4 +- app/models/document/ndf_consultation.rb | 4 +- app/models/document/non_detriment_findings.rb | 4 +- app/models/document/proposal.rb | 4 +- .../range_state_consultation_letter.rb | 4 +- app/models/document/review_details.rb | 4 +- .../document/review_of_significant_trade.rb | 4 +- .../document/short_summary_of_conclusions.rb | 4 +- app/models/document/unep_wcmc_report.rb | 4 +- app/models/document_tag/discussion.rb | 4 +- app/models/document_tag/process_stage.rb | 4 +- app/models/document_tag/proposal_outcome.rb | 4 +- app/models/document_tag/review_phase.rb | 4 +- app/models/m_taxon_concept.rb | 44 ++++++++++++++----- .../cascading_notes_processor.rb | 4 +- .../delete_unreassigned_processor.rb | 4 +- app/models/nomenclature_change/output.rb | 4 +- .../active_record_comparison_attributes.rb | 4 +- lib/tasks/elibrary/citations_importer.rb | 4 +- .../elibrary/document_discussions_importer.rb | 4 +- lib/tasks/elibrary/documents_importer.rb | 4 +- lib/tasks/elibrary/events_importer.rb | 4 +- lib/tasks/elibrary/non_cites_taxa_importer.rb | 4 +- lib/tasks/elibrary/users_importer.rb | 4 +- 31 files changed, 121 insertions(+), 45 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index fbe558eada..34250ebe79 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -81,3 +81,7 @@ Style/SpaceInsideHashLiteralBraces: # Configuration parameters: AllowForAlignment. Style/SpaceAroundOperators: AllowForAlignment: true + +# Configuration parameters: AllowIfMethodIsEmpty. +Style/SingleLineMethods: + AllowIfMethodIsEmpty: true diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 359ae5695f..61e27066ea 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -594,12 +594,6 @@ Style/SignalException: Exclude: - 'lib/tasks/elibrary/import.rake' -# Offense count: 39 -# Cop supports --auto-correct. -# Configuration parameters: AllowIfMethodIsEmpty. -Style/SingleLineMethods: - Enabled: false - # Offense count: 4 # Cop supports --auto-correct. # Configuration parameters: SupportedStyles. diff --git a/app/models/document.rb b/app/models/document.rb index 1978dfdb4a..78eee2eca4 100644 --- a/app/models/document.rb +++ b/app/models/document.rb @@ -61,7 +61,9 @@ class Document < ActiveRecord::Base before_validation :set_title before_validation :reset_designation_if_event_set - def self.display_name; 'Document'; end + def self.display_name + 'Document' + end # Returns document types (class objects) that are relevant to E-Library def self.elibrary_document_types diff --git a/app/models/document/agenda_items.rb b/app/models/document/agenda_items.rb index 1f20558c06..733ca05309 100644 --- a/app/models/document/agenda_items.rb +++ b/app/models/document/agenda_items.rb @@ -25,5 +25,7 @@ # class Document::AgendaItems < Document - def self.display_name; 'Agenda Items'; end + def self.display_name + 'Agenda Items' + end end diff --git a/app/models/document/commission_notes.rb b/app/models/document/commission_notes.rb index 366b236928..9e1f1d36a1 100644 --- a/app/models/document/commission_notes.rb +++ b/app/models/document/commission_notes.rb @@ -25,5 +25,7 @@ # class Document::CommissionNotes < Document - def self.display_name; 'Commission Notes'; end + def self.display_name + 'Commission Notes' + end end diff --git a/app/models/document/detailed_summary_of_conclusions.rb b/app/models/document/detailed_summary_of_conclusions.rb index a850a1ffa0..5aa638c892 100644 --- a/app/models/document/detailed_summary_of_conclusions.rb +++ b/app/models/document/detailed_summary_of_conclusions.rb @@ -25,5 +25,7 @@ # class Document::DetailedSummaryOfConclusions < Document - def self.display_name; 'Detailed Summary of Conclusions'; end + def self.display_name + 'Detailed Summary of Conclusions' + end end diff --git a/app/models/document/list_of_participants.rb b/app/models/document/list_of_participants.rb index 841b5abc33..2bb008eafe 100644 --- a/app/models/document/list_of_participants.rb +++ b/app/models/document/list_of_participants.rb @@ -25,5 +25,7 @@ # class Document::ListOfParticipants < Document - def self.display_name; 'List of Participants'; end + def self.display_name + 'List of Participants' + end end diff --git a/app/models/document/meeting_agenda.rb b/app/models/document/meeting_agenda.rb index d060bfa0b7..fc0f39d655 100644 --- a/app/models/document/meeting_agenda.rb +++ b/app/models/document/meeting_agenda.rb @@ -25,5 +25,7 @@ # class Document::MeetingAgenda < Document - def self.display_name; 'Meeting Agenda'; end + def self.display_name + 'Meeting Agenda' + end end diff --git a/app/models/document/ndf_consultation.rb b/app/models/document/ndf_consultation.rb index 2a00e10bb6..cb77c9bef8 100644 --- a/app/models/document/ndf_consultation.rb +++ b/app/models/document/ndf_consultation.rb @@ -25,5 +25,7 @@ # class Document::NdfConsultation < Document - def self.display_name; 'NDF Consultation'; end + def self.display_name + 'NDF Consultation' + end end diff --git a/app/models/document/non_detriment_findings.rb b/app/models/document/non_detriment_findings.rb index 36d1f3cb9b..a58520d2e8 100644 --- a/app/models/document/non_detriment_findings.rb +++ b/app/models/document/non_detriment_findings.rb @@ -25,5 +25,7 @@ # class Document::NonDetrimentFindings < Document - def self.display_name; 'Non-detriment findings'; end + def self.display_name + 'Non-detriment findings' + end end diff --git a/app/models/document/proposal.rb b/app/models/document/proposal.rb index 76bbbf388c..3326597088 100644 --- a/app/models/document/proposal.rb +++ b/app/models/document/proposal.rb @@ -25,7 +25,9 @@ # class Document::Proposal < Document - def self.display_name; 'Proposal'; end + def self.display_name + 'Proposal' + end attr_accessible :proposal_details_attributes diff --git a/app/models/document/range_state_consultation_letter.rb b/app/models/document/range_state_consultation_letter.rb index 6ce5637c6a..20b4c270d0 100644 --- a/app/models/document/range_state_consultation_letter.rb +++ b/app/models/document/range_state_consultation_letter.rb @@ -25,5 +25,7 @@ # class Document::RangeStateConsultationLetter < Document - def self.display_name; 'Range State Consultation Letter'; end + def self.display_name + 'Range State Consultation Letter' + end end diff --git a/app/models/document/review_details.rb b/app/models/document/review_details.rb index eaf6bd2b40..7fe8f3468a 100644 --- a/app/models/document/review_details.rb +++ b/app/models/document/review_details.rb @@ -16,6 +16,8 @@ class Document::ReviewDetails < ActiveRecord::Base self.table_name = 'review_details' belongs_to :document, touch: true - def self.display_name; 'Review Details'; end + def self.display_name + 'Review Details' + end end diff --git a/app/models/document/review_of_significant_trade.rb b/app/models/document/review_of_significant_trade.rb index 4ddcdc5cde..be6c7fd08c 100644 --- a/app/models/document/review_of_significant_trade.rb +++ b/app/models/document/review_of_significant_trade.rb @@ -25,7 +25,9 @@ # class Document::ReviewOfSignificantTrade < Document - def self.display_name; 'Review of Significant Trade'; end + def self.display_name + 'Review of Significant Trade' + end attr_accessible :review_details_attributes diff --git a/app/models/document/short_summary_of_conclusions.rb b/app/models/document/short_summary_of_conclusions.rb index b1a2497858..1e319363d7 100644 --- a/app/models/document/short_summary_of_conclusions.rb +++ b/app/models/document/short_summary_of_conclusions.rb @@ -25,5 +25,7 @@ # class Document::ShortSummaryOfConclusions < Document - def self.display_name; 'Short Summary of Conclusions'; end + def self.display_name + 'Short Summary of Conclusions' + end end diff --git a/app/models/document/unep_wcmc_report.rb b/app/models/document/unep_wcmc_report.rb index d97b4b3ebc..ebac1d169b 100644 --- a/app/models/document/unep_wcmc_report.rb +++ b/app/models/document/unep_wcmc_report.rb @@ -25,5 +25,7 @@ # class Document::UnepWcmcReport < Document - def self.display_name; 'UNEP-WCMC Report'; end + def self.display_name + 'UNEP-WCMC Report' + end end diff --git a/app/models/document_tag/discussion.rb b/app/models/document_tag/discussion.rb index 4b973be370..9170ba49c1 100644 --- a/app/models/document_tag/discussion.rb +++ b/app/models/document_tag/discussion.rb @@ -11,6 +11,8 @@ class DocumentTag::Discussion < DocumentTag - def self.display_name; 'Discussion'; end + def self.display_name + 'Discussion' + end end diff --git a/app/models/document_tag/process_stage.rb b/app/models/document_tag/process_stage.rb index ca7f65a283..8d3f28c771 100644 --- a/app/models/document_tag/process_stage.rb +++ b/app/models/document_tag/process_stage.rb @@ -11,7 +11,9 @@ class DocumentTag::ProcessStage < DocumentTag - def self.display_name; 'Process stage'; end + def self.display_name + 'Process stage' + end def self.elibrary_document_types [Document::ReviewOfSignificantTrade] diff --git a/app/models/document_tag/proposal_outcome.rb b/app/models/document_tag/proposal_outcome.rb index 32959433b6..d5fdad273d 100644 --- a/app/models/document_tag/proposal_outcome.rb +++ b/app/models/document_tag/proposal_outcome.rb @@ -11,7 +11,9 @@ class DocumentTag::ProposalOutcome < DocumentTag - def self.display_name; 'Proposal outcome'; end + def self.display_name + 'Proposal outcome' + end def self.elibrary_document_types [Document::Proposal] diff --git a/app/models/document_tag/review_phase.rb b/app/models/document_tag/review_phase.rb index 174a96bb09..4a12cb0ec1 100644 --- a/app/models/document_tag/review_phase.rb +++ b/app/models/document_tag/review_phase.rb @@ -11,7 +11,9 @@ class DocumentTag::ReviewPhase < DocumentTag - def self.display_name; 'Review phase'; end + def self.display_name + 'Review phase' + end def self.elibrary_document_types [Document::ReviewOfSignificantTrade] diff --git a/app/models/m_taxon_concept.rb b/app/models/m_taxon_concept.rb index d125ae7c9c..4785407f41 100644 --- a/app/models/m_taxon_concept.rb +++ b/app/models/m_taxon_concept.rb @@ -214,27 +214,49 @@ def countries_ids end end - def countries_iso_codes; all_distribution_iso_codes; end + def countries_iso_codes + all_distribution_iso_codes + end - def countries_full_names; all_distribution; end + def countries_full_names + all_distribution + end - def all_distribution; parse_pg_array(all_distribution_ary || ''); end + def all_distribution + parse_pg_array(all_distribution_ary || '') + end - def all_distribution_iso_codes; parse_pg_array(all_distribution_iso_codes_ary || ''); end + def all_distribution_iso_codes + parse_pg_array(all_distribution_iso_codes_ary || '') + end - def native_distribution; parse_pg_array(native_distribution_ary || ''); end + def native_distribution + parse_pg_array(native_distribution_ary || '') + end - def introduced_distribution; parse_pg_array(introduced_distribution_ary || ''); end + def introduced_distribution + parse_pg_array(introduced_distribution_ary || '') + end - def introduced_uncertain_distribution; parse_pg_array(introduced_uncertain_distribution_ary || ''); end + def introduced_uncertain_distribution + parse_pg_array(introduced_uncertain_distribution_ary || '') + end - def reintroduced_distribution; parse_pg_array(reintroduced_distribution_ary || ''); end + def reintroduced_distribution + parse_pg_array(reintroduced_distribution_ary || '') + end - def extinct_distribution; parse_pg_array(extinct_distribution_ary || ''); end + def extinct_distribution + parse_pg_array(extinct_distribution_ary || '') + end - def extinct_uncertain_distribution; parse_pg_array(extinct_uncertain_distribution_ary || ''); end + def extinct_uncertain_distribution + parse_pg_array(extinct_uncertain_distribution_ary || '') + end - def uncertain_distribution; parse_pg_array(uncertain_distribution_ary || ''); end + def uncertain_distribution + parse_pg_array(uncertain_distribution_ary || '') + end def recently_changed return (cites_listing_updated_at ? cites_listing_updated_at > 8.year.ago : false) diff --git a/app/models/nomenclature_change/cascading_notes_processor.rb b/app/models/nomenclature_change/cascading_notes_processor.rb index c0677d8a0d..917ec62653 100644 --- a/app/models/nomenclature_change/cascading_notes_processor.rb +++ b/app/models/nomenclature_change/cascading_notes_processor.rb @@ -27,7 +27,9 @@ def run end end - def summary; []; end + def summary + [] + end private diff --git a/app/models/nomenclature_change/delete_unreassigned_processor.rb b/app/models/nomenclature_change/delete_unreassigned_processor.rb index 29bccf02ad..1b93770c6c 100644 --- a/app/models/nomenclature_change/delete_unreassigned_processor.rb +++ b/app/models/nomenclature_change/delete_unreassigned_processor.rb @@ -39,6 +39,8 @@ def _is_input_reassignment(reassignment) end end - def summary; []; end + def summary + [] + end end \ No newline at end of file diff --git a/app/models/nomenclature_change/output.rb b/app/models/nomenclature_change/output.rb index e62e79e3ed..b055168c7a 100644 --- a/app/models/nomenclature_change/output.rb +++ b/app/models/nomenclature_change/output.rb @@ -113,7 +113,9 @@ def new_full_name end end - def display_full_name; new_full_name || taxon_concept.try(:full_name); end + def display_full_name + new_full_name || taxon_concept.try(:full_name) + end def display_rank_name try(:new_rank).try(:name) || taxon_concept.try(:rank).try(:name) diff --git a/config/initializers/active_record_comparison_attributes.rb b/config/initializers/active_record_comparison_attributes.rb index ff2b0ba6ee..b885182205 100644 --- a/config/initializers/active_record_comparison_attributes.rb +++ b/config/initializers/active_record_comparison_attributes.rb @@ -9,7 +9,9 @@ def ignored_attributes [:id, :created_at, :updated_at, :created_by_id, :updated_by_id, :original_id] end - def text_attributes; []; end + def text_attributes + [] + end end def comparison_attributes diff --git a/lib/tasks/elibrary/citations_importer.rb b/lib/tasks/elibrary/citations_importer.rb index 2a6c4cab4c..ea555d39ba 100644 --- a/lib/tasks/elibrary/citations_importer.rb +++ b/lib/tasks/elibrary/citations_importer.rb @@ -9,7 +9,9 @@ def initialize(file_name) @document_group = $1 end - def table_name; :"elibrary_citations_#{@document_group}_import"; end + def table_name + :"elibrary_citations_#{@document_group}_import" + end def columns_with_type [ diff --git a/lib/tasks/elibrary/document_discussions_importer.rb b/lib/tasks/elibrary/document_discussions_importer.rb index 0bff2a7e0e..51202ea494 100644 --- a/lib/tasks/elibrary/document_discussions_importer.rb +++ b/lib/tasks/elibrary/document_discussions_importer.rb @@ -7,7 +7,9 @@ def initialize(file_name) @file_name = file_name end - def table_name; :"elibrary_document_discussions_import"; end + def table_name + :"elibrary_document_discussions_import" + end def columns_with_type [ diff --git a/lib/tasks/elibrary/documents_importer.rb b/lib/tasks/elibrary/documents_importer.rb index cdb9e6fe86..b2d95725d2 100644 --- a/lib/tasks/elibrary/documents_importer.rb +++ b/lib/tasks/elibrary/documents_importer.rb @@ -9,7 +9,9 @@ def initialize(file_name) @document_group = $1 end - def table_name; :"elibrary_documents_#{@document_group}_import"; end + def table_name + :"elibrary_documents_#{@document_group}_import" + end def columns_with_type [ diff --git a/lib/tasks/elibrary/events_importer.rb b/lib/tasks/elibrary/events_importer.rb index 32f0950cd9..162287be82 100644 --- a/lib/tasks/elibrary/events_importer.rb +++ b/lib/tasks/elibrary/events_importer.rb @@ -7,7 +7,9 @@ def initialize(file_name) @file_name = file_name end - def table_name; :elibrary_events_import; end + def table_name + :elibrary_events_import + end def columns_with_type [ diff --git a/lib/tasks/elibrary/non_cites_taxa_importer.rb b/lib/tasks/elibrary/non_cites_taxa_importer.rb index 598b9b92e6..dbc67c9a8b 100644 --- a/lib/tasks/elibrary/non_cites_taxa_importer.rb +++ b/lib/tasks/elibrary/non_cites_taxa_importer.rb @@ -7,7 +7,9 @@ def initialize(file_name) @file_name = file_name end - def table_name; :elibrary_non_cites_taxa_import; end + def table_name + :elibrary_non_cites_taxa_import + end def columns_with_type [ diff --git a/lib/tasks/elibrary/users_importer.rb b/lib/tasks/elibrary/users_importer.rb index c83d42ceb9..7727075385 100644 --- a/lib/tasks/elibrary/users_importer.rb +++ b/lib/tasks/elibrary/users_importer.rb @@ -7,7 +7,9 @@ def initialize(file_name) @file_name = file_name end - def table_name; :"elibrary_users_import"; end + def table_name + :"elibrary_users_import" + end def columns_with_type [ From 6704853a7686eb133e76a711cf2939f0ef0431ed Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 1 Jul 2016 10:54:59 +0100 Subject: [PATCH 333/365] fixed if/else/end alignment --- lib/tasks/import_distribution_tags.rake | 10 +++++----- lib/tasks/import_distributions.rake | 10 +++++----- lib/tasks/import_synonyms.rake | 10 +++++----- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/tasks/import_distribution_tags.rake b/lib/tasks/import_distribution_tags.rake index 54d491f9a2..848777b78e 100644 --- a/lib/tasks/import_distribution_tags.rake +++ b/lib/tasks/import_distribution_tags.rake @@ -50,11 +50,11 @@ namespace :import do SELECT DISTINCT legacy_id, rank, geo_entity_type, iso_code2, regexp_split_to_table(#{TMP_TABLE}.tags, E',') AS tag FROM #{TMP_TABLE} WHERE - #{if taxonomy_name == Taxonomy::CITES_EU - "( UPPER(BTRIM(#{TMP_TABLE}.designation)) like '%CITES%' OR UPPER(BTRIM(#{TMP_TABLE}.designation)) like '%EU%')" - else - "UPPER(BTRIM(#{TMP_TABLE}.designation)) like '%CMS%'" - end} + #{if taxonomy_name == Taxonomy::CITES_EU + "( UPPER(BTRIM(#{TMP_TABLE}.designation)) like '%CITES%' OR UPPER(BTRIM(#{TMP_TABLE}.designation)) like '%EU%')" + else + "UPPER(BTRIM(#{TMP_TABLE}.designation)) like '%CMS%'" + end} ) INSERT INTO taggings(tag_id, taggable_id, taggable_type, context, created_at) SELECT subquery.*, NOW() diff --git a/lib/tasks/import_distributions.rake b/lib/tasks/import_distributions.rake index 2c5d5b99c1..67b4d2cd2e 100644 --- a/lib/tasks/import_distributions.rake +++ b/lib/tasks/import_distributions.rake @@ -28,11 +28,11 @@ namespace :import do INNER JOIN taxonomies ON taxonomies.id = taxon_concepts.taxonomy_id WHERE taxon_concepts.id IS NOT NULL AND geo_entities.id IS NOT NULL AND - #{if taxonomy_name == Taxonomy::CITES_EU - "( UPPER(BTRIM(#{TMP_TABLE}.designation)) like '%CITES%' OR UPPER(BTRIM(#{TMP_TABLE}.designation)) like '%EU%')" - else - "UPPER(BTRIM(#{TMP_TABLE}.designation)) like '%CMS%'" - end} + #{if taxonomy_name == Taxonomy::CITES_EU + "( UPPER(BTRIM(#{TMP_TABLE}.designation)) like '%CITES%' OR UPPER(BTRIM(#{TMP_TABLE}.designation)) like '%EU%')" + else + "UPPER(BTRIM(#{TMP_TABLE}.designation)) like '%CMS%'" + end} AND taxonomies.id = #{taxonomy.id} EXCEPT diff --git a/lib/tasks/import_synonyms.rake b/lib/tasks/import_synonyms.rake index 13f15778f0..fa95b2e2ab 100644 --- a/lib/tasks/import_synonyms.rake +++ b/lib/tasks/import_synonyms.rake @@ -54,11 +54,11 @@ namespace :import do LEFT JOIN taxonomies ON taxonomies.id = accepted.taxonomy_id AND taxonomies.id = synonym.taxonomy_id WHERE taxonomies.id = #{taxonomy.id} AND - #{if taxonomy_name == Taxonomy::CITES_EU - "( UPPER(BTRIM(#{TMP_TABLE}.taxonomy)) like '%CITES%' OR UPPER(BTRIM(#{TMP_TABLE}.taxonomy)) like '%EU%')" - else - "UPPER(BTRIM(#{TMP_TABLE}.taxonomy)) like '%CMS%'" - end} + #{if taxonomy_name == Taxonomy::CITES_EU + "( UPPER(BTRIM(#{TMP_TABLE}.taxonomy)) like '%CITES%' OR UPPER(BTRIM(#{TMP_TABLE}.taxonomy)) like '%EU%')" + else + "UPPER(BTRIM(#{TMP_TABLE}.taxonomy)) like '%CMS%'" + end} EXCEPT From f18ccb107ea1d77496f318c120028f8849f900c2 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 12 Jul 2016 14:04:10 +0100 Subject: [PATCH 334/365] added sitemap_generator --- .gitignore | 1 + Gemfile | 2 +- Gemfile.lock | 3 +++ Rakefile | 1 + config/sitemap.rb | 13 +++++++++++++ public/robots.txt | 8 +++++++- vendor/cache/sitemap_generator-5.1.0.gem | Bin 0 -> 80896 bytes 7 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 config/sitemap.rb create mode 100644 vendor/cache/sitemap_generator-5.1.0.gem diff --git a/.gitignore b/.gitignore index a58abd5ae9..4c6346b0aa 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ /public/latex/*.gz /public/latex/index.pdf /public/latex/history.pdf +/public/sitemap* #checklist downloads /public/downloads/checklist/*.* diff --git a/Gemfile b/Gemfile index e3d4437e6b..7a6b7f096d 100644 --- a/Gemfile +++ b/Gemfile @@ -146,6 +146,6 @@ gem 'paper_trail', '~> 4.0.0.beta' gem 'rails-secrets' gem 'dotenv-rails' -gem 'test-unit', '~> 3.1' # annoyingly, rails console won't start without it in staging / production +gem 'sitemap_generator' gem 'appsignal' diff --git a/Gemfile.lock b/Gemfile.lock index f8a89afe40..94471436f4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -395,6 +395,8 @@ GEM rack (~> 1.4) rack-protection (~> 1.3) tilt (~> 1.3, >= 1.3.3) + sitemap_generator (5.1.0) + builder slack-notifier (1.0.0) slackistrano (0.1.9) capistrano (>= 3.0.1) @@ -542,6 +544,7 @@ DEPENDENCIES sidekiq-unique-jobs! simplecov sinatra (>= 1.3.0) + sitemap_generator slack-notifier (~> 1.0) slackistrano slim diff --git a/Rakefile b/Rakefile index 55eb31cbfc..6936e56107 100644 --- a/Rakefile +++ b/Rakefile @@ -4,5 +4,6 @@ require File.expand_path('../config/application', __FILE__) require 'jslint/tasks' if Rails.env.development? +require 'sitemap_generator/tasks' SAPI::Application.load_tasks diff --git a/config/sitemap.rb b/config/sitemap.rb new file mode 100644 index 0000000000..40634ffd66 --- /dev/null +++ b/config/sitemap.rb @@ -0,0 +1,13 @@ +require 'rubygems' +require 'sitemap_generator' + +SitemapGenerator::Sitemap.default_host = 'http://speciesplus.net' +SitemapGenerator::Sitemap.create do + add '/about', changefreq: 'yearly' + add '/terms-of-use', changefreq: 'yearly' + add '/eu_legislation', changefreq: 'yearly' + add '/#/elibrary', changefreq: 'yearly' + MTaxonConcept.where(show_in_species_plus: true).pluck(:id).each do |tc_id| + add "/#/taxon_concepts/#{tc_id}/legal", changefreq: 'monthly' + end +end diff --git a/public/robots.txt b/public/robots.txt index bfcd4c84f9..ecce50284c 100644 --- a/public/robots.txt +++ b/public/robots.txt @@ -1,3 +1,4 @@ +Sitemap: http://speciesplus.net/sitemap.xml.gz User-Agent: * Disallow: / Allow: /about @@ -5,4 +6,9 @@ Allow: /terms-of-use Allow: /cites_trade Allow: /species Allow: /eu_legislation - +Allow: /#/elibrary +Allow: /#/taxon_concepts/*/legal +Allow: /#/taxon_concepts/*/names +Allow: /#/taxon_concepts/*/distribution +Allow: /#/taxon_concepts/*/references +Allow: /#/taxon_concepts/*/documents diff --git a/vendor/cache/sitemap_generator-5.1.0.gem b/vendor/cache/sitemap_generator-5.1.0.gem new file mode 100644 index 0000000000000000000000000000000000000000..8cb3807660169e6f99b423bf9bd53e318e68e734 GIT binary patch literal 80896 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 literal 0 HcmV?d00001 From c52dcd3a565529ebc12881deaa3b4cac33149711 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 12 Jul 2016 14:13:11 +0100 Subject: [PATCH 335/365] refresh sitemap daily --- config/schedule.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/config/schedule.rb b/config/schedule.rb index c0fbeda2cd..d5d0f062a4 100644 --- a/config/schedule.rb +++ b/config/schedule.rb @@ -17,3 +17,7 @@ every 5.minutes do rake "elibrary:refresh_document_search" end + +every 1.day, :at => '5:30 am' do + rake "-s sitemap:refresh" +end From 91f321291eff0ab43c95ffade93f6b8fbdaa1c4d Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 7 Jul 2016 10:44:44 +0100 Subject: [PATCH 336/365] fixed the display of delete buttons --- app/assets/stylesheets/trade/layout.scss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/assets/stylesheets/trade/layout.scss b/app/assets/stylesheets/trade/layout.scss index d3cedf0c07..26720690b9 100644 --- a/app/assets/stylesheets/trade/layout.scss +++ b/app/assets/stylesheets/trade/layout.scss @@ -1,5 +1,7 @@ @import "bootstrap"; +li { line-height: 25px; } + body { padding-top: 40px; } .filters { From 6bd60ee9a06822fd9fceaf8bc8c6e71928f0fb0f Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 5 Jul 2016 14:25:56 +0100 Subject: [PATCH 337/365] removed obsolete method --- .../javascripts/trade/models/annual_report_upload.js.coffee | 4 ---- 1 file changed, 4 deletions(-) diff --git a/app/assets/javascripts/trade/models/annual_report_upload.js.coffee b/app/assets/javascripts/trade/models/annual_report_upload.js.coffee index 56df88bc33..116f772cc1 100644 --- a/app/assets/javascripts/trade/models/annual_report_upload.js.coffee +++ b/app/assets/javascripts/trade/models/annual_report_upload.js.coffee @@ -18,10 +18,6 @@ Trade.AnnualReportUpload = DS.Model.extend @get('fileName') + ')' ).property('numberOfRows', 'tradingCountry.name', 'pointOfView') - hasErrors: (-> - @get('validationErrors.length') > 0 - ).property('validationErrors.length') - Trade.Adapter.map('Trade.AnnualReportUpload', { sandboxShipments: { embedded: 'always' } validationErrors: { embedded: 'load' } From 96d73406bbcca4b7e0e0f9a195545d0119f678cf Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 5 Jul 2016 09:07:44 +0100 Subject: [PATCH 338/365] display ignored and not ignored errors in separate sections --- .../trade/models/validation_error.js.coffee | 5 ++ .../templates/annual_report_upload.handlebars | 49 +++++++++---------- .../sandbox_shipments.handlebars | 7 +++ .../validation_errors.handlebars | 39 +++++++++++++++ .../templates/validation_error.handlebars | 14 ------ .../validation_errors_view.js.coffee | 24 +++++++++ .../views/validation_errors_view.js.coffee | 37 -------------- 7 files changed, 99 insertions(+), 76 deletions(-) create mode 100644 app/assets/javascripts/trade/templates/annual_report_upload/validation_errors.handlebars delete mode 100644 app/assets/javascripts/trade/templates/validation_error.handlebars create mode 100644 app/assets/javascripts/trade/views/annual_report_upload/validation_errors_view.js.coffee delete mode 100644 app/assets/javascripts/trade/views/validation_errors_view.js.coffee diff --git a/app/assets/javascripts/trade/models/validation_error.js.coffee b/app/assets/javascripts/trade/models/validation_error.js.coffee index e641f02758..556b67bc2e 100644 --- a/app/assets/javascripts/trade/models/validation_error.js.coffee +++ b/app/assets/javascripts/trade/models/validation_error.js.coffee @@ -6,3 +6,8 @@ Trade.ValidationError = DS.Model.extend sandboxShipmentsIds: ( -> @get('sandboxShipments').mapBy('id') ).property('sandboxShipments.@each') + ignoredValidationErrorId: DS.attr('number') + + isIgnored: ( -> + @get('ignoredValidationErrorId')? + ).property('ignoredValidationErrorId') diff --git a/app/assets/javascripts/trade/templates/annual_report_upload.handlebars b/app/assets/javascripts/trade/templates/annual_report_upload.handlebars index ac6e96f052..63c79e390e 100644 --- a/app/assets/javascripts/trade/templates/annual_report_upload.handlebars +++ b/app/assets/javascripts/trade/templates/annual_report_upload.handlebars @@ -5,34 +5,33 @@ {{ partial 'trade/flash' }} -

+
-
-

Validation errors

-

- {{#if currentError}} - Selected error: {{currentError.errorMessage}} ({{currentError.errorCount}}) - {{/if}} -

-
-
- {{#view tagName='span' class='pull-right' isVisibleBinding='sandboxShipmentsSubmitting'}} - Submitting... - {{/view}} - - {{#if hasErrors}} - - {{/if}} -
+ {{#view tagName='span' class='pull-right' isVisibleBinding='sandboxShipmentsSubmitting'}} + Submitting... + {{/view}} +
-{{collection Trade.ValidationErrorsView contentBinding='validationErrors' controller=this}} +
+ {{view Trade.ValidationErrorsView + heading="Validation errors" + errorType="active" + content=validationErrors + collapsed=false + controller=this}} -{{ outlet }} + {{view Trade.ValidationErrorsView + heading="Ignored validation errors" + errorType="ignored" + content=ignoredValidationErrors + collapsed=true + controller=this}} +
+{{ outlet }} diff --git a/app/assets/javascripts/trade/templates/annual_report_upload/sandbox_shipments.handlebars b/app/assets/javascripts/trade/templates/annual_report_upload/sandbox_shipments.handlebars index 4a0efcc929..092b7109ab 100644 --- a/app/assets/javascripts/trade/templates/annual_report_upload/sandbox_shipments.handlebars +++ b/app/assets/javascripts/trade/templates/annual_report_upload/sandbox_shipments.handlebars @@ -1,3 +1,10 @@ +

+ Selected error: {{controllers.annualReportUpload.currentError.errorMessage}} ({{controllers.annualReportUpload.currentError.errorCount}}) + {{#link-to "annual_report_upload" controllers.annualReportUpload}} + (close this error) + {{/link-to}} +

+
+ {{else}} + + {{/if}} +
+
+ {{else}} +
No errors detected.
+ {{/each}} + + diff --git a/app/assets/javascripts/trade/templates/validation_error.handlebars b/app/assets/javascripts/trade/templates/validation_error.handlebars deleted file mode 100644 index 5541cb1b14..0000000000 --- a/app/assets/javascripts/trade/templates/validation_error.handlebars +++ /dev/null @@ -1,14 +0,0 @@ -
-
- {{#if isPrimary}} - PRIMARY - {{else}} - SECONDARY - {{/if}} -
- -
diff --git a/app/assets/javascripts/trade/views/annual_report_upload/validation_errors_view.js.coffee b/app/assets/javascripts/trade/views/annual_report_upload/validation_errors_view.js.coffee new file mode 100644 index 0000000000..5bbdbfeaf9 --- /dev/null +++ b/app/assets/javascripts/trade/views/annual_report_upload/validation_errors_view.js.coffee @@ -0,0 +1,24 @@ +Trade.ValidationErrorsView = Ember.View.extend + templateName: 'trade/annual_report_upload/validation_errors' + classNames: ['accordion-group'] + + didInsertElement: -> + $(@get('collapsibleElement')).on('hidden', => + @set('collapsed', true) + ) + $(@get('collapsibleElement')).on('shown', => + @set('collapsed', false) + ) + + toggleHint: ( -> + if @get('collapsed') + '>>' + else + '<<' + ).property('collapsed') + collapsibleId: ( -> + @get('errorType') + '-validation-errors' + ).property('errorType') + collapsibleElement: ( -> + '#' + @get('collapsibleId') + ).property('collapsibleId') \ No newline at end of file diff --git a/app/assets/javascripts/trade/views/validation_errors_view.js.coffee b/app/assets/javascripts/trade/views/validation_errors_view.js.coffee deleted file mode 100644 index 02af06b3c9..0000000000 --- a/app/assets/javascripts/trade/views/validation_errors_view.js.coffee +++ /dev/null @@ -1,37 +0,0 @@ -Trade.ValidationErrorsView = Ember.CollectionView.extend - content: null - classNames: ['collapse'] - itemViewClass: Ember.View.extend - templateName: 'trade/validation_error' - emptyView: Ember.View.extend - template: Ember.Handlebars.compile("No errors detected") - - showMessage: 'Show errors' - hideMessage: 'Hide errors' - - didInsertElement: -> - @_updateErrorDisplay() - $('.collapse').on('hidden', => - $('#toggle-errors').text(@showMessage) - ) - $('.collapse').on('shown', => - $('#toggle-errors').text(@hideMessage) - ) - - errorHasChanged: ( -> - @_updateErrorDisplay() - ).observes('controller.currentError') - - _updateErrorDisplay: -> - $error_button = $('#toggle-errors') - # When there is no error message on the annual report controller, then - # the page has not transitioned to a sandbox shipments yet, so all - # errors are shown. Well yes, it does sound a bit messy... any ideas? - if @get('controller.currentError') - $(".collapse").collapse('hide') - $error_button.text(@showMessage) - # The page has transitioned to sandbox_shipments and this will set an - # error message on the parent controller. - else - $(".collapse").collapse('show') - $error_button.text(@hideMessage) From 5d1e43023e5888529078b148414b9c28f2766867 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 5 Jul 2016 14:13:08 +0100 Subject: [PATCH 339/365] persisting & matching against ignored validation errors --- .../models/annual_report_upload.js.coffee | 2 + .../trade/models/validation_error.js.coffee | 10 +-- app/models/trade/annual_report_upload.rb | 3 +- app/models/trade/inclusion_validation_rule.rb | 73 +++++++++++++++---- .../taxon_concept_source_validation_rule.rb | 3 +- app/models/trade/validation_error.rb | 24 +++--- app/models/trade/validation_rule.rb | 55 ++++++++++---- .../show_annual_report_upload_serializer.rb | 12 ++- .../trade/validation_error_serializer.rb | 2 +- ...05093243_create_trade_validation_errors.rb | 35 +++++++++ ...4949_add_timestamps_to_sandbox_template.rb | 28 +++++++ 11 files changed, 190 insertions(+), 57 deletions(-) create mode 100644 db/migrate/20160705093243_create_trade_validation_errors.rb create mode 100644 db/migrate/20160705114949_add_timestamps_to_sandbox_template.rb diff --git a/app/assets/javascripts/trade/models/annual_report_upload.js.coffee b/app/assets/javascripts/trade/models/annual_report_upload.js.coffee index 116f772cc1..e2cd722610 100644 --- a/app/assets/javascripts/trade/models/annual_report_upload.js.coffee +++ b/app/assets/javascripts/trade/models/annual_report_upload.js.coffee @@ -10,6 +10,7 @@ Trade.AnnualReportUpload = DS.Model.extend updatedBy: DS.attr('string') sandboxShipments: DS.hasMany('Trade.SandboxShipment') validationErrors: DS.hasMany('Trade.ValidationError') + ignoredValidationErrors: DS.hasMany('Trade.ValidationError', {key: 'ignored_validation_errors'}) summary: (-> @get('tradingCountry.name') + ' (' + @get('pointOfView') + '), ' + @@ -21,4 +22,5 @@ Trade.AnnualReportUpload = DS.Model.extend Trade.Adapter.map('Trade.AnnualReportUpload', { sandboxShipments: { embedded: 'always' } validationErrors: { embedded: 'load' } + ignoredValidationErrors: { embedded: 'load' } }) diff --git a/app/assets/javascripts/trade/models/validation_error.js.coffee b/app/assets/javascripts/trade/models/validation_error.js.coffee index 556b67bc2e..028fd019aa 100644 --- a/app/assets/javascripts/trade/models/validation_error.js.coffee +++ b/app/assets/javascripts/trade/models/validation_error.js.coffee @@ -2,12 +2,4 @@ Trade.ValidationError = DS.Model.extend errorMessage: DS.attr('string') errorCount: DS.attr('number') isPrimary: DS.attr('boolean') - sandboxShipments: DS.hasMany('Trade.SandboxShipment') - sandboxShipmentsIds: ( -> - @get('sandboxShipments').mapBy('id') - ).property('sandboxShipments.@each') - ignoredValidationErrorId: DS.attr('number') - - isIgnored: ( -> - @get('ignoredValidationErrorId')? - ).property('ignoredValidationErrorId') + isIgnored: DS.attr('boolean') diff --git a/app/models/trade/annual_report_upload.rb b/app/models/trade/annual_report_upload.rb index bf436a3ab0..7b6f12cfa5 100644 --- a/app/models/trade/annual_report_upload.rb +++ b/app/models/trade/annual_report_upload.rb @@ -97,7 +97,8 @@ def submit def run_validations(validation_rules) validation_errors = [] validation_rules.order(:run_order).each do |vr| - validation_errors << vr.validation_errors(self) + vr.refresh_errors_if_needed(self) + validation_errors << vr.validation_errors_for_aru(self) end validation_errors.flatten end diff --git a/app/models/trade/inclusion_validation_rule.rb b/app/models/trade/inclusion_validation_rule.rb index 69294de490..8ca0673a90 100644 --- a/app/models/trade/inclusion_validation_rule.rb +++ b/app/models/trade/inclusion_validation_rule.rb @@ -44,16 +44,22 @@ def error_message(values_hash = nil) info + ' is invalid' end - def validation_errors(annual_report_upload) - matching_records_grouped(annual_report_upload.sandbox.table_name).map do |mr| - values_hash = Hash[column_names_for_display.map { |cn| [cn, mr.send(cn)] }] - Trade::ValidationError.new( - :error_message => error_message(values_hash), - :annual_report_upload_id => annual_report_upload.id, - :validation_rule_id => self.id, - :error_count => mr.error_count, - :matching_records_ids => parse_pg_array(mr.matching_records_ids), - :is_primary => self.is_primary + def refresh_errors_if_needed(annual_report_upload) + return true unless refresh_needed?(annual_report_upload) + matching_records_grouped(annual_report_upload).map do |mr| + values_hash = Hash[column_names.map{ |cn| [cn, mr.send(cn)] }] + values_hash_for_display = Hash[column_names_for_display.map{ |cn| [cn, mr.send(cn)] }] + matching_criteria_jsonb = jsonb_matching_criteria_for_comparison( + values_hash + ) + existing_record = validation_errors_for_aru(annual_report_upload). + where("matching_criteria @> (#{matching_criteria_jsonb})::JSONB").first + update_or_create_error_record( + annual_report_upload, + existing_record, + mr.error_count.to_i, + error_message(values_hash_for_display), + jsonb_matching_criteria_for_insert(values_hash) ) end end @@ -81,14 +87,55 @@ def column_names_for_display end end + def jsonb_matching_criteria_for_insert(values_hash) + jsonb_keys_and_values = column_names.map do |c| + is_numeric = (c =~ /.+_id$/ || c == 'year') + value = values_hash[c] + value_quoted = if is_numeric + value + else + "\"#{value}\"" + end + "\"#{c}\": #{value_quoted}" + end.join(', ') + '{' + jsonb_keys_and_values + '}' + end + + def jsonb_matching_criteria_for_comparison(values_hash = nil) + jsonb_keys_and_values = column_names.map do |c| + is_numeric = (c =~ /.+_id$/ || c == 'year') + value = values_hash && values_hash[c] + column_reference = "matching_records.#{c}" + value_or_column_reference_quoted = if value && is_numeric + value + elsif value && !is_numeric + "'\"#{value}\"'" + elsif !value && is_numeric + column_reference + else + <<-EOT + '"' || #{column_reference} || '"' + EOT + end + <<-EOT + '"' || '#{c}' || '": ' || #{value_or_column_reference_quoted} + EOT + end.join("|| ', ' ||") + "'{' || #{jsonb_keys_and_values} || '}'" + end + # Returns matching records grouped by column_names to return the count of # specific errors and ids of matching records - def matching_records_grouped(table_name) + def matching_records_grouped(annual_report_upload) + table_name = annual_report_upload.sandbox.table_name Trade::SandboxTemplate. select( column_names_for_display + - ['COUNT(*) AS error_count', 'ARRAY_AGG(id) AS matching_records_ids'] - ).from(Arel.sql("(#{matching_records_arel(table_name).to_sql}) AS matching_records")). + [ + 'COUNT(*) AS error_count', + 'ARRAY_AGG(matching_records.id) AS matching_records_ids' + ] + ).from(Arel.sql("(#{matching_records_arel(table_name).to_sql}) matching_records")). group(column_names_for_display).having( required_column_names.map { |cn| "#{cn} IS NOT NULL" }.join(' AND ') ) diff --git a/app/models/trade/taxon_concept_source_validation_rule.rb b/app/models/trade/taxon_concept_source_validation_rule.rb index 4be76c912a..daf16a6b07 100644 --- a/app/models/trade/taxon_concept_source_validation_rule.rb +++ b/app/models/trade/taxon_concept_source_validation_rule.rb @@ -38,7 +38,8 @@ def validation_errors_for_shipment(shipment) # Returns matching records grouped by column_names to return the count of # specific errors and ids of matching records - def matching_records_grouped(table_name) + def matching_records_grouped(annual_report_upload) + table_name = annual_report_upload.sandbox.table_name sandbox_klass = Trade::SandboxTemplate.ar_klass(table_name) sandbox_klass.from("#{table_name}_view #{table_name}"). joins(<<-SQL diff --git a/app/models/trade/validation_error.rb b/app/models/trade/validation_error.rb index 3baed9dd12..098bf11e09 100644 --- a/app/models/trade/validation_error.rb +++ b/app/models/trade/validation_error.rb @@ -1,15 +1,11 @@ -class Trade::ValidationError - include ActiveModel::SerializerSupport - attr_reader :id, :error_message, :error_count, :is_primary, - :sandbox_shipment_ids - - def initialize(attributes = {}) - @id = attributes[:annual_report_upload_id] + - attributes[:validation_rule_id] * 1000 + rand(1000000) - @error_message = attributes[:error_message] - @error_count = attributes[:error_count] - @sandbox_shipment_ids = attributes[:matching_records_ids] - @is_primary = attributes[:is_primary] - end - +class Trade::ValidationError < ActiveRecord::Base + belongs_to :annual_report_upload, class_name: Trade::AnnualReportUpload + belongs_to :validation_rule, class_name: Trade::ValidationRule + attr_accessible :annual_report_upload_id, + :validation_rule_id, + :matching_criteria, + :is_ignored, + :is_primary, + :error_message, + :error_count end diff --git a/app/models/trade/validation_rule.rb b/app/models/trade/validation_rule.rb index 735f64018a..b7687fbc86 100644 --- a/app/models/trade/validation_rule.rb +++ b/app/models/trade/validation_rule.rb @@ -19,6 +19,7 @@ class Trade::ValidationRule < ActiveRecord::Base attr_accessible :column_names, :run_order, :is_primary, :scope, :is_strict include PgArrayParser serialize :scope, ActiveRecord::Coders::NestedHstore + has_many :validation_errors, class_name: Trade::ValidationError # returns column names as in the shipments table, based on the # list of column_names in sandbox @@ -49,23 +50,21 @@ def column_names=(ary) write_attribute(:column_names, '{' + ary.join(',') + '}') end - def validation_errors(annual_report_upload) + def refresh_errors_if_needed(annual_report_upload) + return true unless refresh_needed?(annual_report_upload) + existing_record = validation_errors_for_aru(annual_report_upload).first matching_records = matching_records(annual_report_upload.sandbox.table_name) - error_count = matching_records.length - if error_count > 0 - [ - Trade::ValidationError.new( - :error_message => error_message, - :annual_report_upload_id => annual_report_upload.id, - :validation_rule_id => self.id, - :error_count => error_count, - :matching_records_ids => matching_records.map(&:id), - :is_primary => self.is_primary - ) - ] - else - [] - end + update_or_create_error_record( + annual_report_upload, + existing_record, + matching_records.length, + error_message, + '{}' + ) + end + + def validation_errors_for_aru(annual_report_upload) + validation_errors.where(annual_report_upload_id: annual_report_upload.id) end def validation_errors_for_shipment(shipment) @@ -96,6 +95,30 @@ def sanitized_sandbox_scope private + def update_or_create_error_record(annual_report_upload, existing_record, error_count, error_message, matching_criteria) + if existing_record + existing_record.update_attributes( + error_count: error_count + ) + elsif error_count > 0 + Trade::ValidationError.create( + annual_report_upload_id: annual_report_upload.id, + validation_rule_id: self.id, + matching_criteria: matching_criteria, + error_message: error_message, + error_count: error_count, + is_primary: self.is_primary, + is_ignored: false + ) + end + end + + def refresh_needed?(annual_report_upload) + sandbox_updated_at = Trade::SandboxTemplate.ar_klass(annual_report_upload.sandbox.table_name).maximum(:updated_at) + errors_updated_at = validation_errors_for_aru(annual_report_upload).maximum(:updated_at) + sandbox_updated_at.blank? || errors_updated_at.blank? || sandbox_updated_at > errors_updated_at + end + # If sandbox scope was :source_code => { :inclusion => ['W'] }, shipments # scope needs to be :source_code => { :inclusion => [ID of W] } def sanitized_shipments_scope diff --git a/app/serializers/trade/show_annual_report_upload_serializer.rb b/app/serializers/trade/show_annual_report_upload_serializer.rb index 7d8d247bc9..bd75071d8c 100644 --- a/app/serializers/trade/show_annual_report_upload_serializer.rb +++ b/app/serializers/trade/show_annual_report_upload_serializer.rb @@ -3,10 +3,18 @@ class Trade::ShowAnnualReportUploadSerializer < ActiveModel::Serializer attributes :id, :trading_country_id, :point_of_view, :number_of_rows, :file_name, :is_done, :has_primary_errors, :created_at, :updated_at, :created_by, :updated_by - has_many :validation_errors + has_many :validation_errors, :ignored_validation_errors def validation_errors - object.validation_errors.sort_by(&:error_message) + object.validation_errors.reject do |ve| + ve.is_ignored + end.sort_by(&:error_message) + end + + def ignored_validation_errors + object.validation_errors.select do |ve| + ve.is_ignored + end.sort_by(&:error_message) end def file_name diff --git a/app/serializers/trade/validation_error_serializer.rb b/app/serializers/trade/validation_error_serializer.rb index 5f3fa3e721..ba8103c5a6 100644 --- a/app/serializers/trade/validation_error_serializer.rb +++ b/app/serializers/trade/validation_error_serializer.rb @@ -1,4 +1,4 @@ class Trade::ValidationErrorSerializer < ActiveModel::Serializer attributes :id, :error_message, :error_count, :is_primary, - :sandbox_shipment_ids + :is_ignored end diff --git a/db/migrate/20160705093243_create_trade_validation_errors.rb b/db/migrate/20160705093243_create_trade_validation_errors.rb new file mode 100644 index 0000000000..1533106be8 --- /dev/null +++ b/db/migrate/20160705093243_create_trade_validation_errors.rb @@ -0,0 +1,35 @@ +class CreateTradeValidationErrors < ActiveRecord::Migration + def up + create_table :trade_validation_errors do |t| + t.references :annual_report_upload, null: false + t.references :validation_rule, null: false + t.column :matching_criteria, :jsonb, null: false + t.column :is_ignored, :boolean, default: false + t.column :is_primary, :boolean, default: false + t.column :error_message, :text, null: false + t.column :error_count, :integer, null: false + + t.timestamps + end + add_index :trade_validation_errors, :annual_report_upload_id, + name: :index_trade_validation_errors_on_aru_id + add_index :trade_validation_errors, :validation_rule_id, + name: :index_trade_validation_errors_on_vr_id + execute "CREATE INDEX index_trade_validation_errors_on_matching_criteria + ON trade_validation_errors USING gin (matching_criteria jsonb_path_ops);" + execute "CREATE UNIQUE INDEX index_trade_validation_errors_unique + ON trade_validation_errors (annual_report_upload_id, validation_rule_id, matching_criteria);" + add_foreign_key :trade_validation_errors, :trade_annual_report_uploads, + column: :annual_report_upload_id, + name: :trade_validation_errors_aru_id_fk, + dependent: :delete + add_foreign_key :trade_validation_errors, :trade_validation_rules, + column: :validation_rule_id, + name: :trade_validation_errors_vr_id_fk, + dependent: :delete + end + + def down + drop_table :trade_validation_errors + end +end diff --git a/db/migrate/20160705114949_add_timestamps_to_sandbox_template.rb b/db/migrate/20160705114949_add_timestamps_to_sandbox_template.rb new file mode 100644 index 0000000000..60675221ff --- /dev/null +++ b/db/migrate/20160705114949_add_timestamps_to_sandbox_template.rb @@ -0,0 +1,28 @@ +class AddTimestampsToSandboxTemplate < ActiveRecord::Migration + def up + add_column :trade_sandbox_template, :created_at, :datetime + add_column :trade_sandbox_template, :updated_at, :datetime + + execute 'UPDATE trade_sandbox_template SET created_at = NOW(), updated_at = NOW()' + + change_column :trade_sandbox_template, :created_at, :datetime, + null: false + execute <<-SQL + ALTER TABLE "trade_sandbox_template" ALTER COLUMN "created_at" + SET DEFAULT (NOW() at time zone 'utc') + SQL + change_column :trade_sandbox_template, :updated_at, :datetime, + null: false + execute <<-SQL + ALTER TABLE "trade_sandbox_template" ALTER COLUMN "updated_at" + SET DEFAULT (NOW() at time zone 'utc') + SQL + end + + def down + execute "SELECT * FROM drop_trade_sandbox_views()" + remove_column :trade_sandbox_template, :created_at + remove_column :trade_sandbox_template, :updated_at + execute "SELECT * FROM create_trade_sandbox_views()" + end +end From 141c3e800f2b95696c33ca91c06bb9edb500a8f9 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 5 Jul 2016 10:20:57 +0100 Subject: [PATCH 340/365] construct taxon - source validation query consistently with other inclusion validation queries --- .../taxon_concept_source_validation_rule.rb | 57 +++++++++++-------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/app/models/trade/taxon_concept_source_validation_rule.rb b/app/models/trade/taxon_concept_source_validation_rule.rb index daf16a6b07..7fb1d4864f 100644 --- a/app/models/trade/taxon_concept_source_validation_rule.rb +++ b/app/models/trade/taxon_concept_source_validation_rule.rb @@ -36,30 +36,39 @@ def validation_errors_for_shipment(shipment) private - # Returns matching records grouped by column_names to return the count of - # specific errors and ids of matching records - def matching_records_grouped(annual_report_upload) - table_name = annual_report_upload.sandbox.table_name - sandbox_klass = Trade::SandboxTemplate.ar_klass(table_name) - sandbox_klass.from("#{table_name}_view #{table_name}"). - joins(<<-SQL - INNER JOIN taxon_concepts ON taxon_concepts.id = taxon_concept_id - INNER JOIN taxonomies ON taxonomies.id = taxon_concepts.taxonomy_id - AND taxonomies.name = '#{Taxonomy::CITES_EU}' - SQL - ).where(<<-SQL - ( - UPPER(taxon_concepts.data->'kingdom_name') = 'ANIMALIA' - AND source_code IN (#{INVALID_KINGDOM_SOURCE['ANIMALIA'].map { |c| "'#{c}'" }.join(',')}) - ) OR - ( - UPPER(taxon_concepts.data->'kingdom_name') = 'PLANTAE' - AND source_code IN (#{INVALID_KINGDOM_SOURCE['PLANTAE'].map { |c| "'#{c}'" }.join(',')}) + def matching_records_arel(table_name) + s = Arel::Table.new("#{table_name}_view") + tc = Arel::Table.new('taxon_concepts') + t = Arel::Table.new('taxonomies') + + upper_kingdom_name = Arel::Nodes::NamedFunction.new( + "UPPER", + [ Arel::SqlLiteral.new("taxon_concepts.data->'kingdom_name'") ] + ) + + arel = s.project( + s['id'], + s['taxon_concept_id'], + s['source_code'], + s['accepted_taxon_name'] + ).join(tc).on( + s['taxon_concept_id'].eq(tc['id']) + ).join(t).on( + tc['taxonomy_id'].eq(t['id']).and(t['name'].eq('CITES_EU')) + ).where( + ( + upper_kingdom_name.eq('ANIMALIA').and( + s['source_code'].in( + INVALID_KINGDOM_SOURCE['ANIMALIA'] ) - SQL - ). - select(['COUNT(*) AS error_count', "ARRAY_AGG(#{table_name}.id) AS matching_records_ids", - 'taxon_concept_id', 'accepted_taxon_name', 'source_code']). - group('taxon_concept_id, accepted_taxon_name, source_code') + ) + ).or( + upper_kingdom_name.eq('PLANTAE').and( + s['source_code'].in( + INVALID_KINGDOM_SOURCE['PLANTAE'] + ) + ) + ) + ) end end From 03776efe046155d7833f572df58535d768dcd7d8 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 5 Jul 2016 14:16:51 +0100 Subject: [PATCH 341/365] updating validation error isIgnored property --- .../annual_report_upload_controller.js.coffee | 21 +++++++++++++++++++ .../validation_errors.handlebars | 12 ++++++----- .../trade/validation_errors_controller.rb | 21 +++++++++++++++++++ config/routes.rb | 1 + 4 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 app/controllers/trade/validation_errors_controller.rb diff --git a/app/assets/javascripts/trade/controllers/annual_report_upload_controller.js.coffee b/app/assets/javascripts/trade/controllers/annual_report_upload_controller.js.coffee index 58151113c5..207f352281 100644 --- a/app/assets/javascripts/trade/controllers/annual_report_upload_controller.js.coffee +++ b/app/assets/javascripts/trade/controllers/annual_report_upload_controller.js.coffee @@ -5,6 +5,10 @@ Trade.AnnualReportUploadController = Ember.ObjectController.extend Trade.Flash, filtersSelected: false sandboxShipmentsSubmitting: false + init: -> + transaction = @get('store').transaction() + @set('transaction', transaction) + capitaliseFirstLetter: (string) -> string.charAt(0).toUpperCase() + string.slice(1) @@ -46,3 +50,20 @@ Trade.AnnualReportUploadController = Ember.ObjectController.extend Trade.Flash, @transitionToRoute('sandbox_shipments', { queryParams: params }) + + toggleIgnoreValidationError: (validationError) -> + oldIsIgnoredValue = validationError.get('isIgnored') + validationError.set('isIgnored', !oldIsIgnoredValue) + unless validationError.get('isSaving') + transaction = @get('transaction') + transaction.add(validationError) + transaction.commit() + validationError.one('didUpdate', this, -> + @flashSuccess(message: 'Successfully updated error.') + if oldIsIgnoredValue + @get('validationErrors').addObject(validationError) + @get('ignoredValidationErrors').removeObject(validationError) + else + @get('ignoredValidationErrors').addObject(validationError) + @get('validationErrors').removeObject(validationError) + ) diff --git a/app/assets/javascripts/trade/templates/annual_report_upload/validation_errors.handlebars b/app/assets/javascripts/trade/templates/annual_report_upload/validation_errors.handlebars index 2d5ff00fca..f2fde618af 100644 --- a/app/assets/javascripts/trade/templates/annual_report_upload/validation_errors.handlebars +++ b/app/assets/javascripts/trade/templates/annual_report_upload/validation_errors.handlebars @@ -25,11 +25,13 @@
- {{#if isIgnored}} - - {{else}} - - {{/if}} +
{{else}} diff --git a/app/controllers/trade/validation_errors_controller.rb b/app/controllers/trade/validation_errors_controller.rb new file mode 100644 index 0000000000..5ad0dea111 --- /dev/null +++ b/app/controllers/trade/validation_errors_controller.rb @@ -0,0 +1,21 @@ +class Trade::ValidationErrorsController < TradeController + respond_to :json + + def update + @validation_error = Trade::ValidationError.find(params[:id]) + if @validation_error.update_attributes(validation_error_params) + render json: @validation_error, status: :ok + else + render json: { 'errors' => @validation_error.errors }, + status: :unprocessable_entity + end + end + + private + + def validation_error_params + params.require(:validation_error).permit( + :is_ignored + ) + end +end diff --git a/config/routes.rb b/config/routes.rb index 90c3617384..d9a35773a0 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -174,6 +174,7 @@ end end resources :validation_rules + resources :validation_errors, only: [:update] resources :shipments do collection do post :update_batch From cab224a569a6c39c9b1fe2d14f450405b245d1aa Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 7 Jul 2016 14:31:14 +0100 Subject: [PATCH 342/365] only display ignore / un-ignore button for primary errors --- .../validation_errors.handlebars | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/app/assets/javascripts/trade/templates/annual_report_upload/validation_errors.handlebars b/app/assets/javascripts/trade/templates/annual_report_upload/validation_errors.handlebars index f2fde618af..072ea841b1 100644 --- a/app/assets/javascripts/trade/templates/annual_report_upload/validation_errors.handlebars +++ b/app/assets/javascripts/trade/templates/annual_report_upload/validation_errors.handlebars @@ -25,13 +25,15 @@
- + {{#unless isPrimary}} + + {{/unless}}
{{else}} From c238b9d2e485042e65c8eb33e06539b0c56ed4db Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 7 Jul 2016 14:30:29 +0100 Subject: [PATCH 343/365] pass validation_error_id to backend rather than sandbox_shipments_ids --- .../annual_report_upload_controller.js.coffee | 5 +--- .../sandbox_shipments_controller.js.coffee | 6 ++-- .../routes/sandbox_shipments_route.js.coffee | 2 +- .../trade/sandbox_shipments_controller.rb | 13 +++++---- app/models/trade/inclusion_validation_rule.rb | 13 +++++++-- app/models/trade/sandbox_filter.rb | 7 ++--- app/models/trade/sandbox_search_params.rb | 9 +++--- app/models/trade/sandbox_template.rb | 28 ++++++++++++++++--- app/models/trade/validation_rule.rb | 6 ++++ 9 files changed, 62 insertions(+), 27 deletions(-) diff --git a/app/assets/javascripts/trade/controllers/annual_report_upload_controller.js.coffee b/app/assets/javascripts/trade/controllers/annual_report_upload_controller.js.coffee index 207f352281..51366c4791 100644 --- a/app/assets/javascripts/trade/controllers/annual_report_upload_controller.js.coffee +++ b/app/assets/javascripts/trade/controllers/annual_report_upload_controller.js.coffee @@ -35,16 +35,13 @@ Trade.AnnualReportUploadController = Ember.ObjectController.extend Trade.Flash, dataType: 'json' })).then(onSuccess, onError) - resetFilters: () -> @resetFilters() - - # new for sandbox shipments updateSelection transitionToSandboxShipments: (error) -> @set('currentError', error) params = { - sandbox_shipments_ids: @get('currentError.sandboxShipmentsIds') + validation_error_id: error.get('id') page: 1 } @transitionToRoute('sandbox_shipments', { diff --git a/app/assets/javascripts/trade/controllers/sandbox_shipments_controller.js.coffee b/app/assets/javascripts/trade/controllers/sandbox_shipments_controller.js.coffee index 7e5097e3d5..00a6db3c0a 100644 --- a/app/assets/javascripts/trade/controllers/sandbox_shipments_controller.js.coffee +++ b/app/assets/javascripts/trade/controllers/sandbox_shipments_controller.js.coffee @@ -4,7 +4,7 @@ Trade.SandboxShipmentsController = Ember.ArrayController.extend Trade.ShipmentPa updatesVisible: false currentShipment: null sandboxShipmentsSaving: false - queryParams: ['page', 'sandboxShipmentsIds:sandbox_shipments_ids'] + queryParams: ['page', 'validationErrorId:validation_error_id'] columns: [ 'appendix', 'taxon_name', 'accepted_taxon_name', @@ -78,7 +78,7 @@ Trade.SandboxShipmentsController = Ember.ArrayController.extend Trade.ShipmentPa url: "trade/annual_report_uploads/#{annualReportUploadId}/sandbox_shipments/update_batch" type: "POST" data: { - sandbox_shipments_ids: @get("controllers.annualReportUpload.currentError.sandboxShipments").mapBy("id"), + validation_error_id: @get("controllers.annualReportUpload.currentError.id"), updates: valuesToUpdate } ).success( (data, textStatus, jqXHR) => @@ -97,7 +97,7 @@ Trade.SandboxShipmentsController = Ember.ArrayController.extend Trade.ShipmentPa url: "trade/annual_report_uploads/#{annualReportUploadId}/sandbox_shipments/destroy_batch" type: "POST" data: { - sandbox_shipments_ids: @get("controllers.annualReportUpload.currentError.sandboxShipments").mapBy("id") + validation_error_id: @get("controllers.annualReportUpload.currentError.id") } ).success( (data, textStatus, jqXHR) => @flashSuccess(message: 'Successfully destroyed shipments.', persists: true) diff --git a/app/assets/javascripts/trade/routes/sandbox_shipments_route.js.coffee b/app/assets/javascripts/trade/routes/sandbox_shipments_route.js.coffee index a477458849..45f43245d2 100644 --- a/app/assets/javascripts/trade/routes/sandbox_shipments_route.js.coffee +++ b/app/assets/javascripts/trade/routes/sandbox_shipments_route.js.coffee @@ -1,6 +1,6 @@ Trade.SandboxShipmentsRoute = Trade.BeforeRoute.extend queryParams: { - sandbox_shipments_ids: { refreshModel: true }, + validation_error_id: { refreshModel: true }, page: { refreshModel: true } } diff --git a/app/controllers/trade/sandbox_shipments_controller.rb b/app/controllers/trade/sandbox_shipments_controller.rb index 9ef7accf2e..ecbd3d865a 100644 --- a/app/controllers/trade/sandbox_shipments_controller.rb +++ b/app/controllers/trade/sandbox_shipments_controller.rb @@ -24,24 +24,26 @@ def destroy aru = Trade::AnnualReportUpload.find(params[:annual_report_upload_id]) sandbox_klass = Trade::SandboxTemplate.ar_klass(aru.sandbox.table_name) @sandbox_shipment = sandbox_klass.find(params[:id]) - @sandbox_shipment.delete + @sandbox_shipment.destroy aru.update_attribute(:number_of_rows, aru.sandbox_shipments.size) head :no_content end def update_batch aru = Trade::AnnualReportUpload.find(params[:annual_report_upload_id]) + ve = Trade::ValidationError.find(params[:validation_error_id]) sandbox_klass = Trade::SandboxTemplate.ar_klass(aru.sandbox.table_name) sandbox_klass.update_batch( - update_batch_params[:updates], update_batch_params[:sandbox_shipments_ids] + update_batch_params[:updates], ve, aru ) head :no_content end def destroy_batch aru = Trade::AnnualReportUpload.find(params[:annual_report_upload_id]) + ve = Trade::ValidationError.find(params[:validation_error_id]) sandbox_klass = Trade::SandboxTemplate.ar_klass(aru.sandbox.table_name) - sandbox_klass.destroy_batch(destroy_batch_params[:sandbox_shipments_ids]) + sandbox_klass.destroy_batch(ve, aru) aru.update_attribute(:number_of_rows, aru.sandbox_shipments.size) head :no_content end @@ -53,12 +55,13 @@ def sandbox_shipment_params end def destroy_batch_params - params.permit(:sandbox_shipments_ids => []) + params.permit(:annual_report_upload_id, :validation_error_id) end def update_batch_params params.permit( - :sandbox_shipments_ids => [], + :annual_report_upload_id, + :validation_error_id, :updates => sandbox_shipment_attributes ) end diff --git a/app/models/trade/inclusion_validation_rule.rb b/app/models/trade/inclusion_validation_rule.rb index 8ca0673a90..f6a326bbb8 100644 --- a/app/models/trade/inclusion_validation_rule.rb +++ b/app/models/trade/inclusion_validation_rule.rb @@ -18,6 +18,15 @@ class Trade::InclusionValidationRule < Trade::ValidationRule attr_accessible :valid_values_view + def matching_records_for_aru_and_error(annual_report_upload, validation_error) + sandbox_klass = Trade::SandboxTemplate.ar_klass(annual_report_upload.sandbox.table_name) + @query = sandbox_klass. + from("#{sandbox_klass.table_name}_view #{sandbox_klass.table_name}"). + where( + "'#{validation_error.matching_criteria}'::JSONB @> (#{jsonb_matching_criteria_for_comparison})::JSONB" + ) + end + def error_message(values_hash = nil) scope_info = sanitized_sandbox_scope.map do |scope_column, scope_def| tmp = [] @@ -105,7 +114,7 @@ def jsonb_matching_criteria_for_comparison(values_hash = nil) jsonb_keys_and_values = column_names.map do |c| is_numeric = (c =~ /.+_id$/ || c == 'year') value = values_hash && values_hash[c] - column_reference = "matching_records.#{c}" + column_reference = c value_or_column_reference_quoted = if value && is_numeric value elsif value && !is_numeric @@ -133,7 +142,7 @@ def matching_records_grouped(annual_report_upload) column_names_for_display + [ 'COUNT(*) AS error_count', - 'ARRAY_AGG(matching_records.id) AS matching_records_ids' + 'ARRAY_AGG(id) AS matching_records_ids' ] ).from(Arel.sql("(#{matching_records_arel(table_name).to_sql}) matching_records")). group(column_names_for_display).having( diff --git a/app/models/trade/sandbox_filter.rb b/app/models/trade/sandbox_filter.rb index eab7f1b13a..132a205a2d 100644 --- a/app/models/trade/sandbox_filter.rb +++ b/app/models/trade/sandbox_filter.rb @@ -10,9 +10,8 @@ def initialize_params(options) def initialize_query aru = Trade::AnnualReportUpload.find(@options[:annual_report_upload_id]) - sandbox_klass = Trade::SandboxTemplate.ar_klass(aru.sandbox.table_name) - @query = sandbox_klass.scoped - - @query = @query.where(:id => @options[:sandbox_shipments_ids]) + ve = Trade::ValidationError.find(@options[:validation_error_id]) + vr = ve.validation_rule + @query = vr.matching_records_for_aru_and_error(aru, ve) end end diff --git a/app/models/trade/sandbox_search_params.rb b/app/models/trade/sandbox_search_params.rb index 0aec4fa575..836ba4dfd1 100644 --- a/app/models/trade/sandbox_search_params.rb +++ b/app/models/trade/sandbox_search_params.rb @@ -3,12 +3,13 @@ # # Array parameters are sorted for caching purposes. class Trade::SandboxSearchParams < Hash + include SearchParamSanitiser def initialize(params) sanitized_params = { - :annual_report_upload_id => params[:annual_report_upload_id], - :sandbox_shipments_ids => params[:sandbox_shipments_ids] && params[:sandbox_shipments_ids].split(","), - :page => params[:page] && params[:page].to_i > 0 ? params[:page].to_i : 1, - :per_page => params[:per_page] && params[:per_page].to_i > 0 ? params[:per_page].to_i : 100 + annual_report_upload_id: sanitise_positive_integer(params[:annual_report_upload_id], nil), + validation_error_id: sanitise_positive_integer(params[:validation_error_id], nil), + page: sanitise_positive_integer(params[:page], 1), + per_page: sanitise_positive_integer(params[:per_page], 100) } super(sanitized_params) self.merge!(sanitized_params) diff --git a/app/models/trade/sandbox_template.rb b/app/models/trade/sandbox_template.rb index 4c61d81820..a00d7cde19 100644 --- a/app/models/trade/sandbox_template.rb +++ b/app/models/trade/sandbox_template.rb @@ -96,14 +96,34 @@ def save(attributes = {}) sanitize end - def self.update_batch(updates, sandbox_shipments_ids) + def destroy + super + self.class.update_all(updated_at: Time.now) # bump timestamp to ensure errors refreshed + end + + def self.records_for_batch_operation(validation_error, annual_report_upload) + vr = validation_error.validation_rule + joins( + <<-SQL + JOIN ( + #{vr.matching_records_for_aru_and_error(annual_report_upload, validation_error).to_sql} + ) matching_records on #{table_name}.id = matching_records.id + SQL + ) + end + + def self.update_batch(updates, validation_error, annual_report_upload) return unless updates - where(:id => sandbox_shipments_ids).update_all(updates) + updates[:updated_at] = Time.now() + records_for_batch_operation(validation_error, annual_report_upload). + update_all(updates) sanitize end - def self.destroy_batch(sandbox_shipments_ids) - where(:id => sandbox_shipments_ids).delete_all + def self.destroy_batch(validation_error, annual_report_upload) + records_for_batch_operation(validation_error, annual_report_upload). + each(&:delete) + update_all(updated_at: Time.now) # bump timestamp to ensure errors refreshed end end diff --git a/app/models/trade/validation_rule.rb b/app/models/trade/validation_rule.rb index b7687fbc86..f2783de11d 100644 --- a/app/models/trade/validation_rule.rb +++ b/app/models/trade/validation_rule.rb @@ -21,6 +21,12 @@ class Trade::ValidationRule < ActiveRecord::Base serialize :scope, ActiveRecord::Coders::NestedHstore has_many :validation_errors, class_name: Trade::ValidationError + def matching_records_for_aru_and_error(annual_report_upload, validation_error) + table_name = annual_report_upload.sandbox.table_name + matching_records(table_name). + from("#{table_name}_view AS #{table_name}") + end + # returns column names as in the shipments table, based on the # list of column_names in sandbox def shipments_columns From a5a511da63b419df045f265c3d2842cb64dd9a17 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 8 Jul 2016 11:13:39 +0100 Subject: [PATCH 344/365] fetch validation error details when transitioning into sandbox_shipments --- .../trade/routes/sandbox_shipments_route.js.coffee | 5 +++++ app/controllers/trade/validation_errors_controller.rb | 5 +++++ config/routes.rb | 2 +- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/trade/routes/sandbox_shipments_route.js.coffee b/app/assets/javascripts/trade/routes/sandbox_shipments_route.js.coffee index 45f43245d2..7fa1781958 100644 --- a/app/assets/javascripts/trade/routes/sandbox_shipments_route.js.coffee +++ b/app/assets/javascripts/trade/routes/sandbox_shipments_route.js.coffee @@ -5,4 +5,9 @@ Trade.SandboxShipmentsRoute = Trade.BeforeRoute.extend } model: (params, transition) -> + @validationError = Trade.ValidationError.find(params.validation_error_id) Trade.SandboxShipment.find(params) + + setupController: (controller, model) -> + controller.set('model', model) + @controllerFor('annualReportUpload').set('currentError', @validationError) diff --git a/app/controllers/trade/validation_errors_controller.rb b/app/controllers/trade/validation_errors_controller.rb index 5ad0dea111..5ec095a5b5 100644 --- a/app/controllers/trade/validation_errors_controller.rb +++ b/app/controllers/trade/validation_errors_controller.rb @@ -1,6 +1,11 @@ class Trade::ValidationErrorsController < TradeController respond_to :json + def show + @validation_error = Trade::ValidationError.find(params[:id]) + render json: @validation_error, status: :ok + end + def update @validation_error = Trade::ValidationError.find(params[:id]) if @validation_error.update_attributes(validation_error_params) diff --git a/config/routes.rb b/config/routes.rb index d9a35773a0..5186904647 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -174,7 +174,7 @@ end end resources :validation_rules - resources :validation_errors, only: [:update] + resources :validation_errors, only: [:update, :show] resources :shipments do collection do post :update_batch From 19a2fb6cf5acd749fb1dd4e46559c339e174391c Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 8 Jul 2016 11:23:17 +0100 Subject: [PATCH 345/365] destroying non-ignored errors once they have 0 count --- app/models/trade/inclusion_validation_rule.rb | 5 +++++ app/models/trade/validation_rule.rb | 10 +++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/app/models/trade/inclusion_validation_rule.rb b/app/models/trade/inclusion_validation_rule.rb index f6a326bbb8..3533e9c8da 100644 --- a/app/models/trade/inclusion_validation_rule.rb +++ b/app/models/trade/inclusion_validation_rule.rb @@ -55,6 +55,7 @@ def error_message(values_hash = nil) def refresh_errors_if_needed(annual_report_upload) return true unless refresh_needed?(annual_report_upload) + errors_to_destroy = validation_errors.where(is_ignored: false) matching_records_grouped(annual_report_upload).map do |mr| values_hash = Hash[column_names.map{ |cn| [cn, mr.send(cn)] }] values_hash_for_display = Hash[column_names_for_display.map{ |cn| [cn, mr.send(cn)] }] @@ -70,7 +71,11 @@ def refresh_errors_if_needed(annual_report_upload) error_message(values_hash_for_display), jsonb_matching_criteria_for_insert(values_hash) ) + if existing_record + errors_to_destroy.reject!{ |e| e.id == existing_record.id } + end end + errors_to_destroy.each(&:destroy) end def validation_errors_for_shipment(shipment) diff --git a/app/models/trade/validation_rule.rb b/app/models/trade/validation_rule.rb index f2783de11d..3002519f49 100644 --- a/app/models/trade/validation_rule.rb +++ b/app/models/trade/validation_rule.rb @@ -103,9 +103,13 @@ def sanitized_sandbox_scope def update_or_create_error_record(annual_report_upload, existing_record, error_count, error_message, matching_criteria) if existing_record - existing_record.update_attributes( - error_count: error_count - ) + if !existing_record.is_ignored && error_count == 0 + existing_record.destroy + else + existing_record.update_attributes( + error_count: error_count + ) + end elsif error_count > 0 Trade::ValidationError.create( annual_report_upload_id: annual_report_upload.id, From 393af2d8b7315b8676f68073edd50ec9ea474592 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 8 Jul 2016 12:59:57 +0100 Subject: [PATCH 346/365] use sandbox.ar_klass to ensure associations are picked up correctly --- app/models/trade/format_validation_rule.rb | 6 ++++-- app/models/trade/numericality_validation_rule.rb | 6 ++++-- app/models/trade/presence_validation_rule.rb | 6 ++++-- app/models/trade/validation_rule.rb | 6 +++--- 4 files changed, 15 insertions(+), 9 deletions(-) diff --git a/app/models/trade/format_validation_rule.rb b/app/models/trade/format_validation_rule.rb index 0fd9151ef3..08c8c7cefe 100644 --- a/app/models/trade/format_validation_rule.rb +++ b/app/models/trade/format_validation_rule.rb @@ -26,9 +26,11 @@ def error_message # Returns records that do not pass the regex test for all columns # specified in column_names. - def matching_records(table_name) + def matching_records(annual_report_upload) + table_name = annual_report_upload.sandbox.table_name + sandbox_klass = Trade::SandboxTemplate.ar_klass(table_name) s = Arel::Table.new(table_name) arel_nodes = column_names.map { |c| "#{c} !~ '#{format_re}'" } - Trade::SandboxTemplate.select('*').from(table_name).where(arel_nodes.inject(&:or)) + sandbox_klass.select('*').where(arel_nodes.inject(&:or)) end end diff --git a/app/models/trade/numericality_validation_rule.rb b/app/models/trade/numericality_validation_rule.rb index ed34b53b61..b1c3e21acd 100644 --- a/app/models/trade/numericality_validation_rule.rb +++ b/app/models/trade/numericality_validation_rule.rb @@ -25,13 +25,15 @@ def error_message # Returns records that do not pass the ISNUMERIC test for all columns # specified in column_names. - def matching_records(table_name) + def matching_records(annual_report_upload) + table_name = annual_report_upload.sandbox.table_name + sandbox_klass = Trade::SandboxTemplate.ar_klass(table_name) s = Arel::Table.new(table_name) arel_columns = column_names.map { |c| Arel::Attribute.new(s, c) } isnumeric_columns = arel_columns.map do |a| Arel::Nodes::NamedFunction.new 'isnumeric', [a] end arel_nodes = isnumeric_columns.map { |c| c.eq(false) } - Trade::SandboxTemplate.select('*').from(table_name).where(arel_nodes.inject(&:or)) + sandbox_klass.select('*').where(arel_nodes.inject(&:or)) end end diff --git a/app/models/trade/presence_validation_rule.rb b/app/models/trade/presence_validation_rule.rb index 7d199d8882..692a0e1dcd 100644 --- a/app/models/trade/presence_validation_rule.rb +++ b/app/models/trade/presence_validation_rule.rb @@ -23,11 +23,13 @@ def error_message # Returns records where the specified columns are NULL. # In case more than one column is specified, predicates are combined # using AND. - def matching_records(table_name) + def matching_records(annual_report_upload) + table_name = annual_report_upload.sandbox.table_name + sandbox_klass = Trade::SandboxTemplate.ar_klass(table_name) s = Arel::Table.new(table_name) arel_nodes = column_names.map do |c| s[c].eq(nil) end - Trade::SandboxTemplate.select('*').from(table_name).where(arel_nodes.inject(&:and)) + sandbox_klass.select('*').where(arel_nodes.inject(&:and)) end end diff --git a/app/models/trade/validation_rule.rb b/app/models/trade/validation_rule.rb index 3002519f49..6edd41979b 100644 --- a/app/models/trade/validation_rule.rb +++ b/app/models/trade/validation_rule.rb @@ -23,8 +23,8 @@ class Trade::ValidationRule < ActiveRecord::Base def matching_records_for_aru_and_error(annual_report_upload, validation_error) table_name = annual_report_upload.sandbox.table_name - matching_records(table_name). - from("#{table_name}_view AS #{table_name}") + matching_records(annual_report_upload). + from("#{table_name}_view AS #{table_name}") end # returns column names as in the shipments table, based on the @@ -59,7 +59,7 @@ def column_names=(ary) def refresh_errors_if_needed(annual_report_upload) return true unless refresh_needed?(annual_report_upload) existing_record = validation_errors_for_aru(annual_report_upload).first - matching_records = matching_records(annual_report_upload.sandbox.table_name) + matching_records = matching_records(annual_report_upload) update_or_create_error_record( annual_report_upload, existing_record, From a0c22a480cdac21c50a43aee8c98abe4a298748b Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 11 Jul 2016 11:49:43 +0100 Subject: [PATCH 347/365] fixed issue with searching by blank --- app/models/trade/inclusion_validation_rule.rb | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/app/models/trade/inclusion_validation_rule.rb b/app/models/trade/inclusion_validation_rule.rb index 3533e9c8da..8abe273920 100644 --- a/app/models/trade/inclusion_validation_rule.rb +++ b/app/models/trade/inclusion_validation_rule.rb @@ -55,7 +55,7 @@ def error_message(values_hash = nil) def refresh_errors_if_needed(annual_report_upload) return true unless refresh_needed?(annual_report_upload) - errors_to_destroy = validation_errors.where(is_ignored: false) + errors_to_destroy = validation_errors.where(is_ignored: false).all matching_records_grouped(annual_report_upload).map do |mr| values_hash = Hash[column_names.map{ |cn| [cn, mr.send(cn)] }] values_hash_for_display = Hash[column_names_for_display.map{ |cn| [cn, mr.send(cn)] }] @@ -118,13 +118,14 @@ def jsonb_matching_criteria_for_insert(values_hash) def jsonb_matching_criteria_for_comparison(values_hash = nil) jsonb_keys_and_values = column_names.map do |c| is_numeric = (c =~ /.+_id$/ || c == 'year') - value = values_hash && values_hash[c] - column_reference = c - value_or_column_reference_quoted = if value && is_numeric + value_present = values_hash && values_hash.key?(c) + value = value_present && values_hash[c] + column_reference = "#{c}" + value_or_column_reference_quoted = if value_present && is_numeric value - elsif value && !is_numeric + elsif value_present && !is_numeric "'\"#{value}\"'" - elsif !value && is_numeric + elsif !value_present && is_numeric column_reference else <<-EOT From fb7e325c905a7c8feb15f93f4277f23908b170c8 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 11 Jul 2016 11:58:30 +0100 Subject: [PATCH 348/365] fixed model specs --- spec/factories/trade.rb | 6 ++++ .../distinct_values_validation_rule_spec.rb | 11 ++++--- .../trade/inclusion_validation_rule_spec.rb | 30 ++++++++++--------- .../pov_inclusion_validation_rule_spec.rb | 16 ++++++---- spec/models/trade/sandbox_template_spec.rb | 23 ++++++++++---- spec/models/trade/shipment_spec.rb | 5 +++- ...cept_appendix_year_validation_rule_spec.rb | 29 +++++++++++------- ...xon_concept_source_validation_rule_spec.rb | 11 ++++--- spec/models/trade/validation_rule_spec.rb | 15 ++++++---- spec/support/sapi_helpers.rb | 9 ++++++ 10 files changed, 105 insertions(+), 50 deletions(-) diff --git a/spec/factories/trade.rb b/spec/factories/trade.rb index 7a32afab9e..c78ecdbba6 100644 --- a/spec/factories/trade.rb +++ b/spec/factories/trade.rb @@ -47,7 +47,13 @@ :class => Trade::DistinctValuesValidationRule factory :taxon_concept_source_validation_rule, :class => Trade::TaxonConceptSourceValidationRule + end + factory :validation_error, :class => Trade::ValidationError do + annual_report_upload + validation_rule + matching_criteria '{}' + is_ignored false end factory :trade_taxon_concept_term_pair, :class => Trade::TaxonConceptTermPair do diff --git a/spec/models/trade/distinct_values_validation_rule_spec.rb b/spec/models/trade/distinct_values_validation_rule_spec.rb index c8c66267c1..313384298b 100644 --- a/spec/models/trade/distinct_values_validation_rule_spec.rb +++ b/spec/models/trade/distinct_values_validation_rule_spec.rb @@ -34,7 +34,7 @@ :iso_code2 => 'AR' ) } - describe :validation_errors do + describe :validation_errors_for_aru do before(:each) do @aru = build(:annual_report_upload, :point_of_view => 'E', :trading_country_id => canada.id) @@ -50,7 +50,8 @@ create_exporter_importer_validation } specify { - subject.validation_errors(@aru).size.should == 1 + subject.refresh_errors_if_needed(@aru) + subject.validation_errors_for_aru(@aru).size.should == 1 } end context 'exporter should not equal importer (I)' do @@ -66,7 +67,8 @@ create_exporter_importer_validation } specify { - subject.validation_errors(@aru).size.should == 1 + subject.refresh_errors_if_needed(@aru) + subject.validation_errors_for_aru(@aru).size.should == 1 } end context 'exporter should not equal country of origin' do @@ -78,7 +80,8 @@ create_exporter_country_of_origin_validation } specify { - subject.validation_errors(@aru).size.should == 1 + subject.refresh_errors_if_needed(@aru) + subject.validation_errors_for_aru(@aru).size.should == 1 } end end diff --git a/spec/models/trade/inclusion_validation_rule_spec.rb b/spec/models/trade/inclusion_validation_rule_spec.rb index 6db4957804..e944dee9de 100644 --- a/spec/models/trade/inclusion_validation_rule_spec.rb +++ b/spec/models/trade/inclusion_validation_rule_spec.rb @@ -29,7 +29,7 @@ let(:sandbox_klass) { Trade::SandboxTemplate.ar_klass(annual_report_upload.sandbox.table_name) } - describe :validation_errors do + describe :validation_errors_for_aru do context 'species name may have extra whitespace between name segments' do before(:each) do genus = create_cites_eu_genus( @@ -41,15 +41,11 @@ ) end subject { - create( - :inclusion_validation_rule, - :column_names => ['taxon_name'], - :valid_values_view => 'valid_taxon_name_view', - :is_strict => true - ) + create_taxon_concept_validation } specify { - subject.validation_errors(annual_report_upload).should be_empty + subject.refresh_errors_if_needed(annual_report_upload) + subject.validation_errors_for_aru(annual_report_upload).should be_empty } end context 'trading partner should be a valid iso code' do @@ -75,7 +71,8 @@ ) } specify { - subject.validation_errors(annual_report_upload).size.should == 1 + subject.refresh_errors_if_needed(annual_report_upload) + subject.validation_errors_for_aru(annual_report_upload).size.should == 1 } end context 'term can only be paired with unit as defined by term_trade_codes_pairs table' do @@ -101,7 +98,8 @@ create_term_unit_validation } specify { - subject.validation_errors(annual_report_upload).size.should == 1 + subject.refresh_errors_if_needed(annual_report_upload) + subject.validation_errors_for_aru(annual_report_upload).size.should == 1 } end context "when required unit blank" do @@ -112,7 +110,8 @@ create_term_unit_validation } specify { - subject.validation_errors(annual_report_upload).size.should == 1 + subject.refresh_errors_if_needed(annual_report_upload) + subject.validation_errors_for_aru(annual_report_upload).size.should == 1 } end end @@ -131,7 +130,8 @@ create_term_purpose_validation } specify { - subject.validation_errors(annual_report_upload).size.should == 2 + subject.refresh_errors_if_needed(annual_report_upload) + subject.validation_errors_for_aru(annual_report_upload).size.should == 2 } end context 'taxon_concept_id can only be paired with term as defined by trade_taxon_concept_term_pairs table' do @@ -151,7 +151,8 @@ sandbox_klass.create(:term_code => 'BAL', :taxon_name => @species.full_name) end specify { - subject.validation_errors(annual_report_upload).size.should == 1 + subject.refresh_errors_if_needed(annual_report_upload) + subject.validation_errors_for_aru(annual_report_upload).size.should == 1 } end context "when hybrid" do @@ -167,7 +168,8 @@ sandbox_klass.create(:term_code => 'BAL', :taxon_name => @hybrid.full_name) end specify { - subject.validation_errors(annual_report_upload).size.should == 1 + subject.refresh_errors_if_needed(annual_report_upload) + subject.validation_errors_for_aru(annual_report_upload).size.should == 1 } end end diff --git a/spec/models/trade/pov_inclusion_validation_rule_spec.rb b/spec/models/trade/pov_inclusion_validation_rule_spec.rb index 19610240eb..72fde7179b 100644 --- a/spec/models/trade/pov_inclusion_validation_rule_spec.rb +++ b/spec/models/trade/pov_inclusion_validation_rule_spec.rb @@ -55,7 +55,7 @@ :geo_entity => argentina ) end - describe :validation_errors do + describe :validation_errors_for_aru do context "when W source and country of origin blank and exporter doesn't match distribution (E)" do before(:each) do @aru = build(:annual_report_upload, :point_of_view => 'E', :trading_country_id => canada.id) @@ -72,7 +72,8 @@ create_taxon_concept_exporter_validation } specify { - subject.validation_errors(@aru).size.should == 1 + subject.refresh_errors_if_needed(@aru) + subject.validation_errors_for_aru(@aru).size.should == 1 } end context "when W source and country of origin blank and exporter doesn't match distribution (I)" do @@ -94,7 +95,8 @@ create_taxon_concept_exporter_validation } specify { - subject.validation_errors(@aru).size.should == 1 + subject.refresh_errors_if_needed(@aru) + subject.validation_errors_for_aru(@aru).size.should == 1 } end context "when W source and country XX" do @@ -116,7 +118,8 @@ create_taxon_concept_exporter_validation } specify { - subject.validation_errors(@aru).should be_empty + subject.refresh_errors_if_needed(@aru) + subject.validation_errors_for_aru(@aru).should be_empty } end context "when W source and country doesn't match distribution of higher taxa" do @@ -138,7 +141,8 @@ create_taxon_concept_exporter_validation } specify { - subject.validation_errors(@aru).should be_empty + subject.refresh_errors_if_needed(@aru) + subject.validation_errors_for_aru(@aru).should be_empty } end context "when invalid scope specified" do @@ -154,7 +158,7 @@ create_taxon_concept_exporter_validation } specify { - expect { subject.validation_errors(@aru) }.to_not raise_error(ActiveRecord::StatementInvalid) + expect{ subject.validation_errors_for_aru(@aru) }.to_not raise_error(ActiveRecord::StatementInvalid) } end end diff --git a/spec/models/trade/sandbox_template_spec.rb b/spec/models/trade/sandbox_template_spec.rb index 77d1a40874..7b275bfcb5 100644 --- a/spec/models/trade/sandbox_template_spec.rb +++ b/spec/models/trade/sandbox_template_spec.rb @@ -61,15 +61,28 @@ describe :update_batch do before(:each) do - @shipment1 = sandbox_klass.create(:taxon_name => canis_lupus.full_name) - @shipment2 = sandbox_klass.create(:taxon_name => canis_aureus.full_name) + canis_lupus + @shipment = sandbox_klass.create(:taxon_name => 'Caniis lupus') + validation_rule = create_taxon_concept_validation + @validation_error = create( + :validation_error, + annual_report_upload_id: annual_report_upload.id, + validation_rule_id: validation_rule.id, + matching_criteria: "{\"taxon_name\": \"Caniis lupus\"}", + is_ignored: false, + is_primary: true, + error_message: "taxon_name Caniis lupus is invalid", + error_count: 1 + ) end specify { + @shipment.reload.taxon_concept_id.should be_nil sandbox_klass.update_batch( - { :taxon_name => 'Canis aureus' }, - [@shipment1.id] + { taxon_name: 'Canis lupus' }, + @validation_error, + annual_report_upload ) - @shipment1.reload.taxon_concept_id.should == canis_aureus.id + @shipment.reload.taxon_concept_id.should == canis_lupus.id } end diff --git a/spec/models/trade/shipment_spec.rb b/spec/models/trade/shipment_spec.rb index db17cf86e7..7bb0dafbf4 100644 --- a/spec/models/trade/shipment_spec.rb +++ b/spec/models/trade/shipment_spec.rb @@ -109,6 +109,7 @@ :effective_at => '2013-01-01', :is_current => true ) + reg2013 # EU event Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings create_taxon_concept_appendix_year_validation end @@ -169,6 +170,7 @@ :taxon_name => create(:taxon_name, :scientific_name => 'nonsignificatus'), :parent => @genus ) + reg2013 # EU event Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings create_taxon_concept_appendix_year_validation end @@ -428,7 +430,8 @@ @artificial = create(:trade_code, :type => 'Source', :code => 'A', :name_en => 'Artificially propagated') create_taxon_concept_source_validation cites - eu + reg2013 # EU event + Designation.all.each{ |d| puts d.inspect } Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings @taxon_concept.reload end diff --git a/spec/models/trade/taxon_concept_appendix_year_validation_rule_spec.rb b/spec/models/trade/taxon_concept_appendix_year_validation_rule_spec.rb index 36ec73fb8a..c141d8e3cb 100644 --- a/spec/models/trade/taxon_concept_appendix_year_validation_rule_spec.rb +++ b/spec/models/trade/taxon_concept_appendix_year_validation_rule_spec.rb @@ -18,7 +18,7 @@ require 'spec_helper' describe Trade::TaxonConceptAppendixYearValidationRule, :drops_tables => true do - describe :validation_errors do + describe :validation_errors_for_aru do before(:each) do @aru = build(:annual_report_upload) @@ -75,7 +75,8 @@ create_taxon_concept_appendix_year_validation } specify { - subject.validation_errors(@aru).size.should == 0 + subject.refresh_errors_if_needed(@aru) + subject.validation_errors_for_aru(@aru).size.should == 0 } end context "when old listing" do @@ -91,10 +92,12 @@ create_taxon_concept_appendix_year_validation } specify { - subject.validation_errors(@aru).size.should == 1 + subject.refresh_errors_if_needed(@aru) + subject.validation_errors_for_aru(@aru).size.should == 1 } specify { - ve = subject.validation_errors(@aru).first + subject.refresh_errors_if_needed(@aru) + ve = subject.validation_errors_for_aru(@aru).first ve.error_message.should == 'taxon_name Loxodonta africana with appendix II with year 1996 is invalid' } end @@ -108,10 +111,12 @@ create_taxon_concept_appendix_year_validation } specify { - subject.validation_errors(@aru).size.should == 1 + subject.refresh_errors_if_needed(@aru) + subject.validation_errors_for_aru(@aru).size.should == 1 } specify { - ve = subject.validation_errors(@aru).first + subject.refresh_errors_if_needed(@aru) + ve = subject.validation_errors_for_aru(@aru).first ve.error_message.should == 'taxon_name Loxodonta africana with appendix N with year 1996 is invalid' } end @@ -125,7 +130,8 @@ create_taxon_concept_appendix_year_validation } specify { - subject.validation_errors(@aru).size.should == 0 + subject.refresh_errors_if_needed(@aru) + subject.validation_errors_for_aru(@aru).size.should == 0 } end context "when hybrid" do @@ -161,7 +167,8 @@ create_taxon_concept_appendix_year_validation } specify { - subject.validation_errors(@aru).size.should == 0 + subject.refresh_errors_if_needed(@aru) + subject.validation_errors_for_aru(@aru).size.should == 0 } end end @@ -176,7 +183,8 @@ create_taxon_concept_appendix_year_validation } specify { - subject.validation_errors(@aru).size.should == 0 + subject.refresh_errors_if_needed(@aru) + subject.validation_errors_for_aru(@aru).size.should == 0 } end context "when not CITES listed and not EU listed" do @@ -190,7 +198,8 @@ create_taxon_concept_appendix_year_validation } specify { - subject.validation_errors(@aru).size.should == 1 + subject.refresh_errors_if_needed(@aru) + subject.validation_errors_for_aru(@aru).size.should == 1 } end end diff --git a/spec/models/trade/taxon_concept_source_validation_rule_spec.rb b/spec/models/trade/taxon_concept_source_validation_rule_spec.rb index 4eaee047f9..af16dc1b1d 100644 --- a/spec/models/trade/taxon_concept_source_validation_rule_spec.rb +++ b/spec/models/trade/taxon_concept_source_validation_rule_spec.rb @@ -29,7 +29,7 @@ let(:sandbox_klass) { Trade::SandboxTemplate.ar_klass(annual_report_upload.sandbox.table_name) } - describe :validation_errors do + describe :validation_errors_for_aru do context "when species name is from Kingdom Animalia, source_code can't be A" do before do @animal = create_cites_eu_animal_species @@ -40,10 +40,12 @@ create_taxon_concept_source_validation } specify { - subject.validation_errors(annual_report_upload).size.should == 1 + subject.refresh_errors_if_needed(annual_report_upload) + subject.validation_errors_for_aru(annual_report_upload).size.should == 1 } specify { - ve = subject.validation_errors(annual_report_upload).first + subject.refresh_errors_if_needed(annual_report_upload) + ve = subject.validation_errors_for_aru(annual_report_upload).first ve.error_message.should == "taxon_name #{@animal.full_name} with source_code A is invalid" } end @@ -59,7 +61,8 @@ create_taxon_concept_source_validation } specify { - subject.validation_errors(annual_report_upload).size.should == 2 + subject.refresh_errors_if_needed(annual_report_upload) + subject.validation_errors_for_aru(annual_report_upload).size.should == 2 } end end diff --git a/spec/models/trade/validation_rule_spec.rb b/spec/models/trade/validation_rule_spec.rb index b84a6b2a51..b4e87ce2c3 100644 --- a/spec/models/trade/validation_rule_spec.rb +++ b/spec/models/trade/validation_rule_spec.rb @@ -31,7 +31,7 @@ } describe Trade::PresenceValidationRule do - describe :validation_errors do + describe :validation_errors_for_aru do before(:each) do sandbox_klass.create(:trading_partner => nil) end @@ -43,14 +43,15 @@ ) } specify { - subject.validation_errors(annual_report_upload).size.should == 1 + subject.refresh_errors_if_needed(annual_report_upload) + subject.validation_errors_for_aru(annual_report_upload).size.should == 1 } end end end describe Trade::NumericalityValidationRule do - describe :validation_errors do + describe :validation_errors_for_aru do before(:each) do sandbox_klass.create(:quantity => 'www') end @@ -63,14 +64,15 @@ ) } specify { - subject.validation_errors(annual_report_upload).size.should == 1 + subject.refresh_errors_if_needed(annual_report_upload) + subject.validation_errors_for_aru(annual_report_upload).size.should == 1 } end end end describe Trade::FormatValidationRule do - describe :validation_errors do + describe :validation_errors_for_aru do before(:each) do sandbox_klass.create(:year => '33333') end @@ -79,7 +81,8 @@ create_year_format_validation } specify { - subject.validation_errors(annual_report_upload).size.should == 1 + subject.refresh_errors_if_needed(annual_report_upload) + subject.validation_errors_for_aru(annual_report_upload).size.should == 1 } end end diff --git a/spec/support/sapi_helpers.rb b/spec/support/sapi_helpers.rb index c6b94eb41a..51a93c85fd 100644 --- a/spec/support/sapi_helpers.rb +++ b/spec/support/sapi_helpers.rb @@ -355,6 +355,15 @@ def create_year_format_validation ) end + def create_taxon_concept_validation + create( + :inclusion_validation_rule, + column_names: ['taxon_name'], + valid_values_view: 'valid_taxon_name_view', + is_strict: true + ) + end + def create_taxon_concept_appendix_year_validation create(:taxon_concept_appendix_year_validation_rule, :is_primary => false, From 7070100792532e05758079d833340e1c0b7bc2cb Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 11 Jul 2016 11:58:46 +0100 Subject: [PATCH 349/365] fixed controller specs --- .../sandbox_shipments_controller_spec.rb | 34 +++++++++++++------ 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/spec/controllers/trade/sandbox_shipments_controller_spec.rb b/spec/controllers/trade/sandbox_shipments_controller_spec.rb index 1992dff7d7..69d9b46e46 100644 --- a/spec/controllers/trade/sandbox_shipments_controller_spec.rb +++ b/spec/controllers/trade/sandbox_shipments_controller_spec.rb @@ -19,7 +19,17 @@ :taxon_name => create(:taxon_name, :scientific_name => 'baerii'), :parent_id => @genus.id ) - @shipment = sandbox_klass.create(:taxon_name => 'Acipenser baerii') + @shipment = sandbox_klass.create(taxon_name: 'Acipenser baerii', appendix: 'I', year: 2016) + @validation_error = create( + :validation_error, + annual_report_upload_id: annual_report_upload.id, + validation_rule_id: create_taxon_concept_appendix_year_validation.id, + matching_criteria: "{\"taxon_concept_id\": #{@species.id}, \"appendix\": \"I\", \"year\": 2016}", + is_ignored: false, + is_primary: false, + error_message: "taxon_name Acipenser baerii with appendix I with year 2016 is invalid", + error_count: 1 + ) end describe "PUT update" do it "should return success when taxon_name not set" do @@ -49,23 +59,25 @@ describe "POST update_batch" do it "should return success" do - post :update_batch, :annual_report_upload_id => annual_report_upload.id, - :sandbox_shipments_ids => [@shipment.id], - :updates => { :taxon_name => @genus.full_name }, - :format => :json + post :update_batch, + annual_report_upload_id: annual_report_upload.id, + validation_error_id: @validation_error.id, + updates: { appendix: 'II' }, + format: :json response.body.should be_blank - sandbox_klass.where(:taxon_name => @species.full_name).count(true).should == 0 - sandbox_klass.where(:taxon_name => @genus.full_name).count(true).should == 1 + sandbox_klass.where(taxon_name: @species.full_name, appendix: 'I').count(true).should == 0 + sandbox_klass.where(taxon_name: @species.full_name, appendix: 'II').count(true).should == 1 end end describe "POST destroy_batch" do it "should return success" do - post :destroy_batch, :annual_report_upload_id => annual_report_upload.id, - :sandbox_shipments_ids => [@shipment.id], - :format => :json + post :destroy_batch, + annual_report_upload_id: annual_report_upload.id, + validation_error_id: @validation_error.id, + format: :json response.body.should be_blank - sandbox_klass.where(:taxon_concept_id => @species.id).count(true).should == 0 + sandbox_klass.where(taxon_concept_id: @species.id).count(true).should == 0 end end From b19eadd1c0c36f0d72683ca7f7cb3d6f6420ad8c Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 11 Jul 2016 14:46:47 +0100 Subject: [PATCH 350/365] more specs --- .../validation_errors_controller_spec.rb | 51 +++++++++ .../trade/inclusion_validation_rule_spec.rb | 102 ++++++++++++++++++ spec/models/trade/sandbox_filter_spec.rb | 68 ++++++++++++ spec/models/trade/validation_rule_spec.rb | 91 ++++++++++++++++ spec/support/sapi_helpers.rb | 7 ++ 5 files changed, 319 insertions(+) create mode 100644 spec/controllers/trade/validation_errors_controller_spec.rb create mode 100644 spec/models/trade/sandbox_filter_spec.rb diff --git a/spec/controllers/trade/validation_errors_controller_spec.rb b/spec/controllers/trade/validation_errors_controller_spec.rb new file mode 100644 index 0000000000..564c68e9be --- /dev/null +++ b/spec/controllers/trade/validation_errors_controller_spec.rb @@ -0,0 +1,51 @@ +require 'spec_helper' + +describe Trade::ValidationErrorsController do + login_admin + + let(:annual_report_upload){ + aru = build(:annual_report_upload) + aru.save(:validate => false) + aru + } + let(:sandbox_klass){ + Trade::SandboxTemplate.ar_klass(annual_report_upload.sandbox.table_name) + } + let!(:shipment){ + sandbox_klass.create(:taxon_name => 'Caniis lupus') + } + let(:validation_rule){ + create_taxon_concept_validation + } + let!(:validation_error){ + create( + :validation_error, + annual_report_upload_id: annual_report_upload.id, + validation_rule_id: validation_rule.id, + matching_criteria: "{\"taxon_name\": \"Caniis lupus\"}", + is_ignored: false, + is_primary: true, + error_message: "taxon_name Caniis lupus is invalid", + error_count: 1 + ) + } + + describe "PUT update" do + it "should update is_ignored" do + put :update, + id: validation_error.id, + validation_error: { + is_ignored: true + } + expect(validation_error.reload.is_ignored).to be_true + end + end + + describe "GET show" do + it "should return success" do + get :show, id: validation_error.id, format: :json + response.body.should have_json_path('validation_error') + end + end + +end \ No newline at end of file diff --git a/spec/models/trade/inclusion_validation_rule_spec.rb b/spec/models/trade/inclusion_validation_rule_spec.rb index e944dee9de..83305f98cf 100644 --- a/spec/models/trade/inclusion_validation_rule_spec.rb +++ b/spec/models/trade/inclusion_validation_rule_spec.rb @@ -29,6 +29,108 @@ let(:sandbox_klass) { Trade::SandboxTemplate.ar_klass(annual_report_upload.sandbox.table_name) } + let(:canis_lupus){ + create_cites_eu_species( + taxon_name: create(:taxon_name, scientific_name: 'lupus'), + parent: create_cites_eu_genus( + :taxon_name => create(:taxon_name, scientific_name: 'Canis') + ) + ) + } + + describe :matching_records_for_aru_and_error do + let(:validation_rule){ + create_taxon_concept_validation + } + before(:each) do + @shipment1 = sandbox_klass.create( + taxon_name: canis_lupus.full_name + ) + @shipment2 = sandbox_klass.create( + taxon_name: 'Caniis lupus' + ) + @validation_error = create( + :validation_error, + annual_report_upload_id: annual_report_upload.id, + validation_rule_id: validation_rule.id, + matching_criteria: "{\"taxon_name\": \"Caniis lupus\"}", + is_ignored: false, + is_primary: true, + error_message: "taxon_name Caniis lupus is invalid", + error_count: 1 + ) + Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings + validation_rule.refresh_errors_if_needed(annual_report_upload) + end + specify { + expect( + validation_rule.matching_records_for_aru_and_error( + annual_report_upload, + @validation_error + ) + ).to eq([@shipment2]) + } + end + + describe :refresh_errors_if_needed do + let(:validation_rule){ + create_taxon_concept_validation + } + before(:each) do + @shipment1 = sandbox_klass.create( + taxon_name: canis_lupus.full_name + ) + @shipment2 = sandbox_klass.create( + taxon_name: 'Caniis lupus' + ) + @shipment3 = sandbox_klass.create( + taxon_name: 'Caniis lupus' + ) + @validation_error = create( + :validation_error, + annual_report_upload_id: annual_report_upload.id, + validation_rule_id: validation_rule.id, + matching_criteria: "{\"taxon_name\": \"Caniis lupus\"}", + is_ignored: false, + is_primary: true, + error_message: "taxon_name Caniis lupus is invalid", + error_count: 2 + ) + Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings + validation_rule.refresh_errors_if_needed(annual_report_upload) + end + + context "when no updates" do + specify do + expect { + validation_rule.refresh_errors_if_needed(annual_report_upload) + }.not_to change { Trade::ValidationError.count } + end + end + + context "when updates and error fixed for all records" do + specify "error record is destroyed" do + Timecop.travel(Time.now + 1) + @shipment2.update_attributes(taxon_name: 'Canis lupus') + @shipment3.update_attributes(taxon_name: 'Canis lupus') + expect { + validation_rule.refresh_errors_if_needed(annual_report_upload) + }.to change { Trade::ValidationError.count }.by(-1) + end + end + + context "when updates and error fixed for some records" do + specify "error record is updated to reflect new error_count" do + Timecop.travel(Time.now + 1) + @shipment2.update_attributes(taxon_name: 'Canis lupus') + expect { + validation_rule.refresh_errors_if_needed(annual_report_upload) + }.to change { @validation_error.reload.error_count }.by(-1) + end + end + + end + describe :validation_errors_for_aru do context 'species name may have extra whitespace between name segments' do before(:each) do diff --git a/spec/models/trade/sandbox_filter_spec.rb b/spec/models/trade/sandbox_filter_spec.rb new file mode 100644 index 0000000000..e8ae252813 --- /dev/null +++ b/spec/models/trade/sandbox_filter_spec.rb @@ -0,0 +1,68 @@ +require 'spec_helper' +describe Trade::SandboxFilter do + let(:annual_report_upload){ + aru = build(:annual_report_upload) + aru.save(:validate => false) + aru + } + let(:sandbox_klass){ + Trade::SandboxTemplate.ar_klass(annual_report_upload.sandbox.table_name) + } + let(:canis_lupus){ + create_cites_eu_species( + taxon_name: create(:taxon_name, scientific_name: 'lupus'), + parent: create_cites_eu_genus( + taxon_name: create(:taxon_name, scientific_name: 'Canis') + ) + ) + } + let(:validation_rule){ + create_taxon_concept_appendix_year_validation + } + before(:each) do + @shipment1 = sandbox_klass.create( + taxon_name: canis_lupus.full_name, + appendix: 'I', + year: 2016 + ) + @shipment2 = sandbox_klass.create( + taxon_name: canis_lupus.full_name, + appendix: 'III', + year: 2016 + ) + create_cites_I_addition( + taxon_concept: canis_lupus, + effective_at: '2010-06-23', + is_current: true + ) + create_eu_A_addition( + taxon_concept: canis_lupus, + effective_at: '2010-06-23', + is_current: true, + event: reg2013 + ) + Sapi::StoredProcedures.rebuild_cites_taxonomy_and_listings + @validation_error = create( + :validation_error, + annual_report_upload_id: annual_report_upload.id, + validation_rule_id: validation_rule.id, + matching_criteria: "{\"taxon_concept_id\": #{canis_lupus.id}, \"appendix\": \"III\", \"year\": 2016}", + is_ignored: false, + is_primary: false, + error_message: "taxon_name Canis lupus with appendix III with year 2016 is invalid", + error_count: 1 + ) + end + + describe :results do + subject do + Trade::SandboxFilter.new( + annual_report_upload_id: annual_report_upload.id, + validation_error_id: @validation_error.id + ).results + end + specify { expect(subject).to include(@shipment2) } + specify { expect(subject).not_to include(@shipment1) } + end + +end diff --git a/spec/models/trade/validation_rule_spec.rb b/spec/models/trade/validation_rule_spec.rb index b4e87ce2c3..995f4a3a01 100644 --- a/spec/models/trade/validation_rule_spec.rb +++ b/spec/models/trade/validation_rule_spec.rb @@ -30,6 +30,97 @@ Trade::SandboxTemplate.ar_klass(annual_report_upload.sandbox.table_name) } + describe :matching_records_for_aru_and_error do + let(:validation_rule){ + create_taxon_name_presence_validation + } + before(:each) do + @shipment1 = sandbox_klass.create( + taxon_name: 'Canis lupus' + ) + @shipment2 = sandbox_klass.create( + taxon_name: nil + ) + @validation_error = create( + :validation_error, + annual_report_upload_id: annual_report_upload.id, + validation_rule_id: validation_rule.id, + matching_criteria: "{}", + is_ignored: false, + is_primary: true, + error_message: "taxon_name cannot be blank", + error_count: 1 + ) + validation_rule.refresh_errors_if_needed(annual_report_upload) + end + specify { + expect( + validation_rule.matching_records_for_aru_and_error( + annual_report_upload, + @validation_error + ) + ).to eq([@shipment2]) + } + end + + describe :refresh_errors_if_needed do + let(:validation_rule){ + create_taxon_name_presence_validation + } + before(:each) do + @shipment1 = sandbox_klass.create( + taxon_name: 'Canis lupus' + ) + @shipment2 = sandbox_klass.create( + taxon_name: '' + ) + @shipment3 = sandbox_klass.create( + taxon_name: nil + ) + @validation_error = create( + :validation_error, + annual_report_upload_id: annual_report_upload.id, + validation_rule_id: validation_rule.id, + matching_criteria: "{}", + is_ignored: false, + is_primary: true, + error_message: "taxon_name cannot be blank", + error_count: 2 + ) + validation_rule.refresh_errors_if_needed(annual_report_upload) + end + + context "when no updates" do + specify do + expect { + validation_rule.refresh_errors_if_needed(annual_report_upload) + }.not_to change { Trade::ValidationError.count } + end + end + + context "when updates and error fixed for all records" do + specify "error record is destroyed" do + Timecop.travel(Time.now + 1) + @shipment2.update_attributes(taxon_name: 'Canis lupus') + @shipment3.update_attributes(taxon_name: 'Canis lupus') + expect { + validation_rule.refresh_errors_if_needed(annual_report_upload) + }.to change { Trade::ValidationError.count }.by(-1) + end + end + + context "when updates and error fixed for some records" do + specify "error record is updated to reflect new error_count" do + Timecop.travel(Time.now + 1) + @shipment2.update_attributes(taxon_name: 'Canis lupus') + expect { + validation_rule.refresh_errors_if_needed(annual_report_upload) + }.to change { @validation_error.reload.error_count }.by(-1) + end + end + + end + describe Trade::PresenceValidationRule do describe :validation_errors_for_aru do before(:each) do diff --git a/spec/support/sapi_helpers.rb b/spec/support/sapi_helpers.rb index 51a93c85fd..7c3d4f3554 100644 --- a/spec/support/sapi_helpers.rb +++ b/spec/support/sapi_helpers.rb @@ -346,6 +346,13 @@ def create_cites_eu_plant_species(options = {}) end end + def create_taxon_name_presence_validation + create( + :presence_validation_rule, + :column_names => ['taxon_name'] + ) + end + def create_year_format_validation create( :format_validation_rule, From 68a8b6dc4c6f503243cfba2c578d0e22188c0856 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 11 Jul 2016 15:32:15 +0100 Subject: [PATCH 351/365] remove double loading of annual report when refreshing page with errors --- .../controllers/annual_report_uploads_controller.js.coffee | 4 ++++ .../trade/routes/annual_report_upload_route.js.coffee | 3 --- .../trade/templates/annual_report_uploads.handlebars | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/assets/javascripts/trade/controllers/annual_report_uploads_controller.js.coffee b/app/assets/javascripts/trade/controllers/annual_report_uploads_controller.js.coffee index 4db8ef8de2..afe2a21ea3 100644 --- a/app/assets/javascripts/trade/controllers/annual_report_uploads_controller.js.coffee +++ b/app/assets/javascripts/trade/controllers/annual_report_uploads_controller.js.coffee @@ -12,6 +12,10 @@ Trade.AnnualReportUploadsController = Ember.ArrayController.extend aru.get('transaction').commit() actions: + transitionToReportUploadFromList: (aru)-> + aru.reload() + @transitionToRoute('annual_report_upload', aru) + transitionToReportUpload: (aru)-> @transitionToRoute('annual_report_upload', aru) diff --git a/app/assets/javascripts/trade/routes/annual_report_upload_route.js.coffee b/app/assets/javascripts/trade/routes/annual_report_upload_route.js.coffee index 438aece570..ecf74d6f68 100644 --- a/app/assets/javascripts/trade/routes/annual_report_upload_route.js.coffee +++ b/app/assets/javascripts/trade/routes/annual_report_upload_route.js.coffee @@ -7,9 +7,6 @@ Trade.AnnualReportUploadRoute = Trade.BeforeRoute.extend @controllerFor('purposes').set('content', Trade.Purpose.find()) Trade.AnnualReportUpload.find(params.annual_report_upload_id) - afterModel: (aru, transition) -> - aru.reload() - setupController: (controller, model) -> controller.set('model', model) controller.set('currentError', null) diff --git a/app/assets/javascripts/trade/templates/annual_report_uploads.handlebars b/app/assets/javascripts/trade/templates/annual_report_uploads.handlebars index 592f10e503..1f6dd5b079 100644 --- a/app/assets/javascripts/trade/templates/annual_report_uploads.handlebars +++ b/app/assets/javascripts/trade/templates/annual_report_uploads.handlebars @@ -13,9 +13,9 @@
- <%= link_to admin_nomenclature_change_new_name_index_path( - :nomenclature_change_id => :new), - :method => :post do - %> - - <% end %> - Create a new name
Create a new name and turn the old name into a synonymChange name status to accepted (e.g. N -> A, S -> A, T -> A)Change name status to accepted (e.g. N -> A, T -> A)
diff --git a/app/views/admin/nomenclature_changes/status_to_accepted/primary_output.html.erb b/app/views/admin/nomenclature_changes/status_to_accepted/primary_output.html.erb index 8124ffa488..4213cf0342 100644 --- a/app/views/admin/nomenclature_changes/status_to_accepted/primary_output.html.erb +++ b/app/views/admin/nomenclature_changes/status_to_accepted/primary_output.html.erb @@ -2,17 +2,16 @@ <%= nomenclature_change_form do |f| %> <%= render 'admin/nomenclature_changes/build/event_selector', :f => f %> <%= f.fields_for :primary_output do |ff| %> -
- -
- <%= ff.text_field :taxon_concept_id, { - :class => 'taxon-concept status-change', - :'data-name' => ff.object.taxon_concept.try(:full_name), - :'data-name-status' => ff.object.taxon_concept.try(:name_status), - :'data-name-status-filter' => ['N', 'S', 'T'].to_json, - :'data-taxonomy-id' => @taxonomy.id - } %> -
+
+ +
+ <%= ff.text_field :taxon_concept_id, { + :class => 'taxon-concept status-change', + :'data-name' => ff.object.taxon_concept.try(:full_name), + :'data-name-status' => ff.object.taxon_concept.try(:name_status), + :'data-name-status-filter' => ['N', 'T'].to_json, + :'data-taxonomy-id' => @taxonomy.id + } %>
<%= render 'admin/nomenclature_changes/build/new_parent', :ff => ff %> <% end %> From 973929e59dcc9becf2c09960881046f7ffdc46f8 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 15 Mar 2016 12:59:53 +0000 Subject: [PATCH 116/365] amended model and specs to reflect removal of S -> A scenario --- .../nomenclature_change/status_to_accepted.rb | 2 +- .../status_to_accepted_controller_spec.rb | 2 +- .../admin/nomenclature_changes_helper_spec.rb | 2 +- .../shared/status_change_definitions.rb | 21 ++++++---- .../status_to_accepted/processor_spec.rb | 42 +------------------ 5 files changed, 18 insertions(+), 51 deletions(-) diff --git a/app/models/nomenclature_change/status_to_accepted.rb b/app/models/nomenclature_change/status_to_accepted.rb index 9f6c45e30b..e24dbef09e 100644 --- a/app/models/nomenclature_change/status_to_accepted.rb +++ b/app/models/nomenclature_change/status_to_accepted.rb @@ -50,7 +50,7 @@ def needs_to_relay_associations? end def needs_to_set_parent? - ['S', 'T'].include? primary_output.try(:name_status) + primary_output.try(:name_status) == 'T' end end diff --git a/spec/controllers/admin/nomenclature_changes/status_to_accepted_controller_spec.rb b/spec/controllers/admin/nomenclature_changes/status_to_accepted_controller_spec.rb index eaee5a3eac..1f6f47c26b 100644 --- a/spec/controllers/admin/nomenclature_changes/status_to_accepted_controller_spec.rb +++ b/spec/controllers/admin/nomenclature_changes/status_to_accepted_controller_spec.rb @@ -16,7 +16,7 @@ end context :summary do before(:each) do - @status_change = s_to_a_with_input + @status_change = t_to_a_with_input end it 'renders the summary template' do get :show, id: :summary, nomenclature_change_id: @status_change.id diff --git a/spec/helpers/admin/nomenclature_changes_helper_spec.rb b/spec/helpers/admin/nomenclature_changes_helper_spec.rb index 1d1dcc6c0e..06ec9dbc49 100644 --- a/spec/helpers/admin/nomenclature_changes_helper_spec.rb +++ b/spec/helpers/admin/nomenclature_changes_helper_spec.rb @@ -44,7 +44,7 @@ describe :status_change_blurb do include_context 'status_change_definitions' context "status upgrade with primary output" do - before(:each) { @nomenclature_change = s_to_a_with_primary_output } + before(:each) { @nomenclature_change = t_to_a_with_primary_output } specify{ expect(helper.status_change_blurb).to match(@nomenclature_change.primary_output.taxon_concept.full_name) } end context "status upgrade with swap" do diff --git a/spec/models/nomenclature_change/shared/status_change_definitions.rb b/spec/models/nomenclature_change/shared/status_change_definitions.rb index 42e31041a6..6c6c88abc5 100644 --- a/spec/models/nomenclature_change/shared/status_change_definitions.rb +++ b/spec/models/nomenclature_change/shared/status_change_definitions.rb @@ -2,7 +2,9 @@ let(:input_species){ create_cites_eu_species } let(:accepted_name){ create_cites_eu_species } let(:input_trade_name){ - tc = create_cites_eu_species(name_status: 'T') + tc = create_cites_eu_species(name_status: 'T', + taxon_name: create(:taxon_name, scientific_name: 'Ridiculus fatalus') + ) create(:taxon_relationship, taxon_concept: accepted_name, other_taxon_concept: tc, @@ -10,6 +12,11 @@ ) tc } + let(:input_trade_name_genus){ + create_cites_eu_genus( + taxon_name: create(:taxon_name, scientific_name: 'Ridiculus') + ) + } let(:input_synonym){ tc = create_cites_eu_species(name_status: 'S', taxon_name: create(:taxon_name, scientific_name: 'Confundus totalus') @@ -36,13 +43,13 @@ status: NomenclatureChange::StatusToSynonym::PRIMARY_OUTPUT ).reload } - let(:s_to_a_with_primary_output){ + let(:t_to_a_with_primary_output){ create(:nomenclature_change_status_to_accepted, primary_output_attributes: { is_primary_output: true, - taxon_concept_id: input_synonym.id, + taxon_concept_id: input_trade_name.id, new_name_status: 'A', - new_parent_id: input_synonym_genus.id + new_parent_id: input_trade_name_genus.id }, status: NomenclatureChange::StatusToAccepted::PRIMARY_OUTPUT ).reload @@ -103,13 +110,13 @@ status: NomenclatureChange::StatusSwap::SWAP ).reload } - let(:s_to_a_with_input){ + let(:t_to_a_with_input){ create(:nomenclature_change_status_to_accepted, primary_output_attributes: { is_primary_output: true, - taxon_concept_id: input_synonym.id, + taxon_concept_id: input_trade_name.id, new_name_status: 'A', - new_parent_id: input_synonym_genus.id + new_parent_id: input_trade_name_genus.id }, status: NomenclatureChange::StatusToAccepted::PRIMARY_OUTPUT ).reload diff --git a/spec/models/nomenclature_change/status_to_accepted/processor_spec.rb b/spec/models/nomenclature_change/status_to_accepted/processor_spec.rb index 7dfafaa742..41a2f9c3df 100644 --- a/spec/models/nomenclature_change/status_to_accepted/processor_spec.rb +++ b/spec/models/nomenclature_change/status_to_accepted/processor_spec.rb @@ -45,49 +45,9 @@ let(:secondary_output_taxon_concept){ status_change.secondary_output.taxon_concept } describe :run do - context "from synonym" do - let(:output_species){ secondary_output_taxon_concept } - let(:s_to_a_with_input){ - create(:nomenclature_change_status_to_accepted, - primary_output_attributes: { - is_primary_output: true, - taxon_concept_id: synonym.id, - new_name_status: 'A', - new_parent_id: synonym_genus.id - }, - input_attributes: { taxon_concept_id: input_species.id }, - status: NomenclatureChange::StatusToAccepted::PRIMARY_OUTPUT - ).reload - } - let(:status_change){ s_to_a_with_input } - before(:each){ - @shipment = create(:shipment, - taxon_concept: accepted_name, - reported_taxon_concept: primary_output_taxon_concept - ) - processor.run - } - specify{ expect(primary_output_taxon_concept.name_status).to eq('A') } - specify{ expect(primary_output_taxon_concept.accepted_names).to be_empty } - specify{ expect(primary_output_taxon_concept.shipments).to include(@shipment) } - specify{ expect(primary_output_taxon_concept.reported_shipments).to include(@shipment) } - specify{ expect(accepted_name.shipments).to be_empty } - end context "from trade name" do let(:output_species){ secondary_output_taxon_concept } - let(:s_to_a_with_input){ - create(:nomenclature_change_status_to_accepted, - primary_output_attributes: { - is_primary_output: true, - taxon_concept_id: trade_name.id, - new_name_status: 'A', - new_parent_id: trade_name_genus.id - }, - input_attributes: { taxon_concept_id: input_species.id }, - status: NomenclatureChange::StatusToAccepted::PRIMARY_OUTPUT - ).reload - } - let(:status_change){ s_to_a_with_input } + let(:status_change){ t_to_a_with_input } before(:each){ @shipment = create(:shipment, taxon_concept: accepted_name, From 78db024e7d382851a3c58b43ad6065ffc0b6bd46 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 15 Mar 2016 13:09:23 +0000 Subject: [PATCH 117/365] added spec for primary output name status validation --- .../nomenclature_change/status_to_accepted.rb | 9 +++ .../status_to_accepted_spec.rb | 68 +++++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 spec/models/nomenclature_change/status_to_accepted_spec.rb diff --git a/app/models/nomenclature_change/status_to_accepted.rb b/app/models/nomenclature_change/status_to_accepted.rb index e24dbef09e..88e3ee3b77 100644 --- a/app/models/nomenclature_change/status_to_accepted.rb +++ b/app/models/nomenclature_change/status_to_accepted.rb @@ -22,10 +22,19 @@ class NomenclatureChange::StatusToAccepted < NomenclatureChange in: self.status_dict, message: "%{value} is not a valid status" } + validate :required_primary_output_name_status, if: :primary_output_or_submitting? before_validation :set_output_name_status, if: :primary_output_or_submitting? before_validation :set_output_rank_id, if: :primary_output_or_submitting? before_validation :set_output_parent_id, if: :primary_output_or_submitting? + def required_primary_output_name_status + if primary_output && !['N', 'T'].include?(primary_output.name_status) + errors.add(:primary_output, "Must be N or T taxon") + return false + end + true + end + def set_output_name_status primary_output && primary_output.new_name_status = 'A' end diff --git a/spec/models/nomenclature_change/status_to_accepted_spec.rb b/spec/models/nomenclature_change/status_to_accepted_spec.rb new file mode 100644 index 0000000000..daeb467759 --- /dev/null +++ b/spec/models/nomenclature_change/status_to_accepted_spec.rb @@ -0,0 +1,68 @@ +# == Schema Information +# +# Table name: nomenclature_changes +# +# id :integer not null, primary key +# event_id :integer +# type :string(255) not null +# status :string(255) not null +# created_by_id :integer not null +# updated_by_id :integer not null +# created_at :datetime not null +# updated_at :datetime not null +# + +require 'spec_helper' + +describe NomenclatureChange::StatusToAccepted do + describe :validate do + context "when required primary output missing" do + context "when primary_output" do + let(:status_change){ + build( + :nomenclature_change_status_to_accepted, + status: NomenclatureChange::StatusToAccepted::PRIMARY_OUTPUT + ) + } + specify { expect(status_change).to have(1).error_on(:primary_output) } + end + context "when submitting" do + let(:status_change){ + build( + :nomenclature_change_status_to_accepted, + status: NomenclatureChange::StatusToAccepted::SUBMITTED + ) + } + specify { expect(status_change).to have(1).error_on(:primary_output) } + end + end + context "when primary output has invalid name status" do + context "when primary_output" do + let(:status_change){ + build( + :nomenclature_change_status_to_accepted, + :primary_output_attributes => { + taxon_concept_id: create_cites_eu_species(name_status: 'S').id + }, + status: NomenclatureChange::StatusToAccepted::PRIMARY_OUTPUT + ) + } + specify { expect(status_change).to have(1).error_on(:primary_output) } + end + end + context "when primary output has valid name status" do + context "when primary_output" do + let(:status_change){ + build( + :nomenclature_change_status_to_accepted, + :primary_output_attributes => { + taxon_concept_id: create_cites_eu_species(name_status: 'T').id + }, + status: NomenclatureChange::StatusToAccepted::PRIMARY_OUTPUT + ) + } + specify { expect(status_change).to have(0).errors_on(:primary_output) } + end + end + end +end From 9b5496433e80e5bd96512dd344de5778d1a932c7 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 15 Mar 2016 13:20:07 +0000 Subject: [PATCH 118/365] fixed broken controller spec --- .../status_to_accepted_controller_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/controllers/admin/nomenclature_changes/status_to_accepted_controller_spec.rb b/spec/controllers/admin/nomenclature_changes/status_to_accepted_controller_spec.rb index 1f6f47c26b..2551fdc591 100644 --- a/spec/controllers/admin/nomenclature_changes/status_to_accepted_controller_spec.rb +++ b/spec/controllers/admin/nomenclature_changes/status_to_accepted_controller_spec.rb @@ -42,8 +42,8 @@ it 'redirects to next step' do put :update, nomenclature_change_status_to_accepted: { primary_output_attributes: { - taxon_concept_id: create_cites_eu_species.id, - new_name_status: 'S' + taxon_concept_id: create_cites_eu_species(name_status: 'N').id, + new_name_status: 'A' } }, nomenclature_change_id: @status_change.id, id: 'primary_output' response.should redirect_to(admin_nomenclature_change_status_to_accepted_url( From d0dd55e5c46662d445167050dd69877bb91deff9 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 18 Mar 2016 17:58:15 +0000 Subject: [PATCH 119/365] fixed spec that was missing mandatory parent id --- .../status_to_accepted_controller_spec.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/spec/controllers/admin/nomenclature_changes/status_to_accepted_controller_spec.rb b/spec/controllers/admin/nomenclature_changes/status_to_accepted_controller_spec.rb index 2551fdc591..51495d9f69 100644 --- a/spec/controllers/admin/nomenclature_changes/status_to_accepted_controller_spec.rb +++ b/spec/controllers/admin/nomenclature_changes/status_to_accepted_controller_spec.rb @@ -42,7 +42,13 @@ it 'redirects to next step' do put :update, nomenclature_change_status_to_accepted: { primary_output_attributes: { - taxon_concept_id: create_cites_eu_species(name_status: 'N').id, + taxon_concept_id: create_cites_eu_species( + name_status: 'N', + taxon_name: create(:taxon_name, scientific_name: 'Patagonus miserabilis') + ).id, + new_parent_id: create_cites_eu_genus( + taxon_name: create(:taxon_name, scientific_name: 'Patagonus') + ).id, new_name_status: 'A' } }, nomenclature_change_id: @status_change.id, id: 'primary_output' From 3465872d67cfa69b6b7234133940649da990855c Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Mon, 21 Mar 2016 10:58:15 +0000 Subject: [PATCH 120/365] Fix inputs initialiser out of scope --- .../javascripts/admin/admin_in_place_editor.js.coffee | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/app/assets/javascripts/admin/admin_in_place_editor.js.coffee b/app/assets/javascripts/admin/admin_in_place_editor.js.coffee index 4b587a8361..3cc5c08988 100644 --- a/app/assets/javascripts/admin/admin_in_place_editor.js.coffee +++ b/app/assets/javascripts/admin/admin_in_place_editor.js.coffee @@ -148,6 +148,12 @@ class AdminEditor } }) + initSelect2Inputs: () -> + $('.taxon-concept').select2(window.defaultTaxonSelect2Options) + $('.taxon-concept-multiple').select2($.extend({}, window.defaultTaxonSelect2Options,window.multiTaxonSelect2Options)) + $('.hybrids-selection').select2($.extend({}, window.defaultTaxonSelect2Options, window.multiTaxonSelect2Options, window.hybridsSelect2Options)) + + class AdminInPlaceEditor extends AdminEditor init: () -> super @@ -196,11 +202,6 @@ class AdminInPlaceEditor extends AdminEditor 'option', 'emptytext', 'not current' ) - initSelect2Inputs: () -> - $('.taxon-concept').select2(window.defaultTaxonSelect2Options) - $('.taxon-concept-multiple').select2($.extend({}, window.defaultTaxonSelect2Options,window.multiTaxonSelect2Options)) - $('.hybrids-selection').select2($.extend({}, window.defaultTaxonSelect2Options, window.multiTaxonSelect2Options, window.hybridsSelect2Options)) - class TaxonConceptsEditor extends AdminEditor init: () -> super From 4862e6de4490f0194d996511a46e05a0087f7348 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Mon, 21 Mar 2016 17:32:40 +0000 Subject: [PATCH 121/365] Add e.g. label to new taxon name --- .../javascripts/admin/nomenclature_changes.js.coffee | 9 +++++++++ .../admin/nomenclature_changes/lump/outputs.html.erb | 1 + 2 files changed, 10 insertions(+) diff --git a/app/assets/javascripts/admin/nomenclature_changes.js.coffee b/app/assets/javascripts/admin/nomenclature_changes.js.coffee index 84f24fa4a2..f1ea0bfc1c 100644 --- a/app/assets/javascripts/admin/nomenclature_changes.js.coffee +++ b/app/assets/javascripts/admin/nomenclature_changes.js.coffee @@ -154,17 +154,26 @@ $(document).ready -> upgrade_info.find('input').prop("value", '') $(obj).closest('.fields').find('.parent-taxon').select2('data',null) + ShowEgLabel = (obj) -> + $(obj).closest('.fields').find('.new-scientific-name-eg').show() + + HideEgLabel = (obj) -> + $(obj).closest('.fields').find('.new-scientific-name-eg').hide() + NewTaxonForm = (obj) -> HideInputTaxon(obj) ShowUpgradeInfo(obj) + ShowEgLabel(obj) ExistingTaxonForm = (obj) -> ShowInputTaxon(obj) HideUpgradeInfo(obj) + HideEgLabel(obj) UpgradedTaxonForm = (obj) -> ShowInputTaxon(obj) ShowUpgradeInfo(obj) + HideEgLabel(obj) DefaultExistingTaxon = (obj) -> $(obj).find('.output-radio[value="existing_taxon"]').attr("checked","checked") diff --git a/app/views/admin/nomenclature_changes/lump/outputs.html.erb b/app/views/admin/nomenclature_changes/lump/outputs.html.erb index 086f44f9fc..6b013d4838 100644 --- a/app/views/admin/nomenclature_changes/lump/outputs.html.erb +++ b/app/views/admin/nomenclature_changes/lump/outputs.html.erb @@ -34,6 +34,7 @@ <%= ff.text_field :new_scientific_name, { :class => 'new-scientific-name' } %> +
From 7449dcf682692d8cdf854d0b0c2ff4815a832317 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Fri, 18 Mar 2016 15:49:05 +0000 Subject: [PATCH 122/365] Loose lump validation to lump across different ranks --- app/models/nomenclature_change/lump.rb | 28 ++------------------------ 1 file changed, 2 insertions(+), 26 deletions(-) diff --git a/app/models/nomenclature_change/lump.rb b/app/models/nomenclature_change/lump.rb index 3e472d71c0..37aaf8c8d4 100644 --- a/app/models/nomenclature_change/lump.rb +++ b/app/models/nomenclature_change/lump.rb @@ -31,13 +31,7 @@ class NomenclatureChange::Lump < NomenclatureChange message: "%{value} is not a valid status" } validate :required_inputs, if: :inputs_or_submitting? - validate :required_inputs_ranks, if: Proc.new{ |nc| - !nc.inputs.empty? && nc.inputs_or_submitting? - } validate :required_outputs, if: :outputs_or_submitting? - validate :required_ranks, if: Proc.new{ |nc| - nc.output && nc.outputs_or_submitting? - } before_validation :set_output_name_status, if: Proc.new{ |nc| !nc.inputs.empty? && nc.output && nc.outputs_or_submitting? } @@ -63,13 +57,6 @@ def required_inputs end end - def required_inputs_ranks - if inputs.map{ |i| i.taxon_concept.try(:rank_id) }.uniq.size > 1 - errors.add(:inputs, "must be of same rank") - return false - end - end - def required_outputs unless output errors.add(:output, "Must have one output") @@ -77,17 +64,6 @@ def required_outputs end end - def required_ranks - if inputs.first.try(:taxon_concept).try(:rank_id) != ( - output.will_create_taxon? ? - output.new_rank_id : - output.try(:taxon_concept).try(:rank_id) - ) - errors.add(:output, "must be at same rank as inputs") - return false - end - end - def required_different_name if output.taxon_name_already_existing? && !output.new_full_name.nil? errors.add(:output, "Name already existing") @@ -107,9 +83,9 @@ def set_output_name_status def set_output_rank_id if output.new_rank_id.blank? && ( output.new_scientific_name.present? || - output.taxon_concept && output.taxon_concept.rank_id != new_output_rank.id + output.taxon_concept ) - output.new_rank_id = new_output_rank.id + output.new_rank_id = output.taxon_concept.rank_id end end From a1643ee1e5cd582934f96328579e4135ffb32000 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Fri, 18 Mar 2016 16:55:11 +0000 Subject: [PATCH 123/365] Get child rank name properly --- app/models/nomenclature_change/lump.rb | 12 +++++++----- app/models/rank.rb | 9 +++++++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/app/models/nomenclature_change/lump.rb b/app/models/nomenclature_change/lump.rb index 37aaf8c8d4..4488891a84 100644 --- a/app/models/nomenclature_change/lump.rb +++ b/app/models/nomenclature_change/lump.rb @@ -81,11 +81,13 @@ def set_output_name_status end def set_output_rank_id - if output.new_rank_id.blank? && ( - output.new_scientific_name.present? || - output.taxon_concept - ) - output.new_rank_id = output.taxon_concept.rank_id + if output.new_rank_id.blank? + if output.new_scientific_name.present? && output.new_parent_id.present? + child_rank = output.new_parent.rank.child_rank_name + output.new_rank_id = Rank.find_by_name(child_rank).id + elsif output.taxon_concept + output.new_rank_id = output.taxon_concept.rank_id + end end end diff --git a/app/models/rank.rb b/app/models/rank.rb index b9d08ff166..93158c2084 100644 --- a/app/models/rank.rb +++ b/app/models/rank.rb @@ -59,6 +59,15 @@ def parent_rank_name end end + def child_rank_name + if name != Rank::VARIETY + rank_index = self.class.dict.index(name) + self.class.dict[rank_index+1] + else + nil + end + end + private def dependent_objects_map From 335e4843d929c9cc57b995b5ae45e81fa69dd209 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Fri, 18 Mar 2016 16:55:31 +0000 Subject: [PATCH 124/365] Remove unnecessary test for different ranks --- spec/models/nomenclature_change/lump_spec.rb | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/spec/models/nomenclature_change/lump_spec.rb b/spec/models/nomenclature_change/lump_spec.rb index 7450cf19af..4b5a2a6f11 100644 --- a/spec/models/nomenclature_change/lump_spec.rb +++ b/spec/models/nomenclature_change/lump_spec.rb @@ -61,21 +61,5 @@ specify { expect(lump).to have(1).errors_on(:inputs) } end end - context "when output has different rank than inputs" do - let(:lump){ - build(:nomenclature_change_lump, - :status => NomenclatureChange::Lump::OUTPUTS, - :inputs_attributes => { - 0 => {:taxon_concept_id => create_cites_eu_subspecies.id}, - 1 => {:taxon_concept_id => create_cites_eu_subspecies.id} - }, - :output_attributes => { - :taxon_concept_id => create_cites_eu_species.id, - :new_rank_id => create(:rank, name: Rank::SPECIES).id - } - ) - } - specify { expect(lump).to have(1).errors_on(:output) } - end end end From f0237115c8e64988e88d0cf39ec98df8d524fb12 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Mon, 21 Mar 2016 16:05:18 +0000 Subject: [PATCH 125/365] Set ranks and add rank dropdown to output step --- .../admin/nomenclature_changes/lump_controller.rb | 7 +++++++ .../admin/nomenclature_changes/lump/outputs.html.erb | 9 +++++++++ 2 files changed, 16 insertions(+) diff --git a/app/controllers/admin/nomenclature_changes/lump_controller.rb b/app/controllers/admin/nomenclature_changes/lump_controller.rb index 84df1a5173..4e2d140284 100644 --- a/app/controllers/admin/nomenclature_changes/lump_controller.rb +++ b/app/controllers/admin/nomenclature_changes/lump_controller.rb @@ -11,6 +11,7 @@ def show builder.build_inputs when :outputs set_taxonomy + set_ranks builder.build_output when :notes builder.build_input_and_output_notes @@ -39,10 +40,12 @@ def update unless success set_events set_taxonomy + set_ranks end when :outputs unless success set_taxonomy + set_ranks end end render_wizard @nomenclature_change @@ -53,4 +56,8 @@ def klass NomenclatureChange::Lump end + def set_ranks + @ranks = Rank.order(:taxonomic_position) + end + end diff --git a/app/views/admin/nomenclature_changes/lump/outputs.html.erb b/app/views/admin/nomenclature_changes/lump/outputs.html.erb index 6b013d4838..e6175eb074 100644 --- a/app/views/admin/nomenclature_changes/lump/outputs.html.erb +++ b/app/views/admin/nomenclature_changes/lump/outputs.html.erb @@ -14,6 +14,15 @@ <%= outputs_selection ff %> +
+ +
+ <%= ff.select :new_rank_id, + options_from_collection_for_select(@ranks, :id, :name), + { class: 'new-rank' } + %> +
+
From ad9a33953334c45102d6eeeb519318be14b9878a Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Mon, 21 Mar 2016 16:05:42 +0000 Subject: [PATCH 126/365] Remove unecessary code for getting the rank --- app/models/nomenclature_change/lump.rb | 18 ------------------ app/models/rank.rb | 9 --------- 2 files changed, 27 deletions(-) diff --git a/app/models/nomenclature_change/lump.rb b/app/models/nomenclature_change/lump.rb index 4488891a84..4da4bd1f5d 100644 --- a/app/models/nomenclature_change/lump.rb +++ b/app/models/nomenclature_change/lump.rb @@ -35,9 +35,6 @@ class NomenclatureChange::Lump < NomenclatureChange before_validation :set_output_name_status, if: Proc.new{ |nc| !nc.inputs.empty? && nc.output && nc.outputs_or_submitting? } - before_validation :set_output_rank_id, if: Proc.new{ |nc| - !nc.inputs.empty? && nc.output && nc.outputs_or_submitting? - } before_save :build_auto_reassignments, if: :notes? def build_auto_reassignments @@ -80,17 +77,6 @@ def set_output_name_status end end - def set_output_rank_id - if output.new_rank_id.blank? - if output.new_scientific_name.present? && output.new_parent_id.present? - child_rank = output.new_parent.rank.child_rank_name - output.new_rank_id = Rank.find_by_name(child_rank).id - elsif output.taxon_concept - output.new_rank_id = output.taxon_concept.rank_id - end - end - end - def inputs_except_outputs inputs.reject{ |i| i.taxon_concept == output.try(:taxon_concept) } end @@ -99,10 +85,6 @@ def inputs_intersect_outputs inputs.select{ |o| o.taxon_concept == output.try(:taxon_concept) } end - def new_output_rank - inputs.first.taxon_concept.rank - end - def new_output_parent inputs.first.taxon_concept.parent end diff --git a/app/models/rank.rb b/app/models/rank.rb index 93158c2084..b9d08ff166 100644 --- a/app/models/rank.rb +++ b/app/models/rank.rb @@ -59,15 +59,6 @@ def parent_rank_name end end - def child_rank_name - if name != Rank::VARIETY - rank_index = self.class.dict.index(name) - self.class.dict[rank_index+1] - else - nil - end - end - private def dependent_objects_map From 68fd4f6cdf5cdb62e1f716c50cd6191b74bec6ef Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Mon, 21 Mar 2016 17:18:06 +0000 Subject: [PATCH 127/365] Fix broken tests --- .../nomenclature_change/shared/lump_definitions.rb | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/spec/models/nomenclature_change/shared/lump_definitions.rb b/spec/models/nomenclature_change/shared/lump_definitions.rb index b0492f0ef9..d36f08e6f2 100644 --- a/spec/models/nomenclature_change/shared/lump_definitions.rb +++ b/spec/models/nomenclature_change/shared/lump_definitions.rb @@ -33,7 +33,10 @@ 0 => { taxon_concept_id: input_species1.id }, 1 => { taxon_concept_id: input_species2.id } }, - output_attributes: { taxon_concept_id: input_species1.id }, + output_attributes: { + new_rank_id: input_species1.rank_id, + taxon_concept_id: input_species1.id + }, status: NomenclatureChange::Lump::OUTPUTS ) } @@ -43,7 +46,10 @@ 0 => { taxon_concept_id: input_species1.id }, 1 => { taxon_concept_id: input_species2.id } }, - output_attributes: { taxon_concept_id: output_species.id }, + output_attributes: { + new_rank_id: output_species.rank_id, + taxon_concept_id: output_species.id + }, status: NomenclatureChange::Lump::OUTPUTS ) } @@ -54,6 +60,7 @@ 1 => { taxon_concept_id: input_species2.id } }, output_attributes: { + new_rank_id: output_species.rank_id, new_scientific_name: 'fatalus', new_parent_id: errorus_genus.id }, @@ -67,6 +74,7 @@ 1 => { taxon_concept_id: input_species2.id } }, output_attributes: { + new_rank_id: output_species.rank_id, taxon_concept_id: output_species.id }, status: NomenclatureChange::Lump::OUTPUTS @@ -79,6 +87,7 @@ 1 => { taxon_concept_id: input_species2.id } }, output_attributes: { + new_rank_id: output_species.rank_id, taxon_concept_id: output_subspecies.id, new_scientific_name: 'lolcatus', new_parent_id: errorus_genus.id From 9ce42bc837469ea6b520f578847cf58cc47d3d3f Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 21 Mar 2016 21:34:40 +0000 Subject: [PATCH 128/365] moved rank selector below and provided a default selection --- app/models/nomenclature_change/lump.rb | 4 ++++ .../nomenclature_changes/lump/outputs.html.erb | 18 +++++++++--------- spec/models/nomenclature_change/lump_spec.rb | 13 +++++++++++++ .../shared/lump_definitions.rb | 5 +---- 4 files changed, 27 insertions(+), 13 deletions(-) diff --git a/app/models/nomenclature_change/lump.rb b/app/models/nomenclature_change/lump.rb index 4da4bd1f5d..ac42ac1c2a 100644 --- a/app/models/nomenclature_change/lump.rb +++ b/app/models/nomenclature_change/lump.rb @@ -85,6 +85,10 @@ def inputs_intersect_outputs inputs.select{ |o| o.taxon_concept == output.try(:taxon_concept) } end + def new_output_rank + inputs.first.taxon_concept.rank + end + def new_output_parent inputs.first.taxon_concept.parent end diff --git a/app/views/admin/nomenclature_changes/lump/outputs.html.erb b/app/views/admin/nomenclature_changes/lump/outputs.html.erb index e6175eb074..1bda2e6994 100644 --- a/app/views/admin/nomenclature_changes/lump/outputs.html.erb +++ b/app/views/admin/nomenclature_changes/lump/outputs.html.erb @@ -14,15 +14,6 @@ <%= outputs_selection ff %> -
- -
- <%= ff.select :new_rank_id, - options_from_collection_for_select(@ranks, :id, :name), - { class: 'new-rank' } - %> -
-
@@ -55,5 +46,14 @@
+
+ +
+ <%= ff.select :new_rank_id, + options_from_collection_for_select(@ranks, :id, :name, ff.object.new_rank_id || f.object.new_output_rank.id), + { class: 'new-rank' } + %> +
+
<% end %> <% end %> diff --git a/spec/models/nomenclature_change/lump_spec.rb b/spec/models/nomenclature_change/lump_spec.rb index 4b5a2a6f11..098995b6d6 100644 --- a/spec/models/nomenclature_change/lump_spec.rb +++ b/spec/models/nomenclature_change/lump_spec.rb @@ -62,4 +62,17 @@ end end end + describe :new_output_rank do + let(:lump){ + build( + :nomenclature_change_lump, + inputs_attributes: { + 0 => { taxon_concept_id: create_cites_eu_species.id }, + 1 => { taxon_concept_id: create_cites_eu_subspecies.id } + }, + status: NomenclatureChange::Lump::INPUTS + ) + } + specify{ expect(lump.new_output_rank.name).to eq(Rank::SPECIES) } + end end diff --git a/spec/models/nomenclature_change/shared/lump_definitions.rb b/spec/models/nomenclature_change/shared/lump_definitions.rb index d36f08e6f2..b0583d154e 100644 --- a/spec/models/nomenclature_change/shared/lump_definitions.rb +++ b/spec/models/nomenclature_change/shared/lump_definitions.rb @@ -34,7 +34,6 @@ 1 => { taxon_concept_id: input_species2.id } }, output_attributes: { - new_rank_id: input_species1.rank_id, taxon_concept_id: input_species1.id }, status: NomenclatureChange::Lump::OUTPUTS @@ -47,7 +46,6 @@ 1 => { taxon_concept_id: input_species2.id } }, output_attributes: { - new_rank_id: output_species.rank_id, taxon_concept_id: output_species.id }, status: NomenclatureChange::Lump::OUTPUTS @@ -74,7 +72,6 @@ 1 => { taxon_concept_id: input_species2.id } }, output_attributes: { - new_rank_id: output_species.rank_id, taxon_concept_id: output_species.id }, status: NomenclatureChange::Lump::OUTPUTS @@ -87,8 +84,8 @@ 1 => { taxon_concept_id: input_species2.id } }, output_attributes: { - new_rank_id: output_species.rank_id, taxon_concept_id: output_subspecies.id, + new_rank_id: output_species.rank_id, new_scientific_name: 'lolcatus', new_parent_id: errorus_genus.id }, From 90f4aa5109424cd630b577e122ffa400984d45d9 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 22 Mar 2016 07:34:07 +0000 Subject: [PATCH 129/365] fixed primary output form display --- .../status_to_accepted/primary_output.html.erb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/views/admin/nomenclature_changes/status_to_accepted/primary_output.html.erb b/app/views/admin/nomenclature_changes/status_to_accepted/primary_output.html.erb index 4213cf0342..291e3b6849 100644 --- a/app/views/admin/nomenclature_changes/status_to_accepted/primary_output.html.erb +++ b/app/views/admin/nomenclature_changes/status_to_accepted/primary_output.html.erb @@ -13,6 +13,7 @@ :'data-taxonomy-id' => @taxonomy.id } %>
- <%= render 'admin/nomenclature_changes/build/new_parent', :ff => ff %> +
+ <%= render 'admin/nomenclature_changes/build/new_parent', :ff => ff %> <% end %> <% end %> \ No newline at end of file From 7780735453a886e35a11076dedc655c407387f24 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Fri, 18 Mar 2016 13:08:38 +0000 Subject: [PATCH 130/365] simplify logic following changes to possible name_status of outputs --- app/models/nomenclature_change/split/processor.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/models/nomenclature_change/split/processor.rb b/app/models/nomenclature_change/split/processor.rb index 400aafe50a..9ca763ed21 100644 --- a/app/models/nomenclature_change/split/processor.rb +++ b/app/models/nomenclature_change/split/processor.rb @@ -26,15 +26,15 @@ def prepare_chain end if output.will_create_taxon? # for the case when an existing accepted subspecies is turned into a species - if ['A', 'N'].include?(output.name_status) + if output.name_status == 'A' chain << NomenclatureChange::ReassignmentTransferProcessor.new(output, output) chain << NomenclatureChange::StatusDowngradeProcessor.new(output) # for the case when an existing synonym subspecies is turned into a species - elsif ['S', 'T'].include?(output.name_status) + elsif output.name_status == 'S' chain << NomenclatureChange::StatusDowngradeProcessor.new(output, [output]) end - elsif !output.will_create_taxon? && ['S', 'T'].include?(output.name_status) + elsif !output.will_create_taxon? && output.name_status == 'S' chain << NomenclatureChange::StatusUpgradeProcessor.new(output) end unless @input.taxon_concept_id == output.taxon_concept_id && !output.will_create_taxon? From 61181178fac4fe1d1bc82fcf3cbe7a726f0503b8 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Sun, 20 Mar 2016 23:34:03 +0000 Subject: [PATCH 131/365] for splits and lumps, cascade taxon-level nomenclature notes to children affected by name change --- .../cascading_notes_processor.rb | 69 +++++++++++++++++++ .../nomenclature_change/lump/processor.rb | 6 +- .../nomenclature_change/split/processor.rb | 2 + .../lump/processor_spec.rb | 55 +++++++++++++++ .../split/processor_spec.rb | 56 +++++++++++++++ 5 files changed, 186 insertions(+), 2 deletions(-) create mode 100644 app/models/nomenclature_change/cascading_notes_processor.rb diff --git a/app/models/nomenclature_change/cascading_notes_processor.rb b/app/models/nomenclature_change/cascading_notes_processor.rb new file mode 100644 index 0000000000..28e8f4b6b3 --- /dev/null +++ b/app/models/nomenclature_change/cascading_notes_processor.rb @@ -0,0 +1,69 @@ +class NomenclatureChange::CascadingNotesProcessor + + def initialize(input_or_output) + @input_or_output = input_or_output + end + + def run + return false unless @input_or_output.taxon_concept + @taxon_concept = @input_or_output.taxon_concept + descendents_for_note_cascading(@taxon_concept).each do |d| + Rails.logger.debug("Processing note for descendant #{d.full_name} of input #{@taxon_concept.full_name}") + append_nomenclature_notes(d, @input_or_output) + end + end + + def summary; end + + private + + def descendents_for_note_cascading(taxon_concept) + unless [Rank::GENUS, Rank::SPECIES].include? taxon_concept.rank.try(:name) + return [] + end + # if it is a genus or a species, we want taxon-level nomenclature notes, + # both public and private, to cascade to descendents + subquery =<<-SQL + WITH RECURSIVE descendents AS ( + SELECT id, + full_name, + name_status, + nomenclature_note_en, + nomenclature_note_es, + nomenclature_note_fr + FROM taxon_concepts + WHERE parent_id = :taxon_concept_id + UNION ALL + SELECT taxon_concepts.id, + taxon_concepts.full_name, + taxon_concepts.name_status, + taxon_concepts.nomenclature_note_en, + taxon_concepts.nomenclature_note_es, + taxon_concepts.nomenclature_note_fr + FROM taxon_concepts + JOIN descendents h ON h.id = taxon_concepts.parent_id + ) + SELECT * FROM descendents + SQL + sanitized_subquery = ActiveRecord::Base.send( + :sanitize_sql_array, [subquery, taxon_concept_id: taxon_concept.id] + ) + TaxonConcept.from( + "(#{sanitized_subquery}) taxon_concepts" + ) + end + + def append_nomenclature_notes(tc, input_or_output) + tc.nomenclature_note_en = "#{tc.nomenclature_note_en} #{input_or_output.note_en}" + tc.nomenclature_note_es = "#{tc.nomenclature_note_es} #{input_or_output.note_es}" + tc.nomenclature_note_fr = "#{tc.nomenclature_note_es} #{input_or_output.note_fr}" + tc.save(validate: false) + nomenclature_comment = tc.nomenclature_comment || + tc.create_nomenclature_comment + nomenclature_comment.update_attribute( + :note, + "#{nomenclature_comment.note} #{input_or_output.internal_note}" + ) + end + +end diff --git a/app/models/nomenclature_change/lump/processor.rb b/app/models/nomenclature_change/lump/processor.rb index 24e7755d9f..174f4bdd8a 100644 --- a/app/models/nomenclature_change/lump/processor.rb +++ b/app/models/nomenclature_change/lump/processor.rb @@ -18,12 +18,14 @@ def prepare_chain chain = [] chain << NomenclatureChange::OutputTaxonConceptProcessor.new(@output) @inputs.each do |input| - unless input.taxon_concept_id == @output.taxon_concept_id && !@output.will_create_taxon? + if !(input.taxon_concept_id == @output.taxon_concept_id && !@output.will_create_taxon?) + chain << NomenclatureChange::InputTaxonConceptProcessor.new(input) + chain << NomenclatureChange::CascadingNotesProcessor.new(input) chain << NomenclatureChange::ReassignmentTransferProcessor.new(input, @output) chain << NomenclatureChange::StatusDowngradeProcessor.new(input, [@output]) - chain << NomenclatureChange::InputTaxonConceptProcessor.new(input) end end + chain << NomenclatureChange::CascadingNotesProcessor.new(@output) chain end diff --git a/app/models/nomenclature_change/split/processor.rb b/app/models/nomenclature_change/split/processor.rb index 9ca763ed21..0ad4065c36 100644 --- a/app/models/nomenclature_change/split/processor.rb +++ b/app/models/nomenclature_change/split/processor.rb @@ -20,6 +20,7 @@ def prepare_chain map(&:taxon_concept_id).include?(@input.taxon_concept_id) chain << NomenclatureChange::InputTaxonConceptProcessor.new(@input) + chain << NomenclatureChange::CascadingNotesProcessor.new(@input) @outputs.each_with_index do |output, idx| if @input.taxon_concept_id != output.taxon_concept_id chain << NomenclatureChange::OutputTaxonConceptProcessor.new(output) @@ -47,6 +48,7 @@ def prepare_chain chain << NomenclatureChange::ReassignmentCopyProcessor.new(@input, output) end end + chain << NomenclatureChange::CascadingNotesProcessor.new(output) end unless input_is_one_of_outputs chain << NomenclatureChange::StatusDowngradeProcessor.new(@input, @outputs) diff --git a/spec/models/nomenclature_change/lump/processor_spec.rb b/spec/models/nomenclature_change/lump/processor_spec.rb index 9e7ba81542..a2cbd46de0 100644 --- a/spec/models/nomenclature_change/lump/processor_spec.rb +++ b/spec/models/nomenclature_change/lump/processor_spec.rb @@ -60,6 +60,61 @@ specify{ expect(lump.output.new_taxon_concept.shipments).to include(@shipment) } end end + context "when input with children that change name" do + let!(:input_species1_child){ + create_cites_eu_subspecies(parent: input_species1) + } + let(:lump){ + create(:nomenclature_change_lump, + inputs_attributes: { + 0 => { + taxon_concept_id: input_species1.id, + note_en: 'input EN note', + internal_note: 'input internal note' + }, + 1 => { taxon_concept_id: input_species2.id } + }, + output_attributes: { + taxon_concept_id: output_species.id, + note_en: 'output EN note', + internal_note: 'output internal note' + }, + status: NomenclatureChange::Lump::LEGISLATION + ) + } + let(:input){ lump.inputs.first } + let(:output){ lump.output } + let(:reassignment){ + create(:nomenclature_change_parent_reassignment, + input: input, + reassignable_id: input_species1_child.id + ) + } + let!(:reassignment_target){ + create(:nomenclature_change_reassignment_target, + reassignment: reassignment, + output: output + ) + } + let(:output_species_child){ output_species.children.first.reload } + before(:each){ processor.run } + specify do + expect(input_species1.reload.nomenclature_note_en).to eq(' input EN note') + expect(input_species1_child.reload.nomenclature_note_en).to eq(input_species1.nomenclature_note_en) + end + specify do + expect(input_species1.nomenclature_comment.note).to eq(' input internal note') + expect(input_species1_child.nomenclature_comment.note).to eq(input_species1.nomenclature_comment.note) + end + specify do + expect(output_species.reload.nomenclature_note_en).to eq(' output EN note') + expect(output_species_child.reload.nomenclature_note_en).to eq(output_species.nomenclature_note_en) + end + specify do + expect(output_species.nomenclature_comment.note).to eq(' output internal note') + expect(output_species_child.nomenclature_comment.note).to eq(output_species.nomenclature_comment.note) + end + end end describe :summary do let(:lump){ lump_with_inputs_and_output_existing_taxon } diff --git a/spec/models/nomenclature_change/split/processor_spec.rb b/spec/models/nomenclature_change/split/processor_spec.rb index 07b6614014..e60106902d 100644 --- a/spec/models/nomenclature_change/split/processor_spec.rb +++ b/spec/models/nomenclature_change/split/processor_spec.rb @@ -75,6 +75,62 @@ specify{ expect(output_species1.shipments).to include(@shipment) } end end + context "when input with children that change name" do + let!(:input_species_child){ + create_cites_eu_subspecies(parent: input_species) + } + let(:split){ + create(:nomenclature_change_split, + input_attributes: { + taxon_concept_id: input_species.id, + note_en: 'input EN note', + internal_note: 'input internal note' + }, + outputs_attributes: { + 0 => { + taxon_concept_id: output_species1.id, + note_en: 'output EN note', + internal_note: 'output internal note' + }, + 1 => { taxon_concept_id: output_species2.id } + }, + status: NomenclatureChange::Split::LEGISLATION + ) + } + let(:input){ split.input } + let(:output){ split.outputs.first } + let(:reassignment){ + create(:nomenclature_change_parent_reassignment, + input: input, + reassignable_id: input_species_child.id + ) + } + let!(:reassignment_target){ + create(:nomenclature_change_reassignment_target, + reassignment: reassignment, + output: output + ) + } + let(:output_species){ output.taxon_concept.reload } + let(:output_species_child){ output.taxon_concept.children.first.reload } + before(:each){ processor.run } + specify do + expect(input_species.reload.nomenclature_note_en).to eq(' input EN note') + expect(input_species_child.reload.nomenclature_note_en).to eq(input_species.nomenclature_note_en) + end + specify do + expect(input_species.nomenclature_comment.note).to eq(' input internal note') + expect(input_species_child.nomenclature_comment.note).to eq(input_species.nomenclature_comment.note) + end + specify do + expect(output_species.reload.nomenclature_note_en).to eq(' output EN note') + expect(output_species_child.reload.nomenclature_note_en).to eq(output_species.nomenclature_note_en) + end + specify do + expect(output_species.nomenclature_comment.note).to eq(' output internal note') + expect(output_species_child.nomenclature_comment.note).to eq(output_species.nomenclature_comment.note) + end + end end describe :summary do let(:split){ split_with_input_and_output_existing_taxon } From 11872a1dab5a0603e649da6a2e4cf12dc398635b Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 21 Mar 2016 16:24:52 +0000 Subject: [PATCH 132/365] cascade notes to descendents of newly created taxa correctly --- .../nomenclature_change/cascading_notes_processor.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/models/nomenclature_change/cascading_notes_processor.rb b/app/models/nomenclature_change/cascading_notes_processor.rb index 28e8f4b6b3..dd974e1b21 100644 --- a/app/models/nomenclature_change/cascading_notes_processor.rb +++ b/app/models/nomenclature_change/cascading_notes_processor.rb @@ -5,8 +5,12 @@ def initialize(input_or_output) end def run - return false unless @input_or_output.taxon_concept - @taxon_concept = @input_or_output.taxon_concept + @taxon_concept = if @input_or_output.kind_of? NomenclatureChange::Output + @input_or_output.new_taxon_concept || @input_or_output.taxon_concept + else + @input_or_output.taxon_concept + end + return false unless @taxon_concept descendents_for_note_cascading(@taxon_concept).each do |d| Rails.logger.debug("Processing note for descendant #{d.full_name} of input #{@taxon_concept.full_name}") append_nomenclature_notes(d, @input_or_output) From d64cbbea9f54a102bf7c82e55dddcb1cc8f5de4c Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 21 Mar 2016 16:26:07 +0000 Subject: [PATCH 133/365] return empty array instead of nil where summary empty --- app/models/nomenclature_change/cascading_notes_processor.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/nomenclature_change/cascading_notes_processor.rb b/app/models/nomenclature_change/cascading_notes_processor.rb index dd974e1b21..a1c400f222 100644 --- a/app/models/nomenclature_change/cascading_notes_processor.rb +++ b/app/models/nomenclature_change/cascading_notes_processor.rb @@ -17,7 +17,7 @@ def run end end - def summary; end + def summary; []; end private From 3b1b214d6514ea1d0d3b4a073067763164046e2a Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Mon, 21 Mar 2016 18:25:16 +0000 Subject: [PATCH 134/365] Always build the notes from scratch --- .../nomenclature_change/lump/constructor.rb | 12 ++++------ .../nomenclature_change/split/constructor.rb | 22 ++++++++----------- 2 files changed, 13 insertions(+), 21 deletions(-) diff --git a/app/models/nomenclature_change/lump/constructor.rb b/app/models/nomenclature_change/lump/constructor.rb index f195b9014f..374d5e5893 100644 --- a/app/models/nomenclature_change/lump/constructor.rb +++ b/app/models/nomenclature_change/lump/constructor.rb @@ -109,19 +109,15 @@ def build_input_and_output_notes output = @nomenclature_change.output event = @nomenclature_change.event @nomenclature_change.inputs_except_outputs.each do |input| - if input.note_en.blank? note = multi_lingual_input_note(input, output, event) input.note_en = note[:en] input.note_es = note[:es] input.note_fr = note[:fr] - end - end - if output.note_en.blank? - note = multi_lingual_output_note(output, @nomenclature_change.inputs, event) - output.note_en = note[:en] - output.note_es = note[:es] - output.note_fr = note[:fr] end + note = multi_lingual_output_note(output, @nomenclature_change.inputs, event) + output.note_en = note[:en] + output.note_es = note[:es] + output.note_fr = note[:fr] end def legislation_note(lng) diff --git a/app/models/nomenclature_change/split/constructor.rb b/app/models/nomenclature_change/split/constructor.rb index be3352243d..2ec8187ff8 100644 --- a/app/models/nomenclature_change/split/constructor.rb +++ b/app/models/nomenclature_change/split/constructor.rb @@ -148,19 +148,15 @@ def multi_lingual_output_note(output, input, event) def build_input_and_output_notes input = @nomenclature_change.input event = @nomenclature_change.event - if input.note_en.blank? - note = multi_lingual_input_note(input, @nomenclature_change.outputs, event) - input.note_en = note[:en] - input.note_es = note[:es] - input.note_fr = note[:fr] - end + note = multi_lingual_input_note(input, @nomenclature_change.outputs, event) + input.note_en = note[:en] + input.note_es = note[:es] + input.note_fr = note[:fr] @nomenclature_change.outputs_except_inputs.each do |output| - if output.note_en.blank? - note = multi_lingual_output_note(output, input, event) - output.note_en = note[:en] - output.note_es = note[:es] - output.note_fr = note[:fr] - end + note = multi_lingual_output_note(output, input, event) + output.note_en = note[:en] + output.note_es = note[:es] + output.note_fr = note[:fr] end end @@ -196,4 +192,4 @@ def multi_lingual_quota_note multi_lingual_legislation_note('split.quota') end -end \ No newline at end of file +end From e913523dff608ed1473eefdbeb7c61ce9ed6cc74 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Mon, 21 Mar 2016 18:39:41 +0000 Subject: [PATCH 135/365] Same type of nomenclature notes amendment for status_change and status_swap --- .../status_change/constructor_helpers.rb | 34 +++++++++---------- .../status_swap/constructor.rb | 32 ++++++++--------- 2 files changed, 31 insertions(+), 35 deletions(-) diff --git a/app/models/nomenclature_change/status_change/constructor_helpers.rb b/app/models/nomenclature_change/status_change/constructor_helpers.rb index 8f0b60fcb6..c9f45eb46f 100644 --- a/app/models/nomenclature_change/status_change/constructor_helpers.rb +++ b/app/models/nomenclature_change/status_change/constructor_helpers.rb @@ -125,23 +125,21 @@ def private_output_note(output, event, lng) end def build_primary_output_note - if @nomenclature_change.primary_output.note_en.blank? - if @nomenclature_change.primary_output.needs_public_note? - primary_note = multi_lingual_public_output_note( - @nomenclature_change.primary_output, - @event - ) - @nomenclature_change.primary_output.note_en = primary_note[:en] - @nomenclature_change.primary_output.note_es = primary_note[:es] - @nomenclature_change.primary_output.note_fr = primary_note[:fr] - else - primary_note = private_output_note( - @nomenclature_change.primary_output, - @event, - :en - ) - @nomenclature_change.primary_output.internal_note = primary_note - end + if @nomenclature_change.primary_output.needs_public_note? + primary_note = multi_lingual_public_output_note( + @nomenclature_change.primary_output, + @event + ) + @nomenclature_change.primary_output.note_en = primary_note[:en] + @nomenclature_change.primary_output.note_es = primary_note[:es] + @nomenclature_change.primary_output.note_fr = primary_note[:fr] + else + primary_note = private_output_note( + @nomenclature_change.primary_output, + @event, + :en + ) + @nomenclature_change.primary_output.internal_note = primary_note end end @@ -185,4 +183,4 @@ def legislation_note(lng) nil end -end \ No newline at end of file +end diff --git a/app/models/nomenclature_change/status_swap/constructor.rb b/app/models/nomenclature_change/status_swap/constructor.rb index 9cde8d6dbe..3bf2c77a49 100644 --- a/app/models/nomenclature_change/status_swap/constructor.rb +++ b/app/models/nomenclature_change/status_swap/constructor.rb @@ -8,23 +8,21 @@ def initialize(nomenclature_change) end def build_secondary_output_note - if @nomenclature_change.secondary_output.note_en.blank? - if @nomenclature_change.secondary_output.needs_public_note? - secondary_note = multi_lingual_public_output_note( - @nomenclature_change.secondary_output, - @event - ) - @nomenclature_change.secondary_output.note_en = secondary_note[:en] - @nomenclature_change.secondary_output.note_es = secondary_note[:es] - @nomenclature_change.secondary_output.note_fr = secondary_note[:fr] - else - secondary_note = private_output_note( - @nomenclature_change.secondary_output, - @event, - :en - ) - @nomenclature_change.secondary_output.internal_note = secondary_note - end + if @nomenclature_change.secondary_output.needs_public_note? + secondary_note = multi_lingual_public_output_note( + @nomenclature_change.secondary_output, + @event + ) + @nomenclature_change.secondary_output.note_en = secondary_note[:en] + @nomenclature_change.secondary_output.note_es = secondary_note[:es] + @nomenclature_change.secondary_output.note_fr = secondary_note[:fr] + else + secondary_note = private_output_note( + @nomenclature_change.secondary_output, + @event, + :en + ) + @nomenclature_change.secondary_output.internal_note = secondary_note end end From fb677adef63b090fc931fe2ce04cfefd318d2d2d Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Tue, 22 Mar 2016 09:54:22 +0000 Subject: [PATCH 136/365] Also update legislation notes --- app/models/nomenclature_change/constructor_helpers.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/models/nomenclature_change/constructor_helpers.rb b/app/models/nomenclature_change/constructor_helpers.rb index 9466e2626c..3411983ac2 100644 --- a/app/models/nomenclature_change/constructor_helpers.rb +++ b/app/models/nomenclature_change/constructor_helpers.rb @@ -129,8 +129,7 @@ def _build_legislation_reassignments(input, outputs) def _build_legislation_type_reassignment(legislation_collection_name, input) legislation_type = legislation_collection_name.to_s.singularize.camelize public_note = send(:"multi_lingual_#{legislation_collection_name.to_s.singularize}_note") - input.send(:"#{legislation_collection_name}_reassignments").first || - input.taxon_concept.send(legislation_collection_name).limit(1).count > 0 && + input.taxon_concept.send(legislation_collection_name).limit(1).count > 0 && input.legislation_reassignment_class.new( reassignable_type: legislation_type, note_en: public_note[:en], From 9e4b0ad8d686344e9d10bbfb6a935a37c5df2af4 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 22 Mar 2016 12:04:47 +0000 Subject: [PATCH 137/365] fixed indentation --- app/models/nomenclature_change/lump/constructor.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/models/nomenclature_change/lump/constructor.rb b/app/models/nomenclature_change/lump/constructor.rb index 374d5e5893..c489657877 100644 --- a/app/models/nomenclature_change/lump/constructor.rb +++ b/app/models/nomenclature_change/lump/constructor.rb @@ -109,10 +109,10 @@ def build_input_and_output_notes output = @nomenclature_change.output event = @nomenclature_change.event @nomenclature_change.inputs_except_outputs.each do |input| - note = multi_lingual_input_note(input, output, event) - input.note_en = note[:en] - input.note_es = note[:es] - input.note_fr = note[:fr] + note = multi_lingual_input_note(input, output, event) + input.note_en = note[:en] + input.note_es = note[:es] + input.note_fr = note[:fr] end note = multi_lingual_output_note(output, @nomenclature_change.inputs, event) output.note_en = note[:en] From 0ce2ad8c101cdc1da11b24b98bc6853a13a76ac5 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 21 Mar 2016 22:01:12 +0000 Subject: [PATCH 138/365] removed validation for name uniqueness, which happens anyway as part of taxon concept validation --- app/models/nomenclature_change/lump.rb | 7 ------- app/models/nomenclature_change/output.rb | 4 ---- app/models/nomenclature_change/split.rb | 10 ---------- 3 files changed, 21 deletions(-) diff --git a/app/models/nomenclature_change/lump.rb b/app/models/nomenclature_change/lump.rb index ac42ac1c2a..00ff767d59 100644 --- a/app/models/nomenclature_change/lump.rb +++ b/app/models/nomenclature_change/lump.rb @@ -61,13 +61,6 @@ def required_outputs end end - def required_different_name - if output.taxon_name_already_existing? && !output.new_full_name.nil? - errors.add(:output, "Name already existing") - return false - end - end - def set_output_name_status if output.new_name_status.blank? && ( output.new_scientific_name.present? || diff --git a/app/models/nomenclature_change/output.rb b/app/models/nomenclature_change/output.rb index aa25db1d90..a79aaf5524 100644 --- a/app/models/nomenclature_change/output.rb +++ b/app/models/nomenclature_change/output.rb @@ -185,10 +185,6 @@ def needs_public_note? end end - def taxon_name_already_existing? - return !TaxonConcept.where("lower(full_name) = ?", display_full_name.downcase).empty? - end - def expected_parent_name if rank.name == Rank::SPECIES display_full_name.split[0] diff --git a/app/models/nomenclature_change/split.rb b/app/models/nomenclature_change/split.rb index 164e057b9b..baa19734ce 100644 --- a/app/models/nomenclature_change/split.rb +++ b/app/models/nomenclature_change/split.rb @@ -34,7 +34,6 @@ class NomenclatureChange::Split < NomenclatureChange validate :required_inputs, if: :inputs_or_submitting? validate :required_outputs, if: :outputs_or_submitting? validate :required_ranks, if: :outputs_or_submitting? - validate :required_different_name, if: :outputs_or_submitting? before_validation :set_outputs_name_status, if: :outputs_or_submitting? before_validation :set_outputs_rank_id, if: :outputs_or_submitting? before_save :build_auto_reassignments, if: :notes? @@ -73,15 +72,6 @@ def required_ranks end end - def required_different_name - if outputs.any? do |output| - output.taxon_name_already_existing? && !output.new_full_name.nil? - end - errors.add(:outputs, "Name already existing") - return false - end - end - def set_outputs_name_status outputs.each do |output| if output.new_name_status.blank? && ( From e9cbf610c436833c0871336fde83a175a44977c8 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 22 Mar 2016 08:30:29 +0000 Subject: [PATCH 139/365] do not detach old parent when downgrading to synonym --- .../status_downgrade_processor.rb | 13 +------------ .../nomenclature_change/lump/processor_spec.rb | 4 +++- .../nomenclature_change/split/processor_spec.rb | 2 +- .../status_swap/processor_spec.rb | 3 +++ .../status_to_synonym/processor_spec.rb | 3 +++ 5 files changed, 11 insertions(+), 14 deletions(-) diff --git a/app/models/nomenclature_change/status_downgrade_processor.rb b/app/models/nomenclature_change/status_downgrade_processor.rb index 9abf7ebe40..60bb52090c 100644 --- a/app/models/nomenclature_change/status_downgrade_processor.rb +++ b/app/models/nomenclature_change/status_downgrade_processor.rb @@ -9,20 +9,9 @@ def run if @input_or_output.kind_of?(NomenclatureChange::Output) && @input_or_output.new_taxon_concept @linked_names << @input_or_output.new_taxon_concept end - higher_taxa_hstore_fields = Rank.in_range(nil, nil).map do |r| - ["#{r.downcase}_id", "#{r.downcase}_name"] - end.flatten - new_data = @input_or_output.taxon_concept.data && - @input_or_output.taxon_concept.data.except(*higher_taxa_hstore_fields) || - {} - # work-around to avoid 3 separate update_column calls TaxonConcept.where(id: @input_or_output.taxon_concept_id).update_all( - name_status: 'S', - parent_id: nil, - data: ActiveRecord::Coders::Hstore.dump( - new_data - ) + name_status: 'S' ) if @old_status == 'T' diff --git a/spec/models/nomenclature_change/lump/processor_spec.rb b/spec/models/nomenclature_change/lump/processor_spec.rb index a2cbd46de0..29735fecdc 100644 --- a/spec/models/nomenclature_change/lump/processor_spec.rb +++ b/spec/models/nomenclature_change/lump/processor_spec.rb @@ -48,6 +48,8 @@ end end context "when output is existing taxon with new name" do + let(:input_genus1){ create_cites_eu_genus } + let(:input_species1){ create_cites_eu_species(parent: input_genus1) } let(:output_species2){ create_cites_eu_subspecies } let!(:lump){ lump_with_inputs_and_output_name_change } specify { expect{ processor.run }.to change(TaxonConcept, :count).by(1) } @@ -55,7 +57,7 @@ context "relationships and trade" do before(:each){ processor.run } specify{ expect(input_species1.reload).to be_is_synonym } - specify{ expect(input_species1.reload.parent_id).to be_nil } + specify{ expect(input_species1.reload.parent).to eq(input_genus1) } specify{ expect(input_species1.accepted_names).to include(lump.output.new_taxon_concept) } specify{ expect(lump.output.new_taxon_concept.shipments).to include(@shipment) } end diff --git a/spec/models/nomenclature_change/split/processor_spec.rb b/spec/models/nomenclature_change/split/processor_spec.rb index e60106902d..537e857be8 100644 --- a/spec/models/nomenclature_change/split/processor_spec.rb +++ b/spec/models/nomenclature_change/split/processor_spec.rb @@ -70,7 +70,7 @@ context "relationships and trade" do before(:each){ processor.run } specify{ expect(input_species.reload).to be_is_synonym } - specify{ expect(input_species.reload.parent_id).to be_nil } + specify{ expect(input_species.reload.parent).to eq(genus1) } specify{ expect(input_species.accepted_names).to include(split.outputs.last.new_taxon_concept) } specify{ expect(output_species1.shipments).to include(@shipment) } end diff --git a/spec/models/nomenclature_change/status_swap/processor_spec.rb b/spec/models/nomenclature_change/status_swap/processor_spec.rb index 4d75d95e5a..d9d23f6201 100644 --- a/spec/models/nomenclature_change/status_swap/processor_spec.rb +++ b/spec/models/nomenclature_change/status_swap/processor_spec.rb @@ -23,6 +23,8 @@ describe :run do context "from accepted name" do + let(:accepted_name_parent){ create_cites_eu_genus } + let(:accepted_name){ create_cites_eu_species(parent: accepted_name_parent) } let(:status_change){ a_to_s_with_swap } before(:each){ @shipment = create(:shipment, @@ -32,6 +34,7 @@ processor.run } specify{ expect(primary_output_taxon_concept).to be_is_synonym } + specify{ expect(primary_output_taxon_concept.parent).to eq(accepted_name_parent) } specify{ expect(secondary_output_taxon_concept.name_status).to eq('A') } specify{ expect(primary_output_taxon_concept.accepted_names).to include(secondary_output_taxon_concept) } end diff --git a/spec/models/nomenclature_change/status_to_synonym/processor_spec.rb b/spec/models/nomenclature_change/status_to_synonym/processor_spec.rb index bb3e8828fc..25bec4e83a 100644 --- a/spec/models/nomenclature_change/status_to_synonym/processor_spec.rb +++ b/spec/models/nomenclature_change/status_to_synonym/processor_spec.rb @@ -11,6 +11,8 @@ describe :run do context "from N name" do + let(:input_species_parent){ create_cites_eu_genus } + let(:input_species){ create_cites_eu_species(parent: input_species_parent) } let(:status_change){ n_to_s_with_input_and_secondary_output } before(:each){ @shipment = create(:shipment, @@ -20,6 +22,7 @@ processor.run } specify{ expect(primary_output_taxon_concept).to be_is_synonym } + specify{ expect(primary_output_taxon_concept.parent).to eq(input_species_parent) } specify{ expect(primary_output_taxon_concept.accepted_names).to include(secondary_output_taxon_concept) } specify{ expect(primary_output_taxon_concept.shipments).to be_empty } specify{ expect(primary_output_taxon_concept.reported_shipments).to include(@shipment) } From d08abfefe0418c0cb1525760cdff19c5af05a8dc Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 22 Mar 2016 11:00:02 +0000 Subject: [PATCH 140/365] when parent name is not compatible, revert the parent reassignment to preserve old ancestry for synonyms --- app/models/nomenclature_change/reassignment_processor.rb | 2 +- .../nomenclature_change/taxonomic_tree_name_resolver.rb | 9 +++++---- .../nomenclature_change/to_synonym_transformation.rb | 3 +-- .../shared/parent_reassignments_processor_examples.rb | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/models/nomenclature_change/reassignment_processor.rb b/app/models/nomenclature_change/reassignment_processor.rb index 1562aea902..8c205a5d39 100644 --- a/app/models/nomenclature_change/reassignment_processor.rb +++ b/app/models/nomenclature_change/reassignment_processor.rb @@ -87,7 +87,7 @@ def conflicting_listing_change_reassignment?(reassignment, reassignable) def post_process(reassigned_object, object_before_reassignment) Rails.logger.warn("Reassignment post processing BEGIN") if reassigned_object.is_a?(TaxonConcept) - resolver = NomenclatureChange::TaxonomicTreeNameResolver.new(reassigned_object) + resolver = NomenclatureChange::TaxonomicTreeNameResolver.new(reassigned_object, object_before_reassignment) resolver.process elsif reassigned_object.is_a?(TaxonRelationship) resolver = NomenclatureChange::TradeShipmentsResolver.new(reassigned_object, object_before_reassignment) diff --git a/app/models/nomenclature_change/taxonomic_tree_name_resolver.rb b/app/models/nomenclature_change/taxonomic_tree_name_resolver.rb index cb8aeb8780..745a6e74b9 100644 --- a/app/models/nomenclature_change/taxonomic_tree_name_resolver.rb +++ b/app/models/nomenclature_change/taxonomic_tree_name_resolver.rb @@ -1,7 +1,8 @@ class NomenclatureChange::TaxonomicTreeNameResolver - def initialize(taxon_concept) + def initialize(taxon_concept, taxon_concept_old_copy) @node = taxon_concept + @node_old_copy = taxon_concept_old_copy end # turn taxa into synonyms when name changes involved @@ -36,13 +37,13 @@ def resolve(node) t.process end end + # restore old parent, even though this ends up as a synonym it should + # have sane ancestry + node.update_attribute(:parent_id, @node_old_copy.parent_id) r = NomenclatureChange::FullReassignment.new(node, compatible_node) r.process t = NomenclatureChange::ToSynonymTransformation.new(node, compatible_node) t.process - node.children.each do |child| - child.update_attribute(:parent_id, compatible_node.id) - end else compatible_node = node end diff --git a/app/models/nomenclature_change/to_synonym_transformation.rb b/app/models/nomenclature_change/to_synonym_transformation.rb index b59debba1a..7ce029532d 100644 --- a/app/models/nomenclature_change/to_synonym_transformation.rb +++ b/app/models/nomenclature_change/to_synonym_transformation.rb @@ -12,8 +12,7 @@ def process relink_relationships( @accepted_taxon_concept.trade_name_relationships, @new_accepted_name ) - # detach from parent and turn into a synonym - @accepted_taxon_concept.update_attributes(parent_id: nil, name_status: 'S') + @accepted_taxon_concept.update_attribute(:name_status, 'S') # turn current name into synonym of new name rel_type = TaxonRelationshipType.find_by_name(TaxonRelationshipType::HAS_SYNONYM) @new_accepted_name.taxon_relationships << TaxonRelationship.new( diff --git a/spec/models/nomenclature_change/shared/parent_reassignments_processor_examples.rb b/spec/models/nomenclature_change/shared/parent_reassignments_processor_examples.rb index ab8e1aa248..6b10cab07e 100644 --- a/spec/models/nomenclature_change/shared/parent_reassignments_processor_examples.rb +++ b/spec/models/nomenclature_change/shared/parent_reassignments_processor_examples.rb @@ -19,7 +19,7 @@ processor.run input_species_child.reload end - specify{ expect(input_species_child.parent).to be_nil } + specify{ expect(input_species_child.parent).to eq(input_species) } specify{ expect(input_species_child.name_status).to eq('S') } specify{ expect(input_species.children.count).to eq(0) } specify do From c04166d53a915190ad1f5043a905d4b7bf553ff6 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 21 Mar 2016 16:57:29 +0000 Subject: [PATCH 141/365] cascade taxon-level nomenclature note to legislation records on lower taxonomic levels --- .../cascading_notes_processor.rb | 17 +++++++++++++++++ .../nomenclature_change/lump/processor_spec.rb | 9 +++++++++ .../nomenclature_change/split/processor_spec.rb | 9 +++++++++ 3 files changed, 35 insertions(+) diff --git a/app/models/nomenclature_change/cascading_notes_processor.rb b/app/models/nomenclature_change/cascading_notes_processor.rb index a1c400f222..c34e22a877 100644 --- a/app/models/nomenclature_change/cascading_notes_processor.rb +++ b/app/models/nomenclature_change/cascading_notes_processor.rb @@ -14,6 +14,15 @@ def run descendents_for_note_cascading(@taxon_concept).each do |d| Rails.logger.debug("Processing note for descendant #{d.full_name} of input #{@taxon_concept.full_name}") append_nomenclature_notes(d, @input_or_output) + ( + d.listing_changes + + d.cites_suspensions + + d.quotas + + d.eu_opinions + + d.eu_suspensions + ).each do |legislation| + append_nomenclature_notes_to_legislation(legislation, @input_or_output) + end end end @@ -70,4 +79,12 @@ def append_nomenclature_notes(tc, input_or_output) ) end + def append_nomenclature_notes_to_legislation(legislation, input_or_output) + legislation.nomenclature_note_en = "#{legislation.nomenclature_note_en} #{input_or_output.note_en}" + legislation.nomenclature_note_es = "#{legislation.nomenclature_note_es} #{input_or_output.note_es}" + legislation.nomenclature_note_fr = "#{legislation.nomenclature_note_es} #{input_or_output.note_fr}" + legislation.internal_notes = "#{legislation.internal_notes} #{input_or_output.internal_note}" + legislation.save(validate: false) + end + end diff --git a/spec/models/nomenclature_change/lump/processor_spec.rb b/spec/models/nomenclature_change/lump/processor_spec.rb index 29735fecdc..3ab29c7535 100644 --- a/spec/models/nomenclature_change/lump/processor_spec.rb +++ b/spec/models/nomenclature_change/lump/processor_spec.rb @@ -66,6 +66,9 @@ let!(:input_species1_child){ create_cites_eu_subspecies(parent: input_species1) } + let!(:input_species1_child_listing){ + create_cites_I_addition(taxon_concept: input_species1_child) + } let(:lump){ create(:nomenclature_change_lump, inputs_attributes: { @@ -116,6 +119,12 @@ expect(output_species.nomenclature_comment.note).to eq(' output internal note') expect(output_species_child.nomenclature_comment.note).to eq(output_species.nomenclature_comment.note) end + specify do + expect(output_species_child.listing_changes.count).to eq(1) + expect( + output_species_child.listing_changes.first.nomenclature_note_en + ).to include(output_species.reload.nomenclature_note_en) + end end end describe :summary do diff --git a/spec/models/nomenclature_change/split/processor_spec.rb b/spec/models/nomenclature_change/split/processor_spec.rb index 537e857be8..4a36862bcc 100644 --- a/spec/models/nomenclature_change/split/processor_spec.rb +++ b/spec/models/nomenclature_change/split/processor_spec.rb @@ -79,6 +79,9 @@ let!(:input_species_child){ create_cites_eu_subspecies(parent: input_species) } + let!(:input_species_child_listing){ + create_cites_I_addition(taxon_concept: input_species_child) + } let(:split){ create(:nomenclature_change_split, input_attributes: { @@ -130,6 +133,12 @@ expect(output_species.nomenclature_comment.note).to eq(' output internal note') expect(output_species_child.nomenclature_comment.note).to eq(output_species.nomenclature_comment.note) end + specify do + expect(output_species_child.listing_changes.count).to eq(1) + expect( + output_species_child.listing_changes.first.nomenclature_note_en + ).to include(output_species.nomenclature_note_en) + end end end describe :summary do From 1950afd8e3548585abadedfa754a68e802f152bb Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 21 Mar 2016 16:58:26 +0000 Subject: [PATCH 142/365] shortened lines --- .../nomenclature_change/lump/processor_spec.rb | 16 ++++++++++++---- .../nomenclature_change/split/processor_spec.rb | 16 ++++++++++++---- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/spec/models/nomenclature_change/lump/processor_spec.rb b/spec/models/nomenclature_change/lump/processor_spec.rb index 3ab29c7535..275ec2d66a 100644 --- a/spec/models/nomenclature_change/lump/processor_spec.rb +++ b/spec/models/nomenclature_change/lump/processor_spec.rb @@ -105,19 +105,27 @@ before(:each){ processor.run } specify do expect(input_species1.reload.nomenclature_note_en).to eq(' input EN note') - expect(input_species1_child.reload.nomenclature_note_en).to eq(input_species1.nomenclature_note_en) + expect( + input_species1_child.reload.nomenclature_note_en + ).to eq(input_species1.nomenclature_note_en) end specify do expect(input_species1.nomenclature_comment.note).to eq(' input internal note') - expect(input_species1_child.nomenclature_comment.note).to eq(input_species1.nomenclature_comment.note) + expect( + input_species1_child.nomenclature_comment.note + ).to eq(input_species1.nomenclature_comment.note) end specify do expect(output_species.reload.nomenclature_note_en).to eq(' output EN note') - expect(output_species_child.reload.nomenclature_note_en).to eq(output_species.nomenclature_note_en) + expect( + output_species_child.reload.nomenclature_note_en + ).to eq(output_species.nomenclature_note_en) end specify do expect(output_species.nomenclature_comment.note).to eq(' output internal note') - expect(output_species_child.nomenclature_comment.note).to eq(output_species.nomenclature_comment.note) + expect( + output_species_child.nomenclature_comment.note + ).to eq(output_species.nomenclature_comment.note) end specify do expect(output_species_child.listing_changes.count).to eq(1) diff --git a/spec/models/nomenclature_change/split/processor_spec.rb b/spec/models/nomenclature_change/split/processor_spec.rb index 4a36862bcc..f7d677b8b4 100644 --- a/spec/models/nomenclature_change/split/processor_spec.rb +++ b/spec/models/nomenclature_change/split/processor_spec.rb @@ -119,19 +119,27 @@ before(:each){ processor.run } specify do expect(input_species.reload.nomenclature_note_en).to eq(' input EN note') - expect(input_species_child.reload.nomenclature_note_en).to eq(input_species.nomenclature_note_en) + expect( + input_species_child.reload.nomenclature_note_en + ).to eq(input_species.nomenclature_note_en) end specify do expect(input_species.nomenclature_comment.note).to eq(' input internal note') - expect(input_species_child.nomenclature_comment.note).to eq(input_species.nomenclature_comment.note) + expect( + input_species_child.nomenclature_comment.note + ).to eq(input_species.nomenclature_comment.note) end specify do expect(output_species.reload.nomenclature_note_en).to eq(' output EN note') - expect(output_species_child.reload.nomenclature_note_en).to eq(output_species.nomenclature_note_en) + expect( + output_species_child.reload.nomenclature_note_en + ).to eq(output_species.nomenclature_note_en) end specify do expect(output_species.nomenclature_comment.note).to eq(' output internal note') - expect(output_species_child.nomenclature_comment.note).to eq(output_species.nomenclature_comment.note) + expect( + output_species_child.nomenclature_comment.note + ).to eq(output_species.nomenclature_comment.note) end specify do expect(output_species_child.listing_changes.count).to eq(1) From d3b05738b2342543d2b1a72a874ebfa8afe93495 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 22 Mar 2016 13:54:53 +0000 Subject: [PATCH 143/365] fixed cascading French notes --- app/models/nomenclature_change/cascading_notes_processor.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/nomenclature_change/cascading_notes_processor.rb b/app/models/nomenclature_change/cascading_notes_processor.rb index c34e22a877..eeb9811c29 100644 --- a/app/models/nomenclature_change/cascading_notes_processor.rb +++ b/app/models/nomenclature_change/cascading_notes_processor.rb @@ -69,7 +69,7 @@ def descendents_for_note_cascading(taxon_concept) def append_nomenclature_notes(tc, input_or_output) tc.nomenclature_note_en = "#{tc.nomenclature_note_en} #{input_or_output.note_en}" tc.nomenclature_note_es = "#{tc.nomenclature_note_es} #{input_or_output.note_es}" - tc.nomenclature_note_fr = "#{tc.nomenclature_note_es} #{input_or_output.note_fr}" + tc.nomenclature_note_fr = "#{tc.nomenclature_note_fr} #{input_or_output.note_fr}" tc.save(validate: false) nomenclature_comment = tc.nomenclature_comment || tc.create_nomenclature_comment @@ -82,7 +82,7 @@ def append_nomenclature_notes(tc, input_or_output) def append_nomenclature_notes_to_legislation(legislation, input_or_output) legislation.nomenclature_note_en = "#{legislation.nomenclature_note_en} #{input_or_output.note_en}" legislation.nomenclature_note_es = "#{legislation.nomenclature_note_es} #{input_or_output.note_es}" - legislation.nomenclature_note_fr = "#{legislation.nomenclature_note_es} #{input_or_output.note_fr}" + legislation.nomenclature_note_fr = "#{legislation.nomenclature_note_fr} #{input_or_output.note_fr}" legislation.internal_notes = "#{legislation.internal_notes} #{input_or_output.internal_note}" legislation.save(validate: false) end From c93d6887bb0d70cec3419fa755d32d894ff29f07 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 22 Mar 2016 15:16:55 +0000 Subject: [PATCH 144/365] simplified conditions for readability --- app/models/nomenclature_change/lump/processor.rb | 2 +- app/models/nomenclature_change/split/processor.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/nomenclature_change/lump/processor.rb b/app/models/nomenclature_change/lump/processor.rb index 174f4bdd8a..fa5c55b5b5 100644 --- a/app/models/nomenclature_change/lump/processor.rb +++ b/app/models/nomenclature_change/lump/processor.rb @@ -18,7 +18,7 @@ def prepare_chain chain = [] chain << NomenclatureChange::OutputTaxonConceptProcessor.new(@output) @inputs.each do |input| - if !(input.taxon_concept_id == @output.taxon_concept_id && !@output.will_create_taxon?) + if input.taxon_concept_id != @output.taxon_concept_id || @output.will_create_taxon? chain << NomenclatureChange::InputTaxonConceptProcessor.new(input) chain << NomenclatureChange::CascadingNotesProcessor.new(input) chain << NomenclatureChange::ReassignmentTransferProcessor.new(input, @output) diff --git a/app/models/nomenclature_change/split/processor.rb b/app/models/nomenclature_change/split/processor.rb index 0ad4065c36..2d89dd80fe 100644 --- a/app/models/nomenclature_change/split/processor.rb +++ b/app/models/nomenclature_change/split/processor.rb @@ -38,7 +38,7 @@ def prepare_chain elsif !output.will_create_taxon? && output.name_status == 'S' chain << NomenclatureChange::StatusUpgradeProcessor.new(output) end - unless @input.taxon_concept_id == output.taxon_concept_id && !output.will_create_taxon? + if @input.taxon_concept_id != output.taxon_concept_id || output.will_create_taxon? # if input is not one of outputs and this is the last output # transfer the associations rather than copy them transfer = !input_is_one_of_outputs && (idx == (@outputs.length - 1)) From f3c9042898d8124d040ce0e1f5792c29f7d9734c Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 22 Mar 2016 15:17:16 +0000 Subject: [PATCH 145/365] only cascade input notes when input is not an output, to avoid cascading from both input and output --- app/models/nomenclature_change/lump/processor.rb | 4 +++- app/models/nomenclature_change/split/processor.rb | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/models/nomenclature_change/lump/processor.rb b/app/models/nomenclature_change/lump/processor.rb index fa5c55b5b5..01562eb869 100644 --- a/app/models/nomenclature_change/lump/processor.rb +++ b/app/models/nomenclature_change/lump/processor.rb @@ -20,7 +20,9 @@ def prepare_chain @inputs.each do |input| if input.taxon_concept_id != @output.taxon_concept_id || @output.will_create_taxon? chain << NomenclatureChange::InputTaxonConceptProcessor.new(input) - chain << NomenclatureChange::CascadingNotesProcessor.new(input) + if input.taxon_concept_id != @output.taxon_concept_id + chain << NomenclatureChange::CascadingNotesProcessor.new(input) + end chain << NomenclatureChange::ReassignmentTransferProcessor.new(input, @output) chain << NomenclatureChange::StatusDowngradeProcessor.new(input, [@output]) end diff --git a/app/models/nomenclature_change/split/processor.rb b/app/models/nomenclature_change/split/processor.rb index 2d89dd80fe..10e4f409a6 100644 --- a/app/models/nomenclature_change/split/processor.rb +++ b/app/models/nomenclature_change/split/processor.rb @@ -20,7 +20,9 @@ def prepare_chain map(&:taxon_concept_id).include?(@input.taxon_concept_id) chain << NomenclatureChange::InputTaxonConceptProcessor.new(@input) - chain << NomenclatureChange::CascadingNotesProcessor.new(@input) + if !input_is_one_of_outputs + chain << NomenclatureChange::CascadingNotesProcessor.new(@input) + end @outputs.each_with_index do |output, idx| if @input.taxon_concept_id != output.taxon_concept_id chain << NomenclatureChange::OutputTaxonConceptProcessor.new(output) From 0cd52fd1895a8eb8cc859658cd11a31a44a52e85 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Tue, 22 Mar 2016 11:43:05 +0000 Subject: [PATCH 146/365] Add notes step to swap and build output notes --- .../status_swap_controller.rb | 2 + app/models/nomenclature_change/status_swap.rb | 2 +- .../status_swap/notes.html.erb | 39 +++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 app/views/admin/nomenclature_changes/status_swap/notes.html.erb diff --git a/app/controllers/admin/nomenclature_changes/status_swap_controller.rb b/app/controllers/admin/nomenclature_changes/status_swap_controller.rb index d2463e856c..9a6cf825f8 100644 --- a/app/controllers/admin/nomenclature_changes/status_swap_controller.rb +++ b/app/controllers/admin/nomenclature_changes/status_swap_controller.rb @@ -12,6 +12,8 @@ def show when :swap set_taxonomy builder.build_secondary_output + when :notes + builder.build_output_notes when :legislation builder.build_legislation_reassignments skip_or_previous_step if @nomenclature_change.input.legislation_reassignments.empty? diff --git a/app/models/nomenclature_change/status_swap.rb b/app/models/nomenclature_change/status_swap.rb index 4fe3b304b4..459b17c9fd 100644 --- a/app/models/nomenclature_change/status_swap.rb +++ b/app/models/nomenclature_change/status_swap.rb @@ -22,7 +22,7 @@ class NomenclatureChange::StatusSwap < NomenclatureChange include NomenclatureChange::StatusChangeHelpers build_steps( - :primary_output, :swap, :legislation, :summary + :primary_output, :swap, :notes, :legislation, :summary ) validates :status, inclusion: { in: self.status_dict, diff --git a/app/views/admin/nomenclature_changes/status_swap/notes.html.erb b/app/views/admin/nomenclature_changes/status_swap/notes.html.erb new file mode 100644 index 0000000000..7b7e8a95b0 --- /dev/null +++ b/app/views/admin/nomenclature_changes/status_swap/notes.html.erb @@ -0,0 +1,39 @@ +

New status swap: nomenclature change notes

+<%= status_change_blurb %> +<%= nomenclature_change_form do |f| %> +

Input

+

+ + Original taxon concept being swapped +

+ <%= f.fields_for :input do |ff| %> +
+ +
+ <%= render partial: 'admin/nomenclature_changes/build/nomenclature_notes', + locals: {ff: ff} + %> +
+
+ <% end %> + +

Output

+

+ + Taxon resulting from the swap +

+ <%= f.fields_for :primary_output do |ff| %> +
+ +
+ <%= render partial: 'admin/nomenclature_changes/build/nomenclature_notes', + locals: {ff: ff} + %> +
+
+ <% end %> +<% end %> From 4c747df233db4ed8591a7b56d2829549e662d6ab Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Tue, 22 Mar 2016 22:29:42 +0000 Subject: [PATCH 147/365] Fix notes associations --- .../admin/nomenclature_changes/status_swap/notes.html.erb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/admin/nomenclature_changes/status_swap/notes.html.erb b/app/views/admin/nomenclature_changes/status_swap/notes.html.erb index 7b7e8a95b0..7998d583d0 100644 --- a/app/views/admin/nomenclature_changes/status_swap/notes.html.erb +++ b/app/views/admin/nomenclature_changes/status_swap/notes.html.erb @@ -1,12 +1,12 @@

New status swap: nomenclature change notes

<%= status_change_blurb %> <%= nomenclature_change_form do |f| %> -

Input

+

Primary output

Original taxon concept being swapped

- <%= f.fields_for :input do |ff| %> + <%= f.fields_for :primary_output do |ff| %>
<% end %> -

Output

+

Secondary output

Taxon resulting from the swap

- <%= f.fields_for :primary_output do |ff| %> + <%= f.fields_for :secondary_output do |ff| %>
-
- -
- <%= ff.select :new_rank_id, - options_from_collection_for_select(@ranks, :id, :name, ff.object.new_rank_id || f.object.new_output_rank.id), - { class: 'new-rank' } - %> -
-
+ <%= render 'admin/nomenclature_changes/build/new_rank', ff: ff, f: f %> <% end %> <% end %> diff --git a/app/views/admin/nomenclature_changes/status_swap/secondary_output.html.erb b/app/views/admin/nomenclature_changes/status_swap/secondary_output.html.erb index 82a78c94bc..660199227d 100644 --- a/app/views/admin/nomenclature_changes/status_swap/secondary_output.html.erb +++ b/app/views/admin/nomenclature_changes/status_swap/secondary_output.html.erb @@ -18,14 +18,6 @@ <%= render 'admin/nomenclature_changes/build/new_parent', :ff => ff %> -
- -
- <%= ff.select :new_rank_id, - options_from_collection_for_select(@ranks, :id, :name, ff.object.new_rank_id || f.object.new_output_rank.id), - { class: 'new-rank' } - %> -
-
+ <%= render 'admin/nomenclature_changes/build/new_rank', ff: ff, f: f %> <% end %> <% end %> \ No newline at end of file From 6e6783e6bde96845634946b3f302feebe200aa03 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 4 Apr 2016 15:00:42 +0200 Subject: [PATCH 188/365] added rank selector to status to accepted primary output step --- .../nomenclature_changes/status_to_accepted_controller.rb | 2 ++ app/models/nomenclature_change/status_to_accepted.rb | 5 +++++ .../status_to_accepted/primary_output.html.erb | 1 + 3 files changed, 8 insertions(+) diff --git a/app/controllers/admin/nomenclature_changes/status_to_accepted_controller.rb b/app/controllers/admin/nomenclature_changes/status_to_accepted_controller.rb index f6ded4bb61..1a7ff6d87a 100644 --- a/app/controllers/admin/nomenclature_changes/status_to_accepted_controller.rb +++ b/app/controllers/admin/nomenclature_changes/status_to_accepted_controller.rb @@ -8,6 +8,7 @@ def show when :primary_output set_events set_taxonomy + set_ranks builder.build_primary_output when :summary processor = klass::Processor.new(@nomenclature_change) @@ -28,6 +29,7 @@ def update unless success set_events set_taxonomy + set_ranks end end render_wizard @nomenclature_change diff --git a/app/models/nomenclature_change/status_to_accepted.rb b/app/models/nomenclature_change/status_to_accepted.rb index 88e3ee3b77..fc505b7144 100644 --- a/app/models/nomenclature_change/status_to_accepted.rb +++ b/app/models/nomenclature_change/status_to_accepted.rb @@ -40,6 +40,7 @@ def set_output_name_status end def set_output_rank_id + return true unless primary_output.new_rank_id.nil? primary_output && primary_output.taxon_concept && primary_output.new_rank_id = primary_output.taxon_concept.rank_id end @@ -50,6 +51,10 @@ def set_output_parent_id primary_output.new_parent_id = primary_output.default_parent.try(:id) end + def new_output_rank + primary_output && primary_output.taxon_concept.try(:rank) + end + def needs_to_receive_associations? false end diff --git a/app/views/admin/nomenclature_changes/status_to_accepted/primary_output.html.erb b/app/views/admin/nomenclature_changes/status_to_accepted/primary_output.html.erb index 291e3b6849..b0243de6bb 100644 --- a/app/views/admin/nomenclature_changes/status_to_accepted/primary_output.html.erb +++ b/app/views/admin/nomenclature_changes/status_to_accepted/primary_output.html.erb @@ -15,5 +15,6 @@ <%= render 'admin/nomenclature_changes/build/new_parent', :ff => ff %> + <%= render 'admin/nomenclature_changes/build/new_rank', ff: ff, f: f %> <% end %> <% end %> \ No newline at end of file From e33872e1a6d3029dc7b6fd306a465724a2d8d4d3 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 4 Apr 2016 15:01:36 +0200 Subject: [PATCH 189/365] added rank selector to status to split outputs step --- app/controllers/admin/nomenclature_changes/split_controller.rb | 2 ++ app/views/admin/nomenclature_changes/split/outputs.html.erb | 1 + 2 files changed, 3 insertions(+) diff --git a/app/controllers/admin/nomenclature_changes/split_controller.rb b/app/controllers/admin/nomenclature_changes/split_controller.rb index 35f0717c44..44b047b037 100644 --- a/app/controllers/admin/nomenclature_changes/split_controller.rb +++ b/app/controllers/admin/nomenclature_changes/split_controller.rb @@ -11,6 +11,7 @@ def show builder.build_input when :outputs set_taxonomy + set_ranks builder.build_outputs when :notes builder.build_input_and_output_notes @@ -45,6 +46,7 @@ def update unless success set_events set_taxonomy + set_ranks end end render_wizard @nomenclature_change diff --git a/app/views/admin/nomenclature_changes/split/outputs.html.erb b/app/views/admin/nomenclature_changes/split/outputs.html.erb index ed69ccf029..7368c1346e 100644 --- a/app/views/admin/nomenclature_changes/split/outputs.html.erb +++ b/app/views/admin/nomenclature_changes/split/outputs.html.erb @@ -41,6 +41,7 @@ + <%= render 'admin/nomenclature_changes/build/new_rank', ff: ff, f: f %> <% end %>
From a5dc44d6fb658663a96fb8bf26923c83c97a9e70 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 4 Apr 2016 15:02:03 +0200 Subject: [PATCH 190/365] use secondary output to set default rank when present --- app/models/nomenclature_change/status_swap.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/models/nomenclature_change/status_swap.rb b/app/models/nomenclature_change/status_swap.rb index fc3a440191..12db6bdfa3 100644 --- a/app/models/nomenclature_change/status_swap.rb +++ b/app/models/nomenclature_change/status_swap.rb @@ -84,7 +84,8 @@ def build_auto_reassignments end def new_output_rank - primary_output.taxon_concept.rank + secondary_output && secondary_output.taxon_concept.try(:rank) || + primary_output && primary_output.taxon_concept.try(:rank) end end From 23c6245ca29e82e142fa5fa98de0cbabd31d0d4c Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 4 Apr 2016 15:04:09 +0200 Subject: [PATCH 191/365] allows passing the rank scope to the autocomplete end-point from the select2 taxon concept selectors --- .../javascripts/admin/nomenclature_changes.js.coffee | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/admin/nomenclature_changes.js.coffee b/app/assets/javascripts/admin/nomenclature_changes.js.coffee index f1ea0bfc1c..76ee1b191e 100644 --- a/app/assets/javascripts/admin/nomenclature_changes.js.coffee +++ b/app/assets/javascripts/admin/nomenclature_changes.js.coffee @@ -14,11 +14,17 @@ $(document).ready -> url: '/admin/taxon_concepts/autocomplete' dataType: 'json' data: (query, page) -> + form = $(@).closest('form') + taxonomySelector = form && form.find('.taxonomy-selector') + rankSelector = form && form.find('.rank-selector') search_params: scientific_name: query - name_status: this.data('name-status-filter') + name_status: @data('name-status-filter') taxonomy: - id: this.data('taxonomy-id') + id: taxonomySelector && taxonomySelector.val() || @data('taxonomy-id') + rank: + id: rankSelector && rankSelector.val() || @data('rank-id') + scope: $(@).attr('data-rank-scope') per_page: 25 page: 1 results: (data, page) => # parse the results into the format expected by Select2. From 3e3b011a38d45158a6bc50024dc2e1c94a94c0f3 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 4 Apr 2016 15:06:33 +0200 Subject: [PATCH 192/365] passing taxonomy and rank from nomenclature change new parent selector --- .../admin/nomenclature_changes/build/_new_parent.html.erb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/views/admin/nomenclature_changes/build/_new_parent.html.erb b/app/views/admin/nomenclature_changes/build/_new_parent.html.erb index aa3cac264e..578907ff71 100644 --- a/app/views/admin/nomenclature_changes/build/_new_parent.html.erb +++ b/app/views/admin/nomenclature_changes/build/_new_parent.html.erb @@ -6,7 +6,9 @@ :'data-name' => ff.object.new_parent.try(:full_name), :'data-name-status' => ff.object.new_parent.try(:name_status), :'data-name-status-filter' => ['A'].to_json, - :'data-taxonomy-id' => @taxonomy.id + :'data-taxonomy-id' => @taxonomy.id, + :'data-rank-id' => ff.object.new_rank_id, + :'data-rank-scope' => 'parent' } %> From e7c9a28e2592e6aed06959268c7bb64677f42c08 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 4 Apr 2016 15:07:55 +0200 Subject: [PATCH 193/365] fixed initialisation of multiple selection select2 taxon selector --- .../admin/nomenclature_changes.js.coffee | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/app/assets/javascripts/admin/nomenclature_changes.js.coffee b/app/assets/javascripts/admin/nomenclature_changes.js.coffee index 76ee1b191e..8fcccb8483 100644 --- a/app/assets/javascripts/admin/nomenclature_changes.js.coffee +++ b/app/assets/javascripts/admin/nomenclature_changes.js.coffee @@ -36,18 +36,18 @@ $(document).ready -> window.multiTaxonSelect2Options = { multiple: true, initSelection: (element, callback) => - id = $(element).val().match(/({|\[)(.*)(}|\])/)[2] + elementValue = $(element).val() # Reset value attribute to let Select2 work properly when submitting the values again $(element).attr('value','') - if (id != null && id != '') - ids = id.split(',').map( (id) -> - parseInt(id.trim()) - ).sort( (a, b) -> a - b) + if elementValue? + ids = elementValue.match(/({|\[)(.*)(}|\])/)[2] names = $(element).data('name') name_status = $(element).data('name-status') result = [] - for id, i in ids - result.push({id: id, text: names[i] + ' ' + name_status}) + if ids != '' + ids = ids.split(',') + for id, i in ids + result.push({id: id, text: names && names[i] + ' ' + name_status}) callback(result) } window.hybridsSelect2Options = { From 019a279dceb17c2bbdc4e97044a6522f7769fdf2 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 4 Apr 2016 15:09:58 +0200 Subject: [PATCH 194/365] restored & renamed hybrid select2 additional options --- app/assets/javascripts/admin/admin_in_place_editor.js.coffee | 2 +- app/assets/javascripts/admin/nomenclature_changes.js.coffee | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/admin/admin_in_place_editor.js.coffee b/app/assets/javascripts/admin/admin_in_place_editor.js.coffee index 3cc5c08988..66a562461f 100644 --- a/app/assets/javascripts/admin/admin_in_place_editor.js.coffee +++ b/app/assets/javascripts/admin/admin_in_place_editor.js.coffee @@ -151,7 +151,7 @@ class AdminEditor initSelect2Inputs: () -> $('.taxon-concept').select2(window.defaultTaxonSelect2Options) $('.taxon-concept-multiple').select2($.extend({}, window.defaultTaxonSelect2Options,window.multiTaxonSelect2Options)) - $('.hybrids-selection').select2($.extend({}, window.defaultTaxonSelect2Options, window.multiTaxonSelect2Options, window.hybridsSelect2Options)) + $('.taxon-concept-multiple-max-2').select2($.extend({}, window.defaultTaxonSelect2Options, window.multiTaxonSelect2Options, window.max2Select2Options)) class AdminInPlaceEditor extends AdminEditor diff --git a/app/assets/javascripts/admin/nomenclature_changes.js.coffee b/app/assets/javascripts/admin/nomenclature_changes.js.coffee index 8fcccb8483..2d3f960964 100644 --- a/app/assets/javascripts/admin/nomenclature_changes.js.coffee +++ b/app/assets/javascripts/admin/nomenclature_changes.js.coffee @@ -50,7 +50,7 @@ $(document).ready -> result.push({id: id, text: names && names[i] + ' ' + name_status}) callback(result) } - window.hybridsSelect2Options = { + window.max2Select2Options = { maximumSelectionSize: 2, formatSelectionTooBig: (limit) -> return 'You can only select ' + limit + ' items' @@ -58,6 +58,7 @@ $(document).ready -> $('.taxon-concept').select2(window.defaultTaxonSelect2Options) $('.taxon-concept-multiple').select2($.extend({}, window.defaultTaxonSelect2Options, window.multiTaxonSelect2Options)) + $('.taxon-concept-multiple-max-2').select2($.extend({}, window.defaultTaxonSelect2Options, window.multiTaxonSelect2Options, window.max2Select2Options)) $('.taxon-concept').on('change', (event) -> return false unless event.val $.when($.ajax( '/admin/taxon_concepts/' + event.val + '.json' ) ).then(( data, textStatus, jqXHR ) => From f63804870919bf8ae4d973081096328ea1317494 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 4 Apr 2016 15:13:46 +0200 Subject: [PATCH 195/365] replaced typeahead taxon concept selectors with select2 --- .../admin/admin_in_place_editor.js.coffee | 2 - app/models/taxon_concept.rb | 42 +++++++++---------- app/views/admin/taxon_concepts/_form.html.erb | 13 +++++- .../taxon_concepts/_hybrid_form.html.erb | 20 ++++----- .../taxon_concepts/_n_name_form.html.erb | 13 +++++- .../taxon_concepts/_synonym_form.html.erb | 11 ++++- app/views/admin/taxon_concepts/new.js.erb | 1 - .../admin/taxon_concepts/new_hybrid.js.erb | 2 +- .../admin/taxon_concepts/new_n_name.js.erb | 2 +- .../admin/taxon_concepts/new_synonym.js.erb | 2 +- spec/factories/taxon_concepts.rb | 1 - 11 files changed, 65 insertions(+), 44 deletions(-) diff --git a/app/assets/javascripts/admin/admin_in_place_editor.js.coffee b/app/assets/javascripts/admin/admin_in_place_editor.js.coffee index 66a562461f..4ce0bd0d48 100644 --- a/app/assets/javascripts/admin/admin_in_place_editor.js.coffee +++ b/app/assets/javascripts/admin/admin_in_place_editor.js.coffee @@ -211,7 +211,6 @@ class TaxonConceptsEditor extends AdminEditor initModals: () -> super @saveAndReopen = false - @initTaxonConceptTypeaheads() $('.distributions-list > a').popover({}); alertSuccess: (txt) -> @@ -237,7 +236,6 @@ class ListingChangesEditor extends AdminEditor event.field.find('.distribution').select2({ placeholder: 'Select countries' }) - @_initTaxonConceptTypeaheads(event.field.find('.typeahead')) ) initDistributionSelectors: () -> diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index 06f018bb00..e79ba96e04 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -45,16 +45,15 @@ class TaxonConcept < ActiveRecord::Base attr_accessible :parent_id, :taxonomy_id, :rank_id, :parent_id, :author_year, :taxon_name_id, :taxonomic_position, :legacy_id, :legacy_type, :full_name, :name_status, - :parent_scientific_name, :accepted_scientific_name, - :hybrid_parent_scientific_name, :other_hybrid_parent_scientific_name, - :tag_list, :legacy_trade_code, :hybrid_parent_ids, - :accepted_name_ids, :accepted_names_for_trade_name_ids, + :tag_list, :legacy_trade_code, :hybrid_parents_ids, + :accepted_names_ids, :accepted_names_for_trade_name_ids, :nomenclature_note_en, :nomenclature_note_es, :nomenclature_note_fr, :created_by_id, :updated_by_id, :dependents_updated_at - attr_writer :parent_scientific_name - attr_accessor :accepted_scientific_name, :hybrid_parent_scientific_name, - :other_hybrid_parent_scientific_name + attr_writer :accepted_names_ids, + :accepted_names_for_trade_name_ids, + :hybrid_parents_ids + acts_as_taggable serialize :data, ActiveRecord::Coders::Hstore @@ -194,22 +193,11 @@ class TaxonConcept < ActiveRecord::Base before_validation :check_taxon_name_exists, :if => lambda { |tc| tc.full_name } - before_validation :check_parent_taxon_concept_exists, - :if => lambda { |tc| tc.parent_scientific_name } before_validation :ensure_taxonomic_position translates :nomenclature_note - after_save :check_accepted_taxon_concept_exists, - :if => lambda { |tc| tc.is_synonym? && tc.accepted_scientific_name } - - after_save :check_hybrid_parent_taxon_concept_exists, - :if => lambda { |tc| tc.is_hybrid? && tc.hybrid_parent_scientific_name } - - after_save :check_other_hybrid_parent_taxon_concept_exists, - :if => lambda { |tc| tc.is_hybrid? && tc.other_hybrid_parent_scientific_name } - scope :at_parent_ranks, lambda{ |rank| joins_sql = <<-SQL INNER JOIN ranks ON ranks.id = taxon_concepts.rank_id @@ -334,11 +322,6 @@ def eu_listed listing['eu_status'] == 'LISTED' && listing['eu_level_of_listing'] end - def parent_scientific_name - @parent_scientific_name || - parent && parent.full_name - end - def standard_taxon_concept_references TaxonConceptReference.from('api_taxon_references_view taxon_concept_references'). where(taxon_concept_id: self.id, is_standard: true) @@ -368,6 +351,19 @@ def rebuild_taxonomy?(params) Rank.in_range(Rank::VARIETY, Rank::GENUS).include?(rank.name) end + def accepted_names_ids + @accepted_names_ids || accepted_names.pluck(:id) + end + + def accepted_names_for_trade_name_ids + @accepted_names_for_trade_name_ids || + accepted_names_for_trade_name.pluck(:id) + end + + def hybrid_parents_ids + @hybrid_parents_ids || hybrid_parents.pluck(:id) + end + def rebuild_relationships(taxa_ids) if ['S', 'T', 'H'].include? name_status new_taxa, removed_taxa = init_accepted_taxa(taxa_ids) diff --git a/app/views/admin/taxon_concepts/_form.html.erb b/app/views/admin/taxon_concepts/_form.html.erb index abcaac9ffc..75ef530b4a 100644 --- a/app/views/admin/taxon_concepts/_form.html.erb +++ b/app/views/admin/taxon_concepts/_form.html.erb @@ -14,7 +14,18 @@ options_from_collection_for_select(@ranks, :id, :name, @taxon_concept && @taxon_concept.rank_id) %> - <%= name_status_related_fields(f, @taxon_concept.name_status) %> +
+ +
+ <%= f.text_field :parent_id, { + class: 'taxon-concept parent-taxon', + :'data-name' => @taxon_concept.parent.try(:full_name), + :'data-name-status' => @taxon_concept.parent.try(:name_status), + :'data-name-status-filter' => ['A'].to_json, + :'data-rank-scope' => 'parent' + } %> +
+
<%= f.text_field :full_name %> diff --git a/app/views/admin/taxon_concepts/_hybrid_form.html.erb b/app/views/admin/taxon_concepts/_hybrid_form.html.erb index d2e632e01a..0b100e716d 100644 --- a/app/views/admin/taxon_concepts/_hybrid_form.html.erb +++ b/app/views/admin/taxon_concepts/_hybrid_form.html.erb @@ -20,16 +20,16 @@ %>
- - <%= f.text_field :hybrid_parent_scientific_name, :class => 'typeahead', - "data-rank-scope" => 'ancestors' - %> -
-
- - <%= f.text_field :other_hybrid_parent_scientific_name, :class => 'typeahead', - "data-rank-scope" => 'ancestors' - %> + +
+ <%= f.text_field :hybrid_parents_ids, { + class: 'taxon-concept-multiple-max-2', + :'data-name-status-filter' => ['A'].to_json, + :'data-name-status' => 'A', + :'data-rank-scope' => 'self_and_ancestors', + :'data-name' => TaxonConcept.where(id: @hybrid.hybrid_parents_ids).pluck(:full_name).to_s + } %> +
diff --git a/app/views/admin/taxon_concepts/_n_name_form.html.erb b/app/views/admin/taxon_concepts/_n_name_form.html.erb index 684f21cf4e..c4070ee5b7 100644 --- a/app/views/admin/taxon_concepts/_n_name_form.html.erb +++ b/app/views/admin/taxon_concepts/_n_name_form.html.erb @@ -14,7 +14,18 @@ options_from_collection_for_select(@ranks, :id, :name, @n_name && @n_name.rank_id) %>
- <%= name_status_related_fields(f, @n_name.name_status) %> +
+ +
+ <%= f.text_field :parent_id, { + class: 'taxon-concept parent-taxon', + :'data-name' => @n_name.parent.try(:full_name), + :'data-name-status' => @n_name.parent.try(:name_status), + :'data-name-status-filter' => ['A', 'N'].to_json, + :'data-rank-scope' => 'parent' + } %> +
+
<%= f.text_field :full_name %> diff --git a/app/views/admin/taxon_concepts/_synonym_form.html.erb b/app/views/admin/taxon_concepts/_synonym_form.html.erb index 743d744acd..bd4e879240 100644 --- a/app/views/admin/taxon_concepts/_synonym_form.html.erb +++ b/app/views/admin/taxon_concepts/_synonym_form.html.erb @@ -20,8 +20,15 @@ %>
- - <%= f.text_field :accepted_scientific_name, :class => 'typeahead' %> + +
+ <%= f.text_field :accepted_names_ids, { + class: 'taxon-concept-multiple', + :'data-name-status-filter' => ['A'].to_json, + :'data-name-status' => 'A', + :'data-name' => TaxonConcept.where(id: @synonym.accepted_names_ids).pluck(:full_name).to_s + } %> +
diff --git a/app/views/admin/taxon_concepts/new.js.erb b/app/views/admin/taxon_concepts/new.js.erb index e580c3a837..8046822aeb 100644 --- a/app/views/admin/taxon_concepts/new.js.erb +++ b/app/views/admin/taxon_concepts/new.js.erb @@ -3,5 +3,4 @@ form.find('.tags').select2(); $('#admin-new-<%= controller_name.singularize %>-form').html(form); $('#new-<%= controller_name.singularize %>').modal('show'); -window.adminEditor.initTaxonConceptTypeaheads(); window.adminEditor.initSelect2Inputs(); diff --git a/app/views/admin/taxon_concepts/new_hybrid.js.erb b/app/views/admin/taxon_concepts/new_hybrid.js.erb index 83c918f58e..6fc7471999 100644 --- a/app/views/admin/taxon_concepts/new_hybrid.js.erb +++ b/app/views/admin/taxon_concepts/new_hybrid.js.erb @@ -1,4 +1,4 @@ $('#admin-new-taxon_concept_hybrid-form').html( "<%= escape_javascript(render('hybrid_form')) %>"); $('#new-taxon_concept_hybrid').modal('show'); -window.adminEditor.initTaxonConceptTypeaheads(); +window.adminEditor.initSelect2Inputs(); diff --git a/app/views/admin/taxon_concepts/new_n_name.js.erb b/app/views/admin/taxon_concepts/new_n_name.js.erb index 4fcb5ec593..60e7dc45de 100644 --- a/app/views/admin/taxon_concepts/new_n_name.js.erb +++ b/app/views/admin/taxon_concepts/new_n_name.js.erb @@ -1,4 +1,4 @@ $('#admin-new-taxon_concept_n_name-form').html( "<%= escape_javascript(render('n_name_form')) %>"); $('#new-taxon_concept_n_name').modal('show'); -window.adminEditor.initTaxonConceptTypeaheads(); +window.adminEditor.initSelect2Inputs(); diff --git a/app/views/admin/taxon_concepts/new_synonym.js.erb b/app/views/admin/taxon_concepts/new_synonym.js.erb index 464cd28d72..3688d08d05 100644 --- a/app/views/admin/taxon_concepts/new_synonym.js.erb +++ b/app/views/admin/taxon_concepts/new_synonym.js.erb @@ -1,4 +1,4 @@ $('#admin-new-taxon_concept_synonym-form').html( "<%= escape_javascript(render('synonym_form')) %>"); $('#new-taxon_concept_synonym').modal('show'); -window.adminEditor.initTaxonConceptTypeaheads(); +window.adminEditor.initSelect2Inputs(); diff --git a/spec/factories/taxon_concepts.rb b/spec/factories/taxon_concepts.rb index 3fec4abbc6..6d0049a659 100644 --- a/spec/factories/taxon_concepts.rb +++ b/spec/factories/taxon_concepts.rb @@ -7,7 +7,6 @@ name_status 'A' data {} listing {} - parent_scientific_name '' before(:create){ |tc| if tc.parent.nil? && tc.name_status == 'A' && tc.rank.try(:name) != 'KINGDOM' tc.parent = create( From 121fc39031ca70714f7d6f5db1f1fd74451d29c0 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 4 Apr 2016 15:14:23 +0200 Subject: [PATCH 196/365] removed obsolete logic --- .../admin/admin_in_place_editor.js.coffee | 40 ------------------- 1 file changed, 40 deletions(-) diff --git a/app/assets/javascripts/admin/admin_in_place_editor.js.coffee b/app/assets/javascripts/admin/admin_in_place_editor.js.coffee index 4ce0bd0d48..9f980379ee 100644 --- a/app/assets/javascripts/admin/admin_in_place_editor.js.coffee +++ b/app/assets/javascripts/admin/admin_in_place_editor.js.coffee @@ -47,46 +47,6 @@ class AdminEditor $(alert).insertBefore($('h1')) - initTaxonConceptTypeaheads: () -> - - $('input.typeahead').each (idx) -> - formId = $(@).closest('form').attr('id') - - if formId? - matches = formId.match('^(.+_)?(new|edit)_(.+)$') - prefix = matches[3] - prefix = matches[1] + prefix unless matches[1] == undefined - - taxonomyEl = $('#' + prefix + '_taxonomy_id') - rankEl = $('#' + prefix + '_rank_id') - - #initialize this typeahead - $(@).typeahead - source: (query, process) => - $.get('/admin/taxon_concepts/autocomplete', - { - search_params: { - scientific_name: query, - taxonomy: { - id: taxonomyEl && taxonomyEl.val() || $(@).attr('data-taxonomy-id') - }, - rank: { - id: rankEl && rankEl.val() || $(@).attr('data-rank-id'), - scope: $(@).attr('data-rank-scope') - } - } - limit: 25 - }, (data) => - labels = [] - $.each(data, (i, item) => - label = item.full_name + ' ' + item.rank_name - labels.push(label) - ) - return process(labels) - ) - $().add(taxonomyEl).add(rankEl).change () => - $(@).val(null) - initSearchTypeahead: () -> $('.search-typeahead').typeahead source: (query, process) -> From e3cacddb40805886f0d431cdd9d8b4747d1012a3 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 4 Apr 2016 15:15:04 +0200 Subject: [PATCH 197/365] removed obsolete logic --- app/helpers/admin/taxon_concepts_helper.rb | 64 ---------------------- 1 file changed, 64 deletions(-) delete mode 100644 app/helpers/admin/taxon_concepts_helper.rb diff --git a/app/helpers/admin/taxon_concepts_helper.rb b/app/helpers/admin/taxon_concepts_helper.rb deleted file mode 100644 index 4f61a7f2e2..0000000000 --- a/app/helpers/admin/taxon_concepts_helper.rb +++ /dev/null @@ -1,64 +0,0 @@ -module Admin::TaxonConceptsHelper - - DEFAULT_OPTS = { - klass: 'taxon-concept-multiple', - multiple: 'multiple', - data_name_status: 'A' - } - def fields_opts f, name_status - case name_status - when 'A', 'N' - DEFAULT_OPTS.merge({ - label: 'Parent', - klass: 'taxon-concept parent-taxon', - field_name: :parent_id, - data_name: f.object.parent.try(:full_name), - data_name_status: f.object.parent.try(:name_status), - multiple: '' - }) - when 'S' - DEFAULT_OPTS.merge({ - label: "Accepted names", - field_name: :accepted_name_ids, - data_name: TaxonConcept.fetch_taxons_full_name( - f.object.accepted_name_ids - ).to_s, - }) - when 'T' - DEFAULT_OPTS.merge({ - label: "Accepted names", - field_name: :accepted_names_for_trade_name_ids, - data_name: TaxonConcept.fetch_taxons_full_name( - f.object.accepted_names_for_trade_name_ids - ).to_s, - }) - when 'H' - DEFAULT_OPTS.merge({ - klass: 'hybrids-selection', - label: 'Parents', - field_name: :hybrid_parent_ids, - data_name: TaxonConcept.fetch_taxons_full_name( - f.object.hybrid_parent_ids - ).to_s, - }) - end - end - - def name_status_related_fields f, name_status - generate_input_form(f, fields_opts(f, name_status)) - end - - def generate_input_form(f, opts={}) - content_tag(:div, class: 'control-group') do - concat content_tag(:label, opts[:label]) - concat f.text_field(opts[:field_name], { - :class => opts[:klass], - :'data-name' => opts[:data_name], - :'data-name-status' => 'A', - :'data-name-status-filter' => ['A'].to_json, - :'data-taxonomy-id' => f.object.taxonomy_id, - opts[:multiple] => opts[:multiple] - }) - end - end -end From 4cb9fc0ab378428839799b04463f309c79c747e6 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 4 Apr 2016 15:15:33 +0200 Subject: [PATCH 198/365] added back-end validation for max hybrid parents --- app/models/taxon_concept.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index e79ba96e04..05a3839b2d 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -180,6 +180,8 @@ class TaxonConcept < ActiveRecord::Base ) } validate :parent_is_an_accepted_name, :if => lambda { |tc| tc.parent } + validate :maximum_2_hybrid_parents, + :if => lambda { |tc| tc.name_status == 'H' } validates :taxon_name_id, :presence => true, :unless => lambda { |tc| tc.taxon_name.try(:valid?) } validates :full_name, :uniqueness => { :scope => [:taxonomy_id, :author_year] } @@ -479,6 +481,14 @@ def parent_at_immediately_higher_rank end end + def maximum_2_hybrid_parents + if hybrid_parents_ids.size > 2 + errors.add(:hybrid_parents_ids, "maximum 2 hybrid parents") + return false + end + true + end + def check_taxon_name_exists self.full_name = TaxonConcept.sanitize_full_name(full_name) scientific_name = if is_accepted_name? From 4bc9ffdfedbf23e44cba1e6cdee6c92896094582 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 4 Apr 2016 15:15:58 +0200 Subject: [PATCH 199/365] removed obsolete logic --- app/models/taxon_concept.rb | 53 ------------------------------------- 1 file changed, 53 deletions(-) diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index 05a3839b2d..4f6c606ed4 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -508,59 +508,6 @@ def check_taxon_name_exists true end - def check_hybrid_parent_taxon_concept_exists - check_associated_taxon_concept_exists(:hybrid_parent_scientific_name) do |tc| - inverse_taxon_relationships.create( - :taxon_concept_id => tc.id, - :other_taxon_concept_id => self.id, - :taxon_relationship_type_id => TaxonRelationshipType. - find_by_name(TaxonRelationshipType::HAS_HYBRID).id - ) - end - end - - def check_other_hybrid_parent_taxon_concept_exists - check_associated_taxon_concept_exists(:other_hybrid_parent_scientific_name) do |tc| - inverse_taxon_relationships.create( - :taxon_concept_id => tc.id, - :other_taxon_concept_id => self.id, - :taxon_relationship_type_id => TaxonRelationshipType. - find_by_name(TaxonRelationshipType::HAS_HYBRID).id - ) - end - end - - def check_accepted_taxon_concept_exists - check_associated_taxon_concept_exists(:accepted_scientific_name) do |tc| - inverse_taxon_relationships.create( - taxon_concept_id: tc.id, - other_taxon_concept_id: self.id, - taxon_relationship_type_id: TaxonRelationshipType. - find_by_name(TaxonRelationshipType::HAS_SYNONYM).id - ) - end - end - - def check_parent_taxon_concept_exists - check_associated_taxon_concept_exists(:parent_scientific_name) do |tc| - self.parent_id = tc.id - end - end - - def check_associated_taxon_concept_exists(full_name_attr) - full_name_var = self.instance_variable_get("@#{full_name_attr}") - return true if full_name_var.blank? - tc = TaxonConcept.find_by_full_name_and_name_status(full_name_var, 'A', taxonomy_id) - unless tc - errors.add(full_name_attr, "does not exist") - return true - end - if block_given? - yield(tc) - end - true - end - def self.find_by_full_name_and_name_status(full_name, name_status, taxonomy_id=nil) full_name = TaxonConcept.sanitize_full_name(full_name) res = TaxonConcept. From 29fa471044a1807f05d49030bcbd1816eddb6933 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 4 Apr 2016 15:17:09 +0200 Subject: [PATCH 200/365] prevents from incorrectly initialising species/ssp/var name with just parent provided --- app/models/taxon_concept_observer.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/models/taxon_concept_observer.rb b/app/models/taxon_concept_observer.rb index 9e2bb01e4a..fe5adffec1 100644 --- a/app/models/taxon_concept_observer.rb +++ b/app/models/taxon_concept_observer.rb @@ -8,7 +8,9 @@ def before_validation(taxon_concept) rank_name = taxon_concept.rank.name parent_full_name = taxon_concept.parent.full_name name = taxon_concept.taxon_name && taxon_concept.taxon_name.scientific_name - if [Rank::SPECIES, Rank::SUBSPECIES].include? rank_name + if name.blank? + nil + elsif [Rank::SPECIES, Rank::SUBSPECIES].include?(rank_name) "#{parent_full_name} #{name.downcase}" elsif rank_name == Rank::VARIETY "#{parent_full_name} var. #{name.downcase}" From f7dadf8799d1d275b7e7f5a1f6a2a9febd928766 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 4 Apr 2016 15:17:55 +0200 Subject: [PATCH 201/365] added selector classes to taxonomy and rank selectors --- app/views/admin/taxon_concepts/_form.html.erb | 12 ++++++++++-- app/views/admin/taxon_concepts/_hybrid_form.html.erb | 11 +++++++---- app/views/admin/taxon_concepts/_n_name_form.html.erb | 12 ++++++++++-- .../admin/taxon_concepts/_synonym_form.html.erb | 11 +++++++---- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/app/views/admin/taxon_concepts/_form.html.erb b/app/views/admin/taxon_concepts/_form.html.erb index 75ef530b4a..c2ea4925e3 100644 --- a/app/views/admin/taxon_concepts/_form.html.erb +++ b/app/views/admin/taxon_concepts/_form.html.erb @@ -5,13 +5,21 @@
<%= f.select :taxonomy_id, - options_from_collection_for_select(@taxonomies, :id, :name, @taxon_concept && @taxon_concept.taxonomy_id) + options_from_collection_for_select( + @taxonomies, :id, :name, @taxon_concept && @taxon_concept.taxonomy_id + ), + {}, + {class: 'taxonomy-selector'} %>
<%= f.select :rank_id, - options_from_collection_for_select(@ranks, :id, :name, @taxon_concept && @taxon_concept.rank_id) + options_from_collection_for_select( + @ranks, :id, :name, @taxon_concept && @taxon_concept.rank_id + ), + {}, + {class: 'rank-selector'} %>
diff --git a/app/views/admin/taxon_concepts/_hybrid_form.html.erb b/app/views/admin/taxon_concepts/_hybrid_form.html.erb index 0b100e716d..9e2a7ec927 100644 --- a/app/views/admin/taxon_concepts/_hybrid_form.html.erb +++ b/app/views/admin/taxon_concepts/_hybrid_form.html.erb @@ -7,16 +7,19 @@ <%= f.select :taxonomy_id, options_from_collection_for_select( @taxonomies, :id, :name, @hybrid && @hybrid.taxonomy_id - ) + ), + {}, + {class: 'taxonomy-selector'} %>
<%= f.select :rank_id, options_from_collection_for_select( - @ranks, :id, :name, - @hybrid && @hybrid.rank_id - ) + @ranks, :id, :name, @hybrid && @hybrid.rank_id + ), + {}, + {class: 'rank-selector'} %>
diff --git a/app/views/admin/taxon_concepts/_n_name_form.html.erb b/app/views/admin/taxon_concepts/_n_name_form.html.erb index c4070ee5b7..969a156fe7 100644 --- a/app/views/admin/taxon_concepts/_n_name_form.html.erb +++ b/app/views/admin/taxon_concepts/_n_name_form.html.erb @@ -5,13 +5,21 @@
<%= f.select :taxonomy_id, - options_from_collection_for_select(@taxonomies, :id, :name, @n_name && @n_name.taxonomy_id) + options_from_collection_for_select( + @taxonomies, :id, :name, @n_name && @n_name.taxonomy_id + ), + {}, + {class: 'taxonomy-selector'} %>
<%= f.select :rank_id, - options_from_collection_for_select(@ranks, :id, :name, @n_name && @n_name.rank_id) + options_from_collection_for_select( + @ranks, :id, :name, @n_name && @n_name.rank_id + ), + {}, + {class: 'rank-selector'} %>
diff --git a/app/views/admin/taxon_concepts/_synonym_form.html.erb b/app/views/admin/taxon_concepts/_synonym_form.html.erb index bd4e879240..93f7a57db3 100644 --- a/app/views/admin/taxon_concepts/_synonym_form.html.erb +++ b/app/views/admin/taxon_concepts/_synonym_form.html.erb @@ -7,16 +7,19 @@ <%= f.select :taxonomy_id, options_from_collection_for_select( @taxonomies, :id, :name, @synonym && @synonym.taxonomy_id - ) + ), + {}, + {class: 'taxonomy-selector'} %>
<%= f.select :rank_id, options_from_collection_for_select( - @ranks, :id, :name, - @synonym && @synonym.rank_id - ) + @ranks, :id, :name, @synonym && @synonym.rank_id + ), + {}, + {class: 'rank-selector'} %>
From 5451e2f378d65bd40476bcd43109cb4327c7fabd Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 4 Apr 2016 15:53:15 +0200 Subject: [PATCH 202/365] fixed exception when primary output is nil --- app/models/nomenclature_change/status_to_accepted.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/nomenclature_change/status_to_accepted.rb b/app/models/nomenclature_change/status_to_accepted.rb index fc505b7144..6030ac7fe5 100644 --- a/app/models/nomenclature_change/status_to_accepted.rb +++ b/app/models/nomenclature_change/status_to_accepted.rb @@ -40,7 +40,7 @@ def set_output_name_status end def set_output_rank_id - return true unless primary_output.new_rank_id.nil? + return true if primary_output && primary_output.new_rank_id.present? primary_output && primary_output.taxon_concept && primary_output.new_rank_id = primary_output.taxon_concept.rank_id end From 1239c435a8fbf70ce0e12b24534a47eeb319e445 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 4 Apr 2016 16:53:51 +0200 Subject: [PATCH 203/365] clear modal window forms when closing --- .../javascripts/admin/admin_in_place_editor.js.coffee | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/app/assets/javascripts/admin/admin_in_place_editor.js.coffee b/app/assets/javascripts/admin/admin_in_place_editor.js.coffee index 9f980379ee..0a88515405 100644 --- a/app/assets/javascripts/admin/admin_in_place_editor.js.coffee +++ b/app/assets/javascripts/admin/admin_in_place_editor.js.coffee @@ -21,14 +21,17 @@ class AdminEditor $('.modal .modal-footer .save-button').click () -> $(@).closest('.modal').find('form').submit() $('.modal').on 'hidden', () => - @clearModalForm($(@)) + $('.modal.hide.fade').each((idx, element) => + @clearModalForm($(element)) + ) @initModals() @initSearchTypeahead() $("[rel='tooltip']").tooltip() - clearModalForm: (modal) -> - form = modal.find('form') - form[0].reset() if form.length > 0 + clearModalForm: (modalElement) -> + modalElement.find('form').each(() -> + @reset() + ) initForm: () -> $(".datepicker").datepicker From 7e8846af0a0988131e785a359bcd856a33991eb1 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 4 Apr 2016 17:18:24 +0200 Subject: [PATCH 204/365] removed obsolete status selector manipulation logic --- .../admin/nomenclature_changes.js.coffee | 16 ---------------- .../status_swap/primary_output.html.erb | 2 +- .../status_to_accepted/primary_output.html.erb | 2 +- .../status_to_synonym/primary_output.html.erb | 2 +- 4 files changed, 3 insertions(+), 19 deletions(-) diff --git a/app/assets/javascripts/admin/nomenclature_changes.js.coffee b/app/assets/javascripts/admin/nomenclature_changes.js.coffee index 2d3f960964..441babcd29 100644 --- a/app/assets/javascripts/admin/nomenclature_changes.js.coffee +++ b/app/assets/javascripts/admin/nomenclature_changes.js.coffee @@ -64,22 +64,6 @@ $(document).ready -> $.when($.ajax( '/admin/taxon_concepts/' + event.val + '.json' ) ).then(( data, textStatus, jqXHR ) => $(this).attr('data-name', data.full_name) $(this).attr('data-name-status', data.name_status) - if $(this).hasClass('status-change') - # reload the name status dropdown based on selection - statusDropdown = $(this).closest('.fields').find('select') - statusFrom = data.name_status - $(statusDropdown).find('option').attr('disabled', true) - statusMap = - 'A': ['S'] - 'N': ['A', 'S'] - 'S': ['A'] - 'T': ['A', 'S'] - $(statusDropdown).find('option[value=' + statusFrom + ']').removeAttr('selected') - defaultStatus = statusMap[statusFrom][0] - $(statusDropdown).find('option[value=' + defaultStatus + ']').attr('selected', true) - $.each(statusMap[statusFrom], (i, status) -> - $(statusDropdown).find('option[value=' + status + ']').removeAttr('disabled') - ) ) if $(this).hasClass('clear-others') # reset selection in other taxon concept select2 instances diff --git a/app/views/admin/nomenclature_changes/status_swap/primary_output.html.erb b/app/views/admin/nomenclature_changes/status_swap/primary_output.html.erb index 4c6607e04a..e444b6dea0 100644 --- a/app/views/admin/nomenclature_changes/status_swap/primary_output.html.erb +++ b/app/views/admin/nomenclature_changes/status_swap/primary_output.html.erb @@ -6,7 +6,7 @@
<%= ff.text_field :taxon_concept_id, { - :class => 'taxon-concept status-change', + :class => 'taxon-concept', :'data-name' => ff.object.taxon_concept.try(:full_name), :'data-name-status' => ff.object.taxon_concept.try(:name_status), :'data-name-status-filter' => ['A'].to_json, diff --git a/app/views/admin/nomenclature_changes/status_to_accepted/primary_output.html.erb b/app/views/admin/nomenclature_changes/status_to_accepted/primary_output.html.erb index b0243de6bb..d463083c43 100644 --- a/app/views/admin/nomenclature_changes/status_to_accepted/primary_output.html.erb +++ b/app/views/admin/nomenclature_changes/status_to_accepted/primary_output.html.erb @@ -6,7 +6,7 @@
<%= ff.text_field :taxon_concept_id, { - :class => 'taxon-concept status-change', + :class => 'taxon-concept', :'data-name' => ff.object.taxon_concept.try(:full_name), :'data-name-status' => ff.object.taxon_concept.try(:name_status), :'data-name-status-filter' => ['N', 'T'].to_json, diff --git a/app/views/admin/nomenclature_changes/status_to_synonym/primary_output.html.erb b/app/views/admin/nomenclature_changes/status_to_synonym/primary_output.html.erb index 6aae4d8279..2d784c66ea 100644 --- a/app/views/admin/nomenclature_changes/status_to_synonym/primary_output.html.erb +++ b/app/views/admin/nomenclature_changes/status_to_synonym/primary_output.html.erb @@ -6,7 +6,7 @@
<%= ff.text_field :taxon_concept_id, { - :class => 'taxon-concept status-change', + :class => 'taxon-concept', :'data-name' => ff.object.taxon_concept.try(:full_name), :'data-name-status' => ff.object.taxon_concept.try(:name_status), :'data-name-status-filter' => ['N', 'T'].to_json, From c62b622f9d59fae35cd6fb5efe516577f08adf62 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 4 Apr 2016 17:19:05 +0200 Subject: [PATCH 205/365] prevent errors when new_output_rank not set --- .../admin/nomenclature_changes/build/_new_rank.html.erb | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/views/admin/nomenclature_changes/build/_new_rank.html.erb b/app/views/admin/nomenclature_changes/build/_new_rank.html.erb index d079680e0d..bdd4b579ff 100644 --- a/app/views/admin/nomenclature_changes/build/_new_rank.html.erb +++ b/app/views/admin/nomenclature_changes/build/_new_rank.html.erb @@ -2,8 +2,11 @@
<%= ff.select :new_rank_id, - options_from_collection_for_select(@ranks, :id, :name, ff.object.new_rank_id || f.object.new_output_rank.id), - { class: 'new-rank' } + options_from_collection_for_select( + @ranks, :id, :name, ff.object.new_rank_id || f.object.new_output_rank.try(:id) + ), + {}, + { class: 'rank-selector' } %>
From 6d0f142dfff8b8b2b728903fbea36eb11319bf25 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Mon, 4 Apr 2016 17:22:02 +0200 Subject: [PATCH 206/365] moved new rank selector before new parent selector, as the rank selection affects the potential parents retrieved --- app/views/admin/nomenclature_changes/lump/outputs.html.erb | 2 +- app/views/admin/nomenclature_changes/split/outputs.html.erb | 2 +- .../nomenclature_changes/status_swap/secondary_output.html.erb | 2 +- .../status_to_accepted/primary_output.html.erb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/admin/nomenclature_changes/lump/outputs.html.erb b/app/views/admin/nomenclature_changes/lump/outputs.html.erb index 3140759801..fcbe85f417 100644 --- a/app/views/admin/nomenclature_changes/lump/outputs.html.erb +++ b/app/views/admin/nomenclature_changes/lump/outputs.html.erb @@ -26,6 +26,7 @@ } %>
+ <%= render 'admin/nomenclature_changes/build/new_rank', ff: ff, f: f %> <%= render 'admin/nomenclature_changes/build/new_parent', :ff => ff %>
@@ -46,6 +47,5 @@
- <%= render 'admin/nomenclature_changes/build/new_rank', ff: ff, f: f %> <% end %> <% end %> diff --git a/app/views/admin/nomenclature_changes/split/outputs.html.erb b/app/views/admin/nomenclature_changes/split/outputs.html.erb index 7368c1346e..b329630b3e 100644 --- a/app/views/admin/nomenclature_changes/split/outputs.html.erb +++ b/app/views/admin/nomenclature_changes/split/outputs.html.erb @@ -21,6 +21,7 @@ } %>
+ <%= render 'admin/nomenclature_changes/build/new_rank', ff: ff, f: f %> <%= render 'admin/nomenclature_changes/build/new_parent', :ff => ff %>
@@ -41,7 +42,6 @@
- <%= render 'admin/nomenclature_changes/build/new_rank', ff: ff, f: f %> <% end %>
diff --git a/app/views/admin/nomenclature_changes/status_swap/secondary_output.html.erb b/app/views/admin/nomenclature_changes/status_swap/secondary_output.html.erb index 660199227d..ebfb7ad062 100644 --- a/app/views/admin/nomenclature_changes/status_swap/secondary_output.html.erb +++ b/app/views/admin/nomenclature_changes/status_swap/secondary_output.html.erb @@ -17,7 +17,7 @@ <%= ff.hidden_field :new_name_status %> - <%= render 'admin/nomenclature_changes/build/new_parent', :ff => ff %> <%= render 'admin/nomenclature_changes/build/new_rank', ff: ff, f: f %> + <%= render 'admin/nomenclature_changes/build/new_parent', :ff => ff %> <% end %> <% end %> \ No newline at end of file diff --git a/app/views/admin/nomenclature_changes/status_to_accepted/primary_output.html.erb b/app/views/admin/nomenclature_changes/status_to_accepted/primary_output.html.erb index d463083c43..5dbcd5f103 100644 --- a/app/views/admin/nomenclature_changes/status_to_accepted/primary_output.html.erb +++ b/app/views/admin/nomenclature_changes/status_to_accepted/primary_output.html.erb @@ -14,7 +14,7 @@ } %> - <%= render 'admin/nomenclature_changes/build/new_parent', :ff => ff %> <%= render 'admin/nomenclature_changes/build/new_rank', ff: ff, f: f %> + <%= render 'admin/nomenclature_changes/build/new_parent', :ff => ff %> <% end %> <% end %> \ No newline at end of file From 21f15cabf357d86d4331fb7b53ecc65b26ac9bfa Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 5 Apr 2016 17:04:25 +0200 Subject: [PATCH 207/365] added parent presence validation for N taxa, relaxed name compatibility validation --- app/models/taxon_concept.rb | 4 ++-- .../status_to_accepted_controller_spec.rb | 2 +- spec/factories/taxon_concepts.rb | 2 +- spec/models/species/trade_name_prefix_matcher_spec.rb | 7 +++++-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/app/models/taxon_concept.rb b/app/models/taxon_concept.rb index 4f6c606ed4..79dc5bf6ee 100644 --- a/app/models/taxon_concept.rb +++ b/app/models/taxon_concept.rb @@ -170,13 +170,13 @@ class TaxonConcept < ActiveRecord::Base validates :rank_id, :presence => true validates :name_status, :presence => true validates :parent_id, presence: true, - if: lambda { |tc| tc.name_status == 'A' && tc.rank.try(:name) != 'KINGDOM' } + if: lambda { |tc| ['A', 'N'].include?(tc.name_status) && tc.rank.try(:name) != 'KINGDOM' } validate :parent_in_same_taxonomy, :if => lambda { |tc| tc.parent } validate :parent_at_immediately_higher_rank, :if => lambda { |tc| tc.parent && tc.name_status == 'A' } validate :parent_name_compatible, :if => lambda { |tc| tc.parent && tc.rank && tc.full_name && ( - ['A', 'N'].include?(tc.name_status) || tc.name_status.blank? + tc.name_status == 'A' || tc.name_status.blank? ) } validate :parent_is_an_accepted_name, :if => lambda { |tc| tc.parent } diff --git a/spec/controllers/admin/nomenclature_changes/status_to_accepted_controller_spec.rb b/spec/controllers/admin/nomenclature_changes/status_to_accepted_controller_spec.rb index 51495d9f69..1dd40ccb41 100644 --- a/spec/controllers/admin/nomenclature_changes/status_to_accepted_controller_spec.rb +++ b/spec/controllers/admin/nomenclature_changes/status_to_accepted_controller_spec.rb @@ -43,7 +43,7 @@ put :update, nomenclature_change_status_to_accepted: { primary_output_attributes: { taxon_concept_id: create_cites_eu_species( - name_status: 'N', + name_status: 'T', taxon_name: create(:taxon_name, scientific_name: 'Patagonus miserabilis') ).id, new_parent_id: create_cites_eu_genus( diff --git a/spec/factories/taxon_concepts.rb b/spec/factories/taxon_concepts.rb index 6d0049a659..10c33b63dd 100644 --- a/spec/factories/taxon_concepts.rb +++ b/spec/factories/taxon_concepts.rb @@ -8,7 +8,7 @@ data {} listing {} before(:create){ |tc| - if tc.parent.nil? && tc.name_status == 'A' && tc.rank.try(:name) != 'KINGDOM' + if tc.parent.nil? && ['A', 'N'].include?(tc.name_status) && tc.rank.try(:name) != 'KINGDOM' tc.parent = create( :taxon_concept, taxonomy: tc.taxonomy, diff --git a/spec/models/species/trade_name_prefix_matcher_spec.rb b/spec/models/species/trade_name_prefix_matcher_spec.rb index e54afeaa4f..d5acebfef5 100644 --- a/spec/models/species/trade_name_prefix_matcher_spec.rb +++ b/spec/models/species/trade_name_prefix_matcher_spec.rb @@ -9,8 +9,11 @@ :name_status => 'T' ) @status_N_species = create_cites_eu_species( - :taxon_name => create(:taxon_name, :scientific_name => 'Vidua paradisaea'), - :name_status => 'N' + taxon_name: create(:taxon_name, scientific_name: 'Paradisaea'), + parent: create_cites_eu_genus( + taxon_name: create(:taxon_name, scientific_name: 'Vidua') + ), + name_status: 'N' ) create(:taxon_relationship, :taxon_concept => @accepted_name, From 572fe63cedcc60eeee14be2352ac55fb52e342a3 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Wed, 6 Apr 2016 11:32:04 +0100 Subject: [PATCH 208/365] Add uniqueness to already existing index on taxon_concept_references and remove the obsolete one --- ...nique_index_on_taxon_concept_references.rb | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 db/migrate/20160406101826_change_unique_index_on_taxon_concept_references.rb diff --git a/db/migrate/20160406101826_change_unique_index_on_taxon_concept_references.rb b/db/migrate/20160406101826_change_unique_index_on_taxon_concept_references.rb new file mode 100644 index 0000000000..49407338a0 --- /dev/null +++ b/db/migrate/20160406101826_change_unique_index_on_taxon_concept_references.rb @@ -0,0 +1,21 @@ +class ChangeUniqueIndexOnTaxonConceptReferences < ActiveRecord::Migration + def up + remove_index "taxon_concept_references", + name: "index_taxon_concept_references_on_tc_id_is_std_is_cascaded" + + add_index "taxon_concept_references", ["taxon_concept_id", "reference_id", "is_standard", "is_cascaded"], name: "index_taxon_concept_references_on_tc_id_is_std_is_cascaded", unique: true + + remove_index "taxon_concept_references", + name: "index_taxon_concept_references_on_taxon_concept_id_and_ref_id" + end + + def down + remove_index "taxon_concept_references", + name: "index_taxon_concept_references_on_tc_id_is_std_is_cascaded" + + add_index "taxon_concept_references", ["taxon_concept_id", "reference_id", "is_standard", "is_cascaded"], name: "index_taxon_concept_references_on_tc_id_is_std_is_cascaded" + + add_index "taxon_concept_references", ["taxon_concept_id", "reference_id"], + name: "index_taxon_concept_references_on_taxon_concept_id_and_ref_id" + end +end From 3cc7be293e29e9285cd460ca68be0156c650f289 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Wed, 6 Apr 2016 16:17:16 +0100 Subject: [PATCH 209/365] If an instance of distribution has no tags, this takes priority --- .../reassignment_transfer_processor.rb | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/app/models/nomenclature_change/reassignment_transfer_processor.rb b/app/models/nomenclature_change/reassignment_transfer_processor.rb index ecf6e3b4ae..83f01c1c91 100644 --- a/app/models/nomenclature_change/reassignment_transfer_processor.rb +++ b/app/models/nomenclature_change/reassignment_transfer_processor.rb @@ -81,15 +81,17 @@ def transfer_distribution_references(reassigned_object, reassignable) end def transfer_distribution_taggings(reassigned_object, reassignable) - return if reassignable.taggings.count == 0 - taggings_to_transfer = reassignable.taggings - if reassigned_object.taggings.count > 0 - taggings_to_transfer = taggings_to_transfer. - where( - 'tag_id NOT IN (?)', - reassigned_object.taggings.select(:tag_id).map(&:tag_id) - ) + if reassignable.taggings.count == 0 + reassigned_object.taggings.destroy_all if reassigned_object.taggings.count > 0 + return + elsif reassigned_object.taggings.count == 0 + return end + taggings_to_transfer = reassignable.taggings. + where( + 'tag_id NOT IN (?)', + reassigned_object.taggings.select(:tag_id).map(&:tag_id) + ) taggings_to_transfer.update_all(taggable_id: reassigned_object.id) end From 5f20594e89a9f540290d6dae459d244621d73029 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Wed, 6 Apr 2016 16:17:38 +0100 Subject: [PATCH 210/365] Manually normalise all empty internal_notes to nil --- ...1_set_distributions_empty_internal_notes_to_nil.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 db/migrate/20160406150331_set_distributions_empty_internal_notes_to_nil.rb diff --git a/db/migrate/20160406150331_set_distributions_empty_internal_notes_to_nil.rb b/db/migrate/20160406150331_set_distributions_empty_internal_notes_to_nil.rb new file mode 100644 index 0000000000..75d79e59d2 --- /dev/null +++ b/db/migrate/20160406150331_set_distributions_empty_internal_notes_to_nil.rb @@ -0,0 +1,11 @@ +class SetDistributionsEmptyInternalNotesToNil < ActiveRecord::Migration + def change + ActiveRecord::Base.connection.execute( + <<-SQL + UPDATE distributions + SET internal_notes=NULL + WHERE internal_notes='' + SQL + ) + end +end From 7d4096737426a4e3e8070f3bd5003366ac1e1673 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Wed, 6 Apr 2016 16:18:06 +0100 Subject: [PATCH 211/365] Add module to be used when we want to normalise empty values before save --- config/initializers/normalise_blank_values.rb | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 config/initializers/normalise_blank_values.rb diff --git a/config/initializers/normalise_blank_values.rb b/config/initializers/normalise_blank_values.rb new file mode 100644 index 0000000000..38f3ad99e6 --- /dev/null +++ b/config/initializers/normalise_blank_values.rb @@ -0,0 +1,21 @@ +module NormaliseBlankValues extend ActiveSupport::Concern + + def self.included(base) + base.extend ClassMethods + end + + def normalise_blank_values + attributes.each do |column, value| + self[column].present? || self[column] = nil + end + end + + module ClassMethods + def normalise_blank_values + before_save :normalise_blank_values + end + end + +end + +ActiveRecord::Base.send(:include, NormaliseBlankValues) From 426a5acc6d2cec982967a76bf44a04115c897dbd Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Wed, 6 Apr 2016 16:18:33 +0100 Subject: [PATCH 212/365] Add empty values normaliser to distribution --- app/models/distribution.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/models/distribution.rb b/app/models/distribution.rb index f26d3554ed..9532e8ba52 100644 --- a/app/models/distribution.rb +++ b/app/models/distribution.rb @@ -18,6 +18,8 @@ class Distribution < ActiveRecord::Base :references_attributes, :internal_notes, :created_by_id, :updated_by_id acts_as_taggable + normalise_blank_values + belongs_to :geo_entity belongs_to :taxon_concept has_many :distribution_references, :dependent => :destroy From 259650e189aeb3e95b779fa97ff4d98d22ba1ce7 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Wed, 6 Apr 2016 17:08:49 +0100 Subject: [PATCH 213/365] Apply same behaviour for copy_processor --- .../reassignment_copy_processor.rb | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/app/models/nomenclature_change/reassignment_copy_processor.rb b/app/models/nomenclature_change/reassignment_copy_processor.rb index b306c3a669..52b62933ce 100644 --- a/app/models/nomenclature_change/reassignment_copy_processor.rb +++ b/app/models/nomenclature_change/reassignment_copy_processor.rb @@ -66,11 +66,23 @@ def build_distribution_associations(reassignable, copied_object) }).first || copied_object.distribution_references.build(distr_ref.comparison_attributes) end # taggings + copy_distribution_taggings(reassignable, copied_object) + end + end + + def copy_distribution_taggings(reassignable, copied_object) + if reassignable.taggings.count == 0 + copied_object.taggings.destroy_all if copied_object.taggings.count > 0 + return + elsif copied_object.taggings.count == 0 + return + end + reassignable.taggings.each do |tagging| !copied_object.new_record? && tagging.duplicates({ taggable_id: copied_object.id }).first || copied_object.taggings.build(tagging.comparison_attributes) - end + end def build_listing_change_associations(reassignable, copied_object) From ee15d164a7d816cb953635485a9f05af646b3648 Mon Sep 17 00:00:00 2001 From: Ferdinando Primerano Date: Wed, 6 Apr 2016 17:08:55 +0100 Subject: [PATCH 214/365] Add some tests --- .../reassignment_copy_processor_spec.rb | 4 +- ...bution_reassignments_processor_examples.rb | 43 ++++++++++++++++++- 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/spec/models/nomenclature_change/reassignment_copy_processor_spec.rb b/spec/models/nomenclature_change/reassignment_copy_processor_spec.rb index 4bf6d34a92..d09a9c16d2 100644 --- a/spec/models/nomenclature_change/reassignment_copy_processor_spec.rb +++ b/spec/models/nomenclature_change/reassignment_copy_processor_spec.rb @@ -19,7 +19,7 @@ end context "when distribution" do include_context 'distribution_reassignments_processor_examples' - specify{ expect(input_species.distributions.count).to eq(2) } + specify{ expect(input_species.distributions.count).to eq(4) } end context "when legislation" do include_context 'legislation_reassignments_processor_examples' @@ -39,4 +39,4 @@ include_context 'shipment_reassignments_processor_examples' end end -end \ No newline at end of file +end diff --git a/spec/models/nomenclature_change/shared/distribution_reassignments_processor_examples.rb b/spec/models/nomenclature_change/shared/distribution_reassignments_processor_examples.rb index fa7ac4e14e..06e968a5fe 100644 --- a/spec/models/nomenclature_change/shared/distribution_reassignments_processor_examples.rb +++ b/spec/models/nomenclature_change/shared/distribution_reassignments_processor_examples.rb @@ -18,12 +18,38 @@ iso_code2: 'PL' ) } + let(:italy){ + create( + :geo_entity, + geo_entity_type_id: country_geo_entity_type.id, + iso_code2: 'IT' + ) + } + let(:united_kingdom){ + create( + :geo_entity, + geo_entity_type_id: country_geo_entity_type.id, + iso_code2: 'UK' + ) + } before(:each) do original_d = create( :distribution, taxon_concept: output_species1, geo_entity: poland ) + original_d2 = create( + :distribution, + taxon_concept: output_species1, + geo_entity: italy, + tag_list: ['reintroduced'] + ) + original_d3 = create( + :distribution, + taxon_concept: output_species1, + geo_entity: united_kingdom, + tag_list: ['introduced'] + ) original_d.distribution_references.create(reference_id: create(:reference).id) create(:preset_tag, model: 'Distribution', name: 'extinct') d = create( @@ -32,12 +58,25 @@ geo_entity: poland, tag_list: ['extinct'] ) + d2 = create( + :distribution, + taxon_concept: input_species, + geo_entity: italy, + tag_list: ['extinct'] + ) + d3 = create( + :distribution, + taxon_concept: input_species, + geo_entity: united_kingdom + ) d.distribution_references.create(reference_id: create(:reference).id) create(:distribution, taxon_concept: input_species) processor.run end - specify{ expect(output_species1.distributions.count).to eq(2) } + specify{ expect(output_species1.distributions.count).to eq(4) } specify{ expect(output_species1.distributions.find_by_geo_entity_id(poland.id)).not_to be_nil } - specify{ expect(output_species1.distributions.find_by_geo_entity_id(poland.id).tag_list).to eq(['extinct']) } + specify{ expect(output_species1.distributions.find_by_geo_entity_id(poland.id).tag_list).to eq([]) } + specify{ expect(output_species1.distributions.find_by_geo_entity_id(italy.id).tag_list).to eq(['extinct', 'reintroduced']) } + specify{ expect(output_species1.distributions.find_by_geo_entity_id(united_kingdom.id).tag_list).to eq([]) } specify{ expect(output_species1.distributions.find_by_geo_entity_id(poland.id).distribution_references.count).to eq(2) } end From 67eaebd4bf3986c6a00349f67ef6f2776575cf6e Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Wed, 6 Apr 2016 10:26:00 +0200 Subject: [PATCH 215/365] render correct edit form for each taxon concept name status --- .../admin/taxon_concepts_controller.rb | 38 +++++++++------- app/helpers/taxon_concept_helper.rb | 44 +++++++++---------- app/views/admin/names/index.html.erb | 2 +- .../admin/taxon_concepts/_basic_info.html.erb | 13 +++++- .../taxon_concepts/_trade_name_form.html.erb | 44 +++++++++++++++++++ .../taxon_concepts/new_trade_name.js.erb | 4 ++ 6 files changed, 105 insertions(+), 40 deletions(-) create mode 100644 app/views/admin/taxon_concepts/_trade_name_form.html.erb create mode 100644 app/views/admin/taxon_concepts/new_trade_name.js.erb diff --git a/app/controllers/admin/taxon_concepts_controller.rb b/app/controllers/admin/taxon_concepts_controller.rb index d67beee9b2..cc91262f1e 100644 --- a/app/controllers/admin/taxon_concepts_controller.rb +++ b/app/controllers/admin/taxon_concepts_controller.rb @@ -30,7 +30,7 @@ def edit @ranks = Rank.order(:taxonomic_position) edit! do |format| load_search - format.js { render 'new' } + format.js { render_new_by_name_status } end end @@ -39,20 +39,7 @@ def create @taxonomies = Taxonomy.order(:name) @ranks = Rank.order(:taxonomic_position) success.js { render('create') } - failure.js { - if @taxon_concept.is_synonym? - @synonym = @taxon_concept - render('new_synonym') - elsif @taxon_concept.is_hybrid? - @hybrid = @taxon_concept - render('new_hybrid') - elsif @taxon_concept.name_status == 'N' - @n_name = @taxon_concept - render('new_n_name') - else - render('new') - end - } + failure.js { render_new_by_name_status } end end @@ -68,7 +55,7 @@ def update @taxonomies = Taxonomy.order(:name) @ranks = Rank.order(:taxonomic_position) load_tags - render 'new' + render_new_by_name_status } success.html { UpdateTaxonomyWorker.perform_async if rebuild_taxonomy @@ -132,4 +119,23 @@ def split_stringified_ids_lists params[:taxon_concept][ids_list_key] = stringified_ids_list.split(',') end end + + def render_new_by_name_status + if @taxon_concept.is_synonym? + @synonym = @taxon_concept + render('new_synonym') + elsif @taxon_concept.is_hybrid? + @hybrid = @taxon_concept + render('new_hybrid') + elsif @taxon_concept.is_trade_name? + @trade_name = @taxon_concept + render('new_trade_name') + elsif @taxon_concept.name_status == 'N' + @n_name = @taxon_concept + render('new_n_name') + else + render('new') + end + end + end diff --git a/app/helpers/taxon_concept_helper.rb b/app/helpers/taxon_concept_helper.rb index 0c5d32c0c6..df3d2fda01 100644 --- a/app/helpers/taxon_concept_helper.rb +++ b/app/helpers/taxon_concept_helper.rb @@ -75,10 +75,31 @@ def admin_new_synonym_modal(nested = false) ){ nested ? '' : render('synonym_form') } end - def admin_new_trade_name_modal + def admin_new_trade_name_modal(nested = false) admin_new_modal( :resource => 'taxon_concept_trade_name', :title => 'Add new Trade name' + ){ nested ? '' : render('trade_name_form') } + end + + def admin_new_hybrid_modal(nested = false) + admin_new_modal( + :resource => 'taxon_concept_hybrid', + :title => 'Add new Hybrid' + ){ nested ? '' : render('hybrid_form') } + end + + def admin_new_n_name_modal + admin_new_modal( + resource: 'taxon_concept_n_name', + title: 'Add new N name' + ){ render('n_name_form') } + end + + def admin_new_taxon_concept_modal options= {} + admin_new_modal( + :resource => 'taxon_concept', + :title => options[:title] || nil ){ '' } end @@ -119,20 +140,6 @@ def admin_edit_distribution_modal(nested = false) ){ nested ? '' : render('admin/distributions/form') } end - def admin_new_hybrid_modal(nested = false) - admin_new_modal( - :resource => 'taxon_concept_hybrid', - :title => 'Add new Hybrid' - ){ nested ? '' : render('hybrid_form') } - end - - def admin_new_n_name_modal - admin_new_modal( - resource: 'taxon_concept_n_name', - title: 'Add new N name' - ){ render('n_name_form') } - end - def admin_add_new_reference_button admin_add_new_button( :resource => 'taxon_concept_reference', @@ -151,13 +158,6 @@ def admin_new_reference_modal(nested = false) ) end - def admin_new_taxon_concept_modal options= {} - admin_new_modal( - :resource => 'taxon_concept', - :title => options[:title] || nil - ){ '' } - end - def admin_new_cites_suspension_modal admin_new_modal( :resource => 'cites_suspension' diff --git a/app/views/admin/names/index.html.erb b/app/views/admin/names/index.html.erb index 20b3238839..8036c68d9d 100644 --- a/app/views/admin/names/index.html.erb +++ b/app/views/admin/names/index.html.erb @@ -16,7 +16,7 @@

Trade names

<%= admin_add_new_trade_name_button %> - <%= admin_new_trade_name_modal %> + <%= admin_new_trade_name_modal(true) %>
<% if @taxon_concept.has_trade_names? %> diff --git a/app/views/admin/taxon_concepts/_basic_info.html.erb b/app/views/admin/taxon_concepts/_basic_info.html.erb index 09b86f5cfd..bcc1941d8b 100644 --- a/app/views/admin/taxon_concepts/_basic_info.html.erb +++ b/app/views/admin/taxon_concepts/_basic_info.html.erb @@ -81,7 +81,18 @@ <%= ancestors_path(@taxon_concept) %>
-<%= admin_new_taxon_concept_modal(:title => 'Edit Taxon Concept') %> +<% case @taxon_concept.name_status %> +<% when 'A' %> + <%= admin_new_taxon_concept_modal(:title => 'Edit Taxon Concept') %> +<% when 'N' %> + <%= admin_new_n_name_modal(:title => 'Edit Taxon Concept') %> +<% when 'S' %> + <%= admin_new_synonym_modal(:title => 'Edit Taxon Concept') %> +<% when 'T' %> + <%= admin_new_trade_name_modal(:title => 'Edit Taxon Concept') %> +<% when 'H' %> + <%= admin_new_hybrid_modal(:title => 'Edit Taxon Concept') %> +<% end %> <% unless @taxon_concept.is_synonym? || @taxon_concept.is_hybrid? || @taxon_concept.is_trade_name? %>

- It is planned to implement a web feed to display CMS species data directly from the CMS species database - in Species+. The release of this web feed is foreseen for the end of 2014. + It is planned to implement a web feed to display CMS species data directly from the CMS species database in Species+.

From 87886909dbccf55375221d3bd7d3a31c886fa543 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 28 Apr 2016 12:20:57 +0100 Subject: [PATCH 259/365] simplified swap processor logic (needs_to_relay always true, needs_to_receive always false) --- app/models/nomenclature_change/status_swap/constructor.rb | 6 +----- app/models/nomenclature_change/status_swap/processor.rb | 7 +------ 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/app/models/nomenclature_change/status_swap/constructor.rb b/app/models/nomenclature_change/status_swap/constructor.rb index f94b4f381c..8a54e8b4a5 100644 --- a/app/models/nomenclature_change/status_swap/constructor.rb +++ b/app/models/nomenclature_change/status_swap/constructor.rb @@ -21,11 +21,7 @@ def build_secondary_output_note private def legislation_note(lng) input = @nomenclature_change.input - output = if @nomenclature_change.needs_to_relay_associations? - @nomenclature_change.secondary_output - elsif @nomenclature_change.needs_to_receive_associations? - @nomenclature_change.primary_output - end + output = @nomenclature_change.secondary_output output = taxon_concept_html(output.display_full_name, output.display_rank_name) input = taxon_concept_html(input.taxon_concept.full_name, input.taxon_concept.rank.name) note = '

' diff --git a/app/models/nomenclature_change/status_swap/processor.rb b/app/models/nomenclature_change/status_swap/processor.rb index 13c0bed5dc..1c930e9dfe 100644 --- a/app/models/nomenclature_change/status_swap/processor.rb +++ b/app/models/nomenclature_change/status_swap/processor.rb @@ -7,15 +7,10 @@ class NomenclatureChange::StatusSwap::Processor < NomenclatureChange::Processor # A subprocessor needs to respond to #run def prepare_chain chain = [] - output = if @nc.needs_to_relay_associations? - @secondary_output - elsif @nc.needs_to_receive_associations? - @primary_output - end chain << NomenclatureChange::OutputTaxonConceptProcessor.new(@primary_output) chain << NomenclatureChange::OutputTaxonConceptProcessor.new(@secondary_output) - chain << reassignment_processor(output) + chain << reassignment_processor(@secondary_output) chain << if @primary_output.new_name_status == 'A' linked_names = @secondary_output ? [@secondary_output] : [] From a41c5cfd0465720fb1b7093810c0b8d9bb58e347 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Thu, 28 Apr 2016 12:21:35 +0100 Subject: [PATCH 260/365] fixed updating existing internal note (needs a separate save) --- .../nomenclature_change/output_taxon_concept_processor.rb | 1 + .../shared/status_change_definitions.rb | 4 +++- .../nomenclature_change/status_swap/processor_spec.rb | 7 +++++++ 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/app/models/nomenclature_change/output_taxon_concept_processor.rb b/app/models/nomenclature_change/output_taxon_concept_processor.rb index 8f3dc5c09a..2fe1e0fddb 100644 --- a/app/models/nomenclature_change/output_taxon_concept_processor.rb +++ b/app/models/nomenclature_change/output_taxon_concept_processor.rb @@ -17,6 +17,7 @@ def run Rails.logger.warn "FAILED to save taxon #{tc.errors.inspect}" return false end + nomenclature_comment.save if new_record Rails.logger.debug("UPDATE NEW TAXON ID #{tc.id}") @output.update_column(:new_taxon_concept_id, tc.id) diff --git a/spec/models/nomenclature_change/shared/status_change_definitions.rb b/spec/models/nomenclature_change/shared/status_change_definitions.rb index 7b5e192d89..3255e63bf1 100644 --- a/spec/models/nomenclature_change/shared/status_change_definitions.rb +++ b/spec/models/nomenclature_change/shared/status_change_definitions.rb @@ -105,7 +105,9 @@ is_primary_output: false, taxon_concept_id: input_synonym.id, new_name_status: 'A', - new_parent_id: input_synonym_genus.id + new_parent_id: input_synonym_genus.id, + note_en: 'public', + internal_note: 'internal' }, status: NomenclatureChange::StatusSwap::SECONDARY_OUTPUT ).reload diff --git a/spec/models/nomenclature_change/status_swap/processor_spec.rb b/spec/models/nomenclature_change/status_swap/processor_spec.rb index b6129d4421..f0447d2d0e 100644 --- a/spec/models/nomenclature_change/status_swap/processor_spec.rb +++ b/spec/models/nomenclature_change/status_swap/processor_spec.rb @@ -31,12 +31,19 @@ taxon_concept: primary_output_taxon_concept, reported_taxon_concept: primary_output_taxon_concept ) + secondary_output_taxon_concept.create_nomenclature_comment processor.run } specify{ expect(primary_output_taxon_concept).to be_is_synonym } specify{ expect(primary_output_taxon_concept.parent).to eq(accepted_name_parent) } specify{ expect(secondary_output_taxon_concept.name_status).to eq('A') } specify{ expect(primary_output_taxon_concept.accepted_names).to include(secondary_output_taxon_concept) } + specify "public nomenclature note is set" do + expect(secondary_output_taxon_concept.nomenclature_note_en).to eq(' public') + end + specify "internal nomenclature note is set" do + expect(secondary_output_taxon_concept.nomenclature_comment.try(:note)).to eq(' internal') + end end end From 5c5573c6c2f288a8ca354ec2c47c0e252bd077e0 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 3 May 2016 12:08:11 +0100 Subject: [PATCH 261/365] added spec for genus split --- .../split/processor_spec.rb | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/spec/models/nomenclature_change/split/processor_spec.rb b/spec/models/nomenclature_change/split/processor_spec.rb index 286435e1c9..9c519fe4fd 100644 --- a/spec/models/nomenclature_change/split/processor_spec.rb +++ b/spec/models/nomenclature_change/split/processor_spec.rb @@ -229,6 +229,70 @@ end end end + context "when input is genus and parent ressignments occur" do + let(:input_genus) do + create_cites_eu_genus( + taxon_name: create(:taxon_name, scientific_name: 'Crotalus') + ) + end + let(:input_genus_child) do + create_cites_eu_species( + parent: input_genus, + taxon_name: create(:taxon_name, scientific_name: 'durissus') + ) + end + let!(:input_genus_child_child) do + create_cites_eu_subspecies( + parent: input_genus_child, + taxon_name: create(:taxon_name, scientific_name: 'unicolor') + ) + end + let(:output_genus) do + create_cites_eu_genus( + taxon_name: create(:taxon_name, scientific_name: 'Paracrotalus') + ) + end + let(:split){ + create(:nomenclature_change_split, + input_attributes: { taxon_concept_id: input_genus.id }, + outputs_attributes: { + 0 => { taxon_concept_id: input_genus.id }, + 1 => { taxon_concept_id: output_genus.id } + }, + status: NomenclatureChange::Split::LEGISLATION + ) + } + let(:reassignment){ + create(:nomenclature_change_parent_reassignment, + input: split.input, + reassignable_id: input_genus_child.id + ) + } + let!(:reassignment_target){ + create(:nomenclature_change_reassignment_target, + reassignment: reassignment, + output: split.outputs.last + ) + } + before(:each){ processor.run } + specify "input genus child is a synonym" do + expect(input_genus_child.reload.name_status).to eq('S') + end + specify "input genus child's child is a synonym" do + expect(input_genus_child_child.reload.name_status).to eq('S') + end + specify "output genus should have child with resolved name" do + output_genus_child = output_genus.children.first + expect(output_genus_child).not_to be_nil + expect(output_genus_child.full_name).to eq('Paracrotalus durissus') + end + specify "output genus child should have child with resolved name" do + output_genus_child = output_genus.children.first + output_genus_child_child = output_genus_child.children.first + expect(output_genus_child_child).not_to be_nil + expect(output_genus_child_child.full_name).to eq('Paracrotalus durissus unicolor') + end + end describe :summary do let(:split){ split_with_input_and_output_existing_taxon } specify { expect(processor.summary).to be_kind_of(Array) } From 5e1b99c3d8fb6143337d23ce87709f57911613cd Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 3 May 2016 12:14:11 +0100 Subject: [PATCH 262/365] match on author & year when selecting existing compatible node --- .../nomenclature_change/taxonomic_tree_name_resolver.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/models/nomenclature_change/taxonomic_tree_name_resolver.rb b/app/models/nomenclature_change/taxonomic_tree_name_resolver.rb index 9d33d5118c..a0c2fe91b1 100644 --- a/app/models/nomenclature_change/taxonomic_tree_name_resolver.rb +++ b/app/models/nomenclature_change/taxonomic_tree_name_resolver.rb @@ -27,7 +27,13 @@ def resolve(node) compatible_node = TaxonConcept.where( taxonomy_id: node.taxonomy_id, full_name: expected_full_name - ).first + ) + # match on author & year as well + compatible_node = if node.author_year.blank? + compatible_node.where('SQUISH_NULL(author_year) IS NULL') + else + compatible_node.where(author_year: node.author_year) + end.first unless compatible_node compatible_node = TaxonConcept.create( taxonomy_id: node.taxonomy_id, From 7763aa24c3d4b3c78685df2c1451394dc1bdf738 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 3 May 2016 13:08:44 +0100 Subject: [PATCH 263/365] corrected parent resolution for subspecies when input is a genus --- .../taxonomic_tree_name_resolver.rb | 111 ++++++++++-------- 1 file changed, 60 insertions(+), 51 deletions(-) diff --git a/app/models/nomenclature_change/taxonomic_tree_name_resolver.rb b/app/models/nomenclature_change/taxonomic_tree_name_resolver.rb index a0c2fe91b1..c8aacd5f26 100644 --- a/app/models/nomenclature_change/taxonomic_tree_name_resolver.rb +++ b/app/models/nomenclature_change/taxonomic_tree_name_resolver.rb @@ -10,69 +10,78 @@ def process resolve(@node) end - private def resolve(node) - expected_full_name = node.expected_full_name(node.parent) + @expected_full_name = node.expected_full_name(node.parent) + return node if name_compatible_with_parent?(node) + Rails.logger.debug("Resolving node name: #{node.full_name} (expected: #{@expected_full_name})") - expected_scientific_name = if ['A', 'N'].include?(node.name_status) - expected_full_name.split.last + # find or create a new accepted name compatible with this parent + compatible_node = TaxonConcept.where( + taxonomy_id: node.taxonomy_id, + full_name: @expected_full_name + ) + # match on author & year as well + compatible_node = if node.author_year.blank? + compatible_node.where('SQUISH_NULL(author_year) IS NULL') else - expected_full_name + compatible_node.where(author_year: node.author_year) + end.first + if !compatible_node + compatible_node = create_compatible_node(node) + elsif compatible_node && !['A', 'N'].include?(compatible_node.name_status) + upgrade_node(compatible_node, node.parent) end - Rails.logger.debug("Resolving node name: #{node.full_name} (expected: #{expected_full_name})") - unless name_compatible_with_parent?(node) - # find or create a new accepted name compatible with this parent - compatible_node = TaxonConcept.where( - taxonomy_id: node.taxonomy_id, - full_name: expected_full_name - ) - # match on author & year as well - compatible_node = if node.author_year.blank? - compatible_node.where('SQUISH_NULL(author_year) IS NULL') - else - compatible_node.where(author_year: node.author_year) - end.first - unless compatible_node - compatible_node = TaxonConcept.create( - taxonomy_id: node.taxonomy_id, - scientific_name: expected_scientific_name, - parent_id: node.parent_id, - name_status: node.name_status, - rank_id: node.rank_id, - author_year: node.author_year, - nomenclature_note_en: node.nomenclature_note_en, - nomenclature_note_es: node.nomenclature_note_es, - nomenclature_note_fr: node.nomenclature_note_fr - ) - if node.nomenclature_comment - compatible_node.create_nomenclature_comment(note: node.nomenclature_comment.note) - end - else - unless ['A', 'N'].include?(compatible_node.name_status) - t = NomenclatureChange::ToAcceptedNameTransformation.new(compatible_node, node.parent) - t.process - end - end - # restore old parent, even though this ends up as a synonym it should - # have sane ancestry - node.update_attribute(:parent_id, @node_old_copy.parent_id) - r = NomenclatureChange::FullReassignment.new(node, compatible_node) - r.process - t = NomenclatureChange::ToSynonymTransformation.new(node, compatible_node) - t.process - else - compatible_node = node - end + # restore old parent, even though this ends up as a synonym it should + # have sane ancestry + node.update_attribute(:parent_id, @node_old_copy.parent_id) - compatible_node.children.each do |child_node| + r = NomenclatureChange::FullReassignment.new(node, compatible_node) + r.process + downgrade_node(node, compatible_node) + + node.children.each do |child_node| + child_node.parent = compatible_node resolve(child_node) end end + def create_compatible_node(node) + expected_scientific_name = if ['A', 'N'].include?(node.name_status) + @expected_full_name.split.last + else + @expected_full_name + end + compatible_node = TaxonConcept.create( + taxonomy_id: node.taxonomy_id, + scientific_name: expected_scientific_name, + parent_id: node.parent_id, + name_status: node.name_status, + rank_id: node.rank_id, + author_year: node.author_year, + nomenclature_note_en: node.nomenclature_note_en, + nomenclature_note_es: node.nomenclature_note_es, + nomenclature_note_fr: node.nomenclature_note_fr + ) + if node.nomenclature_comment + compatible_node.create_nomenclature_comment(note: node.nomenclature_comment.note) + end + compatible_node + end + + def upgrade_node(node, parent) + t = NomenclatureChange::ToAcceptedNameTransformation.new(node, parent) + t.process + end + + def downgrade_node(node, compatible_node) + t = NomenclatureChange::ToSynonymTransformation.new(node, compatible_node) + t.process + end + def name_compatible_with_parent?(node) - node.expected_full_name(node.parent) == node.full_name + @expected_full_name == node.full_name end end From 1fae5372443a8c4d66b8d5c8174978c84ef1382f Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 3 May 2016 13:09:23 +0100 Subject: [PATCH 264/365] simplified full reassignments --- .../nomenclature_change/full_reassignment.rb | 39 +++++++------------ .../split/processor_spec.rb | 12 ++++++ 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/app/models/nomenclature_change/full_reassignment.rb b/app/models/nomenclature_change/full_reassignment.rb index 583727e64e..a67853fd6a 100644 --- a/app/models/nomenclature_change/full_reassignment.rb +++ b/app/models/nomenclature_change/full_reassignment.rb @@ -7,55 +7,44 @@ def initialize(old_taxon_concept, new_taxon_concept) def process Rails.logger.debug "FULL REASSIGNMENT #{@old_taxon_concept.full_name} to #{@new_taxon_concept.full_name}" + update_timestamp = Time.now update_attrs = { - taxon_concept_id: @new_taxon_concept.id + taxon_concept_id: @new_taxon_concept.id, + updated_at: update_timestamp, + updated_by_id: nil } # distributions Rails.logger.debug "FULL REASSIGNMENT Distributions (#{@old_taxon_concept.distributions.count})" - @old_taxon_concept.distributions.each do |d| - d.update_attributes(update_attrs) - end + @old_taxon_concept.distributions.update_all(update_attrs) # references Rails.logger.debug "FULL REASSIGNMENT References (#{@old_taxon_concept.taxon_concept_references.count})" - @old_taxon_concept.taxon_concept_references.each do |tcr| - tcr.update_attributes(update_attrs) - end + @old_taxon_concept.taxon_concept_references.update_all(update_attrs) # listing changes Rails.logger.debug "FULL REASSIGNMENT Listing Changes (#{@old_taxon_concept.listing_changes.count})" - @old_taxon_concept.listing_changes.each do |lc| - lc.update_attributes(update_attrs) - end + @old_taxon_concept.listing_changes.update_all(update_attrs) # EU opinions Rails.logger.debug "FULL REASSIGNMENT EU Opinions (#{@old_taxon_concept.eu_opinions.count})" - @old_taxon_concept.eu_opinions.each do |ed| - ed.update_attributes(update_attrs) - end + @old_taxon_concept.eu_opinions.update_all(update_attrs) # EU suspensions Rails.logger.debug "FULL REASSIGNMENT EU Suspensions (#{@old_taxon_concept.eu_suspensions.count})" - @old_taxon_concept.eu_suspensions.each do |ed| - ed.update_attributes(update_attrs) - end + @old_taxon_concept.eu_suspensions.update_all(update_attrs) # CITES quotas Rails.logger.debug "FULL REASSIGNMENT CITES Quotas (#{@old_taxon_concept.quotas.count})" - @old_taxon_concept.quotas.each do |tr| - tr.update_attributes(update_attrs) - end + @old_taxon_concept.quotas.update_all(update_attrs) # CITES suspensions Rails.logger.debug "FULL REASSIGNMENT CITES Suspensions (#{@old_taxon_concept.cites_suspensions.count})" - @old_taxon_concept.cites_suspensions.each do |tr| - tr.update_attributes(update_attrs) - end + @old_taxon_concept.cites_suspensions.update_all(update_attrs) # common names Rails.logger.debug "FULL REASSIGNMENT Common names (#{@old_taxon_concept.taxon_commons.count})" - @old_taxon_concept.taxon_commons.each do |tc| - tc.update_attributes(update_attrs) - end + @old_taxon_concept.taxon_commons.update_all(update_attrs) # shipments Rails.logger.debug "FULL REASSIGNMENT Shipments" Trade::Shipment.update_all( update_attrs, {taxon_concept_id: @old_taxon_concept.id} ) + @old_taxon_concept.update_attributes(dependents_updated_at: update_timestamp) + @new_taxon_concept.update_attributes(dependents_updated_at: update_timestamp) end end diff --git a/spec/models/nomenclature_change/split/processor_spec.rb b/spec/models/nomenclature_change/split/processor_spec.rb index 9c519fe4fd..59869a9308 100644 --- a/spec/models/nomenclature_change/split/processor_spec.rb +++ b/spec/models/nomenclature_change/split/processor_spec.rb @@ -247,6 +247,7 @@ taxon_name: create(:taxon_name, scientific_name: 'unicolor') ) end + let!(:quota){ create(:quota, taxon_concept: input_genus_child, geo_entity: create(:geo_entity)) } let(:output_genus) do create_cites_eu_genus( taxon_name: create(:taxon_name, scientific_name: 'Paracrotalus') @@ -278,6 +279,10 @@ specify "input genus child is a synonym" do expect(input_genus_child.reload.name_status).to eq('S') end + specify "input genus child is a synonym of output genus child" do + output_genus_child = output_genus.children.first + expect(input_genus_child.accepted_names).to include(output_genus_child) + end specify "input genus child's child is a synonym" do expect(input_genus_child_child.reload.name_status).to eq('S') end @@ -292,6 +297,13 @@ expect(output_genus_child_child).not_to be_nil expect(output_genus_child_child.full_name).to eq('Paracrotalus durissus unicolor') end + specify "input genus child has no quotas" do + expect(input_genus_child.quotas).to be_empty + end + specify "input genus child's accepted name has 1 quota" do + output_genus_child = output_genus.children.first + expect(output_genus_child.quotas.size).to eq(1) + end end describe :summary do let(:split){ split_with_input_and_output_existing_taxon } From dc618281017d3d4c9c8e67a20c6c8195360132a3 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Wed, 11 May 2016 08:56:24 +0100 Subject: [PATCH 265/365] fixed erroneous renaming of old accepted name --- app/models/nomenclature_change/full_reassignment.rb | 1 + spec/models/nomenclature_change/split/processor_spec.rb | 3 +++ 2 files changed, 4 insertions(+) diff --git a/app/models/nomenclature_change/full_reassignment.rb b/app/models/nomenclature_change/full_reassignment.rb index a67853fd6a..f02a917a49 100644 --- a/app/models/nomenclature_change/full_reassignment.rb +++ b/app/models/nomenclature_change/full_reassignment.rb @@ -44,6 +44,7 @@ def process {taxon_concept_id: @old_taxon_concept.id} ) @old_taxon_concept.update_attributes(dependents_updated_at: update_timestamp) + @old_taxon_concept.reload @new_taxon_concept.update_attributes(dependents_updated_at: update_timestamp) end diff --git a/spec/models/nomenclature_change/split/processor_spec.rb b/spec/models/nomenclature_change/split/processor_spec.rb index 59869a9308..399591e44b 100644 --- a/spec/models/nomenclature_change/split/processor_spec.rb +++ b/spec/models/nomenclature_change/split/processor_spec.rb @@ -286,6 +286,9 @@ specify "input genus child's child is a synonym" do expect(input_genus_child_child.reload.name_status).to eq('S') end + specify "input genus child's child's name did not change" do + expect(input_genus_child_child.reload.full_name).to eq('Crotalus durissus unicolor') + end specify "output genus should have child with resolved name" do output_genus_child = output_genus.children.first expect(output_genus_child).not_to be_nil From eb30b3ba20c95363f3886390996c0f8e807eccdc Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Wed, 11 May 2016 08:57:00 +0100 Subject: [PATCH 266/365] specs for lumping a genus with subspecies that cange name --- .../lump/processor_spec.rb | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/spec/models/nomenclature_change/lump/processor_spec.rb b/spec/models/nomenclature_change/lump/processor_spec.rb index faa78e02fc..41a44bff92 100644 --- a/spec/models/nomenclature_change/lump/processor_spec.rb +++ b/spec/models/nomenclature_change/lump/processor_spec.rb @@ -216,6 +216,85 @@ end end end + context "when input is genus and parent ressignments occur" do + let(:input_genus) do + create_cites_eu_genus( + taxon_name: create(:taxon_name, scientific_name: 'Crotalus') + ) + end + let(:input_genus_child) do + create_cites_eu_species( + parent: input_genus, + taxon_name: create(:taxon_name, scientific_name: 'durissus') + ) + end + let!(:input_genus_child_child) do + create_cites_eu_subspecies( + parent: input_genus_child, + taxon_name: create(:taxon_name, scientific_name: 'unicolor') + ) + end + let!(:quota){ create(:quota, taxon_concept: input_genus_child, geo_entity: create(:geo_entity)) } + let(:output_genus) do + create_cites_eu_genus( + taxon_name: create(:taxon_name, scientific_name: 'Paracrotalus') + ) + end + let(:lump){ + create(:nomenclature_change_lump, + inputs_attributes: { + 0 => { taxon_concept_id: input_genus.id }, + 1 => { taxon_concept_id: output_genus.id } + }, + output_attributes: { taxon_concept_id: output_genus.id }, + status: NomenclatureChange::Lump::LEGISLATION + ) + } + let(:reassignment){ + create(:nomenclature_change_parent_reassignment, + input: lump.inputs.first, + reassignable_id: input_genus_child.id + ) + } + let!(:reassignment_target){ + create(:nomenclature_change_reassignment_target, + reassignment: reassignment, + output: lump.output + ) + } + before(:each){ processor.run } + specify "input genus child is a synonym" do + expect(input_genus_child.reload.name_status).to eq('S') + end + specify "input genus child is a synonym of output genus child" do + output_genus_child = output_genus.children.first + expect(input_genus_child.accepted_names).to include(output_genus_child) + end + specify "input genus child's child is a synonym" do + expect(input_genus_child_child.reload.name_status).to eq('S') + end + specify "input genus child's child's name did not change" do + expect(input_genus_child_child.reload.full_name).to eq('Crotalus durissus unicolor') + end + specify "output genus should have child with resolved name" do + output_genus_child = output_genus.children.first + expect(output_genus_child).not_to be_nil + expect(output_genus_child.full_name).to eq('Paracrotalus durissus') + end + specify "output genus child should have child with resolved name" do + output_genus_child = output_genus.children.first + output_genus_child_child = output_genus_child.children.first + expect(output_genus_child_child).not_to be_nil + expect(output_genus_child_child.full_name).to eq('Paracrotalus durissus unicolor') + end + specify "input genus child has no quotas" do + expect(input_genus_child.quotas).to be_empty + end + specify "input genus child's accepted name has 1 quota" do + output_genus_child = output_genus.children.first + expect(output_genus_child.quotas.size).to eq(1) + end + end describe :summary do let(:lump){ lump_with_inputs_and_output_existing_taxon } specify { expect(processor.summary).to be_kind_of(Array) } From ce00e1205c2f861247d0c16f377d18545aeddbd0 Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Wed, 8 Jun 2016 11:10:51 +0100 Subject: [PATCH 267/365] deploy to staging from develop branch --- config/deploy/staging.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/deploy/staging.rb b/config/deploy/staging.rb index 8923725796..0871e0be57 100644 --- a/config/deploy/staging.rb +++ b/config/deploy/staging.rb @@ -1,5 +1,5 @@ set :stage, :staging -set :branch, "nomenclature_changes" +set :branch, "develop" server "sapi-staging.linode.unep-wcmc.org", user: "wcmc", roles: %w{app web db} From 84ec8d2e5ee2386daae559c738592f744707127e Mon Sep 17 00:00:00 2001 From: Agnieszka Figiel Date: Tue, 31 May 2016 13:16:57 +0100 Subject: [PATCH 268/365] upgraded rubocop gem & config files --- .rubocop.yml | 1 + .rubocop_todo.yml | 923 +++++++++++++++---- Gemfile | 1 + Gemfile.lock | 14 + vendor/cache/ast-2.2.0.gem | Bin 0 -> 14848 bytes vendor/cache/parser-2.3.1.0.gem | Bin 0 -> 556544 bytes vendor/cache/powerpack-0.1.1.gem | Bin 0 -> 14336 bytes vendor/cache/rainbow-2.0.0.gem | Bin 0 -> 14336 bytes vendor/cache/rubocop-0.40.0.gem | Bin 0 -> 256512 bytes vendor/cache/ruby-progressbar-1.7.5.gem | Bin 0 -> 21504 bytes vendor/cache/unicode-display_width-1.0.5.gem | Bin 0 -> 11264 bytes 11 files changed, 763 insertions(+), 176 deletions(-) create mode 100644 vendor/cache/ast-2.2.0.gem create mode 100644 vendor/cache/parser-2.3.1.0.gem create mode 100644 vendor/cache/powerpack-0.1.1.gem create mode 100644 vendor/cache/rainbow-2.0.0.gem create mode 100644 vendor/cache/rubocop-0.40.0.gem create mode 100644 vendor/cache/ruby-progressbar-1.7.5.gem create mode 100644 vendor/cache/unicode-display_width-1.0.5.gem diff --git a/.rubocop.yml b/.rubocop.yml index a465d133f3..f70e9c5f7a 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -2,3 +2,4 @@ inherit_from: .rubocop_todo.yml Style/StringLiterals: EnforcedStyle: single_quotes + diff --git a/.rubocop_todo.yml b/.rubocop_todo.yml index 50ca5603bf..0bf5428892 100644 --- a/.rubocop_todo.yml +++ b/.rubocop_todo.yml @@ -1,278 +1,567 @@ -# This configuration was generated by `rubocop --auto-gen-config` -# on 2014-10-02 21:31:18 +0100 using RuboCop version 0.26.1. +# This configuration was generated by +# `rubocop --auto-gen-config` +# on 2016-05-31 10:54:17 +0100 using RuboCop version 0.40.0. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. -# Offense count: 3 +# Offense count: 5 Lint/AmbiguousOperator: - Enabled: false + Exclude: + - 'app/controllers/admin/nomenclature_changes/lump_controller.rb' + - 'app/controllers/admin/nomenclature_changes/split_controller.rb' + - 'app/controllers/admin/nomenclature_changes/status_swap_controller.rb' + - 'app/controllers/admin/nomenclature_changes/status_to_accepted_controller.rb' + - 'app/controllers/admin/nomenclature_changes/status_to_synonym_controller.rb' -# Offense count: 4 +# Offense count: 1 # Configuration parameters: AllowSafeAssignment. Lint/AssignmentInCondition: - Enabled: false + Exclude: + - 'lib/tasks/bbgem.rake' -# Offense count: 16 +# Offense count: 21 # Cop supports --auto-correct. +# Configuration parameters: AlignWith, SupportedStyles. +# SupportedStyles: either, start_of_block, start_of_line Lint/BlockAlignment: Enabled: false -# Offense count: 6 +# Offense count: 11 # Cop supports --auto-correct. Lint/DeprecatedClassMethods: - Enabled: false + Exclude: + - 'app/controllers/admin/documents_controller.rb' + - 'app/controllers/api/v1/documents_controller.rb' + - 'app/models/checklist/history.rb' + - 'app/models/checklist/index.rb' + - 'config/boot.rb' + - 'lib/tasks/elibrary/document_files_importer.rb' + - 'lib/tasks/trade_appendix_report.rake' -# Offense count: 57 -# Configuration parameters: AlignWith, SupportedStyles. +# Offense count: 1 +Lint/DuplicateMethods: + Exclude: + - 'app/models/taxon_concept_observer.rb' + +# Offense count: 2 +Lint/DuplicatedKey: + Exclude: + - 'app/models/checklist/column_display_name_mapping.rb' + - 'spec/models/trade/shipment_spec.rb' + +# Offense count: 69 +# Cop supports --auto-correct. +# Configuration parameters: AlignWith, SupportedStyles, AutoCorrect. +# SupportedStyles: keyword, variable, start_of_line Lint/EndAlignment: Enabled: false # Offense count: 2 Lint/HandleExceptions: - Enabled: false + Exclude: + - 'config/initializers/ahoy.rb' + +# Offense count: 12 +Lint/IneffectiveAccessModifier: + Exclude: + - 'app/models/api_request.rb' + - 'app/models/document_search.rb' + - 'app/models/taxon_concept.rb' + - 'app/models/trade/sandbox_template.rb' + - 'app/models/trade/trade_data_download_logger.rb' # Offense count: 4 Lint/Loop: - Enabled: false + Exclude: + - 'app/models/checklist/csv/history_content.rb' + - 'app/models/checklist/csv/index_content.rb' + - 'app/models/checklist/pdf/history_content.rb' + - 'app/models/checklist/pdf/index_content.rb' # Offense count: 1 -Lint/ParenthesesAsGroupedExpression: - Enabled: false +Lint/NestedMethodDefinition: + Exclude: + - 'lib/modules/latex_to_pdf.rb' -# Offense count: 2 -Lint/RequireParentheses: - Enabled: false +# Offense count: 1 +Lint/NonLocalExitFromIterator: + Exclude: + - 'app/controllers/api/v1/documents_controller.rb' + +# Offense count: 1 +Lint/ParenthesesAsGroupedExpression: + Exclude: + - 'app/models/trade/inclusion_validation_rule.rb' # Offense count: 3 -# Cop supports --auto-correct. Lint/RescueException: - Enabled: false + Exclude: + - 'app/models/iucn_mapping_manager.rb' + - 'lib/tasks/helpers_for_import.rb' -# Offense count: 2 +# Offense count: 4 Lint/ShadowingOuterLocalVariable: - Enabled: false + Exclude: + - 'app/helpers/application_helper.rb' + - 'app/models/checklist/higher_taxa_injector.rb' -# Offense count: 29 +# Offense count: 31 # Cop supports --auto-correct. +# Configuration parameters: AllowUnusedKeywordArguments. Lint/UnusedBlockArgument: Enabled: false -# Offense count: 26 +# Offense count: 22 # Cop supports --auto-correct. +# Configuration parameters: AllowUnusedKeywordArguments, IgnoreEmptyMethods. Lint/UnusedMethodArgument: Enabled: false -# Offense count: 1 +# Offense count: 4 Lint/UselessAccessModifier: - Enabled: false + Exclude: + - 'app/controllers/admin/nomenclature_changes/build_controller.rb' + - 'app/models/api_request.rb' + - 'app/models/trade/sandbox_template.rb' + - 'app/models/trade/trade_data_download_logger.rb' -# Offense count: 74 +# Offense count: 94 Lint/UselessAssignment: Enabled: false -# Offense count: 13 +# Offense count: 14 Lint/Void: - Enabled: false - -# Offense count: 22 + Exclude: + - 'spec/controllers/admin/documents_controller_spec.rb' + - 'spec/controllers/admin/taxon_commons_controller_spec.rb' + - 'spec/controllers/trade/sandbox_shipments_controller_spec.rb' + - 'spec/controllers/trade/shipments_controller_spec.rb' + - 'spec/models/checklist/order_spec.rb' + - 'spec/models/checklist/scientific_name_spec.rb' + - 'spec/models/dashboard_stats_trade_spec.rb' + - 'spec/models/taxon_concept/moschus_spec.rb' + +# Offense count: 203 +Metrics/AbcSize: + Max: 743 + +# Offense count: 30 # Configuration parameters: CountComments. Metrics/ClassLength: - Max: 676 + Max: 800 -# Offense count: 52 +# Offense count: 56 Metrics/CyclomaticComplexity: - Max: 35 + Max: 31 -# Offense count: 2704 -# Configuration parameters: AllowURI, URISchemes. +# Offense count: 2643 +# Configuration parameters: AllowHeredoc, AllowURI, URISchemes. +# URISchemes: http, https Metrics/LineLength: Max: 562 -# Offense count: 296 +# Offense count: 388 # Configuration parameters: CountComments. Metrics/MethodLength: - Max: 674 + Max: 798 -# Offense count: 48 +# Offense count: 10 +# Configuration parameters: CountComments. +Metrics/ModuleLength: + Max: 427 + +# Offense count: 44 Metrics/PerceivedComplexity: Max: 37 +# Offense count: 1 +# Cop supports --auto-correct. +Performance/RangeInclude: + Exclude: + - 'app/models/checklist/checklist.rb' + +# Offense count: 2 +# Cop supports --auto-correct. +Performance/RedundantMatch: + Exclude: + - 'lib/capistrano/tasks/smoke_test.rake' + - 'old_cap/deploy.rb' + +# Offense count: 2 +# Cop supports --auto-correct. +Performance/Sample: + Exclude: + - 'config/deploy.rb' + - 'old_cap/deploy.rb' + # Offense count: 25 # Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. +Performance/TimesMap: + Enabled: false + +# Offense count: 27 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. +# SupportedStyles: outdent, indent Style/AccessModifierIndentation: Enabled: false -# Offense count: 2 +# Offense count: 4 Style/AccessorMethodName: - Enabled: false + Exclude: + - 'app/models/trade/shipments_export.rb' + - 'lib/modules/statistics.rb' + - 'spec/controllers/api/documents_controller_spec.rb' -# Offense count: 2 +# Offense count: 8 # Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: prefer_alias, prefer_alias_method Style/Alias: - Enabled: false + Exclude: + - 'app/models/nomenclature_change/lump/constructor.rb' + - 'app/models/nomenclature_change/split/constructor.rb' + - 'app/models/nomenclature_change/status_change/constructor_helpers.rb' + - 'lib/modules/downloads_cache.rb' -# Offense count: 55 +# Offense count: 49 # Cop supports --auto-correct. Style/AlignArray: Enabled: false -# Offense count: 308 +# Offense count: 484 # Cop supports --auto-correct. # Configuration parameters: EnforcedHashRocketStyle, EnforcedColonStyle, EnforcedLastArgumentHashStyle, SupportedLastArgumentHashStyles. +# SupportedLastArgumentHashStyles: always_inspect, always_ignore, ignore_implicit, ignore_explicit Style/AlignHash: Enabled: false -# Offense count: 392 +# Offense count: 492 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: with_first_parameter, with_fixed_indentation Style/AlignParameters: Enabled: false -# Offense count: 5 +# Offense count: 7 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: always, conditionals Style/AndOr: - Enabled: false + Exclude: + - 'app/controllers/api/v1/documents_controller.rb' + - 'app/controllers/species/exports_controller.rb' + - 'db/migrate/20120530135534_setup_hstore.rb' + - 'db/migrate/20120703141230_setup_tablefunc.rb' + - 'lib/tasks/bbgem.rake' -# Offense count: 20 +# Offense count: 993 # Cop supports --auto-correct. -Style/BlockEndNewline: +# Configuration parameters: EnforcedStyle, SupportedStyles, ProceduralMethods, FunctionalMethods, IgnoredMethods. +# SupportedStyles: line_count_based, semantic, braces_for_chaining +# ProceduralMethods: benchmark, bm, bmbm, create, each_with_object, measure, new, realtime, tap, with_object +# FunctionalMethods: let, let!, subject, watch +# IgnoredMethods: lambda, proc, it +Style/BlockDelimiters: Enabled: false -# Offense count: 899 +# Offense count: 25 # Cop supports --auto-correct. -Style/Blocks: - Enabled: false - -# Offense count: 210 +Style/BlockEndNewline: + Exclude: + - 'spec/controllers/admin/ahoy_events_controller_spec.rb' + - 'spec/controllers/api/taxon_concepts_controller_spec.rb' + - 'spec/models/cites_suspension_notification_spec.rb' + - 'spec/models/designation_spec.rb' + - 'spec/models/nomenclature_change/shared/split_definitions.rb' + - 'spec/models/purpose_spec.rb' + - 'spec/models/source_spec.rb' + - 'spec/models/taxon_concept_prefix_matcher_spec.rb' + - 'spec/models/taxon_relationship_spec.rb' + - 'spec/models/term_spec.rb' + +# Offense count: 243 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: braces, no_braces, context_dependent Style/BracesAroundHashParameters: Enabled: false -# Offense count: 37 -# Configuration parameters: IndentWhenRelativeTo, SupportedStyles, IndentOneStep. +# Offense count: 45 +# Cop supports --auto-correct. +# Configuration parameters: IndentWhenRelativeTo, SupportedStyles, IndentOneStep, IndentationWidth. +# SupportedStyles: case, end Style/CaseIndentation: Enabled: false -# Offense count: 302 +# Offense count: 348 # Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: nested, compact Style/ClassAndModuleChildren: Enabled: false -# Offense count: 58 +# Offense count: 48 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: is_a?, kind_of? Style/ClassCheck: Enabled: false -# Offense count: 4 +# Offense count: 200 # Cop supports --auto-correct. -# Configuration parameters: PreferredMethods. -Style/CollectionMethods: +Style/ClosingParenthesisIndentation: Enabled: false # Offense count: 4 # Cop supports --auto-correct. Style/ColonMethodCall: - Enabled: false + Exclude: + - 'app/models/event.rb' + - 'lib/tasks/db_migrate_plpgsql.rake' + - 'lib/tasks/import.rake' -# Offense count: 14 +# Offense count: 13 +# Cop supports --auto-correct. # Configuration parameters: Keywords. +# Keywords: TODO, FIXME, OPTIMIZE, HACK, REVIEW Style/CommentAnnotation: - Enabled: false + Exclude: + - 'app/controllers/api/v1/geo_entities_controller.rb' + - 'app/controllers/checklist/geo_entities_controller.rb' + - 'app/models/checklist/checklist.rb' + - 'app/models/checklist/pdf/index_content.rb' + - 'app/models/checklist/timeline.rb' + - 'app/models/document.rb' + - 'app/models/trade/distinct_values_validation_rule.rb' + - 'app/models/trade/sandbox.rb' + - 'app/serializers/checklist/checklist_serializer.rb' + - 'config/routes.rb' + - 'lib/tasks/helpers_for_import.rb' + - 'lib/tasks/import_distributions.rake' -# Offense count: 4 +# Offense count: 5 # Cop supports --auto-correct. Style/CommentIndentation: - Enabled: false + Exclude: + - 'app/controllers/cites_trade/shipments_controller.rb' + - 'app/models/search_params.rb' + - 'config/initializers/geocoder.rb' + - 'db/schema.rb' + - 'lib/tasks/import_cms_listings.rake' + +# Offense count: 6 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles, SingleLineConditionsOnly. +# SupportedStyles: assign_to_condition, assign_inside_condition +Style/ConditionalAssignment: + Exclude: + - 'app/controllers/api/v1/taxon_concepts_controller.rb' + - 'app/models/checklist/checklist.rb' + - 'app/models/trade/filter.rb' + - 'lib/modules/html_to_latex.rb' + - 'old_cap/deploy.rb' # Offense count: 10 # Cop supports --auto-correct. Style/DeprecatedHashMethods: - Enabled: false - -# Offense count: 587 + Exclude: + - 'app/controllers/api/v1/geo_entities_controller.rb' + - 'app/controllers/checklist/geo_entities_controller.rb' + - 'app/controllers/trade/shipments_controller.rb' + - 'app/models/trade/validation_rule.rb' + - 'app/models/trade_restriction.rb' + +# Offense count: 623 Style/Documentation: Enabled: false -# Offense count: 539 +# Offense count: 551 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: leading, trailing Style/DotPosition: Enabled: false -# Offense count: 43 +# Offense count: 1 +Style/DoubleNegation: + Exclude: + - 'app/models/eu_decision_type.rb' + +# Offense count: 70 +# Cop supports --auto-correct. +Style/ElseAlignment: + Enabled: false + +# Offense count: 1 +# Cop supports --auto-correct. +Style/EmptyCaseCondition: + Exclude: + - 'app/helpers/admin/nomenclature_changes_helper.rb' + +# Offense count: 7 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: empty, nil, both +Style/EmptyElse: + Exclude: + - 'app/helpers/admin_helper.rb' + - 'app/models/checklist/pdf/history_content.rb' + - 'app/models/cms_mapping_manager.rb' + - 'app/models/m_taxon_concept.rb' + - 'app/models/nomenclature_change/output.rb' + - 'app/models/rank.rb' + - 'app/models/trade/shipment.rb' + +# Offense count: 53 # Cop supports --auto-correct. # Configuration parameters: AllowAdjacentOneLineDefs. Style/EmptyLineBetweenDefs: Enabled: false -# Offense count: 41 +# Offense count: 67 # Cop supports --auto-correct. Style/EmptyLines: Enabled: false -# Offense count: 43 +# Offense count: 54 # Cop supports --auto-correct. Style/EmptyLinesAroundAccessModifier: Enabled: false -# Offense count: 357 +# Offense count: 253 # Cop supports --auto-correct. -Style/EmptyLinesAroundBody: +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: empty_lines, no_empty_lines +Style/EmptyLinesAroundBlockBody: Enabled: false -# Offense count: 3 +# Offense count: 351 +# Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. -Style/For: +# SupportedStyles: empty_lines, no_empty_lines +Style/EmptyLinesAroundClassBody: Enabled: false -# Offense count: 61 -# Configuration parameters: MinBodyLength. -Style/GuardClause: +# Offense count: 11 +# Cop supports --auto-correct. +Style/EmptyLinesAroundMethodBody: + Exclude: + - 'app/models/listing_change_observer.rb' + - 'app/models/m_taxon_concept_filter_by_appendix_population_query.rb' + - 'app/models/nomenclature_change/status_change/processor_helpers.rb' + - 'app/models/species/cites_listings_export.rb' + - 'app/models/trade/filter.rb' + - 'db/migrate/20140606102741_create_nomenclature_change_inputs.rb' + - 'db/migrate/20140811101246_add_timestamps_to_documents.rb' + - 'db/migrate/20140918090432_create_document_proposal_details.rb' + - 'db/migrate/20141014125738_change_multi_permit_number_columns_to_text.rb' + - 'db/migrate/20150421112808_create_unique_index_on_taxon_concept_references.rb' + +# Offense count: 71 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: empty_lines, no_empty_lines +Style/EmptyLinesAroundModuleBody: + Enabled: false + +# Offense count: 97 +# Cop supports --auto-correct. +# Configuration parameters: AllowForAlignment, ForceEqualSignAlignment. +Style/ExtraSpacing: Enabled: false -# Offense count: 8266 +# Offense count: 193 # Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. +# SupportedStyles: consistent, special_for_inner_method_call, special_for_inner_method_call_in_parentheses +Style/FirstParameterIndentation: + Enabled: false + +# Offense count: 3 # Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: for, each +Style/For: + Enabled: false + +# Offense count: 6 +# Configuration parameters: MinBodyLength. +Style/GuardClause: + Exclude: + - 'app/models/annotation_observer.rb' + - 'app/models/cites_suspension_notification.rb' + - 'app/models/nomenclature_change.rb' + - 'app/models/nomenclature_change/lump.rb' + - 'app/models/nomenclature_change/split.rb' + - 'lib/tasks/bbgem.rake' + +# Offense count: 8225 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles, UseHashRocketsWithSymbolValues. +# SupportedStyles: ruby19, ruby19_no_mixed_keys, hash_rockets Style/HashSyntax: Enabled: false -# Offense count: 31 +# Offense count: 3 +Style/IfInsideElse: + Exclude: + - 'app/controllers/api/v1/documents_controller.rb' + - 'app/models/checklist/pdf/helpers.rb' + - 'app/models/checklist/timeline.rb' + +# Offense count: 33 +# Cop supports --auto-correct. # Configuration parameters: MaxLineLength. Style/IfUnlessModifier: Enabled: false -# Offense count: 24 +# Offense count: 68 # Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. +# SupportedStyles: special_inside_parentheses, consistent, align_brackets Style/IndentArray: Enabled: false -# Offense count: 316 +# Offense count: 2 +# Cop supports --auto-correct. +# Configuration parameters: IndentationWidth. +Style/IndentAssignment: + Exclude: + - 'app/models/nomenclature_change/split/constructor.rb' + - 'app/models/taxon_concept.rb' + +# Offense count: 329 # Cop supports --auto-correct. -# Configuration parameters: EnforcedStyle, SupportedStyles. +# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. +# SupportedStyles: special_inside_parentheses, consistent, align_braces Style/IndentHash: Enabled: false -# Offense count: 189 +# Offense count: 82 # Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: normal, rails Style/IndentationConsistency: Enabled: false # Offense count: 126 # Cop supports --auto-correct. +# Configuration parameters: Width. Style/IndentationWidth: Enabled: false -# Offense count: 11 +# Offense count: 12 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: line_count_dependent, lambda, literal Style/Lambda: - Enabled: false + Exclude: + - 'app/models/designation.rb' + - 'app/models/taxon_concept.rb' + - 'app/models/taxonomy.rb' -# Offense count: 182 +# Offense count: 180 # Cop supports --auto-correct. Style/LeadingCommentSpace: Enabled: false @@ -280,141 +569,278 @@ Style/LeadingCommentSpace: # Offense count: 1 # Cop supports --auto-correct. Style/LineEndConcatenation: - Enabled: false + Exclude: + - 'app/helpers/admin_helper.rb' -# Offense count: 6 +# Offense count: 10 # Cop supports --auto-correct. Style/MethodCallParentheses: - Enabled: false + Exclude: + - 'app/controllers/trade/exports_controller.rb' + - 'app/controllers/trade/statistics_controller.rb' + - 'app/models/nomenclature_change/split/constructor.rb' + - 'lib/tasks/import_countries.rake' + - 'lib/tasks/map_eu_opinions_to_ec_srgs.rake' + - 'lib/tasks/map_eu_suspensions_to_terminating_regulations.rake' + - 'lib/tasks/taxonomy_mapping.rake' + - 'lib/tasks/update_eu_decisions_with_missing_source.rake' # Offense count: 60 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: require_parentheses, require_no_parentheses, require_no_parentheses_except_multiline Style/MethodDefParentheses: Enabled: false -# Offense count: 4 +# Offense count: 16 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: symmetrical, new_line, same_line +Style/MultilineArrayBraceLayout: + Exclude: + - 'app/models/country_dictionary.rb' + - 'app/models/quota.rb' + - 'app/models/taxon_concept.rb' + - 'app/models/trade/validation_rule.rb' + - 'app/workers/permit_cleanup_worker.rb' + - 'app/workers/quotas_copy_worker.rb' + - 'lib/modules/downloads_cache.rb' + - 'lib/modules/trade/appendix_report.rb' + - 'lib/modules/trade/species_without_legislation_or_trade_report.rb' + +# Offense count: 2 Style/MultilineBlockChain: - Enabled: false + Exclude: + - 'app/models/trade/filter.rb' -# Offense count: 26 +# Offense count: 38 # Cop supports --auto-correct. Style/MultilineBlockLayout: Enabled: false -# Offense count: 8 -Style/MultilineTernaryOperator: +# Offense count: 7 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: symmetrical, new_line, same_line +Style/MultilineHashBraceLayout: + Exclude: + - 'app/controllers/admin/simple_crud_controller.rb' + - 'app/controllers/admin/taxon_concepts_controller.rb' + - 'app/models/checklist/pdf/index_query.rb' + - 'app/models/preset_tag.rb' + - 'spec/controllers/api/taxon_concepts_controller_spec.rb' + - 'spec/controllers/trade/shipments_controller_spec.rb' + +# Offense count: 147 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: symmetrical, new_line, same_line +Style/MultilineMethodCallBraceLayout: Enabled: false -# Offense count: 14 +# Offense count: 370 # Cop supports --auto-correct. -Style/NegatedIf: +# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. +# SupportedStyles: aligned, indented +Style/MultilineMethodCallIndentation: Enabled: false -# Offense count: 20 +# Offense count: 95 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles, IndentationWidth. +# SupportedStyles: aligned, indented +Style/MultilineOperationIndentation: + Enabled: false + +# Offense count: 7 +Style/MultilineTernaryOperator: + Exclude: + - 'app/models/nomenclature_change/lump.rb' + - 'app/models/quota.rb' + - 'app/workers/quotas_copy_worker.rb' + +# Offense count: 69 +# Cop supports --auto-correct. +Style/MutableConstant: + Enabled: false + +# Offense count: 13 +# Cop supports --auto-correct. +Style/NegatedIf: + Exclude: + - 'app/controllers/admin/quotas_controller.rb' + - 'app/models/checklist/history.rb' + - 'app/models/checklist/index.rb' + - 'app/models/checklist/timeline.rb' + - 'app/models/document_search.rb' + - 'app/models/eu_suspension.rb' + - 'app/models/nomenclature_change/split.rb' + - 'app/models/taxon_concept.rb' + - 'app/models/trade_restriction.rb' + - 'app/uploaders/trade/csv_source_file_uploader.rb' + - 'lib/csv_column_headers_validator.rb' + - 'lib/tasks/helpers_for_import.rb' + +# Offense count: 19 +# Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, MinBodyLength, SupportedStyles. +# SupportedStyles: skip_modifier_ifs, always Style/Next: Enabled: false # Offense count: 1 # Cop supports --auto-correct. Style/NilComparison: - Enabled: false + Exclude: + - 'app/models/trade/trade_data_download_logger.rb' # Offense count: 4 # Cop supports --auto-correct. Style/Not: - Enabled: false + Exclude: + - 'app/models/checklist/csv/history_content.rb' + - 'app/models/checklist/csv/index_content.rb' + - 'app/models/checklist/pdf/history_content.rb' + - 'app/models/checklist/pdf/index_content.rb' -# Offense count: 12 +# Offense count: 13 # Cop supports --auto-correct. Style/NumericLiterals: MinDigits: 15 -# Offense count: 5 -Style/OneLineConditional: - Enabled: false - # Offense count: 2 # Cop supports --auto-correct. +Style/ParallelAssignment: + Exclude: + - 'lib/modules/latex_to_pdf.rb' + +# Offense count: 5 +# Cop supports --auto-correct. # Configuration parameters: AllowSafeAssignment. Style/ParenthesesAroundCondition: - Enabled: false + Exclude: + - 'app/models/checklist/higher_taxa_injector.rb' + - 'app/models/taxon_concept.rb' + - 'app/models/trade/annual_report_upload.rb' + - 'app/models/trade/sandbox.rb' + - 'lib/csv_column_headers_validator.rb' -# Offense count: 6 +# Offense count: 9 # Cop supports --auto-correct. # Configuration parameters: PreferredDelimiters. Style/PercentLiteralDelimiters: - Enabled: false + Exclude: + - 'config/deploy.rb' + - 'config/deploy/elibrary_staging.rb' + - 'config/deploy/production.rb' + - 'config/deploy/staging.rb' + - 'config/initializers/exception_notification.rb' + - 'config/initializers/preload_sti_models.rb' + - 'lib/modules/latex_to_pdf.rb' -# Offense count: 5 +# Offense count: 7 # Cop supports --auto-correct. Style/PerlBackrefs: - Enabled: false + Exclude: + - 'app/models/taxon_concept.rb' + - 'app/models/trade/validation_rule.rb' + - 'lib/modules/latex_to_pdf.rb' + - 'lib/tasks/elibrary/citations_importer.rb' + - 'lib/tasks/elibrary/documents_importer.rb' -# Offense count: 34 -# Configuration parameters: NamePrefix, NamePrefixBlacklist. +# Offense count: 41 +# Configuration parameters: NamePrefix, NamePrefixBlacklist, NameWhitelist. +# NamePrefix: is_, has_, have_ +# NamePrefixBlacklist: is_, has_, have_ +# NameWhitelist: is_a? Style/PredicateName: Enabled: false -# Offense count: 17 +# Offense count: 16 # Cop supports --auto-correct. Style/Proc: - Enabled: false + Exclude: + - 'app/controllers/api/v1/geo_entities_controller.rb' + - 'app/controllers/api/v1/purposes_controller.rb' + - 'app/controllers/api/v1/sources_controller.rb' + - 'app/controllers/api/v1/terms_controller.rb' + - 'app/controllers/api/v1/units_controller.rb' + - 'app/controllers/checklist/geo_entities_controller.rb' + - 'app/models/nomenclature_change/lump.rb' + - 'app/models/nomenclature_change/output.rb' + - 'app/models/taxon_relationship.rb' -# Offense count: 2 +# Offense count: 3 # Cop supports --auto-correct. Style/RedundantBegin: - Enabled: false + Exclude: + - 'app/models/iucn_mapping_manager.rb' + - 'lib/tasks/helpers_for_import.rb' -# Offense count: 3 +# Offense count: 1 +# Cop supports --auto-correct. +Style/RedundantParentheses: + Exclude: + - 'app/models/trade/inclusion_validation_rule.rb' + +# Offense count: 4 # Cop supports --auto-correct. # Configuration parameters: AllowMultipleReturnValues. Style/RedundantReturn: - Enabled: false + Exclude: + - 'app/models/checklist/checklist.rb' + - 'app/models/eu_suspension.rb' + - 'app/models/m_taxon_concept.rb' + - 'app/models/nomenclature_change/output.rb' -# Offense count: 224 +# Offense count: 249 # Cop supports --auto-correct. Style/RedundantSelf: Enabled: false -# Offense count: 1 -Style/RegexpLiteral: - MaxSlashes: 0 - -# Offense count: 5 +# Offense count: 4 +# Cop supports --auto-correct. Style/RescueModifier: - Enabled: false + Exclude: + - 'app/models/document_search_params.rb' + - 'config/deploy.rb' -# Offense count: 10 +# Offense count: 12 # Cop supports --auto-correct. # Configuration parameters: AllowAsExpressionSeparator. Style/Semicolon: - Enabled: false + Exclude: + - 'app/controllers/admin/documents_controller.rb' + - 'app/controllers/admin/simple_crud_controller.rb' + - 'app/controllers/api/v1/documents_controller.rb' + - 'spec/models/checklist/timeline_spec.rb' + - 'spec/models/nomenclature_change/lump/constructor_spec.rb' + - 'spec/models/nomenclature_change/split/constructor_spec.rb' + - 'spec/models/trade/annual_report_upload_spec.rb' + - 'spec/models/user_spec.rb' -# Offense count: 11 +# Offense count: 2 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: only_raise, only_fail, semantic Style/SignalException: - Enabled: false + Exclude: + - 'lib/tasks/elibrary/import.rake' -# Offense count: 28 +# Offense count: 37 # Cop supports --auto-correct. # Configuration parameters: AllowIfMethodIsEmpty. Style/SingleLineMethods: Enabled: false -# Offense count: 1265 -# Cop supports --auto-correct. -Style/SingleSpaceBeforeFirstArg: - Enabled: false - -# Offense count: 1 +# Offense count: 6 # Cop supports --auto-correct. Style/SpaceAfterColon: - Enabled: false + Exclude: + - 'app/helpers/taxon_concept_helper.rb' + - 'lib/tasks/resolve_host_to_country.rake' -# Offense count: 83 +# Offense count: 98 # Cop supports --auto-correct. Style/SpaceAfterComma: Enabled: false @@ -422,112 +848,257 @@ Style/SpaceAfterComma: # Offense count: 1 # Cop supports --auto-correct. Style/SpaceAfterMethodName: - Enabled: false + Exclude: + - 'app/models/dashboard_stats.rb' -# Offense count: 9 +# Offense count: 4 +# Cop supports --auto-correct. +Style/SpaceAfterNot: + Exclude: + - 'app/models/checklist/csv/history_content.rb' + - 'app/models/checklist/csv/index_content.rb' + - 'app/models/checklist/pdf/history_content.rb' + - 'app/models/checklist/pdf/index_content.rb' + +# Offense count: 12 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: space, no_space Style/SpaceAroundEqualsInParameterDefault: Enabled: false -# Offense count: 84 +# Offense count: 101 # Cop supports --auto-correct. +# Configuration parameters: AllowForAlignment. Style/SpaceAroundOperators: Enabled: false -# Offense count: 924 +# Offense count: 1001 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: space, no_space Style/SpaceBeforeBlockBraces: Enabled: false # Offense count: 2 # Cop supports --auto-correct. Style/SpaceBeforeComment: - Enabled: false + Exclude: + - 'lib/modules/latex_to_pdf.rb' + - 'lib/scripts/get_listed_species_per_country.rb' + +# Offense count: 2 +# Cop supports --auto-correct. +# Configuration parameters: AllowForAlignment. +Style/SpaceBeforeFirstArg: + Exclude: + - 'app/serializers/trade/inclusion_validation_rule_serializer.rb' + - 'app/serializers/trade/species_name_appendix_year_validation_rule_serializer.rb' -# Offense count: 292 +# Offense count: 326 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles, EnforcedStyleForEmptyBraces, SpaceBeforeBlockParameters. +# SupportedStyles: space, no_space Style/SpaceInsideBlockBraces: Enabled: false -# Offense count: 12 +# Offense count: 13 # Cop supports --auto-correct. Style/SpaceInsideBrackets: - Enabled: false + Exclude: + - 'app/helpers/admin/nomenclature_changes_helper.rb' + - 'app/models/country_dictionary.rb' + - 'app/models/quota.rb' + - 'app/models/trade/taxon_concept_appendix_year_validation_rule.rb' + - 'config/initializers/devise.rb' + - 'config/routes.rb' + - 'old_cap/deploy.rb' -# Offense count: 625 +# Offense count: 698 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, EnforcedStyleForEmptyBraces, SupportedStyles. +# SupportedStyles: space, no_space Style/SpaceInsideHashLiteralBraces: Enabled: false -# Offense count: 16 +# Offense count: 35 # Cop supports --auto-correct. Style/SpaceInsideParens: - Enabled: false + Exclude: + - 'app/helpers/taxon_concept_helper.rb' + - 'app/models/eu_suspension.rb' + - 'app/models/events_by_type_stats.rb' + - 'app/models/m_taxon_concept.rb' + - 'app/models/taxon_concept_reference.rb' + - 'app/uploaders/trade/csv_source_file_uploader.rb' + - 'lib/capistrano/tasks/smoke_test.rake' + - 'lib/tasks/elibrary/citations_cop_importer.rb' + - 'lib/tasks/elibrary/citations_importer.rb' + - 'lib/tasks/elibrary/citations_rst_importer.rb' + - 'lib/tasks/elibrary/document_discussions_importer.rb' + - 'lib/tasks/elibrary/documents_importer.rb' + - 'old_cap/deploy.rb' + - 'spec/controllers/admin/taxon_eu_suspensions_controller_spec.rb' + - 'spec/controllers/admin/taxon_listing_changes_controller_spec.rb' + +# Offense count: 6 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: space, no_space +Style/SpaceInsideStringInterpolation: + Exclude: + - 'app/helpers/admin/trade_codes_helper.rb' + - 'lib/tasks/import_distribution_tags.rake' + - 'lib/tasks/import_distributions.rake' + - 'lib/tasks/import_synonyms.rake' # Offense count: 4 # Cop supports --auto-correct. +# Configuration parameters: SupportedStyles. +# SupportedStyles: use_perl_names, use_english_names Style/SpecialGlobalVars: + EnforcedStyle: use_perl_names + +# Offense count: 6753 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles, ConsistentQuotesInMultiline. +# SupportedStyles: single_quotes, double_quotes +Style/StringLiterals: Enabled: false -# Offense count: 6991 +# Offense count: 47 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. -Style/StringLiterals: +# SupportedStyles: single_quotes, double_quotes +Style/StringLiteralsInInterpolation: Enabled: false +# Offense count: 2 +# Cop supports --auto-correct. +Style/SymbolLiteral: + Exclude: + - 'lib/tasks/elibrary/document_discussions_importer.rb' + - 'lib/tasks/elibrary/users_importer.rb' + # Offense count: 16 # Cop supports --auto-correct. # Configuration parameters: IgnoredMethods. +# IgnoredMethods: respond_to, define_method Style/SymbolProc: - Enabled: false - -# Offense count: 20 + Exclude: + - 'app/controllers/trade/shipments_controller.rb' + - 'app/models/checklist/checklist.rb' + - 'app/models/nomenclature_change/delete_unreassigned_processor.rb' + - 'app/models/nomenclature_change/processor.rb' + - 'app/models/nomenclature_change/split/constructor.rb' + - 'app/models/nomenclature_change/split/processor.rb' + - 'app/models/trade/batch_update.rb' + - 'app/models/trade/trade_data_download_logger.rb' + - 'app/serializers/trade/show_annual_report_upload_serializer.rb' + - 'lib/tasks/db_migrate_plpgsql.rake' + - 'lib/tasks/elibrary/importable.rb' + - 'spec/models/nomenclature_change/lump/constructor_spec.rb' + - 'spec/models/nomenclature_change/split/constructor_spec.rb' + +# Offense count: 23 # Cop supports --auto-correct. Style/Tab: - Enabled: false + Exclude: + - 'app/controllers/admin/hash_annotations_controller.rb' + - 'app/controllers/trade/statistics_controller.rb' + - 'app/serializers/species/geo_entity_serializer.rb' + - 'app/serializers/trade/inclusion_validation_rule_serializer.rb' + - 'spec/controllers/api/taxon_concepts_controller_spec.rb' + - 'spec/models/checklist/scientific_name_spec.rb' -# Offense count: 127 +# Offense count: 130 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: final_newline, final_blank_line Style/TrailingBlankLines: Enabled: false -# Offense count: 12 +# Offense count: 5 # Cop supports --auto-correct. # Configuration parameters: EnforcedStyleForMultiline, SupportedStyles. -Style/TrailingComma: - Enabled: false +# SupportedStyles: comma, consistent_comma, no_comma +Style/TrailingCommaInArguments: + Exclude: + - 'spec/models/checklist/pdf/index_fetcher_spec.rb' + - 'spec/models/taxon_concept/validation_spec.rb' + - 'spec/shared/colophon.rb' -# Offense count: 114 +# Offense count: 7 # Cop supports --auto-correct. -Style/TrailingWhitespace: - Enabled: false +# Configuration parameters: EnforcedStyleForMultiline, SupportedStyles. +# SupportedStyles: comma, consistent_comma, no_comma +Style/TrailingCommaInLiteral: + Exclude: + - 'app/controllers/admin/iucn_mappings_controller.rb' + - 'config/deploy.rb' + - 'lib/modules/trade/appendix_report.rb' + - 'spec/controllers/cites_trade/shipments_controller_spec.rb' -# Offense count: 1 +# Offense count: 98 # Cop supports --auto-correct. -# Configuration parameters: ExactNameMatch, AllowPredicates, AllowDSLWriters, Whitelist. -Style/TrivialAccessors: +Style/TrailingWhitespace: Enabled: false -# Offense count: 3 +# Offense count: 7 +# Cop supports --auto-correct. Style/UnlessElse: - Enabled: false + Exclude: + - 'app/controllers/api/v1/documents_controller.rb' + - 'app/controllers/trade/annual_report_uploads_controller.rb' + - 'app/models/checklist/timeline.rb' + - 'app/models/nomenclature_change/split/processor.rb' + - 'app/models/nomenclature_change/status_change_processor.rb' + - 'app/models/nomenclature_change/taxonomic_tree_name_resolver.rb' -# Offense count: 16 +# Offense count: 25 +# Cop supports --auto-correct. +Style/UnneededInterpolation: + Exclude: + - 'app/helpers/admin/nomenclature_changes_helper.rb' + - 'app/helpers/admin/trade_codes_helper.rb' + - 'app/helpers/admin_helper.rb' + - 'app/models/checklist/pdf/history_content.rb' + - 'app/models/checklist/pdf/index_content.rb' + - 'app/models/cms_mapping_manager.rb' + - 'app/uploaders/trade/csv_source_file_uploader.rb' + - 'lib/psql_command.rb' + - 'lib/scripts/get_listed_species_per_country.rb' + - 'old_cap/deploy.rb' + - 'spec/controllers/admin/event_documents_controller_spec.rb' + - 'spec/factories/listings.rb' + - 'spec/models/listing_change_spec.rb' + - 'spec/models/species/documents_export_spec.rb' + +# Offense count: 18 # Configuration parameters: EnforcedStyle, SupportedStyles. +# SupportedStyles: snake_case, camelCase Style/VariableName: Enabled: false -# Offense count: 2 +# Offense count: 1 # Cop supports --auto-correct. Style/WhileUntilDo: - Enabled: false + Exclude: + - 'app/models/trade_restriction.rb' -# Offense count: 149 +# Offense count: 314 # Cop supports --auto-correct. +# Configuration parameters: EnforcedStyle, SupportedStyles, MinSize, WordRegex. +# SupportedStyles: percent, brackets Style/WordArray: - MinSize: 13 + Enabled: false + +# Offense count: 12 +# Cop supports --auto-correct. +Style/ZeroLengthPredicate: + Exclude: + - 'app/models/checklist/checklist.rb' + - 'app/models/checklist/timelines_for_taxon_concept.rb' + - 'app/models/listing_change_observer.rb' + - 'app/models/trade/batch_update.rb' + - 'spec/models/listing_change_spec.rb' diff --git a/Gemfile b/Gemfile index 805715ef84..0574aecd27 100644 --- a/Gemfile +++ b/Gemfile @@ -107,6 +107,7 @@ group :development do gem 'webrick', '1.3.1' gem 'jslint_on_rails' gem 'git_pretty_accept' + gem 'rubocop', '~> 0.40.0', require: false end group :test, :development do diff --git a/Gemfile.lock b/Gemfile.lock index b9867a8df1..f8a89afe40 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -70,6 +70,7 @@ GEM rack thread_safe arel (3.0.3) + ast (2.2.0) barber (0.4.2) ember-source execjs @@ -286,6 +287,8 @@ GEM paper_trail (4.0.0.beta2) activerecord (>= 3.0, < 6.0) activesupport (>= 3.0, < 6.0) + parser (2.3.1.0) + ast (~> 2.2) pg (0.17.1) pg-hstore (1.2.0) pg_array_parser (0.0.9) @@ -294,6 +297,7 @@ GEM activesupport (>= 3) polyglot (0.3.5) power_assert (0.2.4) + powerpack (0.1.1) pry (0.9.11.4) coderay (~> 1.0.5) method_source (~> 0.8) @@ -329,6 +333,7 @@ GEM rake (>= 0.8.7) rdoc (~> 3.4) thor (>= 0.14.6, < 2.0) + rainbow (2.0.0) rake (10.0.4) rdoc (3.12.2) json (~> 1.4) @@ -356,6 +361,13 @@ GEM rspec-core (~> 2.12.0) rspec-expectations (~> 2.12.0) rspec-mocks (~> 2.12.0) + rubocop (0.40.0) + parser (>= 2.3.1.0, < 3.0) + powerpack (~> 0.1) + rainbow (>= 1.99.1, < 3.0) + ruby-progressbar (~> 1.7) + unicode-display_width (~> 1.0, >= 1.0.1) + ruby-progressbar (1.7.5) rubyzip (1.1.7) sass (3.2.7) sass-rails (3.2.6) @@ -431,6 +443,7 @@ GEM unf (0.1.4) unf_ext unf_ext (0.0.7.2) + unicode-display_width (1.0.5) user_agent_parser (2.1.5) uuidtools (2.1.4) warden (1.2.6) @@ -519,6 +532,7 @@ DEPENDENCIES rest-client rspec-mocks rspec-rails + rubocop (~> 0.40.0) rubyzip (>= 1.0.0) sass-rails (~> 3.2.3) select2-rails (~> 3.5.7) diff --git a/vendor/cache/ast-2.2.0.gem b/vendor/cache/ast-2.2.0.gem new file mode 100644 index 0000000000000000000000000000000000000000..d5794298f2a76111d39013ea09fae39a66ba5c07 GIT binary patch literal 14848 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%0A)F{k2TnPt3Lj=dN-b+mL6HcP9GS43vJ*H%6J-7t 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 literal 0 HcmV?d00001 diff --git a/vendor/cache/parser-2.3.1.0.gem b/vendor/cache/parser-2.3.1.0.gem new file mode 100644 index 0000000000000000000000000000000000000000..492c6681668f7cffd64ee6581b234e5069fe00e0 GIT binary patch literal 556544 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

eA1k!~4m8mbv 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

6Kq^j`}_U1wgJ%6 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 )ub7n7v=> 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

W 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

kfvEoLr~+^o)&lkw^Zkg09=O8AM-X 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
>^nviqr`Fof7DxVvfBa8SnCeQwrm*jSz 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 aDJg{gKfO% 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 DqS#Y& literal 0 HcmV?d00001 diff --git a/vendor/cache/rainbow-2.0.0.gem b/vendor/cache/rainbow-2.0.0.gem new file mode 100644 index 0000000000000000000000000000000000000000..f22b5e65a1b8008ef752be7258874050e182e7f3 GIT binary patch literal 14336 zcmeHtWo#xvliq7)_L`ZQne8>(Yqr?M)z^yM!3bEibn z*HWo^x->Oa)taYAHII#nvw^XJvjKydC*Z$oF#R2DY;1sk(SOH3YGyVzCIB-F3nvpB zJ0~Xx2Y`v0m5rSpK*aQ470|!+>*C~W;P^KrH**sc>wjzbhxz}>{y%d2*W~`;_WxHe z38SC^PkQ@GpkSA3GIonh$UW~rgBNn{G(Cw?zo}~F!>)sg;R#VWW~~iX8R2eNbP~N> zMkig^E>xvd@OfIeHsA8`eVJaoE*oG$&d6$28LE1N95<}Y8m|>Yj$mdfj{YJ`A(f0wU#3O1ppTyQ-TaTGiM9B^ZWhjn$xX>O@3Y5= zzLgYQ?KpJplucuh9vH9#M>W!5x|fIa_qR>v`R4Buq-IBZOi{lef-#F>=i@eZI z>j=iiOZgZQxK5x+sMQK}>@S5-Kd_;x;vg1#`vXw&pu(t0R&?1xa#Nwad~Np{3tjq+ zWJb~w98k_aO$oRFw!<~J(!d8e8`1Ah$}}mAFYBd*26<)su|H8g=HSu-4W%V2#obXT zbscymN7;XUOKFYFKoy&sg}NwXXZsQxC>s%;Ix?d>EH`S=HI%8i=3d-CS z<3si}j;tp!?ZHxJKSt3Cdn_+$kuD32EY}qhTeGZ4tw!d~L5g~Z;ay%gIwwA?J{XXz z9>kDGSP8Z4j%}6e4lMbT&va9}YUg9pAt;8YB|#pvsr9CTmP#1& zw5e=nvCZ_hwX)2c+6(2tnVF>DQFC0eTijaB9!3jZa)#|~jjiZiFzJ1KBDiqIs_3p? zssQ;xOBT4!ZPUm#Vx-p^a-F;C*m5XRH7Nydwkqi3m6h8~iNF=f37P@1bHQD*Q zACF0DLyTOq~0b7ys1O5 zpQrC~EB-+F=hs5b2gD@2)G|K&|Eq89e_mYw9sBTU_-wru@ z`3zqCrU*jeoa$k1uL}$HuxbY@wd>kHfb$yqov_f$!h?2NHy4hiJ3u;fDxKDIAJDlR zk9$*S9etszp>muux;&Joi+})nU(%)L`nu@gGjr2^lKOe8;vI08b1B>L0QdshetP)F zolSen?WAY49?TWq`Wewq1GScpGk}Eq_XB4$Bi{R30ynyo`c?e(o_$;Nt_CrDwpf?9 zi@jT|l$#qa`1)rj)4Lo9SItK{1Un*PoECOF_P}{;Jawa-r>9l7%W?aiC*k1eF7$Br z+-+Rod(C72(^b+Z=AEBQC(a2_ys_gL81^!z+F{lHy>^&`v(`p`F?}YKRec5Fc@V4J zAxZT&;Z(+(TB#j-qoLYiYsJU$lkMsCbzRjaPUwo;W%-UFcR=VZ?zUNt%dnGG$`_A- zSL(9yn8frf9uh$W&}u{Kvv*DV4-n~YOH?uo-bcvsCv%Aq`lg#7n`?#O-c(uT@tgh+P!7(@ABqR==YdB| z&_rt?2Q10>fF2`TW-At=2xV2(MU!trix{eV(r=?hhVIt8vUdWwGeX6CQ@w{%4ww1- zAPxLVtZ57H+0Q;@Z?5pBwH0l|v^8p+RvRjfa>~{1!*A1L4*VMa>)O@Uwl=W(W|27P z{f;WS0A&w-uYFu62CV0|<>c?=VAC}^Ry-jm3ey>{)27hS3)Ta%^166Eyap|!6o|+Z za&o>1b<$lzg+rB|Ox-h;1vB}8ub*)kXS@g0RKEOP#_z50VuD^yiwPtGRC-7gD;%vU zbbs>z+YIp`4NXGQx!MaxVY6ns))uE0Ji`PvY^ug&W z%WUcqbY4bPz|?ii?_8zrJ6t_sp<97)H?u0^;0v;XiHwK#QCK!|e&&oUsdMs^0&NlI zK&PQj@bkAkYzRk481nRpgG(@7W)zJ*KCI-;kb}d>l1Zo&&36bv4i4JBK?F;`xDwf! zbG`BuiMBS3v3*HusRBd%_mLbXD*j!}W$Q!6a($_t>Fyfls0W}pe+_V@MTlIz7Kn6n zo0Senm(~05S-wJ(>Hv!Py2^_0mKL@)8e7_Br?*)U?1bE6WTvBas;b})~4Lv!Qk!gjfzGy;yx2|h}_#wF@{z}$PVK*+J{TAq>!XCpSC zMlVOTfmXjf`Fp-raAVkkg5ki?^zA?t*Rw{E-mz_UbESH}DePo4b zM|rx4I!wwhdEg_cC+1lGh!=<+F!Y#A<=Az(VHn?MpsE2e7;q2!XY?X(sR}VC+Ak{@ zl9+6qbTdwG9OkQS$yNc-p@z`OPE0#7oAq=Fw5W+7P+lnEq6-4)6_`O$8 z(C8p8se;z8Z|9(`gtEieag-#O{D;#F!`>RApsydv)hQEFgfMlcHevD(!7OXQbi}d7 ztw5TIUP4%LxK{?=vf-_*6INKF(cDcQh4ug}JcPal!y zcf>M5lD8+soiEQtkH@#*Zh=j|xzMngjS*k7=T~2?yg>2G%WK!|dk1H2&S)DRRZ= zRWNFp3QRJud6Z^drG~L60Nk&a*EX!F%l!K4yUwV(Iuyssz$Y-&;jMMygw-o}TYNIt!z@JT8k2bccTbF5Km#RSz)|0M zu3V_#vk>*Eo&c^^&dk<+B6(D}1Jc%>R~#di$_Mv8&S$WiVg0o^pb&^Qy6$IU(_@~?d@=CZdxvG+Pbd!lZ{k^(69 zBlN>4weK1nAS*B`6j@HmG_7BidhdkfJNGl>n?vo|C?S_QZkcZSK6|8m=iLY> z@~|lpakUh3_|zJb%8;GuTYd$=itFkfmC@%|b%#eP5su7rah9v>N$jnN`8~@6BG&8V zp*hvxLuJhdxda7E!`*h{rYG}fa7R?Q&zy?<`u&6=Zr~cPHDZyEceT*rXEz;H?$qs| z`??MC$$c>w;1q8PDOChcDXwBKU?T=?LL}x@vYeUgC^1}L+xVT zxP&Fp_2GdkquA~+Y+;`yo;3RYb-8Xkt|C3N9fYMeD#J?@b^y+JuniIUmv*dD0r*(^ zlib0kW5bRtxTE(ELw7`)Y8#Ku?{;4vT=@@<-2mx6g-WJq`x;I0UM3Ycv7HN;5s~2q znO&LN*)X0r1!~CLnmLB}ZEqr6F1;VV0y!~sI}Y6>71IXb`F8nlm)v=YGLZR>T-5cv zbZf+Hq-QbYu#wZJF?kjzB+e{(z2EB=DIR`A7g-O=D)2&(gSiZixI5BaA-h!%g(&cqUo}#BvZ0V z_l6Kk=jt&o03KAJW+eMEEZ@gjlD%3%p8w3TQ`>onfMbF5&%=_yg;xy?;i=}E>Ob}f zc945f=T!@WR;EyE_{U8r&6VG)wam`;DfmwHiN=H@Qm1O(@YBF6k%g82cu)aJq~=O= z3=-c1SJc)ro}J;d&TeVh3l3v&7%_rJ&g(y$3avx;pmHkhn6g$=>c2 zkRXbKHhh(eK?hrtp*vvvOhsT&I0mIvw}tA2b~1=e0s3rD15VmzJyjFTIs`byHW$R2 zni@wooL%6ejS{9q)2ad7{0Kz7fZa+-VI_s1wopVZ9@cKy9MZ zF3Tqb^QfaP9Pv2KU2{IwJU!_HJf+bDM<5O(;2CEv&z1yaRY!)XFb>{8Dd&C%I&nfT zAiK^ffW5({YGDD0Kt0brN$?SbR;+pYR;jC7ledY2R@J=+j9Bz)vb@O70{fGNfhUL! zWRI`y$QyeXAyA(JxsWVMDak#NDZ;hK4G_*1=dpct+R$rmnnK+@zuRp-fF>PZ&$^ zeh|0=m|1+}Wj*93Onf3R@P3kC(_;8c_w6u3L&;qJb%yR7Wn=|b`gn=MLF|B20nf** z{+mF^gM~Us#Tz6HUQ%k|o=E8Q;Q`%L`9OM!hR` zS4(b{=1uD|1PD{C>mcrnas6U#^>srlp52@uV?Ya9gh?v0FaZ0? z-|xl`A6>EqvTFzxtH2uYZ?RleVI-ub@P6wO5_3a%Sd_m>>iCTSRWx1}ZZ{zJYzj0< zwzZWPWJHGaVce`oY+=PwKOZtR3j^uWi9m*omBQL6))+4kp|abV)SjRa@fj=;#Yv_( zK(C;&M*IZ@UcXC0f<`7JTSzw`CcsGI5SSbmgfB9~mE<9th|FE_rrok87Np_0qRca; zwa?pw6*}&37&#BnG>Z_O^PnN3k(^Qy33uPtX0PIQ$8%&F=lGtBDiCf}5CIIp>Hv5@ z>F``mzhONYf`4-rZ_-rEbT2^5g6ZHhGz>r4GmOrb`(7A2kkdzF@UAN^5U*}FcxFOY zl284u7|s^NY_AGCsLsFH%bs>b11olbZG;lfuMltb#$XZpbg9N0HoLURS{_q2C}7@vL*> zx2ec}-C$fMcs(AXHu7Ta&Xem1$(s5OLnGj0iq7Xx`sR8>g3sA} z`&ok08%sU?6}f-an5w=h;ssiYv}UHnBR|gvi1T$n zOnA2M^AsiQ16yled?*17o504U=o6q&LNgFZEI<>$v04M?z4=IgJuzwF3nN_zf{>Ex zaF5tM6U5`+9#FkZz&F~oOX~|dqZmWgR3|jYgdE=-=z^hU;aP7wSbGvgttQMhe8~?B z{7KvFN%Ga&9Sh{A0@Cgj&YIs#l^%v8Re#af@tWDl9(Ea{uWz!w(~Oue(uPg=031i5}m$W2KnV2%dbn=-I-;6*htzsy6?XOfuqV?gdwuQ=M} zN7kWv?aM-tK`9VE2EQT=+~4e)oGe*<&EJ0191w#5O^@oK*7qnCcEeUo&Swb-*U`SO zYE;ZWmkFml2g6DUw{;N%x&+u92qmpMYYrwHEw;pK?fDMNyuYW<{E?UaN*yoh2vgM$ z_^?}~x&0*ky{-xLN|TpOW5w8!EZs$h|*&5@AilNu)F z>qs{#N%?boMc#Wh5ze!uxcEjt?`H`*G}+&phy3=DyVrX>oB0U)im-W@gtXmpBiPMf zoo4zt^^jeoQ)UZM8+PvUo9$1;3jbq=LB@~EW^cdql-0T+Pcy}aVfa*|LEps_PwSQg z^@)>Jwf0YJiimR-f9R8IMwahK*h$s}x&SObgwjwBh9fOV8aK)a zxrz#Kxyu7)Btzgxf5@wQuuBJGZqnhsn$=moLqV7VH(+xW+29Fn!)A&U*9-;0X9O5= zXw5yj)Rma#f-mQFmlb%#h%sR(kbhiL{6vF~2n`TQ3~CvhyV0~hD2zRI8_hwFM~TdJ zsvxnEV^Se+ucRuS;~s7>8$N{3=y-yH7ZIgM7QvAIRyEYM-?|-09XQu81Rik{64fso zt#{5Pg$jVvM4P!n%wn#h5}69)*H|@_Pjerez~W-19VV%_;n6FC-%mQd6IpLUU&>Oj0p_j~cjXBkL12uymoW}+Z$vhz07e`PI@oiM}4_C_1+ z_6Y6KY*g@}7Hw9Z7c()(CYPGa0>eq@Pp(}1brw&bK3RMw{Z&{-c z@0M5be{D}MCS`0c=$J!e&=l8~NhcT`k}l^?36$2N*G~bIEJfCf&Asp(^*$`tY=Si1 ze8gFPeAJry_&>y+0z?CY_Q@PSC#wWV5 z5l$x%?1*!An1tiz#Un-OGrK|crB^=|+?Wm;4L=u0{e;h-HX|#*OUu9EKN}7CsQ^v^ z#{*i;b_b(O?)swM(II_=&&lrR<@2crYKwSG4PHu(cFEroHHkH`${%4i zh%dk4K)yLuvzY68dO=#mjVtCniMUTLoMji!lYJgr)Xw_kJY{L0M!1Up-k-%`kTT*y zFy}fkiR&7$T#a$j?AMd}+6g+D`abic!~XvE@lj`4^mwl_JPo`JH?kp?*=0 zt|;-7!~3&1IwLb?E;#|)-NtT^-`PZAVj*N1XaBVZld+H`NlIsBCfEjzcz|A{~KSF*G1kvB}O4rIb>i20+xz1>q<~Q5s zeCJPIETVR&4Z9oqZ|ZNw7H3`9gGs{3Hp3qtHKW(q?>e=DYY20O@Xi zSX#mo|3U`BkYP${|DsI^;$g@;DswU`{|T{Bu`&CWxeP9_(j6Ame4nXrXtZy&0 zE1|B)S;8a3pU-2gzdfEk%KGkMaaqV(Zj>cO;)8T@*$pagkDJcI+epmI?p?y7_p``$kIi{(eKk% zQO4jdd?**Z(Yuus;Qal&Vqy} z@X|c-^ML(50Vedf51AMZWNTf10v_A|1vex{vj@Qre{@6;o9zqF0QdhKy$kw&rse~o zPJpJY^*}Qp;D*sFFd2<&_!ScYdHNP~LNwkUh@7)^+ZyRgS~xedzV?xj_q8U;-@i|X^O3TBvZBFv$kgE z)+u&y{T|lI*kR`;ubbHz;bx)t0s)|g#Ho7Hw5jTUmZ~Rtl#8dVeQ8_bSw?~oWfXLW3&=;Wk?6MxNj z@A{|!CmeS>_m%33KM;wQIgBB9-bIApOX*A7m~gE$O5QN?nJ)f_DHRq|tfXV`BxgtU zWucOWC_XLeE}XGe{YyKVJ=uM<@C?98SQ3z78YJx2CwP;L$55YUC{+kq!Uq;LdLTOVK%PtvN_rRs-ZI%zYR79G%ZA(0j_Op<^pf)-f~@i z)C4ZEoQOL-Z>;4v%gbXwf1!oiJ`Wtwd#A+Z=BD~u>o%2@SXjV#S8EA;J6}XVKE-Sr zgk4G?p$I+y5`y|v;nf8{yV0riJ5t;PZ8d|X2~@_FX!VQC+nwq<1&MScR;?8uWpXIt zt1gIsqT%8ML;Mrv0)IX^F)kXmXR(4diS};7UcuOadr?9lXjwET9_g7gZ8C-V1I0JN zc^)Q~{S$nYYOa0P-Hc~QuN40}J5sy0iqJLV9rf)fAl1!E=;omo{YG*OxLfvnDFP^V zN2ohI>Xw1%ckd%q7og74?$6tkFpFq@!SuATJPV=N8cyN zCNFLApweCBK;S5JOo$X6l4aGJqLVAijp!@QvGD9SY!tm%5h~MLVbV;xc`-e zenv%sh?>A@MJKFA5(xwx{=SmjxiEls4(smx-Kg29VYsv|7h%JWfzo>4^xC9m^W}l6 zLCm+&?at|WkBQ0qOPsuyMf1ReS&u@tX{zlFbROqXP-f9_s$%Cb|D@V@UiCf6nV$2R zt>KF48K)9^hB3_xr(0&a`^W-c>*u*CNPv&hwQbuV zuW?Er;g6$9f&gCEZrM|NsH}I|nUkAT)~wYeX3xMWAh(rfr)^G(}Bndcu$sYocS#wuPe+DKefZ zAKI3z6gb=CqBCnolC9<0skp1WBvrXmyb#g!VzIJ4rB?P=@y^D<3zL$VCg(oL8JCTt zF{{;2Zm}sd56JSG?NaKOIZ`o%xiC6RT#AlFBEv~aJmhxd$$|PQg5NLhBNER2X(iE? zZ*3#u9Lz0mr>4=h$2{(u>FVH#2KuS^xHb){KX!6>6m+4ADEk=~!~+Lzt$TLt58KEH z{iw5PX6t<$3XWGEe66-o@<0Xt>49D7w zv~Xv5*tuoz*^`9qK5>+`MU+pNZRTjqLG&er;FOhZyC2$#Q+M6g!r~!Idws*lq0}qP zlraC?#Z(d8808UppR9*(H@z3$zt%S%8R(}L5?9c_#<%q0W`Gr=FTLUt z12wNe;t@ffS)I+7EI3AMifkdBLi#C^_8?tLs8Sgn$1IoO`a>Jpn<1((%JfDhpcUz2LT@ZC0nj;*=OQEcEc#YXPf0fc-S` z^QioJEVznq-&a^yC`hX7%>^rW5KhPW`ve#-lzeBNmd5JrS07~tSpqwxyFkOjxrVy3 zit~f}3TkN{_yCD(oGh%S2i%8Y6BYN*D2=uw45Mi~_%`-3mAgt|JtOa-GwGbyEp5YQ zE|Dw?_gS$+)6gzm8T~F|8%J0laj;leSMC8!lHx)r2S%dq8c99V93ik9fx=(Tnntg3 zU|HnL?iV!+bcbBP1I3knP5g*#P2yNFc?0*)yZn;<2L*TQcwCa)mY1l`3DFiy$Y+@~ zeXou($){V;h(rZqxj(-f$wO5K33zyp4Og=2oa#9DS1}PI+U`!K!B7>8dRmwjoA-U@ zl840bV=~Mcc<##u=2GHNMQW)`+-WtTMq?A?CH~y?YZtjoe0nD@brz7(dod^ls{6ON z{%jH{&yD)&PbZ|^OKZqRf&qUK%_y|qMyq7eFf~kTfRSgr{f&KH(&?6@541?jO-veN zO}h%b9&q`DKevw7L2bpb4L2&KuVcFQjs}<8^FUuLTqV7`Q)q6**Y#Io|4PbV3H>WM z|5N{6^9C!h$>)gpd9e`WG-FhpY2jIL-zOq#@Z*S@b5TW+q1jxSfEa+YR4%|;|mt3hizKgNLi!H4x(pfC9 z@mx++yW6J{X4DWpU{7C2a2c01#C2WWm@MIZ9vRH>bO-~8%>qwo3<-wI0- zmNMq;+?M76<@Ml|YlvBkfqM@8^KAiyh~Vf5>iKLp0(W0GCz$~r*VV#jS7)swV7tqX zPVji+?;(ct?AiCZ6C+LU0Gv^C!Uw)*?E6K@`7R8ZKOE-~T}ezNR}f9=LbKe0+R(D| z5_64$Sip+tkWdOM@1UND<-wDQDP&{qA?WZGyNpnNmRV30=c{ZeHG-4UQ0&8E(9Dts zeHXns|J!3Yz%cmRAo<0Q?VKGY;t644_M04`Qc;xrhfG#H%&!#QsuXpCuf@BB%?R7L z1Cd=9iKlP58~5qPMP%2d3k8&k+qA-iV!`m&ss71DZ_XkQ$**4I=8AC-SM3r7>5FG< z;oukFIQcs2i3)EGB?c^+M>(*Ij8Zz$)S|fCH;C{(+B6J?eF)av;^&T%%IaytHqnqSI@s6>omhzxAs2OI;D!e`22DT&bsxq(6#x#bX`^bhQ_f zC*83PGhDsFX6cbs)9=3*bp5dTj!_sJr|ad0qewIpDeO&2e;(idHjL3@FMH?_%C=pw z?yfFX-Ej*tXUikyPqT)r_RvxS#vncD)_jj+V&Ms&3_ruh9- zix1og9|-m-uY2r(MCtD>{N-lj16=vrGlJmko>KliEUukf&818G_6j$jrpy6pFs|~4 zwXKB95lwmd3ZH!6#synLsf3nBVE(Mh2^}9nXQUs=iNrI?g(Q1@=u_3=a9$&>vY0c& zJk4{l&oe;XZ#nnT?DKWf?~4!s00O}PO)^vgfVcmUuJ@mAFfunWvT|~p%IQ|LL3k?>PKd{-;emcPzRPyx6^fm|kAOq}LB| z@o5-s-Ec_-iL4w$k>JBA;2C4>%AecMjg`k+cLBdAUYhOOqtWX)O6(^{YgHyLYmL!F zHKOzNHVJrbt*0Y_bhnSU!y!$h#rxz9Z23-0!Oo^BoWP~!n&jS^h8w}2Chjc@l!V{6 zQoGXC>=T`ZV5q~e%Q1YG$F-`c&FxT#WQ=!~C6meERg= zEW-2Se(&JmiOve+nt>tpeQDqhxWZyp{JMBnS(^d2&sdzD9(Acd_UmTa3#HQK@fOFd z+fYdDMDn$auQz=XOXKj4l(yE{rGw%G?R!D!3PApy;{0>zpB4CL1^!uq|Boy1-vAE% Ba#R2S literal 0 HcmV?d00001 diff --git a/vendor/cache/rubocop-0.40.0.gem b/vendor/cache/rubocop-0.40.0.gem new file mode 100644 index 0000000000000000000000000000000000000000..8fb3b94d51e66cb13b2637aae97bc784a216e7b7 GIT binary patch literal 256512 zcmeFXRZJyJ5Vi>iImp4?-QC^Y-QC??hQamV?(Xg|z~JuggX`eV3^4oczZbjtZ}w^> z*{z%IPNh3lNhj6y^y_5hX=Z8WX~t~h5AlDMvHoYAoSYE<>-eAj&m#{zD?0=mI}aNt z8z(mh`+t5m4o(gp2vXMns{;Bzp6lh|Y3BZ4NIte!R*wHi$Nx0{KlA@@x&80S{ZHHf z-?}7;gM(O@VbuXZofz&V9(AAvy_y`Ho)oOT>{2nc*oINhlF2R}lhGlxNr|bVQ$1#o zdr`Lc{Q7#^7Lbr{xoV%dr?y3ZN*TVE-%~wy<$at@TAH1m{iD;tf^4ACi&NhJDc{!F zx#v@o*3Q_SDc#8FGJ1_KTEV${X{-y>abb!6r23^_zm8$s`R?1fS7(>ka&K{(HF5X9l&wJYG z=iv?E%;j)I{=#)EG9!@E+_X>yYFWUyZ|8ChZT)2_w+Wq)fq{vJM05E%M>lQ=%xOSgT#T?DF zq=tNy0G0C|5)5drRD_OPxLtS}&BQ+cDZMB1yI7JC`$taE9Rg-ThntuaDErirWRNlAi%g3K}uF^89eKz!y@6{(pG1LcHZ9 z`1syr>>n)^H!=jgix9EKI`SWcYn$7f{Iw%}sucvpFRcZv=iXF?c2;M@<=^}8Obele zoI-drf8Q4MaWS{HKLV-NPK?uh)Oj3Sz*}I~P5!PXZ2UJjy0st_(dCXN@y~;bmIveW zjiuM( zt8ca3L)flR=YPDfR**ot>n)qwC8vE4xe~S3IOW4;nw2^c1tyv;xCYzdr#3hpJAM^r z*crEuamF?B8_+{B<-^w_eu#j*88cShG@-YKl1Vj~T_IZ=?C55uGm{Vy! z;94=p5XN$*fKjHSj*DT6x~f5~OLnfqYLq$-=JjlO%x}wZx#26I5`^mUB#U8Baem`w z^$>eqhL2yG%v4K02#BbM_>QADBV>@6P1qs7--P0vgO*I?VF4&m3DClf5%vP#A-;9} zie&@^g|-dR7G%TJ_@e=}v9Z!e%w7ld16@+*`&72Pk(fs~7JwXFt%f|+Xcnu$g(M-U z+h8*eS9sUr9U99Q!by0H#B#VrF0R*>(e6y*kMxL*SOp{|u`^GG_9_Qf$mm9JX1Qo7 zXL_C0(s?=T>I6cZVn!x!UM~YKs-_5Qn8vkaHkAmzv%`U_o#dlwlXLl;mpBv$93qSj z-pX?4zUz{*dYBC)4y+JPA}dil7Zaj{TwI7*u-k0}MuOWoAR=TgG;>swbyuOOFILP` zPK^B4qIH~dvEj-lGBfyxP~!}gK4BHyH7V$`z#wLXl8SfpV#2C1%g$$^K!h4X^mnlq zTp_DvG{OU#C!cpL*|W-&JsJHmeX=`MG4?k*+jd2nE#p_@Ey5v#Uwg=JgZgv;

P# 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ð7F|P0EG6$=QHN*Bv+{qM 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 @4p-hUt<>| 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

oC^2+bC+#XSGE$B;Om9@49;%wUV*W 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 NKMefC!2cHp{smOCL+bzl literal 0 HcmV?d00001 diff --git a/vendor/cache/ruby-progressbar-1.7.5.gem b/vendor/cache/ruby-progressbar-1.7.5.gem new file mode 100644 index 0000000000000000000000000000000000000000..da36478936d60485187bca56dfb726dc17c4b71a GIT binary patch literal 21504 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