basant307/AI_Governance_Project
048
1/**2 * @license3 * Copyright 2025 Google LLC4 * SPDX-License-Identifier: Apache-2.05 */6 7import { describe, it, expect, vi, beforeEach } from 'vitest';8import { linkCommand, handleLink } from './link.js';9import yargs from 'yargs';10 11const mockInstallExtension = vi.hoisted(() => vi.fn());12const mockWriteStdoutLine = vi.hoisted(() => vi.fn());13const mockWriteStderrLine = vi.hoisted(() => vi.fn());14 15vi.mock('./utils.js', () => ({16 getExtensionManager: vi.fn().mockResolvedValue({17 installExtension: mockInstallExtension,18 }),19}));20 21vi.mock('./consent.js', () => ({22 requestConsentNonInteractive: vi.fn().mockResolvedValue(true),23 requestConsentOrFail: vi.fn(),24}));25 26vi.mock('../../utils/errors.js', () => ({27 getErrorMessage: vi.fn((error: Error) => error.message),28}));29 30vi.mock('../../utils/stdioHelpers.js', () => ({31 writeStdoutLine: mockWriteStdoutLine,32 writeStderrLine: mockWriteStderrLine,33 clearScreen: vi.fn(),34}));35 36describe('extensions link command', () => {37 it('should fail if no path is provided', () => {38 const validationParser = yargs([])39 .command(linkCommand)40 .fail(false)41 .locale('en');42 expect(() => validationParser.parse('link')).toThrow(43 'Not enough non-option arguments: got 0, need at least 1',44 );45 });46 47 it('should accept a path argument', () => {48 const parser = yargs([]).command(linkCommand).fail(false).locale('en');49 expect(() => parser.parse('link /some/path')).not.toThrow();50 });51});52 53describe('handleLink', () => {54 beforeEach(() => {55 vi.clearAllMocks();56 });57 58 it('should link an extension from a local path', async () => {59 const processExitSpy = vi60 .spyOn(process, 'exit')61 .mockImplementation(() => undefined as never);62 63 mockInstallExtension.mockResolvedValueOnce({ name: 'linked-extension' });64 65 await handleLink({66 path: '/some/local/path',67 });68 69 expect(mockInstallExtension).toHaveBeenCalledWith(70 {71 source: '/some/local/path',72 type: 'link',73 },74 expect.any(Function),75 );76 expect(mockWriteStdoutLine).toHaveBeenCalledWith(77 'Extension "linked-extension" linked successfully and enabled.',78 );79 80 processExitSpy.mockRestore();81 });82 83 it('should handle errors and exit with code 1', async () => {84 const processExitSpy = vi85 .spyOn(process, 'exit')86 .mockImplementation(() => undefined as never);87 88 mockInstallExtension.mockRejectedValueOnce(new Error('Link failed'));89 90 await handleLink({91 path: '/some/local/path',92 });93 94 expect(mockWriteStderrLine).toHaveBeenCalledWith('Link failed');95 expect(processExitSpy).toHaveBeenCalledWith(1);96 97 processExitSpy.mockRestore();98 });99});100 