diff --git a/admin/app/components/solidus_admin/base_component.rb b/admin/app/components/solidus_admin/base_component.rb index e3adf62c02f..ba8997e1cd9 100644 --- a/admin/app/components/solidus_admin/base_component.rb +++ b/admin/app/components/solidus_admin/base_component.rb @@ -37,23 +37,5 @@ def self.stimulus_id end delegate :stimulus_id, to: :class - - class << self - private - - def engines_with_routes - Rails::Engine.subclasses.map(&:instance).reject do |engine| - engine.routes.empty? - end - end - end - - # For each engine with routes, define a method that returns the routes proxy. - # This allows us to use the routes in the context of a component class. - engines_with_routes.each do |engine| - define_method(engine.engine_name) do - engine.routes.url_helpers - end - end end end diff --git a/admin/app/components/solidus_admin/ui/pages/index/component.html.erb b/admin/app/components/solidus_admin/ui/pages/index/component.html.erb index 69916f08dd4..caa79f05cc6 100644 --- a/admin/app/components/solidus_admin/ui/pages/index/component.html.erb +++ b/admin/app/components/solidus_admin/ui/pages/index/component.html.erb @@ -1,12 +1,12 @@ <%= page do %> - <% if @tabs %> + <% if tabs %> <%= page_header do %> <%= render_title %> <% end %> <%= page_header do %> <% rendered_tabs = capture do %> - <% @tabs.each do %> + <% renderable_tabs.each do %> <%= render(component("ui/button").new(tag: :a, scheme: :ghost, text: _1.text, 'aria-current': _1.current, href: _1.href)) %> <% end %> <% end %> diff --git a/admin/app/components/solidus_admin/ui/pages/index/component.rb b/admin/app/components/solidus_admin/ui/pages/index/component.rb index ad6cd5b5092..b81be0cb240 100644 --- a/admin/app/components/solidus_admin/ui/pages/index/component.rb +++ b/admin/app/components/solidus_admin/ui/pages/index/component.rb @@ -22,13 +22,18 @@ def columns; []; end def initialize(page:) @page = page - @tabs = tabs&.map { |tab| Tab.new(**tab) } end def row_fade(_record) false end + def renderable_tabs + return unless tabs + + tabs.map { |tab| Tab.new(**tab) } + end + def title model_class.model_name.human.pluralize end diff --git a/admin/lib/solidus_admin/engine.rb b/admin/lib/solidus_admin/engine.rb index 3ad1f087b07..82b1ec3e4ad 100644 --- a/admin/lib/solidus_admin/engine.rb +++ b/admin/lib/solidus_admin/engine.rb @@ -63,5 +63,11 @@ class Engine < ::Rails::Engine SolidusAdmin::Engine.root.join("app/components"), ] end + + initializer "solidus_admin.routing_proxies" do |app| + ActiveSupport.on_load(:after_routes_loaded) do + SolidusAdmin::BaseComponent.include app.routes.mounted_helpers + end + end end end diff --git a/admin/lib/solidus_admin/testing_support/component_helpers.rb b/admin/lib/solidus_admin/testing_support/component_helpers.rb index 58f530eb1fd..f56960561dd 100644 --- a/admin/lib/solidus_admin/testing_support/component_helpers.rb +++ b/admin/lib/solidus_admin/testing_support/component_helpers.rb @@ -12,15 +12,9 @@ module ComponentHelpers # "Rendered" # end # end - def mock_component(&definition) - location = caller(1, 1).first - component_class = Class.new(SolidusAdmin::BaseComponent) - # ViewComponent will complain if we don't fake a class name: - # @see https://github.com/ViewComponent/view_component/blob/5decd07842c48cbad82527daefa3fe9c65a4226a/lib/view_component/base.rb#L371 - component_class.define_singleton_method(:name) { "Foo" } - component_class.define_singleton_method(:to_s) { "#{name} (#{location})" } - component_class.class_eval(&definition) if definition - component_class + def mock_component(class_name = "Foo::Component", &definition) + component_class = stub_const(class_name, Class.new(described_class, &definition)) + component_class.new end end end diff --git a/admin/solidus_admin.gemspec b/admin/solidus_admin.gemspec index 0fd6ac6aff1..ce348c7b33d 100644 --- a/admin/solidus_admin.gemspec +++ b/admin/solidus_admin.gemspec @@ -34,5 +34,5 @@ Gem::Specification.new do |s| s.add_dependency 'solidus_core', '> 4.2' s.add_dependency 'stimulus-rails', '~> 1.2' s.add_dependency 'turbo-rails', '~> 2.0' - s.add_dependency 'view_component', ['~> 3.9', '< 3.21.0'] + s.add_dependency 'view_component', '~> 3.9' end diff --git a/admin/spec/components/solidus_admin/base_component_spec.rb b/admin/spec/components/solidus_admin/base_component_spec.rb index 2c95f2c9fd3..6794d308022 100644 --- a/admin/spec/components/solidus_admin/base_component_spec.rb +++ b/admin/spec/components/solidus_admin/base_component_spec.rb @@ -9,7 +9,7 @@ def call icon_tag("user-line") end - end.new + end render_inline(component) @@ -20,29 +20,25 @@ def call describe "#spree" do it "gives access to spree routing helpers" do - without_partial_double_verification do - allow(Spree::Core::Engine.routes.url_helpers).to receive(:foo_path).and_return("/foo/bar") - end - component = described_class.new - - expect(component.spree.foo_path).to eq("/foo/bar") + expect(described_class.new).to respond_to(:spree) end end describe "#solidus_admin" do it "gives access to solidus_admin routing helpers" do - without_partial_double_verification do - allow(SolidusAdmin::Engine.routes.url_helpers).to receive(:foo_path).and_return("/foo/bar") - end - component = described_class.new + expect(described_class.new).to respond_to(:solidus_admin) + end + end - expect(component.solidus_admin.foo_path).to eq("/foo/bar") + describe "#main_app" do + it "gives access to main_app routing helpers" do + expect(described_class.new).to respond_to(:main_app) end end describe ".stimulus_id" do it "returns the stimulus id for the component" do - stub_const("SolidusAdmin::Foo::Bar::Component", Class.new(described_class)) + mock_component("SolidusAdmin::Foo::Bar::Component") { erb_template "" } expect(SolidusAdmin::Foo::Bar::Component.stimulus_id).to eq("foo--bar") expect(SolidusAdmin::Foo::Bar::Component.new.stimulus_id).to eq("foo--bar") @@ -55,8 +51,7 @@ def call allow(Rails.logger).to receive(:debug) { debug_logs << _1 } - component_class = stub_const("Foo::Component", Class.new(described_class){ erb_template "" }) - component = component_class.new + component = mock_component { erb_template "" } render_inline(component) translation = component.translate("foo.bar.baz")