diff options
| -rw-r--r-- | app/controllers/admin_public_body_controller.rb | 6 | ||||
| -rw-r--r-- | app/models/public_body.rb | 50 | ||||
| -rw-r--r-- | spec/fixtures/files/fake-authority-type-with-field-names.csv | 8 | ||||
| -rw-r--r-- | spec/models/public_body_spec.rb | 48 | 
4 files changed, 88 insertions, 24 deletions
| diff --git a/app/controllers/admin_public_body_controller.rb b/app/controllers/admin_public_body_controller.rb index f88b25572..021122734 100644 --- a/app/controllers/admin_public_body_controller.rb +++ b/app/controllers/admin_public_body_controller.rb @@ -154,10 +154,10 @@ class AdminPublicBodyController < AdminController                  else                      raise "internal error, unknown button label"                  end - +                                  # Try with dry run first                  csv_contents = params[:csv_file].read -                en = PublicBody.import_csv(csv_contents, params[:tag], true, admin_http_auth_user()) +                en = PublicBody.import_csv(csv_contents, params[:tag], true, admin_http_auth_user(), I18n.available_locales)                  errors = en[0]                  notes = en[1] @@ -166,7 +166,7 @@ class AdminPublicBodyController < AdminController                          notes.push("Dry run was successful, real run would do as above.")                      else                          # And if OK, with real run -                        en = PublicBody.import_csv(csv_contents, params[:tag], false, admin_http_auth_user()) +                        en = PublicBody.import_csv(csv_contents, params[:tag], false, admin_http_auth_user(), available_locales)                          errors = en[0]                          notes = en[1]                          if errors.size != 0 diff --git a/app/models/public_body.rb b/app/models/public_body.rb index f1c6582ae..4563146cc 100644 --- a/app/models/public_body.rb +++ b/app/models/public_body.rb @@ -310,31 +310,36 @@ class PublicBody < ActiveRecord::Base      # Import from CSV. Just tests things and returns messages if dry_run is true.      # Returns an array of [array of errors, array of notes]. If there are errors,      # always rolls back (as with dry_run). -    def self.import_csv(csv, tag, dry_run, editor) +    def self.import_csv(csv, tag, dry_run, editor, additional_locales = [])          errors = []          notes = [] -         +          begin              ActiveRecord::Base.transaction do +                # Use the default locale when retrieving existing bodies; otherwise +                # matching names won't work afterwards, and we'll create new bodies instead +                # of updating them                  bodies_by_name = {}                  set_of_existing = Set.new() -                for existing_body in PublicBody.find_by_tag(tag) -                    bodies_by_name[existing_body.name] = existing_body -                    set_of_existing.add(existing_body.name) +                PublicBody.with_locale(I18n.default_locale) do +                    for existing_body in PublicBody.find_by_tag(tag) +                        bodies_by_name[existing_body.name] = existing_body +                        set_of_existing.add(existing_body.name) +                    end                  end - +                                  set_of_importing = Set.new()                  field_names = { 'name'=>1, 'email'=>2 }     # Default values in case no field list is given                  line = 0                  CSV::Reader.parse(csv) do |row| +                    line = line + 1 +                      # Parse the first line as a field list if it starts with '#' -                    if line==0 and row.to_s =~ /^#(.*)$/ +                    if line==1 and row.to_s =~ /^#(.*)$/                          row.each_with_index {|field, i| field_names[field] = i}                          next                      end -                     -                    line = line + 1 - +                          name = row[field_names['name']]                      email = row[field_names['email']]                      next if name.nil? @@ -357,15 +362,38 @@ class PublicBody < ActiveRecord::Base                              notes.push "line " + line.to_s + ": updating email for '" + name + "' from " + public_body.request_email + " to " + email                              public_body.request_email = email                              public_body.last_edit_editor = editor -                            public_body.last_edit_comment = 'Updated from spreadsheet' +                            public_body.last_edit_comment = 'Updated from spreadsheet'                                                          public_body.save!                          end + +                        additional_locales.each do |locale| +                            localized_name = field_names["name.#{locale}"] && row[field_names["name.#{locale}"]] +                            PublicBody.with_locale(locale) do  +                                if !localized_name.nil? and public_body.name != localized_name +                                    notes.push "line " + line.to_s + ": updating name for '#{name}' from '#{public_body.name}' to '#{localized_name}' (locale: #{locale})." +                                    public_body.name = localized_name +                                    public_body.save! +                                end +                            end +                        end                      else                          # New public body                          notes.push "line " + line.to_s + ": new authority '" + name + "' with email " + email                          public_body = PublicBody.new(:name => name, :request_email => email, :short_name => "", :home_page => "", :publication_scheme => "", :notes => "", :last_edit_editor => editor, :last_edit_comment => 'Created from spreadsheet')                          public_body.tag_string = tag                          public_body.save! + +                        additional_locales.each do |locale| +                            localized_name = field_names["name.#{locale}"] && row[field_names["name.#{locale}"]] +                            if !localized_name.nil? +                                PublicBody.with_locale(locale) do  +                                    notes.push "line " + line.to_s + ":   (aka '#{localized_name}' in locale #{locale})" +                                    public_body.name = localized_name +                                    public_body.publication_scheme = "" +                                    public_body.save! +                                end +                            end +                        end                      end                      set_of_importing.add(name) diff --git a/spec/fixtures/files/fake-authority-type-with-field-names.csv b/spec/fixtures/files/fake-authority-type-with-field-names.csv index 5032f2783..93ce00a25 100644 --- a/spec/fixtures/files/fake-authority-type-with-field-names.csv +++ b/spec/fixtures/files/fake-authority-type-with-field-names.csv @@ -1,4 +1,4 @@ -#id,email,name -,north_west_foi@localhost,North West Fake Authority -,scottish_foi@localhost,Scottish Fake Authority -,ni_foi@localhost,Fake Authority of Northern Ireland +#id,email,name,name.es +,north_west_foi@localhost,North West Fake Authority,Autoridad del Nordeste +,scottish_foi@localhost,Scottish Fake Authority,Autoridad Escocesa +,ni_foi@localhost,Fake Authority of Northern Ireland,Autoridad Irlandesa diff --git a/spec/models/public_body_spec.rb b/spec/models/public_body_spec.rb index e532d0d50..83075e4af 100644 --- a/spec/models/public_body_spec.rb +++ b/spec/models/public_body_spec.rb @@ -240,19 +240,55 @@ describe PublicBody, " when loading CSV files" do          PublicBody.count.should == original_count + 3      end -end -describe PublicBody, " when loading CSV files with field names and fields out of order" do -    it "should do a dry run successfully" do +    it "should handle a field list and fields out of order" do          original_count = PublicBody.count          csv_contents = load_file_fixture("fake-authority-type-with-field-names.csv")          errors, notes = PublicBody.import_csv(csv_contents, 'fake', true, 'someadmin') # true means dry run          errors.should == []          notes.size.should == 3 -        notes.should == ["line 1: new authority 'North West Fake Authority' with email north_west_foi@localhost",  -            "line 2: new authority 'Scottish Fake Authority' with email scottish_foi@localhost",  -            "line 3: new authority 'Fake Authority of Northern Ireland' with email ni_foi@localhost"] +        notes.should == ["line 2: new authority 'North West Fake Authority' with email north_west_foi@localhost",  +            "line 3: new authority 'Scottish Fake Authority' with email scottish_foi@localhost",  +            "line 4: new authority 'Fake Authority of Northern Ireland' with email ni_foi@localhost"] + +        PublicBody.count.should == original_count +    end + +    it "should create bodies with names in multiple locales" do +        original_count = PublicBody.count + +        csv_contents = load_file_fixture("fake-authority-type-with-field-names.csv") +        errors, notes = PublicBody.import_csv(csv_contents, 'fake', false, 'someadmin', ['es']) +        errors.should == [] +        notes.size.should == 6 +        notes.should == [ +            "line 2: new authority 'North West Fake Authority' with email north_west_foi@localhost",  +            "line 2:   (aka 'Autoridad del Nordeste' in locale es)",  +            "line 3: new authority 'Scottish Fake Authority' with email scottish_foi@localhost",  +            "line 3:   (aka 'Autoridad Escocesa' in locale es)",  +            "line 4: new authority 'Fake Authority of Northern Ireland' with email ni_foi@localhost", +            "line 4:   (aka 'Autoridad Irlandesa' in locale es)"] + +        PublicBody.count.should == original_count + 3 +         +        # XXX Not sure why trying to do a PublicBody.with_locale fails here. Seems related to  +        # the way categories are loaded every time from the PublicBody class. For now we just +        # test some translation was done. +        body = PublicBody.find_by_name('North West Fake Authority') +        body.translated_locales.should == [:en, :es] +    end + +    it "should not fail if a locale is not found in the input file" do +        original_count = PublicBody.count + +        csv_contents = load_file_fixture("fake-authority-type-with-field-names.csv") +        errors, notes = PublicBody.import_csv(csv_contents, 'fake', true, 'someadmin', ['xx']) # true means dry run +        errors.should == [] +        notes.size.should == 3 +        notes.should == ["line 2: new authority 'North West Fake Authority' with email north_west_foi@localhost",  +            "line 3: new authority 'Scottish Fake Authority' with email scottish_foi@localhost",  +            "line 4: new authority 'Fake Authority of Northern Ireland' with email ni_foi@localhost"]          PublicBody.count.should == original_count      end | 
