Skip to content

Commit d36c62e

Browse files
authored
Merge pull request #62 from saagpatel/codex/fix/response-actions-purity
fix(components): inject tauri calls into useResponseActions
2 parents ca16719 + 4595ae0 commit d36c62e

4 files changed

Lines changed: 51 additions & 19 deletions

File tree

src/components/Draft/DraftTab.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {
55
useImperativeHandle,
66
useMemo,
77
} from "react";
8+
import { auditResponseCopyOverride, exportDraft } from "./draftTauriCommands";
89
import { DraftResponsePanel } from "./DraftResponsePanel";
910
import { InputPanel } from "./InputPanel";
1011
import { DiagnosisPanel, TreeResult } from "./DiagnosisPanel";
@@ -529,6 +530,8 @@ export const DraftTab = forwardRef<DraftTabHandle, DraftTabProps>(
529530
streamingText,
530531
cancelGeneration,
531532
saveAsTemplate,
533+
auditResponseCopyOverride,
534+
exportDraft,
532535
logEvent,
533536
setResponse,
534537
setOriginalResponse,
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { invoke } from "@tauri-apps/api/core";
2+
3+
interface AuditResponseCopyOverrideParams {
4+
reason: string;
5+
confidenceMode: string | null;
6+
sourcesCount: number;
7+
}
8+
9+
export function auditResponseCopyOverride(
10+
params: AuditResponseCopyOverrideParams,
11+
): Promise<unknown> {
12+
return invoke("audit_response_copy_override", { ...params });
13+
}
14+
15+
interface ExportDraftParams {
16+
responseText: string;
17+
format: "Markdown";
18+
}
19+
20+
export function exportDraft(params: ExportDraftParams): Promise<boolean> {
21+
return invoke<boolean>("export_draft", { ...params });
22+
}

src/components/Draft/useResponseActions.test.ts

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
11
// @vitest-environment jsdom
22
import { act, renderHook } from "@testing-library/react";
33
import { beforeEach, describe, expect, it, vi } from "vitest";
4-
5-
const invokeMock = vi.fn();
6-
vi.mock("@tauri-apps/api/core", () => ({
7-
invoke: (command: string, payload?: Record<string, unknown>) =>
8-
invokeMock(command, payload),
9-
}));
10-
114
import { useResponseActions } from "./useResponseActions";
125

136
type HookOptions = Parameters<typeof useResponseActions>[0];
@@ -16,8 +9,6 @@ const writeText = vi.fn().mockResolvedValue(undefined);
169

1710
beforeEach(() => {
1811
writeText.mockClear();
19-
invokeMock.mockReset();
20-
invokeMock.mockResolvedValue(true);
2112
Object.defineProperty(navigator, "clipboard", {
2213
value: { writeText },
2314
configurable: true,
@@ -38,6 +29,8 @@ function makeOptions(overrides: Partial<HookOptions> = {}): HookOptions {
3829

3930
cancelGeneration: vi.fn(),
4031
saveAsTemplate: vi.fn().mockResolvedValue("tpl-1"),
32+
auditResponseCopyOverride: vi.fn().mockResolvedValue(undefined),
33+
exportDraft: vi.fn().mockResolvedValue(true),
4134
logEvent: vi.fn(),
4235

4336
setResponse: vi.fn(),
@@ -62,10 +55,7 @@ describe("useResponseActions", () => {
6255
});
6356

6457
expect(writeText).toHaveBeenCalledWith("generated text");
65-
expect(invokeMock).not.toHaveBeenCalledWith(
66-
"audit_response_copy_override",
67-
expect.anything(),
68-
);
58+
expect(options.auditResponseCopyOverride).not.toHaveBeenCalled();
6959
expect(options.setHandoffTouched).toHaveBeenCalledWith(true);
7060
expect(options.onShowSuccess).toHaveBeenCalledWith(
7161
"Response copied to clipboard",
@@ -84,7 +74,7 @@ describe("useResponseActions", () => {
8474
});
8575

8676
expect(promptSpy).toHaveBeenCalled();
87-
expect(invokeMock).toHaveBeenCalledWith("audit_response_copy_override", {
77+
expect(options.auditResponseCopyOverride).toHaveBeenCalledWith({
8878
reason: "ops needs this now",
8979
confidenceMode: "answer",
9080
sourcesCount: 0,
@@ -115,7 +105,7 @@ describe("useResponseActions", () => {
115105
await result.current.handleExportResponse();
116106
});
117107

118-
expect(invokeMock).toHaveBeenCalledWith("export_draft", {
108+
expect(options.exportDraft).toHaveBeenCalledWith({
119109
responseText: "generated text",
120110
format: "Markdown",
121111
});

src/components/Draft/useResponseActions.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { invoke } from "@tauri-apps/api/core";
21
import { useCallback, useState } from "react";
32
import {
43
calculateEditRatio,
@@ -14,6 +13,17 @@ interface TemplateSaveOptions {
1413
variablesJson?: string;
1514
}
1615

16+
interface AuditResponseCopyOverrideParams {
17+
reason: string;
18+
confidenceMode: string | null;
19+
sourcesCount: number;
20+
}
21+
22+
interface ExportDraftParams {
23+
responseText: string;
24+
format: "Markdown";
25+
}
26+
1727
interface UseResponseActionsOptions {
1828
response: string;
1929
originalResponse: string;
@@ -29,6 +39,10 @@ interface UseResponseActionsOptions {
2939
content: string,
3040
options: TemplateSaveOptions,
3141
) => Promise<string | null>;
42+
auditResponseCopyOverride: (
43+
params: AuditResponseCopyOverrideParams,
44+
) => Promise<unknown>;
45+
exportDraft: (params: ExportDraftParams) => Promise<boolean>;
3246
logEvent: (event: string, payload?: Record<string, unknown>) => unknown;
3347

3448
setResponse: (value: string) => void;
@@ -51,6 +65,8 @@ export function useResponseActions({
5165
streamingText,
5266
cancelGeneration,
5367
saveAsTemplate,
68+
auditResponseCopyOverride,
69+
exportDraft,
5470
logEvent,
5571
setResponse,
5672
setOriginalResponse,
@@ -146,7 +162,7 @@ export function useResponseActions({
146162
onShowError("Copy cancelled (reason required).");
147163
return;
148164
}
149-
await invoke("audit_response_copy_override", {
165+
await auditResponseCopyOverride({
150166
reason: reason.trim(),
151167
confidenceMode: confidence?.mode ?? null,
152168
sourcesCount: sources.length,
@@ -170,6 +186,7 @@ export function useResponseActions({
170186
response,
171187
confidence?.mode,
172188
sources.length,
189+
auditResponseCopyOverride,
173190
logEvent,
174191
savedDraftId,
175192
isResponseEdited,
@@ -185,7 +202,7 @@ export function useResponseActions({
185202
return;
186203
}
187204
try {
188-
const saved = await invoke<boolean>("export_draft", {
205+
const saved = await exportDraft({
189206
responseText: response,
190207
format: "Markdown",
191208
});
@@ -196,7 +213,7 @@ export function useResponseActions({
196213
} catch (e) {
197214
onShowError(`Export failed: ${e}`);
198215
}
199-
}, [response, setHandoffTouched, onShowSuccess, onShowError]);
216+
}, [response, exportDraft, setHandoffTouched, onShowSuccess, onShowError]);
200217

201218
const resetResponseActions = useCallback(() => {
202219
setShowTemplateModal(false);

0 commit comments

Comments
 (0)