From 9495208518cb0c4252e7f966a9aac9269bd294c7 Mon Sep 17 00:00:00 2001 From: Julian Herrero Date: Thu, 20 Sep 2018 17:07:43 +0200 Subject: [PATCH 01/11] Make polls translatable --- .../admin/poll/polls_controller.rb | 6 +- app/controllers/concerns/translatable.rb | 2 +- app/models/poll.rb | 5 + app/views/admin/poll/polls/_form.html.erb | 10 +- config/locales/en/admin.yml | 2 + config/locales/es/admin.yml | 2 + db/dev_seeds/polls.rb | 14 ++ .../20180730213824_add_poll_translations.rb | 15 ++ db/schema.rb | 13 ++ spec/features/admin/poll/polls_spec.rb | 8 +- spec/features/translations/polls_spec.rb | 131 ++++++++++++++++++ 11 files changed, 198 insertions(+), 10 deletions(-) create mode 100644 db/migrate/20180730213824_add_poll_translations.rb create mode 100644 spec/features/translations/polls_spec.rb diff --git a/app/controllers/admin/poll/polls_controller.rb b/app/controllers/admin/poll/polls_controller.rb index 7ed555275..e93a82d47 100644 --- a/app/controllers/admin/poll/polls_controller.rb +++ b/app/controllers/admin/poll/polls_controller.rb @@ -1,4 +1,5 @@ class Admin::Poll::PollsController < Admin::Poll::BaseController + include Translatable load_and_authorize_resource before_action :load_search, only: [:search_booths, :search_officers] @@ -63,7 +64,7 @@ class Admin::Poll::PollsController < Admin::Poll::BaseController attributes = [:name, :starts_at, :ends_at, :geozone_restricted, :summary, :description, :results_enabled, :stats_enabled, geozone_ids: [], image_attributes: image_attributes] - params.require(:poll).permit(*attributes) + params.require(:poll).permit(*attributes, *translation_params(Poll)) end def search_params @@ -74,4 +75,7 @@ class Admin::Poll::PollsController < Admin::Poll::BaseController @search = search_params[:search] end + def resource + @poll ||= Poll.find(params[:id]) + end end diff --git a/app/controllers/concerns/translatable.rb b/app/controllers/concerns/translatable.rb index aecf42fb4..29a85aa25 100644 --- a/app/controllers/concerns/translatable.rb +++ b/app/controllers/concerns/translatable.rb @@ -25,7 +25,7 @@ module Translatable end def enabled_translations - params.fetch(:enabled_translations) + params.fetch(:enabled_translations, {}) .select { |_, v| v == '1' } .keys end diff --git a/app/models/poll.rb b/app/models/poll.rb index bf5a5a0a8..14b102260 100644 --- a/app/models/poll.rb +++ b/app/models/poll.rb @@ -4,6 +4,11 @@ class Poll < ActiveRecord::Base include ActsAsParanoidAliases include Notifiable + translates :name, touch: true + translates :summary, touch: true + translates :description, touch: true + globalize_accessors + RECOUNT_DURATION = 1.week has_many :booth_assignments, class_name: "Poll::BoothAssignment" diff --git a/app/views/admin/poll/polls/_form.html.erb b/app/views/admin/poll/polls/_form.html.erb index 8a91d614a..1f7520547 100644 --- a/app/views/admin/poll/polls/_form.html.erb +++ b/app/views/admin/poll/polls/_form.html.erb @@ -1,6 +1,8 @@ -<%= form_for [:admin, @poll] do |f| %> +<%= render "admin/shared/globalize_locales", resource: @poll %> + +<%= translatable_form_for [:admin, @poll] do |f| %>
- <%= f.text_field :name %> + <%= f.translatable_text_field :name %>
@@ -18,11 +20,11 @@
- <%=f.text_area :summary, rows: 4%> + <%=f.translatable_text_area :summary, rows: 4%>
- <%=f.text_area :description, rows: 8%> + <%=f.translatable_text_area :description, rows: 8%>
diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 682a87dee..b85557664 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -1084,8 +1084,10 @@ en: search_results: "Search results" no_search_results: "No results found." actions: Actions + name: Name title: Title description: Description + summary: Summary image: Image show_image: Show image moderated_content: "Check the content moderated by the moderators, and confirm if the moderation has been done correctly." diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index eabfbc536..93569cdd6 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -1085,8 +1085,10 @@ es: search_results: "Resultados de la búsqueda" no_search_results: "No se han encontrado resultados." actions: Acciones + name: Nombre title: Título description: Descripción + summary: Resumen image: Imagen show_image: Mostrar imagen moderated_content: "Revisa el contenido moderado por los moderadores, y confirma si la moderación se ha realizado correctamente." diff --git a/db/dev_seeds/polls.rb b/db/dev_seeds/polls.rb index 188efe4fd..212a27c3c 100644 --- a/db/dev_seeds/polls.rb +++ b/db/dev_seeds/polls.rb @@ -28,6 +28,20 @@ section "Creating polls" do ends_at: 1.month.ago, results_enabled: true, stats_enabled: true) + + Poll.find_each do |poll| + name = poll.name + I18n.available_locales.map do |locale| + neutral_locale = locale.to_s.downcase.underscore.to_sym + Globalize.with_locale(neutral_locale) do + poll.name = "#{name} (#{locale})" + poll.summary = "Summary for locale #{locale}" + poll.description = "Description for locale #{locale}" + end + end + poll.save! + end + end section "Creating Poll Questions & Answers" do diff --git a/db/migrate/20180730213824_add_poll_translations.rb b/db/migrate/20180730213824_add_poll_translations.rb new file mode 100644 index 000000000..4a4fa72a4 --- /dev/null +++ b/db/migrate/20180730213824_add_poll_translations.rb @@ -0,0 +1,15 @@ +class AddPollTranslations < ActiveRecord::Migration + + def self.up + Poll.create_translation_table!( + name: :string, + summary: :text, + description: :text + ) + end + + def self.down + Poll.drop_translation_table! + end + +end diff --git a/db/schema.rb b/db/schema.rb index b6370693a..803be6b2f 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -900,6 +900,19 @@ ActiveRecord::Schema.define(version: 20180813141443) do add_index "poll_shifts", ["booth_id"], name: "index_poll_shifts_on_booth_id", using: :btree add_index "poll_shifts", ["officer_id"], name: "index_poll_shifts_on_officer_id", using: :btree + create_table "poll_translations", force: :cascade do |t| + t.integer "poll_id", null: false + t.string "locale", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "name" + t.text "summary" + t.text "description" + end + + add_index "poll_translations", ["locale"], name: "index_poll_translations_on_locale", using: :btree + add_index "poll_translations", ["poll_id"], name: "index_poll_translations_on_poll_id", using: :btree + create_table "poll_voters", force: :cascade do |t| t.string "document_number" t.string "document_type" diff --git a/spec/features/admin/poll/polls_spec.rb b/spec/features/admin/poll/polls_spec.rb index e7e4d6bba..cfad58f96 100644 --- a/spec/features/admin/poll/polls_spec.rb +++ b/spec/features/admin/poll/polls_spec.rb @@ -55,11 +55,11 @@ feature 'Admin polls' do start_date = 1.week.from_now end_date = 2.weeks.from_now - fill_in "poll_name", with: "Upcoming poll" + fill_in "poll_name_en", with: "Upcoming poll" fill_in 'poll_starts_at', with: start_date.strftime("%d/%m/%Y") fill_in 'poll_ends_at', with: end_date.strftime("%d/%m/%Y") - fill_in 'poll_summary', with: "Upcoming poll's summary. This poll..." - fill_in 'poll_description', with: "Upcomming poll's description. This poll..." + fill_in 'poll_summary_en', with: "Upcoming poll's summary. This poll..." + fill_in 'poll_description_en', with: "Upcomming poll's description. This poll..." expect(page).not_to have_css("#poll_results_enabled") expect(page).not_to have_css("#poll_stats_enabled") @@ -83,7 +83,7 @@ feature 'Admin polls' do expect(page).to have_css("img[alt='#{poll.image.title}']") - fill_in "poll_name", with: "Next Poll" + fill_in "poll_name_en", with: "Next Poll" fill_in 'poll_ends_at', with: end_date.strftime("%d/%m/%Y") click_button "Update poll" diff --git a/spec/features/translations/polls_spec.rb b/spec/features/translations/polls_spec.rb new file mode 100644 index 000000000..d702205a1 --- /dev/null +++ b/spec/features/translations/polls_spec.rb @@ -0,0 +1,131 @@ +# 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 + + before do + @edit_poll_url = edit_admin_poll_path(poll) + end + + scenario "Add a translation", :js do + visit @edit_poll_url + + select "Français", from: "translation_locale" + fill_in 'poll_name_fr', with: 'Name en Français' + fill_in 'poll_summary_fr', with: 'Summary en Français' + fill_in 'poll_description_fr', with: 'Description en Français' + + click_button 'Update poll' + expect(page).to have_content "Poll updated successfully" + + visit @edit_poll_url + expect(page).to have_field('poll_name_en', with: 'Name in English') + expect(page).to have_field('poll_summary_en', with: 'Summary in English') + expect(page).to have_field('poll_description_en', with: 'Description in English') + + click_link "Español" + expect(page).to have_field('poll_name_es', with: 'Nombre en Español') + expect(page).to have_field('poll_summary_es', with: 'Resumen en Español') + expect(page).to have_field('poll_description_es', with: 'Descripción en Español') + + click_link "Français" + expect(page).to have_field('poll_name_fr', with: 'Name en Français') + expect(page).to have_field('poll_summary_fr', with: 'Summary en Français') + expect(page).to have_field('poll_description_fr', with: 'Description en Français') + end + + scenario "Update a translation", :js do + visit @edit_poll_url + + click_link "Español" + fill_in 'poll_name_es', with: 'Nombre correcto en Español' + fill_in 'poll_summary_es', with: 'Resumen correcto en Español' + fill_in 'poll_description_es', with: 'Descripción correcta en Español' + + click_button 'Update poll' + expect(page).to have_content "Poll updated successfully" + + visit poll_path(poll) + expect(page).to have_content("Name in English") + expect(page).to have_content("Summary in English") + expect(page).to have_content("Description in English") + + select('Español', from: 'locale-switcher') + expect(page).to have_content("Nombre correcto en Español") + expect(page).to have_content("Resumen correcto en Español") + expect(page).to have_content("Descripción correcta en Español") + end + + scenario "Remove a translation", :js do + visit @edit_poll_url + + click_link "Español" + click_link "Remove language" + + expect(page).not_to have_link "Español" + + click_button "Update poll" + visit @edit_poll_url + expect(page).not_to have_link "Español" + end + + context "Globalize javascript interface" do + + scenario "Highlight current locale", :js do + visit @edit_poll_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_poll_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_poll_url + + expect(page).to have_field('poll_description_en', with: 'Description in English') + + click_link "Español" + + expect(page).to have_field('poll_description_es', with: 'Descripción en Español') + end + + scenario "Select a locale and add it to the poll form", :js do + visit @edit_poll_url + + select "Français", from: "translation_locale" + + expect(page).to have_link "Français" + + click_link "Français" + + expect(page).to have_field('poll_description_fr') + end + end + end +end From 5e6248d2ac1d93eaac0389ab86621c881c2fe4f3 Mon Sep 17 00:00:00 2001 From: Julian Herrero Date: Thu, 20 Sep 2018 17:11:53 +0200 Subject: [PATCH 02/11] Make questions translatable --- .../admin/poll/questions_controller.rb | 7 +- app/models/poll/question.rb | 3 + app/views/admin/poll/questions/_form.html.erb | 9 +- db/dev_seeds/polls.rb | 30 +++- ...31173147_add_poll_question_translations.rb | 13 ++ db/schema.rb | 11 ++ spec/features/admin/poll/questions_spec.rb | 6 +- .../translations/poll_questions_spec.rb | 147 ++++++++++++++++++ 8 files changed, 215 insertions(+), 11 deletions(-) create mode 100644 db/migrate/20180731173147_add_poll_question_translations.rb create mode 100644 spec/features/translations/poll_questions_spec.rb 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 @@
+ <% select_options = Poll.all.map { |p| [p.name, p.id] } %> <%= f.select :poll_id, - options_for_select(Poll.pluck(:name, :id)), + options_for_select(select_options), prompt: t("admin.questions.index.select_poll"), label: t("admin.questions.new.poll_label") %>
- <%= f.text_field :title %> + <%= f.translatable_text_field :title %>
<%= f.submit(class: "button success expanded", value: t("shared.save")) %> diff --git a/db/dev_seeds/polls.rb b/db/dev_seeds/polls.rb index 212a27c3c..85ae050a8 100644 --- a/db/dev_seeds/polls.rb +++ b/db/dev_seeds/polls.rb @@ -47,10 +47,18 @@ end section "Creating Poll Questions & Answers" do Poll.find_each do |poll| (1..4).to_a.sample.times do - question = Poll::Question.create!(author: User.all.sample, - title: Faker::Lorem.sentence(3).truncate(60) + '?', - poll: poll) - Faker::Lorem.words((2..4).to_a.sample).each do |answer| + title = Faker::Lorem.sentence(3).truncate(60) + '?' + question = Poll::Question.new(author: User.all.sample, + title: title, + poll: poll) + 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! + Faker::Lorem.words((2..4).to_a.sample).each do |title| description = "

#{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 From 673ec075ebaf2f55d577ec4bdb9be00b3cb6cb04 Mon Sep 17 00:00:00 2001 From: Julian Herrero Date: Thu, 20 Sep 2018 17:13:40 +0200 Subject: [PATCH 03/11] Make answers translatable --- app/assets/javascripts/globalize.js.coffee | 5 +- .../poll/questions/answers_controller.rb | 8 +- app/models/poll/answer.rb | 4 +- app/models/poll/partial_result.rb | 4 +- app/models/poll/question/answer.rb | 7 +- .../poll/questions/answers/_form.html.erb | 25 +++- db/dev_seeds/polls.rb | 48 ++++-- ...9_add_poll_question_answer_translations.rb | 14 ++ db/schema.rb | 12 ++ .../poll/questions/answers/answers_spec.rb | 10 +- spec/features/polls/answers_spec.rb | 4 +- .../poll_question_answers_spec.rb | 138 ++++++++++++++++++ spec/helpers/ckeditor_spec.rb | 7 + 13 files changed, 258 insertions(+), 28 deletions(-) create mode 100644 db/migrate/20180801114529_add_poll_question_answer_translations.rb create mode 100644 spec/features/translations/poll_question_answers_spec.rb create mode 100644 spec/helpers/ckeditor_spec.rb diff --git a/app/assets/javascripts/globalize.js.coffee b/app/assets/javascripts/globalize.js.coffee index 027ac498e..09c13fd04 100644 --- a/app/assets/javascripts/globalize.js.coffee +++ b/app/assets/javascripts/globalize.js.coffee @@ -23,7 +23,10 @@ App.Globalize = element.addClass('is-active'); remove_language: (locale) -> - $(".js-globalize-attribute[data-locale=" + locale + "]").val('').hide() + $(".js-globalize-attribute[data-locale=" + locale + "]").each -> + $(this).val('').hide() + if CKEDITOR.instances[$(this).attr('id')] + CKEDITOR.instances[$(this).attr('id')].setData('') $(".js-globalize-locale-link[data-locale=" + locale + "]").hide() next = $(".js-globalize-locale-link:visible").first() App.Globalize.highlight_locale(next) diff --git a/app/controllers/admin/poll/questions/answers_controller.rb b/app/controllers/admin/poll/questions/answers_controller.rb index 3833111b9..225665b94 100644 --- a/app/controllers/admin/poll/questions/answers_controller.rb +++ b/app/controllers/admin/poll/questions/answers_controller.rb @@ -1,4 +1,6 @@ class Admin::Poll::Questions::AnswersController < Admin::Poll::BaseController + include Translatable + before_action :load_answer, only: [:show, :edit, :update, :documents] load_and_authorize_resource :question, class: "::Poll::Question" @@ -49,11 +51,15 @@ class Admin::Poll::Questions::AnswersController < Admin::Poll::BaseController def answer_params documents_attributes = [:id, :title, :attachment, :cached_attachment, :user_id, :_destroy] attributes = [:title, :description, :question_id, documents_attributes: documents_attributes] - params.require(:poll_question_answer).permit(*attributes) + params.require(:poll_question_answer).permit(*attributes, *translation_params(Poll::Question::Answer)) end def load_answer @answer = ::Poll::Question::Answer.find(params[:id] || params[:answer_id]) end + def resource + load_answer unless @answer + @answer + end end diff --git a/app/models/poll/answer.rb b/app/models/poll/answer.rb index 78122188a..851ce2fbc 100644 --- a/app/models/poll/answer.rb +++ b/app/models/poll/answer.rb @@ -9,7 +9,9 @@ class Poll::Answer < ActiveRecord::Base validates :author, presence: true validates :answer, presence: true - validates :answer, inclusion: { in: ->(a) { a.question.question_answers.pluck(:title) }}, + validates :answer, inclusion: { in: ->(a) { a.question.question_answers + .joins(:translations) + .pluck("poll_question_answer_translations.title") }}, unless: ->(a) { a.question.blank? } scope :by_author, ->(author_id) { where(author_id: author_id) } diff --git a/app/models/poll/partial_result.rb b/app/models/poll/partial_result.rb index 0550650a5..72a3372b3 100644 --- a/app/models/poll/partial_result.rb +++ b/app/models/poll/partial_result.rb @@ -10,7 +10,9 @@ class Poll::PartialResult < ActiveRecord::Base validates :question, presence: true validates :author, presence: true validates :answer, presence: true - validates :answer, inclusion: { in: ->(a) { a.question.question_answers.pluck(:title) }}, + validates :answer, inclusion: { in: ->(a) { a.question.question_answers + .joins(:translations) + .pluck("poll_question_answer_translations.title") }}, unless: ->(a) { a.question.blank? } validates :origin, inclusion: { in: VALID_ORIGINS } diff --git a/app/models/poll/question/answer.rb b/app/models/poll/question/answer.rb index 1c10e2b5c..4697fb0b5 100644 --- a/app/models/poll/question/answer.rb +++ b/app/models/poll/question/answer.rb @@ -1,6 +1,11 @@ class Poll::Question::Answer < ActiveRecord::Base include Galleryable include Documentable + + translates :title, touch: true + translates :description, touch: true + globalize_accessors locales: [:en, :es, :fr, :nl, :pt_br] + documentable max_documents_allowed: 3, max_file_size: 3.megabytes, accepted_content_types: [ "application/pdf" ] @@ -15,7 +20,7 @@ class Poll::Question::Answer < ActiveRecord::Base before_validation :set_order, on: :create def description - super.try :html_safe + self[:description].try :html_safe end def self.order_answers(ordered_array) diff --git a/app/views/admin/poll/questions/answers/_form.html.erb b/app/views/admin/poll/questions/answers/_form.html.erb index cbc450813..975f0995e 100644 --- a/app/views/admin/poll/questions/answers/_form.html.erb +++ b/app/views/admin/poll/questions/answers/_form.html.erb @@ -1,15 +1,30 @@ -<%= form_for(@answer, url: form_url) do |f| %> +<%= render "admin/shared/globalize_locales", resource: @answer %> + +<%= translatable_form_for(@answer, url: form_url) do |f| %> <%= render 'shared/errors', resource: @answer %> <%= f.hidden_field :question_id, value: @answer.question_id || @question.id %> - <%= f.text_field :title %> + <%= f.translatable_text_field :title %>
- <%= f.cktext_area :description, - maxlength: Poll::Question.description_max_length, - ckeditor: { language: I18n.locale } %> + <%= f.label :description, t("admin.shared.description") %> + <% @answer.globalize_locales.each do |locale| %> + <% globalize(locale) do %> + <%= content_tag :span, class: "js-globalize-attribute", + data: { locale: locale }, + style: display_translation?(locale) do %> + + <%= f.cktext_area "description_#{locale}", + maxlength: Poll::Question.description_max_length, + ckeditor: { language: locale }, + class: "js-globalize-attribute", + data: { locale: locale }, + label: false %> + <% end %> + <% end %> + <% end %>
diff --git a/db/dev_seeds/polls.rb b/db/dev_seeds/polls.rb index 85ae050a8..684337f7e 100644 --- a/db/dev_seeds/polls.rb +++ b/db/dev_seeds/polls.rb @@ -60,9 +60,17 @@ section "Creating Poll Questions & Answers" do question.save! Faker::Lorem.words((2..4).to_a.sample).each do |title| description = "

#{Faker::Lorem.paragraphs.join('

')}

" - Poll::Question::Answer.create!(question: question, - title: answer.capitalize, - description: description) + answer = Poll::Question::Answer.new(question: question, + title: title.capitalize, + description: description) + I18n.available_locales.map do |locale| + neutral_locale = locale.to_s.downcase.underscore.to_sym + Globalize.with_locale(neutral_locale) do + answer.title = "#{title} (#{locale})" + answer.description = "#{description} (#{locale})" + end + end + answer.save! end end end @@ -196,10 +204,19 @@ section "Creating Poll Questions from Proposals" do proposal = Proposal.all.sample poll = Poll.current.first question = Poll::Question.create(poll: poll) - Faker::Lorem.words((2..4).to_a.sample).each do |answer| - Poll::Question::Answer.create!(question: question, - title: answer.capitalize, - description: Faker::ChuckNorris.fact) + Faker::Lorem.words((2..4).to_a.sample).each do |title| + description = "

#{Faker::ChuckNorris.fact}

" + answer = Poll::Question::Answer.new(question: question, + title: title.capitalize, + description: description) + I18n.available_locales.map do |locale| + neutral_locale = locale.to_s.downcase.underscore.to_sym + Globalize.with_locale(neutral_locale) do + answer.title = "#{title} (#{locale})" + answer.description = "#{description} (#{locale})" + end + end + answer.save! end question.copy_attributes_from_proposal(proposal) title = question.title @@ -218,10 +235,19 @@ section "Creating Successful Proposals" do proposal = Proposal.all.sample poll = Poll.current.first question = Poll::Question.create(poll: poll) - Faker::Lorem.words((2..4).to_a.sample).each do |answer| - Poll::Question::Answer.create!(question: question, - title: answer.capitalize, - description: Faker::ChuckNorris.fact) + Faker::Lorem.words((2..4).to_a.sample).each do |title| + description = "

#{Faker::ChuckNorris.fact}

" + answer = Poll::Question::Answer.new(question: question, + title: title.capitalize, + description: description) + I18n.available_locales.map do |locale| + neutral_locale = locale.to_s.downcase.underscore.to_sym + Globalize.with_locale(neutral_locale) do + answer.title = "#{title} (#{locale})" + answer.description = "#{description} (#{locale})" + end + end + answer.save! end question.copy_attributes_from_proposal(proposal) title = question.title diff --git a/db/migrate/20180801114529_add_poll_question_answer_translations.rb b/db/migrate/20180801114529_add_poll_question_answer_translations.rb new file mode 100644 index 000000000..91643f443 --- /dev/null +++ b/db/migrate/20180801114529_add_poll_question_answer_translations.rb @@ -0,0 +1,14 @@ +class AddPollQuestionAnswerTranslations < ActiveRecord::Migration + + def self.up + Poll::Question::Answer.create_translation_table!( + title: :string, + description: :text + ) + end + + def self.down + Poll::Question::Answer.drop_translation_table! + end + +end diff --git a/db/schema.rb b/db/schema.rb index 88d4c73d9..d06ce8a4a 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -829,6 +829,18 @@ ActiveRecord::Schema.define(version: 20180813141443) do add_index "poll_partial_results", ["origin"], name: "index_poll_partial_results_on_origin", using: :btree add_index "poll_partial_results", ["question_id"], name: "index_poll_partial_results_on_question_id", using: :btree + create_table "poll_question_answer_translations", force: :cascade do |t| + t.integer "poll_question_answer_id", null: false + t.string "locale", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "title" + t.text "description" + end + + add_index "poll_question_answer_translations", ["locale"], name: "index_poll_question_answer_translations_on_locale", using: :btree + add_index "poll_question_answer_translations", ["poll_question_answer_id"], name: "index_85270fa85f62081a3a227186b4c95fe4f7fa94b9", using: :btree + create_table "poll_question_answer_videos", force: :cascade do |t| t.string "title" t.string "url" diff --git a/spec/features/admin/poll/questions/answers/answers_spec.rb b/spec/features/admin/poll/questions/answers/answers_spec.rb index 288f514a4..dbcf8cf5c 100644 --- a/spec/features/admin/poll/questions/answers/answers_spec.rb +++ b/spec/features/admin/poll/questions/answers/answers_spec.rb @@ -15,8 +15,8 @@ feature 'Answers' do visit admin_question_path(question) click_link 'Add answer' - fill_in 'poll_question_answer_title', with: title - fill_in 'poll_question_answer_description', with: description + fill_in 'poll_question_answer_title_en', with: title + fill_in 'poll_question_answer_description_en', with: description click_button 'Save' @@ -33,8 +33,8 @@ feature 'Answers' do visit admin_question_path(question) click_link 'Add answer' - fill_in 'poll_question_answer_title', with: title - fill_in 'poll_question_answer_description', with: description + fill_in 'poll_question_answer_title_en', with: title + fill_in 'poll_question_answer_description_en', with: description click_button 'Save' @@ -53,7 +53,7 @@ feature 'Answers' do old_title = answer.title new_title = 'Ex Machina' - fill_in 'poll_question_answer_title', with: new_title + fill_in 'poll_question_answer_title_en', with: new_title click_button 'Save' diff --git a/spec/features/polls/answers_spec.rb b/spec/features/polls/answers_spec.rb index 8bb87c94e..6daffc0eb 100644 --- a/spec/features/polls/answers_spec.rb +++ b/spec/features/polls/answers_spec.rb @@ -28,8 +28,8 @@ feature 'Answers' do visit admin_question_path(question) click_link "Add answer" - fill_in "poll_question_answer_title", with: "¿Would you like to reform Central Park?" - fill_in "poll_question_answer_description", with: "Adding more trees, creating a play area..." + fill_in "poll_question_answer_title_en", with: "¿Would you like to reform Central Park?" + fill_in "poll_question_answer_description_en", with: "Adding more trees, creating a play area..." click_button "Save" expect(page).to have_content "Answer created successfully" diff --git a/spec/features/translations/poll_question_answers_spec.rb b/spec/features/translations/poll_question_answers_spec.rb new file mode 100644 index 000000000..3de1bfb38 --- /dev/null +++ b/spec/features/translations/poll_question_answers_spec.rb @@ -0,0 +1,138 @@ +# 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") } + + context "Answers" do + + let(:answer) { create(:poll_question_answer, question: question, + title_en: "Answer in English", + title_es: "Respuesta en Español", + description_en: "Description in English", + description_es: "Descripción en Español") } + + before do + @edit_answer_url = edit_admin_answer_path(answer) + end + + scenario "Add a translation", :js do + visit @edit_answer_url + + select "Français", from: "translation_locale" + fill_in 'poll_question_answer_title_fr', with: 'Answer en Français' + fill_in_ckeditor 'poll_question_answer_description_fr', with: 'Description en Français' + + click_button 'Save' + expect(page).to have_content "Changes saved" + + expect(page).to have_content "Answer in English" + expect(page).to have_content "Description in English" + + select('Español', from: 'locale-switcher') + expect(page).to have_content "Respuesta en Español" + expect(page).to have_content "Descripción en Español" + + select('Français', from: 'locale-switcher') + expect(page).to have_content "Answer en Français" + expect(page).to have_content "Description en Français" + end + + scenario "Update a translation", :js do + visit @edit_answer_url + + click_link "Español" + fill_in 'poll_question_answer_title_es', with: 'Pregunta correcta en Español' + fill_in_ckeditor 'poll_question_answer_description_es', with: 'Descripción correcta en Español' + + click_button 'Save' + expect(page).to have_content "Changes saved" + + expect(page).to have_content("Answer in English") + expect(page).to have_content("Description in English") + + select('Español', from: 'locale-switcher') + expect(page).to have_content("Pregunta correcta en Español") + expect(page).to have_content("Descripción correcta en Español") + end + + scenario "Remove a translation", :js do + visit @edit_answer_url + + click_link "Español" + click_link "Remove language" + + expect(page).not_to have_link "Español" + + click_button "Save" + visit @edit_answer_url + expect(page).not_to have_link "Español" + end + + context "Globalize javascript interface" do + + scenario "Highlight current locale", :js do + visit @edit_answer_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_answer_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_answer_url + + expect(page).to have_field('poll_question_answer_title_en', with: 'Answer in English') + + click_link "Español" + + expect(page).to have_field('poll_question_answer_title_es', with: 'Respuesta en Español') + end + + scenario "Select a locale and add it to the poll form", :js do + visit @edit_answer_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_answer_title_fr') + end + end + end + end + end +end diff --git a/spec/helpers/ckeditor_spec.rb b/spec/helpers/ckeditor_spec.rb new file mode 100644 index 000000000..9ad868123 --- /dev/null +++ b/spec/helpers/ckeditor_spec.rb @@ -0,0 +1,7 @@ +def fill_in_ckeditor(id, with:) + + within_frame find("#cke_#{id} iframe") do + find('body').base.send_keys with + end + +end From e6762d6bcacc9c9feb5d629b138f26bc59c5ac17 Mon Sep 17 00:00:00 2001 From: Julian Herrero Date: Fri, 21 Sep 2018 20:50:23 +0200 Subject: [PATCH 04/11] handle non-underscored locale names for cktext_area --- app/helpers/translatable_form_helper.rb | 11 ++++++++++- .../admin/poll/questions/answers/_form.html.erb | 17 +---------------- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/app/helpers/translatable_form_helper.rb b/app/helpers/translatable_form_helper.rb index 41aa1181a..14d5b5b66 100644 --- a/app/helpers/translatable_form_helper.rb +++ b/app/helpers/translatable_form_helper.rb @@ -35,6 +35,10 @@ module TranslatableFormHelper translatable_field(:text_area, method, options) end + def translatable_cktext_area(method, options = {}) + translatable_field(:cktext_area, method, options) + end + private def translatable_field(field_type, method, options = {}) @@ -47,7 +51,12 @@ module TranslatableFormHelper final_options = @template.merge_translatable_field_options(options, locale) .reverse_merge(label: label_without_locale) - @template.concat send(field_type, localized_attr_name, final_options) + if field_type == :cktext_area + @template.concat content_tag :span, send(field_type, localized_attr_name, final_options), + @template.merge_translatable_field_options(options, locale) + else + @template.concat send(field_type, localized_attr_name, final_options) + end end end end diff --git a/app/views/admin/poll/questions/answers/_form.html.erb b/app/views/admin/poll/questions/answers/_form.html.erb index 975f0995e..1ca05d9ab 100644 --- a/app/views/admin/poll/questions/answers/_form.html.erb +++ b/app/views/admin/poll/questions/answers/_form.html.erb @@ -9,22 +9,7 @@ <%= f.translatable_text_field :title %>
- <%= f.label :description, t("admin.shared.description") %> - <% @answer.globalize_locales.each do |locale| %> - <% globalize(locale) do %> - <%= content_tag :span, class: "js-globalize-attribute", - data: { locale: locale }, - style: display_translation?(locale) do %> - - <%= f.cktext_area "description_#{locale}", - maxlength: Poll::Question.description_max_length, - ckeditor: { language: locale }, - class: "js-globalize-attribute", - data: { locale: locale }, - label: false %> - <% end %> - <% end %> - <% end %> + <%= f.translatable_cktext_area :description, maxlength: Poll::Question.description_max_length %>
From 888ae8e6d6749d34f358ae21b05fc8f1c8b87d4f Mon Sep 17 00:00:00 2001 From: Julian Herrero Date: Fri, 21 Sep 2018 20:51:13 +0200 Subject: [PATCH 05/11] neutral_locale not needed anymore --- db/dev_seeds/polls.rb | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/db/dev_seeds/polls.rb b/db/dev_seeds/polls.rb index 684337f7e..a7884d570 100644 --- a/db/dev_seeds/polls.rb +++ b/db/dev_seeds/polls.rb @@ -32,8 +32,7 @@ section "Creating polls" do Poll.find_each do |poll| name = poll.name I18n.available_locales.map do |locale| - neutral_locale = locale.to_s.downcase.underscore.to_sym - Globalize.with_locale(neutral_locale) do + Globalize.with_locale(locale) do poll.name = "#{name} (#{locale})" poll.summary = "Summary for locale #{locale}" poll.description = "Description for locale #{locale}" @@ -52,8 +51,7 @@ section "Creating Poll Questions & Answers" do title: title, poll: poll) I18n.available_locales.map do |locale| - neutral_locale = locale.to_s.downcase.underscore.to_sym - Globalize.with_locale(neutral_locale) do + Globalize.with_locale(locale) do question.title = "#{title} (#{locale})" end end @@ -64,8 +62,7 @@ section "Creating Poll Questions & Answers" do title: title.capitalize, description: description) I18n.available_locales.map do |locale| - neutral_locale = locale.to_s.downcase.underscore.to_sym - Globalize.with_locale(neutral_locale) do + Globalize.with_locale(locale) do answer.title = "#{title} (#{locale})" answer.description = "#{description} (#{locale})" end @@ -210,8 +207,7 @@ section "Creating Poll Questions from Proposals" do title: title.capitalize, description: description) I18n.available_locales.map do |locale| - neutral_locale = locale.to_s.downcase.underscore.to_sym - Globalize.with_locale(neutral_locale) do + Globalize.with_locale(locale) do answer.title = "#{title} (#{locale})" answer.description = "#{description} (#{locale})" end @@ -221,8 +217,7 @@ section "Creating Poll Questions from Proposals" do 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 + Globalize.with_locale(locale) do question.title = "#{title} (#{locale})" end end @@ -241,8 +236,7 @@ section "Creating Successful Proposals" do title: title.capitalize, description: description) I18n.available_locales.map do |locale| - neutral_locale = locale.to_s.downcase.underscore.to_sym - Globalize.with_locale(neutral_locale) do + Globalize.with_locale(locale) do answer.title = "#{title} (#{locale})" answer.description = "#{description} (#{locale})" end @@ -252,8 +246,7 @@ section "Creating Successful Proposals" do 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 + Globalize.with_locale(locale) do question.title = "#{title} (#{locale})" end end From 549c08657432624654ac2d6c76beae0231d25568 Mon Sep 17 00:00:00 2001 From: Julian Herrero Date: Fri, 21 Sep 2018 20:51:51 +0200 Subject: [PATCH 06/11] put spec helper in the correct place --- .../ckeditor_spec.rb => support/common_actions/ckeditor.rb} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename spec/{helpers/ckeditor_spec.rb => support/common_actions/ckeditor.rb} (100%) diff --git a/spec/helpers/ckeditor_spec.rb b/spec/support/common_actions/ckeditor.rb similarity index 100% rename from spec/helpers/ckeditor_spec.rb rename to spec/support/common_actions/ckeditor.rb From df9955e0c60e766abf8a0046f96dbce3501b7bba Mon Sep 17 00:00:00 2001 From: Julian Herrero Date: Fri, 21 Sep 2018 20:52:35 +0200 Subject: [PATCH 07/11] make use of the new spec helper it_behaves_like translatable --- spec/features/admin/poll/polls_spec.rb | 5 + spec/features/admin/poll/questions_spec.rb | 42 +++++ .../poll_question_answers_spec.rb | 17 +- .../translations/poll_questions_spec.rb | 147 ------------------ spec/features/translations/polls_spec.rb | 131 ---------------- spec/shared/features/translatable.rb | 4 + 6 files changed, 65 insertions(+), 281 deletions(-) delete mode 100644 spec/features/translations/poll_questions_spec.rb delete mode 100644 spec/features/translations/polls_spec.rb diff --git a/spec/features/admin/poll/polls_spec.rb b/spec/features/admin/poll/polls_spec.rb index cfad58f96..b28aff019 100644 --- a/spec/features/admin/poll/polls_spec.rb +++ b/spec/features/admin/poll/polls_spec.rb @@ -7,6 +7,11 @@ feature 'Admin polls' do login_as(admin.user) end + it_behaves_like "translatable", + "poll", + "edit_admin_poll_path", + %w[name summary description] + scenario 'Index empty', :js do visit admin_root_path diff --git a/spec/features/admin/poll/questions_spec.rb b/spec/features/admin/poll/questions_spec.rb index 2b3762c53..230ba5c28 100644 --- a/spec/features/admin/poll/questions_spec.rb +++ b/spec/features/admin/poll/questions_spec.rb @@ -6,6 +6,11 @@ feature 'Admin poll questions' do login_as(create(:administrator).user) end + it_behaves_like "translatable", + "poll_question", + "edit_admin_question_path", + %w[title] + scenario 'Index' do question1 = create(:poll_question) question2 = create(:poll_question) @@ -108,4 +113,41 @@ feature 'Admin poll questions' do pending "Mark all city by default when creating a poll question from a successful proposal" + context "Poll select box" 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") } + + 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 + + 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 end diff --git a/spec/features/translations/poll_question_answers_spec.rb b/spec/features/translations/poll_question_answers_spec.rb index 3de1bfb38..cd33106c1 100644 --- a/spec/features/translations/poll_question_answers_spec.rb +++ b/spec/features/translations/poll_question_answers_spec.rb @@ -57,12 +57,12 @@ feature "Translations" do expect(page).to have_content "Description en Français" end - scenario "Update a translation", :js do + scenario "Update a translation with allowed blank translated field", :js do visit @edit_answer_url click_link "Español" fill_in 'poll_question_answer_title_es', with: 'Pregunta correcta en Español' - fill_in_ckeditor 'poll_question_answer_description_es', with: 'Descripción correcta en Español' + fill_in_ckeditor 'poll_question_answer_description_es', with: '' click_button 'Save' expect(page).to have_content "Changes saved" @@ -72,7 +72,7 @@ feature "Translations" do select('Español', from: 'locale-switcher') expect(page).to have_content("Pregunta correcta en Español") - expect(page).to have_content("Descripción correcta en Español") + expect(page).to_not have_content("Descripción en Español") end scenario "Remove a translation", :js do @@ -88,6 +88,17 @@ feature "Translations" do expect(page).not_to have_link "Español" end + scenario "Add a translation for a locale with non-underscored name", :js do + visit @edit_answer_url + + select('Português', from: 'translation_locale') + fill_in_ckeditor 'poll_question_answer_description_pt_br', with: 'resposta em Português' + click_button 'Save' + + select('Português', from: 'locale-switcher') + expect(page).to have_content("resposta em Português") + end + context "Globalize javascript interface" do scenario "Highlight current locale", :js do diff --git a/spec/features/translations/poll_questions_spec.rb b/spec/features/translations/poll_questions_spec.rb deleted file mode 100644 index 0acd8cf1b..000000000 --- a/spec/features/translations/poll_questions_spec.rb +++ /dev/null @@ -1,147 +0,0 @@ -# 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 diff --git a/spec/features/translations/polls_spec.rb b/spec/features/translations/polls_spec.rb deleted file mode 100644 index d702205a1..000000000 --- a/spec/features/translations/polls_spec.rb +++ /dev/null @@ -1,131 +0,0 @@ -# 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 - - before do - @edit_poll_url = edit_admin_poll_path(poll) - end - - scenario "Add a translation", :js do - visit @edit_poll_url - - select "Français", from: "translation_locale" - fill_in 'poll_name_fr', with: 'Name en Français' - fill_in 'poll_summary_fr', with: 'Summary en Français' - fill_in 'poll_description_fr', with: 'Description en Français' - - click_button 'Update poll' - expect(page).to have_content "Poll updated successfully" - - visit @edit_poll_url - expect(page).to have_field('poll_name_en', with: 'Name in English') - expect(page).to have_field('poll_summary_en', with: 'Summary in English') - expect(page).to have_field('poll_description_en', with: 'Description in English') - - click_link "Español" - expect(page).to have_field('poll_name_es', with: 'Nombre en Español') - expect(page).to have_field('poll_summary_es', with: 'Resumen en Español') - expect(page).to have_field('poll_description_es', with: 'Descripción en Español') - - click_link "Français" - expect(page).to have_field('poll_name_fr', with: 'Name en Français') - expect(page).to have_field('poll_summary_fr', with: 'Summary en Français') - expect(page).to have_field('poll_description_fr', with: 'Description en Français') - end - - scenario "Update a translation", :js do - visit @edit_poll_url - - click_link "Español" - fill_in 'poll_name_es', with: 'Nombre correcto en Español' - fill_in 'poll_summary_es', with: 'Resumen correcto en Español' - fill_in 'poll_description_es', with: 'Descripción correcta en Español' - - click_button 'Update poll' - expect(page).to have_content "Poll updated successfully" - - visit poll_path(poll) - expect(page).to have_content("Name in English") - expect(page).to have_content("Summary in English") - expect(page).to have_content("Description in English") - - select('Español', from: 'locale-switcher') - expect(page).to have_content("Nombre correcto en Español") - expect(page).to have_content("Resumen correcto en Español") - expect(page).to have_content("Descripción correcta en Español") - end - - scenario "Remove a translation", :js do - visit @edit_poll_url - - click_link "Español" - click_link "Remove language" - - expect(page).not_to have_link "Español" - - click_button "Update poll" - visit @edit_poll_url - expect(page).not_to have_link "Español" - end - - context "Globalize javascript interface" do - - scenario "Highlight current locale", :js do - visit @edit_poll_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_poll_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_poll_url - - expect(page).to have_field('poll_description_en', with: 'Description in English') - - click_link "Español" - - expect(page).to have_field('poll_description_es', with: 'Descripción en Español') - end - - scenario "Select a locale and add it to the poll form", :js do - visit @edit_poll_url - - select "Français", from: "translation_locale" - - expect(page).to have_link "Français" - - click_link "Français" - - expect(page).to have_field('poll_description_fr') - end - end - end -end diff --git a/spec/shared/features/translatable.rb b/spec/shared/features/translatable.rb index 9757b134c..ab0a5e75c 100644 --- a/spec/shared/features/translatable.rb +++ b/spec/shared/features/translatable.rb @@ -188,6 +188,10 @@ def update_button_text "Update milestone" when "AdminNotification" "Update notification" + when "Poll" + "Update poll" + when "Poll::Question" + "Save" else "Save changes" end From 46030c72e829006da92bb02892eac893c1823893 Mon Sep 17 00:00:00 2001 From: Julian Herrero Date: Fri, 21 Sep 2018 20:53:20 +0200 Subject: [PATCH 08/11] remove unnecessary parameter --- app/models/poll/question/answer.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/poll/question/answer.rb b/app/models/poll/question/answer.rb index 4697fb0b5..56655e457 100644 --- a/app/models/poll/question/answer.rb +++ b/app/models/poll/question/answer.rb @@ -4,7 +4,7 @@ class Poll::Question::Answer < ActiveRecord::Base translates :title, touch: true translates :description, touch: true - globalize_accessors locales: [:en, :es, :fr, :nl, :pt_br] + globalize_accessors documentable max_documents_allowed: 3, max_file_size: 3.megabytes, From 1c6f0be8561f218af1629eccb3d8870f69f25ce9 Mon Sep 17 00:00:00 2001 From: Julian Herrero Date: Fri, 21 Sep 2018 20:54:11 +0200 Subject: [PATCH 09/11] remove unused locales --- config/locales/en/admin.yml | 2 -- config/locales/es/admin.yml | 2 -- 2 files changed, 4 deletions(-) diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index b85557664..682a87dee 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -1084,10 +1084,8 @@ en: search_results: "Search results" no_search_results: "No results found." actions: Actions - name: Name title: Title description: Description - summary: Summary image: Image show_image: Show image moderated_content: "Check the content moderated by the moderators, and confirm if the moderation has been done correctly." diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 93569cdd6..eabfbc536 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -1085,10 +1085,8 @@ es: search_results: "Resultados de la búsqueda" no_search_results: "No se han encontrado resultados." actions: Acciones - name: Nombre title: Título description: Descripción - summary: Resumen image: Imagen show_image: Mostrar imagen moderated_content: "Revisa el contenido moderado por los moderadores, y confirma si la moderación se ha realizado correctamente." From 1d30909725611fda98c41a12ded834483f59d3d8 Mon Sep 17 00:00:00 2001 From: Julian Herrero Date: Mon, 24 Sep 2018 19:38:59 +0200 Subject: [PATCH 10/11] remove duplicated method --- spec/support/common_actions/ckeditor.rb | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 spec/support/common_actions/ckeditor.rb diff --git a/spec/support/common_actions/ckeditor.rb b/spec/support/common_actions/ckeditor.rb deleted file mode 100644 index 9ad868123..000000000 --- a/spec/support/common_actions/ckeditor.rb +++ /dev/null @@ -1,7 +0,0 @@ -def fill_in_ckeditor(id, with:) - - within_frame find("#cke_#{id} iframe") do - find('body').base.send_keys with - end - -end From 4344165bce7b5009e1635da47295cbbc3631d37e Mon Sep 17 00:00:00 2001 From: Julian Herrero Date: Mon, 24 Sep 2018 19:40:51 +0200 Subject: [PATCH 11/11] change translatable form helper for cktext_area --- app/helpers/translatable_form_helper.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/helpers/translatable_form_helper.rb b/app/helpers/translatable_form_helper.rb index 14d5b5b66..1e468c4ce 100644 --- a/app/helpers/translatable_form_helper.rb +++ b/app/helpers/translatable_form_helper.rb @@ -52,8 +52,10 @@ module TranslatableFormHelper .reverse_merge(label: label_without_locale) if field_type == :cktext_area - @template.concat content_tag :span, send(field_type, localized_attr_name, final_options), - @template.merge_translatable_field_options(options, locale) + @template.concat content_tag :div, send(field_type, localized_attr_name, final_options), + class: "js-globalize-attribute", + style: @template.display_translation?(locale), + data: { locale: locale } else @template.concat send(field_type, localized_attr_name, final_options) end