diff --git a/lib/active_admin_import/importer.rb b/lib/active_admin_import/importer.rb index d37c9ab..4272476 100644 --- a/lib/active_admin_import/importer.rb +++ b/lib/active_admin_import/importer.rb @@ -129,7 +129,14 @@ def process_file end def prepare_headers - headers = self.headers.present? ? self.headers.map(&:to_s) : yield + headers = self.headers.present? ? self.headers : yield + blank_positions = headers.each_index.select { |i| headers[i].to_s.strip.empty? } + unless blank_positions.empty? + raise ActiveAdminImport::Exception, + "blank column header at column #{blank_positions.map { |i| i + 1 }.join(', ')}" + end + + headers = headers.map(&:to_s) @headers = Hash[headers.zip(headers.map { |el| el.underscore.gsub(/\s+/, '_') })].with_indifferent_access @headers.merge!(options[:headers_rewrites].symbolize_keys.slice(*@headers.symbolize_keys.keys)) @headers diff --git a/spec/fixtures/files/authors_blank_header_end.csv b/spec/fixtures/files/authors_blank_header_end.csv new file mode 100644 index 0000000..327f466 --- /dev/null +++ b/spec/fixtures/files/authors_blank_header_end.csv @@ -0,0 +1,3 @@ +Name,Last name,Birthday, +John,Doe,1986-05-01,x +Jane,Roe,1988-11-16,y diff --git a/spec/fixtures/files/authors_blank_header_middle.csv b/spec/fixtures/files/authors_blank_header_middle.csv new file mode 100644 index 0000000..22bfe51 --- /dev/null +++ b/spec/fixtures/files/authors_blank_header_middle.csv @@ -0,0 +1,3 @@ +Name,,Last name,Birthday +John,x,Doe,1986-05-01 +Jane,y,Roe,1988-11-16 diff --git a/spec/fixtures/files/authors_empty_header.csv b/spec/fixtures/files/authors_empty_header.csv new file mode 100644 index 0000000..a6cfa99 --- /dev/null +++ b/spec/fixtures/files/authors_empty_header.csv @@ -0,0 +1,3 @@ +,Name,Last name,Birthday +x,John,Doe,1986-05-01 +y,Jane,Roe,1988-11-16 diff --git a/spec/import_spec.rb b/spec/import_spec.rb index 595acfb..f904cf8 100644 --- a/spec/import_spec.rb +++ b/spec/import_spec.rb @@ -190,6 +190,36 @@ def upload_file!(name, ext = 'csv') end end + # Issue #197: a CSV with an empty header cell used to crash with + # `undefined method 'underscore' for nil`, wherever the blank sits. + context 'with a blank column header' do + shared_examples 'a rejected blank header' do |fixture, column| + before do + add_author_resource + visit '/admin/authors/import' + upload_file!(fixture) + end + + it 'reports a clear error and imports nothing' do + expect(page).to have_content "blank column header at column #{column}" + expect(page).to have_no_content 'undefined method' + expect(Author.count).to eq(0) + end + end + + context 'at the beginning' do + it_behaves_like 'a rejected blank header', :authors_empty_header, 1 + end + + context 'in the middle' do + it_behaves_like 'a rejected blank header', :authors_blank_header_middle, 2 + end + + context 'at the end' do + it_behaves_like 'a rejected blank header', :authors_blank_header_end, 4 + end + end + context 'authors already exist' do before do Author.create!(id: 1, name: 'Jane', last_name: 'Roe')