Skip to content

[FIX-1554] fixture_file_upload cannot find files #1880

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 3, 2017

Conversation

11factory
Copy link
Contributor

No description provided.

Copy link
Member

@JonRowe JonRowe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for tackling this, theres a few changes needed before we can merge this, and we need a green build.

@@ -0,0 +1,38 @@
require 'singleton'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can't be used as it would pollute any codebase using 'rspec-rails', please refactor to not need this.

@@ -83,6 +83,8 @@ def self.initialize_configuration(config)
if ::Rails::VERSION::STRING > '5'
config.add_setting :file_fixture_path, :default => 'spec/fixtures/files'
config.include RSpec::Rails::FileFixtureSupport
elsif ::Rails::VERSION::STRING >= '3'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't support Rails < 3 so this isn't needed.

@@ -0,0 +1,30 @@
require 'spec_helper'

describe RSpec::Rails::FixtureFileUploadSupport do
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/describe/RSpec.describe/ our test suite doesn't allow monkey patching

if ActionController::TestCase.respond_to?(:fixture_path)
ActionController::TestCase.fixture_path = value
end
@fixture_path = value
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to store the value if we can't set it? I think it'd be cleaner if we just implemented this in the main mix in and delegated directly to this with the resolved file.

Copy link
Contributor Author

@11factory 11factory Oct 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes because ActionDispatch::TestProcess is expecting class to respond to fixture_path
And I have to override setter method because of Rails 3 implementation of fixture_file_upload.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JonRowe CI seems to have some random failures / between 2 builds with exact same code differents environments are failing

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes because ActionDispatch::TestProcess is expecting class to respond to fixture_path

Thats fine we can implement fixture_path

And I have to override setter method because of Rails 3 implementation of fixture_file_upload.

Also fine, including the file does that hence why delegation works at all..

To be clear I think we should remove the delegation.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure to get your point - ActionController::TestCase is a class, I don't see a really better way to inject it the fixture_path

Copy link
Member

@JonRowe JonRowe Oct 23, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

module RSpec
  module Rails
    # @private
    module FixtureFileUploadSupport

      def self.included(other)
        if defined?(ActionDispatch::TestProcess)
          other.include ActionDispatch::TestProcess
        end
      end

      def fixture_path
        @fixture_path ||= calculate_path
      end

      def fixture_path=(value)
        # Rails 3.0..3.1 are using ActionController::TestCase class to resolve fixture_path
        # see https://apidock.com/rails/v3.0.0/ActionDispatch/TestProcess/fixture_file_upload
        if ActionController::TestCase.respond_to?(:fixture_path)
          ActionController::TestCase.fixture_path = value
        end
        @fixture_path = value
      end

      private

      def calculate_fixture_path
        resolved_fixture_path = (fixture_path || RSpec.configuration.fixture_path || '')
        self.fixture_path = File.join(resolved_fixture_path, '')
      end
    end
  end
end

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When FixtureFileUploadSupport is included it will define the relevant helpers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixture_path has to be defined as a class method / attribute given how rails resolves it: self.class.respond_to?(:fixture_path) && self.class.fixture_path.
And directly including ActionDispatch::TestProcess will come with other methods not related like cookies, session, ... , I prefer to keep isolated from that class as much as possible.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh that wasn't clear, in that case you need to do the definition inside another module and extend it:

module RSpec
  module Rails
    # @private
    module FixtureFileUploadSupport

      def self.included(other)
        if defined?(ActionDispatch::TestProcess)
          other.include ActionDispatch::TestProcess
        end
        other.extend FixturePathAttribute
      end

      module FixturePathAttribute

        def fixture_path
         @fixture_path ||= calculate_path
        end

        def fixture_path=(value)
          # Rails 3.0..3.1 are using ActionController::TestCase class to resolve fixture_path
          # see https://apidock.com/rails/v3.0.0/ActionDispatch/TestProcess/fixture_file_upload
          if ActionController::TestCase.respond_to?(:fixture_path)
            ActionController::TestCase.fixture_path = value
          end
          @fixture_path = value
        end

        private

        def calculate_fixture_path
          resolved_fixture_path = (fixture_path || RSpec.configuration.fixture_path || '')
          self.fixture_path = File.join(resolved_fixture_path, '')
        end
      end
    end
  end
end

@11factory 11factory force-pushed the fix-1554 branch 3 times, most recently from f00191d to 9d304d1 Compare October 18, 2017 00:19
@11factory
Copy link
Contributor Author

@JonRowe ping

@11factory
Copy link
Contributor Author

11factory commented Oct 25, 2017

I did the changes as suggested, but then still including unecessary methods to initial caller, it's your call.

@11factory
Copy link
Contributor Author

@JonRowe finally, suggested implementation was not working as expected.
I reverted the code to my first proposal, I let you see if you want to take it as it is or just drop it.

@JonRowe JonRowe merged commit 9bd0e41 into rspec:master Nov 3, 2017
@JonRowe
Copy link
Member

JonRowe commented Nov 3, 2017

Thanks, I'll refactor it a bit before release

@bmulholland
Copy link

This seems to have caused a regression: #1921

sebjacobs pushed a commit to futurelearn/rspec-rails that referenced this pull request Mar 15, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants