diff --git a/app/models/ai/tool.rb b/app/models/ai/tool.rb index f7afcc698..5a168d13a 100644 --- a/app/models/ai/tool.rb +++ b/app/models/ai/tool.rb @@ -27,12 +27,14 @@ class Ai::Tool < RubyLLM::Tool end def default_url_options - default_options = Rails.application.default_url_options + options = Rails.application.default_url_options.merge( + script_name: "/#{ApplicationRecord.current_tenant}" + ) - unless default_options.key?(:host) - default_options[:only_path] = true + unless options.key?(:host) + options[:only_path] = true end - default_options.merge(script_name: "/#{ApplicationRecord.current_tenant}") + options end end diff --git a/test/models/ai/list_cards_tool_test.rb b/test/models/ai/list_cards_tool_test.rb new file mode 100644 index 000000000..cb484a13f --- /dev/null +++ b/test/models/ai/list_cards_tool_test.rb @@ -0,0 +1,117 @@ +require "test_helper" + +class Ai::ListCardsToolTest < ActiveSupport::TestCase + include McpHelper + + setup do + @tool = Ai::ListCardsTool.new(user: users(:kevin)) + end + + test "execute" do + response = @tool.execute + page = parse_paginated_response(response) + + assert page[:records].is_a?(Array) + end + + test "execute when ordering the result" do + response = @tool.execute(ordered_by: "id ASC") + page = parse_paginated_response(response) + ids = page[:records].map { |card| card["id"] } + + assert_equal ids.sort, ids, "The IDs are sorted in ascending order" + + response = @tool.execute(ordered_by: "id DESC") + page = parse_paginated_response(response) + ids = page[:records].map { |card| card["id"] } + + assert_equal ids.sort.reverse, ids, "The IDs are sorted in descending order" + + assert_raises(ArgumentError) do + @tool.execute(ordered_by: "created_at foobar") + end + end + + test "execute when filtering by ids" do + cards = cards(:shipping, :logo) + card_ids = cards.pluck(:id) + + response = @tool.execute(ids: cards.pluck(:id).join(", ")) + page = parse_paginated_response(response) + record_ids = page[:records].map { |card| card["id"].to_i } + + assert_equal 2, record_ids.count + assert_equal card_ids.sort, record_ids.sort + end + + test "execute when filtering by collection_ids" do + collection = collections(:writebook) + + response = @tool.execute(collection_ids: collection.id.to_s) + page = parse_paginated_response(response) + + assert page[:records].all? { |card| collection.id == card["collection_id"] } + assert_nil page[:next_param] + end + + test "execute when filtering by golden" do + response = @tool.execute(golden: true) + page = parse_paginated_response(response) + + assert page[:records].all? { |card| card["golden"] == true } + end + + test "execute when filtering by created_at" do + response = @tool.execute(created_after: 8.days.ago.to_s) + page = parse_paginated_response(response) + + assert_not_empty page[:records], "There are cards created in the last 8 days" + + response = @tool.execute(created_after: 3.days.ago.to_s) + page = parse_paginated_response(response) + + assert_empty page[:records], "There are no cards created in the last 3 days" + + response = @tool.execute(created_before: 3.days.ago.to_s) + page = parse_paginated_response(response) + + assert_not_empty page[:records], "There are cards created more than 3 days ago" + + response = @tool.execute(created_before: 8.days.ago.to_s) + page = parse_paginated_response(response) + + assert_empty page[:records], "There are no cards created more than 8 days ago" + + response = @tool.execute(created_before: 3.days.ago.to_s, created_after: 8.days.ago.to_s) + page = parse_paginated_response(response) + + assert_not_empty page[:records], "There are cards created between 3 and 8 days ago" + end + + test "execute when filtering by last_active_at" do + response = @tool.execute(last_active_after: 8.days.ago.to_s) + page = parse_paginated_response(response) + + assert_not_empty page[:records], "There are cards active in the last 8 days" + + response = @tool.execute(last_active_after: 3.days.ago.to_s) + page = parse_paginated_response(response) + + assert_empty page[:records], "There are no cards active in the last 3 days" + + response = @tool.execute(last_active_before: 3.days.ago.to_s) + page = parse_paginated_response(response) + + assert_not_empty page[:records], "There are cards active more than 3 days ago" + + response = @tool.execute(last_active_before: 8.days.ago.to_s) + page = parse_paginated_response(response) + + assert_empty page[:records], "There are no cards active more than 8 days ago" + + response = @tool.execute(last_active_before: 3.days.ago.to_s, last_active_after: 8.days.ago.to_s) + page = parse_paginated_response(response) + + assert_not_empty page[:records], "There are cards active between 3 and 8 days ago" + end +end diff --git a/test/test_helpers/mcp_helper.rb b/test/test_helpers/mcp_helper.rb new file mode 100644 index 000000000..27496eaa2 --- /dev/null +++ b/test/test_helpers/mcp_helper.rb @@ -0,0 +1,12 @@ +module McpHelper + def parse_paginated_response(response) + records_match = response.match(/Records:\n```\n(\[.*\])\n```/m) + assert records_match, "Could not find any records in the paginated response" + records = JSON.parse(records_match[1]) + + next_param_match = response.match(/next page:\n```\n(\[.*\])\n```/m) + next_param = next_param_match[1] if next_param_match + + { records: records, next_param: next_param } + end +end