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); }
/// <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)); }
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); }
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); }
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); }
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 { } } }
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; }
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(); }
public void WhenHospitalDepartmentIsSet_TakesEnumDescription() { var sentinelEntry = new SentinelEntry(); sentinelEntry.HospitalDepartment = HospitalDepartment.Anaesthetics; sentinelEntry.HospitalDepartmentOrOther().Should().Be("anästhesiologisch"); }
public void WhenHospitalDepartmentIsInternalNormalUnit_AddsAdditionalType() { var sentinelEntry = new SentinelEntry(); sentinelEntry.HospitalDepartment = HospitalDepartment.Internal; sentinelEntry.InternalHospitalDepartmentType = InternalHospitalDepartmentType.Cardiological; sentinelEntry.HospitalDepartmentOrOther().Should().Be("internistisch, kardiologisch"); }
public void WhenHospitalDepartmentIsOther_TakesOtherValue() { var sentinelEntry = new SentinelEntry(); sentinelEntry.HospitalDepartment = HospitalDepartment.Other; sentinelEntry.OtherHospitalDepartment = "Foo"; sentinelEntry.HospitalDepartmentOrOther().Should().Be("Foo"); }
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; }
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>(); }
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); }
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); }
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); }
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); }
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); }
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); }
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"); }
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); }