@ -43,6 +43,12 @@ namespace ICSharpCode.AddInManager2.Tests
@@ -43,6 +43,12 @@ namespace ICSharpCode.AddInManager2.Tests
_ addInSetup = new AddInSetup ( _ events , _ nuGet , _ sdAddInManagement ) ;
}
private void ClearAddInNuGetProperties ( AddIn addIn )
{
addIn . Properties . Remove ( ManagedAddIn . NuGetPackageIDManifestAttribute ) ;
addIn . Properties . Remove ( ManagedAddIn . NuGetPackageVersionManifestAttribute ) ;
}
private void CreateAddIns ( )
{
// Create AddIn objects from *.addin files available in this assembly's output directory
@ -51,31 +57,37 @@ namespace ICSharpCode.AddInManager2.Tests
@@ -51,31 +57,37 @@ namespace ICSharpCode.AddInManager2.Tests
using ( StreamReader streamReader = new StreamReader ( @"TestResources\AddInManager2Test.addin" ) )
{
_ addIn1 = AddIn . Load ( _ addInTree , streamReader ) ;
ClearAddInNuGetProperties ( _ addIn1 ) ;
}
using ( StreamReader streamReader = new StreamReader ( @"TestResources\AddInManager2Test_New.addin" ) )
{
_ addIn1_new = AddIn . Load ( _ addInTree , streamReader ) ;
ClearAddInNuGetProperties ( _ addIn1_new ) ;
}
using ( StreamReader streamReader = new StreamReader ( @"TestResources\AddInManager2Test_2.addin" ) )
{
_ addIn2 = AddIn . Load ( _ addInTree , streamReader ) ;
ClearAddInNuGetProperties ( _ addIn2 ) ;
}
using ( StreamReader streamReader = new StreamReader ( @"TestResources\AddInManager2Test_2_New.addin" ) )
{
_ addIn2_new = AddIn . Load ( _ addInTree , streamReader ) ;
ClearAddInNuGetProperties ( _ addIn2_new ) ;
}
using ( StreamReader streamReader = new StreamReader ( @"TestResources\AddInManager2Test_noIdentity.addin" ) )
{
_ addIn_noIdentity = AddIn . Load ( _ addInTree , streamReader ) ;
ClearAddInNuGetProperties ( _ addIn_noIdentity ) ;
}
using ( StreamReader streamReader = new StreamReader ( @"TestResources\AddInManager2Test_noVersion.addin" ) )
{
_ addIn_noVersion = AddIn . Load ( _ addInTree , streamReader ) ;
ClearAddInNuGetProperties ( _ addIn_noVersion ) ;
}
}
@ -702,6 +714,190 @@ namespace ICSharpCode.AddInManager2.Tests
@@ -702,6 +714,190 @@ namespace ICSharpCode.AddInManager2.Tests
Assert . That ( nuGetPackageUninstalled , Is . False , "Downloaded NuGet package should be uninstalled." ) ;
}
[Test, Description("AddIn installed from a NuGet package must be updated from an offline *.sdaddin file. Pending update must be cancellable.")]
public void UpdateAddInFromDownloadedNuGetPackageWithOfflineAddInAndCancel ( )
{
CreateAddIns ( ) ;
// Create fake packages
FakePackage fakePackage = new FakePackage ( )
{
Id = _ addIn1 . Manifest . PrimaryIdentity ,
Version = new SemanticVersion ( _ addIn1 . Version )
} ;
_ addIn1 . Properties [ ManagedAddIn . NuGetPackageIDManifestAttribute ] = _ addIn1 . Manifest . PrimaryIdentity ;
_ addIn1 . Properties [ ManagedAddIn . NuGetPackageVersionManifestAttribute ] = _ addIn1 . Version . ToString ( ) ;
// Prepare all (fake) services needed for AddInSetup and its instance, itself
PrepareAddInSetup ( ) ;
// Prepare event handlers
bool addInInstalledEventReceived = false ;
_ events . AddInInstalled + = delegate ( object sender , AddInInstallationEventArgs e )
{
if ( e . AddIn . Manifest . PrimaryIdentity = = _ addIn1_new . Manifest . PrimaryIdentity )
{
addInInstalledEventReceived = true ;
}
} ;
bool addInUninstalledEventReceived = false ;
_ events . AddInUninstalled + = delegate ( object sender , AddInInstallationEventArgs e )
{
if ( e . AddIn . Manifest . PrimaryIdentity = = _ addIn1_new . Manifest . PrimaryIdentity )
{
addInUninstalledEventReceived = true ;
}
} ;
bool nuGetPackageUninstalled = false ;
_ nuGet . FakeCorePackageManager . UninstallPackageCallback = delegate ( IPackage package , bool forceRemove , bool removeDependencies )
{
if ( ( package = = fakePackage ) & & forceRemove & & ! removeDependencies )
{
nuGetPackageUninstalled = true ;
}
} ;
// This AddIn is already installed
_ sdAddInManagement . RegisteredAddIns . Add ( _ addIn1 ) ;
FakeCorePackageRepository localRepository = new FakeCorePackageRepository ( ) ;
_ nuGet . FakeCorePackageManager . LocalRepository = localRepository ;
localRepository . ReturnedPackages = ( new IPackage [ ] { fakePackage } ) . AsQueryable ( ) ;
// Install the new version of AddIn from manifest
_ sdAddInManagement . AddInToLoad = _ addIn1_new ;
AddIn installedAddIn = _ addInSetup . InstallAddIn ( @"TestResources\AddInManager2Test_New.sdaddin" ) ;
// Test updated AddIn in AddInTree
Assert . That ( installedAddIn , Is . Not . Null , "InstallAddIn() returns valid AddIn object" ) ;
Assert . That ( _ sdAddInManagement . RegisteredAddIns , Contains . Item ( _ addIn1 ) , "Old AddIn object still in AddInTree" ) ;
Assert . That ( _ sdAddInManagement . RegisteredAddIns . Contains ( _ addIn1_new ) , Is . Not . True ,
"New AddIn object not in AddInTree" ) ;
// Look if we find a ManagedAddIn object for the new AddIn
var foundAddIns =
_ addInSetup . AddInsWithMarkedForInstallation . Where ( ma = > ma . AddIn . Manifest . PrimaryIdentity = = _ addIn1 . Manifest . PrimaryIdentity ) ;
Assert . That ( foundAddIns . Any ( ) , "ManagedAddIn found in AddInsWithMarkedForInstallation" ) ;
var foundAddIn = foundAddIns . First ( ) ;
Assert . That ( foundAddIn . AddIn . Version , Is . EqualTo ( _ addIn1_new . Version ) , "ManagedAddIn must have new version" ) ;
Assert . That ( foundAddIn . OldVersion , Is . EqualTo ( _ addIn1 . Version ) , "ManagedAddIn must know installed (old) version" ) ;
Assert . That ( foundAddIn . IsTemporary , Is . True , "ManagedAddIn is temporary" ) ;
Assert . That ( foundAddIn . IsUpdate , Is . True , "ManagedAddIn is an update" ) ;
Assert . That ( foundAddIn . InstallationSource , Is . EqualTo ( AddInInstallationSource . Offline ) , "ManagedAddIn's installation source is 'offline'" ) ;
Assert . That ( addInInstalledEventReceived , "AddInInstalled event sent with correct AddIn" ) ;
// Cancel the update
_ sdAddInManagement . TempInstallDirectory = "" ;
_ sdAddInManagement . UserInstallDirectory = "" ;
_ addInSetup . CancelUpdate ( _ addIn1_new ) ;
// Now check AddInTree, again
foundAddIns =
_ addInSetup . AddInsWithMarkedForInstallation . Where ( ma = > ma . AddIn . Manifest . PrimaryIdentity = = _ addIn1 . Manifest . PrimaryIdentity ) ;
Assert . That ( foundAddIns . Any ( ) , "ManagedAddIn still found in AddInsWithMarkedForInstallation after cancel" ) ;
foundAddIn = foundAddIns . First ( ) ;
Assert . That ( foundAddIn . AddIn . Version , Is . EqualTo ( _ addIn1 . Version ) , "ManagedAddIn now has old version" ) ;
Assert . That ( addInUninstalledEventReceived , "AddInUninstalled event sent with correct AddIn" ) ;
Assert . That ( nuGetPackageUninstalled , Is . False , "Already installed NuGet package must not be removed." ) ;
}
[Test, Description("AddIn installed from a NuGet package must be updated from an offline *.sdaddin file with an older version. Pending update must be cancellable.")]
public void UpdateAddInFromDownloadedNuGetPackageWithOlderOfflineAddInAndCancel ( )
{
CreateAddIns ( ) ;
// Create fake packages
FakePackage fakePackage = new FakePackage ( )
{
Id = _ addIn1_new . Manifest . PrimaryIdentity ,
Version = new SemanticVersion ( _ addIn1_new . Version )
} ;
_ addIn1_new . Properties [ ManagedAddIn . NuGetPackageIDManifestAttribute ] = _ addIn1_new . Manifest . PrimaryIdentity ;
_ addIn1_new . Properties [ ManagedAddIn . NuGetPackageVersionManifestAttribute ] = _ addIn1_new . Version . ToString ( ) ;
// Prepare all (fake) services needed for AddInSetup and its instance, itself
PrepareAddInSetup ( ) ;
// Prepare event handlers
bool addInInstalledEventReceived = false ;
_ events . AddInInstalled + = delegate ( object sender , AddInInstallationEventArgs e )
{
if ( e . AddIn . Manifest . PrimaryIdentity = = _ addIn1_new . Manifest . PrimaryIdentity )
{
addInInstalledEventReceived = true ;
}
} ;
bool addInUninstalledEventReceived = false ;
_ events . AddInUninstalled + = delegate ( object sender , AddInInstallationEventArgs e )
{
if ( e . AddIn . Manifest . PrimaryIdentity = = _ addIn1_new . Manifest . PrimaryIdentity )
{
addInUninstalledEventReceived = true ;
}
} ;
bool nuGetPackageUninstalled = false ;
_ nuGet . FakeCorePackageManager . UninstallPackageCallback = delegate ( IPackage package , bool forceRemove , bool removeDependencies )
{
if ( ( package = = fakePackage ) & & forceRemove & & ! removeDependencies )
{
nuGetPackageUninstalled = true ;
}
} ;
// This AddIn is already installed
_ sdAddInManagement . RegisteredAddIns . Add ( _ addIn1_new ) ;
FakeCorePackageRepository localRepository = new FakeCorePackageRepository ( ) ;
_ nuGet . FakeCorePackageManager . LocalRepository = localRepository ;
localRepository . ReturnedPackages = ( new IPackage [ ] { fakePackage } ) . AsQueryable ( ) ;
// Install the new version of AddIn from manifest
_ sdAddInManagement . AddInToLoad = _ addIn1 ;
AddIn installedAddIn = _ addInSetup . InstallAddIn ( @"TestResources\AddInManager2Test.sdaddin" ) ;
// Test updated AddIn in AddInTree
Assert . That ( installedAddIn , Is . Not . Null , "InstallAddIn() returns valid AddIn object" ) ;
Assert . That ( _ sdAddInManagement . RegisteredAddIns , Contains . Item ( _ addIn1_new ) , "Old AddIn object still in AddInTree" ) ;
Assert . That ( _ sdAddInManagement . RegisteredAddIns . Contains ( _ addIn1 ) , Is . Not . True ,
"New AddIn object not in AddInTree" ) ;
// Look if we find a ManagedAddIn object for the new AddIn
var foundAddIns =
_ addInSetup . AddInsWithMarkedForInstallation . Where ( ma = > ma . AddIn . Manifest . PrimaryIdentity = = _ addIn1_new . Manifest . PrimaryIdentity ) ;
Assert . That ( foundAddIns . Any ( ) , "ManagedAddIn found in AddInsWithMarkedForInstallation" ) ;
var foundAddIn = foundAddIns . First ( ) ;
Assert . That ( foundAddIn . AddIn . Version , Is . EqualTo ( _ addIn1 . Version ) , "ManagedAddIn must have new version" ) ;
Assert . That ( foundAddIn . OldVersion , Is . EqualTo ( _ addIn1_new . Version ) , "ManagedAddIn must know installed (old) version" ) ;
Assert . That ( foundAddIn . IsTemporary , Is . True , "ManagedAddIn is temporary" ) ;
Assert . That ( foundAddIn . IsUpdate , Is . True , "ManagedAddIn is an update" ) ;
Assert . That ( foundAddIn . InstallationSource , Is . EqualTo ( AddInInstallationSource . Offline ) , "ManagedAddIn's installation source is 'offline'" ) ;
Assert . That ( addInInstalledEventReceived , "AddInInstalled event sent with correct AddIn" ) ;
// Cancel the update
_ sdAddInManagement . TempInstallDirectory = "" ;
_ sdAddInManagement . UserInstallDirectory = "" ;
_ addInSetup . CancelUpdate ( _ addIn1 ) ;
// Now check AddInTree, again
foundAddIns =
_ addInSetup . AddInsWithMarkedForInstallation . Where ( ma = > ma . AddIn . Manifest . PrimaryIdentity = = _ addIn1_new . Manifest . PrimaryIdentity ) ;
Assert . That ( foundAddIns . Any ( ) , "ManagedAddIn still found in AddInsWithMarkedForInstallation after cancel" ) ;
foundAddIn = foundAddIns . First ( ) ;
Assert . That ( foundAddIn . AddIn . Version , Is . EqualTo ( _ addIn1_new . Version ) , "ManagedAddIn now has old version" ) ;
Assert . That ( addInUninstalledEventReceived , "AddInUninstalled event sent with correct AddIn" ) ;
Assert . That ( nuGetPackageUninstalled , Is . False , "Already installed NuGet package must not be removed." ) ;
}
[Test, Description("External AddIn must be uninstalled. Pending uninstallation must be cancellable.")]
public void UninstallValidAddInFromManifestAndCancel ( )
{
@ -795,5 +991,118 @@ namespace ICSharpCode.AddInManager2.Tests
@@ -795,5 +991,118 @@ namespace ICSharpCode.AddInManager2.Tests
Assert . That ( nuGetPackageUninstalled , Is . True , "NuGet package must be removed after restart." ) ;
}
[Test]
public void RemoveUnreferencedNuGetPackage ( )
{
CreateAddIns ( ) ;
// Create a fake package
FakePackage fakePackage1 = new FakePackage ( )
{
Id = _ addIn1 . Manifest . PrimaryIdentity ,
Version = new SemanticVersion ( _ addIn1 . Version )
} ;
_ addIn1 . Properties . Set ( ManagedAddIn . NuGetPackageIDManifestAttribute , fakePackage1 . Id ) ;
_ addIn1 . Properties . Set ( ManagedAddIn . NuGetPackageVersionManifestAttribute , fakePackage1 . Version . ToString ( ) ) ;
FakePackage fakePackage1_new = new FakePackage ( )
{
Id = _ addIn1_new . Manifest . PrimaryIdentity ,
Version = new SemanticVersion ( _ addIn1_new . Version )
} ;
_ addIn1_new . Properties . Set ( ManagedAddIn . NuGetPackageIDManifestAttribute , fakePackage1_new . Id ) ;
_ addIn1_new . Properties . Set ( ManagedAddIn . NuGetPackageVersionManifestAttribute , fakePackage1_new . Version . ToString ( ) ) ;
FakePackage fakePackage2 = new FakePackage ( )
{
Id = _ addIn2 . Manifest . PrimaryIdentity ,
Version = new SemanticVersion ( _ addIn2 . Version )
} ;
_ addIn2 . Properties . Set ( ManagedAddIn . NuGetPackageIDManifestAttribute , fakePackage2 . Id ) ;
_ addIn2 . Properties . Set ( ManagedAddIn . NuGetPackageVersionManifestAttribute , fakePackage2 . Version . ToString ( ) ) ;
// Prepare all (fake) services needed for AddInSetup and its instance, itself
PrepareAddInSetup ( ) ;
// Simulate an installed AddIn, which is not related to installed NuGet package
_ sdAddInManagement . TempInstallDirectory = "" ;
_ sdAddInManagement . UserInstallDirectory = "" ;
// Simulate the installed NuGet package in local repository
FakeCorePackageRepository localRepository = new FakeCorePackageRepository ( ) ;
_ nuGet . FakeCorePackageManager . LocalRepository = localRepository ;
bool nuGetPackageUninstalled = false ;
IPackage packageForUninstallEvent = null ;
_ nuGet . FakeCorePackageManager . UninstallPackageCallback = delegate ( IPackage package , bool forceRemove , bool removeDependencies )
{
if ( ( package = = packageForUninstallEvent ) & & forceRemove & & ! removeDependencies )
{
nuGetPackageUninstalled = true ;
}
} ;
// Case 1: AddIn of local NuGet package is completely same as installed
nuGetPackageUninstalled = false ;
localRepository . ReturnedPackages = ( new IPackage [ ] { fakePackage1 } ) . AsQueryable ( ) ;
packageForUninstallEvent = fakePackage1 ;
_ sdAddInManagement . RegisteredAddIns . Clear ( ) ;
_ sdAddInManagement . RegisteredAddIns . Add ( _ addIn1 ) ;
_ addInSetup . RemoveUnreferencedNuGetPackages ( ) ;
Assert . That ( nuGetPackageUninstalled , Is . False , "fakePackage1 must not be removed, because identical to installed." ) ;
// Case 2: AddIn of local NuGet package not installed at all
nuGetPackageUninstalled = false ;
localRepository . ReturnedPackages = ( new IPackage [ ] { fakePackage1 } ) . AsQueryable ( ) ;
packageForUninstallEvent = fakePackage1 ;
_ sdAddInManagement . RegisteredAddIns . Clear ( ) ;
_ sdAddInManagement . RegisteredAddIns . Add ( _ addIn2 ) ;
_ addInSetup . RemoveUnreferencedNuGetPackages ( ) ;
Assert . That ( nuGetPackageUninstalled , Is . True , "fakePackage1 must be removed, because unreferenced." ) ;
// Case 3a: AddIn of local NuGet package is older than the one installed
nuGetPackageUninstalled = false ;
localRepository . ReturnedPackages = ( new IPackage [ ] { fakePackage1 } ) . AsQueryable ( ) ;
packageForUninstallEvent = fakePackage1 ;
_ sdAddInManagement . RegisteredAddIns . Clear ( ) ;
_ sdAddInManagement . RegisteredAddIns . Add ( _ addIn1_new ) ;
_ addInSetup . RemoveUnreferencedNuGetPackages ( ) ;
Assert . That ( nuGetPackageUninstalled , Is . False , "fakePackage1 must not be removed, because older but the only one." ) ;
// Case 3b: There exists a local NuGet package identical to installed AddIn and an older one
nuGetPackageUninstalled = false ;
localRepository . ReturnedPackages = ( new IPackage [ ] { fakePackage1 , fakePackage1_new } ) . AsQueryable ( ) ;
packageForUninstallEvent = fakePackage1 ;
_ sdAddInManagement . RegisteredAddIns . Clear ( ) ;
_ sdAddInManagement . RegisteredAddIns . Add ( _ addIn1_new ) ;
_ addInSetup . RemoveUnreferencedNuGetPackages ( ) ;
Assert . That ( nuGetPackageUninstalled , Is . True , "fakePackage1 must be removed, because older and a better fitting package exists." ) ;
// Case 4a: AddIn of local NuGet package is newer than the one installed
nuGetPackageUninstalled = false ;
localRepository . ReturnedPackages = ( new IPackage [ ] { fakePackage1_new } ) . AsQueryable ( ) ;
packageForUninstallEvent = fakePackage1_new ;
_ sdAddInManagement . RegisteredAddIns . Clear ( ) ;
_ sdAddInManagement . RegisteredAddIns . Add ( _ addIn1 ) ;
_ addInSetup . RemoveUnreferencedNuGetPackages ( ) ;
Assert . That ( nuGetPackageUninstalled , Is . False , "fakePackage1_new must not be removed, because newer but the only one." ) ;
// Case 4b: There exists a local NuGet package identical to installed AddIn and a newer one
nuGetPackageUninstalled = false ;
localRepository . ReturnedPackages = ( new IPackage [ ] { fakePackage1 , fakePackage1_new } ) . AsQueryable ( ) ;
packageForUninstallEvent = fakePackage1_new ;
_ sdAddInManagement . RegisteredAddIns . Clear ( ) ;
_ sdAddInManagement . RegisteredAddIns . Add ( _ addIn1 ) ;
_ addInSetup . RemoveUnreferencedNuGetPackages ( ) ;
Assert . That ( nuGetPackageUninstalled , Is . True , "fakePackage1_new must be removed, because newer and a better fitting package exists." ) ;
// Case 5: Installed AddIn has no NuGet version tag in manifest, and there are two versions of local NuGet packages
nuGetPackageUninstalled = false ;
_ addIn1 . Properties . Remove ( ManagedAddIn . NuGetPackageVersionManifestAttribute ) ;
localRepository . ReturnedPackages = ( new IPackage [ ] { fakePackage1 , fakePackage1_new } ) . AsQueryable ( ) ;
packageForUninstallEvent = fakePackage1 ;
_ sdAddInManagement . RegisteredAddIns . Clear ( ) ;
_ sdAddInManagement . RegisteredAddIns . Add ( _ addIn1 ) ;
_ addInSetup . RemoveUnreferencedNuGetPackages ( ) ;
Assert . That ( nuGetPackageUninstalled , Is . True , "fakePackage1 must be removed, only the latest package is left for AddIn without version info." ) ;
}
}
}