11import * as vscode from "vscode"
22import { GitFetcher } from "../GitFetcher"
33import * as fs from "fs/promises"
4+ import * as path from "path"
45import { Dirent , Stats } from "fs"
56import simpleGit , { SimpleGit } from "simple-git"
67import { MetadataScanner } from "../MetadataScanner"
@@ -48,7 +49,7 @@ jest.mock("util", () => ({
4849// Mock vscode
4950const mockContext = {
5051 globalStorageUri : {
51- fsPath : "/ mock/ storage/ path",
52+ fsPath : path . join ( process . cwd ( ) , " mock- storage- path") ,
5253 } ,
5354} as vscode . ExtensionContext
5455
@@ -73,24 +74,28 @@ describe("GitFetcher", () => {
7374 let gitFetcher : GitFetcher
7475 const mockSimpleGit = simpleGit as jest . MockedFunction < typeof simpleGit >
7576 const testRepoUrl = "https://github.com/test/repo"
76- const testRepoDir = "/mock/storage/ path/ package-manager-cache/ repo"
77+ const testRepoDir = path . join ( mockContext . globalStorageUri . fsPath , " package-manager-cache" , " repo")
7778
7879 beforeEach ( ( ) => {
7980 jest . clearAllMocks ( )
8081 gitFetcher = new GitFetcher ( mockContext )
8182
8283 // Reset fs mock defaults
8384 ; ( fs . mkdir as jest . Mock ) . mockResolvedValue ( undefined )
84- ; ( fs . rm as jest . Mock ) . mockImplementation ( ( path : string , options ?: any ) => {
85+ ; ( fs . rm as jest . Mock ) . mockImplementation ( ( pathToRemove : string , options ?: any ) => {
8586 // Always require recursive and force options
8687 if ( ! options ?. recursive || ! options ?. force ) {
8788 return Promise . reject ( new Error ( "Invalid rm call: missing recursive or force options" ) )
8889 }
8990 // Allow any path under package-manager-cache directory
90- if ( path . includes ( "package-manager-cache/" ) ) {
91+ const normalizedPath = path . normalize ( pathToRemove )
92+ const normalizedCachePath = path . normalize (
93+ path . join ( mockContext . globalStorageUri . fsPath , "package-manager-cache" ) ,
94+ )
95+ if ( normalizedPath . startsWith ( normalizedCachePath ) ) {
9196 return Promise . resolve ( undefined )
9297 }
93- return Promise . reject ( new Error ( " Invalid rm call: path not in package-manager-cache" ) )
98+ return Promise . reject ( new Error ( ` Invalid rm call: path ${ pathToRemove } not in package-manager-cache` ) )
9499 } )
95100
96101 // Setup fs.stat mock for repository structure validation
@@ -182,18 +187,15 @@ describe("GitFetcher", () => {
182187 } )
183188
184189 it ( "should handle clone failures" , async ( ) => {
185- const error = new Error ( "fatal: repository not found" )
186190 const mockGit = {
187191 ...mockSimpleGit ( ) ,
188- clone : jest . fn ( ) . mockRejectedValue ( error ) ,
192+ clone : jest . fn ( ) . mockRejectedValue ( new Error ( "fatal: repository not found" ) ) ,
189193 pull : jest . fn ( ) ,
190194 revparse : jest . fn ( ) ,
191195 } as unknown as SimpleGit
192196 mockSimpleGit . mockReturnValue ( mockGit )
193197
194- await expect ( gitFetcher . fetchRepository ( testRepoUrl ) ) . rejects . toThrow (
195- "Failed to clone/pull repository: fatal: repository not found" ,
196- )
198+ await expect ( gitFetcher . fetchRepository ( testRepoUrl ) ) . rejects . toThrow ( / F a i l e d t o c l o n e \/ p u l l r e p o s i t o r y / )
197199
198200 // Verify cleanup was called
199201 expect ( fs . rm ) . toHaveBeenCalledWith ( testRepoDir , { recursive : true , force : true } )
0 commit comments