@@ -125,22 +125,58 @@ def find_latest_pact_versions_for_provider provider_name, tag = nil
125
125
end
126
126
end
127
127
128
- def find_wip_pact_versions_for_provider provider_name , provider_tags = [ ] , options = { }
129
- return [ ] if provider_tags . empty?
128
+ # To find the work in progress pacts for this verification execution:
129
+ # For each provider tag that will be applied to this verification result (usually there will just be one, but
130
+ # we have to allow for multiple tags),
131
+ # find the head pacts (the pacts that are the latest for their tag) that have been successfully
132
+ # verified against the provider tag.
133
+ # Then, find all the head pacts, and remove the ones that have been successfully verified by ALL
134
+ # of the provider tags supplied.
135
+ # Then, for all of the head pacts that are remaining (these are the WIP ones) work out which
136
+ # provider tags they are pending for.
137
+ # Don't include pact publications that were created
138
+ def find_wip_pact_versions_for_provider provider_name , provider_tags_names = [ ] , options = { }
139
+ return [ ] if provider_tags_names . empty?
140
+
141
+ provider = pacticipant_repository . find_by_name ( provider_name )
142
+
143
+ # Hash of provider tag names => list of head pacts
144
+ successfully_verified_head_pacts_for_provider_tags = find_successfully_verified_head_pacts_by_provider_tag ( provider_name , provider_tags_names , options )
145
+ successfully_verified_head_pact_publication_ids_for_each_provider_tag = successfully_verified_head_pacts_for_provider_tags . each_with_object ( { } ) do | ( provider_tag_name , head_pacts ) , hash |
146
+ hash [ provider_tag_name ] = head_pacts . collect ( &:id )
147
+ end
130
148
131
- # Hash of provider tag names => list of pact_publication_ids
132
- successfully_verified_head_pact_publication_ids_for_each_provider_tag = find_successfully_verified_head_pacts_by_provider_tag ( provider_name , provider_tags , options )
149
+ # list of pact_publication_ids that are NOT work in progress
150
+ head_pact_publication_ids_successully_verified_by_all_provider_tags = successfully_verified_head_pacts_for_provider_tags . values . collect { | head_pacts | head_pacts . collect ( & :id ) } . reduce ( :& )
133
151
134
152
pact_publication_ids = find_head_pacts_that_have_not_been_successfully_verified_by_all_provider_tags (
135
153
provider_name ,
136
- successfully_verified_head_pact_publication_ids_for_each_provider_tag . values . reduce ( :& ) ,
154
+ head_pact_publication_ids_successully_verified_by_all_provider_tags ,
137
155
options )
138
156
139
- pacts = AllPactPublications . where ( id : pact_publication_ids ) . order_ignore_case ( :consumer_name ) . order_append ( :consumer_version_order ) . collect ( &:to_domain )
157
+ pacts = AllPactPublications . where ( id : pact_publication_ids ) . order_ignore_case ( :consumer_name ) . order_append ( :consumer_version_order )
158
+
159
+ # The first instance (by date) of each provider tag with that name
160
+ # Note: created_at is coming back as a string
161
+ provider_tag_collection = PactBroker ::Domain ::Tag
162
+ . select_group ( Sequel [ :tags ] [ :name ] , Sequel [ :pacticipant_id ] )
163
+ . select_append ( Sequel . function ( :min , Sequel [ :tags ] [ :created_at ] ) . as ( :created_at ) )
164
+ . distinct
165
+ . join ( :versions , { Sequel [ :tags ] [ :version_id ] => Sequel [ :versions ] [ :id ] } )
166
+ . where ( pacticipant_id : provider . id )
167
+ . where ( name : provider_tags_names )
168
+ . all
169
+
140
170
pacts . collect do | pact |
141
- pending_tags = find_provider_tags_for_which_pact_publication_id_is_pending ( pact . id , successfully_verified_head_pact_publication_ids_for_each_provider_tag )
142
- VerifiablePact . new ( pact , true , pending_tags , [ ] , pact . consumer_version_tag_names , nil , true )
143
- end
171
+ pending_tag_names = find_provider_tags_for_which_pact_publication_id_is_pending ( pact , successfully_verified_head_pact_publication_ids_for_each_provider_tag )
172
+ pre_existing_tag_names = find_provider_tag_names_that_were_first_used_before_pact_published ( pact , provider_tag_collection )
173
+
174
+ pre_existing_pending_tags = pending_tag_names & pre_existing_tag_names
175
+
176
+ if pre_existing_pending_tags . any?
177
+ VerifiablePact . new ( pact . to_domain , true , pre_existing_pending_tags , [ ] , pact . head_tag_names , nil , true )
178
+ end
179
+ end . compact
144
180
end
145
181
146
182
def find_pact_versions_for_provider provider_name , tag = nil
@@ -333,13 +369,17 @@ def find_all_database_versions_between(consumer_name, options, base_class = Late
333
369
query
334
370
end
335
371
336
- def find_provider_tags_for_which_pact_publication_id_is_pending ( pact_publication_id , successfully_verified_head_pact_publication_ids_for_each_provider_tag )
372
+ def find_provider_tags_for_which_pact_publication_id_is_pending ( pact_publication , successfully_verified_head_pact_publication_ids_for_each_provider_tag )
337
373
successfully_verified_head_pact_publication_ids_for_each_provider_tag
338
- . select do | provider_tag , pact_publication_ids |
339
- !pact_publication_ids . include? ( pact_publication_id )
374
+ . select do | _ , pact_publication_ids |
375
+ !pact_publication_ids . include? ( pact_publication . id )
340
376
end . keys
341
377
end
342
378
379
+ def find_provider_tag_names_that_were_first_used_before_pact_published ( pact_publication , provider_tag_collection )
380
+ provider_tag_collection . select { | tag | DateTime . parse ( tag . created_at ) < pact_publication . created_at } . collect ( &:name )
381
+ end
382
+
343
383
def find_head_pacts_that_have_not_been_successfully_verified_by_all_provider_tags ( provider_name , pact_publication_ids_successfully_verified_by_all_provider_tags , options )
344
384
# Exclude the head pacts that have been successfully verified by all the specified provider tags
345
385
pact_publication_ids = LatestTaggedPactPublications
@@ -349,18 +389,20 @@ def find_head_pacts_that_have_not_been_successfully_verified_by_all_provider_tag
349
389
. select_for_subquery ( :id )
350
390
end
351
391
392
+ # Find the head pacts that have been successfully verified by a provider version with the specified tags
393
+ # Returns a Hash of provider_tag => LatestTaggedPactPublications with only id and tag_name populated
352
394
def find_successfully_verified_head_pacts_by_provider_tag ( provider_name , provider_tags , options )
353
- provider_tags . compact . each_with_object ( { } ) do | provider_tag , tag_to_ids_hash |
354
- ids = LatestTaggedPactPublications
395
+ provider_tags . compact . each_with_object ( { } ) do | provider_tag , hash |
396
+ head_pacts = LatestTaggedPactPublications
355
397
. join ( :verifications , { pact_version_id : :pact_version_id } )
356
398
. join ( :tags , { Sequel [ :verifications ] [ :provider_version_id ] => Sequel [ :provider_tags ] [ :version_id ] } , { table_alias : :provider_tags } )
357
399
. where ( Sequel [ :provider_tags ] [ :name ] => provider_tag )
358
400
. provider ( provider_name )
359
401
. where ( Sequel [ :verifications ] [ :success ] => true )
360
- . where ( Sequel . lit ( 'latest_tagged_pact_publications.created_at > ?' , options . fetch ( :include_wip_pacts_since ) ) )
361
- . select ( Sequel [ :latest_tagged_pact_publications ] [ :id ] . as ( :id ) )
362
- . collect ( & :id )
363
- tag_to_ids_hash [ provider_tag ] = ids
402
+ . or ( Sequel . lit ( 'latest_tagged_pact_publications.created_at < ?' , options . fetch ( :include_wip_pacts_since ) ) )
403
+ . select ( Sequel [ :latest_tagged_pact_publications ] [ :id ] . as ( :id ) , :tag_name )
404
+ . all
405
+ hash [ provider_tag ] = head_pacts
364
406
end
365
407
end
366
408
end
0 commit comments