mirror of
https://github.com/discourse/discourse.git
synced 2026-08-07 13:19:19 +08:00
Related: https://meta.discourse.org/t/manual-localization-doesnt-seem-to-be-working/407319 Users have gotten tripped over and over again when manually inserting translations for posts, not knowing they need to set the post language first before the translation is shown (explained [here](https://meta.discourse.org/t/manual-localization-doesnt-seem-to-be-working/407319/7?u=nat)). This PR adds the ability to allow the user to set the post language in the modal when they are working with translations, highlighting the fact that they need to set the post language before translations can be shown
333 lines
10 KiB
Ruby
Vendored
333 lines
10 KiB
Ruby
Vendored
# frozen_string_literal: true
|
|
|
|
describe PostLocalizationsController do
|
|
fab!(:user)
|
|
fab!(:group)
|
|
fab!(:post_record) { Fabricate(:post, version: 100) }
|
|
|
|
let(:locale) { "ja" }
|
|
let(:raw) { "これは翻訳です。" }
|
|
|
|
before do
|
|
SiteSetting.content_localization_enabled = true
|
|
SiteSetting.content_localization_supported_locales = "ja"
|
|
SiteSetting.content_localization_allowed_groups = group.id.to_s
|
|
group.add(user)
|
|
sign_in(user)
|
|
end
|
|
|
|
describe "#show" do
|
|
it "allows users in allowed groups to view localizations" do
|
|
Fabricate(:post_localization, post: post_record, locale:)
|
|
|
|
get "/post_localizations/#{post_record.id}.json"
|
|
|
|
expect(response.status).to eq(200)
|
|
json = response.parsed_body
|
|
expect(json["post_localizations"].length).to eq(1)
|
|
end
|
|
|
|
it "denies users not in allowed groups" do
|
|
group.remove(user)
|
|
|
|
get "/post_localizations/#{post_record.id}.json"
|
|
|
|
expect(response.status).to eq(403)
|
|
end
|
|
|
|
context "with author localization enabled" do
|
|
fab!(:author, :user)
|
|
fab!(:author_post) { Fabricate(:post, user: author) }
|
|
|
|
before do
|
|
SiteSetting.content_localization_allow_author_localization = true
|
|
group.remove(author)
|
|
end
|
|
|
|
it "allows post authors to view localizations for their own posts" do
|
|
Fabricate(:post_localization, post: author_post, locale:)
|
|
sign_in(author)
|
|
|
|
get "/post_localizations/#{author_post.id}.json"
|
|
|
|
expect(response.status).to eq(200)
|
|
json = response.parsed_body
|
|
expect(json["post_localizations"].length).to eq(1)
|
|
end
|
|
|
|
it "denies post authors from viewing localizations for others' posts" do
|
|
Fabricate(:post_localization, post: post_record, locale:)
|
|
sign_in(author)
|
|
|
|
get "/post_localizations/#{post_record.id}.json"
|
|
|
|
expect(response.status).to eq(403)
|
|
end
|
|
end
|
|
end
|
|
|
|
describe "#create_or_update" do
|
|
context "when localization does not exist" do
|
|
it "creates a new localization" do
|
|
expect {
|
|
post "/post_localizations/create_or_update.json",
|
|
params: {
|
|
post_id: post_record.id,
|
|
locale:,
|
|
raw:,
|
|
}
|
|
}.to change { PostLocalization.count }.by(1)
|
|
|
|
expect(response.status).to eq(201)
|
|
localization = PostLocalization.last
|
|
expect(localization).to have_attributes(
|
|
locale:,
|
|
raw:,
|
|
post_id: post_record.id,
|
|
post_version: post_record.version,
|
|
localizer_user_id: user.id,
|
|
)
|
|
end
|
|
end
|
|
|
|
context "when localization already exists" do
|
|
it "updates the existing localization" do
|
|
localization = Fabricate(:post_localization, post: post_record, locale:, raw: "古い翻訳")
|
|
new_user = Fabricate(:user, groups: [group])
|
|
sign_in(new_user)
|
|
|
|
expect {
|
|
post "/post_localizations/create_or_update.json",
|
|
params: {
|
|
post_id: post_record.id,
|
|
locale:,
|
|
raw:,
|
|
}
|
|
}.not_to change { PostLocalization.count }
|
|
|
|
expect(response.status).to eq(200)
|
|
localization.reload
|
|
expect(localization.raw).to eq(raw)
|
|
expect(localization.localizer_user_id).to eq(new_user.id)
|
|
end
|
|
end
|
|
|
|
it "returns forbidden if user is not in allowed group" do
|
|
group.remove(user)
|
|
|
|
post "/post_localizations/create_or_update.json",
|
|
params: {
|
|
post_id: post_record.id,
|
|
locale:,
|
|
raw:,
|
|
}
|
|
|
|
expect(response.status).to eq(403)
|
|
end
|
|
|
|
it "returns not found if post does not exist" do
|
|
post "/post_localizations/create_or_update.json", params: { post_id: -1, locale:, raw: }
|
|
|
|
expect(response.status).to eq(404)
|
|
end
|
|
end
|
|
|
|
describe "#update_locale" do
|
|
it "updates the original post locale without changing the topic locale" do
|
|
post_record.topic.update!(locale: "fr")
|
|
original_version = post_record.version
|
|
|
|
put "/post_localizations/#{post_record.id}/locale.json", params: { locale: "de" }
|
|
|
|
expect(response.status).to eq(200)
|
|
expect(response.parsed_body["locale"]).to eq("de")
|
|
expect(post_record.reload.locale).to eq("de")
|
|
expect(post_record.version).to eq(original_version)
|
|
expect(post_record.topic.reload.locale).to eq("fr")
|
|
end
|
|
|
|
it "returns forbidden when the user cannot localize the post" do
|
|
group.remove(user)
|
|
|
|
expect {
|
|
put "/post_localizations/#{post_record.id}/locale.json", params: { locale: "ja" }
|
|
}.not_to change { post_record.reload.locale }
|
|
|
|
expect(response.status).to eq(403)
|
|
end
|
|
|
|
it "rejects values that are not a single known locale" do
|
|
post_record.update!(locale: "en")
|
|
|
|
%w[not_a_locale en|ja].each do |invalid_locale|
|
|
expect {
|
|
put "/post_localizations/#{post_record.id}/locale.json",
|
|
params: {
|
|
locale: invalid_locale,
|
|
}
|
|
}.not_to change { post_record.reload.locale }
|
|
|
|
expect(response.status).to eq(400)
|
|
end
|
|
end
|
|
|
|
it "allows the original post locale to be cleared" do
|
|
post_record.update!(locale: "en")
|
|
|
|
put "/post_localizations/#{post_record.id}/locale.json", params: { locale: "" }
|
|
|
|
expect(response.status).to eq(200)
|
|
expect(response.parsed_body["locale"]).to be_nil
|
|
expect(post_record.reload.locale).to be_nil
|
|
end
|
|
end
|
|
|
|
describe "#destroy" do
|
|
it "destroys the localization" do
|
|
Fabricate(:post_localization, post: post_record, locale:)
|
|
|
|
expect {
|
|
delete "/post_localizations/destroy.json", params: { post_id: post_record.id, locale: }
|
|
}.to change { PostLocalization.count }.by(-1)
|
|
|
|
expect(response.status).to eq(204)
|
|
end
|
|
|
|
it "returns 404 if localization is missing" do
|
|
delete "/post_localizations/destroy.json", params: { post_id: post_record.id, locale: "nope" }
|
|
|
|
expect(response.status).to eq(404)
|
|
end
|
|
end
|
|
|
|
context "with author localization" do
|
|
fab!(:author, :user)
|
|
fab!(:author_post) { Fabricate(:post, user: author, version: 100) }
|
|
fab!(:other_user, :user)
|
|
|
|
before { group.remove(author) }
|
|
|
|
describe "#create_or_update for post authors" do
|
|
it "allows post author to create localization on their own post" do
|
|
sign_in(author)
|
|
|
|
SiteSetting.content_localization_allow_author_localization = false
|
|
expect {
|
|
post "/post_localizations/create_or_update.json",
|
|
params: {
|
|
post_id: author_post.id,
|
|
locale:,
|
|
raw:,
|
|
}
|
|
}.not_to change { PostLocalization.count }
|
|
|
|
SiteSetting.content_localization_allow_author_localization = true
|
|
expect {
|
|
post "/post_localizations/create_or_update.json",
|
|
params: {
|
|
post_id: author_post.id,
|
|
locale:,
|
|
raw:,
|
|
}
|
|
}.to change { PostLocalization.count }.by(1)
|
|
expect(response.status).to eq(201)
|
|
localization = PostLocalization.last
|
|
expect(localization.localizer_user_id).to eq(author.id)
|
|
end
|
|
|
|
it "denies post author from creating localization on others' posts" do
|
|
SiteSetting.content_localization_allow_author_localization = true
|
|
sign_in(author)
|
|
|
|
expect {
|
|
post "/post_localizations/create_or_update.json",
|
|
params: {
|
|
post_id: post_record.id,
|
|
locale:,
|
|
raw:,
|
|
}
|
|
}.not_to change { PostLocalization.count }
|
|
|
|
expect(response.status).to eq(403)
|
|
end
|
|
|
|
it "allows author to update their own localization" do
|
|
localization =
|
|
Fabricate(
|
|
:post_localization,
|
|
post: author_post,
|
|
locale:,
|
|
raw: "古い翻訳",
|
|
localizer_user_id: author.id,
|
|
)
|
|
sign_in(author)
|
|
|
|
SiteSetting.content_localization_allow_author_localization = false
|
|
expect {
|
|
post "/post_localizations/create_or_update.json",
|
|
params: {
|
|
post_id: author_post.id,
|
|
locale:,
|
|
raw:,
|
|
}
|
|
}.not_to change { localization.reload.raw }
|
|
|
|
SiteSetting.content_localization_allow_author_localization = true
|
|
post "/post_localizations/create_or_update.json",
|
|
params: {
|
|
post_id: author_post.id,
|
|
locale:,
|
|
raw:,
|
|
}
|
|
expect(response.status).to eq(200)
|
|
localization.reload
|
|
expect(localization.raw).to eq(raw)
|
|
end
|
|
end
|
|
|
|
describe "#destroy for post authors" do
|
|
it "allows author to delete their own localization" do
|
|
Fabricate(:post_localization, post: author_post, locale:, localizer_user_id: author.id)
|
|
sign_in(author)
|
|
|
|
SiteSetting.content_localization_allow_author_localization = false
|
|
expect {
|
|
delete "/post_localizations/destroy.json", params: { post_id: author_post.id, locale: }
|
|
}.not_to change { PostLocalization.count }
|
|
|
|
SiteSetting.content_localization_allow_author_localization = true
|
|
expect {
|
|
delete "/post_localizations/destroy.json", params: { post_id: author_post.id, locale: }
|
|
}.to change { PostLocalization.count }.by(-1)
|
|
|
|
expect(response.status).to eq(204)
|
|
end
|
|
end
|
|
|
|
it "allows users in allowed groups full access regardless of author setting" do
|
|
localization =
|
|
Fabricate(:post_localization, post: author_post, locale:, localizer_user_id: author.id)
|
|
sign_in(user)
|
|
|
|
SiteSetting.content_localization_allow_author_localization = false
|
|
expect {
|
|
post "/post_localizations/create_or_update.json",
|
|
params: {
|
|
post_id: author_post.id,
|
|
locale:,
|
|
raw: "1",
|
|
}
|
|
}.to change { localization.reload.raw }
|
|
|
|
SiteSetting.content_localization_allow_author_localization = true
|
|
expect {
|
|
post "/post_localizations/create_or_update.json",
|
|
params: {
|
|
post_id: author_post.id,
|
|
locale:,
|
|
raw: "2",
|
|
}
|
|
}.to change { localization.reload.raw }
|
|
end
|
|
end
|
|
end
|