diff --git a/app/controllers/commands_controller.rb b/app/controllers/commands_controller.rb index adae98eb1..a5f6b90f0 100644 --- a/app/controllers/commands_controller.rb +++ b/app/controllers/commands_controller.rb @@ -29,7 +29,7 @@ class CommandsController < ApplicationController end def parsing_context - @parsing_context ||= Command::Parser::Context.new(Current.user, url: request.referrer) + @parsing_context ||= Command::Parser::Context.new(Current.user, url: request.referrer, script_name: request.script_name) end def confirmed?(command) diff --git a/app/models/command/ai/parser.rb b/app/models/command/ai/parser.rb index 6e881449e..9d5bb9eb0 100644 --- a/app/models/command/ai/parser.rb +++ b/app/models/command/ai/parser.rb @@ -7,6 +7,7 @@ class Command::Ai::Parser def initialize(context) @context = context + self.default_url_options[:script_name] = context.script_name end def parse(query) @@ -59,7 +60,7 @@ class Command::Ai::Parser def context_from_query(query_json) if context_properties = query_json[:context].presence url = cards_path(**context_properties) - Command::Parser::Context.new(user, url: url) + Command::Parser::Context.new(user, url: url, script_name: context.script_name) end end end diff --git a/app/models/command/parser.rb b/app/models/command/parser.rb index d45cd69ed..1949658d2 100644 --- a/app/models/command/parser.rb +++ b/app/models/command/parser.rb @@ -1,7 +1,7 @@ class Command::Parser attr_reader :context - delegate :user, :cards, :filter, to: :context + delegate :user, :cards, :filter, :script_name, to: :context def initialize(context) @context = context @@ -12,6 +12,7 @@ class Command::Parser command.user = user command.line ||= string command.context ||= context + command.default_url_options[:script_name] = script_name end end diff --git a/app/models/command/parser/context.rb b/app/models/command/parser/context.rb index 401efbd98..ca146f049 100644 --- a/app/models/command/parser/context.rb +++ b/app/models/command/parser/context.rb @@ -1,9 +1,10 @@ class Command::Parser::Context - attr_reader :user, :url + attr_reader :user, :url, :script_name - def initialize(user, url:) + def initialize(user, url:, script_name: "") @user = user @url = url + @script_name = script_name extract_url_components end @@ -52,7 +53,8 @@ class Command::Parser::Context def extract_url_components uri = URI.parse(url || "") - route = Rails.application.routes.recognize_path(uri.path) + path = uri.path.delete_prefix(script_name) + route = Rails.application.routes.recognize_path(path) @controller = route[:controller] @action = route[:action] @params = ActionController::Parameters.new(Rack::Utils.parse_nested_query(uri.query).merge(route.except(:controller, :action))) diff --git a/app/models/command/visit_url.rb b/app/models/command/visit_url.rb index 6066ea0ed..dabd9f52d 100644 --- a/app/models/command/visit_url.rb +++ b/app/models/command/visit_url.rb @@ -6,6 +6,20 @@ class Command::VisitUrl < Command end def execute - redirect_to url + redirect_to real_url end + + private + def real_url + case url + when String + if url.start_with?(context.script_name) + url + else + [ context&.script_name, url ].compact.join + end + else + url + end + end end diff --git a/test/models/command/ai/translator_test.rb b/test/models/command/ai/translator_test.rb index 74d3722d4..feed1606d 100644 --- a/test/models/command/ai/translator_test.rb +++ b/test/models/command/ai/translator_test.rb @@ -108,10 +108,10 @@ class Command::Ai::TranslatorTest < ActionDispatch::IntegrationTest end test "visit screens" do - assert_command({ commands: [ "/visit #{user_path(@user)}" ] }, "my profile") - assert_command({ commands: [ "/visit #{edit_user_path(@user)}" ] }, "edit my profile") - assert_command({ commands: [ "/visit #{account_settings_path}" ] }, "manage users") - assert_command({ commands: [ "/visit #{account_settings_path}" ] }, "account settings") + assert_command({ commands: [ "/visit #{user_path(@user, script_name: nil)}" ] }, "my profile") + assert_command({ commands: [ "/visit #{edit_user_path(@user, script_name: nil)}" ] }, "edit my profile") + assert_command({ commands: [ "/visit #{account_settings_path(script_name: nil)}" ] }, "manage users") + assert_command({ commands: [ "/visit #{account_settings_path(script_name: nil)}" ] }, "account settings") end test "create cards" do @@ -146,7 +146,7 @@ class Command::Ai::TranslatorTest < ActionDispatch::IntegrationTest def translate(query, user: @user, context: :list) raise "Context must be :card or _list" unless context.in?(%i[ card list ]) url = context == :card ? card_url(cards(:logo)) : cards_url - context = Command::Parser::Context.new(user, url: url) + context = Command::Parser::Context.new(user, url: url, script_name: integration_session.default_url_options[:script_name]) translator = Command::Ai::Translator.new(context) translator.translate(query) end diff --git a/test/models/command/visit_url_test.rb b/test/models/command/visit_url_test.rb new file mode 100644 index 000000000..12d89035a --- /dev/null +++ b/test/models/command/visit_url_test.rb @@ -0,0 +1,36 @@ +require "test_helper" + +class Command::VisitUrlTest < ActionDispatch::IntegrationTest + setup do + @user = users(:david) + @card = cards(:logo) + @script_name = integration_session.default_url_options[:script_name] + end + + test "visit a path without the account slug" do + result = visit_command("/foo/1234/bar").execute + + assert_kind_of Command::Result::Redirection, result + assert_equal "#{@script_name}/foo/1234/bar", result.url + end + + test "visit a path with the account slug" do + result = visit_command("#{@script_name}/foo/1234/bar").execute + + assert_kind_of Command::Result::Redirection, result + assert_equal "#{@script_name}/foo/1234/bar", result.url + end + + test "visit an object path" do + result = visit_command(@card).execute + + assert_kind_of Command::Result::Redirection, result + assert_equal @card, result.url + end + + private + def visit_command(url) + context = Command::Parser::Context.new(@user, url: collection_card_url(@card.collection, @card), script_name: integration_session.default_url_options[:script_name]) + Command::VisitUrl.new(url: url, context: context) + end +end diff --git a/test/test_helpers/command_test_helper.rb b/test/test_helpers/command_test_helper.rb index a0d760e8b..7492bc4cd 100644 --- a/test/test_helpers/command_test_helper.rb +++ b/test/test_helpers/command_test_helper.rb @@ -4,7 +4,7 @@ module CommandTestHelper end def parse_command(string, context_url: nil, user: users(:david)) - context = Command::Parser::Context.new(user, url: context_url) + context = Command::Parser::Context.new(user, url: context_url, script_name: integration_session.default_url_options[:script_name]) parser = Command::Parser.new(context) parser.parse(string).tap do |command| command.user = user if command