Path: blob/main/extensions/copilot/src/extension/chatSessions/copilotcli/vscode-node/test/diffCommands.spec.ts
13406 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { beforeEach, describe, expect, it, vi } from 'vitest';6import { TestLogService } from '../../../../../platform/testing/common/testLogService';78const { mockRegisterCommand, mockTabGroups } = vi.hoisted(() => ({9mockRegisterCommand: vi.fn(),10mockTabGroups: {11activeTabGroup: { activeTab: null as unknown },12all: [] as unknown[],13close: vi.fn().mockResolvedValue(undefined),14onDidChangeTabGroups: () => ({ dispose: () => { } }),15onDidChangeTabs: vi.fn(() => ({ dispose: () => { } })),16},17}));1819vi.mock('vscode', () => ({20window: {21tabGroups: mockTabGroups,22},23commands: {24registerCommand: (...args: unknown[]) => mockRegisterCommand(...args),25executeCommand: vi.fn().mockResolvedValue(undefined),26},27TabInputTextDiff: class TabInputTextDiff {28constructor(public original: unknown, public modified: unknown) { }29},30}));3132import * as vscode from 'vscode';33import { DiffStateManager, type ActiveDiff } from '../diffState';34import { registerDiffCommands, ACCEPT_DIFF_COMMAND, REJECT_DIFF_COMMAND } from '../commands/diffCommands';3536function createTestDiff(tabName: string): ActiveDiff {37const modifiedUri = { toString: () => 'modified://' + tabName } as unknown as vscode.Uri;38const originalUri = { toString: () => 'original://' + tabName } as unknown as vscode.Uri;39return {40diffId: 'diff-' + tabName,41tabName,42originalUri,43modifiedUri,44newContents: 'new content',45cleanup: vi.fn(),46resolve: vi.fn(),47};48}4950function createDiffTab(tabName: string, modifiedUri: vscode.Uri) {51return {52label: tabName,53input: new vscode.TabInputTextDiff(54{ scheme: 'copilot-cli-readonly' } as unknown as vscode.Uri,55modifiedUri,56),57};58}5960describe('diff accept/reject commands', () => {61const logger = new TestLogService();62let diffState: DiffStateManager;63let registeredCommands: Map<string, (...args: unknown[]) => void>;6465beforeEach(() => {66vi.clearAllMocks();67diffState = new DiffStateManager(logger);68registeredCommands = new Map();6970mockRegisterCommand.mockImplementation((name: string, callback: (...args: unknown[]) => void) => {71registeredCommands.set(name, callback);72return { dispose: () => { } };73});7475mockTabGroups.activeTabGroup = { activeTab: null };76mockTabGroups.all = [];77});7879it('should register accept and reject commands', () => {80registerDiffCommands(logger, diffState);8182expect(registeredCommands.has(ACCEPT_DIFF_COMMAND)).toBe(true);83expect(registeredCommands.has(REJECT_DIFF_COMMAND)).toBe(true);84});8586it('should resolve diff as SAVED when accept command is executed', () => {87registerDiffCommands(logger, diffState);8889const diff = createTestDiff('Test Diff');90diffState.register(diff);9192const tab = createDiffTab('Test Diff', diff.modifiedUri);93mockTabGroups.activeTabGroup = { activeTab: tab };9495registeredCommands.get(ACCEPT_DIFF_COMMAND)!();9697expect(diff.cleanup).toHaveBeenCalled();98expect(diff.resolve).toHaveBeenCalledWith(99expect.objectContaining({ status: 'SAVED', trigger: 'accepted_via_button' }),100);101});102103it('should resolve diff as REJECTED when reject command is executed', () => {104registerDiffCommands(logger, diffState);105106const diff = createTestDiff('Reject Diff');107diffState.register(diff);108109const tab = createDiffTab('Reject Diff', diff.modifiedUri);110mockTabGroups.activeTabGroup = { activeTab: tab };111112registeredCommands.get(REJECT_DIFF_COMMAND)!();113114expect(diff.cleanup).toHaveBeenCalled();115expect(diff.resolve).toHaveBeenCalledWith(116expect.objectContaining({ status: 'REJECTED', trigger: 'rejected_via_button' }),117);118});119120it('should not resolve when active tab is not a diff tab', () => {121registerDiffCommands(logger, diffState);122123mockTabGroups.activeTabGroup = { activeTab: { label: 'Not A Diff', input: {} } };124125// Should not throw126registeredCommands.get(ACCEPT_DIFF_COMMAND)!();127});128129it('should not resolve when there is no active tab', () => {130registerDiffCommands(logger, diffState);131132mockTabGroups.activeTabGroup = { activeTab: null };133134registeredCommands.get(REJECT_DIFF_COMMAND)!();135});136137it('should not close the tab (tab closing is handled by closeDiff tool)', () => {138registerDiffCommands(logger, diffState);139140const diff = createTestDiff('Close Test');141diffState.register(diff);142143const tab = createDiffTab('Close Test', diff.modifiedUri);144mockTabGroups.activeTabGroup = { activeTab: tab };145146registeredCommands.get(ACCEPT_DIFF_COMMAND)!();147148// diffCommands resolves the diff but does NOT close the tab149expect(diff.resolve).toHaveBeenCalled();150expect(mockTabGroups.close).not.toHaveBeenCalled();151});152});153154155