summaryrefslogtreecommitdiff
path: root/internal/askcli/command_edit_test.go
blob: 3f4b7783f5dfb242418f7c1b897afed99219ae9a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package askcli

import (
	"bytes"
	"context"
	"errors"
	"io"
	"strings"
	"testing"
)

func stubEditorCapture(t *testing.T, content string, err error) {
	t.Helper()
	old := captureFromEditor
	captureFromEditor = func() (string, error) {
		return content, err
	}
	t.Cleanup(func() { captureFromEditor = old })
}

func TestHandleEdit_Success(t *testing.T) {
	now := useIsolatedTaskAliasCache(t)
	writeTaskAliasCacheForTest(t, taskAliasCache{
		NextID: 1,
		Entries: []taskAliasCacheEntry{
			{UUID: "existing-uuid", Alias: "0", CreatedAt: now},
		},
	})
	// editor.OpenTempAndEdit trims content, so mimic that here.
	stubEditorCapture(t, "Multi line\ntask description", nil)

	var capturedArgs []string
	d := NewDispatcher(&spyRunner{runFn: func(ctx context.Context, args []string, stdin io.Reader, stdout, stderr io.Writer) (int, error) {
		capturedArgs = args
		_, _ = io.WriteString(stdout, "Created task abc-123-def.")
		return 0, nil
	}})

	var stdout, stderr bytes.Buffer
	code, _ := d.Dispatch(context.Background(), []string{"edit"}, nil, &stdout, &stderr)
	if code != 0 {
		t.Fatalf("edit code = %d stderr = %q", code, stderr.String())
	}
	if got := strings.TrimSpace(stdout.String()); got != "created task 1" {
		t.Fatalf("stdout = %q, want created task 1", stdout.String())
	}
	if len(capturedArgs) == 0 || capturedArgs[len(capturedArgs)-1] != "Multi line\ntask description" {
		t.Fatalf("description arg = %v, want trimmed multi-line content", capturedArgs)
	}
}

func TestHandleEdit_EmptyContentAborts(t *testing.T) {
	stubEditorCapture(t, "", nil)

	d := NewDispatcher(&spyRunner{runFn: func(ctx context.Context, args []string, stdin io.Reader, stdout, stderr io.Writer) (int, error) {
		t.Fatalf("runner should not be called on empty content")
		return 0, nil
	}})

	var stdout, stderr bytes.Buffer
	code, _ := d.Dispatch(context.Background(), []string{"edit"}, nil, &stdout, &stderr)
	if code != 1 {
		t.Fatalf("edit code = %d, want 1", code)
	}
	if !strings.Contains(stderr.String(), "empty description") {
		t.Fatalf("stderr = %q, want empty description error", stderr.String())
	}
}

func TestHandleEdit_EditorError(t *testing.T) {
	stubEditorCapture(t, "", errors.New("boom"))

	d := NewDispatcher(&spyRunner{runFn: func(ctx context.Context, args []string, stdin io.Reader, stdout, stderr io.Writer) (int, error) {
		t.Fatalf("runner should not be called when editor fails")
		return 0, nil
	}})

	var stdout, stderr bytes.Buffer
	code, _ := d.Dispatch(context.Background(), []string{"edit"}, nil, &stdout, &stderr)
	if code != 1 {
		t.Fatalf("edit code = %d, want 1", code)
	}
	if !strings.Contains(stderr.String(), "boom") {
		t.Fatalf("stderr = %q, want editor error", stderr.String())
	}
}