public void Report_DivisorIsZero_ThrowsException()
        {
            // ARRANGE
            int             reported = 0;
            Action <double> action   = (d) =>
            {
                reported = (int)d;
            };
            ScanningProgress scanningProgress = new ScanningProgress(action, 0, 0);

            // ACT
            scanningProgress.Report(1);

            // ASSERT (handled with ExpectedException)
        }
        public void Report_AddendAddedToDivision()
        {
            // ARRANGE
            int             reported = 0;
            Action <double> action   = (d) =>
            {
                reported = (int)d;
            };
            ScanningProgress scanningProgress = new ScanningProgress(action, 50, 2);

            // ACT
            scanningProgress.Report(100);

            // ASSERT
            Assert.AreEqual(100, reported);
        }
        public void Report_DivisorReducesValue()
        {
            // ARRANGE
            int             reported = 0;
            Action <double> action   = (d) =>
            {
                reported = (int)d;
            };
            ScanningProgress scanningProgress = new ScanningProgress(action, 0, 2);

            // ACT
            scanningProgress.Report(100);

            // ASSERT
            Assert.AreEqual(50, reported);
        }
        public void Report_ValueGreaterThan100Percent_Is100Percent()
        {
            // ARRANGE
            int             reported = 0;
            Action <double> action   = (d) =>
            {
                reported = (int)d;
            };
            ScanningProgress scanningProgress = new ScanningProgress(action);

            // ACT
            scanningProgress.Report(9001);

            // ASSERT
            Assert.AreEqual(100, reported);
        }
        public void Report_UpdatesControlValue()
        {
            // ARRANGE
            int             reported = 0;
            Action <double> action   = (d) =>
            {
                reported = (int)d;
            };
            ScanningProgress scanningProgress = new ScanningProgress(action);

            // ACT
            scanningProgress.Report(69);

            // ASSERT
            Assert.AreEqual(69, reported);
        }
        /// <summary>
        /// <para>Performs the scan process</para>
        /// <para>First the storage backend is queried for existing scanned locations.
        /// Then these existing locations are compared with the user selected locations to
        /// determine which locations are "new" and which are "rescans".</para>
        /// <para>Locations (and records) that are existing but not now user selected
        /// will be purged via
        /// <see cref="ScannedFileStore.PurgeLocationsAsync(List{string})"/></para>
        /// <para>After determining these locations
        /// <see cref="ScannedFileStore.ScanLocationsAsync(List{string}, IProgress{int})"/> is called for
        /// new scans, and <see cref="ScannedFileStore.RescanLocationsAsync(List{string}, IProgress{int})"/>
        /// for rescans.</para>
        /// <para>Any <see cref="Exception"/> should be handled and logged as an error.</para>
        /// </summary>
        internal async Task BeginScanAsync()
        {
            List <string> locations = Locations.Select(t => t.Path).ToList();

            ScanningProgress progress = new ScanningProgress((d) =>
            {
                Progress = (int)d;
            }, 0, 2);

            try
            {
                // Previously scanned locations
                List <string> scannedLocations = await _scannedFileStore.ListScannedLocationsAsync();

                // Determine all locations that are not in scannedLocations, these are new locations
                List <string> newLocations = locations.Except(scannedLocations).ToList();

                // Determine all scannedLocations that are in Locations, these are rescan locations
                List <string> rescanLocations = scannedLocations.Where(t => locations.Contains(t)).ToList();

                // Determine all locations that are in scannedLocations, but not in Locations.
                // We will purge scanned files from these locations
                List <string> purgeLocations = scannedLocations.Except(locations).ToList();

                // Purge any unneeded locations
                await _scannedFileStore.PurgeLocationsAsync(purgeLocations);

                // Scan new locations
                await _scannedFileStore.ScanLocationsAsync(newLocations, progress);

                progress.Addend = 50; // Update the Addend so that value will be reporeted correctly

                // Rescan previously scanned locations
                await _scannedFileStore.RescanLocationsAsync(rescanLocations, progress);

                progress.Report(100);
            }
            catch (Exception ex)
            {
                _logger.Error(ex, "An error occurred during the scanning process.");
            }
        }