Ejemplo n.º 1
0
        public async Task WhenFoundButAlreadyArchived_AllowsAccessForSuperUser()
        {
            var user     = new ClaimsPrincipal();
            var identity = new ClaimsIdentity();

            identity.AddClaim(new Claim(identity.RoleClaimType, nameof(Role.SuperUser)));
            user.AddIdentity(identity);
            var sut = CreateSut(out var repository, out _, out _, "12", user);
            var updateSentinelEntry = new SentinelEntryRequest {
                Id = 567
            };
            var sentinelEntry = new SentinelEntry
            {
                ProtectKey = "12",
                CryoDate   = new DateTime(2010, 10, 10),
                AntimicrobialSensitivityTests = new List <AntimicrobialSensitivityTest>()
            };

            repository.FirstOrDefaultAsync(Arg.Is <SentinelEntryIncludingTestsSpecification>(specification => specification.Id == 567))
            .Returns(Task.FromResult(sentinelEntry));

            var action = await sut.HandleAsync(updateSentinelEntry).ConfigureAwait(true);

            action.Result.Should().BeOfType <OkObjectResult>();
            await repository.Received(1).UpdateAsync(Arg.Any <SentinelEntry>()).ConfigureAwait(true);
        }
Ejemplo n.º 2
0
    /// <summary>
    ///   Checks if the entry exists and if it is accessible by the corresponding user.
    ///   If <paramref name="byPassRole"/> is defined this can be used to force access
    ///   the record if user has this role.
    /// </summary>
    /// <param name="entry">Entry to access, may be <c>null</c></param>
    /// <param name="user">User to check access for</param>
    /// <param name="byPassRole">Role which is allowed access irrespective of other access limitations</param>
    /// <returns></returns>
    public static bool IsNullOrProtected(this SentinelEntry entry, ClaimsPrincipal user, Role?byPassRole = null)
    {
        var organizationId = user.Claims.OrganizationId();
        var userIsInRole   = byPassRole.HasValue && user.IsInRole(byPassRole.Value.ToString());

        return(entry is null || (entry.ProtectKey != organizationId && !userIsInRole));
    }
Ejemplo n.º 3
0
        public async Task WhenFound_DeletesCorrespondingObjects()
        {
            var sut = CreateSut(out var repository, out var sensitivityTestRepository, "12");
            var sensitivityTest1 = new AntimicrobialSensitivityTest();
            var sensitivityTest2 = new AntimicrobialSensitivityTest();
            var sentinelEntry    = new SentinelEntry
            {
                Id         = 567,
                ProtectKey = "12",
                AntimicrobialSensitivityTests = new List <AntimicrobialSensitivityTest>
                {
                    sensitivityTest1, sensitivityTest2
                }
            };

            repository.FirstOrDefaultAsync(Arg.Is <SentinelEntryIncludingTestsSpecification>(specification => specification.Id == 567))
            .Returns(Task.FromResult(sentinelEntry));

            var action = await sut.HandleAsync(567).ConfigureAwait(true);

            await sensitivityTestRepository.Received(1).DeleteAsync(sensitivityTest1).ConfigureAwait(true);

            await sensitivityTestRepository.Received(1).DeleteAsync(sensitivityTest2).ConfigureAwait(true);

            await repository.Received(1).DeleteAsync(sentinelEntry).ConfigureAwait(true);

            var okResult = action.Result.Should().BeOfType <OkObjectResult>().Subject;

            okResult.Value.Should().Be(567);
        }
Ejemplo n.º 4
0
        public async Task WhenFound_UpdatesOnlyDateAndRemark(string dateString, string expectedRemark)
        {
            var expectedDate = dateString != null ? (DateTime?)DateTime.Parse(dateString) : null;
            var sut          = CreateSut(out var repository);

            var cryoArchiveRequest = new CryoArchiveRequest {
                Id = 567, CryoDate = expectedDate, CryoRemark = expectedRemark
            };
            var sentinelEntry = new SentinelEntry
            {
                AgeGroup      = AgeGroup.EightySixToNinety,
                CryoBoxNumber = 10,
                CryoBoxSlot   = 56
            };

            repository.FirstOrDefaultAsync(Arg.Is <SentinelEntryIncludingTestsSpecification>(specification => specification.Id == 567))
            .Returns(Task.FromResult(sentinelEntry));

            var action = await sut.HandleAsync(cryoArchiveRequest).ConfigureAwait(true);

            var okResult    = action.Result.Should().BeOfType <OkObjectResult>().Subject;
            var storedEntry = okResult.Value as SentinelEntry;

            storedEntry.CryoDate.Should().Be(expectedDate);
            storedEntry.CryoRemark.Should().Be(expectedRemark);
            storedEntry.CryoBoxNumber.Should().Be(10);
            storedEntry.CryoBoxSlot.Should().Be(56);
        }
Ejemplo n.º 5
0
        public async Task WhenFoundBySuperUser_ReturnsCorrespondingObjectIrrespectiveOfProtectKey()
        {
            var user     = new ClaimsPrincipal();
            var identity = new ClaimsIdentity();

            identity.AddClaim(new Claim(identity.RoleClaimType, nameof(Role.SuperUser)));
            user.AddIdentity(identity);

            var sut           = CreateSut(out var repository, out var mapper, "1", user);
            var sentinelEntry = new SentinelEntry
            {
                ProtectKey = "12"
            };
            var sentinelEntryResponse = new SentinelEntryResponse
            {
            };

            repository.FirstOrDefaultAsync(Arg.Is <SentinelEntryIncludingTestsSpecification>(specification => specification.Id == 567))
            .Returns(Task.FromResult(sentinelEntry));
            mapper.Map <SentinelEntryResponse>(sentinelEntry).Returns(sentinelEntryResponse);

            var action = await sut.HandleAsync(567).ConfigureAwait(true);

            var okResult = action.Result.Should().BeOfType <OkObjectResult>().Subject;

            okResult.Value.Should().Be(sentinelEntryResponse);
        }
Ejemplo n.º 6
0
            public static void OnCacheItemRemovedCallback(string key, object value, CacheItemRemovedReason reason)
            {
                CacheItemUpdateReason updateReason;
                SentinelEntry         entry = value as SentinelEntry;

                switch (reason)
                {
                case CacheItemRemovedReason.Expired:
                    updateReason = CacheItemUpdateReason.Expired;
                    break;

                case CacheItemRemovedReason.DependencyChanged:
                    updateReason = CacheItemUpdateReason.DependencyChanged;
                    if (entry.ExpensiveObjectDependency.HasChanged)
                    {
                        // If the expensiveObject has been removed explicitly by Cache.Remove,
                        // return from the SentinelEntry removed callback
                        // thus effectively removing the SentinelEntry from the cache.
                        return;
                    }
                    break;

                case CacheItemRemovedReason.Underused:
                    Debug.Fail("Reason should never be CacheItemRemovedReason.Underused since the entry was inserted as NotRemovable.");
                    return;

                default:
                    // do nothing if reason is Removed
                    return;
                }

                CacheDependency         cacheDependency;
                DateTime                absoluteExpiration;
                TimeSpan                slidingExpiration;
                object                  expensiveObject;
                CacheItemUpdateCallback callback = entry.CacheItemUpdateCallback;

                // invoke update callback
                try {
                    callback(entry.Key, updateReason, out expensiveObject, out cacheDependency, out absoluteExpiration, out slidingExpiration);
                    // Dev10 861163 - Only update the "expensive" object if the user returns a new object and the
                    // cache dependency hasn't changed.  (Inserting with a cache dependency that has already changed will cause recursion.)
                    if (expensiveObject != null && (cacheDependency == null || !cacheDependency.HasChanged))
                    {
                        HttpRuntime.Cache.Insert(entry.Key, expensiveObject, cacheDependency, absoluteExpiration, slidingExpiration, entry.CacheItemUpdateCallback);
                    }
                    else
                    {
                        HttpRuntime.Cache.Remove(entry.Key);
                    }
                }
                catch (Exception e) {
                    HttpRuntime.Cache.Remove(entry.Key);
                    try {
                        WebBaseEvent.RaiseRuntimeError(e, value);
                    }
                    catch {
                    }
                }
            }
Ejemplo n.º 7
0
        public async Task WhenCreatedWithValidPredecessor_StoresRelationToRepository()
        {
            SentinelEntry createdEntry = null;
            var           sut          = CreateSut(out var repository, out var mapper, "12");
            var           createSentinelEntryRequest = new SentinelEntryRequest {
                PredecessorLaboratoryNumber = "SN-2022-0001"
            };
            var sentinelEntry = new SentinelEntry {
                Id = 124
            };
            var predecessorSentinelEntry = new SentinelEntry {
                Id = 100
            };

            mapper.Map <SentinelEntry>(createSentinelEntryRequest).Returns(sentinelEntry);
            repository.When(r => r.AddAsync(Arg.Any <SentinelEntry>())).Do(call => createdEntry = call.Arg <SentinelEntry>());
            repository.AddAsync(sentinelEntry).Returns(sentinelEntry);
            repository.FirstOrDefaultAsync(Arg.Any <SentinelEntryByLaboratoryNumberSpecification>()).Returns(predecessorSentinelEntry);

            var action = await sut.HandleAsync(createSentinelEntryRequest).ConfigureAwait(true);

            await repository.Received(1).FirstOrDefaultAsync(Arg.Is <SentinelEntryByLaboratoryNumberSpecification>(
                                                                 s => s.Year == 2022 && s.SequentialNumber == 1 && s.ProtectKey == "12")).ConfigureAwait(true);

            createdEntry.PredecessorEntryId.Should().Be(100);
            var createdResult = action.Result.Should().BeOfType <CreatedResult>().Subject;
        }
Ejemplo n.º 8
0
        public async Task WhenFoundAndUpdateWithoutPredecessor_ClearsPredecessor()
        {
            var sut = CreateSut(out var repository, out var sensitivityTestRepository, out var mapper, "12");
            var updateSentinelEntry = new SentinelEntryRequest {
                Id = 567
            };
            var sensitivityTest1 = new AntimicrobialSensitivityTest();
            var sentinelEntry    = new SentinelEntry
            {
                ProtectKey = "12",
                AntimicrobialSensitivityTests = new List <AntimicrobialSensitivityTest>
                {
                    sensitivityTest1
                },
                PredecessorEntry   = new SentinelEntry(),
                PredecessorEntryId = 123
            };

            repository.FirstOrDefaultAsync(Arg.Is <SentinelEntryIncludingTestsSpecification>(specification => specification.Id == 567))
            .Returns(Task.FromResult(sentinelEntry));

            var action = await sut.HandleAsync(updateSentinelEntry).ConfigureAwait(true);

            await sensitivityTestRepository.Received(1).DeleteAsync(sensitivityTest1).ConfigureAwait(true);

            mapper.Received(1).Map(updateSentinelEntry, sentinelEntry);
            var okResult             = action.Result.Should().BeOfType <OkObjectResult>().Subject;
            var updatedSentinelEntry = okResult.Value.As <SentinelEntry>();

            updatedSentinelEntry.PredecessorEntry.Should().BeNull();
            updatedSentinelEntry.PredecessorEntryId.Should().BeNull();
        }
Ejemplo n.º 9
0
    public void WhenHospitalDepartmentIsSet_TakesEnumDescription()
    {
        var sentinelEntry = new SentinelEntry();

        sentinelEntry.HospitalDepartment = HospitalDepartment.Anaesthetics;

        sentinelEntry.HospitalDepartmentOrOther().Should().Be("anästhesiologisch");
    }
Ejemplo n.º 10
0
    public void WhenHospitalDepartmentIsInternalNormalUnit_AddsAdditionalType()
    {
        var sentinelEntry = new SentinelEntry();

        sentinelEntry.HospitalDepartment             = HospitalDepartment.Internal;
        sentinelEntry.InternalHospitalDepartmentType = InternalHospitalDepartmentType.Cardiological;

        sentinelEntry.HospitalDepartmentOrOther().Should().Be("internistisch, kardiologisch");
    }
Ejemplo n.º 11
0
    public void WhenHospitalDepartmentIsOther_TakesOtherValue()
    {
        var sentinelEntry = new SentinelEntry();

        sentinelEntry.HospitalDepartment      = HospitalDepartment.Other;
        sentinelEntry.OtherHospitalDepartment = "Foo";

        sentinelEntry.HospitalDepartmentOrOther().Should().Be("Foo");
    }
Ejemplo n.º 12
0
            internal static void OnCacheEntryRemovedCallback(CacheEntryRemovedArguments arguments)
            {
                MemoryCache             cache  = arguments.Source as MemoryCache;
                SentinelEntry           entry  = arguments.CacheItem.Value as SentinelEntry;
                CacheEntryRemovedReason reason = arguments.RemovedReason;

                switch (reason)
                {
                case CacheEntryRemovedReason.Expired:
                    break;

                case CacheEntryRemovedReason.ChangeMonitorChanged:
                    if (entry.ExpensiveObjectDependency.HasChanged)
                    {
                        // If the expensiveObject has been removed explicitly by Cache.Remove,
                        // return from the SentinelEntry removed callback
                        // thus effectively removing the SentinelEntry from the cache.
                        return;
                    }
                    break;

                case CacheEntryRemovedReason.Evicted:
                    Debug.Fail("Reason should never be CacheEntryRemovedReason.Evicted since the entry was inserted as NotRemovable.");
                    return;

                default:
                    // do nothing if reason is Removed or CacheSpecificEviction
                    return;
                }

                // invoke update callback
                try
                {
                    CacheEntryUpdateArguments args = new CacheEntryUpdateArguments(cache, reason, entry.Key, null);
                    entry.CacheEntryUpdateCallback(args);
                    object          expensiveObject = (args.UpdatedCacheItem != null) ? args.UpdatedCacheItem.Value : null;
                    CacheItemPolicy policy          = args.UpdatedCacheItemPolicy;
                    // Only update the "expensive" object if the user returns a new object,
                    // a policy with update callback, and the change monitors haven't changed.  (Inserting
                    // with change monitors that have already changed will cause recursion.)
                    if (expensiveObject != null && IsPolicyValid(policy))
                    {
                        cache.Set(entry.Key, expensiveObject, policy);
                    }
                    else
                    {
                        cache.Remove(entry.Key);
                    }
                }
                catch
                {
                    cache.Remove(entry.Key);
                    // Review: What should we do with this exception?
                }
            }
        public void Setup()
        {
            var filler = new Filler <SentinelEntry>();

            SentinelEntry = filler.Create();

            var sentinelEntries = new List <SentinelEntry> {
                SentinelEntry
            };

            sentinelEntries.AddRange(filler.Create(10));
            SentinelEntries = sentinelEntries;
        }
Ejemplo n.º 14
0
        public async Task WhenNotFoundWithCorrespondingProtectKey_Returns404()
        {
            var sut           = CreateSut(out var repository, out _, "12");
            var sentinelEntry = new SentinelEntry
            {
                ProtectKey = "24"
            };

            repository.FirstOrDefaultAsync(Arg.Is <SentinelEntryIncludingTestsSpecification>(specification => specification.Id == 567))
            .Returns(Task.FromResult(sentinelEntry));

            var action = await sut.HandleAsync(123).ConfigureAwait(true);

            action.Result.Should().BeOfType <NotFoundResult>();
        }
Ejemplo n.º 15
0
        public async Task WhenFoundWithinAnotherOrganization_Returns404()
        {
            var sut           = CreateSut(out var repository, out _, "12");
            var sentinelEntry = new SentinelEntry
            {
                ProtectKey = "24"
            };

            repository.FirstOrDefaultAsync(Arg.Is <SentinelEntryIncludingTestsSpecification>(specification => specification.Id == 567))
            .Returns(Task.FromResult(sentinelEntry));

            var action = await sut.HandleAsync(567).ConfigureAwait(true);

            action.Result.Should().BeOfType <NotFoundResult>();
            await repository.Received(0).DeleteAsync(Arg.Any <SentinelEntry>()).ConfigureAwait(true);
        }
Ejemplo n.º 16
0
        public async Task WhenCreatedWithInvalidPredecessorNumber_BadRequest()
        {
            var sut = CreateSut(out var repository, out var mapper, "12");
            var createSentinelEntryRequest = new SentinelEntryRequest()
            {
                PredecessorLaboratoryNumber = "SN-3022-0001"
            };
            var sentinelEntry = new SentinelEntry {
                Id = 123
            };

            var action = await sut.HandleAsync(createSentinelEntryRequest).ConfigureAwait(true);

            action.Result.Should().BeOfType <BadRequestObjectResult>();
            await repository.Received(0).AddAsync(sentinelEntry).ConfigureAwait(true);
        }
Ejemplo n.º 17
0
        public async Task WhenFoundButAlreadyArchived_DeniesAccess()
        {
            var sut           = CreateSut(out var repository, out _, "12");
            var sentinelEntry = new SentinelEntry
            {
                ProtectKey = "12",
                CryoDate   = new DateTime(2010, 10, 10),
                AntimicrobialSensitivityTests = new List <AntimicrobialSensitivityTest>()
            };

            repository.FirstOrDefaultAsync(Arg.Is <SentinelEntryIncludingTestsSpecification>(specification => specification.Id == 567))
            .Returns(Task.FromResult(sentinelEntry));

            var action = await sut.HandleAsync(567).ConfigureAwait(true);

            action.Result.Should().BeOfType <ForbidResult>();
            await repository.Received(0).UpdateAsync(Arg.Any <SentinelEntry>()).ConfigureAwait(true);
        }
Ejemplo n.º 18
0
        public async Task WhenFoundButInvalidPredecessorNumber_BadRequest()
        {
            var sut = CreateSut(out var repository, out _, out _, "12");
            var updateSentinelEntry = new SentinelEntryRequest {
                Id = 567, PredecessorLaboratoryNumber = "Test"
            };
            var sentinelEntry = new SentinelEntry
            {
                ProtectKey = "12",
                AntimicrobialSensitivityTests = new List <AntimicrobialSensitivityTest>()
            };

            repository.FirstOrDefaultAsync(Arg.Is <SentinelEntryIncludingTestsSpecification>(specification => specification.Id == 567))
            .Returns(Task.FromResult(sentinelEntry));

            var action = await sut.HandleAsync(updateSentinelEntry).ConfigureAwait(true);

            action.Result.Should().BeOfType <BadRequestObjectResult>();
            await repository.Received(0).UpdateAsync(Arg.Any <SentinelEntry>()).ConfigureAwait(true);
        }
Ejemplo n.º 19
0
    public static async Task <bool> ResolvePredecessor(SentinelEntryRequest request, SentinelEntry newEntry,
                                                       IAsyncRepository <SentinelEntry> repository, string organizationId, ModelStateDictionary modelState)
    {
        if (string.IsNullOrEmpty(request.PredecessorLaboratoryNumber))
        {
            return(false);
        }

        var predecessor = await repository.FirstOrDefaultAsync(
            new SentinelEntryByLaboratoryNumberSpecification(request.PredecessorLaboratoryNumber, organizationId)).ConfigureAwait(false);

        if (predecessor == null)
        {
            modelState.AddModelError($"{nameof(SentinelEntryRequest.PredecessorLaboratoryNumber)}", "Laboratory number can not be found");
            return(true);
        }

        newEntry.PredecessorEntryId = predecessor.Id;
        return(false);
    }
Ejemplo n.º 20
0
        public async Task WhenFound_ReturnsCorrespondingObject()
        {
            var sut           = CreateSut(out var repository, out var mapper, "12");
            var sentinelEntry = new SentinelEntry
            {
                ProtectKey = "12"
            };
            var sentinelEntryResponse = new SentinelEntryResponse
            {
            };

            repository.FirstOrDefaultAsync(Arg.Is <SentinelEntryIncludingTestsSpecification>(specification => specification.Id == 567))
            .Returns(Task.FromResult(sentinelEntry));
            mapper.Map <SentinelEntryResponse>(sentinelEntry).Returns(sentinelEntryResponse);

            var action = await sut.HandleAsync(567).ConfigureAwait(true);

            var okResult = action.Result.Should().BeOfType <OkObjectResult>().Subject;

            okResult.Value.Should().Be(sentinelEntryResponse);
        }
Ejemplo n.º 21
0
        public async Task WhenCreated_MapsAndStoresToRepository()
        {
            var sut = CreateSut(out var repository, out var mapper, "12");
            var createSentinelEntryRequest = new SentinelEntryRequest();
            var sentinelEntry = new SentinelEntry {
                Id = 123
            };

            mapper.Map <SentinelEntry>(createSentinelEntryRequest).Returns(sentinelEntry);
            repository.AddAsync(sentinelEntry).Returns(sentinelEntry);

            var action = await sut.HandleAsync(createSentinelEntryRequest).ConfigureAwait(true);

            await repository.Received(1).AddAsync(sentinelEntry).ConfigureAwait(true);

            sentinelEntry.ProtectKey.Should().Be("12");
            var createdResult = action.Result.Should().BeOfType <CreatedResult>().Subject;

            createdResult.Value.Should().Be(sentinelEntry);
            createdResult.Location.Should().Be("http://localhost/api/sentinel-entries/123");
        }
Ejemplo n.º 22
0
        public async Task WhenFound_ReturnsCorrespondingObject()
        {
            var sut = CreateSut(out var repository, out var sensitivityTestRepository, out var mapper, "12");
            var updateSentinelEntry = new SentinelEntryRequest {
                Id = 567, PredecessorLaboratoryNumber = "SN-3030-0303"
            };
            var sensitivityTest1 = new AntimicrobialSensitivityTest();
            var sensitivityTest2 = new AntimicrobialSensitivityTest();
            var sentinelEntry    = new SentinelEntry
            {
                ProtectKey = "12",
                AntimicrobialSensitivityTests = new List <AntimicrobialSensitivityTest>
                {
                    sensitivityTest1, sensitivityTest2
                }
            };
            var predecessorSentinelEntry = new SentinelEntry {
                Id = 303
            };

            repository.FirstOrDefaultAsync(Arg.Is <SentinelEntryByLaboratoryNumberSpecification>(s => s.Year == 3030 && s.SequentialNumber == 303)).Returns(predecessorSentinelEntry);
            repository.FirstOrDefaultAsync(Arg.Is <SentinelEntryIncludingTestsSpecification>(specification => specification.Id == 567))
            .Returns(Task.FromResult(sentinelEntry));

            var action = await sut.HandleAsync(updateSentinelEntry).ConfigureAwait(true);

            await sensitivityTestRepository.Received(1).DeleteAsync(sensitivityTest1).ConfigureAwait(true);

            await sensitivityTestRepository.Received(1).DeleteAsync(sensitivityTest2).ConfigureAwait(true);

            mapper.Received(1).Map(updateSentinelEntry, sentinelEntry);
            var okResult = action.Result.Should().BeOfType <OkObjectResult>().Subject;

            okResult.Value.Should().Be(sentinelEntry);
            okResult.Value.As <SentinelEntry>().PredecessorEntryId.Should().Be(303);
        }