Prepare Mastodon for Rails 6 (#15911)

* Fix misuse of foreign_type

* Fix use of removed "add_template_helper"

* Use response.media_type instead of response.content_type in tests

* Fix CSV export controller test on Rails 6

Rails 6 sets a "filename*" field in the Content-Disposition header to
explicitly encode the filename as UTF-8.

This changes checks the first part of the Content-Disposition header so
it matches in both Rails 5 and Rails 6.

* Fix emoji formatting with Rails 6

* Make emoji output more idiomatic and robust

* Switch from redis-rails gem to built-in Rails redis cache storage
This commit is contained in:
Claire 2021-03-17 10:09:55 +01:00 committed by GitHub
parent 9cb6bc56fa
commit 43eff898a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 45 additions and 61 deletions

View File

@ -153,7 +153,6 @@ end
group :production do group :production do
gem 'lograge', '~> 0.11' gem 'lograge', '~> 0.11'
gem 'redis-rails', '~> 5.0'
end end
gem 'concurrent-ruby', require: false gem 'concurrent-ruby', require: false

View File

@ -491,24 +491,8 @@ GEM
rdf-normalize (0.4.0) rdf-normalize (0.4.0)
rdf (~> 3.1) rdf (~> 3.1)
redis (4.2.5) redis (4.2.5)
redis-actionpack (5.2.0)
actionpack (>= 5, < 7)
redis-rack (>= 2.1.0, < 3)
redis-store (>= 1.1.0, < 2)
redis-activesupport (5.2.0)
activesupport (>= 3, < 7)
redis-store (>= 1.3, < 2)
redis-namespace (1.8.1) redis-namespace (1.8.1)
redis (>= 3.0.4) redis (>= 3.0.4)
redis-rack (2.1.3)
rack (>= 2.0.8, < 3)
redis-store (>= 1.2, < 2)
redis-rails (5.0.2)
redis-actionpack (>= 5.0, < 6)
redis-activesupport (>= 5.0, < 6)
redis-store (>= 1.2, < 2)
redis-store (1.9.0)
redis (>= 4, < 5)
regexp_parser (2.1.1) regexp_parser (2.1.1)
request_store (1.5.0) request_store (1.5.0)
rack (>= 1.4) rack (>= 1.4)
@ -790,7 +774,6 @@ DEPENDENCIES
rdf-normalize (~> 0.4) rdf-normalize (~> 0.4)
redis (~> 4.2) redis (~> 4.2)
redis-namespace (~> 1.8) redis-namespace (~> 1.8)
redis-rails (~> 5.0)
rqrcode (~> 1.2) rqrcode (~> 1.2)
rspec-rails (~> 5.0) rspec-rails (~> 5.0)
rspec-sidekiq (~> 3.1) rspec-sidekiq (~> 3.1)

View File

@ -158,9 +158,9 @@ class Formatter
original_url, static_url = emoji original_url, static_url = emoji
replacement = begin replacement = begin
if animate if animate
"<img draggable=\"false\" class=\"emojione\" alt=\":#{encode(shortcode)}:\" title=\":#{encode(shortcode)}:\" src=\"#{encode(original_url)}\" />" image_tag(original_url, draggable: false, class: 'emojione', alt: ":#{shortcode}:", title: ":#{shortcode}:")
else else
"<img draggable=\"false\" class=\"emojione custom-emoji\" alt=\":#{encode(shortcode)}:\" title=\":#{encode(shortcode)}:\" src=\"#{encode(static_url)}\" data-original=\"#{original_url}\" data-static=\"#{static_url}\" />" image_tag(original_url, draggable: false, class: 'emojione custom-emoji', alt: ":#{shortcode}:", title: ":#{shortcode}:", data: { original: original_url, static: static_url })
end end
end end
before_html = shortname_start_index.positive? ? html[0..shortname_start_index - 1] : '' before_html = shortname_start_index.positive? ? html[0..shortname_start_index - 1] : ''

View File

@ -4,7 +4,7 @@ class NotificationMailer < ApplicationMailer
helper :accounts helper :accounts
helper :statuses helper :statuses
add_template_helper RoutingHelper helper RoutingHelper
def mention(recipient, notification) def mention(recipient, notification)
@me = recipient @me = recipient

View File

@ -8,7 +8,7 @@ class UserMailer < Devise::Mailer
helper :instance helper :instance
helper :statuses helper :statuses
add_template_helper RoutingHelper helper RoutingHelper
def confirmation_instructions(user, token, **) def confirmation_instructions(user, token, **)
@resource = user @resource = user

View File

@ -49,12 +49,12 @@ class Notification < ApplicationRecord
belongs_to :from_account, class_name: 'Account', optional: true belongs_to :from_account, class_name: 'Account', optional: true
belongs_to :activity, polymorphic: true, optional: true belongs_to :activity, polymorphic: true, optional: true
belongs_to :mention, foreign_type: 'Mention', foreign_key: 'activity_id', optional: true belongs_to :mention, foreign_key: 'activity_id', optional: true
belongs_to :status, foreign_type: 'Status', foreign_key: 'activity_id', optional: true belongs_to :status, foreign_key: 'activity_id', optional: true
belongs_to :follow, foreign_type: 'Follow', foreign_key: 'activity_id', optional: true belongs_to :follow, foreign_key: 'activity_id', optional: true
belongs_to :follow_request, foreign_type: 'FollowRequest', foreign_key: 'activity_id', optional: true belongs_to :follow_request, foreign_key: 'activity_id', optional: true
belongs_to :favourite, foreign_type: 'Favourite', foreign_key: 'activity_id', optional: true belongs_to :favourite, foreign_key: 'activity_id', optional: true
belongs_to :poll, foreign_type: 'Poll', foreign_key: 'activity_id', optional: true belongs_to :poll, foreign_key: 'activity_id', optional: true
validates :type, inclusion: { in: TYPES } validates :type, inclusion: { in: TYPES }

View File

@ -17,7 +17,7 @@ Rails.application.configure do
if Rails.root.join('tmp/caching-dev.txt').exist? if Rails.root.join('tmp/caching-dev.txt').exist?
config.action_controller.perform_caching = true config.action_controller.perform_caching = true
config.cache_store = :redis_store, ENV['REDIS_URL'], REDIS_CACHE_PARAMS config.cache_store = :redis_cache_store, REDIS_CACHE_PARAMS
config.public_file_server.headers = { config.public_file_server.headers = {
'Cache-Control' => "public, max-age=#{2.days.to_i}", 'Cache-Control' => "public, max-age=#{2.days.to_i}",

View File

@ -52,7 +52,7 @@ Rails.application.configure do
config.log_tags = [:request_id] config.log_tags = [:request_id]
# Use a different cache store in production. # Use a different cache store in production.
config.cache_store = :redis_store, ENV['CACHE_REDIS_URL'], REDIS_CACHE_PARAMS config.cache_store = :redis_cache_store, REDIS_CACHE_PARAMS
# Ignore bad email addresses and do not raise email delivery errors. # Ignore bad email addresses and do not raise email delivery errors.
# Set this to true and configure the email server for immediate delivery to raise delivery errors. # Set this to true and configure the email server for immediate delivery to raise delivery errors.

View File

@ -1,7 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
namespace = ENV.fetch('REDIS_NAMESPACE') { nil } namespace = ENV.fetch('REDIS_NAMESPACE') { nil }
redis_params = { url: ENV['REDIS_URL'] } redis_params = { url: ENV['REDIS_URL'], driver: :hiredis }
if namespace if namespace
redis_params[:namespace] = namespace redis_params[:namespace] = namespace

View File

@ -27,6 +27,8 @@ namespace = ENV.fetch('REDIS_NAMESPACE', nil)
cache_namespace = namespace ? namespace + '_cache' : 'cache' cache_namespace = namespace ? namespace + '_cache' : 'cache'
REDIS_CACHE_PARAMS = { REDIS_CACHE_PARAMS = {
driver: :hiredis,
url: ENV['REDIS_URL'],
expires_in: 10.minutes, expires_in: 10.minutes,
namespace: cache_namespace, namespace: cache_namespace,
}.freeze }.freeze

View File

@ -370,7 +370,7 @@ RSpec.describe AccountsController, type: :controller do
end end
it 'returns application/activity+json' do it 'returns application/activity+json' do
expect(response.content_type).to eq 'application/activity+json' expect(response.media_type).to eq 'application/activity+json'
end end
it_behaves_like 'cachable response' it_behaves_like 'cachable response'
@ -402,7 +402,7 @@ RSpec.describe AccountsController, type: :controller do
end end
it 'returns application/activity+json' do it 'returns application/activity+json' do
expect(response.content_type).to eq 'application/activity+json' expect(response.media_type).to eq 'application/activity+json'
end end
it 'returns public Cache-Control header' do it 'returns public Cache-Control header' do
@ -428,7 +428,7 @@ RSpec.describe AccountsController, type: :controller do
end end
it 'returns application/activity+json' do it 'returns application/activity+json' do
expect(response.content_type).to eq 'application/activity+json' expect(response.media_type).to eq 'application/activity+json'
end end
it_behaves_like 'cachable response' it_behaves_like 'cachable response'
@ -446,7 +446,7 @@ RSpec.describe AccountsController, type: :controller do
end end
it 'returns application/activity+json' do it 'returns application/activity+json' do
expect(response.content_type).to eq 'application/activity+json' expect(response.media_type).to eq 'application/activity+json'
end end
it 'returns private Cache-Control header' do it 'returns private Cache-Control header' do

View File

@ -43,7 +43,7 @@ RSpec.describe ActivityPub::CollectionsController, type: :controller do
end end
it 'returns application/activity+json' do it 'returns application/activity+json' do
expect(response.content_type).to eq 'application/activity+json' expect(response.media_type).to eq 'application/activity+json'
end end
it_behaves_like 'cachable response' it_behaves_like 'cachable response'
@ -88,7 +88,7 @@ RSpec.describe ActivityPub::CollectionsController, type: :controller do
end end
it 'returns application/activity+json' do it 'returns application/activity+json' do
expect(response.content_type).to eq 'application/activity+json' expect(response.media_type).to eq 'application/activity+json'
end end
it_behaves_like 'cachable response' it_behaves_like 'cachable response'
@ -116,7 +116,7 @@ RSpec.describe ActivityPub::CollectionsController, type: :controller do
end end
it 'returns application/activity+json' do it 'returns application/activity+json' do
expect(response.content_type).to eq 'application/activity+json' expect(response.media_type).to eq 'application/activity+json'
end end
it 'returns private Cache-Control header' do it 'returns private Cache-Control header' do
@ -141,7 +141,7 @@ RSpec.describe ActivityPub::CollectionsController, type: :controller do
end end
it 'returns application/activity+json' do it 'returns application/activity+json' do
expect(response.content_type).to eq 'application/activity+json' expect(response.media_type).to eq 'application/activity+json'
end end
it 'returns private Cache-Control header' do it 'returns private Cache-Control header' do

View File

@ -40,7 +40,7 @@ RSpec.describe ActivityPub::FollowersSynchronizationsController, type: :controll
end end
it 'returns application/activity+json' do it 'returns application/activity+json' do
expect(response.content_type).to eq 'application/activity+json' expect(response.media_type).to eq 'application/activity+json'
end end
it 'returns orderedItems with followers from example.com' do it 'returns orderedItems with followers from example.com' do

View File

@ -46,7 +46,7 @@ RSpec.describe ActivityPub::OutboxesController, type: :controller do
end end
it 'returns application/activity+json' do it 'returns application/activity+json' do
expect(response.content_type).to eq 'application/activity+json' expect(response.media_type).to eq 'application/activity+json'
end end
it 'returns totalItems' do it 'returns totalItems' do
@ -85,7 +85,7 @@ RSpec.describe ActivityPub::OutboxesController, type: :controller do
end end
it 'returns application/activity+json' do it 'returns application/activity+json' do
expect(response.content_type).to eq 'application/activity+json' expect(response.media_type).to eq 'application/activity+json'
end end
it 'returns orderedItems with public or unlisted statuses' do it 'returns orderedItems with public or unlisted statuses' do
@ -133,7 +133,7 @@ RSpec.describe ActivityPub::OutboxesController, type: :controller do
end end
it 'returns application/activity+json' do it 'returns application/activity+json' do
expect(response.content_type).to eq 'application/activity+json' expect(response.media_type).to eq 'application/activity+json'
end end
it 'returns orderedItems with public or unlisted statuses' do it 'returns orderedItems with public or unlisted statuses' do
@ -159,7 +159,7 @@ RSpec.describe ActivityPub::OutboxesController, type: :controller do
end end
it 'returns application/activity+json' do it 'returns application/activity+json' do
expect(response.content_type).to eq 'application/activity+json' expect(response.media_type).to eq 'application/activity+json'
end end
it 'returns orderedItems with private statuses' do it 'returns orderedItems with private statuses' do
@ -185,7 +185,7 @@ RSpec.describe ActivityPub::OutboxesController, type: :controller do
end end
it 'returns application/activity+json' do it 'returns application/activity+json' do
expect(response.content_type).to eq 'application/activity+json' expect(response.media_type).to eq 'application/activity+json'
end end
it 'returns empty orderedItems' do it 'returns empty orderedItems' do
@ -210,7 +210,7 @@ RSpec.describe ActivityPub::OutboxesController, type: :controller do
end end
it 'returns application/activity+json' do it 'returns application/activity+json' do
expect(response.content_type).to eq 'application/activity+json' expect(response.media_type).to eq 'application/activity+json'
end end
it 'returns empty orderedItems' do it 'returns empty orderedItems' do

View File

@ -73,7 +73,7 @@ RSpec.describe ActivityPub::RepliesController, type: :controller do
end end
it 'returns application/activity+json' do it 'returns application/activity+json' do
expect(response.content_type).to eq 'application/activity+json' expect(response.media_type).to eq 'application/activity+json'
end end
it_behaves_like 'cachable response' it_behaves_like 'cachable response'
@ -120,7 +120,7 @@ RSpec.describe ActivityPub::RepliesController, type: :controller do
end end
it 'returns application/activity+json' do it 'returns application/activity+json' do
expect(response.content_type).to eq 'application/activity+json' expect(response.media_type).to eq 'application/activity+json'
end end
it_behaves_like 'cachable response' it_behaves_like 'cachable response'

View File

@ -22,8 +22,8 @@ describe ApplicationController, type: :controller do
get :index, format: :csv get :index, format: :csv
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(response.content_type).to eq 'text/csv' expect(response.media_type).to eq 'text/csv'
expect(response.headers['Content-Disposition']).to eq 'attachment; filename="anonymous.csv"' expect(response.headers['Content-Disposition']).to start_with 'attachment; filename="anonymous.csv"'
expect(response.body).to eq user.account.username expect(response.body).to eq user.account.username
end end

View File

@ -8,7 +8,7 @@ describe WellKnown::HostMetaController, type: :controller do
get :show, format: :xml get :show, format: :xml
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(response.content_type).to eq 'application/xrd+xml' expect(response.media_type).to eq 'application/xrd+xml'
expect(response.body).to eq <<XML expect(response.body).to eq <<XML
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0"> <XRD xmlns="http://docs.oasis-open.org/ns/xri/xrd-1.0">

View File

@ -8,7 +8,7 @@ describe WellKnown::KeybaseProofConfigController, type: :controller do
get :show get :show
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(response.content_type).to eq 'application/json' expect(response.media_type).to eq 'application/json'
expect { JSON.parse(response.body) }.not_to raise_exception expect { JSON.parse(response.body) }.not_to raise_exception
end end
end end

View File

@ -8,7 +8,7 @@ describe WellKnown::NodeInfoController, type: :controller do
get :index get :index
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(response.content_type).to eq 'application/json' expect(response.media_type).to eq 'application/json'
json = body_as_json json = body_as_json
@ -23,7 +23,7 @@ describe WellKnown::NodeInfoController, type: :controller do
get :show get :show
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(response.content_type).to eq 'application/json' expect(response.media_type).to eq 'application/json'
json = body_as_json json = body_as_json

View File

@ -25,7 +25,7 @@ describe WellKnown::WebfingerController, type: :controller do
end end
it 'returns application/jrd+json' do it 'returns application/jrd+json' do
expect(response.content_type).to eq 'application/jrd+json' expect(response.media_type).to eq 'application/jrd+json'
end end
it 'returns links for the account' do it 'returns links for the account' do

View File

@ -6,7 +6,7 @@ describe "The catch all route" do
get "/test" get "/test"
expect(response.status).to eq 404 expect(response.status).to eq 404
expect(response.content_type).to eq "text/html" expect(response.media_type).to eq "text/html"
end end
end end
@ -15,7 +15,7 @@ describe "The catch all route" do
get "/test.test" get "/test.test"
expect(response.status).to eq 404 expect(response.status).to eq 404
expect(response.content_type).to eq "text/html" expect(response.media_type).to eq "text/html"
end end
end end
end end

View File

@ -6,7 +6,7 @@ describe "The host_meta route" do
get host_meta_url get host_meta_url
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(response.content_type).to eq "application/xrd+xml" expect(response.media_type).to eq "application/xrd+xml"
end end
end end
end end

View File

@ -8,7 +8,7 @@ describe 'The webfinger route' do
get webfinger_url(resource: alice.to_webfinger_s) get webfinger_url(resource: alice.to_webfinger_s)
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(response.content_type).to eq 'application/jrd+json' expect(response.media_type).to eq 'application/jrd+json'
end end
end end
@ -17,7 +17,7 @@ describe 'The webfinger route' do
get webfinger_url(resource: alice.to_webfinger_s, format: :json) get webfinger_url(resource: alice.to_webfinger_s, format: :json)
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(response.content_type).to eq 'application/jrd+json' expect(response.media_type).to eq 'application/jrd+json'
end end
it 'returns a json response for json accept header' do it 'returns a json response for json accept header' do
@ -25,7 +25,7 @@ describe 'The webfinger route' do
get webfinger_url(resource: alice.to_webfinger_s), headers: headers get webfinger_url(resource: alice.to_webfinger_s), headers: headers
expect(response).to have_http_status(200) expect(response).to have_http_status(200)
expect(response.content_type).to eq 'application/jrd+json' expect(response.media_type).to eq 'application/jrd+json'
end end
end end
end end