@@ -715,7 +715,7 @@ describe('extension tests', () => {
715715
716716 it ( 'should throw an error if the extension does not exist' , async ( ) => {
717717 await expect ( uninstallExtension ( 'nonexistent-extension' ) ) . rejects . toThrow (
718- 'Extension "nonexistent-extension" not found.' ,
718+ 'Extension not found.' ,
719719 ) ;
720720 } ) ;
721721
@@ -733,6 +733,40 @@ describe('extension tests', () => {
733733 new ExtensionUninstallEvent ( 'my-local-extension' , 'success' ) ,
734734 ) ;
735735 } ) ;
736+
737+ it ( 'should uninstall an extension by its source URL' , async ( ) => {
738+ const gitUrl = 'https://github.com/google/gemini-sql-extension.git' ;
739+ const sourceExtDir = createExtension ( {
740+ extensionsDir : userExtensionsDir ,
741+ name : 'gemini-sql-extension' ,
742+ version : '1.0.0' ,
743+ installMetadata : {
744+ source : gitUrl ,
745+ type : 'git' ,
746+ } ,
747+ } ) ;
748+
749+ await uninstallExtension ( gitUrl ) ;
750+
751+ expect ( fs . existsSync ( sourceExtDir ) ) . toBe ( false ) ;
752+ const logger = ClearcutLogger . getInstance ( { } as Config ) ;
753+ expect ( logger ?. logExtensionUninstallEvent ) . toHaveBeenCalledWith (
754+ new ExtensionUninstallEvent ( 'gemini-sql-extension' , 'success' ) ,
755+ ) ;
756+ } ) ;
757+
758+ it ( 'should fail to uninstall by URL if an extension has no install metadata' , async ( ) => {
759+ createExtension ( {
760+ extensionsDir : userExtensionsDir ,
761+ name : 'no-metadata-extension' ,
762+ version : '1.0.0' ,
763+ // No installMetadata provided
764+ } ) ;
765+
766+ await expect (
767+ uninstallExtension ( 'https://github.com/google/no-metadata-extension' ) ,
768+ ) . rejects . toThrow ( 'Extension not found.' ) ;
769+ } ) ;
736770 } ) ;
737771
738772 describe ( 'performWorkspaceExtensionMigration' , ( ) => {
0 commit comments