public async Task GivenAChangeFeedWithNewSeriesAndInstanceForAnExistingImagingStudy_WhenBuilt_ThenCorrectEntryComponentShouldBeCreated()
        {
            const string studyInstanceUid     = "1";
            const string seriesInstanceUid    = "2";
            const string sopInstanceUid       = "3";
            const string patientResourceId    = "p1";
            const string newSeriesInstanceUid = "3";
            const string newSopInstanceUid    = "4";

            ImagingStudy imagingStudy = FhirResourceBuilder.CreateNewImagingStudy(studyInstanceUid, new List <string>()
            {
                seriesInstanceUid
            }, new List <string>()
            {
                sopInstanceUid
            }, patientResourceId);

            _fhirService.RetrieveImagingStudyAsync(Arg.Any <Identifier>(), Arg.Any <CancellationToken>()).Returns(imagingStudy);

            // Update an existing ImagingStudy
            FhirTransactionRequestEntry entry = await BuildImagingStudyEntryComponent(studyInstanceUid, newSeriesInstanceUid, newSopInstanceUid, patientResourceId);

            ImagingStudy updatedImagingStudy = ValidationUtility.ValidateImagingStudyUpdate(studyInstanceUid, patientResourceId, entry);

            Assert.Collection(
                updatedImagingStudy.Series,
                series =>
            {
                ValidationUtility.ValidateSeries(series, seriesInstanceUid, sopInstanceUid);
            },
                series =>
            {
                ValidationUtility.ValidateSeries(series, newSeriesInstanceUid, newSopInstanceUid);
            });
        }
        /// <inheritdoc/>
        public async Task <FhirTransactionRequestEntry> BuildAsync(FhirTransactionContext context, CancellationToken cancellationToken)
        {
            EnsureArg.IsNotNull(context, nameof(context));
            EnsureArg.IsNotNull(context.ChangeFeedEntry, nameof(context.ChangeFeedEntry));
            EnsureArg.IsNotNull(context.Request, nameof(context.Request));

            IResourceId patientId = context.Request.Patient.ResourceId;

            ChangeFeedEntry changeFeedEntry = context.ChangeFeedEntry;

            Identifier imagingStudyIdentifier = ImagingStudyIdentifierUtility.CreateIdentifier(changeFeedEntry.StudyInstanceUid);

            ImagingStudy existingImagingStudy = await _fhirService.RetrieveImagingStudyAsync(imagingStudyIdentifier, cancellationToken);

            ImagingStudy imagingStudy = (ImagingStudy)existingImagingStudy?.DeepCopy();

            FhirTransactionRequestMode requestMode = FhirTransactionRequestMode.None;

            if (existingImagingStudy == null)
            {
                imagingStudy = new ImagingStudy()
                {
                    Status  = ImagingStudy.ImagingStudyStatus.Available,
                    Subject = patientId.ToResourceReference(),
                };

                imagingStudy.Identifier.Add(imagingStudyIdentifier);
                requestMode = FhirTransactionRequestMode.Create;
            }

            SynchronizeImagingStudyProperties(context, imagingStudy);

            if (requestMode != FhirTransactionRequestMode.Create &&
                !existingImagingStudy.IsExactly(imagingStudy))
            {
                requestMode = FhirTransactionRequestMode.Update;
            }

            Bundle.RequestComponent request = requestMode switch
            {
                FhirTransactionRequestMode.Create => ImagingStudyPipelineHelper.GenerateCreateRequest(imagingStudyIdentifier),
                FhirTransactionRequestMode.Update => ImagingStudyPipelineHelper.GenerateUpdateRequest(imagingStudy),
                _ => null,
            };

            IResourceId resourceId = requestMode switch
            {
                FhirTransactionRequestMode.Create => new ClientResourceId(),
                _ => existingImagingStudy.ToServerResourceId(),
            };

            return(new FhirTransactionRequestEntry(
                       requestMode,
                       request,
                       resourceId,
                       imagingStudy));
        }
        /// <inheritdoc/>
        public async Task <FhirTransactionRequestEntry> BuildAsync(FhirTransactionContext context, CancellationToken cancellationToken)
        {
            EnsureArg.IsNotNull(context, nameof(context));
            EnsureArg.IsNotNull(context.ChangeFeedEntry, nameof(context.ChangeFeedEntry));

            ChangeFeedEntry changeFeedEntry = context.ChangeFeedEntry;

            Identifier   imagingStudyIdentifier = ImagingStudyIdentifierUtility.CreateIdentifier(changeFeedEntry.StudyInstanceUid);
            ImagingStudy imagingStudy           = await _fhirService.RetrieveImagingStudyAsync(imagingStudyIdentifier, cancellationToken);

            // Returns null if imagingStudy does not exists for given studyInstanceUid
            if (imagingStudy == null)
            {
                return(null);
            }

            string imagingStudySource = imagingStudy.Meta.Source;

            ImagingStudy.SeriesComponent   series   = ImagingStudyPipelineHelper.GetSeriesWithinAStudy(changeFeedEntry.SeriesInstanceUid, imagingStudy.Series);
            ImagingStudy.InstanceComponent instance = ImagingStudyPipelineHelper.GetInstanceWithinASeries(changeFeedEntry.SopInstanceUid, series);

            // Return null if the given instance is not present in ImagingStudy
            if (instance == null)
            {
                return(null);
            }

            // Removes instance from series collection
            series.Instance.Remove(instance);

            // Removes series from ImagingStudy if its instance collection is empty
            if (series.Instance.Count == 0)
            {
                imagingStudy.Series.Remove(series);
            }

            if (imagingStudy.Series.Count == 0 && _dicomWebEndpoint.Equals(imagingStudySource, System.StringComparison.Ordinal))
            {
                return(new FhirTransactionRequestEntry(
                           FhirTransactionRequestMode.Delete,
                           ImagingStudyPipelineHelper.GenerateDeleteRequest(imagingStudy),
                           imagingStudy.ToServerResourceId(),
                           imagingStudy));
            }

            return(new FhirTransactionRequestEntry(
                       FhirTransactionRequestMode.Update,
                       ImagingStudyPipelineHelper.GenerateUpdateRequest(imagingStudy),
                       imagingStudy.ToServerResourceId(),
                       imagingStudy));
        }
        public async Task GivenAChangeFeedEntryToDeleteAnInstanceWithinASeriesContainingMoreThanOneInstance_WhenBuilt_ThenCorrectEntryComponentShouldBeCreated()
        {
            const string studyInstanceUid  = "1";
            const string seriesInstanceUid = "2";
            const string sopInstanceUid    = "3";
            const string sopInstanceUid1   = "3";
            const string patientResourceId = "p1";

            // create a new ImagingStudy
            ImagingStudy imagingStudy = FhirResourceBuilder.CreateNewImagingStudy(studyInstanceUid, new List <string>()
            {
                seriesInstanceUid
            }, new List <string>()
            {
                sopInstanceUid, sopInstanceUid1
            }, patientResourceId);

            _fhirService.RetrieveImagingStudyAsync(Arg.Any <Identifier>(), Arg.Any <CancellationToken>()).Returns(imagingStudy);

            // delete an existing instance within a study
            FhirTransactionRequestEntry entry = await BuildImagingStudyEntryComponent(studyInstanceUid, seriesInstanceUid, sopInstanceUid, patientResourceId);

            ImagingStudy updatedImagingStudy = ValidationUtility.ValidateImagingStudyUpdate(studyInstanceUid, patientResourceId, entry);

            Assert.Equal(ImagingStudy.ImagingStudyStatus.Available, updatedImagingStudy.Status);

            Assert.Collection(
                updatedImagingStudy.Series,
                series =>
            {
                Assert.Equal(seriesInstanceUid, series.Uid);

                Assert.Collection(
                    series.Instance,
                    instance => Assert.Equal(sopInstanceUid1, instance.Uid));
            });
        }