@@ -10,6 +10,16 @@ import {
1010 needsResolution ,
1111 maskSensitiveValue ,
1212} from './value-resolver.js' ;
13+ import * as shellUtils from '../../utils/shell-utils.js' ;
14+
15+ vi . mock ( '../../utils/shell-utils.js' , async ( importOriginal ) => {
16+ const actual =
17+ await importOriginal < typeof import ( '../../utils/shell-utils.js' ) > ( ) ;
18+ return {
19+ ...actual ,
20+ spawnAsync : vi . fn ( ) ,
21+ } ;
22+ } ) ;
1323
1424describe ( 'value-resolver' , ( ) => {
1525 describe ( 'resolveAuthValue' , ( ) => {
@@ -39,12 +49,24 @@ describe('value-resolver', () => {
3949 } ) ;
4050
4151 describe ( 'shell commands' , ( ) => {
52+ afterEach ( ( ) => {
53+ vi . restoreAllMocks ( ) ;
54+ } ) ;
55+
4256 it ( 'should execute shell command with ! prefix' , async ( ) => {
57+ vi . mocked ( shellUtils . spawnAsync ) . mockResolvedValue ( {
58+ stdout : 'hello\n' ,
59+ stderr : '' ,
60+ } ) ;
4361 const result = await resolveAuthValue ( '!echo hello' ) ;
4462 expect ( result ) . toBe ( 'hello' ) ;
4563 } ) ;
4664
4765 it ( 'should trim whitespace from command output' , async ( ) => {
66+ vi . mocked ( shellUtils . spawnAsync ) . mockResolvedValue ( {
67+ stdout : ' hello \n' ,
68+ stderr : '' ,
69+ } ) ;
4870 const result = await resolveAuthValue ( '!echo " hello "' ) ;
4971 expect ( result ) . toBe ( 'hello' ) ;
5072 } ) ;
@@ -56,16 +78,32 @@ describe('value-resolver', () => {
5678 } ) ;
5779
5880 it ( 'should throw error for command that returns empty output' , async ( ) => {
81+ vi . mocked ( shellUtils . spawnAsync ) . mockResolvedValue ( {
82+ stdout : '' ,
83+ stderr : '' ,
84+ } ) ;
5985 await expect ( resolveAuthValue ( '!echo -n ""' ) ) . rejects . toThrow (
6086 'returned empty output' ,
6187 ) ;
6288 } ) ;
6389
6490 it ( 'should throw error for failed command' , async ( ) => {
91+ vi . mocked ( shellUtils . spawnAsync ) . mockRejectedValue (
92+ new Error ( 'Command failed' ) ,
93+ ) ;
6594 await expect (
6695 resolveAuthValue ( '!nonexistent-command-12345' ) ,
6796 ) . rejects . toThrow ( / C o m m a n d .* f a i l e d / ) ;
6897 } ) ;
98+
99+ it ( 'should throw error for timeout' , async ( ) => {
100+ const timeoutError = new Error ( 'AbortError' ) ;
101+ timeoutError . name = 'AbortError' ;
102+ vi . mocked ( shellUtils . spawnAsync ) . mockRejectedValue ( timeoutError ) ;
103+ await expect ( resolveAuthValue ( '!sleep 100' ) ) . rejects . toThrow (
104+ / t i m e d o u t a f t e r / ,
105+ ) ;
106+ } ) ;
69107 } ) ;
70108
71109 describe ( 'literal values' , ( ) => {
0 commit comments