256 lines
9.1 KiB
Go
256 lines
9.1 KiB
Go
package cli_compat_test
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
// ── attendance record get ──────────────────────────────────
|
|
|
|
func TestAttendanceRecordGet_should_call_get_user_attendance_record_when_valid_inputs(t *testing.T) {
|
|
cap := setupTestDeps(t, "attendance")
|
|
root := buildRoot()
|
|
err := execCmd(t, root, []string{"attendance", "record", "get"}, map[string]string{
|
|
"user": "U001", "date": "2026-03-08",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
assertToolName(t, cap, "get_user_attendance_record")
|
|
assertToolArg(t, cap, "userId", "U001")
|
|
}
|
|
|
|
func TestAttendanceRecordGet_should_convert_date_to_unix_millis(t *testing.T) {
|
|
cap := setupTestDeps(t, "attendance")
|
|
root := buildRoot()
|
|
_ = execCmd(t, root, []string{"attendance", "record", "get"}, map[string]string{
|
|
"user": "U001", "date": "2026-03-08",
|
|
})
|
|
expected := time.Date(2026, 3, 8, 0, 0, 0, 0, time.Local).UnixMilli()
|
|
assertToolArg(t, cap, "workDate", expected)
|
|
}
|
|
|
|
func TestAttendanceRecordGet_should_return_error_when_date_format_invalid(t *testing.T) {
|
|
_ = setupTestDeps(t, "attendance")
|
|
root := buildRoot()
|
|
err := execCmd(t, root, []string{"attendance", "record", "get"}, map[string]string{
|
|
"user": "U001", "date": "03-08-2026",
|
|
})
|
|
if err == nil {
|
|
t.Fatal("expected error for invalid date format")
|
|
}
|
|
}
|
|
|
|
func TestAttendanceRecordGet_should_return_error_when_date_is_nonsense(t *testing.T) {
|
|
_ = setupTestDeps(t, "attendance")
|
|
root := buildRoot()
|
|
err := execCmd(t, root, []string{"attendance", "record", "get"}, map[string]string{
|
|
"user": "U001", "date": "not-a-date",
|
|
})
|
|
if err == nil {
|
|
t.Fatal("expected error for nonsense date")
|
|
}
|
|
}
|
|
|
|
func TestAttendanceRecordGet_should_handle_leap_year_date(t *testing.T) {
|
|
cap := setupTestDeps(t, "attendance")
|
|
root := buildRoot()
|
|
err := execCmd(t, root, []string{"attendance", "record", "get"}, map[string]string{
|
|
"user": "U001", "date": "2024-02-29",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
expected := time.Date(2024, 2, 29, 0, 0, 0, 0, time.Local).UnixMilli()
|
|
assertToolArg(t, cap, "workDate", expected)
|
|
}
|
|
|
|
// ── attendance shift list ──────────────────────────────────
|
|
|
|
func TestAttendanceShiftList_should_call_batch_get_employee_shifts(t *testing.T) {
|
|
cap := setupTestDeps(t, "attendance")
|
|
root := buildRoot()
|
|
err := execCmd(t, root, []string{"attendance", "shift", "list"}, map[string]string{
|
|
"users": "userId1,userId2", "start": "2026-03-03", "end": "2026-03-07",
|
|
})
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
assertToolName(t, cap, "batch_get_employee_shifts")
|
|
}
|
|
|
|
func TestAttendanceShiftList_should_parse_comma_separated_users(t *testing.T) {
|
|
cap := setupTestDeps(t, "attendance")
|
|
root := buildRoot()
|
|
_ = execCmd(t, root, []string{"attendance", "shift", "list"}, map[string]string{
|
|
"users": "userId1,userId2,userId3", "start": "2026-03-03", "end": "2026-03-07",
|
|
})
|
|
assertToolArg(t, cap, "userIds", []string{"userId1", "userId2", "userId3"})
|
|
}
|
|
|
|
func TestAttendanceShiftList_should_trim_whitespace_from_user_ids(t *testing.T) {
|
|
cap := setupTestDeps(t, "attendance")
|
|
root := buildRoot()
|
|
_ = execCmd(t, root, []string{"attendance", "shift", "list"}, map[string]string{
|
|
"users": " userId1 , userId2 , userId3 ", "start": "2026-03-03", "end": "2026-03-07",
|
|
})
|
|
assertToolArg(t, cap, "userIds", []string{"userId1", "userId2", "userId3"})
|
|
}
|
|
|
|
func TestAttendanceShiftList_should_return_error_when_start_date_invalid(t *testing.T) {
|
|
_ = setupTestDeps(t, "attendance")
|
|
root := buildRoot()
|
|
err := execCmd(t, root, []string{"attendance", "shift", "list"}, map[string]string{
|
|
"users": "userId1", "start": "bad-date", "end": "2026-03-07",
|
|
})
|
|
if err == nil {
|
|
t.Fatal("expected error for invalid start date")
|
|
}
|
|
}
|
|
|
|
func TestAttendanceShiftList_should_return_error_when_end_date_invalid(t *testing.T) {
|
|
_ = setupTestDeps(t, "attendance")
|
|
root := buildRoot()
|
|
err := execCmd(t, root, []string{"attendance", "shift", "list"}, map[string]string{
|
|
"users": "userId1", "start": "2026-03-03", "end": "bad-date",
|
|
})
|
|
if err == nil {
|
|
t.Fatal("expected error for invalid end date")
|
|
}
|
|
}
|
|
|
|
func TestAttendanceShiftList_should_convert_dates_to_unix_millis(t *testing.T) {
|
|
cap := setupTestDeps(t, "attendance")
|
|
root := buildRoot()
|
|
_ = execCmd(t, root, []string{"attendance", "shift", "list"}, map[string]string{
|
|
"users": "userId1", "start": "2026-03-03", "end": "2026-03-07",
|
|
})
|
|
fromExpected := time.Date(2026, 3, 3, 0, 0, 0, 0, time.Local).UnixMilli()
|
|
toExpected := time.Date(2026, 3, 7, 0, 0, 0, 0, time.Local).UnixMilli()
|
|
assertToolArg(t, cap, "fromDateTime", fromExpected)
|
|
assertToolArg(t, cap, "toDateTime", toExpected)
|
|
}
|
|
|
|
func TestAttendanceShiftList_should_filter_empty_user_ids(t *testing.T) {
|
|
cap := setupTestDeps(t, "attendance")
|
|
root := buildRoot()
|
|
_ = execCmd(t, root, []string{"attendance", "shift", "list"}, map[string]string{
|
|
"users": "userId1,,userId2,", "start": "2026-03-03", "end": "2026-03-07",
|
|
})
|
|
assertToolArg(t, cap, "userIds", []string{"userId1", "userId2"})
|
|
}
|
|
|
|
// ── attendance summary ─────────────────────────────────────
|
|
|
|
func TestAttendanceSummary_should_call_tool_with_user_and_date(t *testing.T) {
|
|
cap := setupTestDeps(t, "attendance")
|
|
root := buildRoot()
|
|
err := execCmd(t, root, []string{"attendance", "summary"}, map[string]string{"user": "U001", "date": "2026-03-12 15:00:00"})
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
assertToolName(t, cap, "get_attendance_summary")
|
|
}
|
|
|
|
func TestAttendanceSummary_should_pass_user_and_date_flags(t *testing.T) {
|
|
cap := setupTestDeps(t, "attendance")
|
|
root := buildRoot()
|
|
_ = execCmd(t, root, []string{"attendance", "summary"}, map[string]string{
|
|
"user": "U001",
|
|
"date": "2026-03-12 15:00:00",
|
|
})
|
|
last := cap.last()
|
|
if last == nil {
|
|
t.Fatal("no MCP call captured")
|
|
}
|
|
// Verify the call was made with at least the userId
|
|
if vo, ok := last.Args["QueryUserAttendVO"].(map[string]any); ok {
|
|
if vo["userId"] != "U001" {
|
|
t.Errorf("expected userId=U001, got %v", vo["userId"])
|
|
}
|
|
// workDate may or may not be present depending on compat layer
|
|
} else if last.Args["userId"] != "U001" {
|
|
// May pass flat params
|
|
t.Errorf("expected userId=U001 in some form, got args: %v", last.Args)
|
|
}
|
|
}
|
|
|
|
func TestAttendanceSummary_should_error_when_date_missing(t *testing.T) {
|
|
_ = setupTestDeps(t, "attendance")
|
|
root := buildRoot()
|
|
err := execCmd(t, root, []string{"attendance", "summary"}, map[string]string{"user": "U001", "date": ""})
|
|
if err == nil {
|
|
t.Fatal("expected error when --date is missing")
|
|
}
|
|
if !strings.Contains(err.Error(), "date") || !strings.Contains(err.Error(), "required") {
|
|
t.Errorf("expected error to mention date required, got: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestAttendanceSummary_should_error_when_user_missing(t *testing.T) {
|
|
_ = setupTestDeps(t, "attendance")
|
|
root := buildRoot()
|
|
err := execCmd(t, root, []string{"attendance", "summary"}, map[string]string{"user": "", "date": "2026-03-12 15:00:00"})
|
|
if err == nil {
|
|
t.Fatal("expected error when --user is missing")
|
|
}
|
|
if !strings.Contains(err.Error(), "user") || !strings.Contains(err.Error(), "required") {
|
|
t.Errorf("expected error to mention user required, got: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestAttendanceSummary_should_pass_only_user_flag(t *testing.T) {
|
|
cap := setupTestDeps(t, "attendance")
|
|
root := buildRoot()
|
|
_ = execCmd(t, root, []string{"attendance", "summary"}, map[string]string{"user": "U002", "date": "2026-03-12 15:00:00"})
|
|
last := cap.last()
|
|
if last == nil {
|
|
t.Fatal("no call captured")
|
|
}
|
|
vo, ok := last.Args["QueryUserAttendVO"].(map[string]any)
|
|
if !ok {
|
|
t.Fatalf("expected QueryUserAttendVO map, got %T", last.Args["QueryUserAttendVO"])
|
|
}
|
|
if vo["userId"] != "U002" {
|
|
t.Errorf("expected userId=U002, got %v", vo["userId"])
|
|
}
|
|
}
|
|
|
|
func TestAttendanceSummary_should_use_dry_run_mode(t *testing.T) {
|
|
cap := setupTestDepsWithDryRun(t, "attendance")
|
|
root := buildRoot()
|
|
err := execCmd(t, root, []string{"attendance", "summary"}, map[string]string{"user": "U001", "date": "2026-03-12 15:00:00"})
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
if cap.last() != nil {
|
|
t.Error("expected no MCP call in dry-run mode")
|
|
}
|
|
}
|
|
|
|
// ── attendance rules ───────────────────────────────────────
|
|
|
|
func TestAttendanceRules_should_call_tool_with_date(t *testing.T) {
|
|
cap := setupTestDeps(t, "attendance")
|
|
root := buildRoot()
|
|
err := execCmd(t, root, []string{"attendance", "rules"}, map[string]string{"date": "2026-03-14"})
|
|
if err != nil {
|
|
t.Fatalf("unexpected error: %v", err)
|
|
}
|
|
assertToolName(t, cap, "query_attendance_group_or_rules")
|
|
}
|
|
|
|
func TestAttendanceRules_should_pass_date_param(t *testing.T) {
|
|
cap := setupTestDeps(t, "attendance")
|
|
root := buildRoot()
|
|
_ = execCmd(t, root, []string{"attendance", "rules"}, map[string]string{"date": "2026-03-14 09:00:00"})
|
|
last := cap.last()
|
|
if last == nil {
|
|
t.Fatal("no MCP call captured")
|
|
}
|
|
if last.Args["date"] != "2026-03-14 09:00:00" {
|
|
t.Errorf("expected date=2026-03-14 09:00:00, got %v", last.Args["date"])
|
|
}
|
|
}
|