mirror of
https://gh.wpcy.net/https://github.com/discourse/discourse.git
synced 2026-05-05 02:11:15 +08:00
When content localization is enabled, we show a button in the toolbar to set your post language. The current position stands out quite a lot and can get in the way on smaller screens. This PR accomplishes two things: 1. Moves the button to the toolbar, which is a more stable and less in-the-way position 2. De-prioritizes the button on new post creation when AI translations are enabled, as language is auto-detected most of the time. A new value transformer is added `"post-language-selector-priority"` to allow the AI plugin to change the priority of the button, and support for a header has been added to `toolbar-popup-menu-options` <img width="400" alt="image" src="https://github.com/user-attachments/assets/5ca7a45f-d6cc-49ac-9334-3a8613622e10" /> <img width="600" alt="image" src="https://github.com/user-attachments/assets/7393439c-3086-4fd0-bac7-74ed4a59074f" />
315 lines
13 KiB
Ruby
315 lines
13 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
describe "Post translations" do
|
|
POST_LANGUAGE_SWITCHER_SELECTOR = ".d-editor-button-bar .post-language-selector-trigger"
|
|
|
|
fab!(:admin)
|
|
fab!(:topic)
|
|
fab!(:post) { Fabricate(:post, topic:) }
|
|
let(:topic_page) { PageObjects::Pages::Topic.new }
|
|
let(:composer) { PageObjects::Components::Composer.new }
|
|
let(:translation_selector) do
|
|
PageObjects::Components::SelectKit.new(".translation-selector-dropdown")
|
|
end
|
|
let(:post_language_selector) do
|
|
PageObjects::Components::DMenu.new(
|
|
POST_LANGUAGE_SWITCHER_SELECTOR,
|
|
"toolbar-menu__post-language-selector-trigger",
|
|
)
|
|
end
|
|
let(:view_translations_modal) { PageObjects::Modals::ViewTranslationsModal.new }
|
|
|
|
before do
|
|
SiteSetting.default_locale = "en"
|
|
SiteSetting.content_localization_supported_locales = "fr|es|pt_BR"
|
|
SiteSetting.post_menu =
|
|
"read|like|copyLink|flag|edit|bookmark|delete|admin|reply|addTranslation"
|
|
SiteSetting.post_menu_hidden_items = "flag|bookmark|edit|addTranslation|delete|admin"
|
|
SiteSetting.content_localization_enabled = true
|
|
sign_in(admin)
|
|
end
|
|
|
|
context "when a post does not have translations" do
|
|
it "should only show the languages listed in the site setting" do
|
|
post.update!(locale: "en")
|
|
|
|
topic_page.visit_topic(topic)
|
|
|
|
topic_page.click_post_action_button(post, :show_more)
|
|
topic_page.click_post_action_button(post, :add_translation)
|
|
find(".update-translations-menu__add .post-action-menu__add-translation").click
|
|
translation_selector.expand
|
|
expect(all(".translation-selector-dropdown .select-kit-collection li").count).to eq(3)
|
|
expect(translation_selector).to have_option_value("fr")
|
|
expect(translation_selector).to have_option_value("es")
|
|
expect(translation_selector).to have_option_value("pt_BR")
|
|
expect(translation_selector).to have_no_option_value("de")
|
|
end
|
|
|
|
it "allows a user to translate a post" do
|
|
topic_page.visit_topic(topic)
|
|
topic_page.click_post_action_button(post, :show_more)
|
|
topic_page.click_post_action_button(post, :add_translation)
|
|
find(".update-translations-menu__add .post-action-menu__add-translation").click
|
|
expect(composer).to be_opened
|
|
translation_selector.expand
|
|
translation_selector.select_row_by_value("fr")
|
|
find("#translated-topic-title").fill_in(with: "Ceci est un sujet de test 0")
|
|
composer.fill_content("Bonjour le monde")
|
|
composer.submit
|
|
|
|
expect(TopicLocalization.exists?(topic_id: topic.id, locale: "fr")).to be true
|
|
expect(PostLocalization.exists?(post_id: post.id, locale: "fr")).to be true
|
|
expect(PostLocalization.find_by(post_id: post.id, locale: "fr").raw).to eq("Bonjour le monde")
|
|
expect(TopicLocalization.find_by(topic_id: topic.id, locale: "fr").title).to eq(
|
|
"Ceci est un sujet de test 0",
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when a post already has translations" do
|
|
fab!(:post_localization) do
|
|
Fabricate(:post_localization, post: post, locale: "fr", raw: "Bonjour le monde")
|
|
end
|
|
let(:confirmation_dialog) { PageObjects::Components::Dialog.new }
|
|
|
|
it "allows a user to add a new translation" do
|
|
topic_page.visit_topic(topic)
|
|
topic_page.click_post_action_button(post, :show_more)
|
|
topic_page.click_post_action_button(post, :add_translation)
|
|
find(".update-translations-menu__add .post-action-menu__add-translation").click
|
|
expect(composer).to be_opened
|
|
translation_selector.expand
|
|
translation_selector.select_row_by_value("es")
|
|
find("#translated-topic-title").fill_in(with: "Este es un tema de prueba 0")
|
|
composer.fill_content("Hola mundo")
|
|
composer.submit
|
|
|
|
expect(TopicLocalization.exists?(topic_id: topic.id, locale: "es")).to be true
|
|
expect(PostLocalization.exists?(post_id: post.id, locale: "es")).to be true
|
|
expect(PostLocalization.find_by(post_id: post.id, locale: "es").raw).to eq("Hola mundo")
|
|
expect(TopicLocalization.find_by(topic_id: topic.id, locale: "es").title).to eq(
|
|
"Este es un tema de prueba 0",
|
|
)
|
|
end
|
|
|
|
it "allows a user to see locales translated" do
|
|
topic_page.visit_topic(topic)
|
|
topic_page.click_post_action_button(post, :show_more)
|
|
topic_page.click_post_action_button(post, :add_translation)
|
|
view_translation_button = find(".post-action-menu__view-translation")
|
|
expect(view_translation_button).to be_visible
|
|
expect(view_translation_button).to have_text(
|
|
I18n.t("js.post.localizations.view", { count: 1 }),
|
|
)
|
|
|
|
view_translation_button.click
|
|
expect(view_translations_modal).to be_open
|
|
expect(find(".post-translations-modal__locale")).to have_text("fr")
|
|
end
|
|
|
|
it "allows a user to edit a translation" do
|
|
topic_page.visit_topic(topic)
|
|
topic_page.click_post_action_button(post, :show_more)
|
|
topic_page.click_post_action_button(post, :add_translation)
|
|
find(".post-action-menu__view-translation").click
|
|
find(".post-translations-modal__edit-action .btn").click
|
|
expect(composer).to be_opened
|
|
expect(translation_selector).to have_selected_value("fr")
|
|
find("#translated-topic-title").fill_in(with: "C'est un sujet de test 0.")
|
|
composer.fill_content("Bonjour le monde")
|
|
composer.submit
|
|
|
|
expect(TopicLocalization.exists?(topic_id: topic.id, locale: "fr")).to be true
|
|
expect(PostLocalization.exists?(post_id: post.id, locale: "fr")).to be true
|
|
expect(PostLocalization.find_by(post_id: post.id, locale: "fr").raw).to eq("Bonjour le monde")
|
|
expect(TopicLocalization.find_by(topic_id: topic.id, locale: "fr").title).to eq(
|
|
"C'est un sujet de test 0.",
|
|
)
|
|
end
|
|
|
|
it "allows a user in content_localization_allowed_groups to delete a translation" do
|
|
topic_page.visit_topic(topic)
|
|
expect(PostLocalization.exists?(post_id: post.id, locale: "fr")).to be true
|
|
|
|
topic_page.click_post_action_button(post, :show_more)
|
|
topic_page.click_post_action_button(post, :add_translation)
|
|
find(".update-translations-menu__add .post-action-menu__add-translation").click
|
|
find(".post-action-menu__view-translation").click
|
|
find(".post-translations-modal__delete-action .btn").click
|
|
expect(confirmation_dialog).to be_open
|
|
confirmation_dialog.click_yes
|
|
|
|
expect(PostLocalization.exists?(post_id: post.id, locale: "fr")).to be false
|
|
end
|
|
|
|
it "prompts to discard changes when abandoning modified translation" do
|
|
discard_modal = PageObjects::Modals::DiscardDraft.new
|
|
|
|
topic_page.visit_topic(topic)
|
|
topic_page.click_post_action_button(post, :show_more)
|
|
topic_page.click_post_action_button(post, :add_translation)
|
|
find(".update-translations-menu__add .post-action-menu__add-translation").click
|
|
expect(composer).to be_opened
|
|
|
|
translation_selector.expand
|
|
translation_selector.select_row_by_value("fr")
|
|
|
|
composer.fill_content("Salut le monde")
|
|
composer.minimize
|
|
expect(composer).to be_minimized
|
|
|
|
find("#post_#{post.post_number} .post-action-menu__reply").click
|
|
|
|
expect(discard_modal).to be_open
|
|
end
|
|
|
|
it "auto-closes when abandoning unchanged translation" do
|
|
discard_modal = PageObjects::Modals::DiscardDraft.new
|
|
|
|
topic_page.visit_topic(topic)
|
|
topic_page.click_post_action_button(post, :show_more)
|
|
topic_page.click_post_action_button(post, :add_translation)
|
|
find(".update-translations-menu__add .post-action-menu__add-translation").click
|
|
expect(composer).to be_opened
|
|
|
|
translation_selector.expand
|
|
translation_selector.select_row_by_value("fr")
|
|
|
|
composer.minimize
|
|
expect(composer).to be_minimized
|
|
|
|
find("#post_#{post.post_number} .post-action-menu__reply").click
|
|
|
|
expect(discard_modal).to be_closed
|
|
expect(composer).to be_opened
|
|
end
|
|
end
|
|
|
|
context "when creating a new post in a different locale" do
|
|
it "should only show the languages listed in the site setting and default locale and a none value" do
|
|
visit("/latest")
|
|
page.find("#create-topic").click
|
|
post_language_selector.expand
|
|
expect(post_language_selector).to have_content("English") # default locale
|
|
expect(post_language_selector).to have_content("French (Français)")
|
|
expect(post_language_selector).to have_content("Spanish (Español)")
|
|
expect(post_language_selector).to have_content("Portuguese (Português (BR))")
|
|
expect(post_language_selector).to have_content(
|
|
I18n.t("js.post.localizations.post_language_selector.none"),
|
|
)
|
|
end
|
|
|
|
it "should allow a user to create a post in a different locale" do
|
|
visit("/latest")
|
|
page.find("#create-topic").click
|
|
post_language_selector.expand
|
|
post_language_selector.option("[data-name='fr']").click
|
|
composer.fill_title("Ceci est un sujet de test 1")
|
|
composer.fill_content("Bonjour le monde")
|
|
composer.submit
|
|
|
|
updated_post = Topic.last.posts.first
|
|
expect(updated_post.locale).to eq("fr")
|
|
end
|
|
|
|
it "should not have a locale set by default" do
|
|
visit("/latest")
|
|
page.find("#create-topic").click
|
|
expect(
|
|
page.has_no_css?(
|
|
"#{POST_LANGUAGE_SWITCHER_SELECTOR} .toolbar-popup-menu-options__trigger-label",
|
|
),
|
|
).to be true
|
|
end
|
|
end
|
|
|
|
context "when viewing raw markdown in translation editor" do
|
|
fab!(:markdown_post) do
|
|
Fabricate(
|
|
:post,
|
|
topic: topic,
|
|
raw: "# Heading\n\n**Bold** text with [link](https://example.com) and *italic*",
|
|
)
|
|
end
|
|
let(:translation_preview) { PageObjects::Components::DEditorOriginalTranslationPreview.new }
|
|
|
|
it "shows raw markdown toggle only on Original tab" do
|
|
topic_page.visit_topic(topic)
|
|
topic_page.click_post_action_button(post, :show_more)
|
|
topic_page.click_post_action_button(post, :add_translation)
|
|
find(".update-translations-menu__add .post-action-menu__add-translation").click
|
|
|
|
expect(composer).to be_opened
|
|
expect(translation_preview).to have_raw_toggle
|
|
expect(translation_preview.original_tab_active?).to be true
|
|
|
|
translation_preview.click_translation_tab
|
|
expect(translation_preview.translation_tab_active?).to be true
|
|
expect(translation_preview).to have_no_raw_toggle
|
|
end
|
|
|
|
it "displays rendered HTML by default" do
|
|
topic_page.visit_topic(topic)
|
|
topic_page.click_post_action_button(post, :show_more)
|
|
topic_page.click_post_action_button(post, :add_translation)
|
|
find(".update-translations-menu__add .post-action-menu__add-translation").click
|
|
|
|
expect(composer).to be_opened
|
|
expect(translation_preview.original_tab_active?).to be true
|
|
expect(translation_preview).to have_rendered_content
|
|
expect(translation_preview).to have_no_raw_markdown_content
|
|
end
|
|
|
|
it "displays raw markdown when toggle is enabled" do
|
|
topic_page.visit_topic(topic)
|
|
topic_page.click_post_action_button(markdown_post.post_number, :show_more)
|
|
topic_page.click_post_action_button(markdown_post.post_number, :add_translation)
|
|
find(".update-translations-menu__add .post-action-menu__add-translation").click
|
|
|
|
expect(composer).to be_opened
|
|
translation_preview.raw_toggle.toggle
|
|
|
|
expect(translation_preview).to have_raw_markdown_content
|
|
raw_content = translation_preview.raw_markdown_content
|
|
expect(raw_content).to include("# Heading")
|
|
expect(raw_content).to include("**Bold**")
|
|
expect(raw_content).to include("[link](https://example.com)")
|
|
expect(raw_content).to include("*italic*")
|
|
end
|
|
|
|
it "resets raw markdown view when switching tabs" do
|
|
topic_page.visit_topic(topic)
|
|
topic_page.click_post_action_button(post, :show_more)
|
|
topic_page.click_post_action_button(post, :add_translation)
|
|
find(".update-translations-menu__add .post-action-menu__add-translation").click
|
|
|
|
expect(composer).to be_opened
|
|
translation_preview.raw_toggle.toggle
|
|
expect(translation_preview).to have_raw_markdown_content
|
|
|
|
translation_preview.click_translation_tab
|
|
expect(translation_preview).to have_no_raw_toggle
|
|
|
|
translation_preview.click_original_tab
|
|
expect(translation_preview).to have_raw_toggle
|
|
expect(translation_preview.raw_toggle).to be_unchecked
|
|
expect(translation_preview).to have_rendered_content
|
|
end
|
|
|
|
it "maintains raw markdown state while on Original tab" do
|
|
topic_page.visit_topic(topic)
|
|
topic_page.click_post_action_button(post, :show_more)
|
|
topic_page.click_post_action_button(post, :add_translation)
|
|
find(".update-translations-menu__add .post-action-menu__add-translation").click
|
|
|
|
expect(composer).to be_opened
|
|
translation_preview.raw_toggle.toggle
|
|
expect(translation_preview).to have_raw_markdown_content
|
|
|
|
translation_preview.raw_toggle.toggle
|
|
expect(translation_preview).to have_no_raw_markdown_content
|
|
expect(translation_preview).to have_rendered_content
|
|
end
|
|
end
|
|
end
|