@@ -443,6 +443,105 @@ func TestNewManager_InternalApplicationManagement(t *testing.T) {
443443 }
444444}
445445
446+ func TestNewManager_MessengerAddedAfterInit_createsApplication (t * testing.T ) {
447+ db := testdb .NewDBWithDefaultUser (t )
448+
449+ // Simulate a plugin conf that was created on a previous startup when the
450+ // plugin did not yet implement the Messenger interface: it has no
451+ // associated internal application (ApplicationID == 0).
452+ assert .NoError (t , db .CreatePluginConf (& model.PluginConf {
453+ UserID : 1 ,
454+ ModulePath : mock .ModulePath ,
455+ Enabled : true ,
456+ Token : auth .GeneratePluginToken (),
457+ }))
458+
459+ manager , err := NewManager (db , "" , nil , nil )
460+ assert .Nil (t , err )
461+ assert .Nil (t , manager .LoadPlugin (new (mock.Plugin )))
462+ // The mock plugin supports Messenger, so re-initializing must back-fill the
463+ // missing internal application instead of leaving ApplicationID at 0.
464+ assert .Nil (t , manager .InitializeForUserID (1 ))
465+
466+ conf , err := db .GetPluginConfByUserAndPath (1 , mock .ModulePath )
467+ assert .NoError (t , err )
468+ if assert .NotNil (t , conf ) {
469+ assert .NotZero (t , conf .ApplicationID , "an internal application should have been created for the messenger plugin" )
470+
471+ app , err := db .GetApplicationByID (conf .ApplicationID )
472+ assert .NoError (t , err )
473+ if assert .NotNil (t , app ) {
474+ assert .True (t , app .Internal )
475+ assert .Equal (t , uint (1 ), app .UserID )
476+ }
477+ }
478+ }
479+
480+ // failingDB wraps a real test database so that individual operations can be
481+ // forced to fail, allowing the error branches around internal-application
482+ // creation to be exercised.
483+ type failingDB struct {
484+ * testdb.Database
485+ failCreateApplication error
486+ failUpdatePluginConf error
487+ }
488+
489+ func (d * failingDB ) CreateApplication (app * model.Application ) error {
490+ if d .failCreateApplication != nil {
491+ return d .failCreateApplication
492+ }
493+ return d .Database .CreateApplication (app )
494+ }
495+
496+ func (d * failingDB ) UpdatePluginConf (conf * model.PluginConf ) error {
497+ if d .failUpdatePluginConf != nil {
498+ return d .failUpdatePluginConf
499+ }
500+ return d .Database .UpdatePluginConf (conf )
501+ }
502+
503+ func seedMessengerConfWithoutApplication (t * testing.T , db Database ) {
504+ t .Helper ()
505+ assert .NoError (t , db .CreatePluginConf (& model.PluginConf {
506+ UserID : 1 ,
507+ ModulePath : mock .ModulePath ,
508+ Enabled : true ,
509+ Token : auth .GeneratePluginToken (),
510+ }))
511+ }
512+
513+ func TestNewManager_MessengerAddedAfterInit_createApplicationError (t * testing.T ) {
514+ db := & failingDB {
515+ Database : testdb .NewDBWithDefaultUser (t ),
516+ failCreateApplication : errors .New ("create application failed" ),
517+ }
518+ seedMessengerConfWithoutApplication (t , db )
519+
520+ manager , err := NewManager (db , "" , nil , nil )
521+ assert .Nil (t , err )
522+ assert .Nil (t , manager .LoadPlugin (new (mock.Plugin )))
523+
524+ // Back-filling the missing internal application must surface the database
525+ // error instead of silently continuing with ApplicationID == 0.
526+ assert .EqualError (t , manager .InitializeForUserID (1 ), "create application failed" )
527+ }
528+
529+ func TestNewManager_MessengerAddedAfterInit_updatePluginConfError (t * testing.T ) {
530+ db := & failingDB {
531+ Database : testdb .NewDBWithDefaultUser (t ),
532+ failUpdatePluginConf : errors .New ("update plugin conf failed" ),
533+ }
534+ seedMessengerConfWithoutApplication (t , db )
535+
536+ manager , err := NewManager (db , "" , nil , nil )
537+ assert .Nil (t , err )
538+ assert .Nil (t , manager .LoadPlugin (new (mock.Plugin )))
539+
540+ // Persisting the back-filled ApplicationID may fail; that error must be
541+ // propagated as well.
542+ assert .EqualError (t , manager .InitializeForUserID (1 ), "update plugin conf failed" )
543+ }
544+
446545func TestPluginFileLoadError (t * testing.T ) {
447546 err := pluginFileLoadError {Filename : "test.so" , UnderlyingError : errors .New ("test error" )}
448547 assert .Error (t , err )
0 commit comments