mirror of
https://github.com/cyanfish/naps2.git
synced 2024-09-11 15:26:55 +03:00
Add a couple DesktopController tests
Many more to add as we've set up the outline
This commit is contained in:
parent
c77f5b30f9
commit
7544aff995
@ -38,7 +38,7 @@ public static class InternalDefaults
|
||||
HasCheckedForUpdates = false,
|
||||
LastUpdateCheckDate = DateTime.MinValue,
|
||||
HasBeenRun = false,
|
||||
FirstRunDate = DateTime.MinValue,
|
||||
FirstRunDate = null,
|
||||
HasBeenPromptedForDonation = false,
|
||||
LastDonatePromptDate = DateTime.MinValue,
|
||||
DeleteAfterSaving = false,
|
||||
|
@ -61,8 +61,9 @@ public class ThumbnailRenderQueue : IDisposable
|
||||
private void RenderThumbnails()
|
||||
{
|
||||
// TODO: Make this run as async?
|
||||
// TODO: Verify WorkerFactory is not null? Or handle this better for tests?
|
||||
bool useWorker = PlatformCompat.Runtime.UseWorker;
|
||||
var worker = useWorker ? _scanningContext.WorkerFactory.Create() : null;
|
||||
var worker = useWorker ? _scanningContext.WorkerFactory?.Create() : null;
|
||||
var fallback = new ExpFallback(100, 60 * 1000);
|
||||
while (true)
|
||||
{
|
||||
|
@ -1,40 +0,0 @@
|
||||
using NAPS2.Config.Model;
|
||||
using NAPS2.Sdk.Tests;
|
||||
using Xunit;
|
||||
|
||||
namespace NAPS2.Lib.Tests.Config;
|
||||
|
||||
public class InternalDefaultsTests
|
||||
{
|
||||
[Fact]
|
||||
public void NotNullProps()
|
||||
{
|
||||
var config = InternalDefaults.GetCommonConfig();
|
||||
AssertPropNullOrNotNull(config, false, "");
|
||||
}
|
||||
|
||||
private static void AssertPropNullOrNotNull(object config, bool shouldBeNull, string path)
|
||||
{
|
||||
Assert.True(config != null, path);
|
||||
foreach (var prop in config.GetType().GetProperties())
|
||||
{
|
||||
var value = prop.GetValue(config);
|
||||
if (ConfigLookup.HasConfigAttribute(prop))
|
||||
{
|
||||
// Child, so recurse
|
||||
AssertPropNullOrNotNull(value, shouldBeNull, $"{path}{prop.Name}.");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (shouldBeNull)
|
||||
{
|
||||
Assert.True(value == null, $"{prop.DeclaringType?.Name}.{prop.Name} == null");
|
||||
}
|
||||
else
|
||||
{
|
||||
Assert.True(value != null, $"{prop.DeclaringType?.Name}.{prop.Name} != null");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
107
NAPS2.Lib.Tests/WinForms/DesktopControllerTests.cs
Normal file
107
NAPS2.Lib.Tests/WinForms/DesktopControllerTests.cs
Normal file
@ -0,0 +1,107 @@
|
||||
using Moq;
|
||||
using NAPS2.ImportExport.Images;
|
||||
using NAPS2.Platform.Windows;
|
||||
using NAPS2.Recovery;
|
||||
using NAPS2.Update;
|
||||
using NAPS2.WinForms;
|
||||
using Xunit;
|
||||
|
||||
namespace NAPS2.Sdk.Tests.WinForms;
|
||||
|
||||
public class DesktopControllerTests : ContextualTexts
|
||||
{
|
||||
// TODO: We should create individual unit tests for everything that's mocked here.
|
||||
// TODO: We should also make some things more testable:
|
||||
// - Change DesktopFormProvider to e.g. DesktopFormActivator or something else with a mockable interface
|
||||
private readonly DesktopController _desktopController;
|
||||
private readonly UiImageList _imageList;
|
||||
private readonly RecoveryStorageManager _recoveryStorageManager;
|
||||
private readonly ThumbnailRenderQueue _thumbnailRenderQueue;
|
||||
private readonly Mock<OperationProgress> _operationProgress;
|
||||
private readonly Naps2Config _config;
|
||||
private readonly Mock<IOperationFactory> _operationFactory;
|
||||
private readonly Mock<StillImage> _stillImage;
|
||||
private readonly Mock<IUpdateChecker> _updateChecker;
|
||||
private readonly Mock<INotificationManager> _notifcationManager;
|
||||
private readonly ImageTransfer _imageTransfer;
|
||||
private readonly ImageClipboard _imageClipboard;
|
||||
private readonly Mock<IWinFormsExportHelper> _exportHelper;
|
||||
private readonly DesktopImagesController _desktopImagesController;
|
||||
private readonly Mock<IDesktopScanController> _desktopScanController;
|
||||
private readonly DesktopFormProvider _desktopFormProvider;
|
||||
|
||||
public DesktopControllerTests()
|
||||
{
|
||||
ScanningContext.RecoveryPath = Path.Combine(FolderPath, "recovery");
|
||||
ScanningContext.FileStorageManager = new FileStorageManager(ScanningContext.RecoveryPath);
|
||||
_recoveryStorageManager = RecoveryStorageManager.CreateFolder(ScanningContext.RecoveryPath);
|
||||
_imageList = new UiImageList(_recoveryStorageManager);
|
||||
_thumbnailRenderQueue = new ThumbnailRenderQueue(ScanningContext, new ThumbnailRenderer(ImageContext));
|
||||
_operationProgress = new Mock<OperationProgress>();
|
||||
_config = Naps2Config.Stub();
|
||||
_operationFactory = new Mock<IOperationFactory>();
|
||||
_stillImage = new Mock<StillImage>();
|
||||
_updateChecker = new Mock<IUpdateChecker>();
|
||||
_notifcationManager = new Mock<INotificationManager>();
|
||||
_imageTransfer = new ImageTransfer(ImageContext);
|
||||
_imageClipboard = new ImageClipboard(ImageContext, _imageTransfer);
|
||||
_exportHelper = new Mock<IWinFormsExportHelper>();
|
||||
_desktopImagesController = new DesktopImagesController(_imageList);
|
||||
_desktopScanController = new Mock<IDesktopScanController>();
|
||||
_desktopFormProvider = new DesktopFormProvider();
|
||||
_desktopController = new DesktopController(
|
||||
ScanningContext,
|
||||
_imageList,
|
||||
_recoveryStorageManager,
|
||||
_thumbnailRenderQueue,
|
||||
_operationProgress.Object,
|
||||
_config,
|
||||
_operationFactory.Object,
|
||||
_stillImage.Object,
|
||||
_updateChecker.Object,
|
||||
_notifcationManager.Object,
|
||||
_imageTransfer,
|
||||
_imageClipboard,
|
||||
new ImageListActions(ImageContext, _imageList),
|
||||
_exportHelper.Object,
|
||||
_desktopImagesController,
|
||||
_desktopScanController.Object,
|
||||
_desktopFormProvider
|
||||
);
|
||||
|
||||
_operationFactory.Setup(x => x.Create<RecoveryOperation>()).Returns(
|
||||
new RecoveryOperation(new Mock<IFormFactory>().Object, new RecoveryManager(ScanningContext)));
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
base.Dispose();
|
||||
_desktopController.Cleanup();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Initialize_SetsFirstRunDate_IfNotRunBefore()
|
||||
{
|
||||
Assert.False(_config.Get(c => c.HasBeenRun));
|
||||
Assert.Null(_config.Get(c => c.FirstRunDate));
|
||||
|
||||
await _desktopController.Initialize();
|
||||
|
||||
Assert.True(_config.Get(c => c.HasBeenRun));
|
||||
Assert.InRange(_config.Get(c => c.FirstRunDate) ?? DateTime.MinValue,
|
||||
DateTime.Now - TimeSpan.FromMilliseconds(10), DateTime.Now);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Initialize_DoesntSetFirstRunDate_IfAlreadyRun()
|
||||
{
|
||||
var firstRunDate = DateTime.Now - TimeSpan.FromDays(1);
|
||||
_config.User.Set(c => c.HasBeenRun, true);
|
||||
_config.User.Set(c => c.FirstRunDate, firstRunDate);
|
||||
|
||||
await _desktopController.Initialize();
|
||||
|
||||
Assert.True(_config.Get(c => c.HasBeenRun));
|
||||
Assert.Equal(firstRunDate, _config.Get(c => c.FirstRunDate));
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ using NAPS2.ImportExport;
|
||||
using NAPS2.ImportExport.Pdf;
|
||||
using NAPS2.Scan;
|
||||
using NAPS2.Scan.Batch;
|
||||
using NAPS2.Update;
|
||||
using NAPS2.WinForms;
|
||||
using Ninject;
|
||||
using Ninject.Modules;
|
||||
@ -23,10 +24,13 @@ public class WinFormsModule : NinjectModule
|
||||
Bind<IComponentInstallPrompt>().To<WinFormsComponentInstallPrompt>();
|
||||
Bind<DialogHelper>().To<WinFormsDialogHelper>();
|
||||
Bind<IEtoPlatform>().To<WinFormsEtoPlatform>();
|
||||
Bind<NotificationManager>().ToSelf().InSingletonScope();
|
||||
Bind<ISaveNotify>().ToMethod(ctx => ctx.Kernel.Get<NotificationManager>());
|
||||
Bind<INotificationManager>().To<NotificationManager>().InSingletonScope();
|
||||
Bind<ISaveNotify>().ToMethod(ctx => ctx.Kernel.Get<INotificationManager>());
|
||||
Bind<IScannedImagePrinter>().To<PrintDocumentPrinter>();
|
||||
Bind<IDevicePrompt>().To<WinFormsDevicePrompt>();
|
||||
Bind<DesktopController>().ToSelf().InSingletonScope();
|
||||
Bind<IUpdateChecker>().To<UpdateChecker>();
|
||||
Bind<IWinFormsExportHelper>().To<WinFormsExportHelper>();
|
||||
Bind<IDesktopScanController>().To<DesktopScanController>();
|
||||
}
|
||||
}
|
8
NAPS2.Lib.WinForms/Update/IUpdateChecker.cs
Normal file
8
NAPS2.Lib.WinForms/Update/IUpdateChecker.cs
Normal file
@ -0,0 +1,8 @@
|
||||
namespace NAPS2.Update;
|
||||
|
||||
public interface IUpdateChecker
|
||||
{
|
||||
TimeSpan CheckInterval { get; }
|
||||
Task<UpdateInfo> CheckForUpdates();
|
||||
UpdateOperation StartUpdate(UpdateInfo update);
|
||||
}
|
@ -4,7 +4,7 @@ using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace NAPS2.Update;
|
||||
|
||||
public class UpdateChecker
|
||||
public class UpdateChecker : IUpdateChecker
|
||||
{
|
||||
private const string UPDATE_CHECK_ENDPOINT = "https://www.naps2.com/api/v1/update";
|
||||
#if STANDALONE
|
||||
|
@ -26,14 +26,14 @@ public class DesktopController
|
||||
private readonly Naps2Config _config;
|
||||
private readonly IOperationFactory _operationFactory;
|
||||
private readonly StillImage _stillImage;
|
||||
private readonly UpdateChecker _updateChecker;
|
||||
private readonly NotificationManager _notify;
|
||||
private readonly IUpdateChecker _updateChecker;
|
||||
private readonly INotificationManager _notify;
|
||||
private readonly ImageTransfer _imageTransfer;
|
||||
private readonly ImageClipboard _imageClipboard;
|
||||
private readonly ImageListActions _imageListActions;
|
||||
private readonly WinFormsExportHelper _exportHelper;
|
||||
private readonly IWinFormsExportHelper _exportHelper;
|
||||
private readonly DesktopImagesController _desktopImagesController;
|
||||
private readonly DesktopScanController _desktopScanController;
|
||||
private readonly IDesktopScanController _desktopScanController;
|
||||
private readonly DesktopFormProvider _desktopFormProvider;
|
||||
|
||||
private bool _closed;
|
||||
@ -42,9 +42,9 @@ public class DesktopController
|
||||
RecoveryStorageManager recoveryStorageManager, ThumbnailRenderQueue thumbnailRenderQueue,
|
||||
OperationProgress operationProgress, Naps2Config config, IOperationFactory operationFactory,
|
||||
StillImage stillImage,
|
||||
UpdateChecker updateChecker, NotificationManager notify, ImageTransfer imageTransfer,
|
||||
ImageClipboard imageClipboard, ImageListActions imageListActions, WinFormsExportHelper exportHelper,
|
||||
DesktopImagesController desktopImagesController, DesktopScanController desktopScanController,
|
||||
IUpdateChecker updateChecker, INotificationManager notify, ImageTransfer imageTransfer,
|
||||
ImageClipboard imageClipboard, ImageListActions imageListActions, IWinFormsExportHelper exportHelper,
|
||||
DesktopImagesController desktopImagesController, IDesktopScanController desktopScanController,
|
||||
DesktopFormProvider desktopFormProvider)
|
||||
{
|
||||
_scanningContext = scanningContext;
|
||||
|
@ -3,7 +3,7 @@ using NAPS2.Wia;
|
||||
|
||||
namespace NAPS2.WinForms;
|
||||
|
||||
public class DesktopScanController
|
||||
public class DesktopScanController : IDesktopScanController
|
||||
{
|
||||
private readonly Naps2Config _config;
|
||||
private readonly IProfileManager _profileManager;
|
||||
|
@ -21,7 +21,7 @@ namespace NAPS2.WinForms
|
||||
private readonly IScannedImagePrinter _scannedImagePrinter;
|
||||
private readonly KeyboardShortcutManager _ksm;
|
||||
private readonly ThumbnailRenderer _thumbnailRenderer;
|
||||
private readonly NotificationManager _notify;
|
||||
private readonly INotificationManager _notify;
|
||||
private readonly CultureHelper _cultureHelper;
|
||||
private readonly IProfileManager _profileManager;
|
||||
private readonly UiImageList _imageList;
|
||||
@ -29,7 +29,7 @@ namespace NAPS2.WinForms
|
||||
private readonly ThumbnailRenderQueue _thumbnailRenderQueue;
|
||||
private readonly UiThumbnailProvider _thumbnailProvider;
|
||||
private readonly DesktopController _desktopController;
|
||||
private readonly DesktopScanController _desktopScanController;
|
||||
private readonly IDesktopScanController _desktopScanController;
|
||||
private readonly ImageListActions _imageListActions;
|
||||
private readonly DesktopFormProvider _desktopFormProvider;
|
||||
private readonly DesktopSubFormController _desktopSubFormController;
|
||||
@ -46,7 +46,7 @@ namespace NAPS2.WinForms
|
||||
IScannedImagePrinter scannedImagePrinter,
|
||||
KeyboardShortcutManager ksm,
|
||||
ThumbnailRenderer thumbnailRenderer,
|
||||
NotificationManager notify,
|
||||
INotificationManager notify,
|
||||
CultureHelper cultureHelper,
|
||||
IProfileManager profileManager,
|
||||
UiImageList imageList,
|
||||
@ -54,7 +54,7 @@ namespace NAPS2.WinForms
|
||||
ThumbnailRenderQueue thumbnailRenderQueue,
|
||||
UiThumbnailProvider thumbnailProvider,
|
||||
DesktopController desktopController,
|
||||
DesktopScanController desktopScanController,
|
||||
IDesktopScanController desktopScanController,
|
||||
ImageListActions imageListActions,
|
||||
DesktopFormProvider desktopFormProvider, DesktopSubFormController desktopSubFormController)
|
||||
{
|
||||
|
@ -30,7 +30,7 @@ namespace NAPS2.WinForms
|
||||
private ToolStripSeparator _toolStripSeparator2;
|
||||
private ToolStripButton _tsSaveImage;
|
||||
private readonly IOperationFactory _operationFactory;
|
||||
private readonly WinFormsExportHelper _exportHelper;
|
||||
private readonly IWinFormsExportHelper _exportHelper;
|
||||
private ToolStripButton _tsHueSaturation;
|
||||
private ToolStripButton _tsBlackWhite;
|
||||
private ToolStripButton _tsSharpen;
|
||||
@ -38,7 +38,7 @@ namespace NAPS2.WinForms
|
||||
private readonly OperationProgress _operationProgress;
|
||||
private readonly ImageContext _imageContext;
|
||||
|
||||
public FViewer(IOperationFactory operationFactory, WinFormsExportHelper exportHelper, KeyboardShortcutManager ksm, OperationProgress operationProgress, ImageContext imageContext)
|
||||
public FViewer(IOperationFactory operationFactory, IWinFormsExportHelper exportHelper, KeyboardShortcutManager ksm, OperationProgress operationProgress, ImageContext imageContext)
|
||||
{
|
||||
_operationFactory = operationFactory;
|
||||
_exportHelper = exportHelper;
|
||||
|
11
NAPS2.Lib.WinForms/WinForms/IDesktopScanController.cs
Normal file
11
NAPS2.Lib.WinForms/WinForms/IDesktopScanController.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using NAPS2.Scan;
|
||||
|
||||
namespace NAPS2.WinForms;
|
||||
|
||||
public interface IDesktopScanController
|
||||
{
|
||||
Task ScanWithDevice(string deviceID);
|
||||
Task ScanDefault();
|
||||
Task ScanWithNewProfile();
|
||||
Task ScanWithProfile(ScanProfile profile);
|
||||
}
|
12
NAPS2.Lib.WinForms/WinForms/INotificationManager.cs
Normal file
12
NAPS2.Lib.WinForms/WinForms/INotificationManager.cs
Normal file
@ -0,0 +1,12 @@
|
||||
using NAPS2.Update;
|
||||
|
||||
namespace NAPS2.WinForms;
|
||||
|
||||
public interface INotificationManager : ISaveNotify
|
||||
{
|
||||
FormBase ParentForm { get; set; }
|
||||
void DonatePrompt();
|
||||
void OperationProgress(OperationProgress opModalProgress, IOperation op);
|
||||
void UpdateAvailable(IUpdateChecker updateChecker, UpdateInfo update);
|
||||
void Rebuild();
|
||||
}
|
11
NAPS2.Lib.WinForms/WinForms/IWinFormsExportHelper.cs
Normal file
11
NAPS2.Lib.WinForms/WinForms/IWinFormsExportHelper.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using NAPS2.ImportExport.Email;
|
||||
|
||||
namespace NAPS2.WinForms;
|
||||
|
||||
public interface IWinFormsExportHelper
|
||||
{
|
||||
Task<bool> SavePDF(IList<ProcessedImage> images, ISaveNotify notify);
|
||||
Task<bool> ExportPDF(string filename, IList<ProcessedImage> images, bool email, EmailMessage emailMessage);
|
||||
Task<bool> SaveImages(IList<ProcessedImage> images, ISaveNotify notify);
|
||||
Task<bool> EmailPDF(IList<ProcessedImage> images);
|
||||
}
|
@ -3,7 +3,7 @@ using NAPS2.Update;
|
||||
|
||||
namespace NAPS2.WinForms;
|
||||
|
||||
public class NotificationManager : ISaveNotify
|
||||
public class NotificationManager : INotificationManager
|
||||
{
|
||||
private const int PADDING_X = 25, PADDING_Y = 25;
|
||||
private const int SPACING_Y = 20;
|
||||
@ -54,7 +54,7 @@ public class NotificationManager : ISaveNotify
|
||||
Show(new OperationProgressNotifyWidget(opModalProgress, op));
|
||||
}
|
||||
|
||||
public void UpdateAvailable(UpdateChecker updateChecker, UpdateInfo update)
|
||||
public void UpdateAvailable(IUpdateChecker updateChecker, UpdateInfo update)
|
||||
{
|
||||
Show(new UpdateAvailableNotifyWidget(updateChecker, update));
|
||||
}
|
||||
|
@ -5,10 +5,10 @@ namespace NAPS2.WinForms;
|
||||
|
||||
public class UpdateAvailableNotifyWidget : NotifyWidget
|
||||
{
|
||||
private readonly UpdateChecker _updateChecker;
|
||||
private readonly IUpdateChecker _updateChecker;
|
||||
private readonly UpdateInfo _update;
|
||||
|
||||
public UpdateAvailableNotifyWidget(UpdateChecker updateChecker, UpdateInfo update)
|
||||
public UpdateAvailableNotifyWidget(IUpdateChecker updateChecker, UpdateInfo update)
|
||||
: base(MiscResources.UpdateAvailable, string.Format(MiscResources.Install, update.Name), null, null)
|
||||
{
|
||||
_updateChecker = updateChecker;
|
||||
|
@ -7,7 +7,7 @@ using NAPS2.ImportExport.Pdf;
|
||||
namespace NAPS2.WinForms;
|
||||
|
||||
// TODO: Rename this ImageExportController or something
|
||||
public class WinFormsExportHelper
|
||||
public class WinFormsExportHelper : IWinFormsExportHelper
|
||||
{
|
||||
private readonly DialogHelper _dialogHelper;
|
||||
private readonly IOperationFactory _operationFactory;
|
||||
|
@ -6,12 +6,12 @@ namespace NAPS2.WinForms;
|
||||
public class WinFormsOperationProgress : OperationProgress
|
||||
{
|
||||
private readonly IFormFactory _formFactory;
|
||||
private readonly NotificationManager _notificationManager;
|
||||
private readonly INotificationManager _notificationManager;
|
||||
private readonly Naps2Config _config;
|
||||
|
||||
private readonly HashSet<IOperation> _activeOperations = new HashSet<IOperation>();
|
||||
|
||||
public WinFormsOperationProgress(IFormFactory formFactory, NotificationManager notificationManager, Naps2Config config)
|
||||
public WinFormsOperationProgress(IFormFactory formFactory, INotificationManager notificationManager, Naps2Config config)
|
||||
{
|
||||
_formFactory = formFactory;
|
||||
_notificationManager = notificationManager;
|
||||
|
11
NAPS2.Sdk.Tests/Images/UiImageListTests.cs
Normal file
11
NAPS2.Sdk.Tests/Images/UiImageListTests.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using Xunit;
|
||||
|
||||
namespace NAPS2.Sdk.Tests.Images;
|
||||
|
||||
public class UiImageListTests
|
||||
{
|
||||
[Fact]
|
||||
public void Something()
|
||||
{
|
||||
}
|
||||
}
|
11
NAPS2.Sdk.Tests/Images/UiImageTests.cs
Normal file
11
NAPS2.Sdk.Tests/Images/UiImageTests.cs
Normal file
@ -0,0 +1,11 @@
|
||||
using Xunit;
|
||||
|
||||
namespace NAPS2.Sdk.Tests.Images;
|
||||
|
||||
public class UiImageTests
|
||||
{
|
||||
[Fact]
|
||||
public void Something()
|
||||
{
|
||||
}
|
||||
}
|
@ -23,6 +23,7 @@ public class UiImageList
|
||||
_selection = ListSelection.Empty<UiImage>();
|
||||
}
|
||||
|
||||
// TODO: Can we inject this?
|
||||
public ThumbnailRenderer? ThumbnailRenderer { get; set; }
|
||||
|
||||
// TODO: Make this immutable?
|
||||
@ -105,6 +106,7 @@ public class UiImageList
|
||||
|
||||
private void UpdateSelectionOnUiThread(ListSelection<UiImage> currentSelection)
|
||||
{
|
||||
// TODO: This won't work right as SyncContext.Current is only set on the UI thread anyway
|
||||
var syncContext = SynchronizationContext.Current;
|
||||
if (syncContext != null)
|
||||
{
|
||||
|
@ -38,7 +38,7 @@ public class ScanningContext : IDisposable
|
||||
|
||||
public string? RecoveryPath { get; set; }
|
||||
|
||||
public IWorkerFactory WorkerFactory { get; set; }
|
||||
public IWorkerFactory? WorkerFactory { get; set; }
|
||||
|
||||
public OcrRequestQueue OcrRequestQueue { get; } = new();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user