diff --git a/.pryrc b/.pryrc
new file mode 100644
index 000000000..ca997213f
--- /dev/null
+++ b/.pryrc
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+if defined?(PryByebug)
+ Pry.commands.alias_command 's', 'step'
+ Pry.commands.alias_command 'n', 'next'
+ Pry.commands.alias_command 'f', 'finish'
+ Pry.commands.alias_command 'c', 'continue'
+end
diff --git a/.release-version b/.release-version
index 6621aa3bc..9b57023ab 100644
--- a/.release-version
+++ b/.release-version
@@ -1 +1 @@
-3.61.1
+3.62.0
diff --git a/Gemfile.lock b/Gemfile.lock
index 12080ecf5..d6c0e887d 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -136,7 +136,7 @@ GEM
diff-lcs (1.5.1)
docile (1.4.0)
drb (2.2.1)
- dry-cli (1.1.0)
+ dry-cli (1.2.0)
erubi (1.13.0)
exception_notification (4.5.0)
actionmailer (>= 5.2, < 8)
@@ -192,10 +192,10 @@ GEM
tilt
hashdiff (1.1.0)
hashie (5.0.0)
- i18n (1.14.5)
+ i18n (1.14.6)
concurrent-ruby (~> 1.0)
io-console (0.7.2)
- irb (1.14.0)
+ irb (1.14.1)
rdoc (>= 4.0.0)
reline (>= 0.4.2)
json (2.7.2)
@@ -264,7 +264,7 @@ GEM
puma (6.4.3)
nio4r (~> 2.0)
racc (1.8.1)
- rack (3.1.7)
+ rack (3.1.8)
rack-mini-profiler (3.3.1)
rack (>= 1.2.0)
rack-proxy (0.7.7)
@@ -319,7 +319,7 @@ GEM
rdoc (6.7.0)
psych (>= 4.0.0)
regexp_parser (2.9.2)
- reline (0.5.9)
+ reline (0.5.10)
io-console (~> 0.5)
rexml (3.3.6)
strscan
@@ -404,7 +404,7 @@ GEM
rbs
syntax_tree (>= 2.0.1)
temple (0.10.3)
- thor (1.3.1)
+ thor (1.3.2)
tilt (2.4.0)
timeout (0.4.1)
tzinfo (2.0.6)
@@ -413,8 +413,9 @@ GEM
vite_rails (3.0.17)
railties (>= 5.1, < 8)
vite_ruby (~> 3.0, >= 3.2.2)
- vite_ruby (3.6.0)
+ vite_ruby (3.9.0)
dry-cli (>= 0.7, < 2)
+ logger (~> 1.6)
rack-proxy (~> 0.6, >= 0.6.1)
zeitwerk (~> 2.2)
web-console (4.2.1)
@@ -434,7 +435,7 @@ GEM
xpath (3.2.0)
nokogiri (~> 1.8)
yard (0.9.36)
- zeitwerk (2.6.17)
+ zeitwerk (2.6.18)
PLATFORMS
ruby
diff --git a/app/frontend/entrypoints/application.js b/app/frontend/entrypoints/application.js
index dfc9cb98e..e4c83293f 100644
--- a/app/frontend/entrypoints/application.js
+++ b/app/frontend/entrypoints/application.js
@@ -29,6 +29,15 @@ console.log('Visit the guide for more information: ', 'https://vite-ruby.netlify
// ^^^ Template from Vite. Below is custom code for Limber ^^^
+// Import Rails UJS as in Sequencescape
+import Rails from '@rails/ujs'
+
+try {
+ Rails.start()
+} catch {
+ // Nothing
+}
+
// Import Libraries
import 'bootstrap'
import 'popper.js'
diff --git a/app/frontend/javascript/custom-tagged-plate/components/CustomTaggedPlate.spec.js b/app/frontend/javascript/custom-tagged-plate/components/CustomTaggedPlate.spec.js
index 037afeb9c..954bfc22e 100644
--- a/app/frontend/javascript/custom-tagged-plate/components/CustomTaggedPlate.spec.js
+++ b/app/frontend/javascript/custom-tagged-plate/components/CustomTaggedPlate.spec.js
@@ -833,8 +833,8 @@ describe('CustomTaggedPlate', () => {
purpose_uuid: 'purpose-uuid',
parent_uuid: 'parent-plate-uuid',
tag_layout: {
- tag_group: 'tag-1-group-uuid',
- tag2_group: 'tag-2-group-uuid',
+ tag_group_uuid: 'tag-1-group-uuid',
+ tag2_group_uuid: 'tag-2-group-uuid',
direction: 'column',
walking_by: 'manual by plate',
initial_tag: 1,
diff --git a/app/frontend/javascript/custom-tagged-plate/components/CustomTaggedPlate.vue b/app/frontend/javascript/custom-tagged-plate/components/CustomTaggedPlate.vue
index ec11ba7db..8f2f2a123 100644
--- a/app/frontend/javascript/custom-tagged-plate/components/CustomTaggedPlate.vue
+++ b/app/frontend/javascript/custom-tagged-plate/components/CustomTaggedPlate.vue
@@ -619,8 +619,8 @@ export default {
purpose_uuid: this.purposeUuid,
parent_uuid: this.parentUuid,
tag_layout: {
- tag_group: this.tag1GroupUuid,
- tag2_group: this.tag2GroupUuid,
+ tag_group_uuid: this.tag1GroupUuid,
+ tag2_group_uuid: this.tag2GroupUuid,
direction: this.direction,
walking_by: this.walkingBy,
initial_tag: initialTag,
diff --git a/app/frontend/javascript/legacy_scripts_a.js b/app/frontend/javascript/legacy_scripts_a.js
index 392a1766b..47237c542 100644
--- a/app/frontend/javascript/legacy_scripts_a.js
+++ b/app/frontend/javascript/legacy_scripts_a.js
@@ -59,9 +59,12 @@ let limberPlateView = function (defaultTab) {
control.find('a[href="' + defaultTab + '"]').tab('show')
plateElement.on('click', '.aliquot', function (event) {
+ control.find('a[data-plate-view="pools-view"]').tab('show')
+
let pool = $(event.currentTarget).data('pool')
- control.find('a[data-plate-view="pools-view"]').tab('show')
+ // Handle cases where pool is not defined to prevent errors
+ if (pool === undefined || pool === '') return
plateElement
.find('.aliquot[data-pool!=' + pool + ']')
diff --git a/app/frontend/javascript/pipeline-graph/index.js b/app/frontend/javascript/pipeline-graph/index.js
index 9b3d477f8..9e4b0cdeb 100644
--- a/app/frontend/javascript/pipeline-graph/index.js
+++ b/app/frontend/javascript/pipeline-graph/index.js
@@ -226,6 +226,8 @@ const applyMouseEvents = function () {
// when an edge is clicked, filter the graph to show only that pipeline
core.on('click', 'edge', (event) => {
const pipeline = event.target.data('pipeline')
- applyFilter(pipeline)
+ const group = event.target.data('group')
+ const pipelineOrGroup = pipeline || group
+ applyFilter(pipelineOrGroup)
})
}
diff --git a/app/helpers/page_helper.rb b/app/helpers/page_helper.rb
index 49f774667..11e5ba153 100644
--- a/app/helpers/page_helper.rb
+++ b/app/helpers/page_helper.rb
@@ -52,8 +52,8 @@ def jumbotron(jumbotron_id = nil, options = {}, &)
# eg. state_badge('pending')
# Pending
- def state_badge(state)
- tag.span(state.titleize, class: "state-badge #{state}", title: 'Labware State', data: { toggle: 'tooltip' })
+ def state_badge(state, title: 'Labware State')
+ tag.span(state.titleize, class: "state-badge #{state}", title: title, data: { toggle: 'tooltip' })
end
# eg. count_badge(0)
diff --git a/app/models/labware_creators/baited_plate.rb b/app/models/labware_creators/baited_plate.rb
index b4a49ccc6..ebddd05c7 100644
--- a/app/models/labware_creators/baited_plate.rb
+++ b/app/models/labware_creators/baited_plate.rb
@@ -25,12 +25,13 @@ def plate
end
def bait_library_layout_preview
- @bait_library_layout_preview ||= api.bait_library_layout.preview!(plate: parent_uuid, user: user_uuid).layout
+ @bait_library_layout_preview ||=
+ Sequencescape::Api::V2::BaitLibraryLayout.preview(plate_uuid: parent_uuid, user_uuid: user_uuid).first.layout
end
def create_labware!
create_plate_with_standard_transfer! do |child|
- api.bait_library_layout.create!(plate: child.uuid, user: user_uuid)
+ Sequencescape::Api::V2::BaitLibraryLayout.create!(plate_uuid: child.uuid, user_uuid: user_uuid)
end
end
diff --git a/app/models/labware_creators/custom_tagged_plate.rb b/app/models/labware_creators/custom_tagged_plate.rb
index 3f6401b13..d7d161c94 100644
--- a/app/models/labware_creators/custom_tagged_plate.rb
+++ b/app/models/labware_creators/custom_tagged_plate.rb
@@ -18,10 +18,10 @@ class CustomTaggedPlate < Base
{
tag_plate: %i[asset_uuid template_uuid state],
tag_layout: [
- :user,
- :plate,
- :tag_group,
- :tag2_group,
+ :user_uuid,
+ :plate_uuid,
+ :tag_group_uuid,
+ :tag2_group_uuid,
:direction,
:walking_by,
:initial_tag,
@@ -47,14 +47,11 @@ def initialize(*args, &)
def create_plate! # rubocop:todo Metrics/AbcSize
@child =
- api
- .pooled_plate_creation
- .create!(
- child_purpose: purpose_uuid,
- user: user_uuid,
- parents: [parent_uuid, tag_plate.asset_uuid].compact_blank
- )
- .child
+ Sequencescape::Api::V2::PooledPlateCreation.create!(
+ child_purpose_uuid: purpose_uuid,
+ parent_uuids: [parent_uuid, tag_plate.asset_uuid].compact_blank,
+ user_uuid: user_uuid
+ ).child
transfer_material_from_parent!(@child.uuid)
@@ -107,7 +104,7 @@ def tag_layout_attributes
def create_labware!
create_plate! do |plate_uuid|
- api.tag_layout.create!(tag_layout_attributes.merge(plate: plate_uuid, user: user_uuid))
+ Sequencescape::Api::V2::TagLayout.create!(tag_layout_attributes.merge(plate_uuid:, user_uuid:))
end
end
end
diff --git a/app/models/labware_creators/merged_plate.rb b/app/models/labware_creators/merged_plate.rb
index d6bd17bfb..8f1be6c3f 100644
--- a/app/models/labware_creators/merged_plate.rb
+++ b/app/models/labware_creators/merged_plate.rb
@@ -51,10 +51,10 @@ def barcodes=(barcodes)
private
def create_plate_from_parent!
- api.pooled_plate_creation.create!(
- child_purpose: purpose_uuid,
- user: user_uuid,
- parents: source_plates.map(&:uuid)
+ Sequencescape::Api::V2::PooledPlateCreation.create!(
+ child_purpose_uuid: purpose_uuid,
+ parent_uuids: source_plates.map(&:uuid),
+ user_uuid: user_uuid
)
end
diff --git a/app/models/labware_creators/multi_plate_pool.rb b/app/models/labware_creators/multi_plate_pool.rb
index 6beeaacc5..597447a01 100644
--- a/app/models/labware_creators/multi_plate_pool.rb
+++ b/app/models/labware_creators/multi_plate_pool.rb
@@ -17,10 +17,12 @@ class MultiPlatePool < Base
private
def create_labware!
- plate_creation =
- api.pooled_plate_creation.create!(parents: transfers.keys, child_purpose: purpose_uuid, user: user_uuid)
-
- @child = plate_creation.child
+ @child =
+ Sequencescape::Api::V2::PooledPlateCreation.create!(
+ child_purpose_uuid: purpose_uuid,
+ parent_uuids: transfers.keys,
+ user_uuid: user_uuid
+ ).child
api.bulk_transfer.create!(user: user_uuid, well_transfers: well_transfers)
diff --git a/app/models/labware_creators/multi_stamp.rb b/app/models/labware_creators/multi_stamp.rb
index 6cb8a9810..04d09ccbc 100644
--- a/app/models/labware_creators/multi_stamp.rb
+++ b/app/models/labware_creators/multi_stamp.rb
@@ -30,10 +30,12 @@ class MultiStamp < Base # rubocop:todo Style/Documentation
private
def create_labware!
- plate_creation =
- api.pooled_plate_creation.create!(parents: parent_uuids, child_purpose: purpose_uuid, user: user_uuid)
-
- @child = plate_creation.child
+ @child =
+ Sequencescape::Api::V2::PooledPlateCreation.create!(
+ child_purpose_uuid: purpose_uuid,
+ parent_uuids: parent_uuids,
+ user_uuid: user_uuid
+ ).child
transfer_material_from_parent!(@child.uuid)
diff --git a/app/models/labware_creators/multi_stamp_tubes.rb b/app/models/labware_creators/multi_stamp_tubes.rb
index aa3b153d0..c596f399a 100644
--- a/app/models/labware_creators/multi_stamp_tubes.rb
+++ b/app/models/labware_creators/multi_stamp_tubes.rb
@@ -41,13 +41,14 @@ def create_labware!
create_and_build_submission
return if errors.size.positive?
- plate_creation =
- api.pooled_plate_creation.create!(parents: parent_uuids, child_purpose: purpose_uuid, user: user_uuid)
+ @child =
+ Sequencescape::Api::V2::PooledPlateCreation.create!(
+ child_purpose_uuid: purpose_uuid,
+ parent_uuids: parent_uuids,
+ user_uuid: user_uuid
+ ).child
- @child = plate_creation.child
- child_v2 = Sequencescape::Api::V2.plate_with_wells(@child.uuid)
-
- transfer_material_from_parent!(child_v2)
+ transfer_material_from_parent!
yield(@child) if block_given?
true
@@ -87,15 +88,12 @@ def parent_tubes
Sequencescape::Api::V2::Tube.find_all(uuid: parent_uuids, includes: 'receptacle,aliquots,aliquots.study')
end
- def transfer_material_from_parent!(child_plate)
- api.transfer_request_collection.create!(
- user: user_uuid,
- transfer_requests: transfer_request_attributes(child_plate)
- )
+ def transfer_material_from_parent!
+ api.transfer_request_collection.create!(user: user_uuid, transfer_requests: transfer_request_attributes)
end
- def transfer_request_attributes(child_plate)
- transfers.map { |transfer| request_hash(transfer, child_plate) }
+ def transfer_request_attributes
+ transfers.map { |transfer| request_hash(transfer) }
end
def source_tube_outer_request_uuid(tube)
@@ -108,13 +106,13 @@ def source_tube_outer_request_uuid(tube)
pending_reqs.first.uuid || nil
end
- def request_hash(transfer, child_plate)
+ def request_hash(transfer)
tube = Sequencescape::Api::V2::Tube.find_by(uuid: transfer[:source_tube])
{
'source_asset' => transfer[:source_asset],
'target_asset' =>
- child_plate.wells.detect { |child_well| child_well.location == transfer.dig(:new_target, :location) }&.uuid,
+ @child.wells.detect { |child_well| child_well.location == transfer.dig(:new_target, :location) }&.uuid,
'outer_request' => source_tube_outer_request_uuid(tube)
}
end
diff --git a/app/models/labware_creators/multi_stamp_tubes_using_tube_rack_scan.rb b/app/models/labware_creators/multi_stamp_tubes_using_tube_rack_scan.rb
index d640a3ca6..471889ac4 100644
--- a/app/models/labware_creators/multi_stamp_tubes_using_tube_rack_scan.rb
+++ b/app/models/labware_creators/multi_stamp_tubes_using_tube_rack_scan.rb
@@ -65,13 +65,14 @@ def save
#
# @return [Boolean] true if the child plate was created successfully.
def create_labware!
- plate_creation =
- api.pooled_plate_creation.create!(parents: parent_tube_uuids, child_purpose: purpose_uuid, user: user_uuid)
+ @child =
+ Sequencescape::Api::V2::PooledPlateCreation.create!(
+ child_purpose_uuid: purpose_uuid,
+ parent_uuids: parent_tube_uuids,
+ user_uuid: user_uuid
+ ).child
- @child = plate_creation.child
- child_v2 = Sequencescape::Api::V2.plate_with_wells(@child.uuid)
-
- transfer_material_from_parent!(child_v2)
+ transfer_material_from_parent!
yield(@child) if block_given?
true
@@ -232,23 +233,18 @@ def tube_has_expected_active_request?(tube_in_db)
end
# Transfers material from the parent tubes to the given child plate.
- # @param child_plate [Sequencescape::Api::V2::Plate] The plate to transfer material to.
- def transfer_material_from_parent!(child_plate)
- api.transfer_request_collection.create!(
- user: user_uuid,
- transfer_requests: transfer_request_attributes(child_plate)
- )
+ def transfer_material_from_parent!
+ api.transfer_request_collection.create!(user: user_uuid, transfer_requests: transfer_request_attributes)
end
# Returns an array of hashes representing the transfer requests for the given child plate.
# Each hash includes the UUIDs of the parent tube and child well, and the UUID of the outer request.
- # @param child_plate [Sequencescape::Api::V2::Plate] The plate to get the transfer requests for.
# @return [Array] An array of hashes representing the transfer requests.
- def transfer_request_attributes(child_plate)
+ def transfer_request_attributes
parent_tubes.each_with_object([]) do |(foreign_barcode, parent_tube), tube_transfers|
tube_transfers << request_hash(
parent_tube.uuid,
- child_plate
+ @child
.wells
.detect { |child_well| child_well.location == csv_file.location_by_barcode_details[foreign_barcode] }
&.uuid,
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 c69c8300e..ca7208100 100644
--- a/app/models/labware_creators/plate_split_to_tube_racks.rb
+++ b/app/models/labware_creators/plate_split_to_tube_racks.rb
@@ -408,13 +408,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 f7dbe4bfb..abc4a7d10 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 3eafcf7dc..f4c00f7ce 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..cef106449 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
+ child_purpose_uuids: [purpose_uuid] * pool_uuids.length,
+ 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..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,15 +15,14 @@ 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 =
- 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
@@ -40,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/app/sequencescape/sequencescape/api/v2/bait_library_layout.rb b/app/sequencescape/sequencescape/api/v2/bait_library_layout.rb
new file mode 100644
index 000000000..bb5bb251d
--- /dev/null
+++ b/app/sequencescape/sequencescape/api/v2/bait_library_layout.rb
@@ -0,0 +1,6 @@
+# frozen_string_literal: true
+
+# bait library layout resource
+class Sequencescape::Api::V2::BaitLibraryLayout < Sequencescape::Api::V2::Base
+ custom_endpoint :preview, on: :collection, request_method: :post
+end
diff --git a/app/sequencescape/sequencescape/api/v2/pooled_plate_creation.rb b/app/sequencescape/sequencescape/api/v2/pooled_plate_creation.rb
new file mode 100644
index 000000000..ef2d1d631
--- /dev/null
+++ b/app/sequencescape/sequencescape/api/v2/pooled_plate_creation.rb
@@ -0,0 +1,8 @@
+# frozen_string_literal: true
+
+# Represents a pooled plate creation in Limber via the Sequencescape API
+class Sequencescape::Api::V2::PooledPlateCreation < Sequencescape::Api::V2::Base
+ has_one :child, class_name: 'Sequencescape::Api::V2::Plate'
+ has_many :parents, class_name: 'Sequencescape::Api::V2::Labware'
+ has_one :user, class_name: 'Sequencescape::Api::V2::User'
+end
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..4b3235552
--- /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::Labware'
+ has_one :user, class_name: 'Sequencescape::Api::V2::User'
+end
diff --git a/app/sequencescape/sequencescape/api/v2/tag_layout.rb b/app/sequencescape/sequencescape/api/v2/tag_layout.rb
new file mode 100644
index 000000000..2e5f92fda
--- /dev/null
+++ b/app/sequencescape/sequencescape/api/v2/tag_layout.rb
@@ -0,0 +1,5 @@
+# frozen_string_literal: true
+
+# tag layout resource
+class Sequencescape::Api::V2::TagLayout < Sequencescape::Api::V2::Base
+end
diff --git a/app/views/application/_submission_item.html.erb b/app/views/application/_submission_item.html.erb
index b6145c676..f09a8da9b 100644
--- a/app/views/application/_submission_item.html.erb
+++ b/app/views/application/_submission_item.html.erb
@@ -1,3 +1,3 @@
- <%= state_badge(submission_item.state) %> <%= submission_item.name %>
+ <%= state_badge(submission_item.state, title: 'Submission State') %> <%= submission_item.name %>
diff --git a/config/pipelines/bespoke_pcr.yml b/config/pipelines/bespoke_pcr.yml
index 20668475f..e75c64975 100644
--- a/config/pipelines/bespoke_pcr.yml
+++ b/config/pipelines/bespoke_pcr.yml
@@ -35,9 +35,11 @@ Bespoke PCR:
- SGE Library v0.2
library_pass: LBB Lib PCR-XP
relationships:
+ Stock Plate: LBB Ligation
LBB Cherrypick: LBB Ligation
LBC Cherrypick: LBB Ligation
LBB Ligation: LBB Lib PCR-XP
+
Bespoke PCR BCR:
filters:
request_type_key: limber_pcr_bespoke
@@ -45,6 +47,7 @@ Bespoke PCR BCR:
- Manual Chromium single cell BCR
library_pass: LBB Lib PCR-XP
relationships:
+ Stock Plate: LBB Enriched BCR
LBB Cherrypick: LBB Enriched BCR
LBC Cherrypick: LBB Enriched BCR
LBB Enriched BCR: LBB Ligation
@@ -56,6 +59,7 @@ Bespoke PCR BCR HT:
- Manual Chromium single cell BCR HT
library_pass: LBB Lib PCR-XP
relationships:
+ Stock Plate: LBB Enriched BCR HT
LBB Cherrypick: LBB Enriched BCR HT
LBC Cherrypick: LBB Enriched BCR HT
LBB Enriched BCR HT: LBB Ligation
@@ -67,6 +71,7 @@ Bespoke PCR TCR:
- Manual Chromium single cell TCR
library_pass: LBB Lib PCR-XP
relationships:
+ Stock Plate: LBB Enriched TCR
LBB Cherrypick: LBB Enriched TCR
LBC Cherrypick: LBB Enriched TCR
LBB Enriched TCR: LBB Ligation
@@ -78,6 +83,7 @@ Bespoke PCR TCR HT:
- Manual Chromium single cell TCR HT
library_pass: LBB Lib PCR-XP
relationships:
+ Stock Plate: LBB Enriched TCR HT
LBB Cherrypick: LBB Enriched TCR HT
LBC Cherrypick: LBB Enriched TCR HT
LBB Enriched TCR HT: LBB Ligation
diff --git a/config/purposes/bespoke.yml b/config/purposes/bespoke.yml
index 5a4411904..fc21a0aeb 100644
--- a/config/purposes/bespoke.yml
+++ b/config/purposes/bespoke.yml
@@ -43,3 +43,8 @@ LBB Enriched TCR:
LBB Enriched TCR HT:
:asset_type: plate
:creator_class: LabwareCreators::PartialStampedPlateWithoutDilution
+Stock Plate:
+ :asset_type: plate
+ :stock_plate: true
+ :input_plate: true
+ :presenter_class: Presenters::StockPlatePresenter
diff --git a/package.json b/package.json
index 2201fdcf9..7b7c3a0d2 100644
--- a/package.json
+++ b/package.json
@@ -1,8 +1,9 @@
{
"dependencies": {
+ "@rails/ujs": "^7.1.3",
"axios": "^0.28.1",
"bootstrap-vue": "^2.23.1",
- "cytoscape": "^3.30.0",
+ "cytoscape": "^3.30.2",
"cytoscape-elk": "^2.2.0",
"cytoscape-popper": "^2.0.0",
"devour-client": "^2.1.2",
@@ -33,8 +34,8 @@
"prettier": "^3.0.0",
"sass": "^1.77.8",
"typescript": "^4.6.3",
- "vite": "^5.4.7",
- "vite-plugin-ruby": "^5.0.0",
+ "vite": "^5.0.0",
+ "vite-plugin-ruby": "^5.1.0",
"vitest": "^2.0.5",
"vue-template-compiler": "^2.7.0"
},
diff --git a/spec/factories/bait_library_layout_factories.rb b/spec/factories/bait_library_layout_factories.rb
index 9301e066e..f5fc1bc58 100644
--- a/spec/factories/bait_library_layout_factories.rb
+++ b/spec/factories/bait_library_layout_factories.rb
@@ -3,11 +3,9 @@
require_relative '../support/factory_bot_extensions'
FactoryBot.define do
- # Generates a BaitLibraryLayout (API V1)
- factory :bait_library_layout, class: Sequencescape::BaitLibraryLayout, traits: [:api_object] do
- json_root { 'bait_library_layout' }
-
- with_belongs_to_associations 'plate'
+ # Generates an incomplete, but sufficient for testing, V2 BaitLibraryLayout
+ factory :bait_library_layout, class: Sequencescape::Api::V2::BaitLibraryLayout do
+ skip_create
transient do
# Provide an array of pools, describing the number of wells in each
diff --git a/spec/factory_outputs/bait_library_layout_factory_spec.rb b/spec/factory_outputs/bait_library_layout_factory_spec.rb
deleted file mode 100644
index 784db8853..000000000
--- a/spec/factory_outputs/bait_library_layout_factory_spec.rb
+++ /dev/null
@@ -1,32 +0,0 @@
-# frozen_string_literal: true
-
-require 'rails_helper'
-
-RSpec.describe 'bait library layout factory' do
- subject { json(:bait_library_layout, plate_uuid: 'plate-uuid', uuid: 'bait-library-layout-uuid') }
-
- let(:json_content) do
- '{
- "bait_library_layout": {
- "actions": {"read": "http://example.com:3000/bait-library-layout-uuid"},
- "plate": {
- "actions": {
- "read": "http://example.com:3000/plate-uuid"
- },
- "uuid": "plate-uuid"
- },
- "uuid": "bait-library-layout-uuid",
- "layout": {
- "A1": "Human all exon 50MB",
- "B1": "Human all exon 50MB",
- "C1": "Mouse all exon",
- "D1": "Mouse all exon"
- }
- }
- }'
- end
-
- it 'should match the expected json' do
- expect(JSON.parse(subject)['bait_library_layout']).to eq JSON.parse(json_content)['bait_library_layout']
- end
-end
diff --git a/spec/features/creating_plate_with_bait_spec.rb b/spec/features/creating_plate_with_bait_spec.rb
index d7625dd66..99aa56faa 100644
--- a/spec/features/creating_plate_with_bait_spec.rb
+++ b/spec/features/creating_plate_with_bait_spec.rb
@@ -21,6 +21,8 @@
let(:transfer_template) { json :transfer_template, uuid: transfer_template_uuid }
let(:expected_transfers) { WellHelpers.stamp_hash(96) }
+ let(:bait_library_layout) { create :bait_library_layout }
+
let(:transfer_requests) do
WellHelpers.column_order(96)[0, 6].map do |well_name|
{ 'source_asset' => "2-well-#{well_name}", 'target_asset' => "3-well-#{well_name}", 'submission_id' => '2' }
@@ -44,17 +46,7 @@
# end of stubs for plate show page
# These stubs are required to render plate_creation baiting page
- stub_api_post(
- 'bait_library_layouts',
- 'preview',
- body: json(:bait_library_layout),
- payload: {
- bait_library_layout: {
- plate: plate_uuid,
- user: user_uuid
- }
- }
- )
+ expect_api_v2_posts('BaitLibraryLayout', [{ plate_uuid:, user_uuid: }], [[bait_library_layout]], method: :preview)
# end of stubs for plate_creation baiting page
@@ -80,16 +72,8 @@
},
body: '{}'
)
- stub_api_post(
- 'bait_library_layouts',
- body: json(:bait_library_layout),
- payload: {
- bait_library_layout: {
- plate: 'child-uuid',
- user: user_uuid
- }
- }
- )
+
+ expect_api_v2_posts('BaitLibraryLayout', [{ plate_uuid: 'child-uuid', user_uuid: user_uuid }])
# end of stubs for creating a new plate with baits
# Stub the requests for the next plate page
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')
diff --git a/spec/features/pooling_multiple_plates_spec.rb b/spec/features/pooling_multiple_plates_spec.rb
index b7a49849f..e86f00458 100644
--- a/spec/features/pooling_multiple_plates_spec.rb
+++ b/spec/features/pooling_multiple_plates_spec.rb
@@ -34,29 +34,6 @@
purpose_uuid: 'stock-plate-purpose-uuid'
end
- let(:child_plate_uuid) { SecureRandom.uuid }
- let(:child_plate) do
- create :v2_plate,
- purpose_uuid: 'child-purpose-0',
- purpose_name: 'Pool Plate',
- uuid: child_plate_uuid,
- barcode_number: 3
- end
-
- let!(:pooled_plate_creation_request) do
- stub_api_post(
- 'pooled_plate_creations',
- payload: {
- pooled_plate_creation: {
- user: user_uuid,
- child_purpose: 'child-purpose-0',
- parents: [plate_uuid, plate_uuid_2]
- }
- },
- body: json(:plate_creation, child_uuid: child_plate_uuid)
- )
- end
-
let!(:bulk_transfer_request) do
stub_api_post(
'bulk_transfers',
@@ -67,25 +44,44 @@
{
'source_uuid' => plate_uuid,
'source_location' => 'A1',
- 'destination_uuid' => child_plate_uuid,
+ 'destination_uuid' => child_plate.uuid,
'destination_location' => 'A1'
},
{
'source_uuid' => plate_uuid_2,
'source_location' => 'A1',
- 'destination_uuid' => child_plate_uuid,
+ 'destination_uuid' => child_plate.uuid,
'destination_location' => 'B1'
},
{
'source_uuid' => plate_uuid_2,
'source_location' => 'B1',
- 'destination_uuid' => child_plate_uuid,
+ 'destination_uuid' => child_plate.uuid,
'destination_location' => 'B1'
}
]
}
},
- body: json(:plate_creation, child_uuid: child_plate_uuid)
+ body: json(:plate_creation, child_uuid: child_plate.uuid)
+ )
+ end
+
+ let(:child_plate) { create :v2_plate, purpose_name: 'Pool Plate', barcode_number: 3 }
+
+ let(:pooled_plate_creation) do
+ response = double
+ allow(response).to receive(:child).and_return(child_plate)
+
+ response
+ end
+
+ def expect_pooled_plate_creation
+ expect_api_v2_posts(
+ 'PooledPlateCreation',
+ [
+ { child_purpose_uuid: child_plate.purpose.uuid, parent_uuids: [plate_uuid, plate_uuid_2], user_uuid: user_uuid }
+ ],
+ [pooled_plate_creation]
)
end
@@ -94,7 +90,7 @@
create :purpose_config,
creator_class: 'LabwareCreators::MultiPlatePool',
name: 'Pool Plate',
- uuid: 'child-purpose-0'
+ uuid: child_plate.purpose.uuid
create :pipeline, relationships: { 'Pooled example' => 'Pool Plate' }
# We look up the user
@@ -108,6 +104,8 @@
end
scenario 'creates multiple plates' do
+ expect_pooled_plate_creation
+
fill_in_swipecard_and_barcode(user_swipecard, plate_barcode_1)
plate_title = find('#plate-title')
expect(plate_title).to have_text('Pooled example')
@@ -119,7 +117,6 @@
expect(page).to have_content('DN2: A1, B1')
click_on('Make Pre-Cap pool Plate')
expect(page).to have_text('New empty labware added to the system')
- expect(pooled_plate_creation_request).to have_been_made
expect(bulk_transfer_request).to have_been_made
expect(page).to have_text('Pool Plate')
end
diff --git a/spec/helpers/page_helper_spec.rb b/spec/helpers/page_helper_spec.rb
index 9bc98a951..5c8f2d44e 100644
--- a/spec/helpers/page_helper_spec.rb
+++ b/spec/helpers/page_helper_spec.rb
@@ -22,4 +22,18 @@
expect(count_badge(0, 'test')).to eq('0')
end
end
+
+ describe '::state_badge' do
+ it 'returns a badge with the given state and default title' do
+ expect(state_badge('pending')).to eq(
+ 'Pending'
+ )
+ end
+
+ it 'returns a badge with the given state and title' do
+ expect(state_badge('passed', title: 'Submission State')).to eq(
+ 'Passed'
+ )
+ end
+ end
end
diff --git a/spec/models/labware_creators/baited_plate_spec.rb b/spec/models/labware_creators/baited_plate_spec.rb
index 48c035bf4..df6761193 100644
--- a/spec/models/labware_creators/baited_plate_spec.rb
+++ b/spec/models/labware_creators/baited_plate_spec.rb
@@ -23,6 +23,8 @@
let(:form_attributes) { { user_uuid:, purpose_uuid:, parent_uuid: } }
+ let(:bait_library_layout) { create :bait_library_layout }
+
let(:transfer_requests) do
WellHelpers.column_order(96)[0, 6].map do |well_name|
{ 'source_asset' => "2-well-#{well_name}", 'target_asset' => "3-well-#{well_name}", 'submission_id' => '2' }
@@ -36,32 +38,6 @@
context 'create plate' do
has_a_working_api
- let!(:bait_library_layout_preview_request) do
- stub_api_post(
- 'bait_library_layouts/preview',
- payload: {
- bait_library_layout: {
- plate: parent_uuid,
- user: user_uuid
- }
- },
- body: json(:bait_library_layout)
- )
- end
-
- let!(:bait_library_layout_request) do
- stub_api_post(
- 'bait_library_layouts',
- payload: {
- bait_library_layout: {
- plate: 'child-uuid',
- user: user_uuid
- }
- },
- body: json(:bait_library_layout)
- )
- end
-
let!(:plate_creation_request) do
stub_api_post(
'plate_creations',
@@ -79,6 +55,9 @@
before do
stub_v2_plate(parent, stub_search: false)
stub_v2_plate(child, stub_search: false)
+
+ stub_api_v2_post('BaitLibraryLayout')
+ stub_api_v2_post('BaitLibraryLayout', [bait_library_layout], method: :preview)
end
let!(:transfer_creation_request) do
diff --git a/spec/models/labware_creators/custom_pooled_tubes_spec.rb b/spec/models/labware_creators/custom_pooled_tubes_spec.rb
index 2f6b027f9..b8fff5277 100644
--- a/spec/models/labware_creators/custom_pooled_tubes_spec.rb
+++ b/spec/models/labware_creators/custom_pooled_tubes_spec.rb
@@ -71,29 +71,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
@@ -136,8 +135,6 @@
before do
stub_parent_request
stub_qc_file_creation
- tube_creation_children_request
- tube_creation_request
transfer_creation_request
end
@@ -147,9 +144,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
diff --git a/spec/models/labware_creators/custom_tagged_plate_spec.rb b/spec/models/labware_creators/custom_tagged_plate_spec.rb
index 1ae27edd2..5a1ecd5a9 100644
--- a/spec/models/labware_creators/custom_tagged_plate_spec.rb
+++ b/spec/models/labware_creators/custom_tagged_plate_spec.rb
@@ -95,49 +95,69 @@
context 'On create' do
let(:tag_plate_uuid) { 'tag-plate' }
let(:tag_template_uuid) { 'tag-layout-template' }
- let(:child_plate_uuid) { SecureRandom.uuid }
let(:parents) { [plate_uuid, tag_plate_uuid] }
- let!(:plate_creation_request) do
- stub_api_post(
- 'pooled_plate_creations',
- payload: {
- pooled_plate_creation: {
- parents: parents,
- child_purpose: child_purpose_uuid,
- user: user_uuid
- }
- },
- body: json(:plate_creation, child_uuid: child_plate_uuid)
+ let(:expected_transfers) { WellHelpers.stamp_hash(96) }
+
+ let(:child_plate) { create :v2_plate }
+
+ let(:pooled_plate_creation) do
+ response = double
+ allow(response).to receive(:child).and_return(child_plate)
+
+ response
+ end
+
+ def expect_pooled_plate_creation
+ expect_api_v2_posts(
+ 'PooledPlateCreation',
+ [{ child_purpose_uuid: child_purpose_uuid, parent_uuids: parents, user_uuid: user_uuid }],
+ [pooled_plate_creation]
)
end
- let(:expected_transfers) { WellHelpers.stamp_hash(96) }
+ def expect_state_change_creation
+ expect_api_v2_posts(
+ 'StateChange',
+ [
+ {
+ reason: 'Used in Library creation',
+ target_uuid: tag_plate_uuid,
+ target_state: 'exhausted',
+ user_uuid: user_uuid
+ }
+ ]
+ )
+ end
- def expect_transfer_creation
+ def expect_tag_layout_creation
expect_api_v2_posts(
- 'Transfer',
+ 'TagLayout',
[
{
user_uuid: user_uuid,
- source_uuid: plate_uuid,
- destination_uuid: child_plate_uuid,
- transfer_template_uuid: transfer_template_uuid,
- transfers: expected_transfers
+ plate_uuid: child_plate.uuid,
+ tag_group_uuid: 'tag-group-uuid',
+ tag2_group_uuid: 'tag2-group-uuid',
+ direction: 'column',
+ walking_by: 'manual by plate',
+ initial_tag: '1',
+ tags_per_well: 1
}
]
)
end
- def expect_state_change_creation
+ def expect_transfer_creation
expect_api_v2_posts(
- 'StateChange',
+ 'Transfer',
[
{
- reason: 'Used in Library creation',
- target_uuid: tag_plate_uuid,
- target_state: 'exhausted',
- user_uuid: user_uuid
+ user_uuid: user_uuid,
+ source_uuid: plate_uuid,
+ destination_uuid: child_plate.uuid,
+ transfer_template_uuid: transfer_template_uuid,
+ transfers: expected_transfers
}
]
)
@@ -157,9 +177,9 @@ def expect_state_change_creation
state: tag_plate_state
},
tag_layout: {
- user: 'user-uuid',
- tag_group: 'tag-group-uuid',
- tag2_group: 'tag2-group-uuid',
+ user_uuid: 'user-uuid',
+ tag_group_uuid: 'tag-group-uuid',
+ tag2_group_uuid: 'tag2-group-uuid',
direction: 'column',
walking_by: 'manual by plate',
initial_tag: '1',
@@ -177,54 +197,38 @@ def expect_state_change_creation
it_behaves_like 'it has a custom page', 'custom_tagged_plate'
context 'on save' do
- let!(:custom_tag_layout_creation_request) do
- stub_api_post(
- 'tag_layouts',
- payload: {
- tag_layout: {
- user: 'user-uuid',
- plate: child_plate_uuid,
- tag_group: 'tag-group-uuid',
- tag2_group: 'tag2-group-uuid',
- direction: 'column',
- walking_by: 'manual by plate',
- initial_tag: '1',
- tags_per_well: 1
- }
- }
- )
- end
-
context 'with an available tag plate' do
let(:tag_plate_state) { 'available' }
it 'creates a tag plate' do
- expect_transfer_creation
+ expect_pooled_plate_creation
expect_state_change_creation
+ expect_tag_layout_creation
+ expect_transfer_creation
expect(subject.save).to be true
- expect(plate_creation_request).to have_been_made.once
- expect(custom_tag_layout_creation_request).to have_been_made.once
end
it 'has the correct child (and uuid)' do
+ stub_api_v2_post('PooledPlateCreation', pooled_plate_creation)
+ stub_api_v2_post('TagLayout')
stub_api_v2_post('Transfer')
stub_api_v2_post('StateChange')
expect(subject.save).to be true
# This will be our new plate
- expect(subject.child.uuid).to eq(child_plate_uuid)
+ expect(subject.child.uuid).to eq(child_plate.uuid)
end
context 'when a user has exhausted the plate in another tab' do
it 'creates a tag plate' do
- expect_transfer_creation
+ expect_pooled_plate_creation
expect_state_change_creation
+ expect_tag_layout_creation
+ expect_transfer_creation
expect(subject.save).to be true
- expect(plate_creation_request).to have_been_made.once
- expect(custom_tag_layout_creation_request).to have_been_made.once
end
end
end
@@ -233,23 +237,25 @@ def expect_state_change_creation
let(:tag_plate_state) { 'exhausted' }
it 'creates a tagged plate' do
+ # This one will be VERY different
+ expect_tag_layout_creation
+
+ expect_pooled_plate_creation
expect_transfer_creation
expect(Sequencescape::Api::V2::StateChange).not_to receive(:create!)
expect(subject.save).to be true
- expect(plate_creation_request).to have_been_made.once
-
- # This one will be VERY different
- expect(custom_tag_layout_creation_request).to have_been_made.once
end
it 'has the correct child (and uuid)' do
+ stub_api_v2_post('PooledPlateCreation', pooled_plate_creation)
+ stub_api_v2_post('TagLayout')
stub_api_v2_post('Transfer')
expect(subject.save).to be true
# This will be our new plate
- expect(subject.child.uuid).to eq(child_plate_uuid)
+ expect(subject.child.uuid).to eq(child_plate.uuid)
end
end
@@ -259,19 +265,21 @@ def expect_state_change_creation
let(:parents) { [plate_uuid] }
it 'creates a tag plate' do
+ expect_pooled_plate_creation
+ expect_tag_layout_creation
expect_transfer_creation
expect(Sequencescape::Api::V2::StateChange).not_to receive(:create!)
expect(subject.save).to be true
- expect(plate_creation_request).to have_been_made.once
- expect(custom_tag_layout_creation_request).to have_been_made.once
end
it 'has the correct child (and uuid)' do
+ stub_api_v2_post('PooledPlateCreation', pooled_plate_creation)
+ stub_api_v2_post('TagLayout')
stub_api_v2_post('Transfer')
expect(subject.save).to be true
- expect(subject.child.uuid).to eq(child_plate_uuid)
+ expect(subject.child.uuid).to eq(child_plate.uuid)
end
end
end
diff --git a/spec/models/labware_creators/merged_plate_spec.rb b/spec/models/labware_creators/merged_plate_spec.rb
index 62bfa79ae..f67c4e403 100644
--- a/spec/models/labware_creators/merged_plate_spec.rb
+++ b/spec/models/labware_creators/merged_plate_spec.rb
@@ -54,15 +54,6 @@
creator_class: 'LabwareCreators::MergedPlate'
end
- let(:child_plate) do
- create :v2_plate,
- uuid: 'child-uuid',
- barcode_number: '4',
- size: plate_size,
- outer_requests: requests,
- purpose: child_purpose
- end
-
let(:requests) do
Array.new(plate_size) { |i| create :library_request, state: 'started', uuid: "request-#{i}", submission_id: 1 }
end
@@ -70,7 +61,6 @@
let(:user_uuid) { 'user-uuid' }
before do
- stub_v2_plate(child_plate, stub_search: false)
stub_v2_plate(source_plate_1, stub_search: false)
stub_v2_plate(source_plate_2, stub_search: false)
end
@@ -86,20 +76,8 @@
includes: plate_includes
).and_return([source_plate_1, source_plate_2])
)
- end
- let!(:plate_creation_request) do
- stub_api_post(
- 'pooled_plate_creations',
- payload: {
- pooled_plate_creation: {
- user: user_uuid,
- child_purpose: child_purpose_uuid,
- parents: [source_plate_1.uuid, source_plate_2.uuid]
- }
- },
- body: json(:plate_creation, child_uuid: child_plate.uuid)
- )
+ stub_v2_plate(child_plate, stub_search: false)
end
let!(:transfer_creation_request) do
@@ -115,10 +93,42 @@
)
end
+ let(:child_plate) do
+ create :v2_plate,
+ uuid: 'child-uuid',
+ barcode_number: '4',
+ size: plate_size,
+ outer_requests: requests,
+ purpose: child_purpose
+ end
+
+ let(:pooled_plate_creation) do
+ response = double
+ allow(response).to receive(:child).and_return(child_plate)
+
+ response
+ end
+
+ def expect_pooled_plate_creation
+ expect_api_v2_posts(
+ 'PooledPlateCreation',
+ [
+ {
+ child_purpose_uuid: child_purpose_uuid,
+ parent_uuids: [source_plate_1.uuid, source_plate_2.uuid],
+ user_uuid: user_uuid
+ }
+ ],
+ [pooled_plate_creation]
+ )
+ end
+
it 'makes the expected requests' do
+ expect_pooled_plate_creation
+
expect(subject).to be_valid
expect(subject.save!).to eq true
- expect(plate_creation_request).to have_been_made
+
expect(transfer_creation_request).to have_been_made
end
end
diff --git a/spec/models/labware_creators/multi_plate_pool_spec.rb b/spec/models/labware_creators/multi_plate_pool_spec.rb
index f08bc3943..0f9c6ac2e 100644
--- a/spec/models/labware_creators/multi_plate_pool_spec.rb
+++ b/spec/models/labware_creators/multi_plate_pool_spec.rb
@@ -77,18 +77,13 @@
}
end
- let!(:pooled_plate_creation_request) do
- stub_api_post(
- 'pooled_plate_creations',
- payload: {
- pooled_plate_creation: {
- user: user_uuid,
- child_purpose: child_purpose_uuid,
- parents: [plate_uuid, plate_b_uuid]
- }
- },
- body: json(:plate_creation, child_uuid: child_plate_uuid)
- )
+ let(:child_plate) { create :v2_plate }
+
+ let(:pooled_plate_creation) do
+ response = double
+ allow(response).to receive(:child).and_return(child_plate)
+
+ response
end
let!(:bulk_transfer_request) do
@@ -101,38 +96,48 @@
{
'source_uuid' => plate_uuid,
'source_location' => 'A1',
- 'destination_uuid' => child_plate_uuid,
+ 'destination_uuid' => child_plate.uuid,
'destination_location' => 'A1'
},
{
'source_uuid' => plate_uuid,
'source_location' => 'B1',
- 'destination_uuid' => child_plate_uuid,
+ 'destination_uuid' => child_plate.uuid,
'destination_location' => 'A1'
},
{
'source_uuid' => plate_b_uuid,
'source_location' => 'A1',
- 'destination_uuid' => child_plate_uuid,
+ 'destination_uuid' => child_plate.uuid,
'destination_location' => 'B1'
},
{
'source_uuid' => plate_b_uuid,
'source_location' => 'B1',
- 'destination_uuid' => child_plate_uuid,
+ 'destination_uuid' => child_plate.uuid,
'destination_location' => 'B1'
}
]
}
},
- body: json(:plate_creation, child_uuid: child_plate_uuid)
+ body: json(:plate_creation, child_uuid: child_plate.uuid)
+ )
+ end
+
+ def expect_pooled_plate_creation
+ expect_api_v2_posts(
+ 'PooledPlateCreation',
+ [{ child_purpose_uuid: child_purpose_uuid, parent_uuids: [plate_uuid, plate_b_uuid], user_uuid: user_uuid }],
+ [pooled_plate_creation]
)
end
context '#save!' do
it 'creates a plate!' do
+ expect_pooled_plate_creation
+
subject.save!
- expect(pooled_plate_creation_request).to have_been_made.once
+
expect(bulk_transfer_request).to have_been_made.once
end
end
diff --git a/spec/models/labware_creators/multi_stamp_spec.rb b/spec/models/labware_creators/multi_stamp_spec.rb
index 5f8591cc6..e1da3803d 100644
--- a/spec/models/labware_creators/multi_stamp_spec.rb
+++ b/spec/models/labware_creators/multi_stamp_spec.rb
@@ -11,7 +11,6 @@
let(:parent1_uuid) { 'parent1-plate-uuid' }
let(:parent2_uuid) { 'parent2-plate-uuid' }
- let(:child_uuid) { 'child-uuid' }
let(:requests_parent1) { Array.new(24) { |i| create :library_request, state: 'started', uuid: "request-p1-#{i}" } }
let(:requests_parent2) { Array.new(24) { |i| create :library_request, state: 'started', uuid: "request-p2-#{i}" } }
@@ -41,21 +40,19 @@
stock_plate: stock_plate2
)
end
- let(:child_plate_v2) { create :v2_plate, uuid: child_uuid, barcode_number: '5', size: 96 }
- let(:child_plate_v1) { json :stock_plate_with_metadata, stock_plate: { barcode: '5', uuid: child_uuid } }
+ let(:child_plate) { create :v2_plate, barcode_number: '5', size: 96 }
let(:child_purpose_uuid) { 'child-purpose' }
let(:child_purpose_name) { 'Child Purpose' }
let(:user_uuid) { 'user-uuid' }
- let(:user) { json :v1_user, uuid: user_uuid }
before do
create :purpose_config, name: child_purpose_name, uuid: child_purpose_uuid
stub_v2_plate(parent1, stub_search: false)
stub_v2_plate(parent2, stub_search: false)
- stub_v2_plate(child_plate_v2, stub_search: false, custom_query: [:plate_with_wells, child_plate_v2.uuid])
+ stub_v2_plate(child_plate, stub_search: false, custom_query: [:plate_with_wells, child_plate.uuid])
end
context 'on new' do
@@ -484,7 +481,7 @@
parents: [parent1_uuid, parent2_uuid]
}
},
- body: json(:plate_creation, child_uuid:)
+ body: json(:plate_creation, child_uuid: child_plate.uuid)
)
end
@@ -554,19 +551,33 @@
)
end
+ let(:pooled_plate_creation) do
+ response = double
+ allow(response).to receive(:child).and_return(child_plate)
+
+ response
+ end
+
+ def expect_pooled_plate_creation
+ expect_api_v2_posts(
+ 'PooledPlateCreation',
+ [{ child_purpose_uuid: child_purpose_uuid, parent_uuids: [parent1_uuid, parent2_uuid], user_uuid: user_uuid }],
+ [pooled_plate_creation]
+ )
+ end
+
context '#save!' do
setup do
- stub_api_get(child_plate_v2.uuid, body: child_plate_v1)
-
- stub_api_get('user-uuid', body: user)
- stub_api_get('asset-uuid', body: child_plate_v1)
+ # stub_api_get('user-uuid', body: user)
end
it 'creates a plate!' do
+ expect_pooled_plate_creation
+
subject.save!
- expect(pooled_plate_creation_request).to have_been_made.once
+
expect(transfer_creation_request).to have_been_made.once
- expect(subject.child.uuid).to eq(child_uuid)
+ expect(subject.child.uuid).to eq(child_plate.uuid)
expect(subject).to be_valid
expect(subject.errors.messages).to be_empty
end
diff --git a/spec/models/labware_creators/multi_stamp_tubes_spec.rb b/spec/models/labware_creators/multi_stamp_tubes_spec.rb
index 2e3c3e840..5d0df5a90 100644
--- a/spec/models/labware_creators/multi_stamp_tubes_spec.rb
+++ b/spec/models/labware_creators/multi_stamp_tubes_spec.rb
@@ -32,13 +32,8 @@
receptacle: parent2_receptacle
end
- let(:child_uuid) { 'child-uuid' }
let(:child_purpose_uuid) { 'child-purpose' }
let(:child_purpose_name) { 'Child Purpose' }
- let(:child_plate_v2) do
- create :v2_plate_for_submission, uuid: child_uuid, purpose_name: child_purpose_name, barcode_number: '5', size: 96
- end
- let(:child_plate_v1) { json :stock_plate_with_metadata, stock_plate: { barcode: '5', uuid: child_uuid } }
let(:user_uuid) { 'user-uuid' }
let(:user) { json :v1_user, uuid: user_uuid }
@@ -51,7 +46,6 @@
Settings.submission_templates = { 'example' => example_template_uuid }
stub_v2_tube(parent1, stub_search: false)
stub_v2_tube(parent2, stub_search: false)
- stub_v2_plate(child_plate_v2, stub_search: false, custom_includes: 'wells,wells.aliquots,wells.aliquots.study')
end
context 'on new' do
@@ -86,20 +80,6 @@
}
end
- let!(:ms_plate_creation_request) do
- stub_api_post(
- 'pooled_plate_creations',
- payload: {
- pooled_plate_creation: {
- user: user_uuid,
- child_purpose: child_purpose_uuid,
- parents: [parent1_tube_uuid, parent2_tube_uuid]
- }
- },
- body: json(:plate_creation, child_uuid:)
- )
- end
-
let(:transfer_requests) do
[
{ source_asset: 'tube1', target_asset: '5-well-A1', outer_request: 'outer-request-1' },
@@ -119,6 +99,32 @@
body: '{}'
)
end
+
+ let(:child_plate) do
+ create :v2_plate_for_submission, purpose_name: child_purpose_name, barcode_number: '5', size: 96
+ end
+
+ let(:pooled_plate_creation) do
+ response = double
+ allow(response).to receive(:child).and_return(child_plate)
+
+ response
+ end
+
+ def expect_pooled_plate_creation
+ expect_api_v2_posts(
+ 'PooledPlateCreation',
+ [
+ {
+ child_purpose_uuid: child_purpose_uuid,
+ parent_uuids: [parent1_tube_uuid, parent2_tube_uuid],
+ user_uuid: user_uuid
+ }
+ ],
+ [pooled_plate_creation]
+ )
+ end
+
context 'when the submission is created' do
describe 'internal methods' do
it 'determines the configuration for the submission' do
@@ -185,31 +191,7 @@
context '#save!' do
setup do
- stub_api_get(child_plate_v2.uuid, body: child_plate_v1)
- stub_api_get(
- 'custom_metadatum_collection-uuid',
- body: json(:v1_custom_metadatum_collection, uuid: 'custom_metadatum_collection-uuid')
- )
- stub_api_get('user-uuid', body: user)
- stub_api_get('asset-uuid', body: child_plate_v1)
-
expect(subject).to receive(:parent_tubes).and_return([parent1, parent2])
-
- metadata = attributes_for(:v1_custom_metadatum_collection).fetch(:metadata, {})
-
- stub_api_put(
- 'custom_metadatum_collection-uuid',
- payload: {
- custom_metadatum_collection: {
- metadata:
- }
- },
- body: json(:v1_custom_metadatum_collection)
- )
-
- expect('Sequencescape::Api::V2'.constantize).to receive(:plate_with_wells).with(child_uuid).and_return(
- child_plate_v2
- )
expect(subject).to receive(:source_tube_outer_request_uuid).with(parent1).and_return('outer-request-1')
expect(subject).to receive(:source_tube_outer_request_uuid).with(parent2).and_return('outer-request-2')
end
@@ -242,19 +224,6 @@
aliquots: [aliquot2]
end
- let(:child_aliquot1) { create :v2_aliquot, study_id: 1 }
- let(:child_aliquot2) { create :v2_aliquot, study_id: 2 }
- let(:child_well1) { create :v2_stock_well, location: 'A1', uuid: '5-well-A1', aliquots: [child_aliquot1] }
- let(:child_well2) { create :v2_stock_well, location: 'B1', uuid: '5-well-B1', aliquots: [child_aliquot2] }
- let(:child_plate_v2) do
- create :v2_plate_for_submission,
- uuid: child_uuid,
- purpose_name: child_purpose_name,
- barcode_number: '5',
- size: 96,
- wells: [child_well1, child_well2]
- end
-
let!(:order_request) do
stub_api_get(example_template_uuid, body: json(:submission_template, uuid: example_template_uuid))
stub_api_post(
@@ -291,8 +260,10 @@
end
it 'creates a plate!' do
+ expect_pooled_plate_creation
+
subject.save!
- expect(ms_plate_creation_request).to have_been_made.once
+
expect(transfer_creation_request).to have_been_made.once
expect(order_request).to have_been_made.once
expect(submission_request).to have_been_made.once
diff --git a/spec/models/labware_creators/multi_stamp_tubes_using_tube_rack_scan_spec.rb b/spec/models/labware_creators/multi_stamp_tubes_using_tube_rack_scan_spec.rb
index 6bd6e2752..6c4d584fe 100644
--- a/spec/models/labware_creators/multi_stamp_tubes_using_tube_rack_scan_spec.rb
+++ b/spec/models/labware_creators/multi_stamp_tubes_using_tube_rack_scan_spec.rb
@@ -84,30 +84,10 @@
[:purpose, 'receptacle.aliquots.request.request_type', 'receptacle.requests_as_source.request_type']
end
- # child aliquots
- let(:child_aliquot1) { create :v2_aliquot }
- let(:child_aliquot2) { create :v2_aliquot }
-
- # child wells
- let(:child_well1) { create :v2_well, location: 'A1', uuid: '5-well-A1', aliquots: [child_aliquot1] }
- let(:child_well2) { create :v2_well, location: 'B1', uuid: '5-well-B1', aliquots: [child_aliquot2] }
-
# child plate
- let(:child_plate_uuid) { 'child-uuid' }
let(:child_plate_purpose_uuid) { 'child-purpose' }
let(:child_plate_purpose_name) { 'Child Purpose' }
- let(:child_plate_v2) do
- create :v2_plate,
- uuid: child_plate_uuid,
- purpose_name: child_plate_purpose_name,
- barcode_number: '5',
- size: 96,
- wells: [child_well1, child_well2]
- end
-
- let(:child_plate_v2) do
- create :v2_plate, uuid: child_plate_uuid, purpose_name: child_plate_purpose_name, barcode_number: '5', size: 96
- end
+ let(:child_plate) { create :v2_plate, purpose_name: child_plate_purpose_name, barcode_number: '5', size: 96 }
let(:user_uuid) { 'user-uuid' }
let(:user) { json :v1_user, uuid: user_uuid }
@@ -132,7 +112,7 @@
end
let(:stub_upload_file_creation) do
- stub_request(:post, api_url_for(child_plate_uuid, 'qc_files')).with(
+ stub_request(:post, api_url_for(child_plate.uuid, 'qc_files')).with(
body: file_content,
headers: {
'Content-Type' => 'sequencescape/qc_file',
@@ -149,7 +129,7 @@
let(:child_plate_v1) do
# qc_files are created through the API V1. The actions attribute for qcfiles is required by the API V1.
- json :plate, uuid: child_plate_uuid, purpose_uuid: child_plate_purpose_uuid, qc_files_actions: %w[read create]
+ json :plate, uuid: child_plate.uuid, purpose_uuid: child_plate_purpose_uuid, qc_files_actions: %w[read create]
end
before do
@@ -162,9 +142,7 @@
includes: tube_includes
).and_return(parent_tube_2)
- stub_v2_plate(child_plate_v2, stub_search: false, custom_query: [:plate_with_wells, child_plate_v2.uuid])
-
- stub_api_get(child_plate_uuid, body: child_plate_v1)
+ stub_api_get(child_plate.uuid, body: child_plate_v1)
stub_upload_file_creation
@@ -194,20 +172,6 @@
{ user_uuid: user_uuid, purpose_uuid: child_plate_purpose_uuid, parent_uuid: parent_tube_1_uuid, file: file }
end
- let!(:ms_plate_creation_request) do
- stub_api_post(
- 'pooled_plate_creations',
- payload: {
- pooled_plate_creation: {
- user: user_uuid,
- child_purpose: child_plate_purpose_uuid,
- parents: [parent_tube_1_uuid, parent_tube_2_uuid]
- }
- },
- body: json(:plate_creation, child_plate_uuid:)
- )
- end
-
let(:transfer_requests) do
[
{ source_asset: 'tube-1-uuid', target_asset: '5-well-A1', outer_request: 'request-1' },
@@ -228,6 +192,27 @@
)
end
+ let(:pooled_plate_creation) do
+ response = double
+ allow(response).to receive(:child).and_return(child_plate)
+
+ response
+ end
+
+ def expect_pooled_plate_creation
+ expect_api_v2_posts(
+ 'PooledPlateCreation',
+ [
+ {
+ child_purpose_uuid: child_plate_purpose_uuid,
+ parent_uuids: [parent_tube_1_uuid, parent_tube_2_uuid],
+ user_uuid: user_uuid
+ }
+ ],
+ [pooled_plate_creation]
+ )
+ end
+
subject { LabwareCreators::MultiStampTubesUsingTubeRackScan.new(api, form_attributes) }
it 'creates a plate!' do
@@ -235,10 +220,11 @@
subject.labware.barcode.machine = 'AB10000001'
subject.labware.barcode.ean13 = nil
+ expect_pooled_plate_creation
+
subject.save
- expect(subject.errors.full_messages).to be_empty
- expect(ms_plate_creation_request).to have_been_made.once
+ expect(subject.errors.full_messages).to be_empty
expect(transfer_creation_request).to have_been_made.once
end
end
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 4f7f83f9a..0e88bd6af 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,89 +116,68 @@
{ 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
+ let(:sequencing_file) do
+ fixture_file_upload(
+ 'spec/fixtures/files/scrna_core/scrna_core_sequencing_tube_rack_scan.csv',
+ 'sequencescape/qc_file'
)
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
+ let(:contingency_file) do
+ fixture_file_upload(
+ 'spec/fixtures/files/scrna_core/scrna_core_contingency_tube_rack_scan.csv',
+ 'sequencescape/qc_file'
)
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
+ 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) }
- 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
- )
+ child_tubes
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
+ 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)
- let(:sequencing_file) do
- fixture_file_upload(
- 'spec/fixtures/files/scrna_core/scrna_core_sequencing_tube_rack_scan.csv',
- 'sequencescape/qc_file'
+ # 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
- let(:contingency_file) do
- fixture_file_upload(
- 'spec/fixtures/files/scrna_core/scrna_core_contingency_tube_rack_scan.csv',
- 'sequencescape/qc_file'
- )
+ # 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|
+ {
+ 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
@@ -221,12 +200,14 @@
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
@@ -373,13 +354,6 @@
'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
@@ -498,13 +472,6 @@
'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
@@ -635,7 +602,42 @@
end
context '#save' do
- let!(:stub_sequencing_tube_creation_request_uuid) { SecureRandom.uuid }
+ # body for stubbing the contingency file upload
+ let(:contingency_file_content) do
+ content = contingency_file.read
+ contingency_file.rewind
+ content
+ end
+
+ # stub the contingency file upload
+ let!(:stub_contingency_file_upload) do
+ stub_request(:post, api_url_for(parent_uuid, 'qc_files')).with(
+ body: contingency_file_content,
+ headers: {
+ 'Content-Type' => 'sequencescape/qc_file',
+ 'Content-Disposition' => 'form-data; filename="scrna_core_contingency_tube_rack_scan.csv"'
+ }
+ ).to_return(
+ status: 201,
+ body: json(:qc_file, filename: 'scrna_core_contingency_tube_rack_scan.csv'),
+ headers: {
+ 'content-type' => 'application/json'
+ }
+ )
+ end
+
+ 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
before do
stub_v2_plate(
@@ -646,13 +648,6 @@
'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
@@ -666,51 +661,6 @@
}
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
- )
- )
- end
-
# body for stubbing the contingency file upload
let(:contingency_file_content) do
content = contingency_file.read
@@ -742,6 +692,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')).with(
@@ -759,87 +720,26 @@
)
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: '{}'
)
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',
@@ -847,28 +747,20 @@
)
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_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
@@ -878,94 +770,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: '{}'
@@ -979,30 +797,40 @@
)
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)
+ 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
- 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)
+ 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
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
@@ -1042,86 +870,50 @@
)
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]
- )
+ let(:sequencing_tubes) do
+ prepare_created_child_tubes(
+ [
+ # sample 1 from well A1 to sequencing tube 1 in A1
+ { name: 'SEQ:NT1O:A1', foreign_barcode: 'FX00000001' },
+ # sample 2 from well B1 to sequencing tube 2 in B1
+ { name: 'SEQ:NT2P:B1', foreign_barcode: 'FX00000002' }
+ ]
)
end
# stub the transfer creation
let!(:stub_transfer_creation_request) do
+ parent_wells = [parent_well_a1, parent_well_b1]
+ transfer_requests =
+ parent_wells.map.with_index do |parent_well, index|
+ {
+ 'submission_id' => '2',
+ 'source_asset' => parent_well.uuid,
+ 'target_asset' => sequencing_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' }
- ]
+ transfer_requests: transfer_requests
}
},
body: '{}'
)
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 }
-
- # need to stub the creation of the tube metadata
- 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 } }
-
- before do
- stub_v2_user(user)
-
- stub_v2_labware(child_tube_1_v2)
- stub_v2_labware(child_tube_2_v2)
- end
+ before { stub_v2_user(user) }
it 'creates the child tubes' do
- expect_api_v2_posts('CustomMetadatumCollection', [tube_1_create_args, tube_2_create_args])
+ # Contingency tubes creation
+ expect_specific_tube_creation(child_sequencing_tube_purpose_uuid, sequencing_tubes)
+ expect_custom_metadatum_collection_posts({ 'TR00000001' => sequencing_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_transfer_creation_request).to have_been_made.once
end
end
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 a15f483ef..48cf5ae39 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
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 90ca78426..1ee701ebc 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
@@ -51,54 +51,43 @@
let(:form_attributes) { { user_uuid:, purpose_uuid:, parent_uuid:, barcodes: } }
- 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
diff --git a/spec/models/labware_creators/quadrant_stamp_primer_panel_spec.rb b/spec/models/labware_creators/quadrant_stamp_primer_panel_spec.rb
index 6c5abbe77..488f372c8 100644
--- a/spec/models/labware_creators/quadrant_stamp_primer_panel_spec.rb
+++ b/spec/models/labware_creators/quadrant_stamp_primer_panel_spec.rb
@@ -13,7 +13,6 @@
let(:parent1_uuid) { 'example-plate-uuid' }
let(:parent2_uuid) { 'example-plate2-uuid' }
- let(:child_uuid) { 'child-uuid' }
let(:requests) { Array.new(96) { |i| create :gbs_library_request, state: 'started', uuid: "request-#{i}" } }
let(:requests2) { Array.new(96) { |i| create :gbs_library_request, state: 'started', uuid: "request-#{i}" } }
let(:stock_plate1) { create :v2_stock_plate_for_plate, barcode_number: '1' }
@@ -40,20 +39,18 @@
stock_plate: stock_plate2
)
end
- let(:child_plate_v2) { create :v2_plate, uuid: child_uuid, barcode_number: '5', size: 384 }
- let(:child_plate_v1) { json :stock_plate_with_metadata, stock_plate: { barcode: '5', uuid: child_uuid } }
+ let(:child_plate) { create :v2_plate, barcode_number: '5', size: 384 }
let(:child_purpose_uuid) { 'child-purpose' }
let(:child_purpose_name) { 'Child Purpose' }
- let(:user_uuid) { 'user-uuid' }
- let(:v1_user) { json :v1_user, uuid: user_uuid }
- let(:user) { create :user, uuid: user_uuid }
+ let(:user) { create :user }
before do
create :purpose_config, name: child_purpose_name
+ stub_v2_user(user)
stub_v2_plate(parent1, stub_search: false)
stub_v2_plate(parent2, stub_search: false)
- stub_v2_plate(child_plate_v2, stub_search: false, custom_query: [:plate_with_wells, child_plate_v2.uuid])
+ stub_v2_plate(child_plate, stub_search: false, custom_query: [:plate_with_wells, child_plate.uuid])
end
context 'on new' do
@@ -75,7 +72,7 @@
end
context 'on create' do
- subject { LabwareCreators::QuadrantStampPrimerPanel.new(api, form_attributes.merge(user_uuid:)) }
+ subject { LabwareCreators::QuadrantStampPrimerPanel.new(api, form_attributes.merge(user_uuid: user.uuid)) }
let(:form_attributes) do
{
@@ -246,20 +243,6 @@
}
end
- let!(:pooled_plate_creation_request) do
- stub_api_post(
- 'pooled_plate_creations',
- payload: {
- pooled_plate_creation: {
- user: user_uuid,
- child_purpose: child_purpose_uuid,
- parents: [parent1_uuid, parent2_uuid]
- }
- },
- body: json(:plate_creation, child_uuid:)
- )
- end
-
let(:transfer_requests) do
[
{ source_asset: '3-well-A1', outer_request: 'request-0', target_asset: '5-well-A1' },
@@ -290,7 +273,7 @@
'transfer_request_collections',
payload: {
transfer_request_collection: {
- user: user_uuid,
+ user: user.uuid,
transfer_requests: transfer_requests
}
},
@@ -298,37 +281,44 @@
)
end
- context '#save!' do
- setup do
- stub_api_get(child_plate_v2.uuid, body: child_plate_v1)
- stub_api_get(
- 'custom_metadatum_collection-uuid',
- body: json(:v1_custom_metadatum_collection, uuid: 'custom_metadatum_collection-uuid')
- )
- stub_api_get('user-uuid', body: v1_user)
- stub_v2_user(user)
- stub_api_get('asset-uuid', body: child_plate_v1)
+ let(:pooled_plate_creation) do
+ response = double
+ allow(response).to receive(:child).and_return(child_plate)
- metadata =
- attributes_for(:v1_custom_metadatum_collection).fetch(:metadata, {}).merge(
- stock_barcode_q0: stock_plate1.barcode.human,
- stock_barcode_q1: stock_plate2.barcode.human
- )
+ response
+ end
- stub_api_put(
- 'custom_metadatum_collection-uuid',
- payload: {
- custom_metadatum_collection: {
- metadata:
- }
- },
- body: json(:v1_custom_metadatum_collection)
- )
- end
+ def expect_pooled_plate_creation
+ expect_api_v2_posts(
+ 'PooledPlateCreation',
+ [{ child_purpose_uuid: child_purpose_uuid, parent_uuids: [parent1_uuid, parent2_uuid], user_uuid: user.uuid }],
+ [pooled_plate_creation]
+ )
+ end
+ def expect_custom_metadatum_collection_creation
+ expect_api_v2_posts(
+ 'CustomMetadatumCollection',
+ [
+ {
+ asset_id: child_plate.id,
+ metadata: {
+ stock_barcode_q0: stock_plate1.barcode.human,
+ stock_barcode_q1: stock_plate2.barcode.human
+ },
+ user_id: user.id
+ }
+ ]
+ )
+ end
+
+ context '#save!' do
it 'creates a plate!' do
+ expect_pooled_plate_creation
+ expect_custom_metadatum_collection_creation
+
subject.save!
- expect(pooled_plate_creation_request).to have_been_made.once
+
expect(transfer_creation_request).to have_been_made.once
end
end
diff --git a/spec/support/api_url_helper.rb b/spec/support/api_url_helper.rb
index 2e720069e..38bfc39ba 100644
--- a/spec/support/api_url_helper.rb
+++ b/spec/support/api_url_helper.rb
@@ -92,16 +92,16 @@ def stub_api_v2_save(klass)
allow_any_instance_of(receiving_class).to receive(:save).and_return(true)
end
- def stub_api_v2_post(klass, return_value = nil)
- # intercepts the 'create!' method for any class beginning with
- # 'Sequencescape::Api::V2::' and returns the given value or else true.
+ def stub_api_v2_post(klass, return_value = nil, method: :create!)
+ # intercepts the specified `method` for any class beginning with
+ # 'Sequencescape::Api::V2::' and returns the given `return_value`, or else `true`.
receiving_class = "Sequencescape::Api::V2::#{klass}".constantize
return_value ||= true
- allow(receiving_class).to receive(:create!).and_return(return_value)
+ allow(receiving_class).to receive(method).and_return(return_value)
end
- def expect_api_v2_posts(klass, args_list, return_values = [])
- # Expects the 'create!' method for any class beginning with
+ def expect_api_v2_posts(klass, args_list, return_values = [], method: :create!)
+ # Expects the specified `method` for any class beginning with
# 'Sequencescape::Api::V2::' to be called with given arguments, in sequence, and returns the given values.
# If return_values is empty, it will return true.
receiving_class = "Sequencescape::Api::V2::#{klass}".constantize
@@ -109,7 +109,7 @@ def expect_api_v2_posts(klass, args_list, return_values = [])
.zip(return_values)
.each do |args, ret|
ret ||= true
- expect(receiving_class).to receive(:create!).with(args).and_return(ret)
+ expect(receiving_class).to receive(method).with(args).and_return(ret)
end
end
diff --git a/yarn.lock b/yarn.lock
index 9e8731f84..a2d8a360a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -620,6 +620,11 @@
resolved "https://registry.yarnpkg.com/@prettier/plugin-ruby/-/plugin-ruby-4.0.4.tgz#73d85fc2a1731a3f62b57ac3116cf1c234027cb6"
integrity sha512-lCpvfS/dQU5WrwN3AQ5vR8qrvj2h5gE41X08NNzAAXvHdM4zwwGRcP2sHSxfu6n6No+ljWCVx95NvJPFTTjCTg==
+"@rails/ujs@^7.1.3":
+ version "7.1.402"
+ resolved "https://registry.yarnpkg.com/@rails/ujs/-/ujs-7.1.402.tgz#5d4e7e5d1e2e22df081bf5693fc75f0725635130"
+ integrity sha512-q9dDlIR+anDtuGcV56rLnqHAxtWo8vkSnvfFt7juthvHc+97NEtGlnM++uhvnlDbR+7EGkX8nGqQIF8R93oWMQ==
+
"@rollup/rollup-android-arm-eabi@4.22.4":
version "4.22.4"
resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.22.4.tgz#8b613b9725e8f9479d142970b106b6ae878610d5"
@@ -1230,10 +1235,10 @@ cytoscape-popper@^2.0.0:
dependencies:
"@popperjs/core" "^2.0.0"
-cytoscape@^3.30.0:
- version "3.30.0"
- resolved "https://registry.yarnpkg.com/cytoscape/-/cytoscape-3.30.0.tgz#5b0c13f7bb305481e2c70414d4c5f149d92eda82"
- integrity sha512-l590mjTHT6/Cbxp13dGPC2Y7VXdgc+rUeF8AnF/JPzhjNevbDJfObnJgaSjlldOgBQZbue+X6IUZ7r5GAgvauQ==
+cytoscape@^3.30.2:
+ version "3.30.2"
+ resolved "https://registry.yarnpkg.com/cytoscape/-/cytoscape-3.30.2.tgz#94149707fb6547a55e3b44f03ffe232706212161"
+ integrity sha512-oICxQsjW8uSaRmn4UK/jkczKOqTrVqt5/1WL0POiJUT2EKNc9STM4hYFHv917yu55aTBMFNRzymlJhVAiWPCxw==
data-urls@^5.0.0:
version "5.0.0"
@@ -3058,16 +3063,8 @@ std-env@^3.7.0:
resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.7.0.tgz#c9f7386ced6ecf13360b6c6c55b8aaa4ef7481d2"
integrity sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==
-"string-width-cjs@npm:string-width@^4.2.0":
- version "4.2.3"
- resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
- integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
- dependencies:
- emoji-regex "^8.0.0"
- is-fullwidth-code-point "^3.0.0"
- strip-ansi "^6.0.1"
-
-string-width@^4.1.0:
+"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0:
+ name string-width-cjs
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -3085,14 +3082,8 @@ string-width@^5.0.1, string-width@^5.1.2:
emoji-regex "^9.2.2"
strip-ansi "^7.0.1"
-"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
- version "6.0.1"
- resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
- integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
- dependencies:
- ansi-regex "^5.0.1"
-
-strip-ansi@^6.0.0, strip-ansi@^6.0.1:
+"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
+ name strip-ansi-cjs
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -3274,15 +3265,15 @@ vite-node@2.0.5:
tinyrainbow "^1.2.0"
vite "^5.0.0"
-vite-plugin-ruby@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/vite-plugin-ruby/-/vite-plugin-ruby-5.0.0.tgz#cd891198a7672f2e8402439f53ab9d2b08f6502d"
- integrity sha512-c8PjTp21Ah/ttgnNUyu0qvCXZI08Jr9I24oUKg3TRIRhF5GcOZ++6wtlTCrNFd9COEQbpXHxlRIXd/MEg0iZJw==
+vite-plugin-ruby@^5.1.0:
+ version "5.1.0"
+ resolved "https://registry.yarnpkg.com/vite-plugin-ruby/-/vite-plugin-ruby-5.1.0.tgz#489f2071ea6d86b5db735ea1fbbbe10e50e8e9bc"
+ integrity sha512-Dgd/dCvb/8GYxZx2NEgxygEoUpHz9vfad7itlO4fXqYwdfAEwFwwOohC630yf/+kxIGBZXI5yk+Y3WkL9VkwcA==
dependencies:
debug "^4.3.4"
fast-glob "^3.3.2"
-vite@^5.0.0, vite@^5.4.7:
+vite@^5.0.0:
version "5.4.7"
resolved "https://registry.yarnpkg.com/vite/-/vite-5.4.7.tgz#d226f57c08b61379e955f3836253ed3efb2dcf00"
integrity sha512-5l2zxqMEPVENgvzTuBpHer2awaetimj2BGkhBPdnwKbPNOlHsODU+oiazEZzLK7KhAnOrO+XGYJYn4ZlUhDtDQ==