feat(webview): Accept/Reject + dropdown, rejectAll, control parity (#64, INV-53)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -164,3 +164,36 @@ suite("F12 inline diff — editor surface (#64, INV-48/52)", () => {
|
||||
assert.strictEqual(api.proposalController.listProposals(doc).length, 0, "cleared");
|
||||
});
|
||||
});
|
||||
|
||||
suite("F12 inline diff — control parity (#64, INV-53)", () => {
|
||||
test("reject from the webview reverts in place; rejectAll clears every proposal", async () => {
|
||||
const { doc, key } = await freshDoc("docs/f12-parity.md", "# P\n\nuno aaa.\n\ndos bbb.\n");
|
||||
const api = await getApi();
|
||||
const ctl = api.trackChangesPreviewController;
|
||||
await vscode.commands.executeCommand("cowriting.showTrackChangesPreview");
|
||||
await settle();
|
||||
ctl.setEditTurnForTest(async () => ({ replacement: "# P\n\nuno AAA.\n\ndos BBB.\n", model: "m", sessionId: "s" }));
|
||||
const ids = await ctl.runEditAndPropose(doc, { kind: "document" }, "up");
|
||||
await settle(); await settle();
|
||||
assert.ok(doc.getText().includes("AAA") && doc.getText().includes("BBB"));
|
||||
// reject ONE via the webview intent → that block reverts, the other stays applied
|
||||
ctl.receiveMessage(key, { type: "reject", proposalId: ids[0] });
|
||||
await settle(); await settle();
|
||||
assert.ok(doc.getText().includes("uno aaa.") && doc.getText().includes("BBB"), "one reverted, one applied");
|
||||
// rejectAll via the command → all gone, document restored
|
||||
ctl.receiveMessage(key, { type: "rejectAll" });
|
||||
await settle(); await settle();
|
||||
assert.strictEqual(doc.getText(), "# P\n\nuno aaa.\n\ndos bbb.\n", "document restored");
|
||||
assert.strictEqual(api.proposalController.listProposals(doc).length, 0);
|
||||
});
|
||||
|
||||
test("cowriting.rejectAllProposals is registered + markdown-guarded", async () => {
|
||||
const all = await vscode.commands.getCommands(true);
|
||||
assert.ok(all.includes("cowriting.rejectAllProposals"));
|
||||
const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, "../../../../package.json"), "utf8"));
|
||||
const entry = (pkg.contributes.menus.commandPalette as Array<{ command: string; when?: string }>).find(
|
||||
(m) => m.command === "cowriting.rejectAllProposals",
|
||||
);
|
||||
assert.ok(entry && /editorLangId == markdown/.test(entry.when ?? ""), "palette-guarded on markdown");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -231,7 +231,7 @@ describe("renderReview", () => {
|
||||
const html = renderReview("hello world", "hello", [], []);
|
||||
expect(html).toMatch(/<del>|cw-del/);
|
||||
});
|
||||
test("renderReview: a pending proposal renders a blue block with data-proposal-id and ✓/✗ actions", () => {
|
||||
test("renderReview: a pending proposal renders a blue block with data-proposal-id and Accept/Reject actions", () => {
|
||||
const proposals: ProposalView[] = [{ id: "p1", anchorStart: 0, anchorEnd: 5, replaced: "hello", replacement: "goodbye" }];
|
||||
const html = renderReview("hello", "hello", [], proposals);
|
||||
expect(html).toContain('class="cw-proposal"');
|
||||
@@ -412,6 +412,18 @@ describe("renderReview", () => {
|
||||
// the Claude coloring wraps "stable" exactly — not shifted by the proposal's length delta.
|
||||
expect(html).toMatch(/<span class="cw-by-claude">stable<\/span>/);
|
||||
});
|
||||
|
||||
test("proposalBlockHtml renders Accept/Reject controls with dropdown carets (#64)", () => {
|
||||
const html = renderReview("a\n", "b\n", [], [
|
||||
{ id: "pr_1", anchorStart: 0, anchorEnd: 1, replaced: "a", replacement: "b" },
|
||||
]);
|
||||
expect(html).toMatch(/data-action="accept"/);
|
||||
expect(html).toMatch(/data-action="reject"/);
|
||||
expect(html).toMatch(/data-action="acceptAll"/);
|
||||
expect(html).toMatch(/data-action="rejectAll"/);
|
||||
expect(html).toMatch(/Accept/);
|
||||
expect(html).toMatch(/Reject/);
|
||||
});
|
||||
});
|
||||
|
||||
import { renderTrackChanges as rtc2 } from "../src/trackChangesModel";
|
||||
|
||||
Reference in New Issue
Block a user