提交 91b6253a 编写于 作者: E Edouard CHIN

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 https://github.com/rails/rails/blob/22483b86a6c779743b30e2f23bb46accfbf96b28/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.
上级 785427b8
......@@ -5,11 +5,13 @@
module Mime
class Mimes
attr_reader :symbols
include Enumerable
def initialize
@mimes = []
@symbols = nil
@symbols = []
end
def each
......@@ -18,15 +20,16 @@ def each
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
......
# frozen_string_literal: true
require "abstract_unit"
ActionView::Base.default_formats ||= Mime::SET.symbols
class StarStarMimeController < ActionController::Base
layout nil
......
......@@ -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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册