feat: 添加测试框架及功能测试用例
test: 实现BDD测试框架及功能测试 docs: 添加测试配置文件及文档 refactor: 重构命令处理逻辑以支持测试
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
Feature: /close command — terminate a session
|
||||
|
||||
Background:
|
||||
Given user "user_abc123" is sending commands
|
||||
|
||||
Scenario: No sessions returns error
|
||||
When user sends "/close"
|
||||
Then reply contains "No sessions to close"
|
||||
|
||||
Scenario: Close active session by default
|
||||
Given user has session "sess01" in "/tmp/proj1"
|
||||
And active session is "sess01"
|
||||
When user sends "/close"
|
||||
Then reply contains "Closed session"
|
||||
And session manager has 0 sessions for user "user_abc123"
|
||||
|
||||
Scenario: Close session by number
|
||||
Given user has session "sess01" in "/tmp/proj1"
|
||||
And user has session "sess02" in "/tmp/proj2"
|
||||
When user sends "/close 1"
|
||||
Then reply contains "Closed session"
|
||||
And session manager has 1 session for user "user_abc123"
|
||||
|
||||
Scenario: Invalid number returns error
|
||||
Given user has session "sess01" in "/tmp/proj1"
|
||||
When user sends "/close 9"
|
||||
Then reply contains "Invalid session number"
|
||||
|
||||
Scenario: Cannot close another user's session
|
||||
Given session "sess01" in "/tmp/proj1" belongs to user "other_user"
|
||||
When user sends "/close sess01"
|
||||
Then reply contains "belongs to another user"
|
||||
|
||||
Scenario: Closing active session clears active conv
|
||||
Given user has session "sess01" in "/tmp/proj1"
|
||||
And active session is "sess01"
|
||||
When user sends "/close"
|
||||
Then active session for user "user_abc123" is None
|
||||
@@ -0,0 +1,27 @@
|
||||
Feature: /direct and /smart mode toggle
|
||||
|
||||
Background:
|
||||
Given user "user_abc123" is sending commands
|
||||
|
||||
Scenario: /direct requires active session
|
||||
When user sends "/direct"
|
||||
Then reply contains "No active session"
|
||||
|
||||
Scenario: /direct enables passthrough mode
|
||||
Given user has session "sess01" in "/tmp/proj1"
|
||||
And active session is "sess01"
|
||||
When user sends "/direct"
|
||||
Then reply contains "Direct mode ON"
|
||||
And passthrough mode is enabled for user "user_abc123"
|
||||
|
||||
Scenario: /smart disables passthrough mode
|
||||
Given user has session "sess01" in "/tmp/proj1"
|
||||
And active session is "sess01"
|
||||
And direct mode is enabled for user "user_abc123"
|
||||
When user sends "/smart"
|
||||
Then reply contains "Smart mode ON"
|
||||
And passthrough mode is disabled for user "user_abc123"
|
||||
|
||||
Scenario: /smart always succeeds even without active session
|
||||
When user sends "/smart"
|
||||
Then reply contains "Smart mode ON"
|
||||
@@ -0,0 +1,25 @@
|
||||
Feature: /help command — show command reference
|
||||
|
||||
Background:
|
||||
Given user "user_abc123" is sending commands
|
||||
|
||||
Scenario: /help lists all commands
|
||||
When user sends "/help"
|
||||
Then reply contains "/new"
|
||||
And reply contains "/status"
|
||||
And reply contains "/close"
|
||||
And reply contains "/switch"
|
||||
And reply contains "/direct"
|
||||
And reply contains "/smart"
|
||||
And reply contains "/shell"
|
||||
And reply contains "/remind"
|
||||
And reply contains "/tasks"
|
||||
And reply contains "/nodes"
|
||||
|
||||
Scenario: /h alias works
|
||||
When user sends "/h"
|
||||
Then reply contains "/new"
|
||||
|
||||
Scenario: Unknown command is not handled
|
||||
When user sends "/unknown_xyz_cmd"
|
||||
Then command is not handled
|
||||
@@ -0,0 +1,37 @@
|
||||
Feature: /new command — create a Claude Code session
|
||||
|
||||
Background:
|
||||
Given user "user_abc123" is sending commands
|
||||
|
||||
Scenario: No arguments shows usage
|
||||
When user sends "/new"
|
||||
Then reply contains "Usage: /new"
|
||||
|
||||
Scenario: Creates session with valid directory
|
||||
Given run_claude returns "Session ready."
|
||||
When user sends "/new myproject"
|
||||
Then reply contains "myproject"
|
||||
And session manager has 1 session for user "user_abc123"
|
||||
|
||||
Scenario: Creates session with initial message
|
||||
Given run_claude returns "Fixed the bug."
|
||||
When user sends "/new myproject fix the login bug"
|
||||
Then reply contains "myproject"
|
||||
|
||||
Scenario: Path traversal attempt is blocked
|
||||
When user sends "/new ../../etc"
|
||||
Then reply contains "Error"
|
||||
And session manager has 0 sessions for user "user_abc123"
|
||||
|
||||
Scenario: Custom timeout is accepted
|
||||
Given run_claude returns "Done."
|
||||
When user sends "/new myproject --timeout 60"
|
||||
Then reply contains "myproject"
|
||||
And reply contains "timeout: 60s"
|
||||
|
||||
Scenario: Creates session and sends card when chat_id is set
|
||||
Given the current chat_id is "chat_xyz"
|
||||
And run_claude returns "Ready."
|
||||
When user sends "/new myproject"
|
||||
Then a sessions card is sent to chat "chat_xyz"
|
||||
And text reply is empty
|
||||
@@ -0,0 +1,13 @@
|
||||
Feature: /nodes and /node commands — multi-host node management
|
||||
|
||||
Background:
|
||||
Given user "user_abc123" is sending commands
|
||||
And ROUTER_MODE is disabled
|
||||
|
||||
Scenario: /nodes outside router mode returns explanation
|
||||
When user sends "/nodes"
|
||||
Then reply contains "Not in router mode"
|
||||
|
||||
Scenario: /node outside router mode returns explanation
|
||||
When user sends "/node myhost"
|
||||
Then reply contains "Not in router mode"
|
||||
@@ -0,0 +1,33 @@
|
||||
Feature: /remind command — schedule a one-time reminder
|
||||
|
||||
Background:
|
||||
Given user "user_abc123" is sending commands
|
||||
And the current chat_id is "chat_xyz"
|
||||
|
||||
Scenario: No arguments shows usage
|
||||
When user sends "/remind"
|
||||
Then reply contains "Usage: /remind"
|
||||
|
||||
Scenario: Missing message part shows usage
|
||||
When user sends "/remind 10m"
|
||||
Then reply contains "Usage: /remind"
|
||||
|
||||
Scenario: Invalid time format returns error
|
||||
When user sends "/remind badtime check build"
|
||||
Then reply contains "Invalid time format"
|
||||
|
||||
Scenario: Valid reminder with seconds is scheduled
|
||||
When user sends "/remind 30s check the build"
|
||||
Then reply contains "Reminder #"
|
||||
And reply contains "30s"
|
||||
And scheduler has 1 pending job
|
||||
|
||||
Scenario: Valid reminder with minutes is scheduled
|
||||
When user sends "/remind 5m deploy done"
|
||||
Then reply contains "5m"
|
||||
And scheduler has 1 pending job
|
||||
|
||||
Scenario: Valid reminder with hours is scheduled
|
||||
When user sends "/remind 2h weekly report"
|
||||
Then reply contains "2h"
|
||||
And scheduler has 1 pending job
|
||||
@@ -0,0 +1,22 @@
|
||||
Feature: /shell command — run host shell commands
|
||||
|
||||
Background:
|
||||
Given user "user_abc123" is sending commands
|
||||
|
||||
Scenario: No arguments shows usage
|
||||
When user sends "/shell"
|
||||
Then reply contains "Usage: /shell"
|
||||
|
||||
Scenario: Runs echo and returns output
|
||||
When user sends "/shell echo hello"
|
||||
Then reply contains "hello"
|
||||
And reply contains "exit code: 0"
|
||||
|
||||
Scenario: Blocked dangerous command is rejected
|
||||
When user sends "/shell rm -rf /"
|
||||
Then reply contains "Blocked"
|
||||
And reply does not contain "exit code"
|
||||
|
||||
Scenario: Non-zero exit code is reported
|
||||
When user sends "/shell exit 1"
|
||||
Then reply contains "exit code"
|
||||
@@ -0,0 +1,40 @@
|
||||
Feature: /status command — list sessions and current mode
|
||||
|
||||
Background:
|
||||
Given user "user_abc123" is sending commands
|
||||
|
||||
Scenario: No sessions returns empty message
|
||||
When user sends "/status"
|
||||
Then reply contains "No active sessions"
|
||||
|
||||
Scenario: Shows session list
|
||||
Given user has session "sess01" in "/tmp/proj1"
|
||||
And user has session "sess02" in "/tmp/proj2"
|
||||
When user sends "/status"
|
||||
Then reply contains "sess01"
|
||||
And reply contains "sess02"
|
||||
|
||||
Scenario: Shows active marker on current session
|
||||
Given user has session "sess01" in "/tmp/proj1"
|
||||
And active session is "sess01"
|
||||
When user sends "/status"
|
||||
Then reply contains "→"
|
||||
|
||||
Scenario: Shows current mode as Smart by default
|
||||
Given user has session "sess01" in "/tmp/proj1"
|
||||
When user sends "/status"
|
||||
Then reply contains "Smart"
|
||||
|
||||
Scenario: Shows Direct mode after /direct
|
||||
Given user has session "sess01" in "/tmp/proj1"
|
||||
And active session is "sess01"
|
||||
And direct mode is enabled for user "user_abc123"
|
||||
When user sends "/status"
|
||||
Then reply contains "Direct"
|
||||
|
||||
Scenario: Sends card when chat_id is set
|
||||
Given user has session "sess01" in "/tmp/proj1"
|
||||
And the current chat_id is "chat_xyz"
|
||||
When user sends "/status"
|
||||
Then a sessions card is sent to chat "chat_xyz"
|
||||
And text reply is empty
|
||||
@@ -0,0 +1,30 @@
|
||||
Feature: /switch command — activate a different session
|
||||
|
||||
Background:
|
||||
Given user "user_abc123" is sending commands
|
||||
|
||||
Scenario: No sessions returns error
|
||||
When user sends "/switch 1"
|
||||
Then reply contains "No sessions available"
|
||||
|
||||
Scenario: Valid switch updates active session
|
||||
Given user has session "sess01" in "/tmp/proj1"
|
||||
And user has session "sess02" in "/tmp/proj2"
|
||||
When user sends "/switch 2"
|
||||
Then reply contains "Switched to session"
|
||||
And active session for user "user_abc123" is "sess02"
|
||||
|
||||
Scenario: Out of range number returns error
|
||||
Given user has session "sess01" in "/tmp/proj1"
|
||||
When user sends "/switch 5"
|
||||
Then reply contains "Invalid session number"
|
||||
|
||||
Scenario: Non-numeric argument returns error
|
||||
Given user has session "sess01" in "/tmp/proj1"
|
||||
When user sends "/switch notanumber"
|
||||
Then reply contains "Invalid number"
|
||||
|
||||
Scenario: Missing argument shows usage
|
||||
Given user has session "sess01" in "/tmp/proj1"
|
||||
When user sends "/switch"
|
||||
Then reply contains "Usage: /switch"
|
||||
@@ -0,0 +1,27 @@
|
||||
Feature: /tasks command — list background tasks
|
||||
|
||||
Background:
|
||||
Given user "user_abc123" is sending commands
|
||||
|
||||
Scenario: No tasks returns empty message
|
||||
When user sends "/tasks"
|
||||
Then reply contains "No background tasks"
|
||||
|
||||
Scenario: Shows running task with spinner emoji
|
||||
Given there is a running task "task001" described as "CC session abc: fix bug"
|
||||
When user sends "/tasks"
|
||||
Then reply contains "task001"
|
||||
And reply contains "fix bug"
|
||||
And reply contains "⏳"
|
||||
|
||||
Scenario: Shows completed task with checkmark
|
||||
Given there is a completed task "task002" described as "CC session xyz: deploy"
|
||||
When user sends "/tasks"
|
||||
Then reply contains "task002"
|
||||
And reply contains "✅"
|
||||
|
||||
Scenario: Shows failed task with cross
|
||||
Given there is a failed task "task003" described as "CC session err: bad cmd"
|
||||
When user sends "/tasks"
|
||||
Then reply contains "task003"
|
||||
And reply contains "❌"
|
||||
Reference in New Issue
Block a user