diff --git a/app/controllers/admin/poll/questions_controller.rb b/app/controllers/admin/poll/questions_controller.rb index 399c72788..913e6824a 100644 --- a/app/controllers/admin/poll/questions_controller.rb +++ b/app/controllers/admin/poll/questions_controller.rb @@ -1,5 +1,6 @@ class Admin::Poll::QuestionsController < Admin::Poll::BaseController include CommentableActions + include Translatable load_and_authorize_resource :poll load_and_authorize_resource :question, class: 'Poll::Question' @@ -55,11 +56,15 @@ class Admin::Poll::QuestionsController < Admin::Poll::BaseController private def question_params - params.require(:poll_question).permit(:poll_id, :title, :question, :proposal_id) + attributes = [:poll_id, :title, :question, :proposal_id] + params.require(:poll_question).permit(*attributes, *translation_params(Poll::Question)) end def search_params params.permit(:poll_id, :search) end + def resource + @poll_question ||= Poll::Question.find(params[:id]) + end end diff --git a/app/models/poll/question.rb b/app/models/poll/question.rb index 6be729757..bc20ce166 100644 --- a/app/models/poll/question.rb +++ b/app/models/poll/question.rb @@ -5,6 +5,9 @@ class Poll::Question < ActiveRecord::Base acts_as_paranoid column: :hidden_at include ActsAsParanoidAliases + translates :title, touch: true + globalize_accessors + belongs_to :poll belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id' diff --git a/app/views/admin/poll/questions/_form.html.erb b/app/views/admin/poll/questions/_form.html.erb index 5ffdc6573..0f9065262 100644 --- a/app/views/admin/poll/questions/_form.html.erb +++ b/app/views/admin/poll/questions/_form.html.erb @@ -1,4 +1,6 @@ -<%= form_for(@question, url: form_url) do |f| %> +<%= render "admin/shared/globalize_locales", resource: @question %> + +<%= translatable_form_for(@question, url: form_url) do |f| %> <%= render 'shared/errors', resource: @question %> @@ -6,13 +8,14 @@
#{Faker::Lorem.paragraphs.join('
')}
" Poll::Question::Answer.create!(question: question, title: answer.capitalize, @@ -194,6 +202,13 @@ section "Creating Poll Questions from Proposals" do description: Faker::ChuckNorris.fact) end question.copy_attributes_from_proposal(proposal) + title = question.title + I18n.available_locales.map do |locale| + neutral_locale = locale.to_s.downcase.underscore.to_sym + Globalize.with_locale(neutral_locale) do + question.title = "#{title} (#{locale})" + end + end question.save! end end @@ -209,6 +224,13 @@ section "Creating Successful Proposals" do description: Faker::ChuckNorris.fact) end question.copy_attributes_from_proposal(proposal) + title = question.title + I18n.available_locales.map do |locale| + neutral_locale = locale.to_s.downcase.underscore.to_sym + Globalize.with_locale(neutral_locale) do + question.title = "#{title} (#{locale})" + end + end question.save! end end diff --git a/db/migrate/20180731173147_add_poll_question_translations.rb b/db/migrate/20180731173147_add_poll_question_translations.rb new file mode 100644 index 000000000..a167ea00a --- /dev/null +++ b/db/migrate/20180731173147_add_poll_question_translations.rb @@ -0,0 +1,13 @@ +class AddPollQuestionTranslations < ActiveRecord::Migration + + def self.up + Poll::Question.create_translation_table!( + title: :string + ) + end + + def self.down + Poll::Question.drop_translation_table! + end + +end diff --git a/db/schema.rb b/db/schema.rb index 803be6b2f..88d4c73d9 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -847,6 +847,17 @@ ActiveRecord::Schema.define(version: 20180813141443) do add_index "poll_question_answers", ["question_id"], name: "index_poll_question_answers_on_question_id", using: :btree + create_table "poll_question_translations", force: :cascade do |t| + t.integer "poll_question_id", null: false + t.string "locale", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "title" + end + + add_index "poll_question_translations", ["locale"], name: "index_poll_question_translations_on_locale", using: :btree + add_index "poll_question_translations", ["poll_question_id"], name: "index_poll_question_translations_on_poll_question_id", using: :btree + create_table "poll_questions", force: :cascade do |t| t.integer "proposal_id" t.integer "poll_id" diff --git a/spec/features/admin/poll/questions_spec.rb b/spec/features/admin/poll/questions_spec.rb index d499869b9..2b3762c53 100644 --- a/spec/features/admin/poll/questions_spec.rb +++ b/spec/features/admin/poll/questions_spec.rb @@ -41,7 +41,7 @@ feature 'Admin poll questions' do click_link "Create question" select 'Movies', from: 'poll_question_poll_id' - fill_in 'poll_question_title', with: title + fill_in 'poll_question_title_en', with: title click_button 'Save' @@ -56,7 +56,7 @@ feature 'Admin poll questions' do click_link "Create question" expect(page).to have_current_path(new_admin_question_path, ignore_query: true) - expect(page).to have_field('poll_question_title', with: proposal.title) + expect(page).to have_field('poll_question_title_en', with: proposal.title) select 'Proposals', from: 'poll_question_poll_id' @@ -79,7 +79,7 @@ feature 'Admin poll questions' do old_title = question1.title new_title = "Potatoes are great and everyone should have one" - fill_in 'poll_question_title', with: new_title + fill_in 'poll_question_title_en', with: new_title click_button 'Save' diff --git a/spec/features/translations/poll_questions_spec.rb b/spec/features/translations/poll_questions_spec.rb new file mode 100644 index 000000000..0acd8cf1b --- /dev/null +++ b/spec/features/translations/poll_questions_spec.rb @@ -0,0 +1,147 @@ +# coding: utf-8 +require 'rails_helper' + +feature "Translations" do + + context "Polls" do + + let(:poll) { create(:poll, name_en: "Name in English", + name_es: "Nombre en Español", + summary_en: "Summary in English", + summary_es: "Resumen en Español", + description_en: "Description in English", + description_es: "Descripción en Español") } + + background do + admin = create(:administrator) + login_as(admin.user) + end + + context "Questions" do + + let(:question) { create(:poll_question, poll: poll, + title_en: "Question in English", + title_es: "Pregunta en Español") } + + before do + @edit_question_url = edit_admin_question_path(question) + end + + context "Poll select box" do + + scenario "translates the poll name in options", :js do + visit @edit_question_url + + expect(page).to have_select('poll_question_poll_id', options: [poll.name_en]) + + select('Español', from: 'locale-switcher') + + expect(page).to have_select('poll_question_poll_id', options: [poll.name_es]) + end + + scenario "uses fallback if name is not translated to current locale", :js do + visit @edit_question_url + + expect(page).to have_select('poll_question_poll_id', options: [poll.name_en]) + + select('Français', from: 'locale-switcher') + + expect(page).to have_select('poll_question_poll_id', options: [poll.name_es]) + end + end + + scenario "Add a translation", :js do + visit @edit_question_url + + select "Français", from: "translation_locale" + fill_in 'poll_question_title_fr', with: 'Question en Français' + + click_button 'Save' + expect(page).to have_content "Changes saved" + + visit @edit_question_url + expect(page).to have_field('poll_question_title_en', with: 'Question in English') + + click_link "Español" + expect(page).to have_field('poll_question_title_es', with: 'Pregunta en Español') + + click_link "Français" + expect(page).to have_field('poll_question_title_fr', with: 'Question en Français') + end + + scenario "Update a translation", :js do + visit @edit_question_url + + click_link "Español" + fill_in 'poll_question_title_es', with: 'Pregunta correcta en Español' + + click_button 'Save' + expect(page).to have_content "Changes saved" + + visit poll_path(poll) + expect(page).to have_content("Question in English") + + select('Español', from: 'locale-switcher') + expect(page).to have_content("Pregunta correcta en Español") + end + + scenario "Remove a translation", :js do + visit @edit_question_url + + click_link "Español" + click_link "Remove language" + + expect(page).not_to have_link "Español" + + click_button "Save" + visit @edit_question_url + expect(page).not_to have_link "Español" + end + + context "Globalize javascript interface" do + + scenario "Highlight current locale", :js do + visit @edit_question_url + + expect(find("a.js-globalize-locale-link.is-active")).to have_content "English" + + select('Español', from: 'locale-switcher') + + expect(find("a.js-globalize-locale-link.is-active")).to have_content "Español" + end + + scenario "Highlight selected locale", :js do + visit @edit_question_url + + expect(find("a.js-globalize-locale-link.is-active")).to have_content "English" + + click_link "Español" + + expect(find("a.js-globalize-locale-link.is-active")).to have_content "Español" + end + + scenario "Show selected locale form", :js do + visit @edit_question_url + + expect(page).to have_field('poll_question_title_en', with: 'Question in English') + + click_link "Español" + + expect(page).to have_field('poll_question_title_es', with: 'Pregunta en Español') + end + + scenario "Select a locale and add it to the poll form", :js do + visit @edit_question_url + + select "Français", from: "translation_locale" + + expect(page).to have_link "Français" + + click_link "Français" + + expect(page).to have_field('poll_question_title_fr') + end + end + end + end +end