diff options
| -rw-r--r-- | app/controllers/api/v1/netex_imports_controller.rb | 43 | ||||
| -rw-r--r-- | app/controllers/application_controller.rb | 1 | ||||
| -rw-r--r-- | app/controllers/concerns/control_flow.rb | 14 | ||||
| -rw-r--r-- | app/views/api/v1/netex_imports/create.json.rabl | 4 | ||||
| -rw-r--r-- | spec/requests/api/v1/netex_import_spec.rb | 65 | 
5 files changed, 99 insertions, 28 deletions
| diff --git a/app/controllers/api/v1/netex_imports_controller.rb b/app/controllers/api/v1/netex_imports_controller.rb index d67d121c0..17eec2ef8 100644 --- a/app/controllers/api/v1/netex_imports_controller.rb +++ b/app/controllers/api/v1/netex_imports_controller.rb @@ -1,25 +1,54 @@  module Api    module V1      class NetexImportsController < ChouetteController +      include ControlFlow        def create          respond_to do | format | -          format.json do  -            @import = NetexImport.create(netex_import_params) -            unless @import.valid? -              render json: {errors: @import.errors}, status: 406 -            end -          end +          format.json(&method(:create_models))          end        end        private +      def find_workbench +        @workbench = Workbench.find(netex_import_params['workbench_id']) +      rescue ActiveRecord::RecordNotFound +        render json: {errors: {'workbench_id' => 'missing'}}, status: 406 +        finish_action! +      end + +      def create_models +        find_workbench +        create_referential +        create_netex_import +      end + +      def create_netex_import +        @netex_import = NetexImport.new(netex_import_params.merge(referential_id: @new_referential.id)) +        @netex_import.save! +      rescue ActiveRecord::RecordInvalid  +        render json: {errors: @netex_import.errors}, status: 406 +        finish_action! +      end + +      def create_referential +        @new_referential = +          Referential.new( +            name: netex_import_params['name'], +            organisation_id: @workbench.organisation_id, +            workbench_id: @workbench.id) +        @new_referential.save! +      rescue ActiveRecord::RecordInvalid +        render json: {errors: @new_referential.errors}, status: 406 +        finish_action! +      end +        def netex_import_params          params            .require('netex_import') -          .permit(:file, :name, :referential_id, :workbench_id) +          .permit(:file, :name, :workbench_id)        end      end    end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 8fcaa3b1b..d15aa336d 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -37,6 +37,7 @@ class ApplicationController < ActionController::Base      current_organisation    end +    # Overwriting the sign_out redirect path method    def after_sign_out_path_for(resource_or_scope)      new_user_session_path diff --git a/app/controllers/concerns/control_flow.rb b/app/controllers/concerns/control_flow.rb new file mode 100644 index 000000000..0f41a1cda --- /dev/null +++ b/app/controllers/concerns/control_flow.rb @@ -0,0 +1,14 @@ +module ControlFlow +  FinishAction = Class.new RuntimeError + +  def self.included into +    into.rescue_from FinishAction, with: :catch_finish_action +  end + +  # Allow to exit locally inside an action after rendering (especially in error cases) +  def catch_finish_action; end + +  def finish_action! msg = 'finish action' +    raise FinishAction, msg +  end +end diff --git a/app/views/api/v1/netex_imports/create.json.rabl b/app/views/api/v1/netex_imports/create.json.rabl index 1361cdb80..f37703349 100644 --- a/app/views/api/v1/netex_imports/create.json.rabl +++ b/app/views/api/v1/netex_imports/create.json.rabl @@ -1,3 +1,3 @@ -object @import -attributes :id, :type +object @netex_import +attributes :id, :workbench_id, :referential_id diff --git a/spec/requests/api/v1/netex_import_spec.rb b/spec/requests/api/v1/netex_import_spec.rb index ab1e7f6ae..fd5f6d497 100644 --- a/spec/requests/api/v1/netex_import_spec.rb +++ b/spec/requests/api/v1/netex_import_spec.rb @@ -3,13 +3,15 @@ RSpec.describe "NetexImport", type: :request do    describe 'POST netex_imports' do      let( :referential ){ create :referential } +    let( :workbench ){ referential.workbench } +      let( :file_path ){ fixtures_path 'single_reference_import.zip' }      let( :file ){ fixture_file_upload( file_path ) }      let( :post_request ) do        -> (attributes) do -        post "/api/v1/netex_imports.json", +        post api_v1_netex_imports_path(format: :json),            attributes,            authorization        end @@ -19,54 +21,79 @@ RSpec.describe "NetexImport", type: :request do        {          name: 'hello world',          file: file, -        referential_id: referential.id, -        workbench_id:   referential.workbench_id +        workbench_id: workbench.id        }      end  -    let( :illegal_attributes ) do -      { referential_id: referential.id } -    end       context 'with correct credentials and correct request' do        let( :authorization ){ authorization_token_header( get_api_key.token ) } -        it 'succeeds' do          post_request.(netex_import: legal_attributes)          expect( response ).to be_success -        expect( json_response_body ).to eq({'id' => NetexImport.last.id, 'type' => 'NetexImport'}) +        expect( json_response_body ).to eq( +          'id'             => NetexImport.last.id, +          'referential_id' => Referential.last.id, +          'workbench_id'   => workbench.id +        )        end        it 'creates a NetexImport object in the DB' do          expect{ post_request.(netex_import: legal_attributes) }.to change{NetexImport.count}.by(1)        end + +      it 'creates a correct Referential' do +        legal_attributes # force object creation for correct to change behavior +        expect{post_request.(netex_import: legal_attributes)}.to change{Referential.count}.by(1) +        Referential.last.tap do | ref | +          expect( ref.workbench_id ).to eq(workbench.id) +          expect( ref.organisation_id ).to eq(workbench.organisation_id) +        end +      end      end +      context 'with incorrect credentials and correct request' do        let( :authorization ){ authorization_token_header( "#{referential.id}-incorrect_token") } -      it 'does not succeed' do -        post_request.(netex_import: legal_attributes) +      it 'does not create any DB object and does not succeed' do +        legal_attributes # force object creation for correct to change behavior +        expect{ post_request.(netex_import: legal_attributes) }.not_to change{Referential.count}          expect( response.status ).to eq(401)        end -      it 'does not create an Import object' do -        expect{ post_request.(netex_import: legal_attributes) }.not_to change{Import.count} -      end      end      context 'with correct credentials and incorrect request' do        let( :authorization ){ authorization_token_header( get_api_key.token ) } -      it 'does not succeed' do -        post_request.(netex_import: illegal_attributes) -        expect( response.status ).to eq(406) -        expect( json_response_body['errors']['file'] ).not_to be_empty +      shared_examples_for 'illegal attributes' do |bad_attribute, illegal_value=nil, referential_count: 0| +        context "missing #{bad_attribute}" do +          let!( :illegal_attributes ){ legal_attributes.merge( bad_attribute => illegal_value ) } +          it 'does not succeed' do +            post_request.(netex_import: illegal_attributes) +            expect( response.status ).to eq(406) +            expect( json_response_body['errors'][bad_attribute.to_s] ).not_to be_empty +          end + +          it 'does not create an Import object' do +            expect{ post_request.(netex_import: illegal_attributes) }.not_to change{Import.count} +          end + +          it 'might create a referential' do +            expect{ post_request.(netex_import: illegal_attributes) }.to change{Referential.count}.by(referential_count) +          end +        end        end -      it 'does not create an Import object' do -        expect{ post_request.(netex_import: illegal_attributes) }.not_to change{Import.count} +      it_behaves_like 'illegal attributes', :file, referential_count: 1 +      it_behaves_like 'illegal attributes', :workbench_id +      context 'name already taken' do +        before do +          create :referential, name: 'already taken' +        end +        it_behaves_like 'illegal attributes', :name, 'already taken'        end      end    end | 
