@@ -135,10 +135,19 @@ describe('PluginManager', () => {
135135 metadata : { name : 'test' , version : '1.0.0' } ,
136136 install : jest . fn ( )
137137 } as any ;
138-
138+
139139 await expect ( pluginManager . installPlugin ( plugin ) )
140140 . rejects . toThrow ( 'Plugin must implement uninstall method' ) ;
141141 } ) ;
142+
143+ it ( 'should fail when required dependencies are missing' , async ( ) => {
144+ const plugin = createMockPlugin ( 'dep-plugin' ) ;
145+ plugin . metadata . dependencies = { 'non-existent-package' : '1.0.0' } ;
146+
147+ await expect ( pluginManager . installPlugin ( plugin ) )
148+ . rejects . toThrow ( 'Dependency [email protected] not found' ) ; 149+ expect ( plugin . install ) . not . toHaveBeenCalled ( ) ;
150+ } ) ;
142151 } ) ;
143152
144153 describe ( 'Plugin Uninstallation' , ( ) => {
@@ -159,6 +168,15 @@ describe('PluginManager', () => {
159168 await expect ( pluginManager . uninstallPlugin ( 'inexistent-plugin' ) )
160169 . rejects . toThrow ( 'Plugin inexistent-plugin not found' ) ;
161170 } ) ;
171+
172+ it ( 'should handle errors during plugin uninstallation' , async ( ) => {
173+ const plugin = createMockPlugin ( 'test-plugin' ) ;
174+ plugin . uninstall = jest . fn ( ) . mockRejectedValue ( new Error ( 'Uninstall error' ) ) ;
175+ await pluginManager . installPlugin ( plugin ) ;
176+
177+ await expect ( pluginManager . uninstallPlugin ( 'test-plugin' ) )
178+ . rejects . toThrow ( 'Uninstall error' ) ;
179+ } ) ;
162180 } ) ;
163181
164182 describe ( 'Plugin Enable/Disable' , ( ) => {
@@ -301,6 +319,23 @@ describe('PluginManager', () => {
301319 expect ( results [ 1 ] . success ) . toBe ( true ) ;
302320 expect ( successHook ) . toHaveBeenCalled ( ) ;
303321 } ) ;
322+
323+ it ( 'should remove hooks when plugin is uninstalled' , async ( ) => {
324+ const hook = jest . fn ( ) . mockResolvedValue ( { } ) ;
325+ const plugin = createMockPlugin ( 'test-plugin' ) ;
326+ plugin . getHooks = jest . fn ( ) . mockReturnValue ( {
327+ beforePermissionCheck : hook
328+ } ) ;
329+
330+ await pluginManager . installPlugin ( plugin ) ;
331+ await pluginManager . uninstallPlugin ( 'test-plugin' ) ;
332+
333+ const data : HookData = { role : 'user' , operation : 'read' , params : { } } ;
334+ const results = await pluginManager . executeHooks ( 'beforePermissionCheck' , data ) ;
335+
336+ expect ( results ) . toHaveLength ( 0 ) ;
337+ expect ( hook ) . not . toHaveBeenCalled ( ) ;
338+ } ) ;
304339 } ) ;
305340
306341 describe ( 'Plugin Configuration' , ( ) => {
@@ -360,6 +395,18 @@ describe('PluginManager', () => {
360395 } ) ;
361396 } ) ;
362397
398+ describe ( 'Internal Utilities' , ( ) => {
399+ it ( 'should return null when handler has no associated plugin' , ( ) => {
400+ const result = ( pluginManager as any ) . findPluginByHandler ( ( ) => { } ) ;
401+ expect ( result ) . toBeNull ( ) ;
402+ } ) ;
403+
404+ it ( 'should attempt to load plugins from directory' , async ( ) => {
405+ await expect ( pluginManager . loadPluginsFromDirectory ( '/tmp' ) )
406+ . resolves . not . toThrow ( ) ;
407+ } ) ;
408+ } ) ;
409+
363410 describe ( 'Events' , ( ) => {
364411 it ( 'should emit installation event' , async ( ) => {
365412 const eventSpy = jest . fn ( ) ;
@@ -446,6 +493,13 @@ describe('PluginManager', () => {
446493 } )
447494 } ) ) ;
448495 } ) ;
496+
497+ it ( 'should log plugin system errors' , ( ) => {
498+ const errorSpy = jest . spyOn ( console , 'error' ) . mockImplementation ( ( ) => { } ) ;
499+ ( pluginManager as any ) . registry . events . emit ( 'error' , 'boom' ) ;
500+ expect ( errorSpy ) . toHaveBeenCalledWith ( expect . stringContaining ( 'boom' ) ) ;
501+ errorSpy . mockRestore ( ) ;
502+ } ) ;
449503 } ) ;
450504
451505 describe ( 'Strict Mode' , ( ) => {
0 commit comments