From 8185f988723dd95b814bcc5f03ccb3da94edbae4 Mon Sep 17 00:00:00 2001 From: voidSatisfaction Date: Thu, 7 Sep 2017 16:55:42 +0900 Subject: Feat add validation for report comment: characters under 1000 valid (#4833) --- spec/models/report_spec.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'spec') diff --git a/spec/models/report_spec.rb b/spec/models/report_spec.rb index 6c2723845..d40ebf6dc 100644 --- a/spec/models/report_spec.rb +++ b/spec/models/report_spec.rb @@ -21,4 +21,18 @@ describe Report do expect(report.media_attachments).to eq [media_attachment] end end + + describe 'validatiions' do + it 'has a valid fabricator' do + report = Fabricate(:report) + report.valid? + expect(report).to be_valid + end + + it 'is invalid if comment is longer than 1000 characters' do + report = Fabricate.build(:report, comment: Faker::Lorem.characters(1001)) + report.valid? + expect(report).to model_have_error_on_field(:comment) + end + end end -- cgit From a4caa7eb6258ff7f8eea8e6791b86b1c7f4d172e Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 8 Sep 2017 12:00:17 +0200 Subject: Fetch statuses/following/followers numbers from ActivityPub collections (#4840) --- .../activitypub/process_account_service.rb | 37 +++++++++++++++++++--- spec/lib/activitypub/activity/update_spec.rb | 8 +++-- .../fetch_remote_account_service_spec.rb | 2 +- 3 files changed, 39 insertions(+), 8 deletions(-) (limited to 'spec') diff --git a/app/services/activitypub/process_account_service.rb b/app/services/activitypub/process_account_service.rb index 29eb1c2e1..c63577fe5 100644 --- a/app/services/activitypub/process_account_service.rb +++ b/app/services/activitypub/process_account_service.rb @@ -8,11 +8,12 @@ class ActivityPub::ProcessAccountService < BaseService def call(username, domain, json) return if json['inbox'].blank? - @json = json - @uri = @json['id'] - @username = username - @domain = domain - @account = Account.find_by(uri: @uri) + @json = json + @uri = @json['id'] + @username = username + @domain = domain + @account = Account.find_by(uri: @uri) + @collections = {} create_account if @account.nil? upgrade_account if @account.ostatus? @@ -51,6 +52,9 @@ class ActivityPub::ProcessAccountService < BaseService @account.header_remote_url = image_url('image') @account.public_key = public_key || '' @account.locked = @json['manuallyApprovesFollowers'] || false + @account.statuses_count = outbox_total_items if outbox_total_items.present? + @account.following_count = following_total_items if following_total_items.present? + @account.followers_count = followers_total_items if followers_total_items.present? @account.save! end @@ -88,6 +92,29 @@ class ActivityPub::ProcessAccountService < BaseService value['href'] end + def outbox_total_items + collection_total_items('outbox') + end + + def following_total_items + collection_total_items('following') + end + + def followers_total_items + collection_total_items('followers') + end + + def collection_total_items(type) + return if @json[type].blank? + return @collections[type] if @collections.key?(type) + + collection = fetch_resource(@json[type]) + + @collections[type] = collection.is_a?(Hash) && collection['totalItems'].present? && collection['totalItems'].is_a?(Numeric) ? collection['totalItems'] : nil + rescue HTTP::Error, OpenSSL::SSL::SSLError + @collections[type] = nil + end + def auto_suspend? domain_block && domain_block.suspend? end diff --git a/spec/lib/activitypub/activity/update_spec.rb b/spec/lib/activitypub/activity/update_spec.rb index 0bd6d00d9..ea308e35c 100644 --- a/spec/lib/activitypub/activity/update_spec.rb +++ b/spec/lib/activitypub/activity/update_spec.rb @@ -2,12 +2,16 @@ require 'rails_helper' RSpec.describe ActivityPub::Activity::Update do let!(:sender) { Fabricate(:account) } - + before do + stub_request(:get, actor_json[:outbox]).to_return(status: 404) + stub_request(:get, actor_json[:followers]).to_return(status: 404) + stub_request(:get, actor_json[:following]).to_return(status: 404) + sender.update!(uri: ActivityPub::TagManager.instance.uri_for(sender)) end - let(:modified_sender) do + let(:modified_sender) do sender.dup.tap do |modified_sender| modified_sender.display_name = 'Totally modified now' end diff --git a/spec/services/activitypub/fetch_remote_account_service_spec.rb b/spec/services/activitypub/fetch_remote_account_service_spec.rb index 391d051c1..ed7e9bba8 100644 --- a/spec/services/activitypub/fetch_remote_account_service_spec.rb +++ b/spec/services/activitypub/fetch_remote_account_service_spec.rb @@ -41,7 +41,7 @@ RSpec.describe ActivityPub::FetchRemoteAccountService do before do actor[:inbox] = nil - + stub_request(:get, 'https://example.com/alice').to_return(body: Oj.dump(actor)) stub_request(:get, 'https://example.com/.well-known/webfinger?resource=acct:alice@example.com').to_return(body: Oj.dump(webfinger), headers: { 'Content-Type': 'application/jrd+json' }) end -- cgit From 1caf11ddcc029d9e7735ab3b90607ab2d6973034 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Fri, 8 Sep 2017 12:32:22 +0200 Subject: Fix language filter codes (#4841) * Fix language filter codes CLD3 returns BCP-47 language identifier, filter settings expect identifiers in the ISO 639-1 format. Convert between formats, and exclude duplicate languages from filter choices (zh-CN->zh) * Fix zh name --- Gemfile | 1 + Gemfile.lock | 2 ++ app/helpers/settings_helper.rb | 5 +++++ app/lib/language_detector.rb | 11 ++++++++++- app/views/settings/preferences/show.html.haml | 2 +- spec/helpers/settings_helper_spec.rb | 4 ++-- 6 files changed, 21 insertions(+), 4 deletions(-) (limited to 'spec') diff --git a/Gemfile b/Gemfile index 486e72cc4..637bf53ee 100644 --- a/Gemfile +++ b/Gemfile @@ -24,6 +24,7 @@ gem 'addressable', '~> 2.5' gem 'bootsnap' gem 'browser' gem 'charlock_holmes', '~> 0.7.5' +gem 'iso-639' gem 'cld3', '~> 3.1' gem 'devise', '~> 4.2' gem 'devise-two-factor', '~> 3.0' diff --git a/Gemfile.lock b/Gemfile.lock index ef99e0d7b..ddb97dd94 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -225,6 +225,7 @@ GEM terminal-table (>= 1.5.1) idn-ruby (0.1.0) ipaddress (0.8.3) + iso-639 (0.2.8) jmespath (1.3.1) json (2.1.0) json-ld (2.1.5) @@ -560,6 +561,7 @@ DEPENDENCIES httplog (~> 0.99) i18n-tasks (~> 0.9) idn-ruby + iso-639 json-ld-preloaded (~> 2.2.1) kaminari (~> 1.0) letter_opener (~> 1.4) diff --git a/app/helpers/settings_helper.rb b/app/helpers/settings_helper.rb index af950aa63..369a45680 100644 --- a/app/helpers/settings_helper.rb +++ b/app/helpers/settings_helper.rb @@ -30,6 +30,7 @@ module SettingsHelper th: 'ภาษาไทย', tr: 'Türkçe', uk: 'Українська', + zh: '中文', 'zh-CN': '简体中文', 'zh-HK': '繁體中文(香港)', 'zh-TW': '繁體中文(臺灣)', @@ -39,6 +40,10 @@ module SettingsHelper HUMAN_LOCALES[locale] end + def filterable_languages + I18n.available_locales.map { |locale| locale.to_s.split('-').first.to_sym }.uniq + end + def hash_to_object(hash) HashObject.new(hash) end diff --git a/app/lib/language_detector.rb b/app/lib/language_detector.rb index cc7509fdc..1d9932b52 100644 --- a/app/lib/language_detector.rb +++ b/app/lib/language_detector.rb @@ -20,7 +20,16 @@ class LanguageDetector private def detected_language_code - result.language.to_sym if detected_language_reliable? + iso6391(result.language).to_sym if detected_language_reliable? + end + + def iso6391(bcp47) + iso639 = bcp47.split('-').first + + # CLD3 returns grandfathered language code for Hebrew + return 'he' if iso639 == 'iw' + + ISO_639.find(iso639).alpha2 end def result diff --git a/app/views/settings/preferences/show.html.haml b/app/views/settings/preferences/show.html.haml index fae6090c8..f42f92508 100644 --- a/app/views/settings/preferences/show.html.haml +++ b/app/views/settings/preferences/show.html.haml @@ -13,7 +13,7 @@ selected: I18n.locale = f.input :filtered_languages, - collection: I18n.available_locales, + collection: filterable_languages, wrapper: :with_block_label, include_blank: false, label_method: lambda { |locale| human_locale(locale) }, diff --git a/spec/helpers/settings_helper_spec.rb b/spec/helpers/settings_helper_spec.rb index 5a51e0ef1..092c37583 100644 --- a/spec/helpers/settings_helper_spec.rb +++ b/spec/helpers/settings_helper_spec.rb @@ -4,10 +4,10 @@ require 'rails_helper' describe SettingsHelper do describe 'the HUMAN_LOCALES constant' do - it 'has the same number of keys as I18n locales exist' do + it 'includes all I18n locales' do options = I18n.available_locales - expect(described_class::HUMAN_LOCALES.keys).to eq(options) + expect(described_class::HUMAN_LOCALES.keys).to include(*options) end end -- cgit From a12572e074581832744b243f2fadd1742e8418b6 Mon Sep 17 00:00:00 2001 From: unarist Date: Sat, 9 Sep 2017 01:20:03 +0900 Subject: Handle stream_entry URL correctly in ActivityPub (#4854) In before, the method uses stream_entry id as status id, so replied status was wrongly selected. This PR uses StatusFinder which was introduced with `Api::Web::EmbedsController`. --- app/lib/activitypub/tag_manager.rb | 4 +++- spec/lib/activitypub/tag_manager_spec.rb | 28 +++++++++++++++++++++++++++- 2 files changed, 30 insertions(+), 2 deletions(-) (limited to 'spec') diff --git a/app/lib/activitypub/tag_manager.rb b/app/lib/activitypub/tag_manager.rb index de575d9e6..929e87852 100644 --- a/app/lib/activitypub/tag_manager.rb +++ b/app/lib/activitypub/tag_manager.rb @@ -96,12 +96,14 @@ class ActivityPub::TagManager when 'Account' klass.find_local(uri_to_local_id(uri, :username)) else - klass.find_by(id: uri_to_local_id(uri)) + StatusFinder.new(uri).status end elsif ::TagManager.instance.local_id?(uri) klass.find_by(id: ::TagManager.instance.unique_tag_to_local_id(uri, klass.to_s)) else klass.find_by(uri: uri.split('#').first) end + rescue ActiveRecord::RecordNotFound + nil end end diff --git a/spec/lib/activitypub/tag_manager_spec.rb b/spec/lib/activitypub/tag_manager_spec.rb index 8f7662e24..dea8abc65 100644 --- a/spec/lib/activitypub/tag_manager_spec.rb +++ b/spec/lib/activitypub/tag_manager_spec.rb @@ -91,9 +91,35 @@ RSpec.describe ActivityPub::TagManager do end describe '#uri_to_resource' do - it 'returns the local resource' do + it 'returns the local account' do account = Fabricate(:account) expect(subject.uri_to_resource(subject.uri_for(account), Account)).to eq account end + + it 'returns the remote account by matching URI without fragment part' do + account = Fabricate(:account, uri: 'https://example.com/123') + expect(subject.uri_to_resource('https://example.com/123#456', Account)).to eq account + end + + it 'returns the local status for ActivityPub URI' do + status = Fabricate(:status) + expect(subject.uri_to_resource(subject.uri_for(status), Status)).to eq status + end + + it 'returns the local status for OStatus tag: URI' do + status = Fabricate(:status) + expect(subject.uri_to_resource(::TagManager.instance.uri_for(status), Status)).to eq status + end + + it 'returns the local status for OStatus StreamEntry URL' do + status = Fabricate(:status) + stream_entry_url = account_stream_entry_url(status.account, status.stream_entry) + expect(subject.uri_to_resource(stream_entry_url, Status)).to eq status + end + + it 'returns the remote status by matching URI without fragment part' do + status = Fabricate(:status, uri: 'https://example.com/123') + expect(subject.uri_to_resource('https://example.com/123#456', Status)).to eq status + end end end -- cgit From 90712d42933efd9978e4bbae82f81a4650aa4d84 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Sat, 9 Sep 2017 17:36:27 +0200 Subject: Fix errors preventing UnsubscribeService from working (#4866) --- app/services/unsubscribe_service.rb | 13 ++++++++----- spec/services/unsubscribe_service_spec.rb | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) (limited to 'spec') diff --git a/app/services/unsubscribe_service.rb b/app/services/unsubscribe_service.rb index 865f783bc..b99046712 100644 --- a/app/services/unsubscribe_service.rb +++ b/app/services/unsubscribe_service.rb @@ -4,16 +4,19 @@ class UnsubscribeService < BaseService def call(account) return if account.hub_url.blank? - @account = account - @response = build_request.perform + @account = account - Rails.logger.debug "PuSH unsubscribe for #{@account.acct} failed: #{@response.status}" unless @response.status.success? + begin + @response = build_request.perform + + Rails.logger.debug "PuSH unsubscribe for #{@account.acct} failed: #{@response.status}" unless @response.status.success? + rescue HTTP::Error, OpenSSL::SSL::SSLError => e + Rails.logger.debug "PuSH unsubscribe for #{@account.acct} failed: #{e}" + end @account.secret = '' @account.subscription_expires_at = nil @account.save! - rescue HTTP::Error, OpenSSL::SSL::SSLError - Rails.logger.debug "PuSH subscription request for #{@account.acct} could not be made due to HTTP or SSL error" end private diff --git a/spec/services/unsubscribe_service_spec.rb b/spec/services/unsubscribe_service_spec.rb index c81772037..2a02f4c75 100644 --- a/spec/services/unsubscribe_service_spec.rb +++ b/spec/services/unsubscribe_service_spec.rb @@ -26,7 +26,7 @@ RSpec.describe UnsubscribeService do stub_request(:post, 'http://hub.example.com/').to_raise(HTTP::Error) subject.call(account) - expect(logger).to have_received(:debug).with(/PuSH subscription request for bob@example.com could not be made due to HTTP or SSL error/) + expect(logger).to have_received(:debug).with(/unsubscribe for bob@example.com failed/) end def stub_logger -- cgit