diff --git a/CHANGELOG.md b/CHANGELOG.md index 6eeb82b..7d2c0d1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ This project adheres to [Semantic Versioning](http://semver.org/) and [Keep a Ch --- ### New +- Support for options hash for `*_rfc6570` to support Rails Engines. ### Changes @@ -17,6 +18,7 @@ This project adheres to [Semantic Versioning](http://semver.org/) and [Keep a Ch ### Fixes - Fix up `RouteSet#to_rfc6570` and `NamedRouteCollection#to_rfc6570` +- Fix up `*_path_rfc6570` to include Rails Engines mount point. ### Breaks diff --git a/lib/rails/rfc6570.rb b/lib/rails/rfc6570.rb index cf5bbeb..31b1b30 100644 --- a/lib/rails/rfc6570.rb +++ b/lib/rails/rfc6570.rb @@ -52,15 +52,15 @@ def define_rfc6570_helpers(name, route, mod, set) end mod.module_eval do - define_method(rfc6570_name) do |**opts| + define_method(rfc6570_name) do |opts = {}| route.to_rfc6570(**opts, ctx: self) end - define_method(rfc6570_url_name) do |**opts| + define_method(rfc6570_url_name) do |opts = {}| route.to_rfc6570(**opts, ctx: self, path_only: false) end - define_method(rfc6570_path_name) do |**opts| + define_method(rfc6570_path_name) do |opts = {}| route.to_rfc6570(**opts, ctx: self, path_only: true) end end diff --git a/lib/rails/rfc6570/formatter.rb b/lib/rails/rfc6570/formatter.rb index 23cde98..9d8d254 100644 --- a/lib/rails/rfc6570/formatter.rb +++ b/lib/rails/rfc6570/formatter.rb @@ -25,19 +25,16 @@ def evaluate(ctx:, ignore: %w[format], **kwargs) end end - if kwargs.fetch(:path_only, false) - ::Addressable::Template.new parts.join - else - options = ctx.url_options.merge(kwargs) - options[:path] = parts.join - - if (osn = options.delete(:original_script_name)) - options[:script_name] = osn + options[:script_name] - end + options = ctx.url_options.merge(kwargs) + options[:path] = parts.join + options[:only_path] = kwargs.fetch(:path_only, false) - ::Addressable::Template.new \ - ActionDispatch::Http::URL.url_for(options) + if (osn = options.delete(:original_script_name)) + options[:script_name] = osn + options[:script_name] end + + ::Addressable::Template.new \ + ActionDispatch::Http::URL.url_for(options) end def symbol(node, prefix: nil, suffix: nil) diff --git a/spec/dummy/dummy_engine/app/controllers/dummy_engine/application_controller.rb b/spec/dummy/dummy_engine/app/controllers/dummy_engine/application_controller.rb new file mode 100644 index 0000000..b5ba86d --- /dev/null +++ b/spec/dummy/dummy_engine/app/controllers/dummy_engine/application_controller.rb @@ -0,0 +1,4 @@ +module DummyEngine + class ApplicationController < ActionController::API + end +end diff --git a/spec/dummy/dummy_engine/lib/dummy_engine.rb b/spec/dummy/dummy_engine/lib/dummy_engine.rb new file mode 100644 index 0000000..b84cd40 --- /dev/null +++ b/spec/dummy/dummy_engine/lib/dummy_engine.rb @@ -0,0 +1,5 @@ +module DummyEngine + class Engine < ::Rails::Engine + isolate_namespace DummyEngine + end +end diff --git a/spec/rails/rfc6570_spec.rb b/spec/rails/rfc6570_spec.rb index ab25177..f008732 100644 --- a/spec/rails/rfc6570_spec.rb +++ b/spec/rails/rfc6570_spec.rb @@ -1,11 +1,17 @@ # frozen_string_literal: true require 'spec_helper' +require_relative '../dummy/dummy_engine/lib/dummy_engine' +require_relative '../dummy/dummy_engine/app/controllers/dummy_engine/application_controller' ActiveSupport::Inflector.inflections(:en) do |inflect| inflect.acronym 'API' end +DummyEngine::Engine.routes.draw do + get '/action' => 'api#action', as: :action +end + Dummy::Application.routes.draw do get '/' => 'api#index', as: :root @@ -20,6 +26,8 @@ get '/path/*capture/:title' => 'api#index', as: :test4 get '/path(/*capture)/:title' => 'api#index', as: :test5 get '/path(/*capture)(/:title)' => 'api#index', as: :test6 + + mount DummyEngine::Engine => '/dummy_engine' end class APIController < ApplicationController @@ -49,6 +57,18 @@ def default_url_options end end +class DummyEngine::APIController < DummyEngine::ApplicationController + rfc6570_params action: %i[param3] + def action + render json: { + ref: action_path, + template: action_rfc6570, + template_url: action_url_rfc6570, + template_path: action_path_rfc6570, + } + end +end + describe Rails::RFC6570, type: :request do let(:host) { 'http://www.example.com' } let(:json) { JSON.parse response.body } @@ -58,7 +78,7 @@ def default_url_options it 'returns list of all parsed and named routes' do expect(json.keys).to match_array \ - %w[root action test1 test2 test3 test4 test5 test6] + %w[root action test1 test2 test3 test4 test5 test6 dummy_engine] end it 'includes known parameters' do @@ -134,4 +154,24 @@ def default_url_options end end end + + context 'action in Rails Engine' do + before { get '/dummy_engine/action', headers: headers } + + it 'includes URL helpers' do + expect(response).to have_http_status :ok + end + + it 'allows to return and render templates' do + expect(json['template']).to eq "#{host}/dummy_engine/action{?param3}" + end + + it 'allows to return and render url templates' do + expect(json['template_url']).to eq "#{host}/dummy_engine/action{?param3}" + end + + it 'allows to return and render path templates' do + expect(json['template_path']).to eq '/dummy_engine/action{?param3}' + end + end end