1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00

Mime::Mimes#symbols should return a always up to date reference:

- Original issue was reported in https://github.com/rails/rails/issues/38094
  and a fix attempted in https://github.com/rails/rails/pull/38126 but
  it's not the proper fix I think.

  TL;DR Is that `ActionView::Base.default_formats` holds a copy of
  mime symbols at the time ActionView::Base is loaded.
  So if you try to register mime types after ActionView Base is loaded
  then it won't work.

  ```ruby
    ActionView::Base.default_formats ||= Mime::SET.symbols # Note that this is automatically done when ActionView get loaded 22483b86a6/actionpack/lib/action_dispatch.rb (L117)

   Mime::Type.register_alias "application/xhtml+xml", :foobar
   puts ActionView::base.defaults_formats.include?(:foobar) # => false
  ```

  Same issue if you try to unregister a mime after ActionView is loaded.
  That's what was happening in the flaky test:

  ```
   Mime::Type.register_alias "application/xhtml+xml", :foobar
   ActionView::Base.default_formats ||= Mime::SET.symbols

   puts ActionView::base.defaults_formats.include?(:foobar) # => true

   Mime::Type.unregister(:foobar)
   puts ActionView::base.defaults_formats.include?(:foobar) # => true
  ```

  ### Solution

  Return a refence to `@symbols` which is updated each time a new mime is
  registered/unregistered.
This commit is contained in:
Edouard CHIN 2020-01-02 18:05:33 +01:00
parent 785427b88c
commit 91b6253ade
3 changed files with 20 additions and 8 deletions

View file

@ -5,11 +5,13 @@ require "active_support/core_ext/string/starts_ends_with"
module Mime
class Mimes
attr_reader :symbols
include Enumerable
def initialize
@mimes = []
@symbols = nil
@symbols = []
end
def each
@ -18,15 +20,16 @@ module Mime
def <<(type)
@mimes << type
@symbols = nil
@symbols << type.to_sym
end
def delete_if
@mimes.delete_if { |x| yield x }.tap { @symbols = nil }
end
def symbols
@symbols ||= map(&:to_sym)
@mimes.delete_if do |x|
if yield x
@symbols.delete(x.to_sym)
true
end
end
end
end

View file

@ -1,7 +1,6 @@
# frozen_string_literal: true
require "abstract_unit"
ActionView::Base.default_formats ||= Mime::SET.symbols
class StarStarMimeController < ActionController::Base
layout nil

View file

@ -227,4 +227,14 @@ class MimeTypeTest < ActiveSupport::TestCase
Mime::Type.new(nil)
end
end
test "holds a reference to mime symbols" do
old_symbols = Mime::SET.symbols
Mime::Type.register_alias "application/xhtml+xml", :foobar
new_symbols = Mime::SET.symbols
assert_same(old_symbols, new_symbols)
ensure
Mime::Type.unregister(:foobar)
end
end