Add more tests and fix failing ones
This commit is contained in:
@@ -132,7 +132,7 @@ class Command::Ai::Translator
|
||||
– Do NOT infer unassigned just because an assignment follows.
|
||||
* **Possessive “my” in front of “card” or “cards”***
|
||||
→ assignee_ids: [ #{user.to_gid} ] — applies **even when other filters are present***
|
||||
(e.g., “my cards closing soon”, “my stalled cards”, “my cards created yesterday”).
|
||||
(e.g., “my cards closing soon”, “my stalled cards”, “my cards created yesterday”, "cards assigned to me").
|
||||
* “Recent cards” (i.e., newly created) → indexed_by: "newest"
|
||||
* “Cards with recent activity”, “recently updated cards” → indexed_by: "latest"
|
||||
– Only use "latest" if the user mentions activity, updates, or changes
|
||||
@@ -157,6 +157,7 @@ class Command::Ai::Translator
|
||||
* /consider → move card back to "considering" (reconsider)
|
||||
* Unless a clear command applies, fallback to /search with the verbatim text.
|
||||
* When searching for nouns (non-person), prefer /search over terms.
|
||||
* When the person to pass to a command is "me" or "myself", use "#{user.to_gid}"
|
||||
* Respect the spoken order of commands.
|
||||
* "close as [reason]" or "close because [reason]" → /close [reason]
|
||||
– Remove "as" or "because" from the actual command
|
||||
@@ -193,6 +194,7 @@ class Command::Ai::Translator
|
||||
* Never use names, tags, or stage names mentioned **inside commands** (like /assign, /tag, /stage) as filters.
|
||||
* Never duplicate the assignee in both commands and context.
|
||||
* Never add properties tied to UI view ("card", "list", etc.).
|
||||
* When using infinitive verbs such as "assign" or "close", always use the corresponding command, NEVER a filter.
|
||||
* To filter completed or closed cards, use "indexed_by: closed"; don't set a "closure" filter unless the user is asking for cards completed in a specific window of time.
|
||||
* When you see a word with a # prefix, assume it refers to a tag (either a filter or a command argument, but don't search for it).
|
||||
* All filters, including terms, must live **inside** context.
|
||||
|
||||
@@ -40,7 +40,7 @@ class Command::Parser::Context
|
||||
|
||||
def find_workflow_stage(string)
|
||||
candidate_stages.find do |stage|
|
||||
stage.name.downcase.include?(combined_arguments.downcase)
|
||||
stage.name.downcase.include?(string.downcase)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -54,7 +54,7 @@ class Command::Parser::Context
|
||||
end
|
||||
|
||||
def find_collection(string)
|
||||
Collection.where("lower(name) like ?", "%#{name.downcase}%").first
|
||||
Collection.where("lower(name) like ?", "%#{string.downcase}%").first
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<lexical-prompt-item search="<%= "#{user.name} #{user.initials}" %>" sgid="<%= user.attachable_sgid %>">
|
||||
<lexical-prompt-item search="<%= "#{user.name} #{user.initials} #{"me" if user == Current.user}" %>" sgid="<%= user.attachable_sgid %>">
|
||||
<template type="menu">
|
||||
<%= avatar_image_tag user %>
|
||||
<%= user.name %>
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
require "test_helper"
|
||||
|
||||
class Prompts::CardsControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in_as :kevin
|
||||
end
|
||||
|
||||
test "index" do
|
||||
get prompts_cards_path
|
||||
assert_response :success
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,13 @@
|
||||
require "test_helper"
|
||||
|
||||
class Prompts::Collections::UsersControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in_as :kevin
|
||||
@collection = collections(:writebook)
|
||||
end
|
||||
|
||||
test "index" do
|
||||
get prompts_collection_users_path(@collection)
|
||||
assert_response :success
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,12 @@
|
||||
require "test_helper"
|
||||
|
||||
class Prompts::CommandsControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in_as :kevin
|
||||
end
|
||||
|
||||
test "index" do
|
||||
get prompts_commands_path
|
||||
assert_response :success
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,12 @@
|
||||
require "test_helper"
|
||||
|
||||
class Prompts::TagsControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in_as :kevin
|
||||
end
|
||||
|
||||
test "index" do
|
||||
get prompts_tags_path
|
||||
assert_response :success
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,12 @@
|
||||
require "test_helper"
|
||||
|
||||
class Prompts::UsersControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
sign_in_as :kevin
|
||||
end
|
||||
|
||||
test "index" do
|
||||
get prompts_users_path
|
||||
assert_response :success
|
||||
end
|
||||
end
|
||||
@@ -14,10 +14,9 @@ class Command::Ai::ParserTest < ActionDispatch::IntegrationTest
|
||||
end
|
||||
|
||||
test "resolve filter string params as ids" do
|
||||
result = parse_command "cards assigned to kevin, tagged with #web, in the collection writebook"
|
||||
assert_equal 1, result.commands.size
|
||||
command = parse_command "cards assigned to kevin, tagged with #web, in the collection writebook"
|
||||
|
||||
url = result.commands.first.url
|
||||
url = command.url
|
||||
query_string = URI.parse(url).query
|
||||
params = Rack::Utils.parse_nested_query(query_string).with_indifferent_access
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ require "test_helper"
|
||||
class Command::Ai::TranslatorTest < ActionDispatch::IntegrationTest
|
||||
include VcrTestHelper
|
||||
|
||||
vcr_record!
|
||||
|
||||
setup do
|
||||
@user = users(:david)
|
||||
end
|
||||
@@ -89,7 +91,7 @@ class Command::Ai::TranslatorTest < ActionDispatch::IntegrationTest
|
||||
|
||||
test "combine commands and filters" do
|
||||
assert_command(
|
||||
{ context: { card_ids: [ 176, 170 ] }, commands: [ "/do", "/assign david", "/stage Investigating" ] },
|
||||
{ context: { card_ids: [ 176, 170 ] }, commands: [ "/do", "/assign #{users(:david).to_gid}", "/stage Investigating" ] },
|
||||
"Move 176 and 170 to doing, assign to me and set the stage to Investigating")
|
||||
assert_command(
|
||||
{ context: { assignee_ids: [ "jz" ], tag_ids: [ "design" ] }, commands: [ "/assign andy", "/tag #v2" ] },
|
||||
@@ -129,8 +131,7 @@ class Command::Ai::TranslatorTest < ActionDispatch::IntegrationTest
|
||||
|
||||
test "closing soon and falling back soon" do
|
||||
assert_command({ context: { indexed_by: "falling_back_soon" } }, "cards to be reconsidered soon")
|
||||
assert_command({ context: { indexed_by: "falling_back_soon" } }, "cards to be reconsidered soon")
|
||||
assert_command({ context: { assignee_ids: [ "david" ], indexed_by: "closing_soon" } }, "my cards that are going to be auto closed")
|
||||
assert_command({ context: { assignee_ids: [ users(:david).to_gid.to_s ], indexed_by: "closing_soon" } }, "my cards that are going to be auto closed")
|
||||
end
|
||||
|
||||
test "view users profiles" do
|
||||
|
||||
@@ -18,10 +18,9 @@ class Command::GoToCardTest < ActionDispatch::IntegrationTest
|
||||
test "result in a regular search if the card does not exist" do
|
||||
command = parse_command "123"
|
||||
|
||||
visit_command = command.commands.first
|
||||
assert visit_command.valid?
|
||||
assert command.valid?
|
||||
|
||||
result = visit_command.execute
|
||||
result = command.execute
|
||||
assert_equal cards_path(terms: [ "123" ]), result.url
|
||||
end
|
||||
end
|
||||
|
||||
@@ -5,6 +5,7 @@ class Command::Parser::ContextTest < ActiveSupport::TestCase
|
||||
|
||||
setup do
|
||||
@user = users(:david)
|
||||
@context = Command::Parser::Context.new(@user, url: cards_path)
|
||||
|
||||
Card.find_each(&:reindex)
|
||||
Comment.find_each(&:reindex)
|
||||
@@ -49,4 +50,66 @@ class Command::Parser::ContextTest < ActiveSupport::TestCase
|
||||
|
||||
assert_empty context.cards
|
||||
end
|
||||
|
||||
test "find_user by handle" do
|
||||
assert_equal users(:david), @context.find_user("david")
|
||||
assert_equal users(:david), @context.find_user("@david")
|
||||
assert_equal users(:jz), @context.find_user("jz")
|
||||
assert_equal users(:kevin), @context.find_user("kevin")
|
||||
assert_nil @context.find_user("nonexistent")
|
||||
end
|
||||
|
||||
test "find_user by GID" do
|
||||
david_gid = users(:david).to_gid.to_s
|
||||
assert_equal users(:david), @context.find_user(david_gid)
|
||||
|
||||
jz_gid = users(:jz).to_gid.to_s
|
||||
assert_equal users(:jz), @context.find_user(jz_gid)
|
||||
|
||||
assert_nil @context.find_user("invalid-gid")
|
||||
end
|
||||
|
||||
test "find_workflow_stage" do
|
||||
card_context = Command::Parser::Context.new(@user, url: card_path(cards(:logo)))
|
||||
|
||||
assert_equal workflow_stages(:qa_triage), card_context.find_workflow_stage("triage")
|
||||
assert_equal workflow_stages(:qa_in_progress), card_context.find_workflow_stage("in progress")
|
||||
assert_equal workflow_stages(:qa_on_hold), card_context.find_workflow_stage("on hold")
|
||||
assert_equal workflow_stages(:qa_review), card_context.find_workflow_stage("review")
|
||||
|
||||
assert_equal workflow_stages(:qa_in_progress), card_context.find_workflow_stage("progress")
|
||||
|
||||
assert_nil card_context.find_workflow_stage("nonexistent")
|
||||
end
|
||||
|
||||
test "find_tag with title" do
|
||||
assert_equal tags(:web), @context.find_tag("web")
|
||||
assert_equal tags(:web), @context.find_tag("#web")
|
||||
assert_equal tags(:mobile), @context.find_tag("mobile")
|
||||
|
||||
assert_nil @context.find_tag("nonexistent")
|
||||
end
|
||||
|
||||
test "find_tag by GID" do
|
||||
web_gid = tags(:web).to_gid.to_s
|
||||
assert_equal tags(:web), @context.find_tag(web_gid)
|
||||
|
||||
mobile_gid = tags(:mobile).to_gid.to_s
|
||||
assert_equal tags(:mobile), @context.find_tag(mobile_gid)
|
||||
|
||||
assert_nil @context.find_tag("invalid-gid")
|
||||
end
|
||||
|
||||
test "find_collection" do
|
||||
assert_equal collections(:writebook), @context.find_collection("Writebook")
|
||||
assert_equal collections(:writebook), @context.find_collection("writebook")
|
||||
|
||||
assert_equal collections(:private), @context.find_collection("Private collection")
|
||||
assert_equal collections(:private), @context.find_collection("private collection")
|
||||
|
||||
assert_equal collections(:writebook), @context.find_collection("write")
|
||||
assert_equal collections(:private), @context.find_collection("private")
|
||||
|
||||
assert_nil @context.find_collection("nonexistent")
|
||||
end
|
||||
end
|
||||
|
||||
+3736
File diff suppressed because it is too large
Load Diff
+3762
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+9396
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+15676
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+3746
File diff suppressed because it is too large
Load Diff
+3001
File diff suppressed because it is too large
Load Diff
+3740
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user