diff options
| author | Zog | 2018-03-08 11:46:20 +0100 | 
|---|---|---|
| committer | Zog | 2018-03-12 12:00:14 +0100 | 
| commit | a4a075f5eec935dd6a0dbf0a861b6ada13b1dcbc (patch) | |
| tree | b046d69937ce998d918a7a4bf5a3e2e418961fa1 | |
| parent | db15dc6158939d2577ccd53aac66a283ce4f3338 (diff) | |
| download | chouette-core-a4a075f5eec935dd6a0dbf0a861b6ada13b1dcbc.tar.bz2 | |
Refs #6133; Add options on the Exports, and forward them tu the UX
| -rw-r--r-- | app/controllers/exports_controller.rb | 15 | ||||
| -rw-r--r-- | app/javascript/packs/exports/new.js | 3 | ||||
| -rw-r--r-- | app/models/concerns/iev_interfaces/task.rb | 21 | ||||
| -rw-r--r-- | app/models/export/base.rb | 46 | ||||
| -rw-r--r-- | app/models/export/netex.rb | 17 | ||||
| -rw-r--r-- | app/models/export/workbench.rb | 2 | ||||
| -rw-r--r-- | app/models/import/netex.rb | 26 | ||||
| -rw-r--r-- | app/views/exports/_form.html.slim | 9 | ||||
| -rw-r--r-- | app/views/exports/show.html.slim | 4 | ||||
| -rw-r--r-- | config/locales/exports.fr.yml | 3 | ||||
| -rw-r--r-- | db/migrate/20180308095116_add_options_to_exports.rb | 5 | ||||
| -rw-r--r-- | db/schema.rb | 10 | ||||
| -rw-r--r-- | spec/controllers/exports_controller_spec.rb | 65 | ||||
| -rw-r--r-- | spec/models/export/netex_export_spec.rb | 19 | ||||
| -rw-r--r-- | spec/models/export/workbench_export_spec.rb | 10 | ||||
| -rw-r--r-- | spec/models/import/netex_import_spec.rb | 1 | 
16 files changed, 212 insertions, 44 deletions
| diff --git a/app/controllers/exports_controller.rb b/app/controllers/exports_controller.rb index d56b14fb2..3a91217e4 100644 --- a/app/controllers/exports_controller.rb +++ b/app/controllers/exports_controller.rb @@ -8,18 +8,21 @@ class ExportsController < ChouetteController    private    def build_resource -    @export ||= Export::Workbench.new(*resource_params) do |export| +    Export::Base.force_load_descendants if Rails.env.development? +    @export ||= Export::Base.new(*resource_params) do |export|        export.workbench = parent        export.creator   = current_user.name      end +    @export    end    def export_params -    params.require(:export).permit( -      :name, -      :type, -      :referential_id -    ) +    permitted_keys = %i(name type referential_id) +    export_class = params[:export] && params[:export][:type].safe_constantize +    if export_class +      permitted_keys += export_class.options.keys +    end +    params.require(:export).permit(permitted_keys)    end    def decorate_collection(exports) diff --git a/app/javascript/packs/exports/new.js b/app/javascript/packs/exports/new.js new file mode 100644 index 000000000..ffe702cdb --- /dev/null +++ b/app/javascript/packs/exports/new.js @@ -0,0 +1,3 @@ +import MasterSlave from "../../helpers/master_slave" + +new MasterSlave("form") diff --git a/app/models/concerns/iev_interfaces/task.rb b/app/models/concerns/iev_interfaces/task.rb index c84c588b6..f60c16750 100644 --- a/app/models/concerns/iev_interfaces/task.rb +++ b/app/models/concerns/iev_interfaces/task.rb @@ -83,10 +83,29 @@ module IevInterfaces::Task    def child_change      return if self.class.finished_statuses.include?(status) -      update_status    end +  def call_iev_callback +    return if self.class.finished_statuses.include?(status) +    threaded_call_boiv_iev +  end + +  private + +  def threaded_call_boiv_iev +    Thread.new(&method(:call_boiv_iev)) +  end + +  def call_boiv_iev +    Rails.logger.error("Begin IEV call for import") +    Net::HTTP.get iev_callback_url +    Rails.logger.error("End IEV call for import") +  rescue Exception => e +    logger.error "IEV server error : #{e.message}" +    logger.error e.backtrace.inspect +  end +    private    def initialize_fields    end diff --git a/app/models/export/base.rb b/app/models/export/base.rb index 844c66d82..350edd215 100644 --- a/app/models/export/base.rb +++ b/app/models/export/base.rb @@ -1,6 +1,8 @@  class Export::Base < ActiveRecord::Base    self.table_name = "exports" +  validates :type, presence: true +    def self.messages_class_name      "Export::Message"    end @@ -9,12 +11,56 @@ class Export::Base < ActiveRecord::Base      "Export::Resource"    end +  def self.human_name +    self.name.demodulize.humanize +  end + +  if Rails.env.development? +    def self.force_load_descendants +      path = Rails.root.join 'app/models/export' +      Dir.chdir path do +        Dir['**/*.rb'].each do |src| +          next if src =~ /^base/ +          klass_name = "Export::#{src[0..-4].classify}" +          Rails.logger.info "Loading #{klass_name}" +          begin +            klass_name.constantize +          rescue => e +            Rails.logger.info "Failed: #{e.message}" +            nil +          end +        end +      end +    end +  end + +  def self.option name, opts +    store_accessor :options, name +    if !!opts[:required] +      validates name, presence: true +    end +    @options ||= {} +    @options[name] = opts +  end + +  def self.options +    @options +  end +    include IevInterfaces::Task    def self.model_name      ActiveModel::Name.new Export::Base, Export::Base, "Export"    end +  def self.user_visible_descendants +    descendants.select &:user_visible? +  end + +  def self.user_visible? +    true +  end +    private    def initialize_fields diff --git a/app/models/export/netex.rb b/app/models/export/netex.rb index 858f09549..a5bdb63d2 100644 --- a/app/models/export/netex.rb +++ b/app/models/export/netex.rb @@ -1,2 +1,19 @@  class Export::Netex < Export::Base +  after_commit :call_iev_callback, on: :create + +  private + +  def iev_callback_url +    URI("#{Rails.configuration.iev_url}/boiv_iev/referentials/exporter/new?id=#{id}") +  end + +  def self.user_visible? +    false +  end + +  def destroy_non_ready_referential +    if referential && !referential.ready +      referential.destroy +    end +  end  end diff --git a/app/models/export/workbench.rb b/app/models/export/workbench.rb index a4b14cf55..9ec15f22f 100644 --- a/app/models/export/workbench.rb +++ b/app/models/export/workbench.rb @@ -1,6 +1,8 @@  class Export::Workbench < Export::Base    after_commit :launch_worker, :on => :create +  option :timelapse, required: true, type: :integer, default_value: 90 +    def launch_worker      # WorkbenchImportWorker.perform_async(id)    end diff --git a/app/models/import/netex.rb b/app/models/import/netex.rb index a4bf0920d..2b0982229 100644 --- a/app/models/import/netex.rb +++ b/app/models/import/netex.rb @@ -2,37 +2,23 @@ require 'net/http'  class Import::Netex < Import::Base    before_destroy :destroy_non_ready_referential -  after_commit :launch_java_import, on: :create +  after_commit :call_iev_callback, on: :create +    before_save def abort_unless_referential      self.status = 'aborted' unless referential    end    validates_presence_of :parent -  def launch_java_import -    return if self.class.finished_statuses.include?(status) -    threaded_call_boiv_iev -  end -    private +  def iev_callback_url +    URI("#{Rails.configuration.iev_url}/boiv_iev/referentials/importer/new?id=#{id}") +  end +    def destroy_non_ready_referential      if referential && !referential.ready        referential.destroy      end    end - -  def threaded_call_boiv_iev -    Thread.new(&method(:call_boiv_iev)) -  end - -  def call_boiv_iev -    Rails.logger.error("Begin IEV call for import") -    Net::HTTP.get(URI("#{Rails.configuration.iev_url}/boiv_iev/referentials/importer/new?id=#{id}")) -    Rails.logger.error("End IEV call for import") -  rescue Exception => e -    logger.error "IEV server error : #{e.message}" -    logger.error e.backtrace.inspect -  end -  end diff --git a/app/views/exports/_form.html.slim b/app/views/exports/_form.html.slim index c4748b5f9..68228d539 100644 --- a/app/views/exports/_form.html.slim +++ b/app/views/exports/_form.html.slim @@ -3,5 +3,14 @@    .row      .col-lg-12        = form.input :name +    .col-lg-12 +      = form.input :type, as: :select, collection: Export::Base.user_visible_descendants, label_method: :human_name + +      - Export::Base.user_visible_descendants.each do |child| +        .slave data-master="[name='export[type]']" data-value=child.name +          - child.options.each do |attr, option_def| +            = form.input attr, required: option_def[:required], input_html: {value: @export.try(attr) || option_def[:default_value]}, as: option_def[:type]    = form.button :submit, t('actions.submit'), class: 'btn btn-default formSubmitr', form: 'wb_export_form' + += javascript_pack_tag "exports/new" diff --git a/app/views/exports/show.html.slim b/app/views/exports/show.html.slim index dab50ced8..1b193f795 100644 --- a/app/views/exports/show.html.slim +++ b/app/views/exports/show.html.slim @@ -6,7 +6,9 @@    .container-fluid      .row        .col-lg-6.col-md-6.col-sm-12.col-xs-12 -        = definition_list t('metadatas'), { 'Récupération des données' => '-', "Nom de l'archive" => @export.try(:file_identifier)} +        - metadatas = { I18n.t("activerecord.attributes.export.type") => @export.object.class.human_name } +        - metadatas = metadatas.update Hash[*@export.options.map{|k, v| [t("activerecord.attributes.export.#{@export.object.class.name.demodulize.tableize.singularize}.#{k}"), v]}.flatten] +        = definition_list t('metadatas'), metadatas      .row        .col-lg-12 diff --git a/config/locales/exports.fr.yml b/config/locales/exports.fr.yml index c5b8a5e3b..e2e9f1bbb 100644 --- a/config/locales/exports.fr.yml +++ b/config/locales/exports.fr.yml @@ -81,10 +81,13 @@ fr:          max_distance_for_connection_link: "Distance max pour créer les correspondances"          ignore_last_word: "ignorer le dernier mot"          ignore_end_chars: "ignorer les n derniers caractères" +        type: "Type d'export"        export:          <<: *attrs          base:            <<: *attrs +        workbench: +          timelapse: Durée    flash:      exports:        create: diff --git a/db/migrate/20180308095116_add_options_to_exports.rb b/db/migrate/20180308095116_add_options_to_exports.rb new file mode 100644 index 000000000..02744c5cb --- /dev/null +++ b/db/migrate/20180308095116_add_options_to_exports.rb @@ -0,0 +1,5 @@ +class AddOptionsToExports < ActiveRecord::Migration +  def change +    add_column :exports, :options, :hstore +  end +end diff --git a/db/schema.rb b/db/schema.rb index 094d2cb02..885f12e24 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,14 +11,13 @@  #  # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20180307071448) do +ActiveRecord::Schema.define(version: 20180308095116) do    # These are extensions that must be enabled in order to support this database    enable_extension "plpgsql" -  enable_extension "hstore"    enable_extension "postgis" +  enable_extension "hstore"    enable_extension "unaccent" -  enable_extension "objectid"    create_table "access_links", id: :bigserial, force: :cascade do |t|      t.integer  "access_point_id",                        limit: 8 @@ -91,9 +90,9 @@ ActiveRecord::Schema.define(version: 20180307071448) do      t.integer   "organisation_id", limit: 8      t.datetime  "created_at"      t.datetime  "updated_at" +    t.integer   "workgroup_id",    limit: 8      t.integer   "int_day_types"      t.date      "excluded_dates",                            array: true -    t.integer   "workgroup_id",    limit: 8    end    add_index "calendars", ["organisation_id"], name: "index_calendars_on_organisation_id", using: :btree @@ -120,7 +119,6 @@ ActiveRecord::Schema.define(version: 20180307071448) do      t.datetime "updated_at"      t.date     "end_date"      t.string   "date_type" -    t.string   "mode"    end    add_index "clean_ups", ["referential_id"], name: "index_clean_ups_on_referential_id", using: :btree @@ -348,6 +346,7 @@ ActiveRecord::Schema.define(version: 20180307071448) do      t.integer  "current_step",                    default: 0      t.integer  "total_steps",                     default: 0      t.string   "creator" +    t.hstore   "options"    end    add_index "exports", ["referential_id"], name: "index_exports_on_referential_id", using: :btree @@ -807,7 +806,6 @@ ActiveRecord::Schema.define(version: 20180307071448) do      t.datetime "created_at"      t.datetime "updated_at"      t.string   "objectid_format" -    t.string   "registration_number_format"    end    create_table "stop_areas", id: :bigserial, force: :cascade do |t| diff --git a/spec/controllers/exports_controller_spec.rb b/spec/controllers/exports_controller_spec.rb index a1a40d571..a070cfb1f 100644 --- a/spec/controllers/exports_controller_spec.rb +++ b/spec/controllers/exports_controller_spec.rb @@ -18,15 +18,62 @@ RSpec.describe ExportsController, :type => :controller do    end    describe "POST #create" do -    it "displays a flash message" do -      post :create, workbench_id: workbench.id, -        export: { -          name: 'Offre' -        } - -      expect(controller).to set_flash[:notice].to( -        I18n.t('flash.exports.create.notice') -      ) +    let(:params){ {name: "foo"} } +    let(:request){ post :create, workbench_id: workbench.id, export: params  } +    it 'should create no objects' do +      expect{request}.to_not change{Export::Base.count} +    end + +    context "with full params" do +      let(:params){{ +        name: "foo", +        type: "Export::Netex" +      }} + +      it 'should be successful' do +        expect{request}.to change{Export::Base.count}.by(1) +      end + +      it "displays a flash message" do +        request +        expect(controller).to set_flash[:notice].to( +          I18n.t('flash.exports.create.notice') +        ) +      end +    end + +    context "with missing options" do +      let(:params){{ +        name: "foo", +        type: "Export::Workbench" +      }} + +      it 'should be unsuccessful' do +        expect{request}.to change{Export::Base.count}.by(0) +      end +    end + +    context "with all options" do +      let(:params){{ +        name: "foo", +        type: "Export::Workbench", +        timelapse: 90 +      }} + +      it 'should be successful' do +        expect{request}.to change{Export::Base.count}.by(1) +      end +    end + +    context "with wrong type" do +      let(:params){{ +        name: "foo", +        type: "Export::Foo" +      }} + +      it 'should be unsuccessful' do +        expect{request}.to raise_error ActiveRecord::SubclassNotFound +      end      end    end  end diff --git a/spec/models/export/netex_export_spec.rb b/spec/models/export/netex_export_spec.rb new file mode 100644 index 000000000..d9cccd6ad --- /dev/null +++ b/spec/models/export/netex_export_spec.rb @@ -0,0 +1,19 @@ +RSpec.describe Export::Netex, type: [:model, :with_commit] do + +  let( :boiv_iev_uri ){  URI("#{Rails.configuration.iev_url}/boiv_iev/referentials/exporter/new?id=#{subject.id}")} + +  before do +    allow(Thread).to receive(:new).and_yield +  end + +  context 'with referential' do +    subject{ build( :netex_export, id: random_int ) } + +    it 'will trigger the Java API' do +      with_stubbed_request(:get, boiv_iev_uri) do |request| +        with_commit{ subject.save! } +        expect(request).to have_been_requested +      end +    end +  end +end diff --git a/spec/models/export/workbench_export_spec.rb b/spec/models/export/workbench_export_spec.rb new file mode 100644 index 000000000..1b2e81aa4 --- /dev/null +++ b/spec/models/export/workbench_export_spec.rb @@ -0,0 +1,10 @@ +RSpec.describe Export::Workbench, type: [:model, :with_commit] do +  it { should validate_presence_of(:timelapse) } + +  it "should set options" do +    expect(Export::Workbench.options).to have_key :timelapse +    expect(Export::Workbench.options[:timelapse][:required]).to be_truthy +    expect(Export::Workbench.options[:timelapse][:default_value]).to eq 90 +    expect(Export::Workbench.options[:timelapse][:type]).to eq :integer +  end +end diff --git a/spec/models/import/netex_import_spec.rb b/spec/models/import/netex_import_spec.rb index 9b9f50117..6424fbfe1 100644 --- a/spec/models/import/netex_import_spec.rb +++ b/spec/models/import/netex_import_spec.rb @@ -2,7 +2,6 @@ RSpec.describe Import::Netex, type: [:model, :with_commit] do    let( :boiv_iev_uri ){  URI("#{Rails.configuration.iev_url}/boiv_iev/referentials/importer/new?id=#{subject.id}")} -    before do      allow(Thread).to receive(:new).and_yield    end | 
