rubymonolith/superform

`ActionController::UrlGenerationError` testing with RSpec

Closed this issue · 2 comments

Hello there!

I am building a new app and I am going full Phlex and this library looks like the perfect fit. I am having some issues when testing the edit form.

This function uses url_for that expects the controller context to be present.

The only workaround I found is to set the expected value manually controller.request.path_parameters[:id] = brand.id that looks awfull.

module Admin
  module Brands
    class EditView < ApplicationView
      include Phlex::Rails::Helpers::LinkTo

      def initialize(brand:)
        @brand = brand
        super()
      end

      def template
        h1 { 'Editing brand' }
        render FormView.new @brand
        div do
          link_to('Show', admin_brand_path(@brand))
          link_to('Back', admin_brands_path)
        end
      end
    end
  end
end
module Admin
  module Brands
    class FormView < ApplicationForm
      def template(&)
        row field(:name).input
      end
    end
  end
end
RSpec.describe 'admin/brands/edit' do
  let(:brand) { Brand.create!(name: 'MyString') }

  it 'renders the edit brand form' do
    controller.request.path_parameters[:id] = brand.id

    render Admin::Brands::EditView.new(brand:)

    assert_select 'form[action=?][method=?]', admin_brand_path(brand), 'post' do
      assert_select 'input[name=?]', 'brand[name]'
    end
  end
end

Any ides?? Thanks!!

I've had success using rspec doubles to mock calls to any rails helpers:

#... include as a helper
def stub_form(form)
  allow(form).to receive(:helpers) do
    double(
      'helpers',
      url_for: 'some_url',
      form_authenticity_token: 'xxxx'
    )
  end
end

#... with your form

class Form < ApplicationForm
  #... some fields
end

#... in tests
RSpec.describe Form, type: :controller do

  let(:form) { Form.new }

  before do
    stub_form(form)
  end

  it 'has expected behavior' do 
   expect(form.behave).to have_behaved
  end 
end

The internals of Superform calls Rails url_for(@model) if an action: keyword argument is not provided to the constructor.

Outside of that, it appears you’re testing a Phlex view, which is outside the scope of this gem, but you can access helpers for that in the phlex-rails gem. I’d look at this helpers and see if you find a solution to your problem. They you find it please link to it here for others benefit and close the issue if it solves your problem. Thanks!