@@ -112,6 +112,21 @@ describe('detectMusl', () => {
112112 expect ( detectMusl ( ) ) . toBe ( false )
113113 } )
114114
115+ it ( 'should detect musl via /proc/version' , ( ) => {
116+ vi . spyOn ( process , 'platform' , 'get' ) . mockReturnValue ( 'linux' )
117+ vi . mocked ( fs . existsSync ) . mockImplementation ( ( path : unknown ) => {
118+ // Only /proc/version exists, no /etc/os-release or ld-musl.
119+ return path === '/proc/version'
120+ } )
121+ vi . mocked ( fs . readFileSync ) . mockImplementation ( ( path : unknown ) => {
122+ if ( path === '/proc/version' ) {
123+ return 'Linux version 5.15.0 (musl-libc compiler)'
124+ }
125+ throw new Error ( 'File not found' )
126+ } )
127+ expect ( detectMusl ( ) ) . toBe ( true )
128+ } )
129+
115130 it ( 'should cache the result' , ( ) => {
116131 vi . spyOn ( process , 'platform' , 'get' ) . mockReturnValue ( 'linux' )
117132 let existsSyncCallCount = 0
@@ -474,6 +489,31 @@ describe('clearQuarantine', () => {
474489
475490 expect ( spawnMock ) . not . toHaveBeenCalled ( )
476491 } )
492+
493+ it ( 'should call xattr on macOS' , async ( ) => {
494+ vi . spyOn ( process , 'platform' , 'get' ) . mockReturnValue ( 'darwin' )
495+ const spawnModule = await import ( '@socketsecurity/lib/spawn' )
496+ const spawnMock = vi . mocked ( spawnModule . spawn )
497+ spawnMock . mockResolvedValue ( { exitCode : 0 } as never )
498+
499+ await clearQuarantine ( '/path/to/file' )
500+
501+ expect ( spawnMock ) . toHaveBeenCalledWith (
502+ 'xattr' ,
503+ [ '-d' , 'com.apple.quarantine' , '/path/to/file' ] ,
504+ { stdio : 'ignore' } ,
505+ )
506+ } )
507+
508+ it ( 'should handle xattr failure gracefully' , async ( ) => {
509+ vi . spyOn ( process , 'platform' , 'get' ) . mockReturnValue ( 'darwin' )
510+ const spawnModule = await import ( '@socketsecurity/lib/spawn' )
511+ const spawnMock = vi . mocked ( spawnModule . spawn )
512+ spawnMock . mockRejectedValue ( new Error ( 'xattr not found' ) )
513+
514+ // Should not throw.
515+ await clearQuarantine ( '/path/to/file' )
516+ } )
477517} )
478518
479519describe ( 'ensureExecutable' , ( ) => {
@@ -487,4 +527,32 @@ describe('ensureExecutable', () => {
487527 // Should not throw.
488528 await ensureExecutable ( '/path/to/file' )
489529 } )
530+
531+ it ( 'should call chmod on Unix (macOS)' , async ( ) => {
532+ vi . spyOn ( process , 'platform' , 'get' ) . mockReturnValue ( 'darwin' )
533+ const chmodMock = vi . spyOn ( fs . promises , 'chmod' ) . mockResolvedValue ( )
534+
535+ await ensureExecutable ( '/path/to/file' )
536+
537+ expect ( chmodMock ) . toHaveBeenCalledWith ( '/path/to/file' , 0o755 )
538+ } )
539+
540+ it ( 'should call chmod on Unix (Linux)' , async ( ) => {
541+ vi . spyOn ( process , 'platform' , 'get' ) . mockReturnValue ( 'linux' )
542+ const chmodMock = vi . spyOn ( fs . promises , 'chmod' ) . mockResolvedValue ( )
543+
544+ await ensureExecutable ( '/path/to/file' )
545+
546+ expect ( chmodMock ) . toHaveBeenCalledWith ( '/path/to/file' , 0o755 )
547+ } )
548+
549+ it ( 'should handle chmod failure gracefully' , async ( ) => {
550+ vi . spyOn ( process , 'platform' , 'get' ) . mockReturnValue ( 'darwin' )
551+ vi . spyOn ( fs . promises , 'chmod' ) . mockRejectedValue (
552+ new Error ( 'Permission denied' ) ,
553+ )
554+
555+ // Should not throw.
556+ await ensureExecutable ( '/path/to/file' )
557+ } )
490558} )
0 commit comments