Search code examples
ruby-on-railscarrierwavefakeweb

Stub a image url and return an image


How can I stub a call to a url eg http://www.example.com/images/123.png and return an image named 123.png?

I'm using Rails 3.2, Carrierwave. I've tried Fakeweb but got a bit stumped.


Solution

  • After a few hours of research, turns out it's simple:

    FakeWeb.register_uri(:get, string_or_regxp_of_uri,
            body: SupportFiles.uploaded_file("square.jpg"),
            content_type: 'image/jpg')
    

    My problem is more tricky:
    I am testing FB avatar, and I got whitelst extension

    The above code will NOT work since the extension is missing
    (FB avatar URL: https://graph.facebook.com/123/picture)

    But the real FB avatar will redirect to a CDN or something that has the extension
    So you need to add another stub:

    # Register a fake remote image
    fake_avatar_uri = "https://graph.facebook.com/fake_avatar.jpg"
    # Redirect to a fake uri
    FakeWeb.register_uri(:get, %r|https://graph\.facebook\.com/|,
      status: ["301", "Moved Permanently"],
      location: fake_avatar_uri)
    # Feed fake image for the fake uri
    FakeWeb.register_uri(:get, fake_avatar_uri,
      body: SupportFiles.uploaded_file("square.jpg"),
      content_type: 'image/jpg')
    

    The SupportFiles module (not written by myself :P):

    require 'rack/test/uploaded_file'
    
    module SupportFiles
      extend ActiveSupport::Concern
    
      included do
        let(:an_image) do
          open_file("square.jpg")
        end
      end
    
    
      def open_file(filename)
        File.open(support_file_path(filename))
      end
    
      # idea stolen from ActionDispatch::TestProcess#fixture_file_upload
      def uploaded_file(filename)
        Rack::Test::UploadedFile.new(support_file_path(filename))
      end
      module_function :uploaded_file
    
      protected
    
      def support_file_path(filename)
        Rails.root.join("spec/support/files", filename)
      end
      module_function :support_file_path
    
    end