Skip to content
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

MiniTest assertions #193

Open
richardboehme opened this issue Feb 15, 2025 · 1 comment
Open

MiniTest assertions #193

richardboehme opened this issue Feb 15, 2025 · 1 comment

Comments

@richardboehme
Copy link

I'm currently using Inertia Rails in a new project in which we decided to use MiniTest for testing (which is also the Rails default). I noticed that Inertia Rails does not have testing support for MiniTest and wanted to ask if this feature is planned and could be implemented into the gem?

To quickly get something to work, I copied some code from the rspec integration and got some basic assertions working with the following module.
Would you be interested in merging a polished version of this into the gem? Otherwise I guess we could create a companion gem like inertia-rails-minitest.

# frozen_string_literal: true

require "minitest/mock"

module InertiaHelper
  module TestWrapper
    include InertiaHelper

    def run(...)
      install_inertia_test_renderer do
        super
      end
    end
  end

  class InertiaRenderWrapper
    attr_reader :view_data, :props, :component

    def initialize
      @view_data = nil
      @props = nil
      @component = nil
    end

    def call(params)
      assign_values_from_params(params)
      @render_method&.(params)
    end

    def wrap_render(render_method)
      @render_method = render_method
      self
    end

    protected

    def assign_values_from_params(params)
      if params[:locals].present?
        @view_data = params[:locals].except(:page)
        @props = params[:locals][:page][:props]
        @component = params[:locals][:page][:component]
      else
        # Sequential Inertia request
        @view_data = {}
        json = JSON.parse(params[:json])
        @props = json["props"]
        @component = json["component"]
      end
    end
  end

  def inertia_wrap_render(render)
    @_inertia_render_wrapper = InertiaRenderWrapper.new.wrap_render(render)
  end

  def inertia
    assert @_inertia_render_wrapper, "The test never created an Inertia renderer. Maybe the code wasn't able to reach a `render inertia:` call?"

    @_inertia_render_wrapper
  end

  def install_inertia_test_renderer(&)
    new_renderer = InertiaRails::Renderer.method(:new)

    new_stub = ->(component, controller, request, response, render, named_args) do
      new_renderer.(component, controller, request, response, inertia_wrap_render(render), **named_args)
    end

    InertiaRails::Renderer.stub(:new, new_stub, &)
  end

  # Assertions

  def assert_props(**expected_props)
    assert_equal expected_props, inertia.props, "Received unexpected inertia props"
  end

  def assert_includes_props(**expected_props)
    assert_includes expected_props, inertia.props, "Inertia props do not include expected props"
  end

  def assert_component_rendered(expected_component)
    assert_equal expected_component, inertia.component, "Unexpected component rendered with inertia"
  end

  def assert_view_data(**expected_view_data)
    assert_equal expected_view_data, inertia.view_data, "Received unexpected inertia view data"
  end

  def assert_includes_view_data(**expected_view_data)
    assert_includes expected_view_data, inertia.view_data, "Inertia view data does not include expected view data"
  end
end

ActiveSupport.on_load(:action_dispatch_integration_test) { prepend InertiaHelper::TestWrapper }
@skryukov
Copy link
Contributor

We are definitely interested in it, thanks @richardboehme!

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

No branches or pull requests

2 participants