diff --git a/spec/features/admin/admin_notifications_spec.rb b/spec/features/admin/admin_notifications_spec.rb index 424e422cf..9d6007b4f 100644 --- a/spec/features/admin/admin_notifications_spec.rb +++ b/spec/features/admin/admin_notifications_spec.rb @@ -8,11 +8,6 @@ describe "Admin Notifications" do create(:budget) end - it_behaves_like "edit_translatable", - "admin_notification", - "edit_admin_admin_notification_path", - %w[title body] - context "Show" do scenario "Valid Admin Notification" do notification = create(:admin_notification, title: "Notification title", diff --git a/spec/features/admin/banners_spec.rb b/spec/features/admin/banners_spec.rb index f5cc25106..c45566fd5 100644 --- a/spec/features/admin/banners_spec.rb +++ b/spec/features/admin/banners_spec.rb @@ -6,11 +6,6 @@ describe "Admin banners magement" do login_as(create(:administrator).user) end - it_behaves_like "edit_translatable", - "banner", - "edit_admin_banner_path", - %w[title description] - context "Index" do before do @banner1 = create(:banner, title: "Banner number one", diff --git a/spec/features/admin/budget_groups_spec.rb b/spec/features/admin/budget_groups_spec.rb index f1186b643..b94640371 100644 --- a/spec/features/admin/budget_groups_spec.rb +++ b/spec/features/admin/budget_groups_spec.rb @@ -9,11 +9,6 @@ describe "Admin budget groups" do login_as(admin.user) end - it_behaves_like "edit_translatable", - "budget_group", - "edit_admin_budget_group_path", - %w[name] - context "Feature flag" do before do diff --git a/spec/features/admin/budget_headings_spec.rb b/spec/features/admin/budget_headings_spec.rb index 54d77b2ff..b2647064e 100644 --- a/spec/features/admin/budget_headings_spec.rb +++ b/spec/features/admin/budget_headings_spec.rb @@ -10,11 +10,6 @@ describe "Admin budget headings" do login_as(admin.user) end - it_behaves_like "edit_translatable", - "budget_heading", - "edit_admin_budget_group_heading_path", - %w[name] - context "Feature flag" do before do diff --git a/spec/features/admin/budget_investment_milestones_spec.rb b/spec/features/admin/budget_investment_milestones_spec.rb deleted file mode 100644 index d33a672e5..000000000 --- a/spec/features/admin/budget_investment_milestones_spec.rb +++ /dev/null @@ -1,9 +0,0 @@ -require "rails_helper" - -describe "Admin budget investment milestones" do - - it_behaves_like "edit_translatable", - "milestone", - "edit_tracking_budget_budget_investment_milestone_path", - %w[description] -end diff --git a/spec/features/admin/budget_investments_spec.rb b/spec/features/admin/budget_investments_spec.rb index 515cad75d..187bd3287 100644 --- a/spec/features/admin/budget_investments_spec.rb +++ b/spec/features/admin/budget_investments_spec.rb @@ -11,12 +11,6 @@ describe "Admin budget investments" do :budget_investment, "admin_budget_budget_investment_path" - it_behaves_like "edit_translatable", - :budget_investment, - "edit_admin_budget_budget_investment_path", - %w[title], - { "description" => :ckeditor } - before do @admin = create(:administrator) login_as(@admin.user) diff --git a/spec/features/admin/budget_phases_spec.rb b/spec/features/admin/budget_phases_spec.rb index fa1a4031d..b185e5fa1 100644 --- a/spec/features/admin/budget_phases_spec.rb +++ b/spec/features/admin/budget_phases_spec.rb @@ -10,12 +10,6 @@ describe "Admin budget phases" do login_as(admin.user) end - it_behaves_like "edit_translatable", - "budget_phase", - "edit_admin_budget_budget_phase_path", - [], - { "description" => :ckeditor, "summary" => :ckeditor } - scenario "Update phase", :js do visit edit_admin_budget_budget_phase_path(budget, budget.current_phase) diff --git a/spec/features/admin/budgets_spec.rb b/spec/features/admin/budgets_spec.rb index 0d12461ca..b003a2673 100644 --- a/spec/features/admin/budgets_spec.rb +++ b/spec/features/admin/budgets_spec.rb @@ -7,11 +7,6 @@ describe "Admin budgets" do login_as(admin.user) end - it_behaves_like "edit_translatable", - "budget", - "edit_admin_budget_path", - %w[name] - context "Feature flag" do before do diff --git a/spec/features/admin/legislation/draft_versions_spec.rb b/spec/features/admin/legislation/draft_versions_spec.rb index a4c3eae2b..4a072de4d 100644 --- a/spec/features/admin/legislation/draft_versions_spec.rb +++ b/spec/features/admin/legislation/draft_versions_spec.rb @@ -7,12 +7,6 @@ describe "Admin legislation draft versions" do login_as(admin.user) end - it_behaves_like "edit_translatable", - "legislation_draft_version", - "edit_admin_legislation_process_draft_version_path", - %w[title changelog], - { "body" => :markdownit } - context "Feature flag" do scenario "Disabled with a feature flag" do diff --git a/spec/features/admin/legislation/processes_spec.rb b/spec/features/admin/legislation/processes_spec.rb index 58cb3482c..f2eea400b 100644 --- a/spec/features/admin/legislation/processes_spec.rb +++ b/spec/features/admin/legislation/processes_spec.rb @@ -7,11 +7,6 @@ describe "Admin collaborative legislation" do login_as(admin.user) end - it_behaves_like "edit_translatable", - "legislation_process", - "edit_admin_legislation_process_path", - %w[title summary description additional_info] - it_behaves_like "admin_milestoneable", :legislation_process, "admin_legislation_process_milestones_path" diff --git a/spec/features/admin/legislation/questions_spec.rb b/spec/features/admin/legislation/questions_spec.rb index 2ec091d86..fc811c624 100644 --- a/spec/features/admin/legislation/questions_spec.rb +++ b/spec/features/admin/legislation/questions_spec.rb @@ -9,11 +9,6 @@ describe "Admin legislation questions" do let!(:process) { create(:legislation_process, title: "An example legislation process") } - it_behaves_like "edit_translatable", - "legislation_question", - "edit_admin_legislation_process_question_path", - %w[title] - context "Feature flag" do before do diff --git a/spec/features/admin/poll/active_polls_spec.rb b/spec/features/admin/poll/active_polls_spec.rb index ecc3f1490..ebd6ab51b 100644 --- a/spec/features/admin/poll/active_polls_spec.rb +++ b/spec/features/admin/poll/active_polls_spec.rb @@ -7,12 +7,6 @@ describe "Admin Active polls" do login_as(admin.user) end - it_behaves_like "edit_translatable", - "active_poll", - "edit_admin_active_polls_path", - [], - { "description" => :ckeditor } - scenario "Add", :js do expect(ActivePoll.first).to be nil diff --git a/spec/features/admin/poll/polls_spec.rb b/spec/features/admin/poll/polls_spec.rb index a73e11f6d..9460a9e4f 100644 --- a/spec/features/admin/poll/polls_spec.rb +++ b/spec/features/admin/poll/polls_spec.rb @@ -7,11 +7,6 @@ describe "Admin polls" do login_as(admin.user) end - it_behaves_like "edit_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/answers/answers_spec.rb b/spec/features/admin/poll/questions/answers/answers_spec.rb index 149c7532e..9ffcab470 100644 --- a/spec/features/admin/poll/questions/answers/answers_spec.rb +++ b/spec/features/admin/poll/questions/answers/answers_spec.rb @@ -7,12 +7,6 @@ describe "Answers" do login_as admin.user end - it_behaves_like "edit_translatable", - "poll_question_answer", - "edit_admin_answer_path", - %w[title], - { "description" => :ckeditor } - scenario "Create" do question = create(:poll_question) title = "Whatever the question may be, the answer is always 42" diff --git a/spec/features/admin/poll/questions_spec.rb b/spec/features/admin/poll/questions_spec.rb index d516ca361..5af0f58cf 100644 --- a/spec/features/admin/poll/questions_spec.rb +++ b/spec/features/admin/poll/questions_spec.rb @@ -6,11 +6,6 @@ describe "Admin poll questions" do login_as(create(:administrator).user) end - it_behaves_like "edit_translatable", - "poll_question", - "edit_admin_question_path", - %w[title] - scenario "Index" do poll1 = create(:poll) poll2 = create(:poll) diff --git a/spec/features/admin/site_customization/information_texts_spec.rb b/spec/features/admin/site_customization/information_texts_spec.rb index 3d12a3511..c6ac77933 100644 --- a/spec/features/admin/site_customization/information_texts_spec.rb +++ b/spec/features/admin/site_customization/information_texts_spec.rb @@ -7,11 +7,6 @@ describe "Admin custom information texts" do login_as(admin.user) end - it_behaves_like "edit_translatable", - "i18n_content", - "admin_site_customization_information_texts_path", - %w[value] - scenario "page is correctly loaded" do visit admin_site_customization_information_texts_path diff --git a/spec/features/admin/site_customization/pages_spec.rb b/spec/features/admin/site_customization/pages_spec.rb index 9147acfe9..4be5819c4 100644 --- a/spec/features/admin/site_customization/pages_spec.rb +++ b/spec/features/admin/site_customization/pages_spec.rb @@ -7,12 +7,6 @@ describe "Admin custom pages" do login_as(admin.user) end - it_behaves_like "edit_translatable", - "site_customization_page", - "edit_admin_site_customization_page_path", - %w[title subtitle], - { "content" => :ckeditor } - context "Index" do scenario "lists all created custom pages" do diff --git a/spec/features/admin/translatable_spec.rb b/spec/features/admin/translatable_spec.rb index c189561be..b156ffeae 100644 --- a/spec/features/admin/translatable_spec.rb +++ b/spec/features/admin/translatable_spec.rb @@ -1,20 +1,12 @@ -shared_examples "edit_translatable" do |factory_name, path_name, input_fields, textarea_fields = {}| - let(:language_texts) do - { - es: "en español", - en: "in English", - fr: "en Français", - "pt-BR": "Português" - } +require "rails_helper" + +describe "Admin edit translatable records" do + before do + login_as(create(:administrator).user) + translatable.update(attributes) end - let(:translatable_class) { build(factory_name).class } - - let(:input_fields) { input_fields } # So it's accessible by methods - let(:textarea_fields) { textarea_fields } # So it's accessible by methods - let(:path_name) { path_name } # So it's accessible by methods - - let(:fields) { input_fields + textarea_fields.keys } + let(:fields) { translatable.translated_attribute_names } let(:attributes) do fields.product(%i[en es]).map do |field, locale| @@ -22,291 +14,453 @@ shared_examples "edit_translatable" do |factory_name, path_name, input_fields, t end.to_h end - let(:optional_fields) do - fields.select do |field| - translatable.translations.last.dup.tap { |duplicate| duplicate.send(:"#{field}=", "") }.valid? + context "Add a translation", :js do + context "Input fields" do + let(:translatable) { create(:budget_heading) } + let(:path) { edit_admin_budget_group_heading_path(*resource_hierarchy_for(translatable)) } + + scenario "Maintains existing translations" do + visit path + + select "Français", from: :add_language + fill_in "Heading name", with: "Nom en Français" + click_button "Save heading" + + visit path + + expect(page).to have_field "Heading name", with: "Heading name in English" + + select "Español", from: :select_language + + expect(page).to have_field "Heading name", with: "Nombre de la partida en español" + + select "Français", from: :select_language + + expect(page).to have_field "Heading name", with: "Nom en Français" + end + end + + context "CKEditor fields" do + let(:translatable) { create(:site_customization_page) } + let(:path) { edit_admin_site_customization_page_path(translatable) } + + scenario "Maintains existing translations" do + visit path + + select "Français", from: :add_language + fill_in "Title", with: "Titre en Français" + fill_in "Subtitle", with: "Sous-titres en Français" + fill_in_ckeditor "Content", with: "Contenu en Français" + click_button "Update Custom page" + + visit path + + within_frame(0) { expect(page).to have_content "Content in English" } + + select "Español", from: :select_language + + within_frame(0) { expect(page).to have_content "Contenido en español" } + + select "Français", from: :select_language + + within_frame(0) { expect(page).to have_content "Contenu en Français" } + end + end + + context "Markdownit field" do + let(:translatable) { create(:legislation_draft_version) } + let(:path) { edit_admin_legislation_process_draft_version_path(translatable.process, translatable) } + + scenario "Maintains existing translations" do + visit path + + select "Français", from: :add_language + fill_in "Version title", with: "Titre en Français" + click_link class: "fullscreen-toggle" + fill_in "Text", with: "Texte en Français" + click_link class: "fullscreen-toggle" + click_button "Save changes" + + visit path + click_link class: "fullscreen-toggle" + + expect(page).to have_field "Text", with: "Text in English" + + click_link class: "fullscreen-toggle" + select "Español", from: :select_language + click_link class: "fullscreen-toggle" + + expect(page).to have_field "Text", with: "Texto en español" + + click_link class: "fullscreen-toggle" + select "Français", from: :select_language + click_link class: "fullscreen-toggle" + + expect(page).to have_field "Text", with: "Texte en Français" + end + end + + context "Locale with non-underscored name", :js do + let(:translatable) { create(:legislation_question) } + let(:path) { edit_admin_legislation_process_question_path(translatable.process, translatable) } + + scenario "Adds a translation for that locale" do + visit path + + select "Português brasileiro", from: :add_language + fill_in "Question", with: "Português" + click_button "Save changes" + + visit path + select "Português brasileiro", from: "locale-switcher" + + expect(page).to have_field "Questão", with: "Português" + end end end - let(:required_fields) do - fields - optional_fields - end + context "Add an invalid translation", :js do + let(:translatable) { create(:budget_investment) } - let(:user) { create(:administrator).user } - let(:translatable) do - if factory_name == "budget_phase" - budget = create(:budget) - budget.phases.last.update attributes - budget.phases.last - else - create(factory_name, attributes) + context "Input field" do + let(:translatable) { create(:budget) } + + scenario "Shows validation erros" do + visit edit_admin_budget_path(translatable) + + select "Français", from: :add_language + fill_in "Name", with: "" + click_button "Update Budget" + + expect(page).to have_css "#error_explanation" + + select "Français", from: :select_language + + expect(page).to have_field "Name", with: "", class: "error" + end end - end - let(:path) { send(path_name, *resource_hierarchy_for(translatable)) } - before do - login_as(user) + context "CKEditor field" do + let(:translatable) { create(:budget_investment) } - if front_end_path_to_visit?(path_name) - Setting["feature.translation_interface"] = true - translatable.update(author: user) if translatable.respond_to?(:author) + scenario "Shows validation errors" do + visit edit_admin_budget_budget_investment_path(translatable.budget, translatable) + + select "Français", from: :add_language + fill_in "Title", with: "Titre en Français" + fill_in_ckeditor "Description", with: "" + click_button "Update" + + expect(page).to have_css "#error_explanation" + + select "Français", from: :select_language + + within_frame(0) { expect(page.text).to be_empty } + end + end + + context "Markdownit field" do + let(:translatable) { create(:legislation_draft_version) } + + scenario "Shows validation errors" do + visit edit_admin_legislation_process_draft_version_path(translatable.process, translatable) + + select "Français", from: :add_language + fill_in "Version title", with: "Titre en Français" + click_link class: "fullscreen-toggle" + fill_in "Text", with: "" + click_link class: "fullscreen-toggle" + click_button "Save changes" + + expect(page).to have_css "#error_explanation" + + select "Français", from: :select_language + click_link class: "fullscreen-toggle" + + expect(page).to have_field "Text", with: "", class: "error" + end end end - context "Manage translations" do + context "Update a translation", :js do + context "Input fields" do + let(:translatable) { create(:widget_card) } + let(:path) { edit_admin_widget_card_path(translatable) } + + scenario "Changes the existing translation" do + visit path + + select "Español", from: :select_language + + within(".translatable-fields") do + fill_in "Title", with: "Título corregido" + fill_in "Description", with: "Descripción corregida" + fill_in "Link text", with: "Texto del enlace corregido" + fill_in "Label (optional)", with: "Etiqueta corregida" + end + + click_button "Save card" + + visit path + + expect(page).to have_field "Title", with: "Title in English" + + select("Español", from: "locale-switcher") + + expect(page).to have_field "Título", with: "Título corregido" + expect(page).to have_field "Descripción", with: "Descripción corregida" + expect(page).to have_field "Texto del enlace", with: "Texto del enlace corregido" + expect(page).to have_field "Etiqueta (opcional)", with: "Etiqueta corregida" + end + end + + context "CKEditor fields" do + let(:translatable) { create(:poll_question_answer) } + let(:path) { edit_admin_answer_path(translatable) } + + scenario "Changes the existing translation" do + visit path + + select "Español", from: :select_language + + within(".translatable-fields") do + fill_in "Answer", with: "Respuesta corregida" + fill_in_ckeditor "Description", with: "Descripción corregida" + end + + click_button "Save" + + visit path + + expect(page).to have_field "Answer", with: "Answer in English" + + select("Español", from: "locale-switcher") + + expect(page).to have_field "Respuesta", with: "Respuesta corregida" + within_frame(0) { expect(page).to have_content "Descripción corregida" } + end + end + + context "Change value of a translated field to blank", :js do + let(:translatable) { create(:poll) } + let(:path) { edit_admin_poll_path(translatable) } + + scenario "Updates the field to a blank value" do + visit path + + expect(page).to have_field "Summary", with: "Summary in English" + + fill_in "Summary", with: "" + click_button "Update poll" + + visit path + + expect(page).to have_field "Summary", with: "" + end + end + end + + context "Update a translation with invalid data", :js do + context "Input fields" do + let(:translatable) { create(:banner) } + + scenario "Show validation errors" do + visit edit_admin_banner_path(translatable) + select "Español", from: :select_language + + expect(page).to have_field "Title", with: "Title en español" + + fill_in "Title", with: "" + click_button "Save changes" + + expect(page).to have_css "#error_explanation" + + select "Español", from: :select_language + + expect(page).to have_field "Title", with: "", class: "error" + end + end + + context "Markdownit field" do + let(:translatable) { create(:legislation_draft_version) } + + scenario "Shows validation errors" do + visit edit_admin_legislation_process_draft_version_path(translatable.process, translatable) + + select "Español", from: :select_language + click_link class: "fullscreen-toggle" + + expect(page).to have_field "Text", with: "Texto en español" + + fill_in "Text", with: "" + click_link class: "fullscreen-toggle" + click_button "Save changes" + + expect(page).to have_css "#error_explanation" + + select "Español", from: :select_language + click_link class: "fullscreen-toggle" + + expect(page).to have_field "Text", with: "" + end + end + end + + context "Update a translation not having the current locale", :js do + let(:translatable) { create(:legislation_process) } + before do - if translatable_class.name == "I18nContent" - skip "Translation handling is different for site customizations" - end - end - - describe "Should show first available fallback when current locale translation does not exist" do - - scenario "For all translatable except ActivePoll and Budget::Phase", :js do - if translatable_class.name == "ActivePoll" || translatable_class.name == "Budget::Phase" - skip("Skip because after updating it doesn't render the description") - end - attributes = fields.product(%i[fr]).map do |field, locale| - [:"#{field}_#{locale}", text_for(field, locale)] - end.to_h - translatable.update(attributes) - visit path - - select "English", from: :select_language - click_link "Remove language" - select "Español", from: :select_language - click_link "Remove language" - click_button update_button_text - - expect(page).to have_content "en Français" - end - - scenario "For Budget::Phase", :js do - if translatable_class.name != "Budget::Phase" - skip("Skip because force visit budgets_path after update") - end - attributes = fields.product(%i[fr]).map do |field, locale| - [:"#{field}_#{locale}", text_for(field, locale)] - end.to_h - translatable.update(attributes) - visit path - - select "English", from: :select_language - click_link "Remove language" - select "Español", from: :select_language - click_link "Remove language" - click_button update_button_text - visit budgets_path - - expect(page).to have_content "en Français" - end - - scenario "For ActivePoll", :js do - if translatable_class.name != "ActivePoll" - skip("Skip because force visit polls_path after update") - end - attributes = fields.product(%i[fr]).map do |field, locale| - [:"#{field}_#{locale}", text_for(field, locale)] - end.to_h - translatable.update(attributes) - visit path - - select "English", from: :select_language - click_link "Remove language" - select "Español", from: :select_language - click_link "Remove language" - click_button update_button_text - visit polls_path - - expect(page).to have_content "en Français" - end - - end - - scenario "Add a translation", :js do - visit path - - select "Français", from: :add_language - fields.each { |field| fill_in_field field, :fr, with: text_for(field, :fr) } - click_button update_button_text - - visit path - field = fields.sample - - expect_page_to_have_translatable_field field, :en, with: text_for(field, :en) - - select "Español", from: :select_language - expect_page_to_have_translatable_field field, :es, with: text_for(field, :es) - - select "Français", from: :select_language - expect_page_to_have_translatable_field field, :fr, with: text_for(field, :fr) - end - - scenario "Add an invalid translation", :js do - skip("can't have invalid translations") if required_fields.empty? - - field = required_fields.sample - - visit path - - select "Français", from: :add_language - fill_in_field field, :fr, with: "" - click_button update_button_text - - expect(page).to have_css "#error_explanation" - - select "Français", from: :select_language - - expect_page_to_have_translatable_field field, :fr, with: "" - end - - scenario "Update a translation", :js do - visit path - - select "Español", from: :select_language - field = fields.sample - updated_text = "Corrección de #{text_for(field, :es)}" - - fill_in_field field, :es, with: updated_text - - click_button update_button_text - - visit path - - expect_page_to_have_translatable_field field, :en, with: text_for(field, :en) - - select("Español", from: "locale-switcher") - - expect_page_to_have_translatable_field field, :es, with: updated_text - end - - scenario "Update a translation with invalid data", :js do - skip("can't have invalid translations") if required_fields.empty? - - field = required_fields.sample - - visit path - select "Español", from: :select_language - - expect_page_to_have_translatable_field field, :es, with: text_for(field, :es) - - fill_in_field field, :es, with: "" - click_button update_button_text - - expect(page).to have_css "#error_explanation" - - select "Español", from: :select_language - - expect_page_to_have_translatable_field field, :es, with: "" - end - - scenario "Update a translation not having the current locale", :js do translatable.translations.destroy_all - translatable.translations.create( - fields.map { |field| [field, text_for(field, :fr)] }.to_h.merge(locale: :fr) - ) + translatable.translations.create(locale: :fr, title: "Titre en Français") + end - visit path + scenario "Does not add a translation for the current locale" do + visit edit_admin_legislation_process_path(translatable) expect_to_have_language_selected "Français" expect_not_to_have_language "English" - click_button update_button_text + click_button "Save changes" expect(page).not_to have_css "#error_explanation" - path = updated_path_for(translatable) - visit path + visit edit_admin_legislation_process_path(translatable.reload) expect_to_have_language_selected "Français" expect_not_to_have_language "English" end + end - scenario "Remove a translation", :js do + context "Remove a translation", :js do + let(:translatable) { create(:budget_group) } + let(:path) { edit_admin_budget_group_path(translatable.budget, translatable) } + + scenario "Keeps the other languages" do visit path select "Español", from: :select_language click_link "Remove language" - expect_not_to_have_language "Español" + expect(page).not_to have_select :select_language, with_options: ["Español"] - click_button update_button_text + click_button "Save group" visit path - expect_not_to_have_language "Español" + + expect(page).not_to have_select :select_language, with_options: ["Español"] + expect(page).to have_select :select_language, with_options: ["English"] end + end - scenario "Remove all translations should show an error message", :js do - skip("can't have invalid translations") if required_fields.empty? + context "Remove all translations", :js do + let(:translatable) { create(:milestone) } - visit path + scenario "Shows an error message" do + visit edit_tracking_budget_budget_investment_milestone_path(*resource_hierarchy_for(translatable)) click_link "Remove language" click_link "Remove language" - click_button update_button_text + click_button "Update milestone" expect(page).to have_content "Is mandatory to provide one translation at least" end + end - scenario "Remove a translation with invalid data", :js do - skip("can't have invalid translations") if required_fields.empty? - - field = required_fields.sample + context "Remove a translation with invalid data", :js do + let(:translatable) { create(:poll_question) } + let(:path) { edit_admin_question_path(translatable) } + scenario "Doesn't remove the translation" do visit path select "Español", from: :select_language click_link "Remove language" select "English", from: :select_language - fill_in_field field, :en, with: "" - click_button update_button_text + fill_in "Question", with: "" + click_button "Save" expect(page).to have_css "#error_explanation" - expect_page_to_have_translatable_field field, :en, with: "" + expect(page).to have_field "Question", with: "", class: "error" expect_to_have_language_selected "English" expect_not_to_have_language "Español" visit path select "Español", from: :select_language - expect_page_to_have_translatable_field field, :es, with: text_for(field, :es) - end - - scenario "Change value of a translated field to blank", :js do - skip("can't have translatable blank fields") if optional_fields.empty? - - field = optional_fields.sample - - visit path - expect_page_to_have_translatable_field field, :en, with: text_for(field, :en) - - fill_in_field field, :en, with: "" - click_button update_button_text - - visit path - expect_page_to_have_translatable_field field, :en, with: "" - end - - scenario "Add a translation for a locale with non-underscored name", :js do - visit path - - select "Português brasileiro", from: :add_language - fields.each { |field| fill_in_field field, :"pt-BR", with: text_for(field, :"pt-BR") } - click_button update_button_text - - visit path - - select("Português brasileiro", from: "locale-switcher") - - field = fields.sample - expect_page_to_have_translatable_field field, :"pt-BR", with: text_for(field, :"pt-BR") + expect(page).to have_field "Question", with: "Pregunta en español" end end - context "Globalize javascript interface" do - scenario "Select current locale when its translation exists", :js do + context "Current locale translation does not exist", :js do + context "For all translatable except ActivePoll and Budget::Phase" do + let(:translatable) { create(:admin_notification, segment_recipient: "all_users") } + + scenario "Shows first available fallback" do + translatable.update({ title_fr: "Titre en Français", body_fr: "Texte en Français" }) + + visit edit_admin_admin_notification_path(translatable) + + select "English", from: :select_language + click_link "Remove language" + select "Español", from: :select_language + click_link "Remove language" + + click_button "Update notification" + + expect(page).to have_content "Titre en Français" + end + end + + context "For Budget::Phase" do + let(:translatable) { create(:budget).phases.last } + + scenario "Shows first available fallback" do + translatable.update({ description_fr: "Phase en Français", summary_fr: "Phase résumé" }) + + visit edit_admin_budget_budget_phase_path(translatable.budget, translatable) + + select "English", from: :select_language + click_link "Remove language" + select "Español", from: :select_language + click_link "Remove language" + + click_button "Save changes" + + visit budgets_path + + expect(page).to have_content "Phase résumé" + end + end + + context "For ActivePoll" do + let(:translatable) { create(:active_poll) } + + scenario "Shows first available fallback" do + translatable.update({ description_fr: "Sondage en Français" }) + + visit edit_admin_active_polls_path(translatable) + + select "English", from: :select_language + click_link "Remove language" + select "Español", from: :select_language + click_link "Remove language" + click_button "Save" + + visit polls_path + + expect(page).to have_content "Sondage en Français" + end + end + end + + context "Globalize javascript interface", :js do + let(:translatable) { create(:i18n_content) } + let(:content) { translatable } + let(:path) { admin_site_customization_information_texts_path } + + scenario "Select current locale when its translation exists" do visit path expect_to_have_language_selected "English" @@ -316,32 +470,30 @@ shared_examples "edit_translatable" do |factory_name, path_name, input_fields, t expect_to_have_language_selected "Español" end - scenario "Select first locale of existing translations when current locale translation - does not exists", :js do - translatable.translations.where(locale: :en).destroy_all + scenario "Select first locale of existing translations when current locale translation does not exists" do + content.translations.where(locale: :en).destroy_all visit path expect_to_have_language_selected "Español" end - scenario "Show selected locale form", :js do + scenario "Show selected locale form" do visit path - field = fields.sample - expect_page_to_have_translatable_field field, :en, with: text_for(field, :en) + expect(page).to have_field "contents_content_#{content.key}values_value_en", with: "Value in English" select "Español", from: :select_language - expect_page_to_have_translatable_field field, :es, with: text_for(field, :es) + expect(page).to have_field "contents_content_#{content.key}values_value_es", with: "Value en español" end - scenario "Select a locale and add it to the form", :js do + scenario "Select a locale and add it to the form" do visit path select "Français", from: :add_language expect_to_have_language_selected "Français" - expect_page_to_have_translatable_field fields.sample, :fr, with: "" + expect(page).to have_field "contents_content_#{content.key}values_value_fr" end context "Languages in use" do @@ -351,7 +503,7 @@ shared_examples "edit_translatable" do |factory_name, path_name, input_fields, t expect(page).to have_content "2 languages in use" end - scenario "Increase description count after add new language", :js do + scenario "Increase description count after add new language" do visit path select "Français", from: :add_language @@ -359,7 +511,7 @@ shared_examples "edit_translatable" do |factory_name, path_name, input_fields, t expect(page).to have_content "3 languages in use" end - scenario "Decrease description count after remove a language", :js do + scenario "Decrease description count after remove a language" do visit path click_link "Remove language" @@ -369,82 +521,19 @@ shared_examples "edit_translatable" do |factory_name, path_name, input_fields, t end context "When translation interface feature setting" do - describe "At frontend" do - before do - unless front_end_path_to_visit?(path_name) - skip "When path is from backend" - end - end + scenario "Is enabled translation interface should be rendered" do + visit path - scenario "Is enabled translation interface should be rendered" do - visit path - - expect(page).to have_css ".globalize-languages" - end - - scenario "Is disabled translation interface should not be rendered" do - Setting["feature.translation_interface"] = nil - - visit path - - expect(page).not_to have_css ".globalize-languages" - end + expect(page).to have_css ".globalize-languages" end - describe "At backend" do - before do - if front_end_path_to_visit?(path_name) - skip "When path is from frontend" - end - end + scenario "Is disabled translation interface should be rendered" do + Setting["feature.translation_interface"] = nil - scenario "Is enabled translation interface should be rendered" do - visit path + visit path - expect(page).to have_css ".globalize-languages" - end - - scenario "Is disabled translation interface should be rendered" do - Setting["feature.translation_interface"] = nil - - visit path - - expect(page).to have_css ".globalize-languages" - end + expect(page).to have_css ".globalize-languages" end end end end - -def updated_path_for(resource) - send(path_name, *resource_hierarchy_for(resource.reload)) -end - -# FIXME: button texts should be consistent. Right now, buttons don't -# even share the same colour. -def update_button_text - case translatable_class.name - when "Milestone" - "Update milestone" - when "AdminNotification" - "Update notification" - when "Budget::Investment" - "Update" - when "Poll" - "Update poll" - when "Budget" - "Update Budget" - when "Poll::Question", "Poll::Question::Answer", "ActivePoll" - "Save" - when "SiteCustomization::Page" - "Update Custom page" - when "Widget::Card" - "Save card" - when "Budget::Group" - "Save group" - when "Budget::Heading" - "Save heading" - else - "Save changes" - end -end diff --git a/spec/features/admin/widgets/cards_spec.rb b/spec/features/admin/widgets/cards_spec.rb index fed8e88a8..bed7e28ef 100644 --- a/spec/features/admin/widgets/cards_spec.rb +++ b/spec/features/admin/widgets/cards_spec.rb @@ -7,11 +7,6 @@ describe "Cards" do login_as(admin) end - it_behaves_like "edit_translatable", - "widget_card", - "edit_admin_widget_card_path", - %w[title description link_text label] - scenario "Create", :js do visit admin_homepage_path click_link "Create card" diff --git a/spec/features/debates_spec.rb b/spec/features/debates_spec.rb index 9988e872b..421e7021c 100644 --- a/spec/features/debates_spec.rb +++ b/spec/features/debates_spec.rb @@ -16,11 +16,6 @@ describe "Debates" do "new_debate_path", %w[title], { "description" => :ckeditor } - it_behaves_like "edit_translatable", - "debate", - "edit_debate_path", - %w[title], - { "description" => :ckeditor } it_behaves_like "remotely_translatable", :debate, "debates_path", diff --git a/spec/features/proposals_spec.rb b/spec/features/proposals_spec.rb index 22e702204..9ac439d19 100644 --- a/spec/features/proposals_spec.rb +++ b/spec/features/proposals_spec.rb @@ -20,11 +20,6 @@ describe "Proposals" do "new_proposal_path", %w[title summary], { "description" => :ckeditor } - it_behaves_like "edit_translatable", - "proposal", - "edit_proposal_path", - %w[title summary], - { "description" => :ckeditor } it_behaves_like "remotely_translatable", :proposal, "proposals_path", diff --git a/spec/support/common_actions/translations.rb b/spec/support/common_actions/translations.rb index 949dc5ada..09795fcbc 100644 --- a/spec/support/common_actions/translations.rb +++ b/spec/support/common_actions/translations.rb @@ -1,70 +1,10 @@ module Translations def text_for(field, locale) I18n.with_locale(locale) do - "#{translatable_class.human_attribute_name(field)} #{language_texts[locale]}" + "#{translatable.class.human_attribute_name(field)} #{language_texts[locale]}" end end - def field_for(field, locale, visible: true) - if translatable_class.name == "I18nContent" - "contents_content_#{translatable.key}values_#{field}_#{locale}" - else - within(".translatable-fields[data-locale='#{locale}']") do - find("input[id$='_#{field}'], textarea[id$='_#{field}']", visible: visible)[:id] - end - end - end - - def fill_in_field(field, locale, with:) - if input_fields.include?(field) - fill_in field_for(field, locale), with: with - else - fill_in_textarea(field, textarea_fields[field], locale, with: with) - end - end - - def fill_in_textarea(field, textarea_type, locale, with:) - if textarea_type == :markdownit - click_link class: "fullscreen-toggle" - fill_in field_for(field, locale), with: with - click_link class: "fullscreen-toggle" - elsif textarea_type == :ckeditor - fill_in_ckeditor field_for(field, locale, visible: false), with: with - end - end - - def expect_page_to_have_translatable_field(field, locale, with:) - if input_fields.include?(field) - if translatable_class.name == "I18nContent" && with.blank? - expect(page).to have_field field_for(field, locale) - else - expect(page).to have_field field_for(field, locale), with: with - end - else - textarea_type = textarea_fields[field] - - if textarea_type == :markdownit - click_link class: "fullscreen-toggle" - expect(page).to have_field field_for(field, locale), with: with - click_link class: "fullscreen-toggle" - elsif textarea_type == :ckeditor - within("div.js-globalize-attribute[data-locale='#{locale}'] .ckeditor [id$='#{field}']") do - # Wait longer for iframe initialization - expect(page).to have_selector "iframe.cke_wysiwyg_frame", wait: 5 - within_frame(textarea_fields.keys.index(field)) { expect(page).to have_content with } - end - end - end - end - - def front_end_path_to_visit?(path) - path[/admin|managment|valuation|tracking/].blank? - end - - def expect_to_have_language(language) - expect(page).to have_select :select_language, with_options: [language] - end - def expect_not_to_have_language(language) expect(page).not_to have_select :select_language, with_options: [language] end @@ -72,4 +12,11 @@ module Translations def expect_to_have_language_selected(language) expect(page).to have_select :select_language, selected: language end + + def language_texts + { + es: "en español", + en: "in English" + } + end end