@@ -42,6 +42,8 @@ def teardown
4242 @client . destroy ( get_resource ( :Observation ) , @batch_obs_2 . id ) if @batch_obs_2 && !@batch_obs_2 . id . nil?
4343 @client . destroy ( get_resource ( :Observation ) , @batch_obs_3 . id ) if @batch_obs_3 && !@batch_obs_3 . id . nil?
4444 @client . destroy ( get_resource ( :Patient ) , @batch_patient_2 . id ) if @batch_patient_2 && !@batch_patient_2 . id . nil?
45+ @client . destroy ( get_resource ( :Patient ) , @ifmatch_patient . id ) if @ifmatch_patient && !@ifmatch_patient . id . nil?
46+ @client . destroy ( get_resource ( :Patient ) , @ifmatch_patient_2 . id ) if @ifmatch_patient_2 && !@ifmatch_patient_2 . id . nil?
4547 end
4648
4749 # Create a Patient Record as a transaction
@@ -538,6 +540,68 @@ def teardown
538540 assert_bundle_response ( reply )
539541 assert_bundle_transactions_okay ( reply )
540542 end
543+
544+ # Transaction PUT with matching IfMatch should succeed
545+ test 'XFER20' , 'Transaction PUT with matching IfMatch should succeed' do
546+ metadata {
547+ links "#{ REST_SPEC_LINK } #transaction"
548+ links "#{ BASE_SPEC_LINK } /patient.html"
549+ requires resource : 'Patient' , methods : [ 'create' , 'update' ]
550+ requires resource : nil , methods : [ 'transaction-system' ]
551+ validates resource : 'Patient' , methods : [ 'update' ]
552+ validates resource : nil , methods : [ 'transaction-system' ]
553+ }
554+
555+ # Create a Patient and capture the ETag from the response
556+ @ifmatch_patient = ResourceGenerator . minimal_patient ( "#{ Time . now . to_i } " , 'IfMatch' , version_namespace )
557+ reply = @client . create @ifmatch_patient
558+ assert_response_ok ( reply )
559+ @ifmatch_patient . id = ( reply . resource . try ( :id ) || reply . id )
560+
561+ etag = reply . response [ :headers ] [ 'etag' ]
562+ assert etag , 'Server did not return an ETag header on create'
563+
564+ # Modify the patient
565+ @ifmatch_patient . name . first . given = [ 'UpdatedGiven' ]
566+
567+ # Build a transaction with PUT + matching IfMatch
568+ @client . begin_transaction
569+ entry = @client . add_transaction_request ( 'PUT' , "Patient/#{ @ifmatch_patient . id } " , @ifmatch_patient )
570+ entry . request . ifMatch = etag
571+ reply = @client . end_transaction
572+
573+ assert ( ( ( 200 ..299 ) . include? ( reply . code ) ) , "Transaction with matching IfMatch should succeed, got: #{ reply . code } " )
574+ assert_bundle_response ( reply )
575+ end
576+
577+ # Transaction PUT with non-matching IfMatch should fail
578+ test 'XFER21' , 'Transaction PUT with non-matching IfMatch should fail' do
579+ metadata {
580+ links "#{ REST_SPEC_LINK } #transaction"
581+ links "#{ BASE_SPEC_LINK } /patient.html"
582+ requires resource : 'Patient' , methods : [ 'create' , 'update' ]
583+ requires resource : nil , methods : [ 'transaction-system' ]
584+ validates resource : 'Patient' , methods : [ 'update' ]
585+ validates resource : nil , methods : [ 'transaction-system' ]
586+ }
587+
588+ # Create a Patient
589+ @ifmatch_patient_2 = ResourceGenerator . minimal_patient ( "#{ Time . now . to_i } " , 'IfMatch2' , version_namespace )
590+ reply = @client . create @ifmatch_patient_2
591+ assert_response_ok ( reply )
592+ @ifmatch_patient_2 . id = ( reply . resource . try ( :id ) || reply . id )
593+
594+ # Modify the patient
595+ @ifmatch_patient_2 . name . first . given = [ 'UpdatedGiven' ]
596+
597+ # Build a transaction with PUT + non-matching IfMatch
598+ @client . begin_transaction
599+ entry = @client . add_transaction_request ( 'PUT' , "Patient/#{ @ifmatch_patient_2 . id } " , @ifmatch_patient_2 )
600+ entry . request . ifMatch = 'W/"non-matching-version"'
601+ reply = @client . end_transaction
602+
603+ assert ( ( ( 400 ..499 ) . include? ( reply . code ) ) , "Transaction with non-matching IfMatch should fail with 4xx, got: #{ reply . code } " )
604+ end
541605 end
542606 end
543607end
0 commit comments