public void StatusRatingUtilityFunctions()
        {
            float             previousValue = float.MinValue;
            StatusRatingRange previousRange = StatusRatingRange.Pending;

            foreach (StatusRatingRange range in Enum.GetValues(typeof(StatusRatingRange)).Cast <StatusRatingRange>())
            {
                float lowerBound = StatusRating.GetRangeLowerBound(range);
                Assert.IsTrue(float.IsNaN(lowerBound) || lowerBound > previousValue);
                if (!float.IsNaN(lowerBound))
                {
                    previousValue = lowerBound;
                }
                Assert.AreEqual(previousRange, StatusRating.FindRange(lowerBound));
                previousRange = float.IsNaN(lowerBound) ? StatusRatingRange.Fail : range;
                float upperBound = StatusRating.GetRangeUpperBound(range);
                Assert.AreEqual(range, StatusRating.FindRange(upperBound));
                string rangeSymbol = StatusRating.GetRangeSymbol(range);
                Assert.IsFalse(string.IsNullOrEmpty(rangeSymbol));
                Assert.IsFalse(string.IsNullOrEmpty(StatusRating.GetRangeBackgroundColor(upperBound)));
                Assert.IsFalse(string.IsNullOrEmpty(StatusRating.GetRangeForegroundColor(upperBound)));
                Assert.IsFalse(string.IsNullOrEmpty(StatusRating.GetRatingRgbForegroundColor(upperBound)));
            }
            Assert.AreEqual(StatusRating.Okay, StatusResultsOrganizer.ClampedRating(StatusRating.Pending));
            Assert.AreEqual(StatusRating.Catastrophic, StatusResultsOrganizer.ClampedRating(StatusRating.Catastrophic - 1));
            Assert.AreEqual(StatusRating.Okay, StatusResultsOrganizer.ClampedRating(StatusRating.Superlative + 1));
            Assert.AreEqual(StatusRating.GetRatingRgbForegroundColor(StatusRating.Catastrophic), StatusRating.GetRatingRgbForegroundColor(StatusRating.Catastrophic - 1));
            Assert.AreNotEqual(StatusRating.GetRatingRgbForegroundColor(StatusRating.Superlative), StatusRating.GetRatingRgbForegroundColor(StatusRating.Superlative + 1));
        }
Exemple #2
0
        public async Task Status()
        {
            using (AmbientClock.Pause())
            {
                Status           s   = new Status(false);
                LocalDiskAuditor lda = null;
                try
                {
                    //System.Text.StringBuilder str = new System.Text.StringBuilder();
                    //str.AppendLine();
                    //str.AppendLine(Environment.GetFolderPath(Environment.SpecialFolder.System));
                    //str.AppendLine(System.IO.Path.GetTempPath());
                    //str.AppendLine(Path.GetPathRoot(System.IO.Path.GetTempPath()));
                    //Assert.Fail(str.ToString());
                    lda = new LocalDiskAuditor();
                    s.AddCheckerOrAuditor(lda);
                    await s.Start();

                    // run all the tests (just the one here) right now
                    await s.RefreshAsync();

                    StatusAuditAlert a = s.Summary;
                    Assert.AreEqual(StatusRatingRange.Okay, StatusRating.FindRange(a.Rating));
                }
                finally
                {
                    await s.Stop();

                    if (lda != null)
                    {
                        s.RemoveCheckerOrAuditor(lda);                  // note that lda could be null if the constructor throws!
                    }
                }
            }
        }
        /// <summary>
        /// Add a named conservation status rating, if it doesn't already exist
        /// </summary>
        /// <param name="name"></param>
        /// <param name="schemeName"></param>
        /// <returns></returns>
        public async Task <StatusRating> AddAsync(string name, string schemeName)
        {
            // Get the scheme and make sure it exists
            schemeName = _textInfo.ToTitleCase(schemeName.CleanString());
            StatusScheme scheme = await _factory.StatusSchemes.GetAsync(s => s.Name == schemeName);

            if (scheme == null)
            {
                string message = $"Status scheme '{schemeName}' does not exist";
                throw new StatusSchemeDoesNotExistException();
            }

            // Clean up the rating name and see if it exists. If so, just return it.
            // If not, create a new entry and return that
            name = _textInfo.ToTitleCase(name.CleanString());
            StatusRating rating = await GetAsync(r => (r.StatusSchemeId == scheme.Id) &&
                                                 (r.Name == name));

            if (rating == null)
            {
                rating = new StatusRating {
                    Name = name, StatusSchemeId = scheme.Id
                };
                _factory.Context.StatusRatings.Add(rating);
                await _factory.Context.SaveChangesAsync();
            }

            return(rating);
        }
        /// <summary>
        /// Set the conservation status rating for a species
        /// </summary>
        /// <param name="speciesName"></param>
        /// <param name="ratingName"></param>
        /// <param name="schemeName"></param>
        /// <returns></returns>
        public async Task <SpeciesStatusRating> SetRatingAsync(string speciesName, string ratingName, string schemeName)
        {
            // Tidy the parameters for direct comparison
            speciesName = _textInfo.ToTitleCase(speciesName.CleanString());
            ratingName  = _textInfo.ToTitleCase(ratingName.CleanString());
            schemeName  = _textInfo.ToTitleCase(schemeName.CleanString());

            // Check the species and rating
            Species species = await _factory.Species.GetAsync(s => s.Name == speciesName);

            if (species == null)
            {
                string message = $"Species '{speciesName}' does not exist";
                throw new SpeciesDoesNotExistException(message);
            }

            StatusRating rating = await _factory.StatusRatings.GetAsync(s => (s.Name == ratingName) && (s.Scheme.Name == schemeName));

            if (rating == null)
            {
                string message = $"Status rating '{ratingName}' does not exist on scheme '{schemeName}'";
                throw new StatusRatingDoesNotExistException(message);
            }

            // See if there's already a rating for this species on the specified scheme
            SpeciesStatusRating speciesRating = await _factory.Context
                                                .SpeciesStatusRatings
                                                .Include(r => r.Rating)
                                                .FirstOrDefaultAsync(r => (r.SpeciesId == species.Id) &&
                                                                     (r.Rating.StatusSchemeId == rating.StatusSchemeId));

            if (speciesRating != null)
            {
                // There is an existing rating on this scheme, so set the end-date for
                // that rating to midnight yesterday
                speciesRating.End = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 23, 59, 59).AddDays(-1);

                // This could leave a rating where the start date's greater than the end date. If that's the case,
                // make them the same
                if (speciesRating.Start > speciesRating.End)
                {
                    speciesRating.Start = speciesRating.End;
                }
            }

            // Create the new rating
            SpeciesStatusRating newRating = new SpeciesStatusRating
            {
                SpeciesId      = species.Id,
                StatusRatingId = rating.Id,
                Start          = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 0, 0, 0)
            };
            await _factory.Context.SpeciesStatusRatings.AddAsync(newRating);

            await _factory.Context.SaveChangesAsync();

            // Load and return the new rating (to load related entities)
            return(await GetAsync(r => r.Id == newRating.Id));
        }
        public void AddAndGetTest()
        {
            StatusRating entity = _factory.StatusRatings.Get(a => (a.Name == RatingName) && (a.Scheme.Name == SchemeName));

            Assert.IsNotNull(entity);
            Assert.IsTrue(entity.Id > 0);
            Assert.AreEqual(RatingName, entity.Name);
            Assert.AreEqual(SchemeName, entity.Scheme.Name);
        }
        public async Task AddAndGetAsyncTest()
        {
            await _factory.StatusRatings.AddAsync(AsyncRatingName, SchemeName);

            StatusRating entity = await _factory.StatusRatings.GetAsync(a => (a.Name == AsyncRatingName) && (a.Scheme.Name == SchemeName));

            Assert.IsNotNull(entity);
            Assert.IsTrue(entity.Id > 0);
            Assert.AreEqual(AsyncRatingName, entity.Name);
            Assert.AreEqual(SchemeName, entity.Scheme.Name);
        }
        public void RenameTest()
        {
            StatusRating rating = _factory.StatusRatings
                                  .Rename(RatingName, RenamedRatingName, SchemeName);

            Assert.AreEqual(rating.Name, RenamedRatingName);

            StatusRating original = _factory.StatusRatings.Get(s => s.Name == RatingName);

            Assert.IsNull(original);
        }
        public async Task RenameAsyncTest()
        {
            StatusRating rating = await _factory.StatusRatings
                                  .RenameAsync(RatingName, RenamedRatingName, SchemeName);

            Assert.AreEqual(rating.Name, RenamedRatingName);

            StatusRating original = await _factory.StatusRatings
                                    .GetAsync(s => s.Name == RatingName);

            Assert.IsNull(original);
        }
        /// <summary>
        /// Add a new conservation status rating based on the supplied template
        /// </summary>
        /// <param name="template"></param>
        /// <returns></returns>
        public SpeciesStatusRating Add(SpeciesStatusRating template)
        {
            // Retrieve/create the category andspecies. The logic to create new
            // records or return existing ones is in these methods
            Species species = _factory.Species.Add(template.Species.Name, template.Species.Category.Name);

            // If the scheme doesn't exist, create it
            string       schemeName = _textInfo.ToTitleCase(template.Rating.Scheme.Name.CleanString());
            StatusScheme scheme     = _factory.StatusSchemes.Get(s => s.Name == schemeName);

            if (scheme == null)
            {
                scheme = _factory.StatusSchemes.Add(schemeName);
            }

            // If the rating doesn't exist, create it
            string       ratingName = _textInfo.ToTitleCase(template.Rating.Name.CleanString());
            StatusRating rating     = _factory.StatusRatings.Get(r => (r.Name == ratingName) && (r.StatusSchemeId == scheme.Id));

            if (rating == null)
            {
                rating = _factory.StatusRatings.Add(ratingName, schemeName);
            }

            // Add a new species status rating. Note that we DON'T use the SetRating
            // method as it manipulates prior records and we don't want to do that in
            // this context (import of rating data)
            SpeciesStatusRating newRating = new SpeciesStatusRating
            {
                SpeciesId      = species.Id,
                StatusRatingId = rating.Id,
                Region         = template.Region,
                Start          = template.Start,
                End            = template.End
            };

            _factory.Context.SpeciesStatusRatings.Add(newRating);
            _factory.Context.SaveChanges();

            // Load and return the new rating (to load related entities)
            return(Get(r => r.Id == newRating.Id));
        }
        /// <summary>
        /// Rename a conservation status rating
        /// </summary>
        /// <param name="oldName"></param>
        /// <param name="newName"></param>
        /// <param name="schemeName"></param>
        /// <returns></returns>
        public async Task <StatusRating> RenameAsync(string oldName, string newName, string schemeName)
        {
            // Get the scheme and make sure it exists
            schemeName = _textInfo.ToTitleCase(schemeName.CleanString());
            StatusScheme scheme = await _factory.StatusSchemes.GetAsync(s => s.Name == schemeName);

            if (scheme == null)
            {
                string message = $"Status scheme '{schemeName}' does not exist";
                throw new StatusSchemeDoesNotExistException();
            }

            oldName = _textInfo.ToTitleCase(oldName.CleanString());
            newName = _textInfo.ToTitleCase(newName.CleanString());

            // There must be a rating with the original name
            StatusRating original = await GetAsync(r => (r.StatusSchemeId == scheme.Id) &&
                                                   (r.Name == oldName));

            if (original == null)
            {
                string message = $"Conservation status rating '{newName}' does not exist on scheme '{scheme.Name}'";
                throw new StatusRatingDoesNotExistException();
            }

            // There can't be an existing category with the specified name
            StatusRating newRating = await GetAsync(r => (r.StatusSchemeId == scheme.Id) &&
                                                    (r.Name == newName));

            if (newRating != null)
            {
                string message = $"Conservation status rating '{newName}' does not exist on scheme '{scheme.Name}'";
                throw new StatusRatingAlreadyExistsException();
            }

            // Update the name on the original
            original.Name = newName;
            await _factory.Context.SaveChangesAsync();

            return(original);
        }
        /// <summary>
        /// Delete the conservation status rating with the specified name
        /// </summary>
        /// <param name="name"></param>
        /// <param name="schemeName"></param>
        public async Task DeleteAsync(string name, string schemeName)
        {
            // Get the scheme and make sure it exists
            schemeName = _textInfo.ToTitleCase(schemeName.CleanString());
            StatusScheme scheme = await _factory.StatusSchemes.GetAsync(s => s.Name == schemeName);

            if (scheme == null)
            {
                string message = $"Status scheme '{schemeName}' does not exist";
                throw new StatusSchemeDoesNotExistException();
            }

            // Get the rating and make sure it exists
            name = _textInfo.ToTitleCase(name.CleanString());
            StatusRating rating = await GetAsync(r => r.Name == name);

            if (rating == null)
            {
                string message = $"Status rating '{name}' does not exist on scheme '{scheme.Name}'";
                throw new StatusRatingDoesNotExistException();
            }

            // Check the rating isn't associated with any species ratings
            SpeciesStatusRating speciesRatings = await _factory.Context
                                                 .SpeciesStatusRatings
                                                 .AsAsyncEnumerable()
                                                 .FirstOrDefaultAsync(sr => sr.StatusRatingId == rating.Id);

            if (speciesRatings != null)
            {
                string message = $"Cannot delete conservation status rating '{name}' on scheme '{scheme.Name}' while it is in use";
                throw new StatusRatingIsInUseException(message);
            }

            // Delete the rating
            _factory.Context.StatusRatings.Remove(rating);
            await _factory.Context.SaveChangesAsync();
        }
        public override Task Audit(StatusResultsBuilder statusBuilder, CancellationToken cancel = default(CancellationToken))
        {
            statusBuilder.NatureOfSystem = StatusNatureOfSystem.ChildrenIrrelevant;
            StatusRatingRange currentAuditRating = (StatusRatingRange)(_auditNumber++ % (int)EnumExtensions.MaxEnumValue <StatusRatingRange>());
            float             rating             = (StatusRating.GetRangeUpperBound(currentAuditRating) + StatusRating.GetRangeLowerBound(currentAuditRating)) / 2;

            if (rating <= StatusRating.Fail)
            {
                statusBuilder.AddFailure("FailCode", "Fail", "The system has failed!", StatusRating.Fail - rating);
            }
            else if (rating <= StatusRating.Alert)
            {
                statusBuilder.AddAlert("AlertCode", "Alert", "The system has alerted!", StatusRating.Alert - rating);
            }
            else if (rating <= StatusRating.Okay)
            {
                statusBuilder.AddOkay("OkayCode", "Okay", "The system is okay", StatusRating.Okay - rating);
            }
            else
            {
                statusBuilder.AddOkay("SuperCode", "Superlative", "The system is superlative", StatusRating.Superlative - rating);
            }
            return(Task.CompletedTask);
        }
        public void GetMissingTest()
        {
            StatusRating entity = _factory.StatusRatings.Get(a => (a.Name == "Missing") && (a.Scheme.Name == SchemeName));

            Assert.IsNull(entity);
        }
        public void StatusThresholdsRange()
        {
            StatusPropertyThresholds thresholds;
            StatusAuditAlert         alert;

            thresholds = new StatusPropertyThresholds(10.0f, 20.0f, 30.0f);
            for (float testLowValue = -5.0f; testLowValue < 35.0f; testLowValue += 5.0f)
            {
                for (float testHighValue = testLowValue; testHighValue < 35.0f; testHighValue += 5.0f)
                {
                    float             significantValue = testLowValue;
                    StatusRatingRange expectedRatingRange;
                    if (significantValue <= 10.0f)
                    {
                        expectedRatingRange = StatusRatingRange.Fail;
                    }
                    else if (significantValue <= 20.0f)
                    {
                        expectedRatingRange = StatusRatingRange.Alert;
                    }
                    else if (significantValue <= 30.0f)
                    {
                        expectedRatingRange = StatusRatingRange.Okay;
                    }
                    else
                    {
                        expectedRatingRange = StatusRatingRange.Superlative;
                    }
                    alert = thresholds.Rate("Property", testLowValue, testHighValue);
                    Assert.AreEqual(expectedRatingRange, StatusRating.FindRange(alert.Rating));
                }
            }

            thresholds = new StatusPropertyThresholds(30.0f, 20.0f, 10.0f);
            for (float testLowValue = -5.0f; testLowValue < 35.0f; testLowValue += 5.0f)
            {
                for (float testHighValue = testLowValue; testHighValue < 35.0f; testHighValue += 5.0f)
                {
                    float             significantValue = testHighValue;
                    StatusRatingRange expectedRatingRange;
                    if (significantValue >= 30.0f)
                    {
                        expectedRatingRange = StatusRatingRange.Fail;
                    }
                    else if (significantValue >= 20.0f)
                    {
                        expectedRatingRange = StatusRatingRange.Alert;
                    }
                    else if (significantValue >= 10.0f)
                    {
                        expectedRatingRange = StatusRatingRange.Okay;
                    }
                    else
                    {
                        expectedRatingRange = StatusRatingRange.Superlative;
                    }
                    alert = thresholds.Rate("Property", testLowValue, testHighValue);
                    Assert.AreEqual(expectedRatingRange, StatusRating.FindRange(alert.Rating));
                }
            }
        }