From 1c84ffeab33764de75931b66398e6889e87cabd7 Mon Sep 17 00:00:00 2001 From: Natalie Tay Date: Fri, 3 May 2024 15:44:42 +0800 Subject: [PATCH] FIX: Skip translations for empty or small actions posts (#139) --- plugin.rb | 7 +- spec/jobs/detect_translation_spec.rb | 45 +++++++ spec/serializers/post_serializer_spec.rb | 146 ++++++++++++----------- 3 files changed, 126 insertions(+), 72 deletions(-) create mode 100644 spec/jobs/detect_translation_spec.rb diff --git a/plugin.rb b/plugin.rb index f1c8a38..f951584 100644 --- a/plugin.rb +++ b/plugin.rb @@ -168,12 +168,11 @@ def post_process(post) end add_to_serializer :post, :can_translate do - if !( - SiteSetting.translator_enabled && scope.user_group_allow_translate? && - scope.poster_group_allow_translate?(object) - ) + return false if !SiteSetting.translator_enabled + if !scope.user_group_allow_translate? || !scope.poster_group_allow_translate?(object) return false end + return false if raw.blank? || post_type == Post.types[:small_action] detected_lang = post_custom_fields[::DiscourseTranslator::DETECTED_LANG_CUSTOM_FIELD] diff --git a/spec/jobs/detect_translation_spec.rb b/spec/jobs/detect_translation_spec.rb new file mode 100644 index 0000000..1428d3b --- /dev/null +++ b/spec/jobs/detect_translation_spec.rb @@ -0,0 +1,45 @@ +# frozen_string_literal: true + +require "aws-sdk-translate" + +describe Jobs::DetectTranslation do + before do + SiteSetting.translator = "Amazon" + client = Aws::Translate::Client.new(stub_responses: true) + client.stub_responses( + :translate_text, + { translated_text: "大丈夫", source_language_code: "en", target_language_code: "jp" }, + ) + Aws::Translate::Client.stubs(:new).returns(client) + end + + it "does not detect translation if translator disabled" do + SiteSetting.translator_enabled = false + + post = Fabricate(:post) + Jobs::DetectTranslation.new.execute(post_id: post.id) + + expect(post.custom_fields[DiscourseTranslator::DETECTED_LANG_CUSTOM_FIELD]).to be_nil + end + + describe "translator enabled" do + before { SiteSetting.translator_enabled = true } + + it "does not detect translation if post does not exist" do + post = Fabricate(:post) + post.destroy + + Jobs::DetectTranslation.new.execute(post_id: post.id) + + expect(post.custom_fields[DiscourseTranslator::DETECTED_LANG_CUSTOM_FIELD]).to be_nil + end + + it "detects translation" do + post = Fabricate(:post, raw: "this is a sample post") + + Jobs::DetectTranslation.new.execute(post_id: post.id) + + expect(post.custom_fields[DiscourseTranslator::DETECTED_LANG_CUSTOM_FIELD]).to eq("en") + end + end +end diff --git a/spec/serializers/post_serializer_spec.rb b/spec/serializers/post_serializer_spec.rb index dd47b8b..541aead 100644 --- a/spec/serializers/post_serializer_spec.rb +++ b/spec/serializers/post_serializer_spec.rb @@ -3,95 +3,105 @@ require "rails_helper" RSpec.describe PostSerializer do - let(:post) { Fabricate(:post) } + fab!(:group) + fab!(:user) { Fabricate(:user, locale: "en", groups: [group]) } - before do - SiteSetting.translator_enabled = true - Jobs.run_later! - end + fab!(:post_user_group) { Fabricate(:group) } + fab!(:post_user) { Fabricate(:user, locale: "en", groups: [post_user_group]) } + fab!(:post) { Fabricate(:post, user: post_user) } - shared_examples "detected_lang_does_not_match_user_locale" do - describe "when post detected lang does not match user's locale" do - before do - post_with_user.custom_fields[DiscourseTranslator::DETECTED_LANG_CUSTOM_FIELD] = "ja" - post_with_user.save - end + describe "#can_translate" do + it "returns false when translator disabled" do + SiteSetting.translator_enabled = true + serializer = PostSerializer.new(post, scope: Guardian.new) - it { expect(serializer.can_translate).to eq(true) } + expect(serializer.can_translate).to eq(false) end - end - shared_examples "detected_lang_match_user_locale" do - describe "when post detected lang matches user's locale" do + describe "when translator enabled" do before do - post_with_user.custom_fields[DiscourseTranslator::DETECTED_LANG_CUSTOM_FIELD] = "en" - post_with_user.save + SiteSetting.translator_enabled = true + Jobs.run_later! end - it { expect(serializer.can_translate).to eq(false) } - end - end + describe "when small action post" do + fab!(:small_action) + let(:serializer) { PostSerializer.new(small_action, scope: Guardian.new) } - describe "#can_translate" do - describe "logged in user" do - let(:user) do - user = Fabricate(:user, locale: "en") - user.group_users << Fabricate(:group_user, user: user, group: Group[:trust_level_1]) - user + it "cannot translate" do + expect(serializer.can_translate).to eq(false) + end end - let(:serializer) { PostSerializer.new(post_with_user, scope: Guardian.new(user)) } - let(:post_with_user) { Fabricate(:post, user: user) } - describe "when poster is in a allowlisted group" do - before do - SiteSetting.restrict_translation_by_poster_group = - "#{User.find(post_with_user.user_id).groups.first.id}" + describe "when post raw is empty" do + fab!(:empty_post) do + empty_post = Fabricate.build(:post, raw: "") + empty_post.save!(validate: false) + empty_post end + let(:serializer) { PostSerializer.new(empty_post, scope: Guardian.new) } - include_examples "detected_lang_does_not_match_user_locale" - include_examples "detected_lang_match_user_locale" + it "cannot translate" do + expect(serializer.can_translate).to eq(false) + end end - describe "when poster is not in a allowlisted group" do - before do - SiteSetting.restrict_translation_by_poster_group = "#{Group[:trust_level_4]}" - post.custom_fields[DiscourseTranslator::DETECTED_LANG_CUSTOM_FIELD] = "ja" - post.save - end + describe "logged in user" do + let(:serializer) { PostSerializer.new(post, scope: Guardian.new(user)) } - it { expect(serializer.can_translate).to eq(false) } - end + describe "when user is not in restrict_translation_by_group" do + it "cannot translate" do + SiteSetting.restrict_translation_by_group = "" - describe "when user is in a allowlisted group" do - before do - SiteSetting.restrict_translation_by_group = "#{user.groups.first.id}|not_in_the_list" - end - include_examples "detected_lang_does_not_match_user_locale" - include_examples "detected_lang_match_user_locale" - end - describe "when user is not in a allowlisted group" do - before do - post.custom_fields[DiscourseTranslator::DETECTED_LANG_CUSTOM_FIELD] = "ja" - post.save - SiteSetting.restrict_translation_by_group = "not_in_the_list" + expect(serializer.can_translate).to eq(false) + end end - it "should not translate even if the post detected lang does not match the user's locale" do - expect(serializer.can_translate).to eq(false) - end - end - end + describe "when post is not in restrict_translation_by_poster_group" do + it "cannot translate" do + SiteSetting.restrict_translation_by_group = "#{group.id}" + SiteSetting.restrict_translation_by_poster_group = "" - describe "when user is not logged in" do - let(:serializer) { PostSerializer.new(post, scope: Guardian.new) } - before do - post.custom_fields[DiscourseTranslator::DETECTED_LANG_CUSTOM_FIELD] = "ja" - post.save - SiteSetting.restrict_translation_by_group = "11|not_in_the_list" - end + expect(serializer.can_translate).to eq(false) + end + end - it "should not translate" do - expect(serializer.can_translate).to eq(false) + describe "when user is in restrict_translation_by_group and poster in restrict_translation_by_poster_group" do + before do + SiteSetting.restrict_translation_by_group = "#{group.id}" + SiteSetting.restrict_translation_by_poster_group = "#{post_user_group.id}" + end + + describe "when post does not have DETECTED_LANG_CUSTOM_FIELD" do + it "cannot translate" do + expect(serializer.can_translate).to eq(false) + end + + it "enqueues detect translation job" do + expect { serializer.can_translate }.to change { + Jobs::DetectTranslation.jobs.size + }.by(1) + end + end + + describe "when post has DETECTED_LANG_CUSTOM_FIELD matches user locale" do + before do + post.custom_fields[DiscourseTranslator::DETECTED_LANG_CUSTOM_FIELD] = "en" + post.save + end + + it { expect(serializer.can_translate).to eq(false) } + end + + describe "when post has DETECTED_LANG_CUSTOM_FIELD does not match user locale" do + before do + post.custom_fields[DiscourseTranslator::DETECTED_LANG_CUSTOM_FIELD] = "jp" + post.save + end + + it { expect(serializer.can_translate).to eq(true) } + end + end end end end