diff options
20 files changed, 2065 insertions, 729 deletions
diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss index 31fe7e95a..9b792dee3 100644 --- a/app/assets/stylesheets/admin.scss +++ b/app/assets/stylesheets/admin.scss @@ -123,6 +123,14 @@ body.admin { padding: 3px 0; } + .fieldWithErrors { + display:block; + padding:0.2em; + textarea, input { + border:solid 1px Red !important; + } + } + /* Holidays */ .day_select { width: 75px; diff --git a/app/controllers/admin_public_body_categories_controller.rb b/app/controllers/admin_public_body_categories_controller.rb index 5e305dde3..a86171c76 100644 --- a/app/controllers/admin_public_body_categories_controller.rb +++ b/app/controllers/admin_public_body_categories_controller.rb @@ -7,17 +7,39 @@ class AdminPublicBodyCategoriesController < AdminController def new @category = PublicBodyCategory.new - render :formats => [:html] + @category.build_all_translations + end + + def create + I18n.with_locale(I18n.default_locale) do + @category = PublicBodyCategory.new(params[:public_body_category]) + if @category.save + # FIXME: This can't handle failure (e.g. if a PublicBodyHeading + # doesn't exist) + if params[:headings] + params[:headings].values.each do |heading_id| + PublicBodyHeading.find(heading_id).add_category(@category) + end + end + flash[:notice] = 'Category was successfully created.' + redirect_to admin_categories_path + else + @category.build_all_translations + render :action => 'new' + end + end end def edit @category = PublicBodyCategory.find(params[:id]) + @category.build_all_translations @tagged_public_bodies = PublicBody.find_by_tag(@category.category_tag) end def update @category = PublicBodyCategory.find(params[:id]) @tagged_public_bodies = PublicBody.find_by_tag(@category.category_tag) + heading_ids = [] I18n.with_locale(I18n.default_locale) do @@ -43,6 +65,8 @@ class AdminPublicBodyCategoriesController < AdminController end added_headings.each do |heading_id| + # FIXME: This can't handle failure (e.g. if a + # PublicBodyHeading doesn't exist) PublicBodyHeading.find(heading_id).add_category(@category) end end @@ -51,29 +75,13 @@ class AdminPublicBodyCategoriesController < AdminController flash[:notice] = 'Category was successfully updated.' redirect_to edit_admin_category_path(@category) else + @category.build_all_translations render :action => 'edit' end end end end - def create - I18n.with_locale(I18n.default_locale) do - @category = PublicBodyCategory.new(params[:public_body_category]) - if @category.save - if params[:headings] - params[:headings].values.each do |heading_id| - PublicBodyHeading.find(heading_id).add_category(@category) - end - end - flash[:notice] = 'Category was successfully created.' - redirect_to admin_categories_path - else - render :action => 'new' - end - end - end - def destroy @locale = self.locale_from_params I18n.with_locale(@locale) do diff --git a/app/controllers/admin_public_body_controller.rb b/app/controllers/admin_public_body_controller.rb index d188f109d..7de27121a 100644 --- a/app/controllers/admin_public_body_controller.rb +++ b/app/controllers/admin_public_body_controller.rb @@ -23,10 +23,7 @@ class AdminPublicBodyController < AdminController def new @public_body = PublicBody.new - - I18n.available_locales.each do |locale| - @public_body.translations.build(:locale => locale) - end + @public_body.build_all_translations if params[:change_request_id] @change_request = PublicBodyChangeRequest.find(params[:change_request_id]) @@ -58,6 +55,7 @@ class AdminPublicBodyController < AdminController flash[:notice] = 'PublicBody was successfully created.' redirect_to admin_body_url(@public_body) else + @public_body.build_all_translations render :action => 'new' end end @@ -65,10 +63,7 @@ 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 + @public_body.build_all_translations if params[:change_request_id] @change_request = PublicBodyChangeRequest.find(params[:change_request_id]) @@ -99,6 +94,7 @@ class AdminPublicBodyController < AdminController flash[:notice] = 'PublicBody was successfully updated.' redirect_to admin_body_url(@public_body) else + @public_body.build_all_translations render :action => 'edit' end end diff --git a/app/controllers/admin_public_body_headings_controller.rb b/app/controllers/admin_public_body_headings_controller.rb index e893e760d..a7fe27390 100644 --- a/app/controllers/admin_public_body_headings_controller.rb +++ b/app/controllers/admin_public_body_headings_controller.rb @@ -1,22 +1,52 @@ class AdminPublicBodyHeadingsController < AdminController + def new + @heading = PublicBodyHeading.new + @heading.build_all_translations + end + + def create + I18n.with_locale(I18n.default_locale) do + @heading = PublicBodyHeading.new(params[:public_body_heading]) + if @heading.save + flash[:notice] = 'Heading was successfully created.' + redirect_to admin_categories_url + else + @heading.build_all_translations + render :action => 'new' + end + end + end + def edit @heading = PublicBodyHeading.find(params[:id]) - render :formats => [:html] + @heading.build_all_translations end def update + @heading = PublicBodyHeading.find(params[:id]) + I18n.with_locale(I18n.default_locale) do - @heading = PublicBodyHeading.find(params[:id]) if @heading.update_attributes(params[:public_body_heading]) - flash[:notice] = 'Category heading was successfully updated.' + flash[:notice] = 'Heading was successfully updated.' redirect_to edit_admin_heading_path(@heading) else + @heading.build_all_translations render :action => 'edit' end end end + def destroy + @locale = self.locale_from_params + I18n.with_locale(@locale) do + heading = PublicBodyHeading.find(params[:id]) + heading.destroy + flash[:notice] = "Heading was successfully destroyed." + redirect_to admin_categories_url + end + end + def reorder transaction = reorder_headings(params[:headings]) if transaction[:success] @@ -35,33 +65,6 @@ class AdminPublicBodyHeadingsController < AdminController end end - def new - @heading = PublicBodyHeading.new - render :formats => [:html] - end - - def create - I18n.with_locale(I18n.default_locale) do - @heading = PublicBodyHeading.new(params[:public_body_heading]) - if @heading.save - flash[:notice] = 'Category heading was successfully created.' - redirect_to admin_categories_url - else - render :action => 'new' - end - end - end - - def destroy - @locale = self.locale_from_params() - I18n.with_locale(@locale) do - heading = PublicBodyHeading.find(params[:id]) - heading.destroy - flash[:notice] = "Category heading was successfully destroyed." - redirect_to admin_categories_url - end - end - protected def reorder_headings(headings) diff --git a/app/models/public_body.rb b/app/models/public_body.rb index 0e90a3c16..232c0ffa1 100644 --- a/app/models/public_body.rb +++ b/app/models/public_body.rb @@ -64,7 +64,7 @@ class PublicBody < ActiveRecord::Base } translates :name, :short_name, :request_email, :url_name, :notes, :first_letter, :publication_scheme - accepts_nested_attributes_for :translations + accepts_nested_attributes_for :translations, :reject_if => :empty_translation_in_params? # Default fields available for importing from CSV, in the format # [field_name, 'short description of field (basic html allowed)'] @@ -152,33 +152,15 @@ class PublicBody < ActiveRecord::Base translations end - def translations_attributes=(translation_attrs) - def empty_translation?(attrs) - 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) - t = translation_for(attrs[:locale]) || PublicBody::Translation.new - t.attributes = attrs - calculate_cached_fields(t) - 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) - calculate_cached_fields(new_translation) - translations << new_translation - end + def ordered_translations + translations. + select { |t| I18n.available_locales.include?(t.locale) }. + sort_by { |t| I18n.available_locales.index(t.locale) } + end + + def build_all_translations + I18n.available_locales.each do |locale| + translations.build(:locale => locale) unless translations.detect{ |t| t.locale == locale } end end @@ -791,6 +773,13 @@ class PublicBody < ActiveRecord::Base end end + def empty_translation_in_params?(attributes) + attrs_with_values = attributes.select do |key, value| + value != '' and key.to_s != 'locale' + end + attrs_with_values.empty? + end + def request_email_if_requestable # Request_email can be blank, meaning we don't have details if self.is_requestable? diff --git a/app/models/public_body_category.rb b/app/models/public_body_category.rb index 198e8b737..eeb2511fa 100644 --- a/app/models/public_body_category.rb +++ b/app/models/public_body_category.rb @@ -10,12 +10,15 @@ require 'forwardable' class PublicBodyCategory < ActiveRecord::Base attr_accessible :locale, :category_tag, :title, :description, - :translated_versions, :display_order + :translated_versions, :translations_attributes, + :display_order has_many :public_body_category_links, :dependent => :destroy has_many :public_body_headings, :through => :public_body_category_links translates :title, :description + accepts_nested_attributes_for :translations, :reject_if => :empty_translation_in_params? + validates_uniqueness_of :category_tag, :message => 'Tag is already taken' validates_presence_of :title, :message => "Title can't be blank" validates_presence_of :category_tag, :message => "Tag can't be blank" @@ -59,25 +62,48 @@ class PublicBodyCategory < ActiveRecord::Base end def translated_versions=(translation_attrs) - def empty_translation?(attrs) - attrs_with_values = attrs.select{ |key, value| value != '' and key != 'locale' } - attrs_with_values.empty? + warn "[DEPRECATION] PublicBodyCategory#translated_versions= will be replaced " \ + "by PublicBodyCategory#translations_attributes= as of release 0.22" + self.translations_attributes = translation_attrs + end + + def ordered_translations + translations. + select { |t| I18n.available_locales.include?(t.locale) }. + sort_by { |t| I18n.available_locales.index(t.locale) } + end + + def build_all_translations + I18n.available_locales.each do |locale| + translations.build(:locale => locale) unless translations.detect{ |t| t.locale == locale } end - if translation_attrs.respond_to? :each_value # Hash => updating - translation_attrs.each_value do |attrs| - next if empty_translation?(attrs) - t = translation_for(attrs[:locale]) || PublicBodyCategory::Translation.new - t.attributes = attrs - t.save! - end - else # Array => creating - translation_attrs.each do |attrs| - next if empty_translation?(attrs) - new_translation = PublicBodyCategory::Translation.new(attrs) - translations << new_translation - end + end + + private + + def empty_translation_in_params?(attributes) + attrs_with_values = attributes.select do |key, value| + value != '' and key.to_s != 'locale' end + attrs_with_values.empty? end + end +PublicBodyCategory::Translation.class_eval do + with_options :if => lambda { |t| !t.default_locale? && t.required_attribute_submitted? } do |required| + required.validates :title, :presence => { :message => _("Title can't be blank") } + required.validates :description, :presence => { :message => _("Description can't be blank") } + end + + def default_locale? + locale == I18n.default_locale + end + def required_attribute_submitted? + PublicBodyCategory.required_translated_attributes.compact.any? do |attribute| + !read_attribute(attribute).blank? + end + end + +end diff --git a/app/models/public_body_heading.rb b/app/models/public_body_heading.rb index f394c37c6..8c160ba8b 100644 --- a/app/models/public_body_heading.rb +++ b/app/models/public_body_heading.rb @@ -7,13 +7,15 @@ # class PublicBodyHeading < ActiveRecord::Base - attr_accessible :name, :display_order, :translated_versions + attr_accessible :locale, :name, :display_order, :translated_versions, + :translations_attributes has_many :public_body_category_links, :dependent => :destroy has_many :public_body_categories, :order => :category_display_order, :through => :public_body_category_links default_scope order('display_order ASC') translates :name + accepts_nested_attributes_for :translations, :reject_if => :empty_translation_in_params? validates_uniqueness_of :name, :message => 'Name is already taken' validates_presence_of :name, :message => 'Name can\'t be blank' @@ -36,24 +38,20 @@ class PublicBodyHeading < ActiveRecord::Base end def translated_versions=(translation_attrs) - def empty_translation?(attrs) - attrs_with_values = attrs.select{ |key, value| value != '' and key != 'locale' } - attrs_with_values.empty? - end + warn "[DEPRECATION] PublicBodyHeading#translated_versions= will be replaced " \ + "by PublicBodyHeading#translations_attributes= as of release 0.22" + self.translations_attributes = translation_attrs + end + + def ordered_translations + translations. + select { |t| I18n.available_locales.include?(t.locale) }. + sort_by { |t| I18n.available_locales.index(t.locale) } + end - if translation_attrs.respond_to? :each_value # Hash => updating - translation_attrs.each_value do |attrs| - next if empty_translation?(attrs) - t = translation_for(attrs[:locale]) || PublicBodyHeading::Translation.new - t.attributes = attrs - t.save! - end - else # Array => creating - translation_attrs.each do |attrs| - next if empty_translation?(attrs) - new_translation = PublicBodyHeading::Translation.new(attrs) - translations << new_translation - end + def build_all_translations + I18n.available_locales.each do |locale| + translations.build(:locale => locale) unless translations.detect{ |t| t.locale == locale } end end @@ -71,4 +69,13 @@ class PublicBodyHeading < ActiveRecord::Base end end + private + + def empty_translation_in_params?(attributes) + attrs_with_values = attributes.select do |key, value| + value != '' and key.to_s != 'locale' + end + attrs_with_values.empty? + end + end diff --git a/app/views/admin_public_body/_form.html.erb b/app/views/admin_public_body/_form.html.erb index c765c116e..cf0c0e3de 100644 --- a/app/views/admin_public_body/_form.html.erb +++ b/app/views/admin_public_body/_form.html.erb @@ -1,20 +1,39 @@ -<%= error_messages_for 'public_body' %> +<% if @public_body.errors.any? %> + <ul> + <% @public_body.errors.each do |attr, message| %> + <% unless attr.to_s.starts_with?('translation') %> + <li><%= message %></li> + <% end %> + <% end %> + </ul> +<% end %> + +<% @public_body.ordered_translations.each do |translation| %> + <% if translation.errors.any? %> + <%= locale_name(translation.locale.to_s) || translation.locale.to_s %> + <ul> + <% translation.errors.each do |attr, message| %> + <li><%= message %></li> + <% end %> + </ul> + <% end %> +<% end %> <!--[form:public_body]--> <div id="div-locales"> <ul class="locales nav nav-tabs"> - <% @public_body.translations.each do |translation| %> + <% @public_body.ordered_translations.each do |translation| %> <li> <a href="#div-locale-<%= translation.locale.to_s %>" data-toggle="tab"> - <%= locale_name(translation.locale.to_s) || _("Default locale") %> + <%= locale_name(translation.locale.to_s) || translation.locale.to_s %> </a> </li> <% end %> </ul> <div class="tab-content"> - <% @public_body.translations.each do |translation| %> + <% @public_body.ordered_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 } %> diff --git a/app/views/admin_public_body_categories/_form.html.erb b/app/views/admin_public_body_categories/_form.html.erb index 1f033ac9b..00137b9ed 100644 --- a/app/views/admin_public_body_categories/_form.html.erb +++ b/app/views/admin_public_body_categories/_form.html.erb @@ -1,46 +1,49 @@ -<%= error_messages_for 'category' %> +<% if @category.errors.any? %> + <ul> + <% @category.errors.each do |attr, message| %> + <% unless attr.to_s.starts_with?('translation') %> + <li><%= message %></li> + <% end %> + <% end %> + </ul> +<% end %> + +<% @category.ordered_translations.each do |translation| %> + <% if translation.errors.any? %> + <%= locale_name(translation.locale.to_s) || translation.locale.to_s %> + <ul> + <% translation.errors.each do |attr, message| %> + <li><%= message %></li> + <% end %> + </ul> + <% end %> +<% end %> <!--[form:public_body_category]--> <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 %> + <% @category.ordered_translations.each do |translation| %> + <li> + <a href="#div-locale-<%= translation.locale.to_s %>" data-toggle="tab" > + <%= locale_name(translation.locale.to_s) || translation.locale.to_s %> + </a> + </li> + <% end %> </ul> + <div class="tab-content"> -<% - I18n.available_locales.each do |locale| - if locale==I18n.default_locale # The default locale is submitted as part of the bigger object... - prefix = 'public_body_category' - object = @category - else # ...but additional locales go "on the side" - prefix = "public_body_category[translated_versions][]" - object = @category.new_record? ? - PublicBodyCategory::Translation.new : - @category.find_translation_by_locale(locale.to_s) || PublicBodyCategory::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, :title, locale) %>" class="control-label">Title</label> - <div class="controls"> - <%= t.text_field :title, :id => form_tag_id(t.object_name, :title, locale), :class => "span4" %> - </div> - </div> - <div class="control-group"> - <label for="<%= form_tag_id(t.object_name, :description, locale) %>" class="control-label">Description</label> - <div class="controls"> - <%= t.text_field :description, :id => form_tag_id(t.object_name, :description, locale), :class => "span4" %> - </div> - </div> - </div> - <% - end -end -%> + <% @category.ordered_translations.each do |translation| %> + <% if translation.locale.to_s == I18n.default_locale.to_s %> + <%= fields_for('public_body_category', @category) 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_categories/_locale_fields.html.erb b/app/views/admin_public_body_categories/_locale_fields.html.erb new file mode 100644 index 000000000..aff001098 --- /dev/null +++ b/app/views/admin_public_body_categories/_locale_fields.html.erb @@ -0,0 +1,27 @@ +<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, :title, locale) %>" class="control-label">Title</label> + <div class="controls"> + <% if locale == I18n.default_locale && t.object.errors[:title].any? %> + <span class="fieldWithErrors"> + <% end %> + <%= t.text_field :title, :id => form_tag_id(t.object_name, :title, locale), :class => "span4" %> + <% if locale == I18n.default_locale && t.object.errors[:title].any? %> + </span> + <%end %> + </div> + </div> + <div class="control-group"> + <label for="<%= form_tag_id(t.object_name, :description, locale) %>" class="control-label">Description</label> + <div class="controls"> + <% if locale == I18n.default_locale && t.object.errors[:description].any? %> + <span class="fieldWithErrors"> + <% end %> + <%= t.text_field :description, :id => form_tag_id(t.object_name, :description, locale), :class => "span4" %> + <% if locale == I18n.default_locale && t.object.errors[:description].any? %> + </span> + <%end %> + </div> + </div> +</div> diff --git a/app/views/admin_public_body_headings/_form.html.erb b/app/views/admin_public_body_headings/_form.html.erb index d4e914ca1..7eaa4bff7 100644 --- a/app/views/admin_public_body_headings/_form.html.erb +++ b/app/views/admin_public_body_headings/_form.html.erb @@ -1,40 +1,49 @@ -<%= error_messages_for 'heading' %> +<% if @heading.errors.any? %> + <ul> + <% @heading.errors.each do |attr, message| %> + <% unless attr.to_s.starts_with?('translation') %> + <li><%= message %></li> + <% end %> + <% end %> + </ul> +<% end %> + +<% @heading.ordered_translations.each do |translation| %> + <% if translation.errors.any? %> + <%= locale_name(translation.locale.to_s) || translation.locale.to_s %> + <ul> + <% translation.errors.each do |attr, message| %> + <li><%= message %></li> + <% end %> + </ul> + <% end %> +<% end %> + <!--[form:public_body_heading]--> <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 %> + <% @heading.ordered_translations.each do |translation| %> + <li> + <a href="#div-locale-<%= translation.locale.to_s %>" data-toggle="tab" > + <%= locale_name(translation.locale.to_s) || translation.locale.to_s %> + </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_heading' - object = @heading - else # ...but additional locales go "on the side" - prefix = "public_body_heading[translated_versions][]" - object = @heading.new_record? ? - PublicBodyHeading::Translation.new : - @heading.find_translation_by_locale(locale.to_s) || PublicBodyHeading::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> - <% - end -end -%> + <% @heading.ordered_translations.each do |translation| %> + <% if translation.locale.to_s == I18n.default_locale.to_s %> + <%= fields_for('public_body_heading', @heading) 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_headings/_locale_fields.html.erb b/app/views/admin_public_body_headings/_locale_fields.html.erb new file mode 100644 index 000000000..3846bfafa --- /dev/null +++ b/app/views/admin_public_body_headings/_locale_fields.html.erb @@ -0,0 +1,9 @@ +<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> diff --git a/spec/controllers/admin_public_body_categories_controller_spec.rb b/spec/controllers/admin_public_body_categories_controller_spec.rb index 4c641bd75..1131b3c0b 100644 --- a/spec/controllers/admin_public_body_categories_controller_spec.rb +++ b/spec/controllers/admin_public_body_categories_controller_spec.rb @@ -1,120 +1,268 @@ require 'spec_helper' describe AdminPublicBodyCategoriesController do - context 'when showing the index of categories and headings' do - render_views - it 'shows the index page' do + describe :index do + + it 'responds successfully' do get :index expect(response).to be_success end + + it 'uses the current locale by default' do + get :index + expect(assigns(:locale)).to eq(I18n.locale.to_s) + end + + it 'sets the locale if the show_locale param is passed' do + get :index, :show_locale => 'es' + expect(assigns(:locale)).to eq('es') + end + + it 'finds all category headings' do + PublicBodyHeading.destroy_all + + headings = [FactoryGirl.create(:public_body_heading), + FactoryGirl.create(:public_body_heading)] + + get :index + + expect(assigns(:category_headings)).to eq(headings) + end + + it 'finds all categories without their headings' do + PublicBodyHeading.destroy_all + PublicBodyCategory.destroy_all + + without_heading = FactoryGirl.create(:public_body_category) + + heading = FactoryGirl.create(:public_body_heading) + with_heading = FactoryGirl.create(:public_body_category) + PublicBodyCategoryLink.create!(:public_body_heading_id => heading.id, + :public_body_category_id => with_heading.id) + + + get :index + expect(assigns(:without_heading)).to eq([without_heading]) + end + + it 'renders the index template' do + get :index + expect(response).to render_template('index') + end + end - context 'when showing the form for a new public body category' do - it 'should assign a new public body category to the view' do + describe :new do + + it 'responds successfully' do get :new - assigns[:category].should be_a(PublicBodyCategory) + expect(response).to be_success end - it 'renders the new template' do + it 'builds a new PublicBodyCategory' do get :new - expect(response).to render_template('new') + expect(assigns(:category)).to be_new_record end + it 'builds new translations for all locales' do + get :new + + translations = assigns(:category).translations.map{ |t| t.locale.to_s }.sort + available = I18n.available_locales.map{ |l| l.to_s }.sort + + expect(translations).to eq(available) + end + + it 'renders the new template' do + get :new + expect(response).to render_template('new') + end + end - context 'when creating a public body category' do - it "creates a new public body category in one locale" do - n = PublicBodyCategory.count - post :create, { - :public_body_category => { - :title => 'New Category', - :category_tag => 'new_test_category', - :description => 'New category for testing stuff' - } - } - PublicBodyCategory.count.should == n + 1 + describe :create do + + context 'on success' do + + before(:each) do + PublicBodyCategory.destroy_all + @params = { :category_tag => 'new_test_category', + :translations_attributes => { + 'en' => { :locale => 'en', + :title => 'New Category', + :description => 'New category for testing stuff' } + } } + end + + it 'creates a new category in the default locale' do + PublicBodyCategory.destroy_all + + expect { + post :create, :public_body_category => @params + }.to change{ PublicBodyCategory.count }.from(0).to(1) + end + + it "saves the public body category's heading associations" do + heading = FactoryGirl.create(:public_body_heading) + params = FactoryGirl.attributes_for(:public_body_category) + + post :create, :public_body_category => @params, + :headings => { "heading_#{ heading.id }" => heading.id } + + category = PublicBodyCategory.find_by_title(@params[:translations_attributes]['en'][:title]) + expect(category.public_body_headings).to eq([heading]) + end + + it 'notifies the admin that the category was created' do + post :create, :public_body_category => @params + expect(flash[:notice]).to eq('Category was successfully created.') + end + + it 'redirects to the categories index' do + post :create, :public_body_category => @params + expect(response).to redirect_to(admin_categories_path) + end - category = PublicBodyCategory.find_by_title("New Category") - response.should redirect_to(admin_categories_path) end - it "saves the public body category's heading associations" do - heading = FactoryGirl.create(:public_body_heading) - category_attributes = FactoryGirl.attributes_for(:public_body_category) - post :create, { - :public_body_category => category_attributes, - :headings => {"heading_#{heading.id}" => heading.id} - } - request.flash[:notice].should include('successful') - category = PublicBodyCategory.find_by_title(category_attributes[:title]) - category.public_body_headings.should == [heading] + context 'on success for multiple locales' do + + before(:each) do + PublicBodyCategory.destroy_all + @params = { :category_tag => 'new_test_category', + :translations_attributes => { + 'en' => { :locale => 'en', + :title => 'New Category', + :description => 'New category for testing stuff' }, + 'es' => { :locale => 'es', + :title => 'Mi Nuevo Category', + :description => 'ES Description' } + } } + end + + it 'saves the category' do + expect { + post :create, :public_body_category => @params + }.to change{ PublicBodyCategory.count }.from(0).to(1) + end + + it 'saves the default locale translation' do + post :create, :public_body_category => @params + + category = PublicBodyCategory.find_by_title('New Category') + + I18n.with_locale(:en) do + expect(category.title).to eq('New Category') + end + end + + it 'saves the alternative locale translation' do + post :create, :public_body_category => @params + + category = PublicBodyCategory.find_by_title('New Category') + + I18n.with_locale(:es) do + expect(category.title).to eq('Mi Nuevo Category') + end + end + end - it 'creates a new public body category with multiple locales' do - n = PublicBodyCategory.count - post :create, { - :public_body_category => { - :title => 'New Category', - :category_tag => 'new_test_category', - :description => 'New category for testing stuff', - :translated_versions => [{ :locale => "es", - :title => "Mi Nuevo Category" }] - } - } - PublicBodyCategory.count.should == n + 1 + context 'on failure' do - category = PublicBodyCategory.find_by_title("New Category") - category.translations.map {|t| t.locale.to_s}.sort.should == ["en", "es"] - I18n.with_locale(:en) do - category.title.should == "New Category" + it 'renders the form if creating the record was unsuccessful' do + post :create, :public_body_category => { :title => '' } + expect(response).to render_template('new') end - I18n.with_locale(:es) do - category.title.should == "Mi Nuevo Category" + + it 'is rebuilt with the given params' do + post :create, :public_body_category => { :title => 'Need a description' } + expect(assigns(:category).title).to eq('Need a description') end - response.should redirect_to(admin_categories_path) end - it "renders the form if creating the record was unsuccessful" do - post :create, :public_body_category => { :title => '' } - expect(response).to render_template('new') + context 'on failure for multiple locales' do + + before(:each) do + @params = { :category_tag => 'new_test_category', + :translations_attributes => { + 'en' => { :locale => 'en', + :title => 'Need a description', + :description => nil }, + 'es' => { :locale => 'es', + :title => 'Mi Nuevo Category', + :description => 'ES Description' } + } } + end + + it 'is rebuilt with the default locale translation' do + post :create, :public_body_category => @params + expect(assigns(:category).title).to eq('Need a description') + end + + it 'is rebuilt with the alternative locale translation' do + post :create, :public_body_category => @params + + I18n.with_locale(:es) do + expect(assigns(:category).title).to eq('Mi Nuevo Category') + end + end + end end - context 'when editing a public body category' do + describe :edit do + before do @category = FactoryGirl.create(:public_body_category) I18n.with_locale('es') do @category.title = 'Los category' + @category.description = 'ES Description' @category.save! end end - render_views + it 'responds successfully' do + get :edit, :id => @category.id + expect(response).to be_success + end - it "finds the requested category" do + it 'finds the requested category' do get :edit, :id => @category.id expect(assigns[:category]).to eq(@category) end - it "renders the edit template" do + it 'builds new translations if the body does not already have a translation in the specified locale' do get :edit, :id => @category.id - expect(assigns[:category]).to render_template('edit') + expect(assigns[:category].translations.map(&:locale)).to include(:fr) end - it "edits a public body in another locale" do - get :edit, { :id => @category.id, :locale => :en } + it 'finds the public bodies tagged with the category tag' do + # FIXME: I wanted to call PublicBody.destroy_all here so that we + # have a known DB state, but the constraints were preventing the + # deletion of the fixture data + FactoryGirl.create(:public_body, :tag_string => 'wont_be_found') + + category = FactoryGirl.create(:public_body_category, :category_tag => 'spec') + expected_bodies = [FactoryGirl.create(:public_body, :tag_string => 'spec'), + FactoryGirl.create(:public_body, :tag_string => 'spec')] - # When editing a body, the controller returns all available - # translations - assigns[:category].find_translation_by_locale("es").title.should == 'Los category' - response.should render_template('edit') + get :edit, :id => category.id + + expect(assigns(:tagged_public_bodies).sort).to eq(expected_bodies.sort) end + + it 'renders the edit template' do + get :edit, :id => @category.id + expect(response).to render_template('edit') + end + end - context 'when updating a public body category' do + describe :update do before do @heading = FactoryGirl.create(:public_body_heading) @@ -126,109 +274,389 @@ describe AdminPublicBodyCategoriesController do @tag = @category.category_tag I18n.with_locale('es') do @category.title = 'Los category' + @category.description = 'ES Description' @category.save! end + + @params = { :category_tag => @category.category_tag, + :translations_attributes => { + 'en' => { :id => @category.translation_for(:en).id, + :locale => 'en', + :title => @category.title(:en), + :description => @category.description(:en) }, + 'es' => { :id => @category.translation_for(:es).id, + :locale => 'es', + :title => @category.title(:es), + :description => @category.description(:es) } + } } end - render_views + it 'finds the category to update' do + post :update, :id => @category.id, + :public_body_category => @params + expect(assigns(:category)).to eq(@category) + end + + it 'finds the public bodies tagged with the category tag' do + # FIXME: I wanted to call PublicBody.destroy_all here so that we + # have a known DB state, but the constraints were preventing the + # deletion of the fixture data + FactoryGirl.create(:public_body, :tag_string => 'wont_be_found') + + category = FactoryGirl.create(:public_body_category, :category_tag => 'spec') + expected_bodies = [FactoryGirl.create(:public_body, :tag_string => 'spec'), + FactoryGirl.create(:public_body, :tag_string => 'spec')] + + post :update, :id => category.id, + :public_body_category => category.serializable_hash.except(:title, :description) - it "saves edits to a public body category" do - post :update, { :id => @category.id, - :public_body_category => { :title => "Renamed" } } - request.flash[:notice].should include('successful') - pbc = PublicBodyCategory.find(@category.id) - pbc.title.should == "Renamed" + expect(assigns(:tagged_public_bodies)).to eq(expected_bodies) end it "saves edits to a public body category's heading associations" do - @category.public_body_headings.should == [@heading] + # We already have a heading from the before block. Here we're going + # to update to a new heading. heading = FactoryGirl.create(:public_body_heading) - post :update, { :id => @category.id, - :public_body_category => { :title => "Renamed" }, - :headings => {"heading_#{heading.id}" => heading.id} } - request.flash[:notice].should include('successful') - pbc = PublicBodyCategory.find(@category.id) - pbc.public_body_headings.should == [heading] - end - - it "saves edits to a public body category in another locale" do - I18n.with_locale(:es) do - @category.title.should == 'Los category' - post :update, { - :id => @category.id, - :public_body_category => { - :title => "Category", - :translated_versions => { - @category.id => {:locale => "es", - :title => "Renamed"} + + post :update, :id => @category.id, + :public_body_category => { + :translations_attributes => { + 'en' => { :id => @category.translation_for(:en).id, + :title => 'Renamed' } } - } - } - request.flash[:notice].should include('successful') + }, + :headings => { "heading_#{ heading.id }" => heading.id } + + category = PublicBodyCategory.find(@category.id) + expect(category.public_body_headings).to eq([heading]) + end + + context 'when the category has associated bodies' do + + it 'does not save edits to category_tag' do + body = FactoryGirl.create(:public_body, :tag_string => @tag) + + post :update, :id => @category.id, + :public_body_category => { :category_tag => 'Renamed' } + + + category = PublicBodyCategory.find(@category.id) + expect(category.category_tag).to eq(@tag) end - pbc = PublicBodyCategory.find(@category.id) - I18n.with_locale(:es) do - pbc.title.should == "Renamed" + it 'notifies the user that the category_tag could not be updated' do + body = FactoryGirl.create(:public_body, :tag_string => @tag) + msg = %Q(There are authorities associated with this category, + so the tag can't be renamed).squish + + post :update, :id => @category.id, + :public_body_category => { :category_tag => 'Renamed' } + + expect(flash[:error]).to eq(msg) end - I18n.with_locale(:en) do - pbc.title.should == "Category" + + it 'renders the edit action' do + body = FactoryGirl.create(:public_body, :tag_string => @tag) + + post :update, :id => @category.id, + :public_body_category => { :category_tag => 'Renamed' } + + expect(response).to render_template('edit') end + end - it "does not save edits to category_tag if the category has associated bodies" do - body = FactoryGirl.create(:public_body, :tag_string => @tag) - post :update, { :id => @category.id, - :public_body_category => { :category_tag => "renamed" } } - - msg = "There are authorities associated with this category, so the tag can't be renamed" - request.flash[:error].should == msg - pbc = PublicBodyCategory.find(@category.id) - pbc.category_tag.should == @tag + context 'on success' do + + before(:each) do + @params = { :id => @category.id, + :public_body_category => { + :translations_attributes => { + 'en' => { :id => @category.translation_for(:en).id, + :title => 'Renamed' } + } + } + } + end + + it 'saves edits to a public body category' do + post :update, @params + category = PublicBodyCategory.find(@category.id) + expect(category.title).to eq('Renamed') + end + + it 'notifies the admin that the category was created' do + post :update, @params + expect(flash[:notice]).to eq('Category was successfully updated.') + end + + it 'redirects to the category edit page' do + post :update, @params + expect(response).to redirect_to(edit_admin_category_path(@category)) + end + + it 'saves edits to category_tag if the category has no associated bodies' do + category = FactoryGirl.create(:public_body_category, :category_tag => 'empty') + + post :update, :id => category.id, + :public_body_category => { :category_tag => 'Renamed' } + + category = PublicBodyCategory.find(category.id) + expect(category.category_tag).to eq('Renamed') + end + end + context 'on success for multiple locales' do + + it "saves edits to a public body category in another locale" do + @category.title(:es).should == 'Los category' + post :update, :id => @category.id, + :public_body_category => { + :translations_attributes => { + 'en' => { :id => @category.translation_for(:en).id, + :locale => 'en', + :title => @category.title(:en), + :description => @category.description(:en) }, + 'es' => { :id => @category.translation_for(:es).id, + :locale => 'es', + :title => 'Renamed', + :description => 'ES Description' } + } + } + + category = PublicBodyCategory.find(@category.id) + expect(category.title(:es)).to eq('Renamed') + expect(category.title(:en)).to eq(@category.title(:en)) + end + + it 'adds a new translation' do + @category.translation_for(:es).destroy + @category.reload + + put :update, { + :id => @category.id, + :public_body_category => { + :translations_attributes => { + 'en' => { :id => @category.translation_for(:en).id, + :locale => 'en', + :title => @category.title(:en), + :description => @category.description(:en) }, + 'es' => { :locale => "es", + :title => "Example Public Body Category ES", + :description => @category.description(:es) } + } + } + } + + request.flash[:notice].should include('successful') + + pbc = PublicBodyCategory.find(@category.id) + + I18n.with_locale(:es) do + expect(pbc.title).to eq('Example Public Body Category ES') + end + end + + it 'adds new translations' do + @category.translation_for(:es).destroy + @category.reload + + post :update, { + :id => @category.id, + :public_body_category => { + :translations_attributes => { + 'en' => { :id => @category.translation_for(:en).id, + :locale => 'en', + :title => @category.title(:en), + :description => @category.description(:en) }, + 'es' => { :locale => "es", + :title => "Example Public Body Category ES", + :description => 'ES Description' }, + 'fr' => { :locale => "fr", + :title => "Example Public Body Category FR", + :description => 'FR Description' } + } + } + } + + request.flash[:notice].should include('successful') + + pbc = PublicBodyCategory.find(@category.id) + + I18n.with_locale(:es) do + expect(pbc.title).to eq('Example Public Body Category ES') + end + I18n.with_locale(:fr) do + expect(pbc.title).to eq('Example Public Body Category FR') + end + end + + it 'updates an existing translation and adds a third translation' do + post :update, { + :id => @category.id, + :public_body_category => { + :translations_attributes => { + 'en' => { :id => @category.translation_for(:en).id, + :locale => 'en', + :title => @category.title(:en), + :description => @category.description(:en) }, + # Update existing translation + 'es' => { :id => @category.translation_for(:es).id, + :locale => "es", + :title => "Renamed Example Public Body Category ES", + :description => @category.description }, + # Add new translation + 'fr' => { :locale => "fr", + :title => "Example Public Body Category FR", + :description => @category.description } + } + } + } + + request.flash[:notice].should include('successful') + + pbc = PublicBodyCategory.find(@category.id) + + I18n.with_locale(:es) do + expect(pbc.title).to eq('Renamed Example Public Body Category ES') + end + I18n.with_locale(:fr) do + expect(pbc.title).to eq('Example Public Body Category FR') + end + end + + it "redirects to the edit page after a successful update" do + post :update, :id => @category.id, + :public_body_category => { + :translations_attributes => { + 'en' => { :id => @category.translation_for(:en).id, + :locale => 'en', + :title => @category.title(:en), + :description => @category.description(:en) } + } } + + expect(response).to redirect_to(edit_admin_category_path(@category)) + end - it "save edits to category_tag if the category has no associated bodies" do - category = PublicBodyCategory.create(:title => "Empty Category", :category_tag => "empty", :description => "-") - post :update, { :id => category.id, - :public_body_category => { :category_tag => "renamed" } } - request.flash[:notice].should include('success') - pbc = PublicBodyCategory.find(category.id) - pbc.category_tag.should == "renamed" end - it "redirects to the edit page after a successful update" do - post :update, { :id => @category.id, - :public_body_category => { :title => "Renamed" } } + context 'on failure' do + + it 'renders the form if creating the record was unsuccessful' do + post :update, :id => @category.id, + :public_body_category => { + :translations_attributes => { + 'en' => { :id => @category.translation_for(:en).id, + :locale => 'en', + :title => '', + :description => @category.description(:en) } + } } + expect(response).to render_template('edit') + end + + it 'is rebuilt with the given params' do + post :update, :id => @category.id, + :public_body_category => { + :translations_attributes => { + 'en' => { :id => @category.translation_for(:en).id, + :locale => 'en', + :title => 'Need a description', + :description => '' } + } } + expect(assigns(:category).title).to eq('Need a description') + end - expect(response).to redirect_to(edit_admin_category_path(@category)) end - it "re-renders the edit form after an unsuccessful update" do - post :update, { :id => @category.id, - :public_body_category => { :title => '' } } + context 'on failure for multiple locales' do + + before(:each) do + @params = { :category_tag => 'new_test_category', + :translations_attributes => { + 'en' => { :id => @category.translation_for(:en).id, + :locale => 'en', + :title => 'Need a description', + :description => '' }, + 'es' => { :id => @category.translation_for(:es).id, + :locale => 'es', + :title => 'Mi Nuevo Category', + :description => 'ES Description' } + } } + end + + it 'is rebuilt with the default locale translation' do + post :update, :id => @category.id, + :public_body_category => @params + expect(assigns(:category).title(:en)).to eq('Need a description') + end + + it 'is rebuilt with the alternative locale translation' do + post :update, :id => @category.id, + :public_body_category => @params + + I18n.with_locale(:es) do + expect(assigns(:category).title).to eq('Mi Nuevo Category') + end + end - expect(response).to render_template('edit') end end - context 'when destroying a public body category' do - it "destroys empty public body categories" do - pbc = PublicBodyCategory.create(:title => "Empty Category", :category_tag => "empty", :description => "-") - n = PublicBodyCategory.count - post :destroy, { :id => pbc.id } - response.should redirect_to(admin_categories_path) - PublicBodyCategory.count.should == n - 1 + describe :destroy do + + it 'uses the current locale by default' do + category = FactoryGirl.create(:public_body_category) + post :destroy, :id => category.id + expect(assigns(:locale)).to eq(I18n.locale.to_s) end - it "destroys non-empty public body categories" do + it 'sets the locale if the show_locale param is passed' do + category = FactoryGirl.create(:public_body_category) + post :destroy, :id => category.id, :show_locale => 'es' + expect(assigns(:locale)).to eq('es') + end + + it 'destroys empty public body categories' do + PublicBodyCategory.destroy_all + + category = FactoryGirl.create(:public_body_category) + + expect{ + post :destroy, :id => category.id + }.to change{ PublicBodyCategory.count }.from(1).to(0) + end + + it 'destroys non-empty public body categories' do + PublicBodyCategory.destroy_all + + # FIXME: Couldn't create the PublicBodyCategory with a Factory + # because #authorities= doesn't exist? + # undefined method `authorities=' for + # #<PublicBodyCategory:0x7f55cbb84f70> authority = FactoryGirl.create(:public_body) - pbc = PublicBodyCategory.create(:title => "In-Use Category", :category_tag => "empty", :description => "-", :authorities => [authority]) - n = PublicBodyCategory.count - post :destroy, { :id => pbc.id } - response.should redirect_to(admin_categories_path) - PublicBodyCategory.count.should == n - 1 + category = PublicBodyCategory.create(:title => "In-Use Category", + :category_tag => "empty", + :description => "-", + :authorities => [authority]) + + expect{ + post :destroy, :id => category.id + }.to change{ PublicBodyCategory.count }.from(1).to(0) + end + + it 'notifies the admin that the category was destroyed' do + category = FactoryGirl.create(:public_body_category) + post :destroy, :id => category.id + expect(flash[:notice]).to eq('Category was successfully destroyed.') + end + + it 'redirects to the categories index' do + category = FactoryGirl.create(:public_body_category) + post :destroy, :id => category.id + expect(response).to redirect_to(admin_categories_path) end + end end diff --git a/spec/controllers/admin_public_body_controller_spec.rb b/spec/controllers/admin_public_body_controller_spec.rb index 3ab58317a..50a373d9d 100644 --- a/spec/controllers/admin_public_body_controller_spec.rb +++ b/spec/controllers/admin_public_body_controller_spec.rb @@ -39,9 +39,14 @@ end describe AdminPublicBodyController, 'when showing the form for a new public body' do + it 'responds successfully' do + get :new + expect(response).to be_success + end + it 'should assign a new public body to the view' do get :new - assigns[:public_body].should be_a(PublicBody) + expect(assigns(:public_body)).to be_new_record end it "builds new translations for all locales" do @@ -53,6 +58,11 @@ describe AdminPublicBodyController, 'when showing the form for a new public body expect(translations).to eq(available) end + it 'renders the new template' do + get :new + expect(response).to render_template('new') + end + context 'when passed a change request id as a param' do render_views @@ -76,51 +86,127 @@ end describe AdminPublicBodyController, "when creating a public body" do render_views - it "creates a new public body in one locale" do - n = PublicBody.count - post :create, { :public_body => { :name => "New Quango", - :short_name => "", - :tag_string => "blah", - :request_email => 'newquango@localhost', - :last_edit_comment => 'From test code' } } - PublicBody.count.should == n + 1 + context 'on success' do + + before(:each) do + @params = { :public_body => { :name => 'New Quango', + :short_name => 'nq', + :request_email => 'newquango@localhost', + :tag_string => 'spec', + :last_edit_comment => 'From test code' } } + end + + it 'creates a new body in the default locale' do + # FIXME: Can't call PublicBody.destroy_all because database + # database contstraints prevent them being deleted. + existing = PublicBody.count + expected = existing + 1 + expect { + post :create, @params + }.to change{ PublicBody.count }.from(existing).to(expected) + end + + it 'notifies the admin that the body was created' do + post :create, @params + expect(flash[:notice]).to eq('PublicBody was successfully created.') + end + + it 'redirects to the admin page of the body' do + post :create, @params + expect(response).to redirect_to(admin_body_path(assigns(:public_body))) + end - body = PublicBody.find_by_name("New Quango") - response.should redirect_to(:controller=>'admin_public_body', :action=>'show', :id=>body.id) end - it "creates a new public body with multiple locales" do - n = PublicBody.count - post :create, { - :public_body => { :name => "New Quango", - :short_name => "", - :tag_string => "blah", - :request_email => 'newquango@localhost', - :last_edit_comment => 'From test code', - :translations_attributes => { - 'es' => { :locale => "es", - :name => "Mi Nuevo Quango", - :short_name => "", - :request_email => 'newquango@localhost' } - } - } - } - PublicBody.count.should == n + 1 + context 'on success for multiple locales' do + + before(:each) do + @params = { :public_body => { :name => 'New Quango', + :short_name => 'nq', + :request_email => 'newquango@localhost', + :tag_string => 'spec', + :last_edit_comment => 'From test code', + :translations_attributes => { + 'es' => { :locale => 'es', + :name => 'Los Quango' } + } } } + end + + it 'saves the body' do + # FIXME: Can't call PublicBody.destroy_all because database + # database contstraints prevent them being deleted. + existing = PublicBody.count + expected = existing + 1 + expect { + post :create, @params + }.to change{ PublicBody.count }.from(existing).to(expected) + end + + it 'saves the default locale translation' do + post :create, @params - body = PublicBody.find_by_name("New Quango") - body.translations.map {|t| t.locale.to_s}.sort.should == ["en", "es"] - I18n.with_locale(:en) do - body.name.should == "New Quango" - body.url_name.should == "new_quango" - body.first_letter.should == "N" + body = PublicBody.find_by_name('New Quango') + + I18n.with_locale(:en) do + expect(body.name).to eq('New Quango') + end + end + + it 'saves the alternative locale translation' do + post :create, @params + + body = PublicBody.find_by_name('New Quango') + + I18n.with_locale(:es) do + expect(body.name).to eq('Los Quango') + end + end + + end + + context 'on failure' do + + it 'renders the form if creating the record was unsuccessful' do + post :create, :public_body => { :name => '', + :translations_attributes => {} } + expect(response).to render_template('new') end - I18n.with_locale(:es) do - body.name.should == "Mi Nuevo Quango" - body.url_name.should == "mi_nuevo_quango" - body.first_letter.should == "M" + + it 'is rebuilt with the given params' do + post :create, :public_body => { :name => '', + :request_email => 'newquango@localhost', + :translations_attributes => {} } + expect(assigns(:public_body).request_email).to eq('newquango@localhost') + end + + end + + context 'on failure for multiple locales' do + + before(:each) do + @params = { :public_body => { :name => '', + :request_email => 'newquango@localhost', + :translations_attributes => { + 'es' => { :locale => 'es', + :name => 'Los Quango' } + } } } + end + + it 'is rebuilt with the default locale translation' do + post :create, @params + expect(assigns(:public_body)).to_not be_persisted + expect(assigns(:public_body).request_email).to eq('newquango@localhost') + end + + it 'is rebuilt with the alternative locale translation' do + post :create, @params + + expect(assigns(:public_body)).to_not be_persisted + I18n.with_locale(:es) do + expect(assigns(:public_body).name).to eq('Los Quango') + end end - response.should redirect_to(:controller=>'admin_public_body', :action=>'show', :id=>body.id) end context 'when the body is being created as a result of a change request' do @@ -157,10 +243,34 @@ end describe AdminPublicBodyController, "when editing a public body" do render_views - it "edits a public body" do - get :edit, :id => 2 + before do + @body = FactoryGirl.create(:public_body) + I18n.with_locale('es') do + @body.name = 'Los Body' + @body.save! + end + end + + it 'responds successfully' do + get :edit, :id => @body.id + expect(response).to be_success + end + + it 'finds the requested body' do + get :edit, :id => @body.id + expect(assigns[:public_body]).to eq(@body) end + it 'builds new translations if the body does not already have a translation in the specified locale' do + get :edit, :id => @body.id + expect(assigns[:public_body].translations.map(&:locale)).to include(:fr) + end + + it 'renders the edit template' do + get :edit, :id => @body.id + expect(response).to render_template('edit') + end + it "edits a public body in another locale" do get :edit, {:id => 3, :locale => :en} @@ -170,12 +280,6 @@ 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 @@ -201,159 +305,200 @@ end describe AdminPublicBodyController, "when updating a public body" do render_views - it "saves edits to a public body" do - public_bodies(:humpadink_public_body).name.should == "Department for Humpadinking" - post :update, { :id => 3, :public_body => { :name => "Renamed", - :short_name => "", - :tag_string => "some tags", - :request_email => 'edited@localhost', - :last_edit_comment => 'From test code' } } - request.flash[:notice].should include('successful') - pb = PublicBody.find(public_bodies(:humpadink_public_body).id) - 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) - pb.name.should == "El Department for Humpadinking" - post :update, { - :id => 3, - :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 => "Renamed", - :short_name => "", - :request_email => 'edited@localhost' } - } - } - } - request.flash[:notice].should include('successful') - end - - pb = PublicBody.find(public_bodies(:humpadink_public_body).id) - - I18n.with_locale(:es) do - expect(pb.name).to eq('Renamed') - end - - I18n.with_locale(:en) do - expect(pb.name).to eq('Department for Humpadinking') + before do + @body = FactoryGirl.create(:public_body) + I18n.with_locale('es') do + @body.name = 'Los Quango' + @body.save! + end + + @params = { :id => @body.id, + :public_body => { :name => 'Renamed', + :short_name => @body.short_name, + :request_email => @body.request_email, + :tag_string => @body.tag_string, + :last_edit_comment => 'From test code', + :translations_attributes => { + 'es' => { :id => @body.translation_for(:es).id, + :locale => 'es', + :title => @body.name(:es) } + } } } + end + + it 'finds the heading to update' do + post :update, @params + expect(assigns(:heading)).to eq(@heading) + end + + context 'on success' do + + it 'saves edits to a public body heading' do + post :update, @params + body = PublicBody.find(@body.id) + expect(body.name).to eq('Renamed') + end + + it 'notifies the admin that the body was updated' do + post :update, @params + expect(flash[:notice]).to eq('PublicBody was successfully updated.') + end + + it 'redirects to the admin body page' do + post :update, @params + expect(response).to redirect_to(admin_body_path(@body)) + end + + end + + context 'on success for multiple locales' do + + it 'saves edits to a public body heading in another locale' do + @body.name(:es).should == 'Los Quango' + post :update, :id => @body.id, + :public_body => { + :name => @body.name(:en), + :translations_attributes => { + 'es' => { :id => @body.translation_for(:es).id, + :locale => 'es', + :name => 'Renamed' } + } + } + + body = PublicBody.find(@body.id) + expect(body.name(:es)).to eq('Renamed') + expect(body.name(:en)).to eq(@body.name(:en)) + end + + it 'adds a new translation' do + @body.translation_for(:es).destroy + @body.reload + + put :update, { + :id => @body.id, + :public_body => { + :name => @body.name(:en), + :translations_attributes => { + 'es' => { :locale => "es", + :name => "Example Public Body ES" } + } + } + } + + request.flash[:notice].should include('successful') + + body = PublicBody.find(@body.id) + + I18n.with_locale(:es) do + expect(body.name).to eq('Example Public Body ES') + end + end + + it 'adds new translations' do + @body.translation_for(:es).destroy + @body.reload + + post :update, { + :id => @body.id, + :public_body => { + :name => @body.name(:en), + :translations_attributes => { + 'es' => { :locale => "es", + :name => "Example Public Body ES" }, + 'fr' => { :locale => "fr", + :name => "Example Public Body FR" } + } + } + } + + request.flash[:notice].should include('successful') + + body = PublicBody.find(@body.id) + + I18n.with_locale(:es) do + expect(body.name).to eq('Example Public Body ES') + end + I18n.with_locale(:fr) do + expect(body.name).to eq('Example Public Body FR') + end + end + + it 'updates an existing translation and adds a third translation' do + post :update, { + :id => @body.id, + :public_body => { + :name => @body.name(:en), + :translations_attributes => { + # Update existing translation + 'es' => { :id => @body.translation_for(:es).id, + :locale => "es", + :name => "Renamed Example Public Body ES" }, + # Add new translation + 'fr' => { :locale => "fr", + :name => "Example Public Body FR" } + } + } + } + + request.flash[:notice].should include('successful') + + body = PublicBody.find(@body.id) + + I18n.with_locale(:es) do + expect(body.name).to eq('Renamed Example Public Body ES') + end + I18n.with_locale(:fr) do + expect(body.name).to eq('Example Public Body FR') + end + end + + end + + context 'on failure' do + + it 'renders the form if creating the record was unsuccessful' do + post :update, :id => @body.id, + :public_body => { + :name => '', + :translations_attributes => {} + } + expect(response).to render_template('edit') + end + + it 'is rebuilt with the given params' do + post :update, :id => @body.id, + :public_body => { + :name => '', + :request_email => 'updated@localhost', + :translations_attributes => {} + } + expect(assigns(:public_body).request_email).to eq('updated@localhost') + end + + end + + context 'on failure for multiple locales' do + + before(:each) do + @params = { :id => @body.id, + :public_body => { :name => '', + :translations_attributes => { + 'es' => { :id => @body.translation_for(:es).id, + :locale => 'es', + :name => 'Mi Nuevo Body' } + } } } + end + + it 'is rebuilt with the default locale translation' do + post :update, @params + expect(assigns(:public_body).name(:en)).to eq('') + end + + it 'is rebuilt with the alternative locale translation' do + post :update, @params + + I18n.with_locale(:es) do + expect(assigns(:public_body).name).to eq('Mi Nuevo Body') + end end end diff --git a/spec/controllers/admin_public_body_headings_controller_spec.rb b/spec/controllers/admin_public_body_headings_controller_spec.rb index afbe0fa30..ccdfdecfb 100644 --- a/spec/controllers/admin_public_body_headings_controller_spec.rb +++ b/spec/controllers/admin_public_body_headings_controller_spec.rb @@ -2,161 +2,466 @@ require 'spec_helper' describe AdminPublicBodyHeadingsController do - context 'when showing the form for a new public body category' do - it 'should assign a new public body heading to the view' do + describe :new do + + it 'responds successfully' do get :new - assigns[:heading].should be_a(PublicBodyHeading) + expect(response).to be_success end - it 'renders the new template' do + it 'builds a new PublicBodyHeading' do get :new - expect(response).to render_template('new') + expect(assigns(:heading)).to be_new_record end + + it 'builds new translations for all locales' do + get :new + + translations = assigns(:heading).translations.map{ |t| t.locale.to_s }.sort + available = I18n.available_locales.map{ |l| l.to_s }.sort + + expect(translations).to eq(available) + end + + it 'renders the new template' do + get :new + expect(response).to render_template('new') + end + end - context 'when creating a public body heading' do - it "creates a new public body heading in one locale" do - n = PublicBodyHeading.count - post :create, { - :public_body_heading => { - :name => 'New Heading' - } - } - PublicBodyHeading.count.should == n + 1 - - heading = PublicBodyHeading.find_by_name("New Heading") - response.should redirect_to(admin_categories_path) - end + describe :create do - it 'creates a new public body heading with multiple locales' do - n = PublicBodyHeading.count - post :create, { - :public_body_heading => { - :name => 'New Heading', - :translated_versions => [{ :locale => "es", - :name => "Mi Nuevo Heading" }] - } - } - PublicBodyHeading.count.should == n + 1 - - heading = PublicBodyHeading.find_by_name("New Heading") - heading.translations.map {|t| t.locale.to_s}.sort.should == ["en", "es"] - I18n.with_locale(:en) do - heading.name.should == "New Heading" + context 'on success' do + + before(:each) do + PublicBodyHeading.destroy_all + @params = { :translations_attributes => { + 'en' => { :locale => 'en', + :name => 'New Heading' } + } } end - I18n.with_locale(:es) do - heading.name.should == "Mi Nuevo Heading" + + it 'creates a new heading in the default locale' do + expect { + post :create, :public_body_heading => @params + }.to change{ PublicBodyHeading.count }.from(0).to(1) end - response.should redirect_to(admin_categories_path) - end + it 'notifies the admin that the heading was created' do + post :create, :public_body_heading => @params + expect(flash[:notice]).to eq('Heading was successfully created.') + end + + it 'redirects to the categories index' do + post :create, :public_body_heading => @params + expect(response).to redirect_to(admin_categories_path) + end - it "renders the form if creating the record was unsuccessful" do - post :create, :public_body_heading => { :name => '' } - expect(response).to render_template('new') end - end + context 'on success for multiple locales' do - context 'when editing a public body heading' do - before do - @heading = FactoryGirl.create(:public_body_heading) - end + before(:each) do + PublicBodyHeading.destroy_all + @params = { :translations_attributes => { + 'en' => { :locale => 'en', + :name => 'New Heading' }, + 'es' => { :locale => 'es', + :name => 'Mi Nuevo Heading' } + } } + end - render_views + it 'saves the heading' do + expect { + post :create, :public_body_heading => @params + }.to change{ PublicBodyHeading.count }.from(0).to(1) + end - it "finds the requested heading" do - get :edit, :id => @heading.id - expect(assigns[:heading]).to eq(@heading) - end + it 'saves the default locale translation' do + post :create, :public_body_heading => @params - it "renders the edit template" do - get :edit, :id => @heading.id - expect(assigns[:heading]).to render_template('edit') - end - end + heading = PublicBodyHeading.find_by_name('New Heading') + + I18n.with_locale(:en) do + expect(heading.name).to eq('New Heading') + end + end + + it 'saves the alternative locale translation' do + post :create, :public_body_heading => @params + + heading = PublicBodyHeading.find_by_name('New Heading') + + I18n.with_locale(:es) do + expect(heading.name).to eq('Mi Nuevo Heading') + end + end - context 'when updating a public body heading' do - before do - @heading = FactoryGirl.create(:public_body_heading) - @name = @heading.name end - it "saves edits to a public body heading" do - post :update, { :id => @heading.id, - :public_body_heading => { :name => "Renamed" } } - request.flash[:notice].should include('successful') - found_heading = PublicBodyHeading.find(@heading.id) - found_heading.name.should == "Renamed" + context 'on failure' do + + it 'renders the form if creating the record was unsuccessful' do + post :create, :public_body_heading => { :name => '' } + expect(response).to render_template('new') + end + + it 'is rebuilt with the given params' do + post :create, :public_body_heading => { :name => 'Need a description' } + expect(assigns(:heading).name).to eq('Need a description') + end + end - it "saves edits to a public body heading in another locale" do - I18n.with_locale(:es) do - post :update, { - :id => @heading.id, - :public_body_heading => { - :name => @name, - :translated_versions => { - @heading.id => {:locale => "es", - :name => "Renamed"} - } - } - } - request.flash[:notice].should include('successful') + context 'on failure for multiple locales' do + + before(:each) do + @params = { :translations_attributes => { + 'en' => { :locale => 'en', + :name => 'Need a description' }, + 'es' => { :locale => 'es', + :name => 'Mi Nuevo Heading' } + } } + end + + it 'is rebuilt with the default locale translation' do + post :create, :public_body_heading => @params + expect(assigns(:heading).name).to eq('Need a description') end - heading = PublicBodyHeading.find(@heading.id) - I18n.with_locale(:es) do - heading.name.should == "Renamed" + it 'is rebuilt with the alternative locale translation' do + post :create, :public_body_heading => @params + + I18n.with_locale(:es) do + expect(assigns(:heading).name).to eq('Mi Nuevo Heading') + end end - I18n.with_locale(:en) do - heading.name.should == @name + + end + + end + + describe :edit do + + before do + @heading = FactoryGirl.create(:public_body_heading) + I18n.with_locale('es') do + @heading.name = 'Los heading' + @heading.save! end end - it "redirects to the edit page after a successful update" do - post :update, { :id => @heading.id, - :public_body_heading => { :name => "Renamed" } } + it 'responds successfully' do + get :edit, :id => @heading.id + expect(response).to be_success + end - expect(response).to redirect_to(edit_admin_heading_path(@heading)) + it 'finds the requested heading' do + get :edit, :id => @heading.id + expect(assigns[:heading]).to eq(@heading) end - it "re-renders the edit form after an unsuccessful update" do - post :update, { :id => @heading.id, - :public_body_heading => { :name => '' } } + it 'builds new translations if the body does not already have a translation in the specified locale' do + get :edit, :id => @heading.id + expect(assigns[:heading].translations.map(&:locale)).to include(:fr) + end + it 'renders the edit template' do + get :edit, :id => @heading.id expect(response).to render_template('edit') end end - context 'when destroying a public body heading' do + describe :update do + + before do + @heading = FactoryGirl.create(:public_body_heading) + I18n.with_locale('es') do + @heading.name = 'Los heading' + @heading.save! + end + @params = { :translations_attributes => { + 'en' => { :id => @heading.translation_for(:en).id, + :locale => 'en', + :name => @heading.name(:en) }, + 'es' => { :id => @heading.translation_for(:es).id, + :locale => 'es', + :title => @heading.name(:es) } + } } + end + + it 'finds the heading to update' do + post :update, :id => @heading.id, + :public_body_category => @params + expect(assigns(:heading)).to eq(@heading) + end + + context 'on success' do + + before(:each) do + @params = { :id => @heading.id, + :public_body_heading => { + :translations_attributes => { + 'en' => { :id => @heading.translation_for(:en).id, + :name => 'Renamed' } + } + } + } + end + + it 'saves edits to a public body heading' do + post :update, @params + heading = PublicBodyHeading.find(@heading.id) + expect(heading.name).to eq('Renamed') + end + + it 'notifies the admin that the heading was updated' do + post :update, @params + expect(flash[:notice]).to eq('Heading was successfully updated.') + end + + it 'redirects to the heading edit page' do + post :update, @params + expect(response).to redirect_to(edit_admin_heading_path(@heading)) + end + + end + + context 'on success for multiple locales' do + + it 'saves edits to a public body heading in another locale' do + @heading.name(:es).should == 'Los heading' + post :update, :id => @heading.id, + :public_body_heading => { + :translations_attributes => { + 'en' => { :id => @heading.translation_for(:en).id, + :locale => 'en', + :name => @heading.name(:en) }, + 'es' => { :id => @heading.translation_for(:es).id, + :locale => 'es', + :name => 'Renamed' } + } + } + + heading = PublicBodyHeading.find(@heading.id) + expect(heading.name(:es)).to eq('Renamed') + expect(heading.name(:en)).to eq(@heading.name(:en)) + end + + it 'adds a new translation' do + @heading.translation_for(:es).destroy + @heading.reload + + put :update, { + :id => @heading.id, + :public_body_heading => { + :translations_attributes => { + 'en' => { :id => @heading.translation_for(:en).id, + :locale => 'en', + :name => @heading.name(:en) }, + 'es' => { :locale => "es", + :name => "Example Public Body Heading ES" } + } + } + } + + request.flash[:notice].should include('successful') + + heading = PublicBodyHeading.find(@heading.id) + + I18n.with_locale(:es) do + expect(heading.name).to eq('Example Public Body Heading ES') + end + end + + it 'adds new translations' do + @heading.translation_for(:es).destroy + @heading.reload + + post :update, { + :id => @heading.id, + :public_body_heading => { + :translations_attributes => { + 'en' => { :id => @heading.translation_for(:en).id, + :locale => 'en', + :name => @heading.name(:en) }, + 'es' => { :locale => "es", + :name => "Example Public Body Heading ES" }, + 'fr' => { :locale => "fr", + :name => "Example Public Body Heading FR" } + } + } + } + + request.flash[:notice].should include('successful') + + heading = PublicBodyHeading.find(@heading.id) + + I18n.with_locale(:es) do + expect(heading.name).to eq('Example Public Body Heading ES') + end + I18n.with_locale(:fr) do + expect(heading.name).to eq('Example Public Body Heading FR') + end + end + + it 'updates an existing translation and adds a third translation' do + post :update, { + :id => @heading.id, + :public_body_heading => { + :translations_attributes => { + 'en' => { :id => @heading.translation_for(:en).id, + :locale => 'en', + :name => @heading.name(:en) }, + # Update existing translation + 'es' => { :id => @heading.translation_for(:es).id, + :locale => "es", + :name => "Renamed Example Public Body Heading ES" }, + # Add new translation + 'fr' => { :locale => "fr", + :name => "Example Public Body Heading FR" } + } + } + } + + request.flash[:notice].should include('successful') + + heading = PublicBodyHeading.find(@heading.id) + + I18n.with_locale(:es) do + expect(heading.name).to eq('Renamed Example Public Body Heading ES') + end + I18n.with_locale(:fr) do + expect(heading.name).to eq('Example Public Body Heading FR') + end + end + + it "redirects to the edit page after a successful update" do + post :update, :id => @heading.id, + :public_body_heading => { + :translations_attributes => { + 'en' => { :id => @heading.translation_for(:en).id, + :locale => 'en', + :name => @heading.name(:en) } + } } + + expect(response).to redirect_to(edit_admin_heading_path(@heading)) + end + + end + + context 'on failure' do + + it 'renders the form if creating the record was unsuccessful' do + post :update, :id => @heading.id, + :public_body_heading => { + :translations_attributes => { + 'en' => { :id => @heading.translation_for(:en).id, + :locale => 'en', + :name => '' } + } } + expect(response).to render_template('edit') + end + + it 'is rebuilt with the given params' do + post :update, :id => @heading.id, + :public_body_heading => { + :translations_attributes => { + 'en' => { :id => @heading.translation_for(:en).id, + :locale => 'en', + :name => 'Need a description' } + } } + expect(assigns(:heading).name).to eq('Need a description') + end + + end + + context 'on failure for multiple locales' do + + before(:each) do + @params = { :translations_attributes => { + 'en' => { :id => @heading.translation_for(:en).id, + :locale => 'en', + :name => '' }, + 'es' => { :id => @heading.translation_for(:es).id, + :locale => 'es', + :name => 'Mi Nuevo Heading' } + } } + end + + it 'is rebuilt with the default locale translation' do + post :update, :id => @heading.id, + :public_body_heading => @params + expect(assigns(:heading).name(:en)).to eq('') + end + + it 'is rebuilt with the alternative locale translation' do + post :update, :id => @heading.id, + :public_body_heading => @params + + I18n.with_locale(:es) do + expect(assigns(:heading).name).to eq('Mi Nuevo Heading') + end + end + + end + + end + + describe :destroy do + + it 'uses the current locale by default' do + heading = FactoryGirl.create(:public_body_heading) + post :destroy, :id => heading.id + expect(assigns(:locale)).to eq(I18n.locale.to_s) + end - before do - @heading = FactoryGirl.create(:public_body_heading) + it 'sets the locale if the show_locale param is passed' do + heading = FactoryGirl.create(:public_body_heading) + post :destroy, :id => heading.id, :show_locale => 'es' + expect(assigns(:locale)).to eq('es') end - it "destroys a public body heading that has associated categories" do + it 'destroys the public body heading' do + PublicBodyHeading.destroy_all + + heading = FactoryGirl.create(:public_body_heading) + + expect{ + post :destroy, :id => heading.id + }.to change{ PublicBodyHeading.count }.from(1).to(0) + end + + it 'destroys a heading that has associated categories' do + PublicBodyHeading.destroy_all + PublicBodyCategory.destroy_all + + heading = FactoryGirl.create(:public_body_heading) category = FactoryGirl.create(:public_body_category) link = FactoryGirl.create(:public_body_category_link, :public_body_category => category, - :public_body_heading => @heading, + :public_body_heading => heading, :category_display_order => 0) - n = PublicBodyHeading.count - n_links = PublicBodyCategoryLink.count - post :destroy, { :id => @heading.id } - response.should redirect_to(admin_categories_path) - PublicBodyHeading.count.should == n - 1 - PublicBodyCategoryLink.count.should == n_links - 1 + expect{ + post :destroy, :id => heading.id + }.to change{ PublicBodyHeading.count }.from(1).to(0) + end + + it 'notifies the admin that the heading was destroyed' do + heading = FactoryGirl.create(:public_body_heading) + post :destroy, :id => heading.id + expect(flash[:notice]).to eq('Heading was successfully destroyed.') end - it "destroys an empty public body heading" do - n = PublicBodyHeading.count - post :destroy, { :id => @heading.id } - response.should redirect_to(admin_categories_path) - PublicBodyHeading.count.should == n - 1 + it 'redirects to the categories index' do + heading = FactoryGirl.create(:public_body_heading) + post :destroy, :id => heading.id + expect(response).to redirect_to(admin_categories_path) end + end context 'when reordering public body headings' do diff --git a/spec/integration/admin_public_body_category_edit_spec.rb b/spec/integration/admin_public_body_category_edit_spec.rb new file mode 100644 index 000000000..043524189 --- /dev/null +++ b/spec/integration/admin_public_body_category_edit_spec.rb @@ -0,0 +1,59 @@ +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') +require File.expand_path(File.dirname(__FILE__) + '/alaveteli_dsl') + +describe 'Editing a Public Body Category' do + before do + AlaveteliConfiguration.stub!(:skip_admin_auth).and_return(false) + + confirm(:admin_user) + @admin = login(:admin_user) + @category = FactoryGirl.create(:public_body_category) + end + + it 'can edit the default locale' do + @admin.visit edit_admin_category_path(@category) + @admin.fill_in 'public_body_category_title__en', :with => 'New Category EN' + @admin.click_button 'Save' + + @category.reload + expect(@category.title).to eq('New Category EN') + end + + it 'can add a translation for a single locale' do + expect(@category.find_translation_by_locale('fr')).to be_nil + + @admin.visit edit_admin_category_path(@category) + @admin.fill_in 'public_body_category_translations_attributes_fr_title__fr', :with => 'New Category FR' + @admin.fill_in 'public_body_category_translations_attributes_fr_description__fr', :with => 'FR Description' + @admin.click_button 'Save' + + @category.reload + I18n.with_locale(:fr) do + expect(@category.title).to eq('New Category FR') + end + end + + it 'can add a translation for multiple locales' do + # Add FR translation + @admin.visit edit_admin_category_path(@category) + @admin.fill_in 'public_body_category_translations_attributes_fr_title__fr', :with => 'New Category FR' + @admin.fill_in 'public_body_category_translations_attributes_fr_description__fr', :with => 'FR Description' + @admin.click_button 'Save' + + # Add ES translation + @admin.visit edit_admin_category_path(@category) + @admin.fill_in 'public_body_category_translations_attributes_es_title__es', :with => 'New Category ES' + @admin.fill_in 'public_body_category_translations_attributes_es_description__es', :with => 'ES Description' + @admin.click_button 'Save' + + @category.reload + I18n.with_locale(:fr) do + expect(@category.title).to eq('New Category FR') + end + + I18n.with_locale(:es) do + expect(@category.title).to eq('New Category ES') + end + end + +end diff --git a/spec/integration/admin_public_body_heading_edit_spec.rb b/spec/integration/admin_public_body_heading_edit_spec.rb new file mode 100644 index 000000000..6c7a5a74b --- /dev/null +++ b/spec/integration/admin_public_body_heading_edit_spec.rb @@ -0,0 +1,58 @@ +require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') +require File.expand_path(File.dirname(__FILE__) + '/alaveteli_dsl') + +describe 'Editing a Public Body Heading' do + before do + AlaveteliConfiguration.stub!(:skip_admin_auth).and_return(false) + + confirm(:admin_user) + @admin = login(:admin_user) + @heading = FactoryGirl.create(:public_body_heading) + end + + it 'can edit the default locale' do + @admin.visit edit_admin_heading_path(@heading) + @admin.fill_in 'public_body_heading_name__en', :with => 'New Heading EN' + @admin.click_button 'Save' + + @heading.reload + expect(@heading.name).to eq('New Heading EN') + end + + it 'can add a translation for a single locale' do + expect(@heading.find_translation_by_locale('fr')).to be_nil + + @admin.visit edit_admin_heading_path(@heading) + @admin.fill_in 'public_body_heading_translations_attributes_fr_name__fr', :with => 'New Heading FR' + @admin.click_button 'Save' + + @heading.reload + I18n.with_locale(:fr) do + expect(@heading.name).to eq('New Heading FR') + end + end + + it 'can add a translation for multiple locales' do + # Add FR translation + expect(@heading.find_translation_by_locale('fr')).to be_nil + @admin.visit edit_admin_heading_path(@heading) + @admin.fill_in 'public_body_heading_translations_attributes_fr_name__fr', :with => 'New Heading FR' + @admin.click_button 'Save' + + # Add ES translation + expect(@heading.find_translation_by_locale('es')).to be_nil + @admin.visit edit_admin_heading_path(@heading) + @admin.fill_in 'public_body_heading_translations_attributes_es_name__es', :with => 'New Heading ES' + @admin.click_button 'Save' + + @heading.reload + I18n.with_locale(:fr) do + expect(@heading.name).to eq('New Heading FR') + end + + I18n.with_locale(:es) do + expect(@heading.name).to eq('New Heading ES') + end + end + +end diff --git a/spec/models/public_body_category_spec.rb b/spec/models/public_body_category_spec.rb index c16c9b8a1..297bd096a 100644 --- a/spec/models/public_body_category_spec.rb +++ b/spec/models/public_body_category_spec.rb @@ -34,5 +34,145 @@ describe PublicBodyCategory do category.should_not be_valid category.errors[:description].should == ["Description can't be blank"] end + + it 'validates the translations' do + category = FactoryGirl.build(:public_body_category) + translation = category.translations.build + expect(category).to_not be_valid + end + + it 'uses the base model validation for the default locale' do + category = PublicBodyCategory.new + translation = category.translations.build(:locale => 'en', + :description => 'No title') + category.valid? + translation.valid? + + expect(category).to have(1).error_on(:title) + expect(translation).to have(0).errors_on(:title) + end + end + + describe :save do + + it 'saves translations' do + category = FactoryGirl.build(:public_body_category) + category.translations_attributes = { :es => { :locale => 'es', + :title => 'El Category', + :description => 'Spanish description' } } + + category.save + expect(PublicBodyCategory.find(category.id).translations.size).to eq(2) + end + + end + + describe :translations_attributes= do + + context 'translation_attrs is a Hash' do + + it 'does not persist translations' do + category = FactoryGirl.create(:public_body_category) + category.translations_attributes = { :es => { :locale => 'es', + :title => 'El Category', + :description => 'Spanish description' } } + + expect(PublicBodyCategory.find(category.id).translations.size).to eq(1) + end + + it 'creates a new translation' do + category = FactoryGirl.create(:public_body_category) + category.translations_attributes = { :es => { :locale => 'es', + :title => 'El Category', + :description => 'Spanish description' } } + category.save + category.reload + expect(category.title(:es)).to eq('El Category') + end + + it 'updates an existing translation' do + category = FactoryGirl.create(:public_body_category) + category.translations_attributes = { 'es' => { :locale => 'es', + :title => 'Name', + :description => 'Desc' } } + category.save + + category.translations_attributes = { 'es' => { :id => category.translation_for(:es).id, + :locale => 'es', + :title => 'Renamed', + :description => 'Desc' } } + category.save + expect(category.title(:es)).to eq('Renamed') + end + + it 'updates an existing translation and creates a new translation' do + category = FactoryGirl.create(:public_body_category) + category.translations.create(:locale => 'es', + :title => 'Los Category', + :description => 'ES Description') + + expect(category.translations.size).to eq(2) + + category.translations_attributes = { + 'es' => { :id => category.translation_for(:es).id, + :locale => 'es', + :title => 'Renamed' }, + 'fr' => { :locale => 'fr', + :title => 'Le Category' } + } + + expect(category.translations.size).to eq(3) + I18n.with_locale(:es) { expect(category.title).to eq('Renamed') } + I18n.with_locale(:fr) { expect(category.title).to eq('Le Category') } + end + + it 'skips empty translations' do + category = FactoryGirl.create(:public_body_category) + category.translations.create(:locale => 'es', + :title => 'Los Category', + :description => 'ES Description') + + expect(category.translations.size).to eq(2) + + category.translations_attributes = { + 'es' => { :id => category.translation_for(:es).id, + :locale => 'es', + :title => 'Renamed' }, + 'fr' => { :locale => 'fr' } + } + + expect(category.translations.size).to eq(2) + end + + end + end + +end + +describe PublicBodyCategory::Translation do + + it 'requires a locale' do + translation = PublicBodyCategory::Translation.new + translation.valid? + expect(translation.errors[:locale]).to eq(["can't be blank"]) + end + + it 'is valid if no required attributes are assigned' do + translation = PublicBodyCategory::Translation.new(:locale => I18n.default_locale) + expect(translation).to be_valid + end + + it 'requires a title if another required attribute is assigned' do + translation = PublicBodyCategory::Translation.new(:description => 'spec') + translation.valid? + expect(translation.errors[:title]).to eq(["Title can't be blank"]) + end + + it 'requires a description if another required attribute is assigned' do + translation = PublicBodyCategory::Translation.new(:title => 'spec') + translation.valid? + expect(translation.errors[:description]).to eq(["Description can't be blank"]) + end + end diff --git a/spec/models/public_body_heading_spec.rb b/spec/models/public_body_heading_spec.rb index 620f7da9c..be3e7c7d2 100644 --- a/spec/models/public_body_heading_spec.rb +++ b/spec/models/public_body_heading_spec.rb @@ -30,6 +30,13 @@ describe PublicBodyHeading do heading.valid? heading.display_order.should == PublicBodyHeading.next_display_order end + + it 'validates the translations' do + heading = FactoryGirl.build(:public_body_heading) + translation = heading.translations.build + expect(heading).to_not be_valid + end + end context 'when setting a display order' do @@ -43,4 +50,105 @@ describe PublicBodyHeading do PublicBodyHeading.next_display_order.should == 1 end end + + describe :save do + + it 'saves translations' do + heading = FactoryGirl.build(:public_body_heading) + heading.translations_attributes = { :es => { :locale => 'es', + :name => 'El Heading' } } + + heading.save + expect(PublicBodyHeading.find(heading.id).translations.size).to eq(2) + end + + end + + describe :translations_attributes= do + + context 'translation_attrs is a Hash' do + + it 'does not persist translations' do + heading = FactoryGirl.create(:public_body_heading) + heading.translations_attributes = { :es => { :locale => 'es', + :name => 'El Heading' } } + + expect(PublicBodyHeading.find(heading.id).translations.size).to eq(1) + end + + it 'creates a new translation' do + heading = FactoryGirl.create(:public_body_heading) + heading.translations_attributes = { :es => { :locale => 'es', + :name => 'El Heading' } } + heading.save + heading.reload + expect(heading.name(:es)).to eq('El Heading') + end + + it 'updates an existing translation' do + heading = FactoryGirl.create(:public_body_heading) + heading.translations_attributes = { 'es' => { :locale => 'es', + :name => 'Name' } } + heading.save + + heading.translations_attributes = { 'es' => { :id => heading.translation_for(:es).id, + :locale => 'es', + :name => 'Renamed' } } + heading.save + expect(heading.name(:es)).to eq('Renamed') + end + + it 'updates an existing translation and creates a new translation' do + heading = FactoryGirl.create(:public_body_heading) + heading.translations.create(:locale => 'es', + :name => 'Los Heading') + + expect(heading.translations.size).to eq(2) + + heading.translations_attributes = { + 'es' => { :id => heading.translation_for(:es).id, + :locale => 'es', + :name => 'Renamed' }, + 'fr' => { :locale => 'fr', + :name => 'Le Heading' } + } + + expect(heading.translations.size).to eq(3) + I18n.with_locale(:es) { expect(heading.name).to eq('Renamed') } + I18n.with_locale(:fr) { expect(heading.name).to eq('Le Heading') } + end + + it 'skips empty translations' do + heading = FactoryGirl.create(:public_body_heading) + heading.translations.create(:locale => 'es', + :name => 'Los Heading') + + expect(heading.translations.size).to eq(2) + + heading.translations_attributes = { + 'es' => { :id => heading.translation_for(:es).id, + :locale => 'es', + :name => 'Renamed' }, + 'fr' => { :locale => 'fr' } + } + + expect(heading.translations.size).to eq(2) + end + end + end +end + +describe PublicBodyHeading::Translation do + + it 'requires a locale' do + translation = PublicBodyHeading::Translation.new + translation.valid? + expect(translation.errors[:locale]).to eq(["can't be blank"]) + end + + it 'is valid if all required attributes are assigned' do + translation = PublicBodyHeading::Translation.new(:locale => I18n.default_locale) + expect(translation).to be_valid + end + end diff --git a/spec/models/public_body_spec.rb b/spec/models/public_body_spec.rb index d91021315..7b55efda1 100644 --- a/spec/models/public_body_spec.rb +++ b/spec/models/public_body_spec.rb @@ -30,106 +30,81 @@ 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 - + describe :translations_attributes= do + + context 'translation_attrs is a Hash' do + + it 'does not persist translations' do + body = FactoryGirl.create(:public_body) + body.translations_attributes = { :es => { :locale => 'es', + :name => 'El Body' } } + + expect(PublicBody.find(body.id).translations.size).to eq(1) + end + + it 'creates a new translation' do + body = FactoryGirl.create(:public_body) + body.translations_attributes = { :es => { :locale => 'es', + :name => 'El Body' } } + body.save + body.reload + expect(body.name(:es)).to eq('El Body') + end + + it 'updates an existing translation' do + body = FactoryGirl.create(:public_body) + body.translations_attributes = { 'es' => { :locale => 'es', + :name => 'El Body' } } + body.save + + body.translations_attributes = { 'es' => { :id => body.translation_for(:es).id, + :locale => 'es', + :name => 'Renamed' } } + body.save + expect(body.name(:es)).to eq('Renamed') + end + + it 'updates an existing translation and creates a new translation' do + body = FactoryGirl.create(:public_body) + body.translations.create(:locale => 'es', + :name => 'El Body') + + expect(body.translations.size).to eq(2) + + body.translations_attributes = { + 'es' => { :id => body.translation_for(:es).id, + :locale => 'es', + :name => 'Renamed' }, + 'fr' => { :locale => 'fr', + :name => 'Le Body' } + } + + 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 Body') } + end + + it 'skips empty translations' do + body = FactoryGirl.create(:public_body) + body.translations.create(:locale => 'es', + :name => 'El Body') + + expect(body.translations.size).to eq(2) + + body.translations_attributes = { + 'es' => { :id => body.translation_for(:es).id, + :locale => 'es', + :name => 'Renamed' }, + 'fr' => { :locale => 'fr' } + } + + expect(body.translations.size).to eq(2) + end + end + end end + describe PublicBody, " using tags" do before do @public_body = PublicBody.new(:name => 'Aardvark Monitoring Service', @@ -1264,3 +1239,17 @@ describe PublicBody do end +describe PublicBody::Translation do + + it 'requires a locale' do + translation = PublicBody::Translation.new + translation.valid? + expect(translation.errors[:locale]).to eq(["can't be blank"]) + end + + it 'is valid if all required attributes are assigned' do + translation = PublicBody::Translation.new(:locale => I18n.default_locale) + expect(translation).to be_valid + end + +end |