Root folder improvements

Fixed: Prevent non-writeable root folder from being added
Fixed: Errors getting free space/subfolders for root folder won't prevent the UI from loading
This commit is contained in:
Mark McDowall 2015-02-09 16:42:26 -08:00
parent d3c1deb203
commit 573c2b8f60
2 changed files with 53 additions and 7 deletions

View File

@ -4,6 +4,7 @@ using System.IO;
using Moq; using Moq;
using NUnit.Framework; using NUnit.Framework;
using NzbDrone.Common.Disk; using NzbDrone.Common.Disk;
using NzbDrone.Core.Configuration;
using NzbDrone.Core.RootFolders; using NzbDrone.Core.RootFolders;
using NzbDrone.Core.Test.Framework; using NzbDrone.Core.Test.Framework;
using NzbDrone.Test.Common; using NzbDrone.Test.Common;
@ -21,6 +22,10 @@ namespace NzbDrone.Core.Test.RootFolderTests
.Setup(m => m.FolderExists(It.IsAny<string>())) .Setup(m => m.FolderExists(It.IsAny<string>()))
.Returns(true); .Returns(true);
Mocker.GetMock<IDiskProvider>()
.Setup(m => m.FolderWritable(It.IsAny<string>()))
.Returns(true);
Mocker.GetMock<IRootFolderRepository>() Mocker.GetMock<IRootFolderRepository>()
.Setup(s => s.All()) .Setup(s => s.All())
.Returns(new List<RootFolder>()); .Returns(new List<RootFolder>());
@ -77,6 +82,26 @@ namespace NzbDrone.Core.Test.RootFolderTests
Assert.Throws<InvalidOperationException>(() => Subject.Add(new RootFolder { Path = @"C:\TV".AsOsAgnostic() })); Assert.Throws<InvalidOperationException>(() => Subject.Add(new RootFolder { Path = @"C:\TV".AsOsAgnostic() }));
} }
[Test]
public void should_throw_when_adding_not_writable_folder()
{
Mocker.GetMock<IDiskProvider>()
.Setup(m => m.FolderWritable(It.IsAny<string>()))
.Returns(false);
Assert.Throws<UnauthorizedAccessException>(() => Subject.Add(new RootFolder { Path = @"C:\TV".AsOsAgnostic() }));
}
[Test]
public void should_throw_when_same_path_as_drone_factory()
{
var path = @"C:\TV".AsOsAgnostic();
Mocker.GetMock<IConfigService>()
.SetupGet(s => s.DownloadedEpisodesFolder)
.Returns(path);
Assert.Throws<InvalidOperationException>(() => Subject.Add(new RootFolder { Path = path }));
}
} }
} }

View File

@ -6,7 +6,6 @@ using NLog;
using NzbDrone.Common; using NzbDrone.Common;
using NzbDrone.Common.Disk; using NzbDrone.Common.Disk;
using NzbDrone.Common.Extensions; using NzbDrone.Common.Extensions;
using NzbDrone.Common.Instrumentation;
using NzbDrone.Core.Configuration; using NzbDrone.Core.Configuration;
using NzbDrone.Core.Tv; using NzbDrone.Core.Tv;
@ -67,12 +66,22 @@ namespace NzbDrone.Core.RootFolders
var rootFolders = _rootFolderRepository.All().ToList(); var rootFolders = _rootFolderRepository.All().ToList();
rootFolders.ForEach(folder => rootFolders.ForEach(folder =>
{
try
{ {
if (folder.Path.IsPathValid() && _diskProvider.FolderExists(folder.Path)) if (folder.Path.IsPathValid() && _diskProvider.FolderExists(folder.Path))
{ {
folder.FreeSpace = _diskProvider.GetAvailableSpace(folder.Path); folder.FreeSpace = _diskProvider.GetAvailableSpace(folder.Path);
folder.UnmappedFolders = GetUnmappedFolders(folder.Path); folder.UnmappedFolders = GetUnmappedFolders(folder.Path);
} }
}
//We don't want an exception to prevent the root folders from loading in the UI, so they can still be deleted
catch (Exception ex)
{
_logger.ErrorException("Unable to get free space and unmapped folders for root folder: " + folder.Path, ex);
folder.FreeSpace = 0;
folder.UnmappedFolders = new List<UnmappedFolder>();
}
}); });
return rootFolders; return rootFolders;
@ -83,17 +92,29 @@ namespace NzbDrone.Core.RootFolders
var all = All(); var all = All();
if (String.IsNullOrWhiteSpace(rootFolder.Path) || !Path.IsPathRooted(rootFolder.Path)) if (String.IsNullOrWhiteSpace(rootFolder.Path) || !Path.IsPathRooted(rootFolder.Path))
{
throw new ArgumentException("Invalid path"); throw new ArgumentException("Invalid path");
}
if (!_diskProvider.FolderExists(rootFolder.Path)) if (!_diskProvider.FolderExists(rootFolder.Path))
{
throw new DirectoryNotFoundException("Can't add root directory that doesn't exist."); throw new DirectoryNotFoundException("Can't add root directory that doesn't exist.");
}
if (all.Exists(r => r.Path.PathEquals(rootFolder.Path))) if (all.Exists(r => r.Path.PathEquals(rootFolder.Path)))
{
throw new InvalidOperationException("Recent directory already exists."); throw new InvalidOperationException("Recent directory already exists.");
}
if (!String.IsNullOrWhiteSpace(_configService.DownloadedEpisodesFolder) && if (_configService.DownloadedEpisodesFolder.IsNotNullOrWhiteSpace() && _configService.DownloadedEpisodesFolder.PathEquals(rootFolder.Path))
_configService.DownloadedEpisodesFolder.PathEquals(rootFolder.Path)) {
throw new InvalidOperationException("Drone Factory folder cannot be used."); throw new InvalidOperationException("Drone Factory folder cannot be used.");
}
if (!_diskProvider.FolderWritable(rootFolder.Path))
{
throw new UnauthorizedAccessException(String.Format("Root folder path '{0}' is not writable by user '{1}'", rootFolder.Path, Environment.UserName));
}
_rootFolderRepository.Insert(rootFolder); _rootFolderRepository.Insert(rootFolder);