Merge branch 'master' into glitch-soc/merge-upstream

Conflicts:
	db/migrate/20170716191202_add_hide_notifications_to_mute.rb
	spec/controllers/application_controller_spec.rb

Took our version, upstream changes were only minor style linting.
This commit is contained in:
Thibaut Girka 2018-10-05 15:23:57 +02:00
commit 00fcdebed7
93 changed files with 406 additions and 324 deletions

View File

@ -1,5 +1,5 @@
FROM node:8.11.3-alpine as node FROM node:8.12.0-alpine as node
FROM ruby:2.4.4-alpine3.6 FROM ruby:2.4.4-alpine3.7
LABEL maintainer="https://github.com/tootsuite/mastodon" \ LABEL maintainer="https://github.com/tootsuite/mastodon" \
description="Your self-hosted, globally interconnected microblogging community" description="Your self-hosted, globally interconnected microblogging community"

27
Gemfile
View File

@ -10,14 +10,14 @@ gem 'rails', '~> 5.2.1'
gem 'thor', '~> 0.20' gem 'thor', '~> 0.20'
gem 'hamlit-rails', '~> 0.2' gem 'hamlit-rails', '~> 0.2'
gem 'pg', '~> 1.0' gem 'pg', '~> 1.1'
gem 'makara', '~> 0.4' gem 'makara', '~> 0.4'
gem 'pghero', '~> 2.2' gem 'pghero', '~> 2.2'
gem 'dotenv-rails', '~> 2.2', '< 2.3' gem 'dotenv-rails', '~> 2.2', '< 2.3'
gem 'aws-sdk-s3', '~> 1.9', require: false gem 'aws-sdk-s3', '~> 1.20', require: false
gem 'fog-core', '~> 1.45' gem 'fog-core', '~> 2.1'
gem 'fog-openstack', '~> 0.1', require: false gem 'fog-openstack', '~> 1.0', require: false
gem 'paperclip', '~> 6.0' gem 'paperclip', '~> 6.0'
gem 'paperclip-av-transcoder', '~> 0.6' gem 'paperclip-av-transcoder', '~> 0.6'
gem 'streamio-ffmpeg', '~> 3.0' gem 'streamio-ffmpeg', '~> 3.0'
@ -27,6 +27,7 @@ gem 'addressable', '~> 2.5'
gem 'bootsnap', '~> 1.3', require: false gem 'bootsnap', '~> 1.3', require: false
gem 'browser' gem 'browser'
gem 'charlock_holmes', '~> 0.7.6' gem 'charlock_holmes', '~> 0.7.6'
gem 'colorize'
gem 'iso-639' gem 'iso-639'
gem 'chewy', '~> 5.0' gem 'chewy', '~> 5.0'
gem 'cld3', '~> 3.2.0' gem 'cld3', '~> 3.2.0'
@ -50,10 +51,10 @@ gem 'hiredis', '~> 0.6'
gem 'redis-namespace', '~> 1.5' gem 'redis-namespace', '~> 1.5'
gem 'html2text' gem 'html2text'
gem 'htmlentities', '~> 4.3' gem 'htmlentities', '~> 4.3'
gem 'http', '~> 3.2' gem 'http', '~> 3.3'
gem 'http_accept_language', '~> 2.1' gem 'http_accept_language', '~> 2.1'
gem 'http_parser.rb', '~> 0.6', git: 'https://github.com/tmm1/http_parser.rb', ref: '54b17ba8c7d8d20a16dfc65d1775241833219cf2' gem 'http_parser.rb', '~> 0.6', git: 'https://github.com/tmm1/http_parser.rb', ref: '54b17ba8c7d8d20a16dfc65d1775241833219cf2'
gem 'httplog', '~> 1.0' gem 'httplog', '~> 1.1'
gem 'idn-ruby', require: 'idn' gem 'idn-ruby', require: 'idn'
gem 'kaminari', '~> 1.1' gem 'kaminari', '~> 1.1'
gem 'link_header', '~> 0.0' gem 'link_header', '~> 0.0'
@ -66,7 +67,7 @@ gem 'ox', '~> 2.10'
gem 'posix-spawn', git: 'https://github.com/rtomayko/posix-spawn', ref: '58465d2e213991f8afb13b984854a49fcdcc980c' gem 'posix-spawn', git: 'https://github.com/rtomayko/posix-spawn', ref: '58465d2e213991f8afb13b984854a49fcdcc980c'
gem 'pundit', '~> 1.1' gem 'pundit', '~> 1.1'
gem 'premailer-rails' gem 'premailer-rails'
gem 'rack-attack', '~> 5.2' gem 'rack-attack', '~> 5.4'
gem 'rack-cors', '~> 1.0', require: 'rack/cors' gem 'rack-cors', '~> 1.0', require: 'rack/cors'
gem 'rails-i18n', '~> 5.1' gem 'rails-i18n', '~> 5.1'
gem 'rails-settings-cached', '~> 0.6' gem 'rails-settings-cached', '~> 0.6'
@ -96,11 +97,11 @@ gem 'rdf-normalize', '~> 0.3'
group :development, :test do group :development, :test do
gem 'fabrication', '~> 2.20' gem 'fabrication', '~> 2.20'
gem 'fuubar', '~> 2.2' gem 'fuubar', '~> 2.3'
gem 'i18n-tasks', '~> 0.9', require: false gem 'i18n-tasks', '~> 0.9', require: false
gem 'pry-byebug', '~> 3.6' gem 'pry-byebug', '~> 3.6'
gem 'pry-rails', '~> 0.3' gem 'pry-rails', '~> 0.3'
gem 'rspec-rails', '~> 3.7' gem 'rspec-rails', '~> 3.8'
end end
group :production, :test do group :production, :test do
@ -108,14 +109,14 @@ group :production, :test do
end end
group :test do group :test do
gem 'capybara', '~> 2.18' gem 'capybara', '~> 3.8'
gem 'climate_control', '~> 0.2' gem 'climate_control', '~> 0.2'
gem 'faker', '~> 1.8' gem 'faker', '~> 1.8'
gem 'microformats', '~> 4.0' gem 'microformats', '~> 4.0'
gem 'rails-controller-testing', '~> 1.0' gem 'rails-controller-testing', '~> 1.0'
gem 'rspec-sidekiq', '~> 3.0' gem 'rspec-sidekiq', '~> 3.0'
gem 'simplecov', '~> 0.16', require: false gem 'simplecov', '~> 0.16', require: false
gem 'webmock', '~> 3.3' gem 'webmock', '~> 3.4'
gem 'parallel_tests', '~> 2.21' gem 'parallel_tests', '~> 2.21'
end end
@ -128,8 +129,8 @@ group :development do
gem 'letter_opener', '~> 1.4' gem 'letter_opener', '~> 1.4'
gem 'letter_opener_web', '~> 1.3' gem 'letter_opener_web', '~> 1.3'
gem 'memory_profiler' gem 'memory_profiler'
gem 'rubocop', '~> 0.55', require: false gem 'rubocop', '~> 0.59', require: false
gem 'brakeman', '~> 4.2', require: false gem 'brakeman', '~> 4.3', require: false
gem 'bundler-audit', '~> 0.6', require: false gem 'bundler-audit', '~> 0.6', require: false
gem 'scss_lint', '~> 0.57', require: false gem 'scss_lint', '~> 0.57', require: false

View File

@ -75,19 +75,21 @@ GEM
encryptor (~> 3.0.0) encryptor (~> 3.0.0)
av (0.9.0) av (0.9.0)
cocaine (~> 0.5.3) cocaine (~> 0.5.3)
aws-partitions (1.80.0) aws-eventstream (1.0.1)
aws-sdk-core (3.19.0) aws-partitions (1.105.0)
aws-sdk-core (3.29.0)
aws-eventstream (~> 1.0)
aws-partitions (~> 1.0) aws-partitions (~> 1.0)
aws-sigv4 (~> 1.0) aws-sigv4 (~> 1.0)
jmespath (~> 1.0) jmespath (~> 1.0)
aws-sdk-kms (1.5.0) aws-sdk-kms (1.9.0)
aws-sdk-core (~> 3) aws-sdk-core (~> 3, >= 3.26.0)
aws-sigv4 (~> 1.0) aws-sigv4 (~> 1.0)
aws-sdk-s3 (1.9.1) aws-sdk-s3 (1.20.0)
aws-sdk-core (~> 3) aws-sdk-core (~> 3, >= 3.26.0)
aws-sdk-kms (~> 1) aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.0) aws-sigv4 (~> 1.0)
aws-sigv4 (1.0.2) aws-sigv4 (1.0.3)
bcrypt (3.1.12) bcrypt (3.1.12)
benchmark-ips (2.7.2) benchmark-ips (2.7.2)
better_errors (2.4.0) better_errors (2.4.0)
@ -98,7 +100,7 @@ GEM
debug_inspector (>= 0.0.1) debug_inspector (>= 0.0.1)
bootsnap (1.3.2) bootsnap (1.3.2)
msgpack (~> 1.0) msgpack (~> 1.0)
brakeman (4.2.1) brakeman (4.3.1)
browser (2.5.3) browser (2.5.3)
builder (3.2.3) builder (3.2.3)
bullet (5.7.5) bullet (5.7.5)
@ -119,18 +121,18 @@ GEM
capistrano-rails (1.3.1) capistrano-rails (1.3.1)
capistrano (~> 3.1) capistrano (~> 3.1)
capistrano-bundler (~> 1.1) capistrano-bundler (~> 1.1)
capistrano-rbenv (2.1.3) capistrano-rbenv (2.1.4)
capistrano (~> 3.1) capistrano (~> 3.1)
sshkit (~> 1.3) sshkit (~> 1.3)
capistrano-yarn (2.0.2) capistrano-yarn (2.0.2)
capistrano (~> 3.0) capistrano (~> 3.0)
capybara (2.18.0) capybara (3.8.2)
addressable addressable
mini_mime (>= 0.1.3) mini_mime (>= 0.1.3)
nokogiri (>= 1.3.3) nokogiri (~> 1.8)
rack (>= 1.0.0) rack (>= 1.6.0)
rack-test (>= 0.5.4) rack-test (>= 0.6.3)
xpath (>= 2.0, < 4.0) xpath (~> 3.1)
case_transform (0.2) case_transform (0.2)
activesupport activesupport
charlock_holmes (0.7.6) charlock_holmes (0.7.6)
@ -154,7 +156,7 @@ GEM
css_parser (1.6.0) css_parser (1.6.0)
addressable addressable
debug_inspector (0.0.3) debug_inspector (0.0.3)
derailed_benchmarks (1.3.4) derailed_benchmarks (1.3.5)
benchmark-ips (~> 2) benchmark-ips (~> 2)
get_process_mem (~> 0) get_process_mem (~> 0)
heapy (~> 0) heapy (~> 0)
@ -211,27 +213,28 @@ GEM
faraday (0.15.0) faraday (0.15.0)
multipart-post (>= 1.2, < 3) multipart-post (>= 1.2, < 3)
fast_blank (1.0.0) fast_blank (1.0.0)
fastimage (2.1.1) fastimage (2.1.4)
ffi (1.9.25) ffi (1.9.25)
fog-core (1.45.0) fog-core (2.1.2)
builder builder
excon (~> 0.58) excon (~> 0.58)
formatador (~> 0.2) formatador (~> 0.2)
fog-json (1.0.2) mime-types
fog-core (~> 1.0) fog-json (1.2.0)
fog-core
multi_json (~> 1.10) multi_json (~> 1.10)
fog-openstack (0.1.25) fog-openstack (1.0.3)
fog-core (~> 1.40) fog-core (~> 2.1)
fog-json (>= 1.0) fog-json (>= 1.0)
ipaddress (>= 0.8) ipaddress (>= 0.8)
formatador (0.2.5) formatador (0.2.5)
fugit (1.1.6) fugit (1.1.6)
et-orbi (~> 1.1, >= 1.1.6) et-orbi (~> 1.1, >= 1.1.6)
raabro (~> 1.1) raabro (~> 1.1)
fuubar (2.3.1) fuubar (2.3.2)
rspec-core (~> 3.0) rspec-core (~> 3.0)
ruby-progressbar (~> 1.4) ruby-progressbar (~> 1.4)
get_process_mem (0.2.1) get_process_mem (0.2.2)
globalid (0.4.1) globalid (0.4.1)
activesupport (>= 4.2.0) activesupport (>= 4.2.0)
goldfinger (2.1.0) goldfinger (2.1.0)
@ -252,7 +255,7 @@ GEM
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
hashdiff (0.3.7) hashdiff (0.3.7)
hashie (3.5.7) hashie (3.5.7)
heapy (0.1.3) heapy (0.1.4)
highline (1.7.10) highline (1.7.10)
hiredis (0.6.1) hiredis (0.6.1)
hitimes (1.3.0) hitimes (1.3.0)
@ -260,18 +263,18 @@ GEM
html2text (0.2.1) html2text (0.2.1)
nokogiri (~> 1.6) nokogiri (~> 1.6)
htmlentities (4.3.4) htmlentities (4.3.4)
http (3.2.0) http (3.3.0)
addressable (~> 2.3) addressable (~> 2.3)
http-cookie (~> 1.0) http-cookie (~> 1.0)
http-form_data (~> 2.0) http-form_data (~> 2.0)
http_parser.rb (~> 0.6.0) http_parser.rb (~> 0.6.0)
http-cookie (1.0.3) http-cookie (1.0.3)
domain_name (~> 0.5) domain_name (~> 0.5)
http-form_data (2.1.0) http-form_data (2.1.1)
http_accept_language (2.1.1) http_accept_language (2.1.1)
httplog (1.0.2) httplog (1.1.1)
colorize (~> 0.8)
rack (>= 1.0) rack (>= 1.0)
rainbow (>= 2.0.0)
i18n (1.1.0) i18n (1.1.0)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
i18n-tasks (0.9.21) i18n-tasks (0.9.21)
@ -287,6 +290,7 @@ GEM
idn-ruby (0.1.0) idn-ruby (0.1.0)
ipaddress (0.8.3) ipaddress (0.8.3)
iso-639 (0.2.8) iso-639 (0.2.8)
jaro_winkler (1.5.1)
jmespath (1.4.0) jmespath (1.4.0)
json (2.1.0) json (2.1.0)
json-ld (2.2.1) json-ld (2.2.1)
@ -340,7 +344,7 @@ GEM
mime-types-data (~> 3.2015) mime-types-data (~> 3.2015)
mime-types-data (3.2018.0812) mime-types-data (3.2018.0812)
mimemagic (0.3.2) mimemagic (0.3.2)
mini_mime (1.0.0) mini_mime (1.0.1)
mini_portile2 (2.3.0) mini_portile2 (2.3.0)
minitest (5.11.3) minitest (5.11.3)
msgpack (1.2.4) msgpack (1.2.4)
@ -352,7 +356,7 @@ GEM
net-ssh (>= 2.6.5) net-ssh (>= 2.6.5)
net-ssh (5.0.2) net-ssh (5.0.2)
nio4r (2.3.1) nio4r (2.3.1)
nokogiri (1.8.4) nokogiri (1.8.5)
mini_portile2 (~> 2.3.0) mini_portile2 (~> 2.3.0)
nokogumbo (1.5.0) nokogumbo (1.5.0)
nokogiri nokogiri
@ -390,16 +394,16 @@ GEM
parallel (1.12.1) parallel (1.12.1)
parallel_tests (2.21.3) parallel_tests (2.21.3)
parallel parallel
parser (2.5.1.0) parser (2.5.1.2)
ast (~> 2.4.0) ast (~> 2.4.0)
pastel (0.7.2) pastel (0.7.2)
equatable (~> 0.5.0) equatable (~> 0.5.0)
tty-color (~> 0.4.0) tty-color (~> 0.4.0)
pg (1.0.0) pg (1.1.3)
pghero (2.2.0) pghero (2.2.0)
activerecord activerecord
pkg-config (1.3.1) pkg-config (1.3.1)
powerpack (0.1.1) powerpack (0.1.2)
premailer (1.11.1) premailer (1.11.1)
addressable addressable
css_parser (>= 1.6.0) css_parser (>= 1.6.0)
@ -416,14 +420,14 @@ GEM
pry (~> 0.10) pry (~> 0.10)
pry-rails (0.3.6) pry-rails (0.3.6)
pry (>= 0.10.4) pry (>= 0.10.4)
public_suffix (3.0.2) public_suffix (3.0.3)
puma (3.11.4) puma (3.11.4)
pundit (1.1.0) pundit (1.1.0)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
raabro (1.1.6) raabro (1.1.6)
rack (2.0.5) rack (2.0.5)
rack-attack (5.2.0) rack-attack (5.4.1)
rack rack (>= 1.0, < 3)
rack-cors (1.0.2) rack-cors (1.0.2)
rack-protection (2.0.4) rack-protection (2.0.4)
rack rack
@ -474,7 +478,7 @@ GEM
link_header (~> 0.0, >= 0.0.8) link_header (~> 0.0, >= 0.0.8)
rdf-normalize (0.3.3) rdf-normalize (0.3.3)
rdf (>= 2.2, < 4.0) rdf (>= 2.2, < 4.0)
redis (4.0.1) redis (4.0.2)
redis-actionpack (5.0.2) redis-actionpack (5.0.2)
actionpack (>= 4.0, < 6) actionpack (>= 4.0, < 6)
redis-rack (>= 1, < 3) redis-rack (>= 1, < 3)
@ -502,29 +506,30 @@ GEM
rpam2 (4.0.2) rpam2 (4.0.2)
rqrcode (0.10.1) rqrcode (0.10.1)
chunky_png (~> 1.0) chunky_png (~> 1.0)
rspec-core (3.7.1) rspec-core (3.8.0)
rspec-support (~> 3.7.0) rspec-support (~> 3.8.0)
rspec-expectations (3.7.0) rspec-expectations (3.8.1)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.7.0) rspec-support (~> 3.8.0)
rspec-mocks (3.7.0) rspec-mocks (3.8.0)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.7.0) rspec-support (~> 3.8.0)
rspec-rails (3.7.2) rspec-rails (3.8.0)
actionpack (>= 3.0) actionpack (>= 3.0)
activesupport (>= 3.0) activesupport (>= 3.0)
railties (>= 3.0) railties (>= 3.0)
rspec-core (~> 3.7.0) rspec-core (~> 3.8.0)
rspec-expectations (~> 3.7.0) rspec-expectations (~> 3.8.0)
rspec-mocks (~> 3.7.0) rspec-mocks (~> 3.8.0)
rspec-support (~> 3.7.0) rspec-support (~> 3.8.0)
rspec-sidekiq (3.0.3) rspec-sidekiq (3.0.3)
rspec-core (~> 3.0, >= 3.0.0) rspec-core (~> 3.0, >= 3.0.0)
sidekiq (>= 2.4.0) sidekiq (>= 2.4.0)
rspec-support (3.7.1) rspec-support (3.8.0)
rubocop (0.55.0) rubocop (0.59.2)
jaro_winkler (~> 1.5.1)
parallel (~> 1.10) parallel (~> 1.10)
parser (>= 2.5) parser (>= 2.5, != 2.5.1.1)
powerpack (~> 0.1) powerpack (~> 0.1)
rainbow (>= 2.2.2, < 4.0) rainbow (>= 2.2.2, < 4.0)
ruby-progressbar (~> 1.7) ruby-progressbar (~> 1.7)
@ -624,11 +629,11 @@ GEM
unf (0.1.4) unf (0.1.4)
unf_ext unf_ext
unf_ext (0.0.7.5) unf_ext (0.0.7.5)
unicode-display_width (1.3.2) unicode-display_width (1.4.0)
uniform_notifier (1.11.0) uniform_notifier (1.11.0)
warden (1.2.7) warden (1.2.7)
rack (>= 1.0) rack (>= 1.0)
webmock (3.3.0) webmock (3.4.2)
addressable (>= 2.3.6) addressable (>= 2.3.6)
crack (>= 0.3.2) crack (>= 0.3.2)
hashdiff hashdiff
@ -636,14 +641,14 @@ GEM
activesupport (>= 4.2) activesupport (>= 4.2)
rack-proxy (>= 0.6.1) rack-proxy (>= 0.6.1)
railties (>= 4.2) railties (>= 4.2)
webpush (0.3.3) webpush (0.3.4)
hkdf (~> 0.2) hkdf (~> 0.2)
jwt (~> 2.0) jwt (~> 2.0)
websocket-driver (0.7.0) websocket-driver (0.7.0)
websocket-extensions (>= 0.1.0) websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.3) websocket-extensions (0.1.3)
wisper (2.0.0) wisper (2.0.0)
xpath (3.0.0) xpath (3.1.0)
nokogiri (~> 1.8) nokogiri (~> 1.8)
PLATFORMS PLATFORMS
@ -654,11 +659,11 @@ DEPENDENCIES
active_record_query_trace (~> 1.5) active_record_query_trace (~> 1.5)
addressable (~> 2.5) addressable (~> 2.5)
annotate (~> 2.7) annotate (~> 2.7)
aws-sdk-s3 (~> 1.9) aws-sdk-s3 (~> 1.20)
better_errors (~> 2.4) better_errors (~> 2.4)
binding_of_caller (~> 0.7) binding_of_caller (~> 0.7)
bootsnap (~> 1.3) bootsnap (~> 1.3)
brakeman (~> 4.2) brakeman (~> 4.3)
browser browser
bullet (~> 5.7) bullet (~> 5.7)
bundler-audit (~> 0.6) bundler-audit (~> 0.6)
@ -666,11 +671,12 @@ DEPENDENCIES
capistrano-rails (~> 1.3) capistrano-rails (~> 1.3)
capistrano-rbenv (~> 2.1) capistrano-rbenv (~> 2.1)
capistrano-yarn (~> 2.0) capistrano-yarn (~> 2.0)
capybara (~> 2.18) capybara (~> 3.8)
charlock_holmes (~> 0.7.6) charlock_holmes (~> 0.7.6)
chewy (~> 5.0) chewy (~> 5.0)
cld3 (~> 3.2.0) cld3 (~> 3.2.0)
climate_control (~> 0.2) climate_control (~> 0.2)
colorize
derailed_benchmarks derailed_benchmarks
devise (~> 4.5) devise (~> 4.5)
devise-two-factor (~> 3.0) devise-two-factor (~> 3.0)
@ -681,18 +687,18 @@ DEPENDENCIES
faker (~> 1.8) faker (~> 1.8)
fast_blank (~> 1.0) fast_blank (~> 1.0)
fastimage fastimage
fog-core (~> 1.45) fog-core (~> 2.1)
fog-openstack (~> 0.1) fog-openstack (~> 1.0)
fuubar (~> 2.2) fuubar (~> 2.3)
goldfinger (~> 2.1) goldfinger (~> 2.1)
hamlit-rails (~> 0.2) hamlit-rails (~> 0.2)
hiredis (~> 0.6) hiredis (~> 0.6)
html2text html2text
htmlentities (~> 4.3) htmlentities (~> 4.3)
http (~> 3.2) http (~> 3.3)
http_accept_language (~> 2.1) http_accept_language (~> 2.1)
http_parser.rb (~> 0.6)! http_parser.rb (~> 0.6)!
httplog (~> 1.0) httplog (~> 1.1)
i18n-tasks (~> 0.9) i18n-tasks (~> 0.9)
idn-ruby idn-ruby
iso-639 iso-639
@ -719,7 +725,7 @@ DEPENDENCIES
paperclip (~> 6.0) paperclip (~> 6.0)
paperclip-av-transcoder (~> 0.6) paperclip-av-transcoder (~> 0.6)
parallel_tests (~> 2.21) parallel_tests (~> 2.21)
pg (~> 1.0) pg (~> 1.1)
pghero (~> 2.2) pghero (~> 2.2)
pkg-config (~> 1.3) pkg-config (~> 1.3)
posix-spawn! posix-spawn!
@ -729,7 +735,7 @@ DEPENDENCIES
pry-rails (~> 0.3) pry-rails (~> 0.3)
puma (~> 3.11) puma (~> 3.11)
pundit (~> 1.1) pundit (~> 1.1)
rack-attack (~> 5.2) rack-attack (~> 5.4)
rack-cors (~> 1.0) rack-cors (~> 1.0)
rails (~> 5.2.1) rails (~> 5.2.1)
rails-controller-testing (~> 1.0) rails-controller-testing (~> 1.0)
@ -740,9 +746,9 @@ DEPENDENCIES
redis-namespace (~> 1.5) redis-namespace (~> 1.5)
redis-rails (~> 5.0) redis-rails (~> 5.0)
rqrcode (~> 0.10) rqrcode (~> 0.10)
rspec-rails (~> 3.7) rspec-rails (~> 3.8)
rspec-sidekiq (~> 3.0) rspec-sidekiq (~> 3.0)
rubocop (~> 0.55) rubocop (~> 0.59)
ruby-progressbar (~> 1.4) ruby-progressbar (~> 1.4)
sanitize (~> 4.6) sanitize (~> 4.6)
scss_lint (~> 0.57) scss_lint (~> 0.57)
@ -763,7 +769,7 @@ DEPENDENCIES
tty-prompt (~> 0.17) tty-prompt (~> 0.17)
twitter-text (~> 1.14) twitter-text (~> 1.14)
tzinfo-data (~> 1.2018) tzinfo-data (~> 1.2018)
webmock (~> 3.3) webmock (~> 3.4)
webpacker (~> 3.5) webpacker (~> 3.5)
webpush webpush
@ -771,4 +777,4 @@ RUBY VERSION
ruby 2.5.0p0 ruby 2.5.0p0
BUNDLED WITH BUNDLED WITH
1.16.3 1.16.5

View File

@ -95,7 +95,7 @@ module Admin
:remote, :remote,
:by_domain, :by_domain,
:silenced, :silenced,
:recent, :alphabetic,
:suspended, :suspended,
:username, :username,
:display_name, :display_name,

View File

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
module Admin::FilterHelper module Admin::FilterHelper
ACCOUNT_FILTERS = %i(local remote by_domain silenced suspended recent username display_name email ip staff).freeze ACCOUNT_FILTERS = %i(local remote by_domain silenced suspended alphabetic username display_name email ip staff).freeze
REPORT_FILTERS = %i(resolved account_id target_account_id).freeze REPORT_FILTERS = %i(resolved account_id target_account_id).freeze
INVITE_FILTER = %i(available expired).freeze INVITE_FILTER = %i(available expired).freeze
CUSTOM_EMOJI_FILTERS = %i(local remote by_domain shortcode).freeze CUSTOM_EMOJI_FILTERS = %i(local remote by_domain shortcode).freeze

View File

@ -26,7 +26,7 @@ class ActivityPub::Activity::Accept < ActivityPub::Activity
end end
def relay def relay
@relay ||= Relay.find_by(follow_activity_id: object_uri) @relay ||= Relay.find_by(follow_activity_id: object_uri) unless object_uri.nil?
end end
def relay_follow? def relay_follow?

View File

@ -17,6 +17,8 @@ class ActivityPub::Activity::Delete < ActivityPub::Activity
end end
def delete_note def delete_note
return if object_uri.nil?
@status = Status.find_by(uri: object_uri, account: @account) @status = Status.find_by(uri: object_uri, account: @account)
@status ||= Status.find_by(uri: @object['atomUri'], account: @account) if @object.is_a?(Hash) && @object['atomUri'].present? @status ||= Status.find_by(uri: @object['atomUri'], account: @account) if @object.is_a?(Hash) && @object['atomUri'].present?

View File

@ -28,7 +28,7 @@ class ActivityPub::Activity::Reject < ActivityPub::Activity
end end
def relay def relay
@relay ||= Relay.find_by(follow_activity_id: object_uri) @relay ||= Relay.find_by(follow_activity_id: object_uri) unless object_uri.nil?
end end
def relay_follow? def relay_follow?

View File

@ -19,6 +19,8 @@ class ActivityPub::Activity::Undo < ActivityPub::Activity
private private
def undo_announce def undo_announce
return if object_uri.nil?
status = Status.find_by(uri: object_uri, account: @account) status = Status.find_by(uri: object_uri, account: @account)
status ||= Status.find_by(uri: @object['atomUri'], account: @account) if @object.is_a?(Hash) && @object['atomUri'].present? status ||= Status.find_by(uri: @object['atomUri'], account: @account) if @object.is_a?(Hash) && @object['atomUri'].present?

View File

@ -315,8 +315,8 @@ class Account < ApplicationRecord
def initialize(account, attributes) def initialize(account, attributes)
@account = account @account = account
@attributes = attributes @attributes = attributes
@name = attributes['name'].strip[0, 255] @name = attributes['name'].strip[0, string_limit]
@value = attributes['value'].strip[0, 255] @value = attributes['value'].strip[0, string_limit]
@verified_at = attributes['verified_at']&.to_datetime @verified_at = attributes['verified_at']&.to_datetime
@errors = {} @errors = {}
end end
@ -325,8 +325,18 @@ class Account < ApplicationRecord
verified_at.present? verified_at.present?
end end
def value_for_verification
@value_for_verification ||= begin
if account.local?
value
else
ActionController::Base.helpers.strip_tags(value)
end
end
end
def verifiable? def verifiable?
value.present? && value.start_with?('http://', 'https://') value_for_verification.present? && value_for_verification.start_with?('http://', 'https://')
end end
def mark_verified! def mark_verified!
@ -337,6 +347,16 @@ class Account < ApplicationRecord
def to_h def to_h
{ name: @name, value: @value, verified_at: @verified_at } { name: @name, value: @value, verified_at: @verified_at }
end end
private
def string_limit
if account.local?
255
else
2047
end
end
end end
class << self class << self

View File

@ -8,7 +8,7 @@ class AccountFilter
end end
def results def results
scope = Account.alphabetic scope = Account.recent
params.each do |key, value| params.each do |key, value|
scope.merge!(scope_for(key, value)) if value.present? scope.merge!(scope_for(key, value)) if value.present?
@ -29,8 +29,8 @@ class AccountFilter
Account.where(domain: value) Account.where(domain: value)
when 'silenced' when 'silenced'
Account.silenced Account.silenced
when 'recent' when 'alphabetic'
Account.recent Account.reorder(nil).alphabetic
when 'suspended' when 'suspended'
Account.suspended Account.suspended
when 'username' when 'username'

View File

@ -25,6 +25,7 @@ class Follow < ApplicationRecord
has_one :notification, as: :activity, dependent: :destroy has_one :notification, as: :activity, dependent: :destroy
validates :account_id, uniqueness: { scope: :target_account_id } validates :account_id, uniqueness: { scope: :target_account_id }
validates_with FollowLimitValidator, on: :create
scope :recent, -> { reorder(id: :desc) } scope :recent, -> { reorder(id: :desc) }

View File

@ -22,6 +22,7 @@ class FollowRequest < ApplicationRecord
has_one :notification, as: :activity, dependent: :destroy has_one :notification, as: :activity, dependent: :destroy
validates :account_id, uniqueness: { scope: :target_account_id } validates :account_id, uniqueness: { scope: :target_account_id }
validates_with FollowLimitValidator, on: :create
def authorize! def authorize!
account.follow!(target_account, reblogs: show_reblogs, uri: uri) account.follow!(target_account, reblogs: show_reblogs, uri: uri)

View File

@ -11,11 +11,7 @@ class REST::AccountSerializer < ActiveModel::Serializer
has_many :emojis, serializer: REST::CustomEmojiSerializer has_many :emojis, serializer: REST::CustomEmojiSerializer
class FieldSerializer < ActiveModel::Serializer class FieldSerializer < ActiveModel::Serializer
attributes :name, :value attributes :name, :value, :verified_at
attribute :verified_at, if: :verifiable?
delegate :verifiable?, to: :object
def value def value
Formatter.instance.format_field(object.account, object.value) Formatter.instance.format_field(object.account, object.value)

View File

@ -3,7 +3,7 @@
class VerifyLinkService < BaseService class VerifyLinkService < BaseService
def call(field) def call(field)
@link_back = ActivityPub::TagManager.instance.url_for(field.account) @link_back = ActivityPub::TagManager.instance.url_for(field.account)
@url = field.value @url = field.value_for_verification
perform_request! perform_request!

View File

@ -0,0 +1,27 @@
# frozen_string_literal: true
class FollowLimitValidator < ActiveModel::Validator
LIMIT = ENV.fetch('MAX_FOLLOWS_THRESHOLD', 7_500).to_i
RATIO = ENV.fetch('MAX_FOLLOWS_RATIO', 1.1).to_f
def validate(follow)
return if follow.account.nil? || !follow.account.local?
follow.errors.add(:base, I18n.t('users.follow_limit_reached', limit: self.class.limit_for_account(follow.account))) if limit_reached?(follow.account)
end
class << self
def limit_for_account(account)
if account.following_count < LIMIT
LIMIT
else
account.followers_count * RATIO
end
end
end
private
def limit_reached?(account)
account.following_count >= self.class.limit_for_account(account)
end
end

View File

@ -38,8 +38,8 @@
.filter-subset .filter-subset
%strong= t('admin.accounts.order.title') %strong= t('admin.accounts.order.title')
%ul %ul
%li= filter_link_to t('admin.accounts.order.alphabetic'), recent: nil %li= filter_link_to t('admin.accounts.order.most_recent'), alphabetic: nil
%li= filter_link_to t('admin.accounts.order.most_recent'), recent: '1' %li= filter_link_to t('admin.accounts.order.alphabetic'), alphabetic: '1'
= form_tag admin_accounts_url, method: 'GET', class: 'simple_form' do = form_tag admin_accounts_url, method: 'GET', class: 'simple_form' do
.fields-group .fields-group

View File

@ -37,6 +37,8 @@ class ImportWorker
end end
def import_rows def import_rows
CSV.new(import_contents).reject(&:blank?) rows = CSV.new(import_contents).reject(&:blank?)
rows = rows.take(FollowLimitValidator.limit_for_account(@import.account)) if @import.type == 'following'
rows
end end
end end

View File

@ -42,7 +42,7 @@ Rails.application.configure do
config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
# Allow to specify public IP of reverse proxy if it's needed # Allow to specify public IP of reverse proxy if it's needed
config.action_dispatch.trusted_proxies = ENV['TRUSTED_PROXY_IP'].split.map { |item| IPAddr.new(item) } unless ENV['TRUSTED_PROXY_IP'].blank? config.action_dispatch.trusted_proxies = ENV['TRUSTED_PROXY_IP'].split.map { |item| IPAddr.new(item) } if ENV['TRUSTED_PROXY_IP'].present?
# Use the lowest log level to ensure availability of diagnostic information # Use the lowest log level to ensure availability of diagnostic information
# when problems arise. # when problems arise.

View File

@ -3,7 +3,7 @@ Rails.application.config.middleware.use OmniAuth::Builder do
end end
Devise.setup do |config| Devise.setup do |config|
# Devise omniauth strategies # Devise omniauth strategies
options = {} options = {}
options[:redirect_at_sign_in] = ENV['OAUTH_REDIRECT_AT_SIGN_IN'] == 'true' options[:redirect_at_sign_in] = ENV['OAUTH_REDIRECT_AT_SIGN_IN'] == 'true'
@ -62,5 +62,4 @@ Devise.setup do |config|
saml_options[:uid_attribute] = ENV['SAML_UID_ATTRIBUTE'] if ENV['SAML_UID_ATTRIBUTE'] saml_options[:uid_attribute] = ENV['SAML_UID_ATTRIBUTE'] if ENV['SAML_UID_ATTRIBUTE']
config.omniauth :saml, saml_options config.omniauth :saml, saml_options
end end
end end

View File

@ -1,7 +1,7 @@
require 'open-uri' require 'open-uri'
module OpenURI module OpenURI
def OpenURI.redirectable?(uri1, uri2) # :nodoc: def self.redirectable?(uri1, uri2) # :nodoc:
uri1.scheme.downcase == uri2.scheme.downcase || uri1.scheme.downcase == uri2.scheme.downcase ||
(/\A(?:http|https|ftp)\z/i =~ uri1.scheme && /\A(?:http|https|ftp)\z/i =~ uri2.scheme) (/\A(?:http|https|ftp)\z/i =~ uri1.scheme && /\A(?:http|https|ftp)\z/i =~ uri2.scheme)
end end

View File

@ -42,7 +42,7 @@ class Rack::Attack
# (blocklist & throttles are skipped) # (blocklist & throttles are skipped)
Rack::Attack.safelist('allow from localhost') do |req| Rack::Attack.safelist('allow from localhost') do |req|
# Requests are allowed if the return value is truthy # Requests are allowed if the return value is truthy
'127.0.0.1' == req.ip || '::1' == req.ip req.ip == '127.0.0.1' || req.ip == '::1'
end end
throttle('throttle_authenticated_api', limit: 300, period: 5.minutes) do |req| throttle('throttle_authenticated_api', limit: 300, period: 5.minutes) do |req|

View File

@ -19,4 +19,4 @@ Sidekiq.configure_client do |config|
config.redis = redis_params config.redis = redis_params
end end
Sidekiq::Logging.logger.level = ::Logger::const_get(ENV.fetch('RAILS_LOG_LEVEL', 'info').upcase.to_s) Sidekiq::Logging.logger.level = ::Logger.const_get(ENV.fetch('RAILS_LOG_LEVEL', 'info').upcase.to_s)

View File

@ -1,6 +1,5 @@
module Twitter module Twitter
class Regex class Regex
REGEXEN[:valid_general_url_path_chars] = /[^\p{White_Space}\(\)\?]/iou REGEXEN[:valid_general_url_path_chars] = /[^\p{White_Space}\(\)\?]/iou
REGEXEN[:valid_url_path_ending_chars] = /[^\p{White_Space}\(\)\?!\*';:=\,\.\$%\[\]~&\|@]|(?:#{REGEXEN[:valid_url_balanced_parens]})/iou REGEXEN[:valid_url_path_ending_chars] = /[^\p{White_Space}\(\)\?!\*';:=\,\.\$%\[\]~&\|@]|(?:#{REGEXEN[:valid_url_balanced_parens]})/iou
REGEXEN[:valid_url_balanced_parens] = / REGEXEN[:valid_url_balanced_parens] = /

View File

@ -1,7 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
Rails.application.configure do Rails.application.configure do
# You can generate the keys using the following command (first is the private key, second is the public one) # You can generate the keys using the following command (first is the private key, second is the public one)
# You should only generate this once per instance. If you later decide to change it, all push subscription will # You should only generate this once per instance. If you later decide to change it, all push subscription will
# be invalidated, requiring the users to access the website again to resubscribe. # be invalidated, requiring the users to access the website again to resubscribe.

View File

@ -31,9 +31,9 @@ de:
privacy_policy: Datenschutzerklärung privacy_policy: Datenschutzerklärung
source_code: Quellcode source_code: Quellcode
status_count_after: status_count_after:
one: Status one: Statusmeldung
other: Status other: Statusmeldungen
status_count_before: die status_count_before: mit
terms: Nutzungsbedingungen terms: Nutzungsbedingungen
user_count_after: user_count_after:
one: Benutzer one: Benutzer

View File

@ -919,6 +919,7 @@ en:
tips: Tips tips: Tips
title: Welcome aboard, %{name}! title: Welcome aboard, %{name}!
users: users:
follow_limit_reached: You cannot follow more than %{limit} people
invalid_email: The e-mail address is invalid invalid_email: The e-mail address is invalid
invalid_otp_token: Invalid two-factor code invalid_otp_token: Invalid two-factor code
otp_lost_help_html: If you lost access to both, you may get in touch with %{email} otp_lost_help_html: If you lost access to both, you may get in touch with %{email}

View File

@ -1,7 +1,7 @@
threads_count = ENV.fetch('MAX_THREADS') { 5 }.to_i threads_count = ENV.fetch('MAX_THREADS') { 5 }.to_i
threads threads_count, threads_count threads threads_count, threads_count
if ENV['SOCKET'] then if ENV['SOCKET']
bind 'unix://' + ENV['SOCKET'] bind 'unix://' + ENV['SOCKET']
else else
port ENV.fetch('PORT') { 3000 } port ENV.fetch('PORT') { 3000 }

View File

@ -1,5 +1,4 @@
class ChangeTagSearchIndexToBtree < ActiveRecord::Migration[5.1] class ChangeTagSearchIndexToBtree < ActiveRecord::Migration[5.1]
def up def up
remove_index :tags, name: :hashtag_search_index remove_index :tags, name: :hashtag_search_index
execute 'CREATE INDEX hashtag_search_index ON tags (name text_pattern_ops);' execute 'CREATE INDEX hashtag_search_index ON tags (name text_pattern_ops);'

View File

@ -11,7 +11,6 @@
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 2018_08_20_232245) do ActiveRecord::Schema.define(version: 2018_08_20_232245) do
# These are extensions that must be enabled in order to support this database # These are extensions that must be enabled in order to support this database
enable_extension "plpgsql" enable_extension "plpgsql"

View File

@ -5,6 +5,7 @@ require_relative 'mastodon/media_cli'
require_relative 'mastodon/emoji_cli' require_relative 'mastodon/emoji_cli'
require_relative 'mastodon/accounts_cli' require_relative 'mastodon/accounts_cli'
require_relative 'mastodon/feeds_cli' require_relative 'mastodon/feeds_cli'
require_relative 'mastodon/settings_cli'
module Mastodon module Mastodon
class CLI < Thor class CLI < Thor
@ -19,5 +20,8 @@ module Mastodon
desc 'feeds SUBCOMMAND ...ARGS', 'Manage feeds' desc 'feeds SUBCOMMAND ...ARGS', 'Manage feeds'
subcommand 'feeds', Mastodon::FeedsCLI subcommand 'feeds', Mastodon::FeedsCLI
desc 'settings SUBCOMMAND ...ARGS', 'Manage dynamic settings'
subcommand 'settings', Mastodon::SettingsCLI
end end
end end

View File

@ -0,0 +1,26 @@
# frozen_string_literal: true
require_relative '../../config/boot'
require_relative '../../config/environment'
require_relative 'cli_helper'
module Mastodon
class RegistrationsCLI < Thor
desc 'open', 'Open registrations'
def open
Setting.open_registrations = true
say('OK', :green)
end
desc 'close', 'Close registrations'
def close
Setting.open_registrations = false
say('OK', :green)
end
end
class SettingsCLI < Thor
desc 'registrations SUBCOMMAND ...ARGS', 'Manage state of registrations'
subcommand 'registrations', RegistrationsCLI
end
end

View File

@ -1,7 +1,5 @@
# frozen_string_literal: true # frozen_string_literal: true
require 'optparse'
require 'colorize'
require 'tty-command' require 'tty-command'
require 'tty-prompt' require 'tty-prompt'
@ -390,25 +388,6 @@ namespace :mastodon do
end end
end end
namespace :push do
desc 'Unsubscribes from PuSH updates of feeds nobody follows locally'
task clear: :environment do
Pubsubhubbub::UnsubscribeWorker.push_bulk(Account.remote.without_followers.where.not(subscription_expires_at: nil).pluck(:id))
end
end
namespace :settings do
desc 'Open registrations on this instance'
task open_registrations: :environment do
Setting.open_registrations = true
end
desc 'Close registrations on this instance'
task close_registrations: :environment do
Setting.open_registrations = false
end
end
namespace :webpush do namespace :webpush do
desc 'Generate VAPID key' desc 'Generate VAPID key'
task generate_vapid_key: :environment do task generate_vapid_key: :environment do
@ -427,7 +406,3 @@ def disable_log_stdout!
HttpLog.configuration.logger = dev_null HttpLog.configuration.logger = dev_null
Paperclip.options[:log] = false Paperclip.options[:log] = false
end end
def prepare_for_options!
2.times { ARGV.shift }
end

View File

@ -25,7 +25,7 @@ RSpec.describe Admin::AccountsController, type: :controller do
expect(h[:remote]).to eq '1' expect(h[:remote]).to eq '1'
expect(h[:by_domain]).to eq 'domain' expect(h[:by_domain]).to eq 'domain'
expect(h[:silenced]).to eq '1' expect(h[:silenced]).to eq '1'
expect(h[:recent]).to eq '1' expect(h[:alphabetic]).to eq '1'
expect(h[:suspended]).to eq '1' expect(h[:suspended]).to eq '1'
expect(h[:username]).to eq 'username' expect(h[:username]).to eq 'username'
expect(h[:display_name]).to eq 'display name' expect(h[:display_name]).to eq 'display name'
@ -40,7 +40,7 @@ RSpec.describe Admin::AccountsController, type: :controller do
remote: '1', remote: '1',
by_domain: 'domain', by_domain: 'domain',
silenced: '1', silenced: '1',
recent: '1', alphabetic: '1',
suspended: '1', suspended: '1',
username: 'username', username: 'username',
display_name: 'display name', display_name: 'display name',
@ -75,7 +75,6 @@ RSpec.describe Admin::AccountsController, type: :controller do
end end
end end
describe 'POST #subscribe' do describe 'POST #subscribe' do
subject { post :subscribe, params: { id: account.id } } subject { post :subscribe, params: { id: account.id } }

View File

@ -15,7 +15,6 @@ describe Admin::ReportNotesController do
let(:report) { Fabricate(:report, action_taken: action_taken, action_taken_by_account_id: account_id) } let(:report) { Fabricate(:report, action_taken: action_taken, action_taken_by_account_id: account_id) }
context 'when parameter is valid' do context 'when parameter is valid' do
context 'when report is unsolved' do context 'when report is unsolved' do
let(:action_taken) { false } let(:action_taken) { false }
let(:account_id) { nil } let(:account_id) { nil }

View File

@ -25,7 +25,6 @@ RSpec.describe Api::V1::Statuses::FavouritedByAccountsController, type: :control
expect(response.headers['Link'].links.size).to eq(2) expect(response.headers['Link'].links.size).to eq(2)
end end
end end
end end
context 'without an oauth token' do context 'without an oauth token' do

View File

@ -42,5 +42,4 @@ describe Api::V1::StreamingController do
end end
end end
end end
end end

View File

@ -8,6 +8,7 @@ describe ApplicationController, type: :controller do
def index def index
send_export_file send_export_file
end end
def export_data def export_data
@export.account.username @export.account.username
end end

View File

@ -21,7 +21,6 @@ describe Settings::ApplicationsController do
end end
end end
describe 'GET #show' do describe 'GET #show' do
it 'returns http success' do it 'returns http success' do
get :show, params: { id: app.id } get :show, params: { id: app.id }

View File

@ -10,7 +10,6 @@ describe Settings::MigrationsController do
end end
describe 'GET #show' do describe 'GET #show' do
context 'when user is not sign in' do context 'when user is not sign in' do
subject { get :show } subject { get :show }
@ -45,7 +44,6 @@ describe Settings::MigrationsController do
end end
describe 'PUT #update' do describe 'PUT #update' do
context 'when user is not sign in' do context 'when user is not sign in' do
subject { put :update } subject { put :update }

View File

@ -1,3 +1,2 @@
Fabricator(:site_upload) do Fabricator(:site_upload) do
end end

View File

@ -170,7 +170,6 @@ RSpec.describe Formatter do
end end
end end
describe '#format_spoiler' do describe '#format_spoiler' do
subject { Formatter.instance.format_spoiler(status) } subject { Formatter.instance.format_spoiler(status) }

View File

@ -2,10 +2,10 @@ require 'rails_helper'
describe AccountFilter do describe AccountFilter do
describe 'with empty params' do describe 'with empty params' do
it 'defaults to alphabetic account list' do it 'defaults to recent account list' do
filter = described_class.new({}) filter = described_class.new({})
expect(filter.results).to eq Account.alphabetic expect(filter.results).to eq Account.recent
end end
end end
@ -60,7 +60,7 @@ describe AccountFilter do
end end
describe 'that call account methods' do describe 'that call account methods' do
%i(local remote silenced recent suspended).each do |option| %i(local remote silenced alphabetic suspended).each do |option|
it "delegates the #{option} option" do it "delegates the #{option} option" do
allow(Account).to receive(option).and_return(Account.none) allow(Account).to receive(option).and_return(Account.none)
filter = described_class.new({ option => true }) filter = described_class.new({ option => true })

View File

@ -1,5 +1,4 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe AccountModerationNote, type: :model do RSpec.describe AccountModerationNote, type: :model do
end end

View File

@ -1,5 +1,4 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe Admin::ActionLog, type: :model do RSpec.describe Admin::ActionLog, type: :model do
end end

View File

@ -1,5 +1,4 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe Backup, type: :model do RSpec.describe Backup, type: :model do
end end

View File

@ -1,5 +1,4 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe ConversationMute, type: :model do RSpec.describe ConversationMute, type: :model do
end end

View File

@ -1,5 +1,4 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe CustomFilter, type: :model do RSpec.describe CustomFilter, type: :model do
end end

View File

@ -23,6 +23,20 @@ RSpec.describe Follow, type: :model do
follow.valid? follow.valid?
expect(follow).to model_have_error_on_field(:target_account) expect(follow).to model_have_error_on_field(:target_account)
end end
it 'is invalid if account already follows too many people' do
alice.update(following_count: FollowLimitValidator::LIMIT)
expect(subject).to_not be_valid
expect(subject).to model_have_error_on_field(:base)
end
it 'is valid if account is only on the brink of following too many people' do
alice.update(following_count: FollowLimitValidator::LIMIT - 1)
expect(subject).to be_valid
expect(subject).to_not model_have_error_on_field(:base)
end
end end
describe 'recent' do describe 'recent' do

View File

@ -1,5 +1,4 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe ListAccount, type: :model do RSpec.describe ListAccount, type: :model do
end end

View File

@ -1,5 +1,4 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe List, type: :model do RSpec.describe List, type: :model do
end end

View File

@ -1,5 +1,4 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe Mute, type: :model do RSpec.describe Mute, type: :model do
end end

View File

@ -1,5 +1,4 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe PreviewCard, type: :model do RSpec.describe PreviewCard, type: :model do
end end

View File

@ -1,5 +1,4 @@
require 'rails_helper' require 'rails_helper'
RSpec.describe Web::Setting, type: :model do RSpec.describe Web::Setting, type: :model do
end end

View File

@ -3,6 +3,7 @@ require 'rails_helper'
RSpec.describe VerifyLinkService, type: :service do RSpec.describe VerifyLinkService, type: :service do
subject { described_class.new } subject { described_class.new }
context 'given a local account' do
let(:account) { Fabricate(:account, username: 'alice') } let(:account) { Fabricate(:account, username: 'alice') }
let(:field) { Account::Field.new(account, 'name' => 'Website', 'value' => 'http://example.com') } let(:field) { Account::Field.new(account, 'name' => 'Website', 'value' => 'http://example.com') }
@ -80,3 +81,29 @@ RSpec.describe VerifyLinkService, type: :service do
end end
end end
end end
context 'given a remote account' do
let(:account) { Fabricate(:account, username: 'alice', domain: 'example.com', url: 'https://profile.example.com/alice') }
let(:field) { Account::Field.new(account, 'name' => 'Website', 'value' => '<a href="http://example.com" rel="me"><span class="invisible">http://</span><span class="">example.com</span><span class="invisible"></span></a>') }
before do
stub_request(:get, 'http://example.com').to_return(status: 200, body: html)
subject.call(field)
end
context 'when a link contains an <a> back' do
let(:html) do
<<-HTML
<!doctype html>
<body>
<a href="https://profile.example.com/alice" rel="me">Follow me on Mastodon</a>
</body>
HTML
end
it 'marks the field as verified' do
expect(field.verified?).to be true
end
end
end
end