aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/controllers/admin_public_body_controller.rb10
-rw-r--r--app/models/public_body.rb19
-rw-r--r--app/views/admin_public_body/_form.html.erb77
-rw-r--r--app/views/admin_public_body/_locale_fields.html.erb49
-rw-r--r--config/initializers/alaveteli.rb2
-rw-r--r--config/test.yml2
-rw-r--r--spec/controllers/admin_public_body_controller_spec.rb154
-rw-r--r--spec/integration/admin_public_body_edit_spec.rb71
-rw-r--r--spec/models/public_body_spec.rb102
9 files changed, 411 insertions, 75 deletions
diff --git a/app/controllers/admin_public_body_controller.rb b/app/controllers/admin_public_body_controller.rb
index f7a80476c..baa5a1d22 100644
--- a/app/controllers/admin_public_body_controller.rb
+++ b/app/controllers/admin_public_body_controller.rb
@@ -83,6 +83,11 @@ class AdminPublicBodyController < AdminController
def new
@public_body = PublicBody.new
+
+ I18n.available_locales.each do |locale|
+ @public_body.translations.build(:locale => locale)
+ end
+
if params[:change_request_id]
@change_request = PublicBodyChangeRequest.find(params[:change_request_id])
end
@@ -120,6 +125,11 @@ class AdminPublicBodyController < AdminController
def edit
@public_body = PublicBody.find(params[:id])
+
+ I18n.available_locales.each do |locale|
+ @public_body.translations.find_or_initialize_by_locale(locale)
+ end
+
if params[:change_request_id]
@change_request = PublicBodyChangeRequest.find(params[:change_request_id])
end
diff --git a/app/models/public_body.rb b/app/models/public_body.rb
index a9cdfeab2..829625cac 100644
--- a/app/models/public_body.rb
+++ b/app/models/public_body.rb
@@ -64,6 +64,7 @@ class PublicBody < ActiveRecord::Base
}
translates :name, :short_name, :request_email, :url_name, :notes, :first_letter, :publication_scheme
+ accepts_nested_attributes_for :translations
# Default fields available for importing from CSV, in the format
# [field_name, 'short description of field (basic html allowed)']
@@ -151,12 +152,11 @@ class PublicBody < ActiveRecord::Base
translations
end
- def translated_versions=(translation_attrs)
+ def translations_attributes=(translation_attrs)
def empty_translation?(attrs)
- attrs_with_values = attrs.select{ |key, value| value != '' and key != 'locale' }
+ attrs_with_values = attrs.select{ |key, value| value != '' and key.to_s != 'locale' }
attrs_with_values.empty?
end
-
if translation_attrs.respond_to? :each_value # Hash => updating
translation_attrs.each_value do |attrs|
next if empty_translation?(attrs)
@@ -166,6 +166,13 @@ class PublicBody < ActiveRecord::Base
t.save!
end
else # Array => creating
+ warn "[DEPRECATION] PublicBody#translations_attributes= " \
+ "will no longer accept an Array as of release 0.22. " \
+ "Use Hash arguments instead. See " \
+ "spec/models/public_body_spec.rb and " \
+ "app/views/admin_public_body/_form.html.erb for more " \
+ "details."
+
translation_attrs.each do |attrs|
next if empty_translation?(attrs)
new_translation = PublicBody::Translation.new(attrs)
@@ -175,6 +182,12 @@ class PublicBody < ActiveRecord::Base
end
end
+ def translated_versions=(translation_attrs)
+ warn "[DEPRECATION] PublicBody#translated_versions= will be replaced " \
+ "by PublicBody#translations_attributes= as of release 0.22"
+ self.translations_attributes = translation_attrs
+ end
+
def set_default_publication_scheme
# Make sure publication_scheme gets the correct default value.
# (This would work automatically, were publication_scheme not a translated attribute)
diff --git a/app/views/admin_public_body/_form.html.erb b/app/views/admin_public_body/_form.html.erb
index 2da13ab01..c765c116e 100644
--- a/app/views/admin_public_body/_form.html.erb
+++ b/app/views/admin_public_body/_form.html.erb
@@ -4,66 +4,27 @@
<div id="div-locales">
<ul class="locales nav nav-tabs">
- <% I18n.available_locales.each_with_index do |locale, i| %>
- <li><a href="#div-locale-<%=locale.to_s%>" data-toggle="tab" ><%=locale_name(locale.to_s) || _("Default locale")%></a></li>
- <% end %>
+ <% @public_body.translations.each do |translation| %>
+ <li>
+ <a href="#div-locale-<%= translation.locale.to_s %>" data-toggle="tab">
+ <%= locale_name(translation.locale.to_s) || _("Default locale") %>
+ </a>
+ </li>
+ <% end %>
</ul>
+
<div class="tab-content">
-<%
- for locale in I18n.available_locales do
- if locale==I18n.default_locale # The default locale is submitted as part of the bigger object...
- prefix = 'public_body'
- object = @public_body
- else # ...but additional locales go "on the side"
- prefix = "public_body[translated_versions][]"
- object = @public_body.new_record? ?
- PublicBody::Translation.new :
- @public_body.find_translation_by_locale(locale.to_s) || PublicBody::Translation.new
- end
-%>
- <%= fields_for prefix, object do |t| %>
- <div class="tab-pane" id="div-locale-<%=locale.to_s%>">
- <div class="control-group">
- <%= t.hidden_field :locale, :value => locale.to_s %>
- <label for="<%= form_tag_id(t.object_name, :name, locale) %>" class="control-label">Name</label>
- <div class="controls">
- <%= t.text_field :name, :id => form_tag_id(t.object_name, :name, locale), :class => "span4" %>
- </div>
- </div>
- <div class="control-group">
- <label for="<%= form_tag_id(t.object_name, :short_name, locale) %>", class="control-label"><%=_("Short name")%></label>
- <div class="controls">
- <%= t.text_field :short_name, :id => form_tag_id(t.object_name, :short_name, locale), :class => "span2" %>
- <p class="help-block"><%=_("Only put in abbreviations which are really used, otherwise leave blank. Short or long name is used in the URL – don't worry about breaking URLs through renaming, as the history is used to redirect")%></p>
- </div>
- </div>
- <div class="control-group">
- <label for="<%= form_tag_id(t.object_name, :request_email, locale) %>" class="control-label"><%=_("Request email")%></label>
- <div class="controls">
- <%= t.text_field :request_email, :id => form_tag_id(t.object_name, :request_email, locale), :class => "span3" %>
- <p class="help-block"><%=_("set to <strong>blank</strong> (empty string) if can't find an address; these emails are <strong>public</strong> as anyone can view with a CAPTCHA")%></p>
- </div>
- </div>
- <div class="control-group">
- <label for="<%= form_tag_id(t.object_name, :publication_scheme, locale) %>" class="control-label"><%=_("Publication scheme URL")%></label>
- <div class="controls">
- <%= t.text_field :publication_scheme, :size => 60, :id => form_tag_id(t.object_name, :publication_scheme, locale), :class => "span3" %>
- </div>
- </div>
- <div class="control-group">
- <label for="<%= form_tag_id(t.object_name, :notes, locale) %>" class="control-label"><%=_("Public notes")%></label>
- <div class="controls">
- <%= t.text_area :notes, :rows => 3, :id => form_tag_id(t.object_name, :notes, locale), :class => "span6" %>
- <p class="help-block">
- HTML, for users to consider when making FOI requests to the authority
- </p>
- </div>
- </div>
- </div>
-<%
- end
- end
-%>
+ <% @public_body.translations.each do |translation| %>
+ <% if translation.locale.to_s == I18n.default_locale.to_s %>
+ <%= fields_for('public_body', @public_body) do |t| %>
+ <%= render :partial => 'locale_fields', :locals => { :t => t, :locale => translation.locale } %>
+ <% end %>
+ <% else %>
+ <%= f.fields_for(:translations, translation, :child_index => translation.locale) do |t| %>
+ <%= render :partial => 'locale_fields' , :locals => { :t => t, :locale => translation.locale } %>
+ <% end %>
+ <% end %>
+ <% end %>
</div>
</div>
diff --git a/app/views/admin_public_body/_locale_fields.html.erb b/app/views/admin_public_body/_locale_fields.html.erb
new file mode 100644
index 000000000..cbe008fe2
--- /dev/null
+++ b/app/views/admin_public_body/_locale_fields.html.erb
@@ -0,0 +1,49 @@
+
+<div class="tab-pane" id="div-locale-<%=locale.to_s%>">
+ <div class="control-group">
+ <%= t.hidden_field :locale, :value => locale.to_s %>
+ <label for="<%= form_tag_id(t.object_name, :name, locale) %>" class="control-label">Name</label>
+ <div class="controls">
+ <%= t.text_field :name, :id => form_tag_id(t.object_name, :name, locale), :class => "span4" %>
+ </div>
+ </div>
+
+ <div class="control-group">
+ <label for="<%= form_tag_id(t.object_name, :short_name, locale) %>" class="control-label"><%=_("Short name")%></label>
+ <div class="controls">
+ <%= t.text_field :short_name, :id => form_tag_id(t.object_name, :short_name, locale), :class => "span2" %>
+ <p class="help-block">
+ <%=_("Only put in abbreviations which are really used, otherwise leave blank. Short or long name is used in the URL – don't worry about breaking URLs through renaming, as the history is used to redirect")%>
+ </p>
+ </div>
+ </div>
+
+ <div class="control-group">
+ <label for="<%= form_tag_id(t.object_name, :request_email, locale) %>" class="control-label"><%=_("Request email")%></label>
+ <div class="controls">
+ <%= t.text_field :request_email, :id => form_tag_id(t.object_name, :request_email, locale), :class => "span3" %>
+ <p class="help-block">
+ <%=_("set to <strong>blank</strong> (empty string) if can't find an address; these emails are <strong>public</strong> as anyone can view with a CAPTCHA")%>
+ </p>
+ </div>
+ </div>
+
+ <div class="control-group">
+ <label for="<%= form_tag_id(t.object_name, :publication_scheme, locale) %>" class="control-label"><%=_("Publication scheme URL")%></label>
+ <div class="controls">
+ <%= t.text_field :publication_scheme, :size => 60, :id => form_tag_id(t.object_name, :publication_scheme, locale), :class => "span3" %>
+ </div>
+ </div>
+
+ <div class="control-group">
+ <label for="<%= form_tag_id(t.object_name, :notes, locale) %>" class="control-label"><%=_("Public notes")%></label>
+ <div class="controls">
+ <%= t.text_area :notes, :rows => 3, :id => form_tag_id(t.object_name, :notes, locale), :class => "span6" %>
+ <p class="help-block">
+ HTML, for users to consider when making FOI requests to the authority
+ </p>
+ </div>
+ </div>
+
+</div>
+
diff --git a/config/initializers/alaveteli.rb b/config/initializers/alaveteli.rb
index ee9ad8316..9167a0c8e 100644
--- a/config/initializers/alaveteli.rb
+++ b/config/initializers/alaveteli.rb
@@ -10,7 +10,7 @@ load "debug_helpers.rb"
load "util.rb"
# Application version
-ALAVETELI_VERSION = '0.20.0.5'
+ALAVETELI_VERSION = '0.20.0.6'
# Add new inflection rules using the following format
# (all these examples are active by default):
diff --git a/config/test.yml b/config/test.yml
index 599e1e81a..4a5de704f 100644
--- a/config/test.yml
+++ b/config/test.yml
@@ -27,7 +27,7 @@ BLOG_FEED: 'http://www.mysociety.org/category/projects/whatdotheyknow/feed/'
TWITTER_USERNAME: 'alaveteli_foi'
# Locales we wish to support in this app, space-delimited
-AVAILABLE_LOCALES: 'en es en_GB'
+AVAILABLE_LOCALES: 'en es fr en_GB'
DEFAULT_LOCALE: 'en'
# if 'true', respect the user's choice of language in the browser
diff --git a/spec/controllers/admin_public_body_controller_spec.rb b/spec/controllers/admin_public_body_controller_spec.rb
index 095d23245..f176150da 100644
--- a/spec/controllers/admin_public_body_controller_spec.rb
+++ b/spec/controllers/admin_public_body_controller_spec.rb
@@ -44,6 +44,15 @@ describe AdminPublicBodyController, 'when showing the form for a new public body
assigns[:public_body].should be_a(PublicBody)
end
+ it "builds new translations for all locales" do
+ get :new
+
+ translations = assigns[:public_body].translations.map{ |t| t.locale.to_s }.sort
+ available = I18n.available_locales.map{ |l| l.to_s }.sort
+
+ expect(translations).to eq(available)
+ end
+
context 'when passed a change request id as a param' do
render_views
@@ -88,11 +97,13 @@ describe AdminPublicBodyController, "when creating a public body" do
:tag_string => "blah",
:request_email => 'newquango@localhost',
:last_edit_comment => 'From test code',
- :translated_versions => [{ :locale => "es",
- :name => "Mi Nuevo Quango",
- :short_name => "",
- :request_email => 'newquango@localhost' }]
- }
+ :translations_attributes => {
+ 'es' => { :locale => "es",
+ :name => "Mi Nuevo Quango",
+ :short_name => "",
+ :request_email => 'newquango@localhost' }
+ }
+ }
}
PublicBody.count.should == n + 1
@@ -159,6 +170,12 @@ describe AdminPublicBodyController, "when editing a public body" do
response.should render_template('edit')
end
+ it "builds new translations if the body does not already have a translation in the specified locale" do
+ public_body = FactoryGirl.create(:public_body)
+ get :edit, :id => public_body.id
+ expect(assigns[:public_body].translations.map(&:locale)).to include(:fr)
+ end
+
context 'when passed a change request id as a param' do
render_views
@@ -196,6 +213,116 @@ describe AdminPublicBodyController, "when updating a public body" do
pb.name.should == "Renamed"
end
+ it 'adds a new translation' do
+ pb = public_bodies(:humpadink_public_body)
+ pb.translation_for(:es).destroy
+ pb.reload
+
+ post :update, {
+ :id => pb.id,
+ :public_body => {
+ :name => "Department for Humpadinking",
+ :short_name => "",
+ :tag_string => "some tags",
+ :request_email => 'edited@localhost',
+ :last_edit_comment => 'From test code',
+ :translations_attributes => {
+ 'es' => { :locale => "es",
+ :name => "El Department for Humpadinking",
+ :short_name => "",
+ :request_email => 'edited@localhost' }
+ }
+ }
+ }
+
+ request.flash[:notice].should include('successful')
+
+ pb = PublicBody.find(public_bodies(:humpadink_public_body).id)
+
+ I18n.with_locale(:es) do
+ expect(pb.name).to eq('El Department for Humpadinking')
+ end
+ end
+
+ it 'adds new translations' do
+ pb = public_bodies(:humpadink_public_body)
+ pb.translation_for(:es).destroy
+ pb.reload
+
+ post :update, {
+ :id => pb.id,
+ :public_body => {
+ :name => "Department for Humpadinking",
+ :short_name => "",
+ :tag_string => "some tags",
+ :request_email => 'edited@localhost',
+ :last_edit_comment => 'From test code',
+ :translations_attributes => {
+ 'es' => { :locale => "es",
+ :name => "El Department for Humpadinking",
+ :short_name => "",
+ :request_email => 'edited@localhost' },
+ 'fr' => { :locale => "fr",
+ :name => "Le Department for Humpadinking",
+ :short_name => "",
+ :request_email => 'edited@localhost' }
+ }
+ }
+ }
+
+ request.flash[:notice].should include('successful')
+
+ pb = PublicBody.find(public_bodies(:humpadink_public_body).id)
+
+ I18n.with_locale(:es) do
+ expect(pb.name).to eq('El Department for Humpadinking')
+ end
+
+ I18n.with_locale(:fr) do
+ expect(pb.name).to eq('Le Department for Humpadinking')
+ end
+ end
+
+ it 'updates an existing translation and adds a third translation' do
+ pb = public_bodies(:humpadink_public_body)
+
+ put :update, {
+ :id => pb.id,
+ :public_body => {
+ :name => "Department for Humpadinking",
+ :short_name => "",
+ :tag_string => "some tags",
+ :request_email => 'edited@localhost',
+ :last_edit_comment => 'From test code',
+ :translations_attributes => {
+ # Update existing translation
+ 'es' => { :locale => "es",
+ :name => "Renamed Department for Humpadinking",
+ :short_name => "",
+ :request_email => 'edited@localhost' },
+ # Add new translation
+ 'fr' => { :locale => "fr",
+ :name => "Le Department for Humpadinking",
+ :short_name => "",
+ :request_email => 'edited@localhost' }
+ }
+ }
+ }
+
+ request.flash[:notice].should include('successful')
+
+ pb = PublicBody.find(public_bodies(:humpadink_public_body).id)
+
+ I18n.with_locale(:es) do
+ expect(pb.name).to eq('Renamed Department for Humpadinking')
+ end
+
+ I18n.with_locale(:fr) do
+ expect(pb.name).to eq('Le Department for Humpadinking')
+ end
+
+ end
+
it "saves edits to a public body in another locale" do
I18n.with_locale(:es) do
pb = PublicBody.find(id=3)
@@ -208,11 +335,11 @@ describe AdminPublicBodyController, "when updating a public body" do
:tag_string => "some tags",
:request_email => 'edited@localhost',
:last_edit_comment => 'From test code',
- :translated_versions => {
- 3 => {:locale => "es",
- :name => "Renamed",
- :short_name => "",
- :request_email => 'edited@localhost'}
+ :translations_attributes => {
+ 'es' => { :locale => "es",
+ :name => "Renamed",
+ :short_name => "",
+ :request_email => 'edited@localhost' }
}
}
}
@@ -220,12 +347,15 @@ describe AdminPublicBodyController, "when updating a public body" do
end
pb = PublicBody.find(public_bodies(:humpadink_public_body).id)
+
I18n.with_locale(:es) do
- pb.name.should == "Renamed"
+ expect(pb.name).to eq('Renamed')
end
+
I18n.with_locale(:en) do
- pb.name.should == "Department for Humpadinking"
+ expect(pb.name).to eq('Department for Humpadinking')
end
+
end
context 'when the body is being updated as a result of a change request' do
diff --git a/spec/integration/admin_public_body_edit_spec.rb b/spec/integration/admin_public_body_edit_spec.rb
new file mode 100644
index 000000000..613793dd4
--- /dev/null
+++ b/spec/integration/admin_public_body_edit_spec.rb
@@ -0,0 +1,71 @@
+require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+require File.expand_path(File.dirname(__FILE__) + '/alaveteli_dsl')
+
+describe 'Editing a Public Body' do
+ before do
+ AlaveteliConfiguration.stub!(:skip_admin_auth).and_return(false)
+
+ confirm(:admin_user)
+ @admin = login(:admin_user)
+
+ PublicBody.create(:name => 'New Quango',
+ :short_name => '',
+ :request_email => 'newquango@localhost',
+ :last_edit_editor => 'test',
+ :last_edit_comment => 'testing')
+
+ @body = PublicBody.find_by_name('New Quango')
+ end
+
+ it 'can edit the default locale' do
+ @admin.visit admin_body_edit_path(@body)
+ @admin.fill_in 'public_body_name__en', :with => 'New Quango EN'
+ @admin.click_button 'Save'
+
+ pb = @body.reload
+ expect(pb.name).to eq('New Quango EN')
+ end
+
+ it 'can add a translation for a single locale' do
+ expect(@body.find_translation_by_locale('fr')).to be_nil
+
+ @admin.visit admin_body_edit_path(@body)
+ @admin.fill_in 'public_body_translations_attributes_fr_name__fr', :with => 'New Quango FR'
+ @admin.click_button 'Save'
+
+ pb = @body.reload
+ I18n.with_locale(:fr) do
+ expect(pb.name).to eq('New Quango FR')
+ end
+ end
+
+ it 'can add a translation for multiple locales', :focus => true do
+ @admin.visit admin_body_edit_path(@body)
+ @admin.fill_in 'public_body_name__en', :with => 'New Quango EN'
+ @admin.click_button 'Save'
+
+ # Add FR translation
+ expect(@body.find_translation_by_locale('fr')).to be_nil
+ @admin.visit admin_body_edit_path(@body)
+ @admin.fill_in 'public_body_translations_attributes_fr_name__fr', :with => 'New Quango FR'
+ @admin.click_button 'Save'
+
+ # Add ES translation
+ expect(@body.find_translation_by_locale('es')).to be_nil
+ @admin.visit admin_body_edit_path(@body)
+ @admin.fill_in 'public_body_translations_attributes_es_name__es', :with => 'New Quango ES'
+ @admin.click_button 'Save'
+
+ pb = @body.reload
+
+ expect(pb.name).to eq('New Quango EN')
+
+ I18n.with_locale(:fr) do
+ expect(pb.name).to eq('New Quango FR')
+ end
+
+ I18n.with_locale(:es) do
+ expect(pb.name).to eq('New Quango ES')
+ end
+ end
+end
diff --git a/spec/models/public_body_spec.rb b/spec/models/public_body_spec.rb
index 225958cac..f12582f21 100644
--- a/spec/models/public_body_spec.rb
+++ b/spec/models/public_body_spec.rb
@@ -28,6 +28,108 @@
require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+describe PublicBody do
+
+ describe :translations_attributes= do
+
+ context 'translation_attrs is a Hash' do
+
+ it 'takes the correct code path for a Hash' do
+ attrs = {}
+ attrs.should_receive(:each_value)
+ PublicBody.new().translations_attributes = attrs
+ end
+
+ it 'updates an existing translation' do
+ body = public_bodies(:geraldine_public_body)
+ translation = body.translation_for(:es)
+ params = { 'es' => { :locale => 'es',
+ :name => 'Renamed' } }
+
+ body.translations_attributes = params
+ I18n.with_locale(:es) { expect(body.name).to eq('Renamed') }
+ end
+
+ it 'updates an existing translation and creates a new translation' do
+ body = public_bodies(:geraldine_public_body)
+ translation = body.translation_for(:es)
+
+ expect(body.translations.size).to eq(2)
+
+ body.translations_attributes = {
+ 'es' => { :locale => 'es',
+ :name => 'Renamed' },
+ 'fr' => { :locale => 'fr',
+ :name => 'Le Geraldine Quango' }
+ }
+
+ expect(body.translations.size).to eq(3)
+ I18n.with_locale(:es) { expect(body.name).to eq('Renamed') }
+ I18n.with_locale(:fr) { expect(body.name).to eq('Le Geraldine Quango') }
+ end
+
+ it 'skips empty translations' do
+ body = public_bodies(:geraldine_public_body)
+ translation = body.translation_for(:es)
+
+ expect(body.translations.size).to eq(2)
+
+ body.translations_attributes = {
+ 'es' => { :locale => 'es',
+ :name => 'Renamed' },
+ 'fr' => { :locale => 'fr' }
+ }
+
+ expect(body.translations.size).to eq(2)
+ end
+
+ end
+
+ context 'translation_attrs is an Array' do
+
+ it 'takes the correct code path for an Array' do
+ attrs = []
+ attrs.should_receive(:each)
+ PublicBody.new().translations_attributes = attrs
+ end
+
+ it 'creates a new translation' do
+ body = public_bodies(:geraldine_public_body)
+ body.translation_for(:es).destroy
+ body.reload
+
+ expect(body.translations.size).to eq(1)
+
+ body.translations_attributes = [ {
+ :locale => 'es',
+ :name => 'Renamed'
+ }
+ ]
+
+ expect(body.translations.size).to eq(2)
+ I18n.with_locale(:es) { expect(body.name).to eq('Renamed') }
+ end
+
+ it 'skips empty translations' do
+ body = public_bodies(:geraldine_public_body)
+ body.translation_for(:es).destroy
+ body.reload
+
+ expect(body.translations.size).to eq(1)
+
+ body.translations_attributes = [
+ { :locale => 'empty' }
+ ]
+
+ expect(body.translations.size).to eq(1)
+ end
+
+ end
+
+ end
+
+end
+
describe PublicBody, " using tags" do
before do
@public_body = PublicBody.new(:name => 'Aardvark Monitoring Service',