File size: 3,847 Bytes
fd2c364
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
import { beforeEach, describe, expect, it, vi } from "vitest";
import { render, screen } from "@testing-library/react";
import userEvent from "@testing-library/user-event";
import ConversationService from "#/api/conversation-service/conversation-service.api";
import { ChatMessage } from "#/components/features/chat/chat-message";
import { WorkspaceFilesForChatContext } from "#/components/features/chat/chat-markdown-path-code";
import { useFilesTabStore } from "#/stores/files-tab-store";

const openWorkspaceFile = vi.fn();

vi.mock("#/services/canvas-ui", () => ({
  openWorkspaceFile: (...args: unknown[]) => openWorkspaceFile(...args),
}));

vi.mock("#/hooks/use-conversation-id", () => ({
  useOptionalConversationId: () => ({ conversationId: "conv-1" }),
}));

const WORKSPACE_FILES = ["test.md", "motivational_message.md", "src/app.ts"];

function renderAgentMessage(
  message: string,
  files: string[] = WORKSPACE_FILES,
) {
  return render(
    <WorkspaceFilesForChatContext.Provider value={files}>
      <ChatMessage type="agent" message={message} />
    </WorkspaceFilesForChatContext.Provider>,
  );
}

describe("assistant chat Markdown path linking", () => {
  beforeEach(() => {
    openWorkspaceFile.mockClear();
    ConversationService.setCurrentConversation(null);
    useFilesTabStore.setState({
      selectedPath: null,
      selectedConversationId: null,
      openPaths: [],
    });
  });

  it("opens the Files drawer when an existing workspace path is clicked", async () => {
    const user = userEvent.setup();

    renderAgentMessage("Created `test.md`");

    await user.click(screen.getByTestId("markdown-file-path-link"));

    expect(openWorkspaceFile).toHaveBeenCalledWith("test.md", "conv-1");
  });

  it("opens the Files drawer for bold-emphasized existing paths", async () => {
    const user = userEvent.setup();

    renderAgentMessage(
      "The file **motivational_message.md** has been created with an inspiring quote.",
    );

    await user.click(screen.getByTestId("markdown-file-path-link"));

    expect(openWorkspaceFile).toHaveBeenCalledWith(
      "motivational_message.md",
      "conv-1",
    );
  });

  it("links absolute nested working-dir paths using ConversationService working_dir", async () => {
    const user = userEvent.setup();
    ConversationService.setCurrentConversation({
      id: "conv-1",
      workspace: { working_dir: "/workspace/project/packages/app" },
    } as never);

    renderAgentMessage("See `/workspace/project/packages/app/src/index.ts`", [
      "src/index.ts",
    ]);

    await user.click(screen.getByTestId("markdown-file-path-link"));

    expect(openWorkspaceFile).toHaveBeenCalledWith("src/index.ts", "conv-1");
  });

  it("does not link paths that are not in the workspace", () => {
    renderAgentMessage("Send me exactly same text - profile.md");

    expect(
      screen.queryByTestId("markdown-file-path-link"),
    ).not.toBeInTheDocument();
    expect(screen.getByText(/profile\.md/)).toBeInTheDocument();
  });

  it("does not link missing backtick paths either", () => {
    renderAgentMessage("See `profile.md` please");

    expect(
      screen.queryByTestId("markdown-file-path-link"),
    ).not.toBeInTheDocument();
    expect(screen.getByText("profile.md").tagName).toBe("CODE");
  });

  it("keeps path code nested in a Markdown link as plain code", () => {
    renderAgentMessage("See [`src/app.ts`](https://example.com)");

    expect(
      screen.queryByTestId("markdown-file-path-link"),
    ).not.toBeInTheDocument();
    expect(screen.getByText("src/app.ts").tagName).toBe("CODE");
  });

  it("does not link ordinary dotted / non-path inline code", () => {
    renderAgentMessage("Use `console.log` and `v1.2.3`");

    expect(
      screen.queryByTestId("markdown-file-path-link"),
    ).not.toBeInTheDocument();
  });
});