Language detection refactor (#2099)
* Extract detect_language to separate class * Use default locale, not just en * Add spec to confirm that whatlanguage cant identify empty string * Allow account locale to override default in language detector * PostStatusService supplies an account to detect language
This commit is contained in:
		
							
								
								
									
										20
									
								
								app/lib/language_detector.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								app/lib/language_detector.rb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,20 @@ | |||||||
|  | # frozen_string_literal: true | ||||||
|  |  | ||||||
|  | class LanguageDetector | ||||||
|  |   attr_reader :text, :account | ||||||
|  |  | ||||||
|  |   def initialize(text, account = nil) | ||||||
|  |     @text = text | ||||||
|  |     @account = account | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   def to_iso_s | ||||||
|  |     WhatLanguage.new(:all).language_iso(text) || default_locale.to_sym | ||||||
|  |   end | ||||||
|  |  | ||||||
|  |   private | ||||||
|  |  | ||||||
|  |   def default_locale | ||||||
|  |     account&.user&.locale || I18n.default_locale | ||||||
|  |   end | ||||||
|  | end | ||||||
| @@ -19,7 +19,7 @@ class PostStatusService < BaseService | |||||||
|                                       sensitive: options[:sensitive], |                                       sensitive: options[:sensitive], | ||||||
|                                       spoiler_text: options[:spoiler_text] || '', |                                       spoiler_text: options[:spoiler_text] || '', | ||||||
|                                       visibility: options[:visibility], |                                       visibility: options[:visibility], | ||||||
|                                       language: detect_language(text), |                                       language: detect_language_for(text, account), | ||||||
|                                       application: options[:application]) |                                       application: options[:application]) | ||||||
|  |  | ||||||
|     attach_media(status, media) |     attach_media(status, media) | ||||||
| @@ -52,8 +52,8 @@ class PostStatusService < BaseService | |||||||
|     media.update(status_id: status.id) |     media.update(status_id: status.id) | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   def detect_language(text) |   def detect_language_for(text, account) | ||||||
|     WhatLanguage.new(:all).language_iso(text) || 'en' |     LanguageDetector.new(text, account).to_iso_s | ||||||
|   end |   end | ||||||
|  |  | ||||||
|   def process_mentions_service |   def process_mentions_service | ||||||
|   | |||||||
							
								
								
									
										71
									
								
								spec/lib/language_detector_spec.rb
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								spec/lib/language_detector_spec.rb
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | |||||||
|  | # frozen_string_literal: true | ||||||
|  |  | ||||||
|  | require 'rails_helper' | ||||||
|  |  | ||||||
|  | describe LanguageDetector do | ||||||
|  |   describe 'to_iso_s' do | ||||||
|  |     it 'detects english language' do | ||||||
|  |       string = 'Hello and welcome to mastadon' | ||||||
|  |       result = described_class.new(string).to_iso_s | ||||||
|  |  | ||||||
|  |       expect(result).to eq :en | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     it 'detects spanish language' do | ||||||
|  |       string = 'Obtener un Hola y bienvenidos a Mastadon' | ||||||
|  |       result = described_class.new(string).to_iso_s | ||||||
|  |  | ||||||
|  |       expect(result).to eq :es | ||||||
|  |     end | ||||||
|  |  | ||||||
|  |     describe 'when language cant be detected' do | ||||||
|  |       it 'confirm language engine cant detect' do | ||||||
|  |         result = WhatLanguage.new(:all).language_iso('') | ||||||
|  |         expect(result).to be_nil | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       describe 'with an account' do | ||||||
|  |         it 'uses the account locale when present' do | ||||||
|  |           user = double(:user, locale: 'fr') | ||||||
|  |           account = double(:account, user: user) | ||||||
|  |           result = described_class.new('', account).to_iso_s | ||||||
|  |  | ||||||
|  |           expect(result).to eq :fr | ||||||
|  |         end | ||||||
|  |  | ||||||
|  |         it 'uses default locale when account is present but has no locale' do | ||||||
|  |           user = double(:user, locale: nil) | ||||||
|  |           account = double(:accunt, user: user) | ||||||
|  |           result = described_class.new('', account).to_iso_s | ||||||
|  |  | ||||||
|  |           expect(result).to eq :en | ||||||
|  |         end | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       describe 'with an `en` default locale' do | ||||||
|  |         it 'uses the default locale' do | ||||||
|  |           string = '' | ||||||
|  |           result = described_class.new(string).to_iso_s | ||||||
|  |  | ||||||
|  |           expect(result).to eq :en | ||||||
|  |         end | ||||||
|  |       end | ||||||
|  |  | ||||||
|  |       describe 'with a non-`en` default locale' do | ||||||
|  |         around(:each) do |example| | ||||||
|  |           before = I18n.default_locale | ||||||
|  |           I18n.default_locale = :ja | ||||||
|  |           example.run | ||||||
|  |           I18n.default_locale = before | ||||||
|  |         end | ||||||
|  |  | ||||||
|  |         it 'uses the default locale' do | ||||||
|  |           string = '' | ||||||
|  |           result = described_class.new(string).to_iso_s | ||||||
|  |  | ||||||
|  |           expect(result).to eq :ja | ||||||
|  |         end | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
| @@ -64,6 +64,18 @@ RSpec.describe PostStatusService do | |||||||
|     expect(status.application).to eq application |     expect(status.application).to eq application | ||||||
|   end |   end | ||||||
|  |  | ||||||
|  |   it 'creates a status with a language set' do | ||||||
|  |     detector = double(to_iso_s: :en) | ||||||
|  |     allow(LanguageDetector).to receive(:new).and_return(detector) | ||||||
|  |  | ||||||
|  |     account = Fabricate(:account) | ||||||
|  |     text = 'test status text' | ||||||
|  |  | ||||||
|  |     subject.call(account, text) | ||||||
|  |  | ||||||
|  |     expect(LanguageDetector).to have_received(:new).with(text, account) | ||||||
|  |   end | ||||||
|  |  | ||||||
|   it 'processes mentions' do |   it 'processes mentions' do | ||||||
|     mention_service = double(:process_mentions_service) |     mention_service = double(:process_mentions_service) | ||||||
|     allow(mention_service).to receive(:call) |     allow(mention_service).to receive(:call) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user