From 5ebd2467cb6e388eb606e56f9ccc3c8a4a5a8709 Mon Sep 17 00:00:00 2001 From: Stuart McHattie Date: Fri, 13 Sep 2024 11:35:16 +0100 Subject: [PATCH 1/9] Switch SpecificTubeCreation requests to go through API v2 --- .../labware_creators/plate_split_to_tube_racks.rb | 11 +++++------ app/models/labware_creators/pooled_tubes_base.rb | 11 +++++------ app/models/labware_creators/pooled_tubes_by_sample.rb | 11 +++++------ .../pooled_tubes_by_submission_with_phi_x.rb | 9 ++++----- .../pooled_tubes_from_whole_plates.rb | 11 +++++------ .../sequencescape/api/v2/specific_tube_creation.rb | 8 ++++++++ 6 files changed, 32 insertions(+), 29 deletions(-) create mode 100644 app/sequencescape/sequencescape/api/v2/specific_tube_creation.rb diff --git a/app/models/labware_creators/plate_split_to_tube_racks.rb b/app/models/labware_creators/plate_split_to_tube_racks.rb index da3e2098d..f869083cd 100644 --- a/app/models/labware_creators/plate_split_to_tube_racks.rb +++ b/app/models/labware_creators/plate_split_to_tube_racks.rb @@ -405,13 +405,12 @@ def parent_wells_for_contingency # @param tube_attributes [Hash] A hash of attributes to use for the created tubes. # @return [Hash] A hash of the created tubes indexed by name. def create_tubes(tube_purpose_uuid, number_of_tubes, tube_attributes) - api - .specific_tube_creation + Sequencescape::Api::V2::SpecificTubeCreation .create!( - user: user_uuid, - parent: parent_uuid, - child_purposes: [tube_purpose_uuid] * number_of_tubes, - tube_attributes: tube_attributes + child_purpose_uuids: [tube_purpose_uuid] * number_of_tubes, + parent_uuids: [parent_uuid], + tube_attributes: tube_attributes, + user_uuid: user_uuid ) .children .index_by(&:name) diff --git a/app/models/labware_creators/pooled_tubes_base.rb b/app/models/labware_creators/pooled_tubes_base.rb index f55e8bc3a..e8ae7a7e2 100644 --- a/app/models/labware_creators/pooled_tubes_base.rb +++ b/app/models/labware_creators/pooled_tubes_base.rb @@ -20,13 +20,12 @@ def create_labware! end def create_child_stock_tubes - api - .specific_tube_creation + Sequencescape::Api::V2::SpecificTubeCreation .create!( - user: user_uuid, - parent: parent_uuid, - child_purposes: [purpose_uuid] * pool_uuids.length, - tube_attributes: tube_attributes + child_purpose_uuids: [purpose_uuid] * pool_uuids.length, + parent_uuids: [parent_uuid], + tube_attributes: tube_attributes, + user_uuid: user_uuid ) .children .index_by(&:name) diff --git a/app/models/labware_creators/pooled_tubes_by_sample.rb b/app/models/labware_creators/pooled_tubes_by_sample.rb index 29121318a..6504e0c76 100644 --- a/app/models/labware_creators/pooled_tubes_by_sample.rb +++ b/app/models/labware_creators/pooled_tubes_by_sample.rb @@ -47,13 +47,12 @@ def parent_v1 # Have we made this class so cardinal-specific (e.g. lookup of ancestor vac tubes) that it cannot be re-used? def create_child_stock_tubes - api - .specific_tube_creation + Sequencescape::Api::V2::SpecificTubeCreation .create!( - user: user_uuid, - parent: parent_uuid, - child_purposes: [purpose_uuid] * pool_uuids.length, - tube_attributes: tube_attributes + child_purpose_uuids: [purpose_uuid] * pool_uuids.length, + parent_uuids: [parent_uuid], + tube_attributes: tube_attributes, + user_uuid: user_uuid ) .children .index_by(&:name) diff --git a/app/models/labware_creators/pooled_tubes_by_submission_with_phi_x.rb b/app/models/labware_creators/pooled_tubes_by_submission_with_phi_x.rb index f0d6103f0..50d7a916d 100644 --- a/app/models/labware_creators/pooled_tubes_by_submission_with_phi_x.rb +++ b/app/models/labware_creators/pooled_tubes_by_submission_with_phi_x.rb @@ -15,13 +15,12 @@ class PooledTubesBySubmissionWithPhiX < PooledTubesBySubmission attr_accessor :spikedbuffer_tube_barcode def create_child_stock_tubes - api - .specific_tube_creation + Sequencescape::Api::V2::SpecificTubeCreation .create!( - user: user_uuid, - parents: parents, child_purposes: [purpose_uuid] * pool_uuids.length, - tube_attributes: tube_attributes + parent_uuids: parents, + tube_attributes: tube_attributes, + user_uuid: user_uuid ) .children .index_by(&:name) diff --git a/app/models/labware_creators/pooled_tubes_from_whole_plates.rb b/app/models/labware_creators/pooled_tubes_from_whole_plates.rb index 41a09f490..33f9034ca 100644 --- a/app/models/labware_creators/pooled_tubes_from_whole_plates.rb +++ b/app/models/labware_creators/pooled_tubes_from_whole_plates.rb @@ -17,13 +17,12 @@ def create_labware! # Create a single tube # TODO: This should link to multiple parents in production @child = - api - .specific_tube_creation + Sequencescape::Api::V2::SpecificTubeCreation .create!( - user: user_uuid, - parent: parents.first.uuid, - child_purposes: [purpose_uuid], - tube_attributes: [{ name: "#{stock_plate_barcode}+" }] + child_purpose_uuids: [purpose_uuid], + parent_uuids: [parents.first.uuid], + tube_attributes: [{ name: "#{stock_plate_barcode}+" }], + user_uuid: user_uuid ) .children .first diff --git a/app/sequencescape/sequencescape/api/v2/specific_tube_creation.rb b/app/sequencescape/sequencescape/api/v2/specific_tube_creation.rb new file mode 100644 index 000000000..035a70c5a --- /dev/null +++ b/app/sequencescape/sequencescape/api/v2/specific_tube_creation.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +# Represents a specific tube creation in Limber via the Sequencescape API +class Sequencescape::Api::V2::SpecificTubeCreation < Sequencescape::Api::V2::Base + has_many :children, class_name: 'Sequencescape::Api::V2::Tube' + has_many :parents, class_name: 'Sequencescape::Api::V2::Asset' + has_one :user, class_name: 'Sequencescape::Api::V2::User' +end From 1860cce4e0dcc49e02bf84dc8b67c6a11ac3355e Mon Sep 17 00:00:00 2001 From: Stuart McHattie Date: Mon, 16 Sep 2024 16:58:38 +0100 Subject: [PATCH 2/9] Fix tests for pooling multiple plates into one tube --- .../pooled_tubes_from_whole_plates.rb | 6 ++- ...ling_multiple_plates_into_one_tube_spec.rb | 51 +++++++------------ 2 files changed, 24 insertions(+), 33 deletions(-) diff --git a/app/models/labware_creators/pooled_tubes_from_whole_plates.rb b/app/models/labware_creators/pooled_tubes_from_whole_plates.rb index 33f9034ca..937e23569 100644 --- a/app/models/labware_creators/pooled_tubes_from_whole_plates.rb +++ b/app/models/labware_creators/pooled_tubes_from_whole_plates.rb @@ -15,7 +15,7 @@ class PooledTubesFromWholePlates < Base def create_labware! # Create a single tube - # TODO: This should link to multiple parents in production + # TODO: {Y24-190} See if we can do all the transfers as part of the SpecificTubeCreation instead of separately. @child = Sequencescape::Api::V2::SpecificTubeCreation .create!( @@ -39,6 +39,10 @@ def stock_plate_barcode "#{parents.first.stock_plate.barcode.prefix}#{parents.first.stock_plate.barcode.number}" end + def redirection_target + TubeProxy.new(@child.uuid) + end + # TODO: This should probably be asynchronous def available_plates @search_options = OngoingPlate.new(purposes: [parent.plate_purpose.uuid], include_used: false, states: ['passed']) diff --git a/spec/features/pooling_multiple_plates_into_one_tube_spec.rb b/spec/features/pooling_multiple_plates_into_one_tube_spec.rb index 73937a3d7..1e2487b1a 100644 --- a/spec/features/pooling_multiple_plates_into_one_tube_spec.rb +++ b/spec/features/pooling_multiple_plates_into_one_tube_spec.rb @@ -57,32 +57,13 @@ end let(:example_plate_3_listed) { associated(*example_plate3_args) } - let(:child_tube_uuid) { 'tube-0' } - let(:child_tube) do - create :v2_tube, purpose_uuid: 'child-purpose-0', purpose_name: 'Pool tube', uuid: child_tube_uuid - end + let(:child_tube) { create :v2_tube, purpose_uuid: 'child-purpose-0', purpose_name: 'Pool tube' } - let(:tube_creation_request_uuid) { SecureRandom.uuid } - - let!(:tube_creation_request) do - # TODO: In reality we want to link in all four parents. - stub_api_post( - 'specific_tube_creations', - payload: { - specific_tube_creation: { - user: user_uuid, - parent: plate_uuid, - child_purposes: ['child-purpose-0'], - tube_attributes: [{ name: 'DN2+' }] - } - }, - body: json(:specific_tube_creation, uuid: tube_creation_request_uuid, children_count: 1) - ) - end + let(:specific_tube_creation) do + response = double + allow(response).to receive(:children).and_return([child_tube]) - # Find out what tubes we've just made! - let!(:tube_creation_children_request) do - stub_api_get(tube_creation_request_uuid, 'children', body: json(:tube_collection, names: ['DN1+'])) + response end # Used to fetch the pools. This is the kind of thing we could pass through from a custom form @@ -119,8 +100,6 @@ stub_v2_plate(example_plate_new_api) - stub_v2_plate(example_plate_new_api) - stub_api_get(plate_uuid, body: example_plate) stub_api_get(plate_uuid, 'wells', body: well_set_a) @@ -132,13 +111,25 @@ scenario 'creates multiple plates' do stub_v2_plate(example_plate_2) + expect_api_v2_posts( + 'SpecificTubeCreation', + [ + { + child_purpose_uuids: ['child-purpose-0'], + parent_uuids: [plate_uuid], + tube_attributes: [{ name: 'DN2+' }], + user_uuid: user_uuid + } + ], + [specific_tube_creation] + ) expect_api_v2_posts( 'Transfer', [plate_uuid, plate_uuid_2].map do |source_uuid| { user_uuid: user_uuid, source_uuid: source_uuid, - destination_uuid: 'tube-0', + destination_uuid: child_tube.uuid, transfer_template_uuid: 'whole-plate-to-tube' } end @@ -156,15 +147,11 @@ click_on('Make Pool') expect(page).to have_text('New empty labware added to the system') expect(page).to have_text('Pool tube') - - # This isn't strictly speaking correct to test. But there isn't a great way - # of confirming that the right information got passed to the back end otherwise. - # (Although you expect it to fail on an incorrect request) - expect(tube_creation_request).to have_been_made end scenario 'detects tag clash' do stub_v2_plate(example_plate_3) + fill_in_swipecard_and_barcode(user_swipecard, plate_barcode_1) plate_title = find('#plate-title') expect(plate_title).to have_text('example-purpose') From 1d5fc5f29be24452fdfa28cc7da04732a5fac702 Mon Sep 17 00:00:00 2001 From: Stuart McHattie Date: Mon, 16 Sep 2024 17:02:21 +0100 Subject: [PATCH 3/9] Fix test for pooled tubes from whole plates --- .../pooled_tubes_from_whole_plates_spec.rb | 49 +++++++------------ 1 file changed, 19 insertions(+), 30 deletions(-) diff --git a/spec/models/labware_creators/pooled_tubes_from_whole_plates_spec.rb b/spec/models/labware_creators/pooled_tubes_from_whole_plates_spec.rb index e5ce80273..993edb48b 100644 --- a/spec/models/labware_creators/pooled_tubes_from_whole_plates_spec.rb +++ b/spec/models/labware_creators/pooled_tubes_from_whole_plates_spec.rb @@ -53,54 +53,43 @@ { user_uuid: user_uuid, purpose_uuid: purpose_uuid, parent_uuid: parent_uuid, barcodes: barcodes } end - let(:tube_creation_request_uuid) { SecureRandom.uuid } + let(:child_tube) { create :v2_tube } + let(:specific_tube_creation) do + response = double + allow(response).to receive(:children).and_return([child_tube]) - let(:tube_creation_request) do - # TODO: In reality we want to link in all four parents. - stub_api_post( - 'specific_tube_creations', - payload: { - specific_tube_creation: { - user: user_uuid, - parent: parent_uuid, - child_purposes: [purpose_uuid], - tube_attributes: [{ name: 'DN2+' }] - } - }, - body: json(:specific_tube_creation, uuid: tube_creation_request_uuid, children_count: 1) - ) + response end - # Find out what tubes we've just made! - let(:tube_creation_children_request) do - stub_api_get(tube_creation_request_uuid, 'children', body: json(:tube_collection, names: ['DN2+'])) - end - - # Used to fetch the pools. This is the kind of thing we could pass through from a custom form - let(:stub_barcode_searches) { stub_asset_search(barcodes, [parent, parent2, parent3, parent4]) } - - before do - stub_barcode_searches - tube_creation_children_request - tube_creation_request - end + before { stub_asset_search(barcodes, [parent, parent2, parent3, parent4]) } context 'with compatible plates' do it 'pools from all the plates' do + expect_api_v2_posts( + 'SpecificTubeCreation', + [ + { + child_purpose_uuids: [purpose_uuid], + parent_uuids: [parent_uuid], + tube_attributes: [{ name: 'DN2+' }], + user_uuid: user_uuid + } + ], + [specific_tube_creation] + ) expect_api_v2_posts( 'Transfer', [parent_uuid, parent2_uuid, parent3_uuid, parent4_uuid].map do |source_uuid| { user_uuid: user_uuid, source_uuid: source_uuid, - destination_uuid: 'tube-0', + destination_uuid: child_tube.uuid, transfer_template_uuid: 'whole-plate-to-tube' } end ) expect(subject.save!).to be_truthy - expect(tube_creation_request).to have_been_made.once end end end From a4a38082c09ab4cc636603e0e0b3460bc96503b7 Mon Sep 17 00:00:00 2001 From: Stuart McHattie Date: Tue, 17 Sep 2024 13:24:13 +0100 Subject: [PATCH 4/9] Fix tests for plate_split_to_tube_racks --- .../plate_split_to_tube_racks_spec.rb | 380 +++++++----------- 1 file changed, 144 insertions(+), 236 deletions(-) diff --git a/spec/models/labware_creators/plate_split_to_tube_racks_spec.rb b/spec/models/labware_creators/plate_split_to_tube_racks_spec.rb index 4ab8c6154..040feb362 100644 --- a/spec/models/labware_creators/plate_split_to_tube_racks_spec.rb +++ b/spec/models/labware_creators/plate_split_to_tube_racks_spec.rb @@ -201,6 +201,56 @@ ) end + def prepare_created_child_tubes(tube_attributes) + # Prepare child tubes and stub their lookups. + child_tubes = + tube_attributes.map { |attrs| create(:v2_tube, name: attrs[:name], foreign_barcode: attrs[:foreign_barcode]) } + child_tubes.each { |child_tube| stub_v2_labware(child_tube) } + + child_tubes + end + + def expect_specific_tube_creation(child_purpose_uuid, child_tubes) + # Create a mock for the specific tube creation. + specific_tube_creation = double + allow(specific_tube_creation).to receive(:children).and_return(child_tubes) + + # Expect the post request and return the mock. + expect_api_v2_posts( + 'SpecificTubeCreation', + [ + { + child_purpose_uuids: [child_purpose_uuid] * child_tubes.size, + parent_uuids: [parent_uuid], + tube_attributes: child_tubes.map { |tube| { name: tube.name, foreign_barcode: tube.foreign_barcode } }, + user_uuid: user_uuid + } + ], + [specific_tube_creation] + ) + end + + # tubes_hash should be a hash with tube rack barcodes as keys and arrays of tubes as values. + def expect_custom_metadatum_collection_posts(tubes_hash) + # Prepare the expected call arguments. + expected_call_args = + tubes_hash.flat_map do |tube_rack_barcode, tubes| + tubes.map do |tube| + metadata = { + user_id: user.id, + asset_id: tube.id, + metadata: { + tube_rack_barcode: tube_rack_barcode, + tube_rack_position: tube.name.split(':').last + } + } + end + end + + # Expect the post requests. + expect_api_v2_posts('CustomMetadatumCollection', expected_call_args) + end + before do # need both child tubes to have a purpose config here create( @@ -661,48 +711,16 @@ ) end - # stub the contingency tube creation - let!(:stub_contingency_tube_creation_request_uuid) { SecureRandom.uuid } - let!(:stub_contingency_tube_creation_request) do - stub_api_post( - 'specific_tube_creations', - payload: { - specific_tube_creation: { - child_purposes: [ - child_contingency_tube_purpose_uuid, - child_contingency_tube_purpose_uuid, - child_contingency_tube_purpose_uuid - ], - tube_attributes: [ - # sample 1 from well A2 to contingency tube 1 in A1 - { name: 'SPR:NT1O:A1', foreign_barcode: 'FX00000011' }, - # sample 2 from well B2 to contingency tube 2 in B1 - { name: 'SPR:NT2P:B1', foreign_barcode: 'FX00000012' }, - # sample 1 from well A3 to contingency tube 3 in C1 - { name: 'SPR:NT1O:C1', foreign_barcode: 'FX00000013' } - ], - user: user_uuid, - parent: parent_uuid - } - }, - body: json(:specific_tube_creation, uuid: stub_contingency_tube_creation_request_uuid, children_count: 3) - ) - end - - # stub what contingency tubes were just made - let!(:stub_contingency_tube_creation_children_request) do - stub_api_get( - stub_contingency_tube_creation_request_uuid, - 'children', - body: - json( - :tube_collection_with_barcodes_specified, - size: 3, - names: %w[SPR:NT1O:A1 SPR:NT2P:B1 SPR:NT1O:C1], - barcode_prefix: 'FX', - barcode_numbers: [11, 12, 13], - uuid_index_offset: 2 - ) + let(:contingency_tubes) do + prepare_created_child_tubes( + [ + # sample 1 from well A2 to contingency tube 1 in A1 + { name: 'SPR:NT1O:A1', foreign_barcode: 'FX00000011' }, + # sample 2 from well B2 to contingency tube 2 in B1 + { name: 'SPR:NT2P:B1', foreign_barcode: 'FX00000012' }, + # sample 1 from well A3 to contingency tube 3 in C1 + { name: 'SPR:NT1O:C1', foreign_barcode: 'FX00000013' } + ] ) end @@ -742,6 +760,17 @@ content end + let(:sequencing_tubes) do + prepare_created_child_tubes( + [ + # sample 1 in well A1 to seq tube 1 in A1 + { name: 'SEQ:NT1O:A1', foreign_barcode: 'FX00000001' }, + # sample 2 in well B1 to seq tube 2 in B1 + { name: 'SEQ:NT2P:B1', foreign_barcode: 'FX00000002' } + ] + ) + end + # stub the sequencing file upload let!(:stub_sequencing_file_upload) do stub_request(:post, api_url_for(parent_uuid, 'qc_files')) @@ -761,58 +790,20 @@ ) end - # stub the sequencing tube creation - let!(:stub_sequencing_tube_creation_request_uuid) { SecureRandom.uuid } - let!(:stub_sequencing_tube_creation_request) do - stub_api_post( - 'specific_tube_creations', - payload: { - specific_tube_creation: { - child_purposes: [child_sequencing_tube_purpose_uuid, child_sequencing_tube_purpose_uuid], - tube_attributes: [ - # sample 1 in well A1 to seq tube 1 in A1 - { name: 'SEQ:NT1O:A1', foreign_barcode: 'FX00000001' }, - # sample 2 in well B1 to seq tube 2 in B1 - { name: 'SEQ:NT2P:B1', foreign_barcode: 'FX00000002' } - ], - user: user_uuid, - parent: parent_uuid - } - }, - body: json(:specific_tube_creation, uuid: stub_sequencing_tube_creation_request_uuid, children_count: 2) - ) - end - - # stub what sequencing tubes were just made - let!(:stub_sequencing_tube_creation_children_request) do - stub_api_get( - stub_sequencing_tube_creation_request_uuid, - 'children', - body: - json( - :tube_collection_with_barcodes_specified, - size: 2, - names: %w[SEQ:NT1O:A1 SEQ:NT2P:B1], - barcode_prefix: 'FX', - barcode_numbers: [1, 2] - ) - ) - end - # stub the transfer creation let!(:stub_transfer_creation_request) do + parent_wells = [parent_well_a1, parent_well_b1, parent_well_a2, parent_well_b2, parent_well_a3] + target_tubes = sequencing_tubes + contingency_tubes + transfer_requests = + parent_wells.map.with_index do |parent_well, index| + { 'submission_id' => '2', 'source_asset' => parent_well.uuid, 'target_asset' => target_tubes[index].uuid } + end stub_api_post( 'transfer_request_collections', payload: { transfer_request_collection: { user: user_uuid, - transfer_requests: [ - { 'submission_id' => '2', 'source_asset' => parent_well_a1.uuid, 'target_asset' => 'tube-0' }, - { 'submission_id' => '2', 'source_asset' => parent_well_b1.uuid, 'target_asset' => 'tube-1' }, - { 'submission_id' => '2', 'source_asset' => parent_well_a2.uuid, 'target_asset' => 'tube-2' }, - { 'submission_id' => '2', 'source_asset' => parent_well_b2.uuid, 'target_asset' => 'tube-3' }, - { 'submission_id' => '2', 'source_asset' => parent_well_a3.uuid, 'target_asset' => 'tube-4' } - ] + transfer_requests: transfer_requests } }, body: '{}' @@ -860,17 +851,17 @@ end it 'creates the child tubes' do - expect_api_v2_posts( - 'CustomMetadatumCollection', - [tube_1_create_args, tube_2_create_args, tube_3_create_args, tube_4_create_args, tube_5_create_args] + expect_specific_tube_creation(child_sequencing_tube_purpose_uuid, sequencing_tubes) + expect_specific_tube_creation(child_contingency_tube_purpose_uuid, contingency_tubes) + + expect_custom_metadatum_collection_posts( + { 'TR00000001' => sequencing_tubes, 'TR00000002' => contingency_tubes } ) expect(subject.valid?).to be_truthy expect(subject.save).to be_truthy expect(stub_sequencing_file_upload).to have_been_made.once - expect(stub_sequencing_tube_creation_request).to have_been_made.once expect(stub_contingency_file_upload).to have_been_made.once - expect(stub_contingency_tube_creation_request).to have_been_made.once expect(stub_transfer_creation_request).to have_been_made.once end @@ -880,94 +871,20 @@ create(:v2_well, location: 'A1', aliquots: [parent_aliquot_sample1_aliquot1], state: 'failed') end - # as A1 is failed order of samples is changed - let!(:stub_sequencing_tube_creation_request) do - stub_api_post( - 'specific_tube_creations', - payload: { - specific_tube_creation: { - child_purposes: [child_sequencing_tube_purpose_uuid, child_sequencing_tube_purpose_uuid], - tube_attributes: [ - # sample 2 in well B1 to seq tube 1 in A1 - { name: 'SEQ:NT2P:A1', foreign_barcode: 'FX00000001' }, - # sample 1 in well A2 to seq tube 2 in B1 - { name: 'SEQ:NT1O:B1', foreign_barcode: 'FX00000002' } - ], - user: user_uuid, - parent: parent_uuid - } - }, - body: json(:specific_tube_creation, uuid: stub_sequencing_tube_creation_request_uuid, children_count: 2) - ) - end - - # stub what sequencing tubes were just made (order changed) - let!(:stub_sequencing_tube_creation_children_request) do - stub_api_get( - stub_sequencing_tube_creation_request_uuid, - 'children', - body: - json( - :tube_collection_with_barcodes_specified, - size: 2, - names: %w[SEQ:NT2P:A1 SEQ:NT1O:B1], - barcode_prefix: 'FX', - barcode_numbers: [1, 2] - ) - ) - end - - # only 2 contingency tubes will be needed - let!(:stub_contingency_tube_creation_request) do - stub_api_post( - 'specific_tube_creations', - payload: { - specific_tube_creation: { - child_purposes: [child_contingency_tube_purpose_uuid, child_contingency_tube_purpose_uuid], - tube_attributes: [ - # sample 2 from well B2 to contingency tube 1 in A1 - { name: 'SPR:NT2P:A1', foreign_barcode: 'FX00000011' }, - # sample 1 from well A3 to contingency tube 2 in B1 - { name: 'SPR:NT1O:B1', foreign_barcode: 'FX00000012' } - ], - user: user_uuid, - parent: parent_uuid - } - }, - body: json(:specific_tube_creation, uuid: stub_contingency_tube_creation_request_uuid, children_count: 3) - ) - end - - # stub what contingency tubes were just made (just 2) - let!(:stub_contingency_tube_creation_children_request) do - stub_api_get( - stub_contingency_tube_creation_request_uuid, - 'children', - body: - json( - :tube_collection_with_barcodes_specified, - size: 2, - names: %w[SPR:NT2P:A1 SPR:NT1O:B1], - barcode_prefix: 'FX', - barcode_numbers: [11, 12], - uuid_index_offset: 2 - ) - ) - end - # one fewer transfer request let!(:stub_transfer_creation_request) do + parent_wells = [parent_well_b1, parent_well_a2, parent_well_b2, parent_well_a3] + target_tubes = sequencing_tubes + contingency_tubes + transfer_requests = + parent_wells.map.with_index do |parent_well, index| + { 'submission_id' => '2', 'source_asset' => parent_well.uuid, 'target_asset' => target_tubes[index].uuid } + end stub_api_post( 'transfer_request_collections', payload: { transfer_request_collection: { user: user_uuid, - transfer_requests: [ - { 'submission_id' => '2', 'source_asset' => parent_well_b1.uuid, 'target_asset' => 'tube-0' }, - { 'submission_id' => '2', 'source_asset' => parent_well_a2.uuid, 'target_asset' => 'tube-1' }, - { 'submission_id' => '2', 'source_asset' => parent_well_b2.uuid, 'target_asset' => 'tube-2' }, - { 'submission_id' => '2', 'source_asset' => parent_well_a3.uuid, 'target_asset' => 'tube-3' } - ] + transfer_requests: transfer_requests } }, body: '{}' @@ -981,6 +898,28 @@ ) end + let(:sequencing_tubes) do + prepare_created_child_tubes( + [ + # sample 2 in well B1 to seq tube 1 in A1 + { name: 'SEQ:NT2P:A1', foreign_barcode: 'FX00000001' }, + # sample 1 in well A2 to seq tube 2 in B1 + { name: 'SEQ:NT1O:B1', foreign_barcode: 'FX00000002' } + ] + ) + end + + let(:contingency_tubes) do + prepare_created_child_tubes( + [ + # sample 2 from well B2 to contingency tube 1 in A1 + { name: 'SPR:NT2P:A1', foreign_barcode: 'FX00000011' }, + # sample 1 from well A3 to contingency tube 2 in B1 + { name: 'SPR:NT1O:B1', foreign_barcode: 'FX00000012' } + ] + ) + end + before do stub_get_labware_metadata(child_tube_1_v2.barcode.machine, child_tube_1_v1) stub_get_labware_metadata(child_tube_2_v2.barcode.machine, child_tube_2_v1) @@ -994,17 +933,17 @@ end it 'does not create a tube for the failed well' do - expect_api_v2_posts( - 'CustomMetadatumCollection', - [tube_1_create_args, tube_2_create_args, tube_3_create_args, tube_4_create_args] # no tube 5 + expect_specific_tube_creation(child_sequencing_tube_purpose_uuid, sequencing_tubes) + expect_specific_tube_creation(child_contingency_tube_purpose_uuid, contingency_tubes) + + expect_custom_metadatum_collection_posts( + { 'TR00000001' => sequencing_tubes, 'TR00000002' => contingency_tubes } ) expect(subject.valid?).to be_truthy expect(subject.save).to be_truthy expect(stub_sequencing_file_upload).to have_been_made.once - expect(stub_sequencing_tube_creation_request).to have_been_made.once expect(stub_contingency_file_upload).to have_been_made.once - expect(stub_contingency_tube_creation_request).to have_been_made.once expect(stub_transfer_creation_request).to have_been_made.once end end @@ -1090,69 +1029,40 @@ ) end - # stub the contingency tube creation - let!(:stub_contingency_tube_creation_request) do - stub_api_post( - 'specific_tube_creations', - payload: { - specific_tube_creation: { - child_purposes: [ - child_contingency_tube_purpose_uuid, - child_contingency_tube_purpose_uuid, - child_contingency_tube_purpose_uuid, - child_contingency_tube_purpose_uuid, - child_contingency_tube_purpose_uuid - ], - tube_attributes: [ - # sample 1 from well A1 to contingency tube 1 in A1 - { name: 'SPR:NT1O:A1', foreign_barcode: 'FX00000011' }, - # sample 2 from well B1 to contingency tube 2 in B1 - { name: 'SPR:NT2P:B1', foreign_barcode: 'FX00000012' }, - # sample 1 from well A2 to contingency tube 3 in C1 - { name: 'SPR:NT1O:C1', foreign_barcode: 'FX00000013' }, - # sample 2 from well B2 to contingency tube 4 in E1 (D1 set as NO READ) - { name: 'SPR:NT2P:E1', foreign_barcode: 'FX00000014' }, - # sample 1 from well A3 to contingency tube 5 in F1 - { name: 'SPR:NT1O:F1', foreign_barcode: 'FX00000015' } - ], - user: user_uuid, - parent: parent_uuid - } - }, - body: json(:specific_tube_creation, uuid: stub_contingency_tube_creation_request_uuid, children_count: 5) - ) - end - - # stub what contingency tubes were just made - let!(:stub_contingency_tube_creation_children_request) do - stub_api_get( - stub_contingency_tube_creation_request_uuid, - 'children', - body: - json( - :tube_collection_with_barcodes_specified, - size: 5, - names: %w[SPR:NT1O:A1 SPR:NT2P:B1 SPR:NT1O:C1 SPR:NT2P:E1 SPR:NT1O:F1], - barcode_prefix: 'FX', - barcode_numbers: [11, 12, 13, 14, 15] - ) + let(:contingency_tubes) do + prepare_created_child_tubes( + [ + # sample 1 from well A1 to contingency tube 1 in A1 + { name: 'SPR:NT1O:A1', foreign_barcode: 'FX00000011' }, + # sample 2 from well B1 to contingency tube 2 in B1 + { name: 'SPR:NT2P:B1', foreign_barcode: 'FX00000012' }, + # sample 1 from well A2 to contingency tube 3 in C1 + { name: 'SPR:NT1O:C1', foreign_barcode: 'FX00000013' }, + # sample 2 from well B2 to contingency tube 4 in E1 (D1 set as NO READ) + { name: 'SPR:NT2P:E1', foreign_barcode: 'FX00000014' }, + # sample 1 from well A3 to contingency tube 5 in F1 + { name: 'SPR:NT1O:F1', foreign_barcode: 'FX00000015' } + ] ) end # stub the transfer creation let!(:stub_transfer_creation_request) do + parent_wells = [parent_well_a1, parent_well_b1, parent_well_a2, parent_well_b2, parent_well_a3] + transfer_requests = + parent_wells.map.with_index do |parent_well, index| + { + 'submission_id' => '2', + 'source_asset' => parent_well.uuid, + 'target_asset' => contingency_tubes[index].uuid + } + end stub_api_post( 'transfer_request_collections', payload: { transfer_request_collection: { user: user_uuid, - transfer_requests: [ - { 'submission_id' => '2', 'source_asset' => parent_well_a1.uuid, 'target_asset' => 'tube-0' }, - { 'submission_id' => '2', 'source_asset' => parent_well_b1.uuid, 'target_asset' => 'tube-1' }, - { 'submission_id' => '2', 'source_asset' => parent_well_a2.uuid, 'target_asset' => 'tube-2' }, - { 'submission_id' => '2', 'source_asset' => parent_well_b2.uuid, 'target_asset' => 'tube-3' }, - { 'submission_id' => '2', 'source_asset' => parent_well_a3.uuid, 'target_asset' => 'tube-4' } - ] + transfer_requests: transfer_requests } }, body: '{}' @@ -1193,15 +1103,13 @@ end it 'creates the child tubes' do - expect_api_v2_posts( - 'CustomMetadatumCollection', - [tube_1_create_args, tube_2_create_args, tube_3_create_args, tube_4_create_args, tube_5_create_args] - ) + # Contingency tubes creation + expect_specific_tube_creation(child_contingency_tube_purpose_uuid, contingency_tubes) + expect_custom_metadatum_collection_posts({ 'TR00000002' => contingency_tubes }) expect(subject.valid?).to be_truthy expect(subject.save).to be_truthy expect(stub_contingency_file_upload).to have_been_made.once - expect(stub_contingency_tube_creation_request).to have_been_made.once expect(stub_transfer_creation_request).to have_been_made.once end end From 9ebf0823a185b37be58def6aaaed80fe4b356632 Mon Sep 17 00:00:00 2001 From: Stuart McHattie Date: Tue, 17 Sep 2024 13:34:33 +0100 Subject: [PATCH 5/9] Remove unneeded fixtures for child tubes --- .../plate_split_to_tube_racks_spec.rb | 245 +----------------- 1 file changed, 10 insertions(+), 235 deletions(-) diff --git a/spec/models/labware_creators/plate_split_to_tube_racks_spec.rb b/spec/models/labware_creators/plate_split_to_tube_racks_spec.rb index 040feb362..6fd9a237b 100644 --- a/spec/models/labware_creators/plate_split_to_tube_racks_spec.rb +++ b/spec/models/labware_creators/plate_split_to_tube_racks_spec.rb @@ -116,77 +116,6 @@ { user_uuid: user_uuid, purpose_uuid: child_sequencing_tube_purpose_uuid, parent_uuid: parent_uuid } end - # child tubes for lookup after creation - let(:child_tube_1_uuid) { SecureRandom.uuid } - let(:child_tube_1_aliquot) { create(:v2_aliquot, sample: sample1) } - let(:child_tube_1_v2) do - create( - :v2_stock_tube, - state: 'passed', - purpose_name: child_sequencing_tube_purpose_name, - aliquots: [child_tube_1_aliquot], - barcode_prefix: 'FX', - barcode_number: 1, - uuid: child_tube_1_uuid - ) - end - - let(:child_tube_2_uuid) { SecureRandom.uuid } - let(:child_tube_2_aliquot) { create(:v2_aliquot, sample: sample2) } - let(:child_tube_2_v2) do - create( - :v2_stock_tube, - state: 'passed', - purpose_name: child_sequencing_tube_purpose_name, - aliquots: [child_tube_2_aliquot], - barcode_prefix: 'FX', - barcode_number: 2, - uuid: child_tube_2_uuid - ) - end - - let(:child_tube_3_uuid) { SecureRandom.uuid } - let(:child_tube_3_aliquot) { create(:v2_aliquot, sample: sample1) } - let(:child_tube_3_v2) do - create( - :v2_stock_tube, - state: 'passed', - purpose_name: child_contingency_tube_purpose_name, - aliquots: [child_tube_3_aliquot], - barcode_prefix: 'FX', - barcode_number: 11, - uuid: child_tube_3_uuid - ) - end - - let(:child_tube_4_uuid) { SecureRandom.uuid } - let(:child_tube_4_aliquot) { create(:v2_aliquot, sample: sample1) } - let(:child_tube_4_v2) do - create( - :v2_stock_tube, - state: 'passed', - purpose_name: child_contingency_tube_purpose_name, - aliquots: [child_tube_4_aliquot], - barcode_prefix: 'FX', - barcode_number: 12, - uuid: child_tube_4_uuid - ) - end - - let(:child_tube_5_uuid) { SecureRandom.uuid } - let(:child_tube_5_aliquot) { create(:v2_aliquot, sample: sample2) } - let(:child_tube_5_v2) do - create( - :v2_stock_tube, - state: 'passed', - purpose_name: child_contingency_tube_purpose_name, - aliquots: [child_tube_5_aliquot], - barcode_prefix: 'FX', - barcode_number: 13, - uuid: child_tube_5_uuid - ) - end - let(:sequencing_file) do fixture_file_upload( 'spec/fixtures/files/scrna_core/scrna_core_sequencing_tube_rack_scan.csv', @@ -271,12 +200,14 @@ def expect_custom_metadatum_collection_posts(tubes_hash) stub_v2_tube(ancestor_tube_1_v2, stub_search: false) stub_v2_tube(ancestor_tube_2_v2, stub_search: false) - # child tube lookups - stub_v2_tube(child_tube_1_v2, stub_search: false) - stub_v2_tube(child_tube_2_v2, stub_search: false) - stub_v2_tube(child_tube_3_v2, stub_search: false) - stub_v2_tube(child_tube_4_v2, stub_search: false) - stub_v2_tube(child_tube_5_v2, stub_search: false) + # Block finding tubes by given barcodes. + allow(Sequencescape::Api::V2::Tube).to receive(:find_by).with(barcode: 'FX00000001').and_return(nil) + allow(Sequencescape::Api::V2::Tube).to receive(:find_by).with(barcode: 'FX00000002').and_return(nil) + allow(Sequencescape::Api::V2::Tube).to receive(:find_by).with(barcode: 'FX00000011').and_return(nil) + allow(Sequencescape::Api::V2::Tube).to receive(:find_by).with(barcode: 'FX00000012').and_return(nil) + allow(Sequencescape::Api::V2::Tube).to receive(:find_by).with(barcode: 'FX00000013').and_return(nil) + allow(Sequencescape::Api::V2::Tube).to receive(:find_by).with(barcode: 'FX00000014').and_return(nil) + allow(Sequencescape::Api::V2::Tube).to receive(:find_by).with(barcode: 'FX00000015').and_return(nil) end context 'on new' do @@ -423,13 +354,6 @@ def expect_custom_metadatum_collection_posts(tubes_hash) 'wells.aliquots,wells.aliquots.sample,wells.downstream_tubes,' \ 'wells.downstream_tubes.custom_metadatum_collection' ) - allow(Sequencescape::Api::V2::Tube).to receive(:find_by).with(barcode: 'FX00000001').and_return(nil) - allow(Sequencescape::Api::V2::Tube).to receive(:find_by).with(barcode: 'FX00000002').and_return(nil) - allow(Sequencescape::Api::V2::Tube).to receive(:find_by).with(barcode: 'FX00000011').and_return(nil) - allow(Sequencescape::Api::V2::Tube).to receive(:find_by).with(barcode: 'FX00000012').and_return(nil) - allow(Sequencescape::Api::V2::Tube).to receive(:find_by).with(barcode: 'FX00000013').and_return(nil) - allow(Sequencescape::Api::V2::Tube).to receive(:find_by).with(barcode: 'FX00000014').and_return(nil) - allow(Sequencescape::Api::V2::Tube).to receive(:find_by).with(barcode: 'FX00000015').and_return(nil) end context 'when files are not present' do @@ -548,13 +472,6 @@ def expect_custom_metadatum_collection_posts(tubes_hash) 'wells.aliquots,wells.aliquots.sample,wells.downstream_tubes,' \ 'wells.downstream_tubes.custom_metadatum_collection' ) - allow(Sequencescape::Api::V2::Tube).to receive(:find_by).with(barcode: 'FX00000001').and_return(nil) - allow(Sequencescape::Api::V2::Tube).to receive(:find_by).with(barcode: 'FX00000002').and_return(nil) - allow(Sequencescape::Api::V2::Tube).to receive(:find_by).with(barcode: 'FX00000011').and_return(nil) - allow(Sequencescape::Api::V2::Tube).to receive(:find_by).with(barcode: 'FX00000012').and_return(nil) - allow(Sequencescape::Api::V2::Tube).to receive(:find_by).with(barcode: 'FX00000013').and_return(nil) - allow(Sequencescape::Api::V2::Tube).to receive(:find_by).with(barcode: 'FX00000014').and_return(nil) - allow(Sequencescape::Api::V2::Tube).to receive(:find_by).with(barcode: 'FX00000015').and_return(nil) end context 'when files are not present' do @@ -733,13 +650,6 @@ def expect_custom_metadatum_collection_posts(tubes_hash) 'wells.downstream_tubes.custom_metadatum_collection' ) stub_api_get(parent_uuid, body: parent_v1) - allow(Sequencescape::Api::V2::Tube).to receive(:find_by).with(barcode: 'FX00000001').and_return(nil) - allow(Sequencescape::Api::V2::Tube).to receive(:find_by).with(barcode: 'FX00000002').and_return(nil) - allow(Sequencescape::Api::V2::Tube).to receive(:find_by).with(barcode: 'FX00000011').and_return(nil) - allow(Sequencescape::Api::V2::Tube).to receive(:find_by).with(barcode: 'FX00000012').and_return(nil) - allow(Sequencescape::Api::V2::Tube).to receive(:find_by).with(barcode: 'FX00000013').and_return(nil) - allow(Sequencescape::Api::V2::Tube).to receive(:find_by).with(barcode: 'FX00000014').and_return(nil) - allow(Sequencescape::Api::V2::Tube).to receive(:find_by).with(barcode: 'FX00000015').and_return(nil) end context 'with both sequencing and contingency files' do @@ -810,29 +720,6 @@ def expect_custom_metadatum_collection_posts(tubes_hash) ) end - # need api v1 versions of child tubes - let(:child_tube_1_v1) { json :tube, uuid: child_tube_1_uuid, barcode_prefix: 'FX', barcode_number: 1 } - let(:child_tube_2_v1) { json :tube, uuid: child_tube_2_uuid, barcode_prefix: 'FX', barcode_number: 2 } - let(:child_tube_3_v1) { json :tube, uuid: child_tube_3_uuid, barcode_prefix: 'FX', barcode_number: 11 } - let(:child_tube_4_v1) { json :tube, uuid: child_tube_4_uuid, barcode_prefix: 'FX', barcode_number: 12 } - let(:child_tube_5_v1) { json :tube, uuid: child_tube_5_uuid, barcode_prefix: 'FX', barcode_number: 13 } - - # Metadata expected to be sent in POST requests - let!(:metadata_for_tube_1) { { tube_rack_barcode: 'TR00000001', tube_rack_position: 'A1' } } - let(:tube_1_create_args) { { user_id: user.id, asset_id: child_tube_1_v2.id, metadata: metadata_for_tube_1 } } - - let!(:metadata_for_tube_2) { { tube_rack_barcode: 'TR00000001', tube_rack_position: 'B1' } } - let(:tube_2_create_args) { { user_id: user.id, asset_id: child_tube_2_v2.id, metadata: metadata_for_tube_2 } } - - let!(:metadata_for_tube_3) { { tube_rack_barcode: 'TR00000002', tube_rack_position: 'A1' } } - let(:tube_3_create_args) { { user_id: user.id, asset_id: child_tube_3_v2.id, metadata: metadata_for_tube_3 } } - - let!(:metadata_for_tube_4) { { tube_rack_barcode: 'TR00000002', tube_rack_position: 'B1' } } - let(:tube_4_create_args) { { user_id: user.id, asset_id: child_tube_4_v2.id, metadata: metadata_for_tube_4 } } - - let!(:metadata_for_tube_5) { { tube_rack_barcode: 'TR00000002', tube_rack_position: 'C1' } } - let(:tube_5_create_args) { { user_id: user.id, asset_id: child_tube_5_v2.id, metadata: metadata_for_tube_5 } } - let(:contingency_file) do fixture_file_upload( 'spec/fixtures/files/scrna_core/scrna_core_contingency_tube_rack_scan_3_tubes.csv', @@ -840,15 +727,7 @@ def expect_custom_metadatum_collection_posts(tubes_hash) ) end - before do - stub_v2_user(user) - - stub_v2_labware(child_tube_1_v2) - stub_v2_labware(child_tube_2_v2) - stub_v2_labware(child_tube_3_v2) - stub_v2_labware(child_tube_4_v2) - stub_v2_labware(child_tube_5_v2) - end + before { stub_v2_user(user) } it 'creates the child tubes' do expect_specific_tube_creation(child_sequencing_tube_purpose_uuid, sequencing_tubes) @@ -920,18 +799,6 @@ def expect_custom_metadatum_collection_posts(tubes_hash) ) end - before do - stub_get_labware_metadata(child_tube_1_v2.barcode.machine, child_tube_1_v1) - stub_get_labware_metadata(child_tube_2_v2.barcode.machine, child_tube_2_v1) - stub_get_labware_metadata(child_tube_3_v2.barcode.machine, child_tube_3_v1) - stub_get_labware_metadata(child_tube_4_v2.barcode.machine, child_tube_4_v1) - - stub_asset_search(child_tube_1_v2.barcode.machine, child_tube_1_v1) - stub_asset_search(child_tube_2_v2.barcode.machine, child_tube_2_v1) - stub_asset_search(child_tube_3_v2.barcode.machine, child_tube_3_v1) - stub_asset_search(child_tube_4_v2.barcode.machine, child_tube_4_v1) - end - it 'does not create a tube for the failed well' do expect_specific_tube_creation(child_sequencing_tube_purpose_uuid, sequencing_tubes) expect_specific_tube_creation(child_contingency_tube_purpose_uuid, contingency_tubes) @@ -968,67 +835,6 @@ def expect_custom_metadatum_collection_posts(tubes_hash) } end - # child tubes for lookup after creation - let(:child_tube_1_v2) do - create( - :v2_stock_tube, - state: 'passed', - purpose_name: child_contingency_tube_purpose_name, - aliquots: [child_tube_1_aliquot], - barcode_prefix: 'FX', - barcode_number: 11, - uuid: child_tube_1_uuid - ) - end - - let(:child_tube_2_v2) do - create( - :v2_stock_tube, - state: 'passed', - purpose_name: child_contingency_tube_purpose_name, - aliquots: [child_tube_2_aliquot], - barcode_prefix: 'FX', - barcode_number: 12, - uuid: child_tube_2_uuid - ) - end - - let(:child_tube_3_v2) do - create( - :v2_stock_tube, - state: 'passed', - purpose_name: child_contingency_tube_purpose_name, - aliquots: [child_tube_3_aliquot], - barcode_prefix: 'FX', - barcode_number: 13, - uuid: child_tube_3_uuid - ) - end - - let(:child_tube_4_v2) do - create( - :v2_stock_tube, - state: 'passed', - purpose_name: child_contingency_tube_purpose_name, - aliquots: [child_tube_4_aliquot], - barcode_prefix: 'FX', - barcode_number: 14, - uuid: child_tube_4_uuid - ) - end - - let(:child_tube_5_v2) do - create( - :v2_stock_tube, - state: 'passed', - purpose_name: child_contingency_tube_purpose_name, - aliquots: [child_tube_5_aliquot], - barcode_prefix: 'FX', - barcode_number: 15, - uuid: child_tube_5_uuid - ) - end - let(:contingency_tubes) do prepare_created_child_tubes( [ @@ -1069,38 +875,7 @@ def expect_custom_metadatum_collection_posts(tubes_hash) ) end - # need api v1 versions of child tubes - let(:child_tube_1_v1) { json :tube, uuid: child_tube_1_uuid, barcode_prefix: 'FX', barcode_number: 11 } - let(:child_tube_2_v1) { json :tube, uuid: child_tube_2_uuid, barcode_prefix: 'FX', barcode_number: 12 } - let(:child_tube_3_v1) { json :tube, uuid: child_tube_3_uuid, barcode_prefix: 'FX', barcode_number: 13 } - let(:child_tube_4_v1) { json :tube, uuid: child_tube_4_uuid, barcode_prefix: 'FX', barcode_number: 14 } - let(:child_tube_5_v1) { json :tube, uuid: child_tube_5_uuid, barcode_prefix: 'FX', barcode_number: 15 } - - # need to stub the creation of the tube metadata - let!(:metadata_for_tube_1) { { tube_rack_barcode: 'TR00000002', tube_rack_position: 'A1' } } - let(:tube_1_create_args) { { user_id: user.id, asset_id: child_tube_1_v2.id, metadata: metadata_for_tube_1 } } - - let!(:metadata_for_tube_2) { { tube_rack_barcode: 'TR00000002', tube_rack_position: 'B1' } } - let(:tube_2_create_args) { { user_id: user.id, asset_id: child_tube_2_v2.id, metadata: metadata_for_tube_2 } } - - let!(:metadata_for_tube_3) { { tube_rack_barcode: 'TR00000002', tube_rack_position: 'C1' } } - let(:tube_3_create_args) { { user_id: user.id, asset_id: child_tube_3_v2.id, metadata: metadata_for_tube_3 } } - - let!(:metadata_for_tube_4) { { tube_rack_barcode: 'TR00000002', tube_rack_position: 'E1' } } - let(:tube_4_create_args) { { user_id: user.id, asset_id: child_tube_4_v2.id, metadata: metadata_for_tube_4 } } - - let!(:metadata_for_tube_5) { { tube_rack_barcode: 'TR00000002', tube_rack_position: 'F1' } } - let(:tube_5_create_args) { { user_id: user.id, asset_id: child_tube_5_v2.id, metadata: metadata_for_tube_5 } } - - before do - stub_v2_user(user) - - stub_v2_labware(child_tube_1_v2) - stub_v2_labware(child_tube_2_v2) - stub_v2_labware(child_tube_3_v2) - stub_v2_labware(child_tube_4_v2) - stub_v2_labware(child_tube_5_v2) - end + before { stub_v2_user(user) } it 'creates the child tubes' do # Contingency tubes creation From cd8c643d9a0d64f756d8198a780b1ee9234a0731 Mon Sep 17 00:00:00 2001 From: Stuart McHattie Date: Tue, 17 Sep 2024 13:37:04 +0100 Subject: [PATCH 6/9] Remove accidental assignment to unused variable --- spec/models/labware_creators/plate_split_to_tube_racks_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/models/labware_creators/plate_split_to_tube_racks_spec.rb b/spec/models/labware_creators/plate_split_to_tube_racks_spec.rb index 6fd9a237b..5a0de7246 100644 --- a/spec/models/labware_creators/plate_split_to_tube_racks_spec.rb +++ b/spec/models/labware_creators/plate_split_to_tube_racks_spec.rb @@ -165,7 +165,7 @@ def expect_custom_metadatum_collection_posts(tubes_hash) expected_call_args = tubes_hash.flat_map do |tube_rack_barcode, tubes| tubes.map do |tube| - metadata = { + { user_id: user.id, asset_id: tube.id, metadata: { From 9f10f6a0e28740510cb47bcccb64df5ae5b0d17a Mon Sep 17 00:00:00 2001 From: Stuart McHattie Date: Tue, 17 Sep 2024 14:22:20 +0100 Subject: [PATCH 7/9] Fix tests for pooled tubes by submission --- .../pooled_tubes_by_submission_spec.rb | 103 ++++++++---------- 1 file changed, 43 insertions(+), 60 deletions(-) diff --git a/spec/models/labware_creators/pooled_tubes_by_submission_spec.rb b/spec/models/labware_creators/pooled_tubes_by_submission_spec.rb index f358503a5..cb8033efe 100644 --- a/spec/models/labware_creators/pooled_tubes_by_submission_spec.rb +++ b/spec/models/labware_creators/pooled_tubes_by_submission_spec.rb @@ -11,6 +11,8 @@ RSpec.describe LabwareCreators::PooledTubesBySubmission do include FeatureHelpers + has_a_working_api + it_behaves_like 'it only allows creation from charged and passed plates with defined downstream pools' subject { LabwareCreators::PooledTubesBySubmission.new(api, form_attributes) } @@ -31,10 +33,25 @@ before { stub_v2_plate(source_plate, stub_search: false) } context '#save!' do - has_a_working_api - - let(:child_1_name) { 'DN5 A1:C1' } - let(:child_2_name) { 'DN5 D1:A2' } + def expect_specific_tube_creation(child_tubes) + # Create a mock for the specific tube creation. + specific_tube_creation = double + allow(specific_tube_creation).to receive(:children).and_return(child_tubes) + + # Expect the post request and return the mock. + expect_api_v2_posts( + 'SpecificTubeCreation', + [ + { + child_purpose_uuids: [purpose_uuid] * child_tubes.size, + parent_uuids: [parent_uuid], + tube_attributes: child_tubes.map { |tube| { name: tube.name } }, + user_uuid: user_uuid + } + ], + [specific_tube_creation] + ) + end # Used to fetch the pools. This is the kind of thing we could pass through from a custom form let!(:parent_request) do @@ -42,40 +59,20 @@ stub_api_get(parent_uuid, 'wells', body: wells_json) end - let(:creation_payload) do - { - user: user_uuid, - parent: parent_uuid, - child_purposes: [purpose_uuid, purpose_uuid], - tube_attributes: [{ name: child_1_name }, { name: child_2_name }] - } - end + let(:child_1_name) { 'DN5 A1:C1' } + let(:child_2_name) { 'DN5 D1:A2' } - let(:tube_creation_request_uuid) { SecureRandom.uuid } + let(:tube_attributes) { [{ name: child_1_name }, { name: child_2_name }] } - let!(:tube_creation_request) do - stub_api_post( - 'specific_tube_creations', - payload: { - specific_tube_creation: creation_payload - }, - body: - json( - :specific_tube_creation, - uuid: tube_creation_request_uuid, - children_count: 2, - names: [child_1_name, child_2_name] - ) - ) - end + let(:child_tubes) do + # Prepare child tubes and stub their lookups. + child_tubes = + tube_attributes.each_with_index.map do |attrs, index| + create(:v2_tube, name: attrs[:name], uuid: "tube-#{index}") + end + child_tubes.each { |child_tube| stub_v2_labware(child_tube) } - # Find out what tubes we've just made! - let!(:tube_creation_children_request) do - stub_api_get( - tube_creation_request_uuid, - 'children', - body: json(:tube_collection, names: [child_1_name, child_2_name]) - ) + child_tubes end let(:transfer_requests) do @@ -106,9 +103,10 @@ end context 'without parent metadata' do + before { expect_specific_tube_creation(child_tubes) } + it 'pools by submission' do expect(subject.save!).to be_truthy - expect(tube_creation_request).to have_been_made.once expect(transfer_creation_request).to have_been_made.once end @@ -133,24 +131,11 @@ for_multiplexing: true end - setup do - stub_get_labware_metadata('DN10', parent, metadata: { stock_barcode: 'DN6' }) - stub_api_post( - 'specific_tube_creations', - payload: { - specific_tube_creation: creation_payload - }, - body: - json( - :specific_tube_creation, - uuid: tube_creation_request_uuid, - children_count: 2, - names: [child_1_name, child_2_name] - ) - ) - end + setup { stub_get_labware_metadata('DN10', parent, metadata: { stock_barcode: 'DN6' }) } it 'sets the correct tube name' do + expect_specific_tube_creation(child_tubes) + expect(subject.save!).to be_truthy expect(subject.child_stock_tubes.length).to eq(2) expect(subject.child_stock_tubes).to have_key(child_1_name) @@ -172,6 +157,9 @@ { 'source_asset' => 'example-well-uuid-7', 'target_asset' => 'tube-1', 'submission' => 'pool-2-uuid' } ] end + + before { expect_specific_tube_creation(child_tubes) } + it 'pools by submission' do expect(subject.save!).to be_truthy expect(transfer_creation_request).to have_been_made.once @@ -191,14 +179,9 @@ ] end - let(:creation_payload) do - { - user: user_uuid, - parent: parent_uuid, - child_purposes: [purpose_uuid], - tube_attributes: [{ name: child_1_name }] - } - end + let(:tube_attributes) { [{ name: child_1_name }] } + + before { expect_specific_tube_creation(child_tubes) } it 'pools by submission' do expect(subject.save!).to be_truthy From 8ca6cc86c93c599807c30ad669882cdde07827d8 Mon Sep 17 00:00:00 2001 From: Stuart McHattie Date: Tue, 17 Sep 2024 14:34:43 +0100 Subject: [PATCH 8/9] Fix tests for custom_pooled_tubes --- .../custom_pooled_tubes_spec.rb | 48 +++++++++---------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/spec/models/labware_creators/custom_pooled_tubes_spec.rb b/spec/models/labware_creators/custom_pooled_tubes_spec.rb index c9ed9f2e9..489727e2f 100644 --- a/spec/models/labware_creators/custom_pooled_tubes_spec.rb +++ b/spec/models/labware_creators/custom_pooled_tubes_spec.rb @@ -73,29 +73,28 @@ ) end - let(:tube_creation_request_uuid) { SecureRandom.uuid } - - let(:tube_creation_request) do - stub_api_post( - 'specific_tube_creations', - payload: { - specific_tube_creation: { - user: user_uuid, - parent: parent_uuid, - child_purposes: [purpose_uuid, purpose_uuid], - tube_attributes: [{ name: 'DN5 A1:B2' }, { name: 'DN5 C1:G2' }] + def expect_specific_tube_creation + child_tubes = [ + create(:v2_tube, name: 'DN5 A1:B2', uuid: 'tube-0'), + create(:v2_tube, name: 'DN5 C1:G2', uuid: 'tube-1') + ] + + # Create a mock for the specific tube creation. + specific_tube_creation = double + allow(specific_tube_creation).to receive(:children).and_return(child_tubes) + + # Expect the post request and return the mock. + expect_api_v2_posts( + 'SpecificTubeCreation', + [ + { + child_purpose_uuids: [purpose_uuid, purpose_uuid], + parent_uuids: [parent_uuid], + tube_attributes: child_tubes.map { |tube| { name: tube.name } }, + user_uuid: user_uuid } - }, - body: json(:specific_tube_creation, uuid: tube_creation_request_uuid, children_count: 2) - ) - end - - # Find out what tubes we've just made! - let(:tube_creation_children_request) do - stub_api_get( - tube_creation_request_uuid, - 'children', - body: json(:tube_collection, names: ['DN5 A1:B2', 'DN5 C1:G2']) + ], + [specific_tube_creation] ) end @@ -138,8 +137,6 @@ before do stub_parent_request stub_qc_file_creation - tube_creation_children_request - tube_creation_request transfer_creation_request end @@ -149,9 +146,10 @@ end it 'pools according to the file' do + expect_specific_tube_creation + expect(subject.save).to be_truthy expect(stub_qc_file_creation).to have_been_made.once - expect(tube_creation_request).to have_been_made.once expect(transfer_creation_request).to have_been_made.once end end From 3d096e488460e4814521d907b16f227b0a6eadef Mon Sep 17 00:00:00 2001 From: Stuart McHattie Date: Tue, 17 Sep 2024 16:42:22 +0100 Subject: [PATCH 9/9] Change parents relationship to Labware instead of Asset --- .../sequencescape/api/v2/specific_tube_creation.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/sequencescape/sequencescape/api/v2/specific_tube_creation.rb b/app/sequencescape/sequencescape/api/v2/specific_tube_creation.rb index 035a70c5a..4b3235552 100644 --- a/app/sequencescape/sequencescape/api/v2/specific_tube_creation.rb +++ b/app/sequencescape/sequencescape/api/v2/specific_tube_creation.rb @@ -3,6 +3,6 @@ # Represents a specific tube creation in Limber via the Sequencescape API class Sequencescape::Api::V2::SpecificTubeCreation < Sequencescape::Api::V2::Base has_many :children, class_name: 'Sequencescape::Api::V2::Tube' - has_many :parents, class_name: 'Sequencescape::Api::V2::Asset' + has_many :parents, class_name: 'Sequencescape::Api::V2::Labware' has_one :user, class_name: 'Sequencescape::Api::V2::User' end