diff --git a/app/api/core/abilities.rb b/app/api/core/abilities.rb deleted file mode 100644 index 863acbdb43..0000000000 --- a/app/api/core/abilities.rb +++ /dev/null @@ -1,197 +0,0 @@ -# frozen_string_literal: true - -# The classes within this namespace are responsible for defining the abilities of the user and the application -# that are accessing the API. -# -#-- -# To maintain the behaviour of the API before this was introduced the logic is very straight-forward: -# -# 1. If the application is authorised then everything is possible. -# 2. If the application is unauthorised then the user capabilities take priority. -# -# There are several pieces of functionality that are always accessible: -# -# - UUID lookups are always available -# - Searches are always available -# - Submissions can be created and updated -# - Sample manifests can be created through studies and updated individually -# -# In the future we'll be able to adjust this and get the right behaviour based on the combination of the -# application and the user. We'll also be able to extend the application abilities so that they are refined -# for certain applications. -#++ -module Core::Abilities - def self.create(request) - CompositeAbility.new(request) - end - - module ActionBehaviour - # Modify the behaviour so that we can only access the action if the ability permits and the super - # implementation permits it too. - def accessible_action?(handler, action, request, object) - request.ability.can?(action, handler, object) and super - end - private :accessible_action? - end - - class CompositeAbility #:nodoc: - attr_reader :user, :application - private :user, :application - - def initialize(request) - @user, @application = User.new(request), Application.new(request) - @application.authenticate!(@user) - end - - def can?(...) - application.can?(...) or user.can?(...) - end - end - - class Base - class Recorder #:nodoc: - def initialize - @recorded = [] - end - - def play_back(target) - @recorded.each { |block| target.instance_eval(&block) } - end - - def record(&block) - @recorded << block - end - end - - module ClassMethods - def recorder_helper(name) - line = __LINE__ + 1 - singleton_class.class_eval( - " - def #{name}(&block) - record(@#{name} ||= Recorder.new, &block) - end - ", - __FILE__, - line - ) - end - - def record(recorder, &block) - recorder.tap { |recorder| recorder.record(&block) if block } - end - private :record - end - - require 'cancancan' - include CanCan::Ability - extend ClassMethods - - recorder_helper(:full) - recorder_helper(:unregistered) - - def initialize(request) - @request = request - abilitise(:unregistered) - abilitise(privilege) if registered? - end - - def abilitise(name) - self.class.send(name).play_back(self) - end - private :abilitise - end - - class User < Base - unregistered do - # The API is designed to be read-only, at least. - can(:read, :all) - end - - recorder_helper(:authenticated) - - authenticated do - # Submissions should be createable & updateable by anyone - can(:create, Endpoints::Submissions::Model) - can(:create, Endpoints::OrderTemplates::Instance::Orders) - can(:update, Endpoints::Orders::Instance) - can(:create, Endpoints::Submissions::Instance::Submit) - can(:update, Endpoints::Submissions::Instance) - - # Sample manifests should also be createable & updateable by anyone - can(:update, Endpoints::SampleManifests::Instance) - can(:create, Endpoints::Studies::Instance::SampleManifests::CreateForPlates) - can(:create, Endpoints::Studies::Instance::SampleManifests::CreateForTubes) - can(:create, Endpoints::Studies::Instance::SampleManifests::CreateForMultiplexedLibraries) - end - - def registered? - false - end - private :registered? - - # Updates the abilities of the user based on the currently authenticated user instance. If the user - # unauthenticated then the API remains read-only. - def authenticated! - abilitise(:authenticated) if @request.user.present? - end - end - - class Application < Base - recorder_helper(:tag_plates) - - def initialize(request) - @api_application = ApiApplication.find_by(key: request.authorisation_code) - super - end - - def privilege - @api_application.privilege.to_sym - end - - unregistered do - # The API is designed to be read-only, at least. - can(:read, :all) - - # Every application is entitled to be able to lookup UUIDs and make searches - can(:create, [Endpoints::Uuids::Model::Lookup, Endpoints::Uuids::Model::Bulk]) - can( - :create, - [Endpoints::Searches::Instance::First, Endpoints::Searches::Instance::All, Endpoints::Searches::Instance::Last] - ) - end - - # Registered applications can manage all objects that allow it and can have unauthenticated users. - full do - can(:manage, :all) - can(:authenticate, :all) - end - - # State changes only - tag_plates do - can(:create, [Endpoints::StateChanges::Model]) - can(:authenticate, :all) - end - - def registered? - @api_application.present? - end - private :registered? - - # The decision as to whether the application requires the user to be authenticated is made - # by the application. If it does, however, then the user abilities may need to be changed - # so we need to modify that too. - def authenticate!(user_ability) - single_sign_on_cookie = @request.authentication_code - if single_sign_on_cookie.blank? && cannot?(:authenticate, :nil) - Core::Service::Authentication::UnauthenticatedError.no_cookie! - elsif single_sign_on_cookie.present? - user = ::User.find_by(api_key: single_sign_on_cookie) or - Core::Service::Authentication::UnauthenticatedError.unauthenticated! - @request.service.instance_variable_set(:@user, user) - end - - user_ability.authenticated! - end - end -end diff --git a/app/api/core/benchmarking.rb b/app/api/core/benchmarking.rb deleted file mode 100644 index c0b13ee420..0000000000 --- a/app/api/core/benchmarking.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true - -module Core::Benchmarking - def self.registered(app) - app.helpers self - end - - def benchmark(_message = nil) - yield - # ActiveRecord::Base.benchmark("===== API benchmark (#{message || 'general'}):", Logger::ERROR, &block) - end -end diff --git a/app/api/core/endpoint/base.rb b/app/api/core/endpoint/base.rb deleted file mode 100644 index 860796e0e6..0000000000 --- a/app/api/core/endpoint/base.rb +++ /dev/null @@ -1,112 +0,0 @@ -# frozen_string_literal: true - -# @abstract Define new endpoints by specifying {#model} and {#instance} actions -# -# Core class for {file:docs/api_v1.md API V1} endpoints, which effectively acts as a controller layer. -# New endpoints should be placed in `app/api/endpoints/` and should inherit from Core::Endpoint::Base. -# All endpoints are in the {Endpoints} namespace. -# -# @example Asset Audit -# class ::Endpoints::AssetAudits < ::Core::Endpoint::Base -# model do -# action(:create) do |request, _response| -# request.create! -# end -# end -# -# instance do -# belongs_to(:asset, json: 'asset') -# end -# end -# -# {#model model} defines actions on the collection, in the asset audit example a -# create action on `api/1/asset_audits` -# -# {#instance instance} defines actions on individual instances, usually accessed via -# their uuid. In this case each asset audit has an asset action which returns the associated asset. -# ie. `api/1/000000-0000-0000-0000-000000000000/asset` -# -# There is no need to modify the routes when adding endpoints. -# -# It is not necessary to define index or show endpoints, these are defined by default. -# -# @see Core::Endpoint::Base::InstanceBehaviour -# @see Core::Endpoint::Base::ModelBehaviour -# @see Core::Endpoint::BasicHandler -class Core::Endpoint::Base - # Adds ability to define instance endpoints to Core::Endpoint::Base - module InstanceBehaviour - # @abstract Sub-classed automatically for each instance endpoint, and effectively acts as a controller. - class Handler < Core::Endpoint::BasicHandler - standard_action(:read) - - private - - def _read(request, _) - yield(self, request.target) - end - end - - def self.extended(base) - base.class_attribute :instance_handler, instance_writer: false - end - - # - # Opens up a block for defining endpoints on an instance of the model - # @yield [] Yields control to block evaluated by the InstanceBehaviour::Handler - # This is where you define your actions. - # - # @return [Void] - def instance(&) - handler = Class.new(Handler).tap { |handler_class| const_set(:Instance, handler_class) }.new(&) - handler.instance_variable_set(:@name, name) - self.instance_handler = handler - end - end - - # Adds ability to define collection endpoints to Core::Endpoint::Base - module ModelBehaviour - # @abstract Sub-classed automatically for each model endpoint, and effectively acts as a controller. - class Handler < Core::Endpoint::BasicHandler - include Core::Endpoint::BasicHandler::Paged - - standard_action(:read) - - private - - def _read(request, _) - request - .target - .order(:id) - .scoping do - page = request.path.first.try(:to_i) || 1 - results = page_of_results(request.io.eager_loading_for(request.target).include_uuid, page, request.target) - results.singleton_class.send(:define_method, :model) { request.target } - yield(self, results) - end - end - end - - def self.extended(base) - base.class_attribute :model_handler, instance_writer: false - end - - # - # Opens up a block for defining endpoints on the collection for a given model - # @yield [] Yields control to block evaluated by the ModelBehaviour::Handler - # This is where you define your actions. - # - # @return [Void] - def model(&) - handler = Class.new(Handler).tap { |handler_class| const_set(:Model, handler_class) }.new(&) - self.model_handler = handler - end - end - - extend InstanceBehaviour - extend ModelBehaviour - - def self.root - name.sub(/^(::)?Endpoints::/, '').underscore.pluralize - end -end diff --git a/app/api/core/endpoint/basic_handler/actions.rb b/app/api/core/endpoint/basic_handler/actions.rb index 0d80310e43..f9721b7e17 100644 --- a/app/api/core/endpoint/basic_handler/actions.rb +++ b/app/api/core/endpoint/basic_handler/actions.rb @@ -13,7 +13,7 @@ def self.included(base) include Core::Endpoint::BasicHandler::Actions::Factory include Core::Endpoint::BasicHandler::Actions::Guards include Core::Endpoint::BasicHandler::EndpointLookup - include Core::Abilities::ActionBehaviour + # include Core::Abilities::ActionBehaviour end end diff --git a/app/api/core/initializable.rb b/app/api/core/initializable.rb deleted file mode 100644 index 62c6fc1f50..0000000000 --- a/app/api/core/initializable.rb +++ /dev/null @@ -1,44 +0,0 @@ -# frozen_string_literal: true - -module Core::Initializable - class Initializer - def initialize(owner) - @owner = owner - end - - class << self - def delegated_attribute_writer(*names) - names.each { |name| class_eval("def #{name}=(value) ; @owner.instance_variable_set(:@#{name}, value) ; end") } - delegate_to_owner(*names) - end - - def delegate_to_owner(*names) - delegate(*names, to: :@owner) - end - end - end - - def self.extended(base) - base.class_eval do - include InstanceMethods - - const_set(:Initializer, Class.new(Core::Initializable::Initializer)) - end - end - - def initialized_attr_reader(*names) - attr_reader(*names) - - self::Initializer.delegated_attribute_writer(*names) - end - - def initialized_delegate(*names) - self::Initializer.delegate_to_owner(*names) - end - - module InstanceMethods - def initialize - yield(self.class::Initializer.new(self)) if block_given? - end - end -end diff --git a/app/api/core/io/base.rb b/app/api/core/io/base.rb index f65f1a7f3b..2434b51320 100644 --- a/app/api/core/io/base.rb +++ b/app/api/core/io/base.rb @@ -17,8 +17,6 @@ # end # class Core::Io::Base - extend ::Core::Logging - extend ::Core::Benchmarking extend ::Core::Io::Base::EagerLoadingBehaviour extend ::Core::Io::Base::JsonFormattingBehaviour diff --git a/app/api/core/io/base/json_formatting_behaviour/input.rb b/app/api/core/io/base/json_formatting_behaviour/input.rb index dd20a333ec..0a6eaace9f 100644 --- a/app/api/core/io/base/json_formatting_behaviour/input.rb +++ b/app/api/core/io/base/json_formatting_behaviour/input.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true module Core::Io::Base::JsonFormattingBehaviour::Input - class ReadOnlyAttribute < ::Core::Service::Error + class ReadOnlyAttribute < StandardError def initialize(attribute) super('is read-only') @attribute = attribute diff --git a/app/api/core/io/list.rb b/app/api/core/io/list.rb index e2ebfc565f..bd37d6a104 100644 --- a/app/api/core/io/list.rb +++ b/app/api/core/io/list.rb @@ -1,7 +1,5 @@ # frozen_string_literal: true class Core::Io::List - include Core::Benchmarking - def initialize(command, objects) @command, @container = command, command.send(:container) @objects = objects.map { |o| Core::Io::Registry.instance.lookup(o.class).create!(@container, o) } diff --git a/app/api/core/logging.rb b/app/api/core/logging.rb deleted file mode 100644 index 68b3a3a4c2..0000000000 --- a/app/api/core/logging.rb +++ /dev/null @@ -1,35 +0,0 @@ -# frozen_string_literal: true - -module Core::Logging - # @deprecated This method does not appear to be used and will be removed in a future version. - # Use Rails.logger.debug directly instead. - def debug(message) - Rails.logger.debug(add_api_context(message)) - end - - # @deprecated This method does not appear to be used and will be removed in a future version. - # Use Rails.logger.debug directly instead. - def info(message) - Rails.logger.info(add_api_context(message)) - end - - def error(message) - Rails.logger.error(add_api_context(message)) - end - - def low_level(*args) - # debug(*args) - end - - private - - # Add API context to the log message from the instance's class name. - # - # @param message [String] The log message to be formatted. - # @return [String] The formatted log message with API context. - # Example: "API(ClassName): Log message" - def add_api_context(message) - class_name = self.class.name - "API(#{class_name}): #{message}" - end -end diff --git a/app/api/core/references.rb b/app/api/core/references.rb deleted file mode 100644 index 0f31007104..0000000000 --- a/app/api/core/references.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true - -module Core::References - # Discards all of the references that this object is keeping to other objects. This means that - # all of the objects should be garbage collected, rather than a proportion that are external to an - # instance of this class. - def discard_all_references - instance_variables.each { |name| instance_variable_set(name, nil) } - end - private :discard_all_references -end diff --git a/app/api/core/registry.rb b/app/api/core/registry.rb index 7943750814..c0188071d5 100644 --- a/app/api/core/registry.rb +++ b/app/api/core/registry.rb @@ -2,7 +2,6 @@ class Core::Registry include ::Singleton - include ::Core::Logging RegistryError = Class.new(StandardError) AlreadyRegisteredError = Class.new(RegistryError) diff --git a/app/api/core/service.rb b/app/api/core/service.rb deleted file mode 100644 index 2ea9b16d41..0000000000 --- a/app/api/core/service.rb +++ /dev/null @@ -1,266 +0,0 @@ -# frozen_string_literal: true -require 'sinatra/base' -module Core - class Service < Sinatra::Base - API_VERSION = 1 - - class Error < StandardError - module Behaviour - def self.included(base) - base.class_eval do - class_attribute :api_error_code - class_attribute :api_error_message - alias_method :api_error_message, :message - self.api_error_code = 500 - end - end - - def api_error(response) - response.general_error(self.class.api_error_code, [self.class.api_error_message || api_error_message]) - end - end - - include Behaviour - end - - class UnsupportedAction < Error - self.api_error_code = 501 - self.api_error_message = 'requested action is not supported on this resource' - end - - class DeprecatedAction < Error - self.api_error_code = 410 - self.api_error_message = 'requested action is no longer supported' - end - - class MethodNotAllowed < Error - def initialize(allowed_http_verbs) - super('HTTP verb was not allowed!') - @allowed = Array(allowed_http_verbs).map(&:to_s).map(&:upcase).join(',') - end - - self.api_error_code = 405 - self.api_error_message = 'unsupported action' - - def api_error(response) - response.headers('Allow' => @allowed) - super - end - end - - # Report the performance and status of any request - def report(handler) - Rails.logger.info("API[start]: #{handler}: #{request.fullpath}") - yield - ensure - Rails.logger.info("API[handled]: #{handler}: #{request.fullpath}") - end - private :report - - # Disable the Sinatra rubbish that happens in the development environment because we want - # Rails to do all of the handling if we don't - set(:environment, Rails.env) - - # This ensures that our Sinatra applications behave properly within the Rails environment. - # Without this you'll find that only one of the services actually behaves properly, the others - # will all fail with 404 errors. - def handle_not_found!(_boom) - @response.status = 404 - @response.headers['X-Cascade'] = 'pass' - @response.body = nil - end - - # Configure a handler for the cucumber environment that logs the error to the console so that - # we can see it. - configure :cucumber do - error(Exception) do - $stderr.puts exception_thrown.message - $stderr.puts exception_thrown.backtrace.join("\n") - raise exception_thrown - end - end - - def redirect_to(url, body) - status(301) # Moved permanently - headers('Location' => url) - body(body) - end - - def redirect_to_multiple_locations(body) - status(300) # Multiple content - body(body) - end - - def self.api_version_path - @version = "api/#{API_VERSION}" - end - - def api_path(*sub_path) - "#{request.scheme}://#{request.host_with_port}/#{self.class.api_version_path}/#{sub_path.compact.join('/')}" - end - - def self.before_all_actions(&) - before('/*', &) - end - - def self.after_all_actions(&) - after('/*', &) - end - - attr_reader :command - - register Core::Benchmarking - register Core::Service::ErrorHandling - register Core::Service::Authentication - register Core::Service::ContentFiltering - - class Request - extend Core::Initializable - include Core::References - include Core::Benchmarking - include Core::Service::EndpointHandling - - initialized_attr_reader :service, :target, :path, :io, :json, :file, :filename - attr_writer :io, :file, :filename - attr_reader :ability, :identifier, :started_at - - delegate :user, to: :service - - def initialize(identifier, *, &) - @identifier, @started_at = identifier, Time.zone.now - super(*, &) - @ability = Core::Abilities.create(self) - end - - def authorisation_code - @service.request.env['HTTP_X_SEQUENCESCAPE_CLIENT_ID'] - end - - def authentication_code - # The WTSISignOn service has been retired. However previously the code - # supported supplying the API key in this cookie, so this has been left - # for compatibility purposes - @service.request.cookies['api_key'] || @service.request.cookies['WTSISignOn'] - end - - def response(&) - ::Core::Service::Response.new(self, &) - end - - # Safe way to push a particular value on to the request target stack. Ensures that the - # original value is reset when the block is exitted. - def push(value) - target_before, @target = @target, value - yield - ensure - @target = target_before - end - - def attributes(_object = nil) - io.map_parameters_to_attributes(json, nil) - end - - def create!(instance_attributes = attributes) - ActiveRecord::Base.transaction do - record = target.create!(instance_attributes) - ::Core::Io::Registry - .instance - .lookup_for_object(record) - .eager_loading_for(record.class) - .include_uuid - .find(record.id) - end - end - - def update!(instance_attributes = attributes) - ActiveRecord::Base.transaction { target.tap { |o| o.update!(instance_attributes) } } - end - end - - include Core::Endpoint::BasicHandler::EndpointLookup - - # A response from an endpoint handler is made of a pair of values. One is the object that - # is to be sent back to the client in JSON. The other is the endpoint handler that dealt - # with the request and that provides the actions that are available for said object. So - # the JSON that is actually returned is a merge of the object JSON and the actions. - class Response - extend Core::Initializable - include Core::References - include Core::Benchmarking - - class Initializer - delegate :status, :headers, :api_path, to: '@owner.request.service' - - # Causes a response that will redirect the client to the specified UUID path. - def redirect_to(uuid) - status(301) - headers('Location' => api_path(uuid)) - end - - # If you want to return multiple records as a kind of "redirect" then this is the - # method you want to use! - def multiple_choices - status(300) - end - end - - attr_reader :request - - initialized_attr_reader :handled_by, :object - - delegate :io, :identifier, :started_at, to: :request - - delegate :status, to: 'request.service' - initialized_delegate :status - - delegate :endpoint_for_object, to: 'request.service' - private :endpoint_for_object - - def initialize(request, &) - @request, @io, @include_actions = request, nil, true - status(200) - super(&) - end - - #-- - # Note that this method disables garbage collection, which should improve the performance of writing - # out the JSON to the client. The garbage collection is then re-enabled in close. - #++ - # rubocop:todo Metrics/MethodLength - def each(&block) # rubocop:todo Metrics/AbcSize - Rails.logger.info('API[streaming]: starting JSON streaming') - start = Time.zone.now - - ::Core::Io::Buffer.new(block) do |buffer| - ::Core::Io::Json::Stream - .new(buffer) - .open do |stream| - ::Core::Io::Registry - .instance - .lookup_for_object(object) - .as_json(response: self, target: object, stream: stream, object: object, handled_by: handled_by) - end - end - - Rails.logger.info("API[streaming]: finished JSON streaming in #{Time.zone.now - start}s") - end - - # rubocop:enable Metrics/MethodLength - - def close - identifier, started_at = self.identifier, self.started_at # Save for later as next line discards our request! - discard_all_references - ensure - Rails.logger.info("API[finished]: #{identifier} in #{Time.zone.now - started_at}s") - end - - def discard_all_references - request.send(:discard_all_references) - super - # NOTE: Previously we released our connection here, which prevented rails from - # properly sweeping the query cache. - end - private :discard_all_references - end - end -end diff --git a/app/api/core/service/authentication.rb b/app/api/core/service/authentication.rb deleted file mode 100644 index 10c40e436b..0000000000 --- a/app/api/core/service/authentication.rb +++ /dev/null @@ -1,26 +0,0 @@ -# frozen_string_literal: true -module Core::Service::Authentication - class UnauthenticatedError < Core::Service::Error - def self.no_cookie! - raise self, 'no authentication provided' - end - - def self.unauthenticated! - raise self, 'could not be authenticated' - end - - def api_error(response) - response.general_error(401) - end - end - - module Helpers - def user - @user - end - end - - def self.registered(app) - app.helpers Helpers - end -end diff --git a/app/api/core/service/content_filtering.rb b/app/api/core/service/content_filtering.rb deleted file mode 100644 index 4874ba3c14..0000000000 --- a/app/api/core/service/content_filtering.rb +++ /dev/null @@ -1,70 +0,0 @@ -# frozen_string_literal: true -# Everything coming in and going out should be JSON. -module Core::Service::ContentFiltering - class InvalidRequestedContentType < ::Core::Service::Error - self.api_error_code = 406 - self.api_error_message = - "the 'Accept' header can only be 'application/json' or a supported filetype eg.'sequencescape/qc_file'" - end - - class InvalidRequestedContentTypeOnFile < ::Core::Service::Error - self.api_error_code = 406 - self.api_error_message = "the 'Accept' header can only be 'application/json' when submitting a file" - end - - class InvalidBodyContentType < ::Core::Service::Error - self.api_error_code = 415 - self.api_error_message = - "the 'Content-Type' can only be 'application/json' or a supported filetype eg.'sequencescape/qc_file'" - end - - module Helpers - def json - @json - end - - def process_request_body # rubocop:todo Metrics/AbcSize - content = request.body.read - if content.present? && acceptable_types.exclude?(request.content_type) - raise Core::Service::ContentFiltering::InvalidBodyContentType - end - - if request.content_type == 'application/json' || content.blank? - @json = content.blank? ? {} : MultiJson.load(content) - end - ensure - # It's important to ensure that the body IO object has been rewound to the start for other requests. - request.body.rewind - end - - def process_response_body - headers('Content-Type' => request_accepted.first) - end - - ACCEPTABLE_TYPES = Rails.env.development? ? %w[application/json */*].freeze : ['application/json'].freeze - - def acceptable_types - ACCEPTABLE_TYPES + ::Api::EndpointHandler.registered_mimetypes - end - - def check_acceptable_content_type_requested! - accepts_json_or_star = request.acceptable_media_types.prioritize(*acceptable_types).present? - raise Core::Service::ContentFiltering::InvalidRequestedContentType unless accepts_json_or_star - end - - def request_accepted - request.acceptable_media_types.prioritize(*acceptable_types).map(&:to_s) - end - end - - def self.registered(app) - app.helpers Helpers - - app.before_all_actions do - check_acceptable_content_type_requested! - process_request_body - end - - app.after_all_actions { process_response_body } - end -end diff --git a/app/api/core/service/endpoint_handling.rb b/app/api/core/service/endpoint_handling.rb deleted file mode 100644 index fca70c3f4b..0000000000 --- a/app/api/core/service/endpoint_handling.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true -module Core::Service::EndpointHandling - def self.included(base) - base.class_eval { attr_reader :endpoint } - end - - def instance(action, endpoint) - @endpoint = endpoint - @endpoint.instance_handler.send(action, self, path) - end - - def model(action, endpoint) - @endpoint = endpoint - @endpoint.model_handler.send(action, self, path) - end -end diff --git a/app/api/core/service/error_handling.rb b/app/api/core/service/error_handling.rb deleted file mode 100644 index 4c6fe74001..0000000000 --- a/app/api/core/service/error_handling.rb +++ /dev/null @@ -1,110 +0,0 @@ -# frozen_string_literal: true -module Core::Service::ErrorHandling - def self.registered(app) # rubocop:todo Metrics/AbcSize, Metrics/MethodLength - app.instance_eval do - helpers Helpers - - error( - ::IllegalOperation, - ::Core::Service::Error, - ActiveRecord::ActiveRecordError, - ActiveModel::ValidationError, - Aliquot::TagClash - ) do - buffer = [exception_thrown.message, exception_thrown.backtrace].join("\n") - Rails.logger.error("API[error]: #{buffer}") - exception_thrown.api_error(self) - end - error(StandardError) do - buffer = [exception_thrown.message, exception_thrown.backtrace].join("\n") - Rails.logger.error("API[error]: #{buffer}") - general_error(501) - end - end - end - - module Helpers - class JsonError - def initialize(error) - @error = error - end - - def each - yield JSON.generate(@error) - end - end - - def exception_thrown - @env['sinatra.error'] - end - - def general_error(code, errors = nil) - Rails.logger.error(exception_thrown.backtrace.join("\n")) - errors ||= [exception_thrown.message] - error(code, JsonError.new(general: errors)) - end - - def content_error(code, errors = nil) - error(code, JsonError.new(content: errors)) - end - end -end - -class ActiveRecord::ActiveRecordError - include ::Core::Service::Error::Behaviour - - self.api_error_code = 500 -end - -class ActiveRecord::RecordNotFound - self.api_error_code = 404 -end - -class ActiveRecord::AssociationTypeMismatch - self.api_error_code = 422 -end - -class ActiveRecord::RecordInvalid - def api_error(response) - io_handler = ::Core::Io::Registry.instance.lookup_for_object(record) - response.content_error(422, errors_grouped_by_attribute { |attribute| io_handler.json_field_for(attribute) }) - end - - def errors_grouped_by_attribute - record.errors.as_json.transform_keys { |k| yield(k) }.transform_values { |v| [v].flatten.uniq } - end - private :errors_grouped_by_attribute -end - -class ActiveModel::ValidationError - def api_error(response) - io_handler = ::Core::Io::Registry.instance.lookup_for_object(model) - response.content_error(422, errors_grouped_by_attribute { |attribute| io_handler.json_field_for(attribute) }) - end - - def errors_grouped_by_attribute - model.errors.to_hash { |k, v| [yield(k), [v].flatten.uniq] } - end - private :errors_grouped_by_attribute -end - -class ActiveRecord::RecordNotSaved - def api_error(response) - response.content_error(422, message) - end -end - -class IllegalOperation < RuntimeError - include ::Core::Service::Error::Behaviour - - self.api_error_code = 501 - self.api_error_message = 'requested action is not supported on this resource' -end - -class Aliquot::TagClash - include Core::Service::Error::Behaviour - - def self.api_error_code - 422 - end -end diff --git a/app/api/docs.md b/app/api/docs.md deleted file mode 100644 index 004ef8b2c5..0000000000 --- a/app/api/docs.md +++ /dev/null @@ -1 +0,0 @@ -@see {file:docs/api_v1.md} diff --git a/app/api/endpoints/asset_audits.rb b/app/api/endpoints/asset_audits.rb deleted file mode 100644 index ab2d3c0ced..0000000000 --- a/app/api/endpoints/asset_audits.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for AssetAudits -class Endpoints::AssetAudits < Core::Endpoint::Base - model { action(:create) { |request, _response| request.create! } } - - instance { belongs_to(:asset, json: 'asset') } -end diff --git a/app/api/endpoints/asset_groups.rb b/app/api/endpoints/asset_groups.rb deleted file mode 100644 index 3f865f13b6..0000000000 --- a/app/api/endpoints/asset_groups.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for AssetGroups -class Endpoints::AssetGroups < Core::Endpoint::Base - model {} - - instance do - belongs_to(:study, json: 'study') - belongs_to(:submission, json: 'submission') - has_many(:assets, include: [], json: 'assets', to: 'assets') - end -end diff --git a/app/api/endpoints/assets.rb b/app/api/endpoints/assets.rb deleted file mode 100644 index d030826174..0000000000 --- a/app/api/endpoints/assets.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for Assets -class Endpoints::Assets < Core::Endpoint::Base - model {} - - instance {} -end diff --git a/app/api/endpoints/bait_library_layouts.rb b/app/api/endpoints/bait_library_layouts.rb deleted file mode 100644 index af2cd7139d..0000000000 --- a/app/api/endpoints/bait_library_layouts.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for BaitLibraryLayouts -class Endpoints::BaitLibraryLayouts < Core::Endpoint::Base - model do - action(:create, to: :standard_create!) - - # You can preview a bait library layout, which is effectively an unsaved version of the one - # that will be created. - bind_action(:create, as: 'preview', to: 'preview') do |_, request, response| - request.target.preview!(request.attributes).tap { |_| response.status(200) } - end - end - - instance do - belongs_to(:plate, json: 'plate') - belongs_to(:user, json: 'user') - end -end diff --git a/app/api/endpoints/barcode_printers.rb b/app/api/endpoints/barcode_printers.rb deleted file mode 100644 index ecaf7656c9..0000000000 --- a/app/api/endpoints/barcode_printers.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for BarcodePrinters -class Endpoints::BarcodePrinters < Core::Endpoint::Base - model {} - - instance {} -end diff --git a/app/api/endpoints/batches.rb b/app/api/endpoints/batches.rb deleted file mode 100644 index 095c07b58d..0000000000 --- a/app/api/endpoints/batches.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for Batches -class Endpoints::Batches < Core::Endpoint::Base - model {} - - instance { belongs_to(:pipeline, json: 'pipeline') } -end diff --git a/app/api/endpoints/bulk_transfers.rb b/app/api/endpoints/bulk_transfers.rb deleted file mode 100644 index 4f7075f6cb..0000000000 --- a/app/api/endpoints/bulk_transfers.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for BulkTransfers -class Endpoints::BulkTransfers < Core::Endpoint::Base - model { action(:create, to: :standard_create!) } - - instance do - belongs_to(:user, json: 'user') - has_many(:transfers, json: 'transfers', to: 'transfers') - end -end diff --git a/app/api/endpoints/comments.rb b/app/api/endpoints/comments.rb deleted file mode 100644 index 689e5b0a12..0000000000 --- a/app/api/endpoints/comments.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for Comments -class Endpoints::Comments < Core::Endpoint::Base - model {} - - instance { belongs_to(:user, json: 'user') } -end diff --git a/app/api/endpoints/custom_metadatum_collections.rb b/app/api/endpoints/custom_metadatum_collections.rb deleted file mode 100644 index 5601f7d3d4..0000000000 --- a/app/api/endpoints/custom_metadatum_collections.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for CustomMetadatumCollections -class Endpoints::CustomMetadatumCollections < Core::Endpoint::Base - model { action(:create, to: :standard_create!) } - - instance do - belongs_to(:asset, json: 'asset', to: 'asset') - belongs_to(:user, json: 'user', to: 'user') - action(:update, to: :standard_update!) - end -end diff --git a/app/api/endpoints/dilution_plate_purposes.rb b/app/api/endpoints/dilution_plate_purposes.rb deleted file mode 100644 index 95d31f2c72..0000000000 --- a/app/api/endpoints/dilution_plate_purposes.rb +++ /dev/null @@ -1,4 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for DilutionPlatePurposes -class Endpoints::DilutionPlatePurposes < Endpoints::PlatePurposes -end diff --git a/app/api/endpoints/extraction_attributes.rb b/app/api/endpoints/extraction_attributes.rb deleted file mode 100644 index ea170ab622..0000000000 --- a/app/api/endpoints/extraction_attributes.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for ExtractionAttributes -class Endpoints::ExtractionAttributes < Core::Endpoint::Base - model { action(:create, to: :standard_create!) } - - instance { belongs_to(:target, json: 'target') } -end diff --git a/app/api/endpoints/lanes.rb b/app/api/endpoints/lanes.rb deleted file mode 100644 index a3e81b6ce4..0000000000 --- a/app/api/endpoints/lanes.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for Lanes -class Endpoints::Lanes < Core::Endpoint::Base - model {} - - instance { has_many(:requests, json: 'requests', to: 'requests') } -end diff --git a/app/api/endpoints/library_creation_requests.rb b/app/api/endpoints/library_creation_requests.rb deleted file mode 100644 index 4b2ead4a16..0000000000 --- a/app/api/endpoints/library_creation_requests.rb +++ /dev/null @@ -1,4 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for LibraryCreationRequests -class Endpoints::LibraryCreationRequests < Endpoints::Requests -end diff --git a/app/api/endpoints/library_events.rb b/app/api/endpoints/library_events.rb deleted file mode 100644 index 8cff479975..0000000000 --- a/app/api/endpoints/library_events.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for LibraryEvents -class Endpoints::LibraryEvents < Core::Endpoint::Base - model { action(:create, to: :standard_create!) } - - instance do - belongs_to(:seed, json: 'seed') - belongs_to(:user, json: 'user') - end -end diff --git a/app/api/endpoints/library_tubes.rb b/app/api/endpoints/library_tubes.rb deleted file mode 100644 index ecab1823f6..0000000000 --- a/app/api/endpoints/library_tubes.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for LibraryTubes -class Endpoints::LibraryTubes < Endpoints::Tubes - instance do - belongs_to(:custom_metadatum_collection, json: 'custom_metadatum_collection', to: 'custom_metadatum_collection') - belongs_to(:purpose, json: 'purpose') - has_many(:requests_as_source, json: 'requests', to: 'requests') - belongs_to(:source_request, json: 'source_request') - end -end diff --git a/app/api/endpoints/lot_types.rb b/app/api/endpoints/lot_types.rb deleted file mode 100644 index 121ff4c993..0000000000 --- a/app/api/endpoints/lot_types.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for LotTypes -class Endpoints::LotTypes < Core::Endpoint::Base - model {} - - instance do - has_many(:lots, json: 'lots', to: 'lots') do - action(:create) do |request, _| - ActiveRecord::Base.transaction { request.target.proxy_association.owner.create!(request.attributes) } - end - end - end -end diff --git a/app/api/endpoints/lots.rb b/app/api/endpoints/lots.rb deleted file mode 100644 index 911d4357d4..0000000000 --- a/app/api/endpoints/lots.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for Lots -class Endpoints::Lots < Core::Endpoint::Base - model {} - - instance do - has_many(:qcables, json: 'qcables', to: 'qcables') - belongs_to(:lot_type, json: 'lot_type', to: 'lot_type') - belongs_to(:template, json: 'template', to: 'template') - end -end diff --git a/app/api/endpoints/multiplexed_library_creation_requests.rb b/app/api/endpoints/multiplexed_library_creation_requests.rb deleted file mode 100644 index f8b630f8ae..0000000000 --- a/app/api/endpoints/multiplexed_library_creation_requests.rb +++ /dev/null @@ -1,4 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for MultiplexedLibraryCreationRequests -class Endpoints::MultiplexedLibraryCreationRequests < Endpoints::LibraryCreationRequests -end diff --git a/app/api/endpoints/multiplexed_library_tubes.rb b/app/api/endpoints/multiplexed_library_tubes.rb deleted file mode 100644 index e775e028e1..0000000000 --- a/app/api/endpoints/multiplexed_library_tubes.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for MultiplexedLibraryTubes -class Endpoints::MultiplexedLibraryTubes < Endpoints::LibraryTubes - instance do - belongs_to(:custom_metadatum_collection, json: 'custom_metadatum_collection', to: 'custom_metadatum_collection') - has_many(:requests_as_source, json: 'requests', to: 'requests') - has_many(:studies, json: 'studies', to: 'studies') - belongs_to(:purpose, json: 'purpose') - has_many(:qc_files, json: 'qc_files', to: 'qc_files', include: []) do - action(:create, as: 'create') do |request, _| - ActiveRecord::Base.transaction { QcFile.create!(request.attributes.merge(asset: request.target)) } - end - action(:create_from_file, as: 'create') do |request, _| - ActiveRecord::Base.transaction { request.target.add_qc_file(request.file, request.filename) } - end - end - end -end diff --git a/app/api/endpoints/order_templates.rb b/app/api/endpoints/order_templates.rb deleted file mode 100644 index cf24305eee..0000000000 --- a/app/api/endpoints/order_templates.rb +++ /dev/null @@ -1,20 +0,0 @@ -# frozen_string_literal: true -class Endpoints::OrderTemplates < Core::Endpoint::Base - model {} - - instance do - nested('orders') do - action(:create) do |request, _| - ActiveRecord::Base.transaction do - attributes = ::Io::Order.map_parameters_to_attributes(request.json) - attributes[:user] = request.user if request.user.present? - request.target.create_order!(attributes) - end - end - end - end -end - -# Ensure that this template is used for the SubmissionTemplate model whilst it exists. Without this we -# would need to implement another endpoint and the end users would be confused. -Endpoints::SubmissionTemplates = Endpoints::OrderTemplates diff --git a/app/api/endpoints/orders.rb b/app/api/endpoints/orders.rb deleted file mode 100644 index abec956819..0000000000 --- a/app/api/endpoints/orders.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true -class Endpoints::Orders < Core::Endpoint::Base - model {} - - instance do - belongs_to(:project, json: 'project') - belongs_to(:study, json: 'study') - belongs_to(:user, json: 'user') - - action(:update, to: :standard_update!, if: :building?) - end -end diff --git a/app/api/endpoints/pipelines.rb b/app/api/endpoints/pipelines.rb deleted file mode 100644 index d46ed8e8f3..0000000000 --- a/app/api/endpoints/pipelines.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for Pipelines -class Endpoints::Pipelines < Core::Endpoint::Base - model {} - - instance do - has_many( - :inbox, - scoped: 'ready_in_storage.full_inbox.order_most_recently_created_first', - include: [], - json: 'requests', - to: 'requests' - ) - - has_many(:batches, scoped: 'order_most_recently_updated_first', include: [], json: 'batches', to: 'batches') do - action(:create) do |request, _| - ActiveRecord::Base.transaction do - request.create!(::Io::Batch.map_parameters_to_attributes(request.json).merge(user: request.user)) - end - end - end - end -end diff --git a/app/api/endpoints/plate_conversions.rb b/app/api/endpoints/plate_conversions.rb deleted file mode 100644 index 46dfbc6c5c..0000000000 --- a/app/api/endpoints/plate_conversions.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for PlateConversions -class Endpoints::PlateConversions < Core::Endpoint::Base - model { action(:create, to: :standard_create!) } - - instance do - belongs_to(:target, json: 'target') - belongs_to(:purpose, json: 'purpose') - belongs_to(:user, json: 'user') - belongs_to(:parent, json: 'parent') - end -end diff --git a/app/api/endpoints/plate_creations.rb b/app/api/endpoints/plate_creations.rb deleted file mode 100644 index 40bab7e0ef..0000000000 --- a/app/api/endpoints/plate_creations.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for PlateCreations -class Endpoints::PlateCreations < Core::Endpoint::Base - model { action(:create, to: :standard_create!) } - - instance do - belongs_to(:child, json: 'child') - belongs_to(:child_purpose, json: 'child_purpose') - belongs_to(:parent, json: 'parent') - belongs_to(:user, json: 'user') - end -end diff --git a/app/api/endpoints/plate_purposes.rb b/app/api/endpoints/plate_purposes.rb deleted file mode 100644 index c20b4ca848..0000000000 --- a/app/api/endpoints/plate_purposes.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for PlatePurposes -class Endpoints::PlatePurposes < Core::Endpoint::Base - model { action(:create, to: :standard_create!) } - - instance do - has_many(:child_purposes, json: 'children', to: 'children') - has_many(:parent_purposes, json: 'parents', to: 'parents') - - has_many(:plates, json: 'plates', to: 'plates') do - action(:create) do |request, _| - ActiveRecord::Base.transaction { request.target.proxy_association.owner.create!(request.attributes) } - end - end - end -end diff --git a/app/api/endpoints/plate_templates.rb b/app/api/endpoints/plate_templates.rb deleted file mode 100644 index d17912dcb0..0000000000 --- a/app/api/endpoints/plate_templates.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for PlateTemplates -class Endpoints::PlateTemplates < Core::Endpoint::Base - model {} - - instance { has_many(:wells, json: 'wells', to: 'wells', scoped: 'for_api_plate_json.in_row_major_order') } -end diff --git a/app/api/endpoints/plates.rb b/app/api/endpoints/plates.rb deleted file mode 100644 index c16ac49133..0000000000 --- a/app/api/endpoints/plates.rb +++ /dev/null @@ -1,35 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for Plates -class Endpoints::Plates < Core::Endpoint::Base - model {} - - instance do - has_many(:comments, json: 'comments', to: 'comments') { action(:create, to: :standard_create!) } - - has_many(:volume_updates, json: 'volume_updates', to: 'volume_updates') { action(:create, to: :standard_create!) } - - has_many(:extraction_attributes, json: 'extraction_attributes', to: 'extraction_attributes') do - action(:create, to: :standard_create!) - end - - has_many(:wells, json: 'wells', to: 'wells', scoped: 'for_api_plate_json.in_row_major_order', per_page: 400) - has_many(:submission_pools, json: 'submission_pools', to: 'submission_pools') - belongs_to(:plate_purpose, json: 'plate_purpose') - - has_many(:qc_files, json: 'qc_files', to: 'qc_files', include: []) do - action(:create, as: 'create') do |request, _| - ActiveRecord::Base.transaction { QcFile.create!(request.attributes.merge(asset: request.target)) } - end - action(:create_from_file, as: 'create') do |request, _| - ActiveRecord::Base.transaction { request.target.add_qc_file(request.file, request.filename) } - end - end - - has_many(:transfer_request_collections, json: 'transfer_request_collections', to: 'transfer_request_collections') - - has_many(:transfers_as_source, json: 'source_transfers', to: 'source_transfers') - has_many(:transfers_to_tubes, json: 'transfers_to_tubes', to: 'transfers_to_tubes') - has_many(:transfers_as_destination, json: 'creation_transfers', to: 'creation_transfers') - belongs_to(:custom_metadatum_collection, json: 'custom_metadatum_collection', to: 'custom_metadatum_collection') - end -end diff --git a/app/api/endpoints/pooled_plate_creations.rb b/app/api/endpoints/pooled_plate_creations.rb deleted file mode 100644 index 345e6e3f30..0000000000 --- a/app/api/endpoints/pooled_plate_creations.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for PooledPlateCreations -class Endpoints::PooledPlateCreations < Core::Endpoint::Base - model { action(:create, to: :standard_create!) } - - instance do - belongs_to(:child, json: 'child') - belongs_to(:child_purpose, json: 'child_purpose') - has_many(:parents, json: 'parents', to: 'parents') - belongs_to(:user, json: 'user') - end -end diff --git a/app/api/endpoints/projects.rb b/app/api/endpoints/projects.rb deleted file mode 100644 index 96d56f5c71..0000000000 --- a/app/api/endpoints/projects.rb +++ /dev/null @@ -1,6 +0,0 @@ -# frozen_string_literal: true -class Endpoints::Projects < Core::Endpoint::Base - model {} - - instance { has_many(:submissions, json: 'submissions', to: 'submissions') } -end diff --git a/app/api/endpoints/qc_decisions.rb b/app/api/endpoints/qc_decisions.rb deleted file mode 100644 index 4ecfa1dd68..0000000000 --- a/app/api/endpoints/qc_decisions.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for QcDecisions -class Endpoints::QcDecisions < Core::Endpoint::Base - model do - action(:create) do |request, _| - request.target.create!( - request.attributes.tap do |attributes| - attributes[:decisions] = (attributes[:decisions] || []).map do |d| - d.merge('qcable' => Uuid.find_by(external_id: d['qcable']).resource) - end - end - ) - end - end - - instance do - belongs_to(:user, json: 'user') - belongs_to(:lot, json: 'lot') - has_many(:qcables, json: 'qcables', to: 'qcables') - end -end diff --git a/app/api/endpoints/qc_files.rb b/app/api/endpoints/qc_files.rb deleted file mode 100644 index 7cae7b2e44..0000000000 --- a/app/api/endpoints/qc_files.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for QcFiles -class Endpoints::QcFiles < Core::Endpoint::Base - model do - # action(:create, :to => :standard_create!) - end - - instance do - # belongs_to :plate, :json => 'plate' - has_file(content_type: 'sequencescape/qc_file') - end -end diff --git a/app/api/endpoints/qcable_creators.rb b/app/api/endpoints/qcable_creators.rb deleted file mode 100644 index 47a328cc88..0000000000 --- a/app/api/endpoints/qcable_creators.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for QcableCreators -class Endpoints::QcableCreators < Core::Endpoint::Base - model { action(:create, to: :standard_create!) } - - instance do - belongs_to(:user, json: 'user') - belongs_to(:lot, json: 'lot') - has_many(:qcables, json: 'qcables', to: 'qcables') - end -end diff --git a/app/api/endpoints/qcables.rb b/app/api/endpoints/qcables.rb deleted file mode 100644 index b34488fdb2..0000000000 --- a/app/api/endpoints/qcables.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for Qcables -class Endpoints::Qcables < Core::Endpoint::Base - model {} - - instance do - belongs_to(:asset, json: 'asset') - belongs_to(:lot, json: 'lot') - end -end diff --git a/app/api/endpoints/reference_genomes.rb b/app/api/endpoints/reference_genomes.rb deleted file mode 100644 index 3a74e86580..0000000000 --- a/app/api/endpoints/reference_genomes.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for ReferenceGenomes -class Endpoints::ReferenceGenomes < Core::Endpoint::Base - model { action(:create, to: :standard_create!) } - - instance { action(:update, to: :standard_update!) } -end diff --git a/app/api/endpoints/request_types.rb b/app/api/endpoints/request_types.rb deleted file mode 100644 index 794cd79dee..0000000000 --- a/app/api/endpoints/request_types.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for RequestTypes -class Endpoints::RequestTypes < Core::Endpoint::Base - model {} - - instance {} -end diff --git a/app/api/endpoints/requests.rb b/app/api/endpoints/requests.rb deleted file mode 100644 index 957861cb53..0000000000 --- a/app/api/endpoints/requests.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for Requests -class Endpoints::Requests < Core::Endpoint::Base - model {} - - instance do - belongs_to(:asset, json: 'source_asset') - belongs_to(:target_asset, json: 'target_asset') - belongs_to(:submission, json: 'submission') - end -end diff --git a/app/api/endpoints/robots.rb b/app/api/endpoints/robots.rb deleted file mode 100644 index 6811709e8a..0000000000 --- a/app/api/endpoints/robots.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for Robots -class Endpoints::Robots < Core::Endpoint::Base - model {} - - instance {} -end diff --git a/app/api/endpoints/sample_manifests.rb b/app/api/endpoints/sample_manifests.rb deleted file mode 100644 index a36e858460..0000000000 --- a/app/api/endpoints/sample_manifests.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for SampleManifests -class Endpoints::SampleManifests < Core::Endpoint::Base - model do - # TODO: For the moment we have to disable the read functionality as it consumes too much memory. - # Loading a sample manifest of only a few thousand samples causes the memory to spike at 1.2GB - # and when you have 10s of these in a 100 entry page of results that is not good. - disable :read - deprecate :create - end - - instance do - belongs_to(:study, json: 'study') - belongs_to(:supplier, json: 'supplier') - - deprecate :update - end -end diff --git a/app/api/endpoints/sample_tubes.rb b/app/api/endpoints/sample_tubes.rb deleted file mode 100644 index 6aa436852d..0000000000 --- a/app/api/endpoints/sample_tubes.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for SampleTubes -class Endpoints::SampleTubes < Endpoints::Tubes - instance do - belongs_to(:custom_metadatum_collection, json: 'custom_metadatum_collection', to: 'custom_metadatum_collection') - has_many(:requests_as_source, json: 'requests', to: 'requests') - has_many(:library_tubes, json: 'library_tubes', to: 'library_tubes') - end -end diff --git a/app/api/endpoints/samples.rb b/app/api/endpoints/samples.rb deleted file mode 100644 index 5818b13f50..0000000000 --- a/app/api/endpoints/samples.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for Samples -class Endpoints::Samples < Core::Endpoint::Base - model {} - - instance {} -end diff --git a/app/api/endpoints/searches.rb b/app/api/endpoints/searches.rb deleted file mode 100644 index 59509b24c2..0000000000 --- a/app/api/endpoints/searches.rb +++ /dev/null @@ -1,46 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for Searches -class Endpoints::Searches < Core::Endpoint::Base - module SearchActions - def search_action(name) # rubocop:todo Metrics/AbcSize - bind_action(:create, to: name.to_s, as: name.to_sym) do |action, request, response| - request.json['search']['page'] ||= request.path.fetch(1).to_i if request.path.fetch(1, false) - scope = request.target.scope(request.json['search']).send(name) - - # If we're not paginated, just convert to an array. This will stop - # the api from trying to paginate the results. Ideally all searches should be - # paginated, but this may break downstream clients - (scope.respond_to?(:total_entries) ? scope : scope.to_a).tap do |results| - response.handled_by = action - yield(response, results) - end - end - end - - def singular_search_action(name) # rubocop:todo Metrics/AbcSize, Metrics/MethodLength - bind_action(:create, to: name.to_s, as: name.to_sym) do |_action, request, response| - record = request.target.scope(request.json['search']).send(name.to_sym) - raise ActiveRecord::RecordNotFound, 'no resources found with that search criteria' if record.nil? - - request.io = ::Core::Io::Registry.instance.lookup_for_object(record) - request - .io - .eager_loading_for(record.class) - .include_uuid - .find(record.id) - .tap { |_result| response.redirect_to(record.uuid) } - end - end - end - - model {} - - instance do - extend SearchActions - - singular_search_action(:first) - singular_search_action(:last) - - search_action(:all) { |response, _records| response.multiple_choices } - end -end diff --git a/app/api/endpoints/sequencing_requests.rb b/app/api/endpoints/sequencing_requests.rb deleted file mode 100644 index 20501fb2f5..0000000000 --- a/app/api/endpoints/sequencing_requests.rb +++ /dev/null @@ -1,4 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for SequencingRequests -class Endpoints::SequencingRequests < Endpoints::Requests -end diff --git a/app/api/endpoints/specific_tube_creations.rb b/app/api/endpoints/specific_tube_creations.rb deleted file mode 100644 index 4d49cff85e..0000000000 --- a/app/api/endpoints/specific_tube_creations.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for SpecificTubeCreations -class Endpoints::SpecificTubeCreations < Core::Endpoint::Base - model { action(:create, to: :standard_create!) } - - instance do - has_many(:children, json: 'children', to: 'children') - has_many(:child_purposes, json: 'child_purposes', to: 'child_purposes') - has_many(:parents, json: 'parents', to: 'parents') - belongs_to(:user, json: 'user') - end -end diff --git a/app/api/endpoints/stamps.rb b/app/api/endpoints/stamps.rb deleted file mode 100644 index 627c49f974..0000000000 --- a/app/api/endpoints/stamps.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for Stamps -class Endpoints::Stamps < Core::Endpoint::Base - model { action(:create, to: :standard_create!) } - - instance do - belongs_to(:user, json: 'user') - belongs_to(:robot, json: 'robot') - belongs_to(:lot, json: 'lot') - has_many(:qcables, json: 'qcables', to: 'qcables') - has_many(:stamp_qcables, json: 'stamp_qcables', to: 'stamp_qcables') - end -end diff --git a/app/api/endpoints/state_changes.rb b/app/api/endpoints/state_changes.rb deleted file mode 100644 index 33087fd6f7..0000000000 --- a/app/api/endpoints/state_changes.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for StateChanges -class Endpoints::StateChanges < Core::Endpoint::Base - model { action(:create, to: :standard_create!) } - - instance do - belongs_to(:target, json: 'target') - belongs_to(:user, json: 'user') - end -end diff --git a/app/api/endpoints/studies.rb b/app/api/endpoints/studies.rb deleted file mode 100644 index afafab64f7..0000000000 --- a/app/api/endpoints/studies.rb +++ /dev/null @@ -1,30 +0,0 @@ -# frozen_string_literal: true -class Endpoints::Studies < Core::Endpoint::Base - model {} - - instance do - has_many(:samples, json: 'samples', to: 'samples') - has_many(:projects, json: 'projects', to: 'projects') - has_many(:asset_groups, json: 'asset_groups', to: 'asset_groups') - - has_many(:sample_manifests, json: 'sample_manifests', to: 'sample_manifests') do - def self.deprecated_constructor(name) - line = __LINE__ + 1 - instance_eval( - " - bind_action(:create, :as => #{name.to_sym.inspect}, :to => #{name.to_s.inspect}) do |_, request, response| - raise ::Core::Service::DeprecatedAction - end - ", - __FILE__, - line - ) - end - - deprecated_constructor(:create_for_plates) - deprecated_constructor(:create_for_tubes) - deprecated_constructor(:create_for_multiplexed_libraries) - deprecate :create_for_plates, :create_for_tubes, :create_for_multiplexed_libraries - end - end -end diff --git a/app/api/endpoints/submission_pools.rb b/app/api/endpoints/submission_pools.rb deleted file mode 100644 index 8b1d18ccb6..0000000000 --- a/app/api/endpoints/submission_pools.rb +++ /dev/null @@ -1,6 +0,0 @@ -# frozen_string_literal: true -class Endpoints::SubmissionPools < Core::Endpoint::Base - model {} - - instance {} -end diff --git a/app/api/endpoints/submissions.rb b/app/api/endpoints/submissions.rb deleted file mode 100644 index 6f8364f947..0000000000 --- a/app/api/endpoints/submissions.rb +++ /dev/null @@ -1,26 +0,0 @@ -# frozen_string_literal: true -class Endpoints::Submissions < Core::Endpoint::Base - model do - action(:create) do |request, _| - attributes = ::Io::Submission.map_parameters_to_attributes(request.json) - attributes[:user] = request.user if request.user.present? - request.target.create!(attributes) - end - end - - instance do - belongs_to(:user, json: 'user') - has_many(:requests, json: 'requests', to: 'requests', include: %i[source_asset target_asset]) - - action(:update, to: :standard_update!, if: :building?) - - bind_action(:create, as: :submit, to: 'submit', if: :building?) do |_, request, response| - ActiveRecord::Base.transaction do - request.target.tap do |submission| - submission.built! - response.status(200) # OK - end - end - end - end -end diff --git a/app/api/endpoints/suppliers.rb b/app/api/endpoints/suppliers.rb deleted file mode 100644 index 8b78bd6492..0000000000 --- a/app/api/endpoints/suppliers.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for Suppliers -class Endpoints::Suppliers < Core::Endpoint::Base - model {} - - instance { has_many(:sample_manifests, include: [], json: 'sample_manifests', to: 'sample_manifests') } -end diff --git a/app/api/endpoints/tag2_layout_templates.rb b/app/api/endpoints/tag2_layout_templates.rb deleted file mode 100644 index d9c8928df2..0000000000 --- a/app/api/endpoints/tag2_layout_templates.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for Tag2LayoutTemplates -class Endpoints::Tag2LayoutTemplates < Core::Endpoint::Base - model {} - - instance do - action(:create) do |request, _| - ActiveRecord::Base.transaction do - request.create!(::Io::Tag2Layout.map_parameters_to_attributes(request.json).reverse_merge(user: request.user)) - end - end - end -end diff --git a/app/api/endpoints/tag2_layouts.rb b/app/api/endpoints/tag2_layouts.rb deleted file mode 100644 index d3935c4478..0000000000 --- a/app/api/endpoints/tag2_layouts.rb +++ /dev/null @@ -1,10 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for Tag2Layouts -class Endpoints::Tag2Layouts < Core::Endpoint::Base - model { action(:create, to: :standard_create!) } - - instance do - belongs_to(:plate, json: 'plate') - belongs_to(:source, json: 'source') - end -end diff --git a/app/api/endpoints/tag_groups.rb b/app/api/endpoints/tag_groups.rb deleted file mode 100644 index aaa69fd49d..0000000000 --- a/app/api/endpoints/tag_groups.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for TagGroups -class Endpoints::TagGroups < Core::Endpoint::Base - model {} - - instance {} -end diff --git a/app/api/endpoints/tag_layout_templates.rb b/app/api/endpoints/tag_layout_templates.rb deleted file mode 100644 index f78f6f6783..0000000000 --- a/app/api/endpoints/tag_layout_templates.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for TagLayoutTemplates -class Endpoints::TagLayoutTemplates < Core::Endpoint::Base - model {} - - instance do - action(:create) do |request, _| - ActiveRecord::Base.transaction do - request.create!(::Io::TagLayout.map_parameters_to_attributes(request.json).reverse_merge(user: request.user)) - end - end - end -end diff --git a/app/api/endpoints/tag_layouts.rb b/app/api/endpoints/tag_layouts.rb deleted file mode 100644 index 28eb9ab787..0000000000 --- a/app/api/endpoints/tag_layouts.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for TagLayouts -class Endpoints::TagLayouts < Core::Endpoint::Base - model { action(:create, to: :standard_create!) } - - instance { belongs_to(:plate, json: 'plate') } -end diff --git a/app/api/endpoints/transfer_request_collections.rb b/app/api/endpoints/transfer_request_collections.rb deleted file mode 100644 index 2e5814c8ea..0000000000 --- a/app/api/endpoints/transfer_request_collections.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true -module Endpoints - class TransferRequestCollections < ::Core::Endpoint::Base - model { action(:create, to: :standard_create!) } - - instance { belongs_to(:user, json: 'user') } - end -end diff --git a/app/api/endpoints/transfer_requests.rb b/app/api/endpoints/transfer_requests.rb deleted file mode 100644 index e321a0b8c4..0000000000 --- a/app/api/endpoints/transfer_requests.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -# TransferRequests are exposed via the API and allow -# you to access their source and target assets, and their submissions -# Controls API V1 {::Core::Endpoint::Base endpoints} for TransferRequests -class Endpoints::TransferRequests < Core::Endpoint::Base - model {} - - instance do - belongs_to(:asset, json: 'source_asset') - belongs_to(:target_asset, json: 'target_asset') - belongs_to(:submission, json: 'submission') - end -end diff --git a/app/api/endpoints/transfer_templates.rb b/app/api/endpoints/transfer_templates.rb deleted file mode 100644 index b4c4deff63..0000000000 --- a/app/api/endpoints/transfer_templates.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for TransferTemplates -class Endpoints::TransferTemplates < Core::Endpoint::Base - model {} - - instance do - def extract_parameters(request) - # Here we have to map the JSON provided based on the transfer class we're going to build - io_handler = ::Core::Io::Registry.instance.lookup_for_class(request.target.transfer_class) - yield(io_handler.map_parameters_to_attributes(request.json).reverse_merge(user: request.user)) - end - - action(:create) do |request, response| - response.status(201) - ActiveRecord::Base.transaction { extract_parameters(request) { |parameters| request.target.create!(parameters) } } - end - bind_action(:create, as: 'preview', to: 'preview') do |_, request, response| - response.status(200) - extract_parameters(request) { |parameters| request.target.preview!(parameters) } - end - end -end diff --git a/app/api/endpoints/transfers.rb b/app/api/endpoints/transfers.rb deleted file mode 100644 index 7d5a1ba4de..0000000000 --- a/app/api/endpoints/transfers.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for Transfers -class Endpoints::Transfers < Core::Endpoint::Base - model {} - - instance {} -end diff --git a/app/api/endpoints/tube/purposes.rb b/app/api/endpoints/tube/purposes.rb deleted file mode 100644 index 3e0f064791..0000000000 --- a/app/api/endpoints/tube/purposes.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for Tube -class Endpoints::Tube::Purposes < Core::Endpoint::Base - model { action(:create, to: :standard_create!) } - - instance do - has_many(:child_purposes, json: 'children', to: 'children') - has_many(:parent_purposes, json: 'parents', to: 'parents') - has_many(:tubes, json: 'tubes', to: 'tubes') - end -end diff --git a/app/api/endpoints/tube_creations.rb b/app/api/endpoints/tube_creations.rb deleted file mode 100644 index bc0d0cfc63..0000000000 --- a/app/api/endpoints/tube_creations.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for TubeCreations -class Endpoints::TubeCreations < Core::Endpoint::Base - model { action(:create, to: :standard_create!) } - - instance do - has_many(:children, json: 'children', to: 'children') - belongs_to(:child_purpose, json: 'child_purpose') - belongs_to(:parent, json: 'parent') - belongs_to(:user, json: 'user') - end -end diff --git a/app/api/endpoints/tube_from_tube_creations.rb b/app/api/endpoints/tube_from_tube_creations.rb deleted file mode 100644 index f9502dd888..0000000000 --- a/app/api/endpoints/tube_from_tube_creations.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for TubeFromTubeCreations -class Endpoints::TubeFromTubeCreations < Core::Endpoint::Base - model { action(:create, to: :standard_create!) } - - instance do - belongs_to(:child, json: 'child', to: 'child') - belongs_to(:child_purpose, json: 'child_purpose') - belongs_to(:parent, json: 'parent') - belongs_to(:user, json: 'user') - end -end diff --git a/app/api/endpoints/tubes.rb b/app/api/endpoints/tubes.rb deleted file mode 100644 index 8835872fb2..0000000000 --- a/app/api/endpoints/tubes.rb +++ /dev/null @@ -1,20 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for Tubes -class Endpoints::Tubes < Core::Endpoint::Base - model {} - - instance do - has_many(:requests_as_source, json: 'requests', to: 'requests') - belongs_to(:purpose, json: 'purpose') - belongs_to(:custom_metadatum_collection, json: 'custom_metadatum_collection', to: 'custom_metadatum_collection') - - has_many(:qc_files, json: 'qc_files', to: 'qc_files', include: []) do - action(:create, as: 'create') do |request, _| - ActiveRecord::Base.transaction { QcFile.create!(request.attributes.merge(asset: request.target)) } - end - action(:create_from_file, as: 'create') do |request, _| - ActiveRecord::Base.transaction { request.target.add_qc_file(request.file, request.filename) } - end - end - end -end diff --git a/app/api/endpoints/users.rb b/app/api/endpoints/users.rb deleted file mode 100644 index d7b00e3741..0000000000 --- a/app/api/endpoints/users.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for Users -class Endpoints::Users < Core::Endpoint::Base - model {} - - instance { action(:update, to: :standard_update!) } -end diff --git a/app/api/endpoints/uuids.rb b/app/api/endpoints/uuids.rb deleted file mode 100644 index 0782fa13b8..0000000000 --- a/app/api/endpoints/uuids.rb +++ /dev/null @@ -1,140 +0,0 @@ -# frozen_string_literal: true -#-- -# This is a complete hack of the standard behaviour and quite rightly so: people shouldn't be using it and -# so it is going to go. Rather than pollute the main API code with this rubbish it's here. -#++ -# Controls API V1 {::Core::Endpoint::Base endpoints} for Uuids -class Endpoints::Uuids < Core::Endpoint::Base - module Response - def redirect_to(path) - @owner.request.service.status(301) - @owner.request.service.headers('Location' => path) - render_body_json_directly - end - - def multiple_choices - @owner.request.service.status(300) - render_body_json_directly - end - - def render_body_json_directly - def @owner.each - yield(object.to_json) - end - end - private :render_body_json_directly - end - - class Search - class CriteriaInvalid < ::Core::Service::Error - def initialize(*args) - super - @errors = { lookup: [message] } - end - - def api_error(response) - response.content_error(422, @errors) - end - end - - include ::Validateable - - attr_reader :lookup - protected :lookup - validates_presence_of :lookup, message: 'should be a tuple' - validates_each(:lookup, allow_blank: true) do |record, field, value| - record.errors.add(field, 'should be a tuple') unless value.is_a?(Hash) - end - - def self.attribute_delegate(*names) # rubocop:todo Metrics/MethodLength - names.each do |name| - line = __LINE__ + 1 - class_eval( - " - def #{name} - return nil unless lookup.respond_to?(:fetch) - lookup[#{name.to_s.inspect}] - end - protected #{name.to_sym.inspect} - ", - __FILE__, - line - ) - end - end - - attribute_delegate(:id, :model) - validates_numericality_of :id, only_integer: true, greater_than: 0, allow_blank?: false - validates_presence_of :model - - def initialize(attributes) - @lookup = attributes - end - - def self.create!(attributes) - search = new(attributes) - search.validate! {} - search - end - - def self.create_bulk!(list_of_attributes) - raise CriteriaInvalid, 'should be an array of tuples' if list_of_attributes.nil? - raise CriteriaInvalid, 'should be an array of tuples' unless list_of_attributes.is_a?(Array) - raise CriteriaInvalid, "can't be blank" if list_of_attributes.blank? - raise CriteriaInvalid, 'should be a tuple' unless list_of_attributes.all?(Hash) - - list_of_attributes.map(&method(:create!)) - end - - def find - Uuid.find_uuid_instance!(model.classify, id) - end - end - - model do - # You should not be able to read UUIDs - disable(:read) - - # Does an individual resource lookup - bind_action(:create, to: 'lookup', as: :lookup) do |_, request, response| - lookup = request.json.respond_to?(:keys) ? request.json['lookup'] : nil - uuid = Search.create!(lookup).find - - # Hack time ... - class << response - include ::Endpoints::Uuids::Response - end - response.redirect_to(request.service.api_path(uuid.external_id)) - - { - 'model' => uuid.resource_type.underscore, - 'id' => uuid.resource_id, - 'uuid' => uuid.external_id, - 'url' => request.service.api_path(uuid.external_id) - } - end - bound_action_not_require_an_io_class?(:lookup) - - # Handles trying to find multiple resources - bind_action(:create, to: 'bulk', as: :bulk) do |_, request, response| - lookup = request.json.respond_to?(:keys) ? request.json['lookup'] : nil - uuids = Search.create_bulk!(lookup).map(&:find) - - # Hack time ... - class << response - include ::Endpoints::Uuids::Response - end - response.multiple_choices - - uuids.map do |uuid| - { - 'model' => uuid.resource_type.underscore, - 'id' => uuid.resource_id, - 'uuid' => uuid.external_id, - 'url' => request.service.api_path(uuid.external_id) - } - end - end - bound_action_not_require_an_io_class?(:bulk) - end -end diff --git a/app/api/endpoints/volume_updates.rb b/app/api/endpoints/volume_updates.rb deleted file mode 100644 index e9a34f2512..0000000000 --- a/app/api/endpoints/volume_updates.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for VolumeUpdates -class Endpoints::VolumeUpdates < Core::Endpoint::Base - model { action(:create, to: :standard_create!) } - - instance { belongs_to(:target, json: 'target') } -end diff --git a/app/api/endpoints/wells.rb b/app/api/endpoints/wells.rb deleted file mode 100644 index ba372c7e91..0000000000 --- a/app/api/endpoints/wells.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for Wells -class Endpoints::Wells < Core::Endpoint::Base - model {} - - instance { belongs_to :plate, json: 'plate' } -end diff --git a/app/api/endpoints/work_completions.rb b/app/api/endpoints/work_completions.rb deleted file mode 100644 index 936f2056a4..0000000000 --- a/app/api/endpoints/work_completions.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 {::Core::Endpoint::Base endpoints} for WorkCompletions -class Endpoints::WorkCompletions < Core::Endpoint::Base - model { action(:create, to: :standard_create!) } - - instance do - belongs_to(:target, json: 'target') - belongs_to(:user, json: 'user') - has_many(:submissions, json: 'submissions', to: 'submissions') - end -end diff --git a/app/api/io/active_record/relation.rb b/app/api/io/active_record/relation.rb deleted file mode 100644 index bbc2ec99b2..0000000000 --- a/app/api/io/active_record/relation.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: true -class Io::ActiveRecord::Relation - extend ::Core::Io::Collection - - class << self - def as_json(options = {}) - options[:handled_by].generate_json_actions( - options[:object], - options.merge(target: options[:response].request.target) - ) - super - end - - def size_for(results) - results.count - end - private :size_for - end -end diff --git a/app/api/io/aliquot.rb b/app/api/io/aliquot.rb deleted file mode 100644 index 80262bcf0b..0000000000 --- a/app/api/io/aliquot.rb +++ /dev/null @@ -1,39 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::Aliquot} -class Io::Aliquot < Core::Io::Base - set_model_for_input(::Aliquot) - set_json_root(:aliquot) - - PRELOADS = [ - :bait_library, - :primer_panel, - { - tag: :tag_group, - tag2: :tag_group, - sample: [:study_reference_genome, :uuid_object, { sample_metadata: :reference_genome }] - } - ].freeze - - define_attribute_and_json_mapping( - ' - sample => sample - - tag.name => tag.name - tag.map_id => tag.identifier - tag.oligo => tag.oligo - tag.tag_group.name => tag.group - - tag2.name => tag2.name - tag2.map_id => tag2.identifier - tag2.oligo => tag2.oligo - tag2.tag_group.name => tag2.group - - bait_library => bait_library - - insert_size.from => insert_size.from - insert_size.to => insert_size.to - - suboptimal => suboptimal - ' - ) -end diff --git a/app/api/io/array.rb b/app/api/io/array.rb deleted file mode 100644 index b35c334de1..0000000000 --- a/app/api/io/array.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true -# Provides tools for paginating Array objects -class Io::Array - extend Core::Io::Collection - - def self.size_for(collection) - collection.size - end -end diff --git a/app/api/io/asset.rb b/app/api/io/asset.rb deleted file mode 100644 index 66d4546ae1..0000000000 --- a/app/api/io/asset.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::Asset} -# @note {Asset} is deprecated and has now been split into {Labware} and {Receptacle} -class Io::Asset < Core::Io::Base - set_model_for_input(::Asset) - set_json_root(:asset) - set_eager_loading { |model| model } - - define_attribute_and_json_mapping( - ' - name => name - qc_state => qc_state - ' - ) -end diff --git a/app/api/io/asset_audit.rb b/app/api/io/asset_audit.rb deleted file mode 100644 index 2c77532dad..0000000000 --- a/app/api/io/asset_audit.rb +++ /dev/null @@ -1,55 +0,0 @@ -# frozen_string_literal: true -module Io - # Controls API V1 IO for {::AssetAudit} - class AssetAudit < ::Core::Io::Base - # This module adds the behaviour we require from the AssetAudit module. - module ApiIoSupport - def self.included(base) - base.class_eval do - # TODO: add any named scopes - # TODO: add any associations - end - end - - def asset_uuid - asset.try(:uuid) - end - - def asset_uuid=(uuid) - self.asset = Uuid.with_external_id(uuid).include_resource.map(&:resource).first - end - - # TODO: add any methods - end - - set_model_for_input(::AssetAudit) - set_json_root(:asset_audit) - - # set_eager_loading { |model| model } # TODO: uncomment and add any named_scopes that do includes you need - - # TODO: define the mapping from the model attributes to the JSON attributes - # - # The rules are relatively straight forward with each line looking like ' ', and blank - # lines or those starting with '#' being considered comments and ignored. - # - # Here 'access' is either '=>' (for read only, indicating that the 'attribute' maps to the 'json'), or '<=' for - # write only (yes, there are cases for this!) or '<=>' for read-write. - # - # The 'json' is the JSON attribute to generate in dot notation, i.e. 'parent.child' generates the JSON - # '{parent:{child:value}}'. - # - # The 'attribute' is the attribute to write, i.e. 'name' would be the 'name' attribute, and 'parent.name' would be - # the 'name' attribute of whatever 'parent' is. - - define_attribute_and_json_mapping( - ' - message <=> message - key <=> key - created_by <=> created_by - asset_uuid <=> asset - witnessed_by <=> witnessed_by - metadata <=> metadata - ' - ) - end -end diff --git a/app/api/io/asset_group.rb b/app/api/io/asset_group.rb deleted file mode 100644 index 9e9b0a459c..0000000000 --- a/app/api/io/asset_group.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::AssetGroup} -class Io::AssetGroup < Core::Io::Base - set_model_for_input(::AssetGroup) - set_json_root(:asset_group) - set_eager_loading { |model| model.include_study.include_assets } - - define_attribute_and_json_mapping( - ' - name => name - study.name => study.name - ' - ) -end diff --git a/app/api/io/bait_library.rb b/app/api/io/bait_library.rb deleted file mode 100644 index 344ba4d026..0000000000 --- a/app/api/io/bait_library.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::BaitLibrary} -class Io::BaitLibrary < Core::Io::Base - set_model_for_input(::BaitLibrary) - set_json_root(:bait_library) - - define_attribute_and_json_mapping( - ' - bait_library_supplier.name => supplier.name - supplier_identifier => supplier.identifier - name => name - target_species => target.species - bait_library_type.name => bait_library_type - ' - ) -end diff --git a/app/api/io/bait_library_layout.rb b/app/api/io/bait_library_layout.rb deleted file mode 100644 index 9bd886f4e6..0000000000 --- a/app/api/io/bait_library_layout.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::BaitLibraryLayout} -class Io::BaitLibraryLayout < Core::Io::Base - set_model_for_input(::BaitLibraryLayout) - set_json_root(:bait_library_layout) - set_eager_loading(&:include_plate) - - define_attribute_and_json_mapping( - ' - user <=> user - plate <=> plate - well_layout => layout - ' - ) -end diff --git a/app/api/io/barcode_printer.rb b/app/api/io/barcode_printer.rb deleted file mode 100644 index 2fa626fb27..0000000000 --- a/app/api/io/barcode_printer.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::BarcodePrinter} -class Io::BarcodePrinter < Core::Io::Base - set_model_for_input(::BarcodePrinter) - set_json_root(:barcode_printer) - set_eager_loading(&:include_barcode_printer_type) - - define_attribute_and_json_mapping( - ' - name => name - active => active - print_service => print_service - service_url => service.url - barcode_printer_type.name => type.name - barcode_printer_type.printer_type_id => type.layout - ' - ) -end diff --git a/app/api/io/batch.rb b/app/api/io/batch.rb deleted file mode 100644 index d09f664e02..0000000000 --- a/app/api/io/batch.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::Batch} -class Io::Batch < Core::Io::Base - set_model_for_input(::Batch) - set_json_root(:batch) - set_eager_loading { |model| model.include_user.include_requests.include_pipeline } - - define_attribute_and_json_mapping( - ' - state => state - production_state => production_state - qc_state => qc_state - barcode => barcode - user.login => user.login - - requests <=> requests - ' - ) -end diff --git a/app/api/io/bulk_transfer.rb b/app/api/io/bulk_transfer.rb deleted file mode 100644 index a09c284266..0000000000 --- a/app/api/io/bulk_transfer.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::BulkTransfer} -class Io::BulkTransfer < Core::Io::Base - set_model_for_input(::BulkTransfer) - set_json_root(:bulk_transfer) - - define_attribute_and_json_mapping( - ' - user <=> user -well_transfers <= well_transfers - ' - ) -end diff --git a/app/api/io/comment.rb b/app/api/io/comment.rb deleted file mode 100644 index 9f4842cd57..0000000000 --- a/app/api/io/comment.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::Comment} -class Io::Comment < Core::Io::Base - set_model_for_input(::Comment) - set_json_root(:comment) - set_eager_loading { |model| model } - - define_attribute_and_json_mapping( - ' - user <= user - title <=> title - description <=> description - ' - ) -end diff --git a/app/api/io/custom_metadatum_collection.rb b/app/api/io/custom_metadatum_collection.rb deleted file mode 100644 index 0f20e80cc5..0000000000 --- a/app/api/io/custom_metadatum_collection.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::CustomMetadatumCollection} -class Io::CustomMetadatumCollection < Core::Io::Base - set_model_for_input(::CustomMetadatumCollection) - set_json_root(:custom_metadatum_collection) - - define_attribute_and_json_mapping( - ' - metadata <=> metadata - user <= user - asset <= asset - ' - ) -end diff --git a/app/api/io/dilution_plate_purpose.rb b/app/api/io/dilution_plate_purpose.rb deleted file mode 100644 index 31c6c0cbcd..0000000000 --- a/app/api/io/dilution_plate_purpose.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::DilutionPlatePurpose} -class Io::DilutionPlatePurpose < Io::PlatePurpose - set_model_for_input(::DilutionPlatePurpose) - set_json_root(:dilution_plate_purpose) - - define_attribute_and_json_mapping( - ' - - ' - ) -end diff --git a/app/api/io/endpoints/uuids/search.rb b/app/api/io/endpoints/uuids/search.rb deleted file mode 100644 index cae5e06b73..0000000000 --- a/app/api/io/endpoints/uuids/search.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true -class Io::Endpoints::Uuids::Search - def self.model_for_input - ::Uuids::Search - end - - def initialize(search) - @search = search - end - - def self.json_field_for(attribute) - attribute - end -end diff --git a/app/api/io/extraction_attribute.rb b/app/api/io/extraction_attribute.rb deleted file mode 100644 index 2de69a0c76..0000000000 --- a/app/api/io/extraction_attribute.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::ExtractionAttribute} -class Io::ExtractionAttribute < Core::Io::Base - set_model_for_input(::ExtractionAttribute) - set_json_root(:extraction_attribute) - - # set_eager_loading { |model| model } # TODO: uncomment and add any named_scopes that do includes you need - - define_attribute_and_json_mapping( - ' - created_by <=> created_by - attributes_update <=> attributes_update - ' - ) -end diff --git a/app/api/io/labware.rb b/app/api/io/labware.rb deleted file mode 100644 index eeed855c99..0000000000 --- a/app/api/io/labware.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -# Controls API V1 IO for {::Labware} -class Io::Labware < Core::Io::Base - set_model_for_input(::Labware) - set_json_root(:asset) - set_eager_loading { |model| model } - - define_attribute_and_json_mapping( - ' - name => name - ' - ) -end diff --git a/app/api/io/lane.rb b/app/api/io/lane.rb deleted file mode 100644 index 4fe869194a..0000000000 --- a/app/api/io/lane.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::Lane} -class Io::Lane < Io::Asset - set_model_for_input(::Lane) - set_json_root(:lane) - define_attribute_and_json_mapping( - ' - external_release => external_release - ' - ) -end diff --git a/app/api/io/library_creation_request.rb b/app/api/io/library_creation_request.rb deleted file mode 100644 index ddc55f937d..0000000000 --- a/app/api/io/library_creation_request.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::LibraryCreationRequest} -class Io::LibraryCreationRequest < Io::Request - set_model_for_input(::LibraryCreationRequest) - set_json_root(:library_creation_request) - - define_attribute_and_json_mapping( - ' - request_metadata.library_type => library_type - ' - ) -end diff --git a/app/api/io/library_event.rb b/app/api/io/library_event.rb deleted file mode 100644 index d09f3fa591..0000000000 --- a/app/api/io/library_event.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::LibraryEvent} -class Io::LibraryEvent < Core::Io::Base - set_model_for_input(::LibraryEvent) - set_json_root(:library_event) - - define_attribute_and_json_mapping( - ' - event_type <=> event_type - user <=> user - seed <=> seed - ' - ) -end diff --git a/app/api/io/library_tube.rb b/app/api/io/library_tube.rb deleted file mode 100644 index f81aba9d29..0000000000 --- a/app/api/io/library_tube.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::LibraryTube} -class Io::LibraryTube < Io::Tube - set_model_for_input(::LibraryTube) - set_json_root(:library_tube) - set_eager_loading(&:include_source_request) - - define_attribute_and_json_mapping( - ' - source_request.request_metadata.read_length => source_request.read_length - source_request.request_metadata.library_type => source_request.library_type - source_request.request_metadata.fragment_size_required_from => source_request.fragment_size.from - source_request.request_metadata.fragment_size_required_to => source_request.fragment_size.to - ' - ) -end diff --git a/app/api/io/lot.rb b/app/api/io/lot.rb deleted file mode 100644 index da48d56d42..0000000000 --- a/app/api/io/lot.rb +++ /dev/null @@ -1,20 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::Lot} -class Io::Lot < Core::Io::Base - set_model_for_input(::Lot) - set_json_root(:lot) - - set_eager_loading { |model| model.include_lot_type.include_template } - - define_attribute_and_json_mapping( - ' - lot_number <=> lot_number - received_at <=> received_at - template.name => template_name - lot_type.name => lot_type_name - lot_type <= lot_type - user <= user - template <= template - ' - ) -end diff --git a/app/api/io/lot_type.rb b/app/api/io/lot_type.rb deleted file mode 100644 index 13b6500c1e..0000000000 --- a/app/api/io/lot_type.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::LotType} -class Io::LotType < Core::Io::Base - set_model_for_input(::LotType) - set_json_root(:lot_type) - - define_attribute_and_json_mapping( - ' - name => name - template_class => template_class - target_purpose.name => qcable_name - printer_type => printer_type - ' - ) -end diff --git a/app/api/io/multiplexed_library_creation_request.rb b/app/api/io/multiplexed_library_creation_request.rb deleted file mode 100644 index 81443c8376..0000000000 --- a/app/api/io/multiplexed_library_creation_request.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for MultiplexedLibraryCreationRequest -class Io::MultiplexedLibraryCreationRequest < Io::LibraryCreationRequest - set_model_for_input(::MultiplexedLibraryCreationRequest) - set_json_root(:multiplexed_library_creation_request) - define_attribute_and_json_mapping('') -end diff --git a/app/api/io/multiplexed_library_tube.rb b/app/api/io/multiplexed_library_tube.rb deleted file mode 100644 index 7a99f333a6..0000000000 --- a/app/api/io/multiplexed_library_tube.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true -class Io::MultiplexedLibraryTube < Io::LibraryTube - set_model_for_input(::MultiplexedLibraryTube) - set_json_root(:multiplexed_library_tube) - - define_attribute_and_json_mapping('') - # TODO: Find an efficient way to display state as it kills transfers_to_tubes for plates! - # define_attribute_and_json_mapping(%Q{ - # state => state - # }) -end diff --git a/app/api/io/order.rb b/app/api/io/order.rb deleted file mode 100644 index f4744192cb..0000000000 --- a/app/api/io/order.rb +++ /dev/null @@ -1,44 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::Order} -class Io::Order < Core::Io::Base - REQUEST_OPTIONS_FIELDS = - { - read_length: 'read_length', - library_type: 'library_type', - fragment_size_required_from: 'fragment_size_required.from', - fragment_size_required_to: 'fragment_size_required.to', - pcr_cycles: 'pcr_cycles', - primer_panel_name: 'primer_panel_name' - }.to_h { |k, v| [:"request_options.#{k}", "request_options.#{v}"] } - - def self.json_field_for(attribute) - REQUEST_OPTIONS_FIELDS[attribute.to_sym] || super - end - - set_model_for_input(::Order) - set_json_root(:order) - set_eager_loading { |model| model.include_study.include_project.include_assets } - - define_attribute_and_json_mapping( - ' - study <= study - study.name => study.name - - project <= project - project.name => project.name - - asset_group <= asset_group - asset_group_name <= asset_group_name - - assets <=> assets - - request_type_objects => request_types - request_options_structured <=> request_options - - user <= user - - autodetect_studies <= autodetect_studies - autodetect_projects <= autodetect_projects - ' - ) -end diff --git a/app/api/io/pac_bio_library_tube.rb b/app/api/io/pac_bio_library_tube.rb deleted file mode 100644 index bc9a32843d..0000000000 --- a/app/api/io/pac_bio_library_tube.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true -class Io::PacBioLibraryTube < Io::Asset - set_model_for_input(::PacBioLibraryTube) - set_json_root(:pac_bio_library_tube) - - # set_eager_loading { |model| model } # TODO: uncomment and add any named_scopes that do includes you need - - define_attribute_and_json_mapping( - ' - pac_bio_library_tube_metadata.prep_kit_barcode <=> prep_kit_barcode - pac_bio_library_tube_metadata.binding_kit_barcode <=> binding_kit_barcode - pac_bio_library_tube_metadata.smrt_cells_available <=> smrt_cells_available - pac_bio_library_tube_metadata.movie_length <=> movie_length - ' - ) -end diff --git a/app/api/io/pipeline.rb b/app/api/io/pipeline.rb deleted file mode 100644 index b80b213bd9..0000000000 --- a/app/api/io/pipeline.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::Pipeline} -class Io::Pipeline < Core::Io::Base - set_model_for_input(::Pipeline) - set_json_root(:pipeline) - - define_attribute_and_json_mapping( - ' - name => name - ' - ) -end diff --git a/app/api/io/plate.rb b/app/api/io/plate.rb deleted file mode 100644 index 625ab92533..0000000000 --- a/app/api/io/plate.rb +++ /dev/null @@ -1,40 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for Plate -class Io::Plate < Core::Io::Base - set_model_for_input(::Plate) - set_json_root(:plate) - set_eager_loading(&:include_plate_purpose) - - define_attribute_and_json_mapping( - ' - name => name - size <=> size - plate_purpose.name => plate_purpose.name - plate_purpose.lifespan => plate_purpose.lifespan - - state => state - iteration => iteration - pools => pools - role => label.prefix - purpose.name => label.text - priority => priority - - source_plate.uuid => stock_plate.uuid - - source_plate.barcode_number => stock_plate.barcode.number - source_plate.prefix => stock_plate.barcode.prefix - source_plate.two_dimensional_barcode => stock_plate.barcode.two_dimensional - source_plate.ean13_barcode => stock_plate.barcode.ean13 - source_plate.machine_barcode => stock_plate.barcode.machine - source_plate.barcode_type => stock_plate.barcode.type - - barcode_number => barcode.number - prefix => barcode.prefix - two_dimensional_barcode => barcode.two_dimensional - machine_barcode => barcode.machine - ean13_barcode => barcode.ean13 - barcode_type => barcode.type - - ' - ) -end diff --git a/app/api/io/plate_conversion.rb b/app/api/io/plate_conversion.rb deleted file mode 100644 index eda3c527dc..0000000000 --- a/app/api/io/plate_conversion.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::PlateConversion} -class Io::PlateConversion < Core::Io::Base - set_model_for_input(::PlateConversion) - set_json_root(:plate_conversion) - set_eager_loading { |model| model } - - define_attribute_and_json_mapping( - ' - user <=> user - target <=> target - purpose <=> purpose - parent <= parent - ' - ) -end diff --git a/app/api/io/plate_creation.rb b/app/api/io/plate_creation.rb deleted file mode 100644 index 3321a9c488..0000000000 --- a/app/api/io/plate_creation.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::PlateCreation} -class Io::PlateCreation < Core::Io::Base - set_model_for_input(::PlateCreation) - set_json_root(:plate_creation) - set_eager_loading { |model| model.include_parent.include_child } - - define_attribute_and_json_mapping( - ' - user <=> user - parent <=> parent - child_purpose <=> child_purpose - child => child - ' - ) -end diff --git a/app/api/io/plate_purpose.rb b/app/api/io/plate_purpose.rb deleted file mode 100644 index 1566cfaf21..0000000000 --- a/app/api/io/plate_purpose.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for PlatePurpose -class Io::PlatePurpose < Core::Io::Base - set_model_for_input(::PlatePurpose) - set_json_root(:plate_purpose) - - define_attribute_and_json_mapping( - ' - name <=> name - lifespan <=> lifespan - cherrypickable_target <=> cherrypickable_target - stock_plate <=> stock_plate - input_plate <= input_plate - size <=> size - ' - ) -end diff --git a/app/api/io/plate_template.rb b/app/api/io/plate_template.rb deleted file mode 100644 index d595b7ad51..0000000000 --- a/app/api/io/plate_template.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for PlateTemplate -class Io::PlateTemplate < Core::Io::Base - set_model_for_input(::PlateTemplate) - set_json_root(:plate_template) - - define_attribute_and_json_mapping( - ' - size <=> size - name <=> name - ' - ) -end diff --git a/app/api/io/pooled_plate_creation.rb b/app/api/io/pooled_plate_creation.rb deleted file mode 100644 index 14f6b4d25d..0000000000 --- a/app/api/io/pooled_plate_creation.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::PooledPlateCreation} -class Io::PooledPlateCreation < Core::Io::Base - set_model_for_input(::PooledPlateCreation) - set_json_root(:pooled_plate_creation) - - # set_eager_loading { |model| model.include_parents.include_child } - - define_attribute_and_json_mapping( - ' - user <=> user - parents <= parents - child_purpose <=> child_purpose - child => child - ' - ) -end diff --git a/app/api/io/project.rb b/app/api/io/project.rb deleted file mode 100644 index ae9fce25b3..0000000000 --- a/app/api/io/project.rb +++ /dev/null @@ -1,26 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for Project -class Io::Project < Core::Io::Base - set_model_for_input(::Project) - set_json_root(:project) - set_eager_loading { |model| model.include_project_metadata.include_roles } - - define_attribute_and_json_mapping( - ' - name => name - approved => approved - state => state - - project_metadata.project_manager.name => project_manager - project_metadata.project_cost_code => cost_code - project_metadata.funding_comments => funding_comments - project_metadata.collaborators => collaborators - project_metadata.external_funding_source => external_funding_source - project_metadata.budget_division.name => budget_division - project_metadata.sequencing_budget_cost_centre => budget_cost_centre - project_metadata.project_funding_model => funding_model - - roles_as_json => roles - ' - ) -end diff --git a/app/api/io/purpose.rb b/app/api/io/purpose.rb deleted file mode 100644 index 51f6cdcf48..0000000000 --- a/app/api/io/purpose.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for Purpose -class Io::Purpose < Core::Io::Base - set_model_for_input(::Purpose) - set_json_root(:purpose) - - define_attribute_and_json_mapping( - ' - name => name - ' - ) -end diff --git a/app/api/io/qc_decision.rb b/app/api/io/qc_decision.rb deleted file mode 100644 index f8cfcf9f53..0000000000 --- a/app/api/io/qc_decision.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for QcDecision -class Io::QcDecision < Core::Io::Base - set_model_for_input(::QcDecision) - set_json_root(:qc_decision) - - define_attribute_and_json_mapping( - ' - user <=> user - lot <=> lot - decisions <= decisions - ' - ) -end diff --git a/app/api/io/qc_file.rb b/app/api/io/qc_file.rb deleted file mode 100644 index b9d31327e0..0000000000 --- a/app/api/io/qc_file.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::QcFile} -class Io::QcFile < Core::Io::Base - set_model_for_input(::QcFile) - set_json_root(:qc_file) - - # set_eager_loading { |model| model } # TODO: uncomment and add any named_scopes that do includes you need - - define_attribute_and_json_mapping( - ' - filename => filename - size => size - ' - ) -end diff --git a/app/api/io/qcable.rb b/app/api/io/qcable.rb deleted file mode 100644 index 974b617d86..0000000000 --- a/app/api/io/qcable.rb +++ /dev/null @@ -1,24 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for Qcable -class Io::Qcable < Core::Io::Base - set_model_for_input(::Qcable) - set_json_root(:qcable) - - set_eager_loading(&:include_for_json) - - define_attribute_and_json_mapping( - ' - state => state - stamp_qcable.bed => stamp_bed - stamp_index => stamp_index - - asset.barcode_number => barcode.number - asset.prefix => barcode.prefix -asset.two_dimensional_barcode => barcode.two_dimensional - asset.ean13_barcode => barcode.ean13 - asset.machine_barcode => barcode.machine - asset.barcode_type => barcode.type - - ' - ) -end diff --git a/app/api/io/qcable_creator.rb b/app/api/io/qcable_creator.rb deleted file mode 100644 index 995b887201..0000000000 --- a/app/api/io/qcable_creator.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for QcableCreator -class Io::QcableCreator < Core::Io::Base - set_model_for_input(::QcableCreator) - set_json_root(:qcable_creator) - - define_attribute_and_json_mapping( - ' - user <=> user - lot <=> lot - count <= count - barcodes <= barcodes - - ' - ) -end diff --git a/app/api/io/receptacle.rb b/app/api/io/receptacle.rb deleted file mode 100644 index ef4ef7942e..0000000000 --- a/app/api/io/receptacle.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true - -# Controls API V1 IO for Asset -class Io::Receptacle < Core::Io::Base - set_model_for_input(::Receptacle) - set_json_root(:asset) - set_eager_loading { |model| model } - - define_attribute_and_json_mapping( - ' - labware.name => name - qc_state => qc_state - aliquots => aliquots - ' - ) -end diff --git a/app/api/io/reference_genome.rb b/app/api/io/reference_genome.rb deleted file mode 100644 index eb6d807d58..0000000000 --- a/app/api/io/reference_genome.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::ReferenceGenome} -class Io::ReferenceGenome < Core::Io::Base - set_model_for_input(::ReferenceGenome) - set_json_root(:reference_genome) - - define_attribute_and_json_mapping( - ' - name <=> name - ' - ) -end diff --git a/app/api/io/request.rb b/app/api/io/request.rb deleted file mode 100644 index 6e49804f01..0000000000 --- a/app/api/io/request.rb +++ /dev/null @@ -1,30 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for Request -class Io::Request < Core::Io::Base - set_model_for_input(::Request) - set_json_root(:request) - set_eager_loading do |model| - model.include_request_type.include_request_metadata.include_submission.include_source_asset.include_target_asset - end - - define_attribute_and_json_mapping( - ' - request_type.name => type - request_metadata.fragment_size_required_from => fragment_size.from - request_metadata.fragment_size_required_to => fragment_size.to - state <=> state - - submission.uuid => submission.uuid - - asset <= source_asset - asset.api_asset_type => source_asset.type - asset.name => source_asset.name - asset.aliquots => source_asset.aliquots - - target_asset <= target_asset - target_asset.api_asset_type => target_asset.type - target_asset.name => target_asset.name - target_asset.aliquots => target_asset.aliquots - ' - ) -end diff --git a/app/api/io/request_type.rb b/app/api/io/request_type.rb deleted file mode 100644 index 0e085a206f..0000000000 --- a/app/api/io/request_type.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::RequestType} -class Io::RequestType < Core::Io::Base - set_model_for_input(::RequestType) - set_json_root(:request_type) - - define_attribute_and_json_mapping( - ' - name => name - ' - ) -end diff --git a/app/api/io/robot.rb b/app/api/io/robot.rb deleted file mode 100644 index 9bebf8de69..0000000000 --- a/app/api/io/robot.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for Robot -class Io::Robot < Core::Io::Base - set_model_for_input(::Robot) - set_json_root(:robot) - - set_eager_loading(&:include_properties) - - define_attribute_and_json_mapping( - ' - name => name - json_for_properties => robot_properties - ' - ) -end diff --git a/app/api/io/sample.rb b/app/api/io/sample.rb deleted file mode 100644 index 5164deac45..0000000000 --- a/app/api/io/sample.rb +++ /dev/null @@ -1,80 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for Sample -class Io::Sample < Core::Io::Base - set_model_for_input(::Sample) - set_json_root(:sample) - set_eager_loading { |model| model.include_sample_metadata.include_studies } - - define_attribute_and_json_mapping( - ' - sm_container <= container - name => sanger.name - sanger_sample_id => sanger.sample_id - sample_metadata.is_resubmitted <=> sanger.resubmitted - sample_metadata.sample_description <=> sanger.description - - sample_metadata.supplier_name <=> supplier.sample_name - sample_metadata.sample_storage_conditions <=> supplier.storage_conditions - - sample_metadata.date_of_sample_collection <=> supplier.collection.date - - sample_metadata.date_of_sample_extraction <=> supplier.extraction.date - sample_metadata.sample_extraction_method <=> supplier.extraction.method - - sample_metadata.sample_purified <=> supplier.purification.purified - sample_metadata.purification_method <=> supplier.purification.method - - sample_metadata.volume <=> supplier.measurements.volume - sample_metadata.concentration <=> supplier.measurements.concentration - sample_metadata.gc_content <=> supplier.measurements.gc_content - sample_metadata.gender <=> supplier.measurements.gender - sample_metadata.concentration_determined_by <=> supplier.measurements.concentration_determined_by - - sample_metadata.dna_source <=> source.dna_source - sample_metadata.cohort <=> source.cohort - sample_metadata.country_of_origin <=> source.country - sample_metadata.geographical_region <=> source.region - sample_metadata.ethnicity <=> source.ethnicity - control <=> source.control - - sample_metadata.mother <=> family.mother - sample_metadata.father <=> family.father - sample_metadata.replicate <=> family.replicate - sample_metadata.sibling <=> family.sibling - - sample_metadata.sample_taxon_id <=> taxonomy.id - sample_metadata.sample_strain_att <=> taxonomy.strain - sample_metadata.sample_common_name <=> taxonomy.common_name - sample_metadata.organism <=> taxonomy.organism - sample_reference_genome_name <=> reference.genome - - sample_metadata.sample_ebi_accession_number <=> data_release.accession_number - sample_metadata.sample_type <=> data_release.sample_type - - sample_metadata.sample_sra_hold => data_release.visibility - sample_metadata.sample_public_name <=> data_release.public_name - sample_metadata.sample_description <=> data_release.description - - sample_metadata.genotype <=> data_release.metagenomics.genotype - sample_metadata.phenotype <=> data_release.metagenomics.phenotype - sample_metadata.age <=> data_release.metagenomics.age - sample_metadata.developmental_stage <=> data_release.metagenomics.developmental_stage - sample_metadata.cell_type <=> data_release.metagenomics.cell_type - sample_metadata.disease_state <=> data_release.metagenomics.disease_state - sample_metadata.compound <=> data_release.metagenomics.compound - sample_metadata.dose <=> data_release.metagenomics.dose - sample_metadata.immunoprecipitate <=> data_release.metagenomics.immunoprecipitate - sample_metadata.growth_condition <=> data_release.metagenomics.growth_condition - sample_metadata.rnai <=> data_release.metagenomics.rnai - sample_metadata.organism_part <=> data_release.metagenomics.organism_part - sample_metadata.time_point <=> data_release.metagenomics.time_point - sample_metadata.treatment <=> data_release.metagenomics.treatment - sample_metadata.subject <=> data_release.metagenomics.subject - sample_metadata.disease <=> data_release.metagenomics.disease - - sample_metadata.treatment <=> data_release.managed.treatment - sample_metadata.subject <=> data_release.managed.subject - sample_metadata.disease <=> data_release.managed.disease - ' - ) -end diff --git a/app/api/io/sample_manifest.rb b/app/api/io/sample_manifest.rb deleted file mode 100644 index 0e67c382c8..0000000000 --- a/app/api/io/sample_manifest.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::SampleManifest} -class Io::SampleManifest < Core::Io::Base - set_model_for_input(::SampleManifest) - set_json_root(:sample_manifest) - set_eager_loading(&:include_samples) - - define_attribute_and_json_mapping( - ' - last_errors => last_errors - state => state - io_samples => samples - ' - ) -end diff --git a/app/api/io/sample_tube.rb b/app/api/io/sample_tube.rb deleted file mode 100644 index 324dab0420..0000000000 --- a/app/api/io/sample_tube.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for SampleTube -class Io::SampleTube < Io::Tube - set_model_for_input(::SampleTube) - set_json_root(:sample_tube) - - define_attribute_and_json_mapping('') -end diff --git a/app/api/io/search.rb b/app/api/io/search.rb deleted file mode 100644 index 45616eb5af..0000000000 --- a/app/api/io/search.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::Search} -class Io::Search < Core::Io::Base - set_json_root(:search) - - define_attribute_and_json_mapping( - ' - name => name - ' - ) -end diff --git a/app/api/io/sequencing_request.rb b/app/api/io/sequencing_request.rb deleted file mode 100644 index 9e593476df..0000000000 --- a/app/api/io/sequencing_request.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for SequencingRequest -class Io::SequencingRequest < Io::Request - set_model_for_input(::SequencingRequest) - set_json_root(:sequencing_request) - - define_attribute_and_json_mapping( - ' - request_metadata.read_length => read_length - ' - ) -end diff --git a/app/api/io/specific_tube_creation.rb b/app/api/io/specific_tube_creation.rb deleted file mode 100644 index 823d752165..0000000000 --- a/app/api/io/specific_tube_creation.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::SpecificTubeCreation} -class Io::SpecificTubeCreation < Core::Io::Base - set_model_for_input(::SpecificTubeCreation) - set_json_root(:specific_tube_creation) - set_eager_loading(&:include_parent) - - define_attribute_and_json_mapping( - ' - user <=> user - parents <= parents - parent <=> parent - set_child_purposes <= child_purposes - tube_attributes <= tube_attributes - ' - ) -end diff --git a/app/api/io/stamp.rb b/app/api/io/stamp.rb deleted file mode 100644 index abe67160c0..0000000000 --- a/app/api/io/stamp.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for Stamp -class Io::Stamp < Core::Io::Base - set_model_for_input(::Stamp) - set_json_root(:stamp) - - define_attribute_and_json_mapping( - ' - tip_lot <=> tip_lot - user <=> user - lot <=> lot - robot <=> robot - - stamp_details <= stamp_details - ' - ) -end diff --git a/app/api/io/state_change.rb b/app/api/io/state_change.rb deleted file mode 100644 index 6a87601338..0000000000 --- a/app/api/io/state_change.rb +++ /dev/null @@ -1,20 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::StateChange} -class Io::StateChange < Core::Io::Base - set_model_for_input(::StateChange) - set_json_root(:state_change) - - # set_eager_loading { |model| model } # TODO: uncomment and add any named_scopes that do includes you need - - define_attribute_and_json_mapping( - ' - user <=> user - contents <=> contents - reason <=> reason - target <= target - target_state <=> target_state - previous_state => previous_state - customer_accepts_responsibility <= customer_accepts_responsibility - ' - ) -end diff --git a/app/api/io/stock_multiplexed_library_tube.rb b/app/api/io/stock_multiplexed_library_tube.rb deleted file mode 100644 index 40b492b7c9..0000000000 --- a/app/api/io/stock_multiplexed_library_tube.rb +++ /dev/null @@ -1,12 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for StockMultiplexedLibraryTube -class Io::StockMultiplexedLibraryTube < Io::Tube - set_model_for_input(::StockMultiplexedLibraryTube) - set_json_root(:tube) - - define_attribute_and_json_mapping( - ' - sibling_tubes => sibling_tubes - ' - ) -end diff --git a/app/api/io/study.rb b/app/api/io/study.rb deleted file mode 100644 index ff3165c4f4..0000000000 --- a/app/api/io/study.rb +++ /dev/null @@ -1,32 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for Study -class Io::Study < Core::Io::Base - set_model_for_input(::Study) - set_json_root(:study) - set_eager_loading { |model| model.include_study_metadata.include_projects } - - define_attribute_and_json_mapping( - ' - name => name - ethically_approved => ethically_approved - state => state - abbreviation => abbreviation - - study_metadata.study_type.name => type - study_metadata.faculty_sponsor.name => sac_sponsor - study_metadata.reference_genome.name => reference_genome - study_metadata.study_ebi_accession_number => accession_number - study_metadata.study_description => description - study_metadata.study_abstract => abstract - - study_metadata.contaminated_human_dna => contaminated_human_dna - study_metadata.remove_x_and_autosomes? => remove_x_and_autosomes - study_metadata.separate_y_chromosome_data => separate_y_chromosome_data - study_metadata.contains_human_dna => contains_human_dna - study_metadata.commercially_available => commercially_available - study_metadata.data_release_study_type.name => data_release_sort_of_study - study_metadata.data_release_strategy => data_release_strategy -study_metadata.contaminated_human_data_access_group => contaminated_human_data_access_group - ' - ) -end diff --git a/app/api/io/submission.rb b/app/api/io/submission.rb deleted file mode 100644 index ed53cdd675..0000000000 --- a/app/api/io/submission.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::Submission} -class Io::Submission < Core::Io::Base - set_model_for_input(::Submission) - set_json_root(:submission) - set_eager_loading(&:include_orders) - - define_attribute_and_json_mapping( - ' - state => state - orders <=> orders - - user <= user - ' - ) -end diff --git a/app/api/io/submission_pool.rb b/app/api/io/submission_pool.rb deleted file mode 100644 index eb590b6420..0000000000 --- a/app/api/io/submission_pool.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::SubmissionPool} -class Io::SubmissionPool < Core::Io::Base - set_model_for_input(::SubmissionPool) - set_json_root(:submission_pool) - set_eager_loading { |model| model } - - define_attribute_and_json_mapping( - ' - plates_in_submission => plates_in_submission - used_tag_layout_templates => used_tag_layout_templates - used_tag2_layout_templates => used_tag2_layout_templates - ' - ) -end diff --git a/app/api/io/submission_template.rb b/app/api/io/submission_template.rb deleted file mode 100644 index 83b484cc79..0000000000 --- a/app/api/io/submission_template.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::SubmissionTemplate} -class Io::SubmissionTemplate < Core::Io::Base - set_model_for_input(::SubmissionTemplate) - set_json_root(:order_template) - - # set_eager_loading { |model| model } # TODO: uncomment and add any named_scopes that do includes you need - - define_attribute_and_json_mapping( - ' - name => name - ' - ) -end diff --git a/app/api/io/supplier.rb b/app/api/io/supplier.rb deleted file mode 100644 index d5bb597705..0000000000 --- a/app/api/io/supplier.rb +++ /dev/null @@ -1,32 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::Supplier} -class Io::Supplier < Core::Io::Base - # This module adds the behaviour we require from the Supplier module. - module ApiIoSupport - def self.included(base) - base.class_eval do - # TODO: add any named scopes - # TODO: add any associations - end - end - - # TODO: add any methods - end - - set_json_root(:supplier) - - # set_eager_loading { |model| model } # TODO: uncomment and add any named_scopes that do includes you need - - define_attribute_and_json_mapping( - ' - name => name - email => email - address => address - contact_name => contact_name - phone_number => phone_number - fax => fax - supplier_url => url - abbreviation => abbreviation - ' - ) -end diff --git a/app/api/io/tag2_layout.rb b/app/api/io/tag2_layout.rb deleted file mode 100644 index 7844719793..0000000000 --- a/app/api/io/tag2_layout.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::Tag2Layout} -class Io::Tag2Layout < Core::Io::Base - set_model_for_input(::Tag2Layout) - set_json_root(:tag2_layout) - set_eager_loading { |model| model.include_plate.include_tag } - - define_attribute_and_json_mapping( - ' - user <=> user - plate <=> plate - target_well_locations <=> target_well_locations - source <=> source - - tag.name => tag.name - tag.map_id => tag.identifier - tag.oligo => tag.oligo - tag.tag_group.name => tag.group - ' - ) -end diff --git a/app/api/io/tag2_layout_template.rb b/app/api/io/tag2_layout_template.rb deleted file mode 100644 index 2a8beb309d..0000000000 --- a/app/api/io/tag2_layout_template.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::Tag2LayoutTemplate} -class Io::Tag2LayoutTemplate < Core::Io::Base - set_model_for_input(::Tag2LayoutTemplate) - set_json_root(:tag2_layout_template) - set_eager_loading(&:include_tag) # TODO: uncomment and add any named_scopes that do includes you need - - define_attribute_and_json_mapping( - ' - name => name - - tag.name => tag.name - tag.map_id => tag.identifier - tag.oligo => tag.oligo - tag.tag_group.name => tag.group - ' - ) -end diff --git a/app/api/io/tag_group.rb b/app/api/io/tag_group.rb deleted file mode 100644 index ce0133183f..0000000000 --- a/app/api/io/tag_group.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::TagGroup} -class Io::TagGroup < Core::Io::Base - set_model_for_input(::TagGroup) - set_json_root(:tag_group) - - define_attribute_and_json_mapping( - ' - name => name - indexed_tags => tags - ' - ) -end diff --git a/app/api/io/tag_layout.rb b/app/api/io/tag_layout.rb deleted file mode 100644 index 46f0c80a1d..0000000000 --- a/app/api/io/tag_layout.rb +++ /dev/null @@ -1,21 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::TagLayout} -class Io::TagLayout < Core::Io::Base - set_model_for_input(::TagLayout) - set_json_root(:tag_layout) - set_eager_loading { |model| model.include_plate.include_tag_group } - - define_attribute_and_json_mapping( - ' - user <=> user - plate <=> plate - substitutions <=> substitutions - tag_group <=> tag_group - tag2_group <=> tag2_group - direction <=> direction - walking_by <=> walking_by - initial_tag <=> initial_tag - enforce_uniqueness <= enforce_uniqueness - ' - ) -end diff --git a/app/api/io/tag_layout_template.rb b/app/api/io/tag_layout_template.rb deleted file mode 100644 index ac6b82bfd8..0000000000 --- a/app/api/io/tag_layout_template.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::TagLayoutTemplate} -class Io::TagLayoutTemplate < Core::Io::Base - set_model_for_input(::TagLayoutTemplate) - set_json_root(:tag_layout_template) - set_eager_loading { |model| model.include_tags.enabled_only } - - define_attribute_and_json_mapping( - ' - name => name - tag_group => tag_group - tag2_group => tag2_group - direction => direction - walking_by => walking_by - ' - ) -end diff --git a/app/api/io/transfer.rb b/app/api/io/transfer.rb deleted file mode 100644 index 9175bf57f5..0000000000 --- a/app/api/io/transfer.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::Transfer} -class Io::Transfer < Core::Io::Base - set_model_for_input(::Transfer) - set_json_root(:transfer) - - define_attribute_and_json_mapping( - ' - user <=> user - source <=> source - ' - ) -end diff --git a/app/api/io/transfer/between_plates.rb b/app/api/io/transfer/between_plates.rb deleted file mode 100644 index 02b0b7df78..0000000000 --- a/app/api/io/transfer/between_plates.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true -class Io::Transfer::BetweenPlates < Core::Io::Base - set_model_for_input(::Transfer::BetweenPlates) - set_json_root(:transfer) - set_eager_loading { |model| model.include_source.include_destination } - - define_attribute_and_json_mapping( - ' - user <=> user - source <=> source - destination <=> destination - transfers <=> transfers - ' - ) -end diff --git a/app/api/io/transfer/between_plates_by_submission.rb b/app/api/io/transfer/between_plates_by_submission.rb deleted file mode 100644 index 853c41e51e..0000000000 --- a/app/api/io/transfer/between_plates_by_submission.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true -class Io::Transfer::BetweenPlatesBySubmission < Core::Io::Base - set_model_for_input(::Transfer::BetweenPlatesBySubmission) - set_json_root(:transfer) - set_eager_loading { |model| model.include_source.include_destination } - - define_attribute_and_json_mapping( - ' - user <=> user - source <=> source - destination <=> destination - transfers => transfers - ' - ) -end diff --git a/app/api/io/transfer/between_specific_tubes.rb b/app/api/io/transfer/between_specific_tubes.rb deleted file mode 100644 index 2c18e6d08c..0000000000 --- a/app/api/io/transfer/between_specific_tubes.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true -class Io::Transfer::BetweenSpecificTubes < Core::Io::Base - set_model_for_input(::Transfer::BetweenSpecificTubes) - set_json_root(:transfer) - - # set_eager_loading { |model| model.include_source.include_destination } - - define_attribute_and_json_mapping( - ' - user <=> user - source <=> source - destination <=> destination - ' - ) -end diff --git a/app/api/io/transfer/between_tubes_by_submission.rb b/app/api/io/transfer/between_tubes_by_submission.rb deleted file mode 100644 index 5b80fe9755..0000000000 --- a/app/api/io/transfer/between_tubes_by_submission.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true -class Io::Transfer::BetweenTubesBySubmission < Core::Io::Base - set_model_for_input(::Transfer::BetweenTubesBySubmission) - set_json_root(:transfer) - - # set_eager_loading { |model| model.include_source.include_destination } - - define_attribute_and_json_mapping( - ' - user <=> user - source <=> source - destination => destination - ' - ) -end diff --git a/app/api/io/transfer/from_plate_to_specific_tubes.rb b/app/api/io/transfer/from_plate_to_specific_tubes.rb deleted file mode 100644 index 9b52a0bead..0000000000 --- a/app/api/io/transfer/from_plate_to_specific_tubes.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true -class Io::Transfer::FromPlateToSpecificTubes < Core::Io::Base - set_model_for_input(::Transfer::FromPlateToSpecificTubes) - set_json_root(:transfer) - set_eager_loading { |model| model.include_source.include_transfers } - - define_attribute_and_json_mapping( - ' - user <=> user - source <=> source - targets <= targets - transfers => transfers - ' - ) -end diff --git a/app/api/io/transfer/from_plate_to_specific_tubes_by_pool.rb b/app/api/io/transfer/from_plate_to_specific_tubes_by_pool.rb deleted file mode 100644 index 232f6d3db7..0000000000 --- a/app/api/io/transfer/from_plate_to_specific_tubes_by_pool.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true -class Io::Transfer::FromPlateToSpecificTubesByPool < Core::Io::Base - set_model_for_input(::Transfer::FromPlateToSpecificTubesByPool) - set_json_root(:transfer) - set_eager_loading { |model| model.include_source.include_transfers } - - define_attribute_and_json_mapping( - ' - user <=> user - source <=> source - targets <= targets - transfers => transfers - ' - ) -end diff --git a/app/api/io/transfer/from_plate_to_tube.rb b/app/api/io/transfer/from_plate_to_tube.rb deleted file mode 100644 index bf050fd9a2..0000000000 --- a/app/api/io/transfer/from_plate_to_tube.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true -class Io::Transfer::FromPlateToTube < Core::Io::Base - set_model_for_input(::Transfer::FromPlateToTube) - set_json_root(:transfer) - - define_attribute_and_json_mapping( - ' - user <=> user - source <=> source - destination <=> destination - transfers <=> transfers - ' - ) -end diff --git a/app/api/io/transfer/from_plate_to_tube_by_multiplex.rb b/app/api/io/transfer/from_plate_to_tube_by_multiplex.rb deleted file mode 100644 index 96b9745eba..0000000000 --- a/app/api/io/transfer/from_plate_to_tube_by_multiplex.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true -class Io::Transfer::FromPlateToTubeByMultiplex < Core::Io::Base - set_model_for_input(::Transfer::FromPlateToTubeByMultiplex) - set_json_root(:transfer) - set_eager_loading { |model| model.include_source.include_transfers } - - define_attribute_and_json_mapping( - ' - user <=> user - source <=> source - transfers => transfers - ' - ) -end diff --git a/app/api/io/transfer/from_plate_to_tube_by_submission.rb b/app/api/io/transfer/from_plate_to_tube_by_submission.rb deleted file mode 100644 index 5566d17a30..0000000000 --- a/app/api/io/transfer/from_plate_to_tube_by_submission.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true -class Io::Transfer::FromPlateToTubeBySubmission < Core::Io::Base - set_model_for_input(::Transfer::FromPlateToTubeBySubmission) - set_json_root(:transfer) - set_eager_loading { |model| model.include_source.include_transfers } - - define_attribute_and_json_mapping( - ' - user <=> user - source <=> source - transfers => transfers - ' - ) -end diff --git a/app/api/io/transfer_request.rb b/app/api/io/transfer_request.rb deleted file mode 100644 index 3422399829..0000000000 --- a/app/api/io/transfer_request.rb +++ /dev/null @@ -1,20 +0,0 @@ -# frozen_string_literal: true -module Io - # Controls API V1 IO for {::TransferRequest} - class TransferRequest < ::Core::Io::Base - set_model_for_input(::TransferRequest) - set_json_root(:transfer_request) - set_eager_loading { |model| model.includes(asset: :uuid_object).includes(target_asset: :uuid_object) } - - define_attribute_and_json_mapping( - ' - state <=> state - - submission.uuid => submission.uuid - submission <= submission - asset <= source_asset - target_asset <= target_asset - ' - ) - end -end diff --git a/app/api/io/transfer_request_collection.rb b/app/api/io/transfer_request_collection.rb deleted file mode 100644 index dd0e2775e8..0000000000 --- a/app/api/io/transfer_request_collection.rb +++ /dev/null @@ -1,32 +0,0 @@ -# frozen_string_literal: true -module Io - # Controls API V1 IO for {::TransferRequestCollection} - class TransferRequestCollection < ::Core::Io::Base - set_model_for_input(::TransferRequestCollection) - set_json_root(:transfer_request_collection) - - set_eager_loading do |model| - # Note we use preload here, rather than includes, as otherwise the target_tubes nuke our loaded transfer requests - model - .eager_load(user: :uuid_object) - .preload( - target_tubes: [:uuid_object, :purpose, { aliquots: Io::Aliquot::PRELOADS }, :transfer_requests_as_target] - ) - .preload( - transfer_requests: [ - :uuid_object, - { asset: :uuid_object, target_asset: :uuid_object, submission: :uuid_object } - ] - ) - end - - define_attribute_and_json_mapping( - ' - user <= user - transfer_requests => transfer_requests - transfer_requests_io <= transfer_requests - target_tubes => target_tubes - ' - ) - end -end diff --git a/app/api/io/transfer_template.rb b/app/api/io/transfer_template.rb deleted file mode 100644 index 928eb632b9..0000000000 --- a/app/api/io/transfer_template.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::TransferTemplate} -class Io::TransferTemplate < Core::Io::Base - set_model_for_input(::TransferTemplate) - set_json_root(:transfer_template) - - define_attribute_and_json_mapping( - ' - name => name - transfers => transfers - ' - ) -end diff --git a/app/api/io/tube.rb b/app/api/io/tube.rb deleted file mode 100644 index 6b80a8694e..0000000000 --- a/app/api/io/tube.rb +++ /dev/null @@ -1,39 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for Tube -class Io::Tube < Io::Asset - set_model_for_input(::Tube) - set_json_root(:tube) - set_eager_loading { |model| model.include_aliquots_for_api.include_scanned_into_lab_event } - - define_attribute_and_json_mapping( - ' - state => state - purpose.name => purpose.name - purpose.uuid => purpose.uuid - - closed => closed - concentration.to_f => concentration - volume.to_f => volume - scanned_in_date => scanned_in_date - role => label.prefix - purpose.name => label.text - - source_plate.uuid => stock_plate.uuid - source_plate.barcode_number => stock_plate.barcode.number - source_plate.prefix => stock_plate.barcode.prefix - source_plate.two_dimensional_barcode => stock_plate.barcode.two_dimensional - source_plate.ean13_barcode => stock_plate.barcode.ean13 - source_plate.machine_barcode => stock_plate.barcode.machine - source_plate.barcode_type => stock_plate.barcode.type - - barcode_number => barcode.number - prefix => barcode.prefix - two_dimensional_barcode => barcode.two_dimensional - machine_barcode => barcode.machine - ean13_barcode => barcode.ean13 - barcode_type => barcode.type - - aliquots => aliquots - ' - ) -end diff --git a/app/api/io/tube/purpose.rb b/app/api/io/tube/purpose.rb deleted file mode 100644 index 552a55642e..0000000000 --- a/app/api/io/tube/purpose.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -# Controls API V1 IO for Tube -class Io::Tube::Purpose < Core::Io::Base - set_model_for_input(::Tube::Purpose) - set_json_root(:tube_purpose) - - define_attribute_and_json_mapping( - ' - name <=> name - parent_purposes <= parents - child_purposes <= children - target_type <= target_type - type <= type - ' - ) -end diff --git a/app/api/io/tube_creation.rb b/app/api/io/tube_creation.rb deleted file mode 100644 index 212caa4bdb..0000000000 --- a/app/api/io/tube_creation.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::TubeCreation} -class Io::TubeCreation < Core::Io::Base - set_model_for_input(::TubeCreation) - set_json_root(:tube_creation) - set_eager_loading(&:include_parent) - - define_attribute_and_json_mapping( - ' - user <=> user - parent <=> parent - child_purpose <=> child_purpose - ' - ) -end diff --git a/app/api/io/tube_from_tube_creation.rb b/app/api/io/tube_from_tube_creation.rb deleted file mode 100644 index 0272c0ba5a..0000000000 --- a/app/api/io/tube_from_tube_creation.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::TubeFromTubeCreation} -class Io::TubeFromTubeCreation < Core::Io::Base - set_model_for_input(::TubeFromTubeCreation) - set_json_root(:tube_from_tube_creation) - - set_eager_loading { |model| model.includes(parent: { aliquots: Io::Aliquot::PRELOADS }) } - - define_attribute_and_json_mapping( - ' - user <=> user - parent <=> parent - child_purpose <=> child_purpose - ' - ) -end diff --git a/app/api/io/user.rb b/app/api/io/user.rb deleted file mode 100644 index fa226c7214..0000000000 --- a/app/api/io/user.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::User} -class Io::User < Core::Io::Base - set_model_for_input(::User) - set_json_root(:user) - define_attribute_and_json_mapping( - ' - login => login - email <=> email - first_name <=> first_name - last_name <=> last_name - barcode <=> barcode - swipecard_code <= swipecard_code - swipecard_code? => has_a_swipecard_code - -' - ) -end diff --git a/app/api/io/volume_update.rb b/app/api/io/volume_update.rb deleted file mode 100644 index fd55af6ede..0000000000 --- a/app/api/io/volume_update.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::VolumeUpdate} -class Io::VolumeUpdate < Core::Io::Base - set_model_for_input(::VolumeUpdate) - set_json_root(:volume_update) - - # set_eager_loading { |model| model } # TODO: uncomment and add any named_scopes that do includes you need - - define_attribute_and_json_mapping( - ' - created_by <=> created_by - volume_change <=> volume_change - ' - ) -end diff --git a/app/api/io/well.rb b/app/api/io/well.rb deleted file mode 100644 index ce8604691d..0000000000 --- a/app/api/io/well.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::Well} -class Io::Well < Core::Io::Base - set_model_for_input(::Well) - set_json_root(:well) - - # set_eager_loading { |model| model } # TODO: uncomment and add any named_scopes that do includes you need - - define_attribute_and_json_mapping( - ' - state => state - map.description => location - aliquots => aliquots - ' - ) -end diff --git a/app/api/io/work_completion.rb b/app/api/io/work_completion.rb deleted file mode 100644 index d210db4abf..0000000000 --- a/app/api/io/work_completion.rb +++ /dev/null @@ -1,16 +0,0 @@ -# frozen_string_literal: true -# Controls API V1 IO for {::WorkCompletion} -class Io::WorkCompletion < Core::Io::Base - set_model_for_input(::WorkCompletion) - set_json_root(:work_completion) - - # set_eager_loading { |model| model } # TODO: uncomment and add any named_scopes that do includes you need - - define_attribute_and_json_mapping( - ' - user <= user - target <= target - submissions <= submissions - ' - ) -end diff --git a/app/api/model_extensions/asset_group.rb b/app/api/model_extensions/asset_group.rb deleted file mode 100644 index 38f5bd16c0..0000000000 --- a/app/api/model_extensions/asset_group.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true -# Included in {AssetGroup} to provide scopes used by the V1 API -# @note This could easily be in-lined in asset group itself -module ModelExtensions::AssetGroup - def self.included(base) - base.class_eval do - scope :include_study, -> { includes(:study) } - scope :include_assets, -> { includes(:assets) } - end - end -end diff --git a/app/api/model_extensions/bait_library_layout.rb b/app/api/model_extensions/bait_library_layout.rb deleted file mode 100644 index 0609f2bb05..0000000000 --- a/app/api/model_extensions/bait_library_layout.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true -# Included in {BaitLibraryLayout} to provide scopes used by the V1 API -module ModelExtensions::BaitLibraryLayout - def self.included(base) - base.class_eval do - extend ModelExtensions::Plate::NamedScopeHelpers - - include_plate_named_scope :plate - end - end -end diff --git a/app/api/model_extensions/barcode_printer.rb b/app/api/model_extensions/barcode_printer.rb deleted file mode 100644 index 6844f0c74d..0000000000 --- a/app/api/model_extensions/barcode_printer.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true -# Was used to extend {BarcodePrinter} with methods which were supposed to be specific to the -# V1 API. Now redundant -# @note JG: I believe this file can just be deleted. Only reason I'm not doing it now -# is to try and keep this branch almost exclusively documentation related. -# @todo Delete this file. It doesn't even appear to be included in {BarcodePrinter} -module ModelExtensions::BarcodePrinter - def self.included(base) - base.class_eval do - # TODO: Add an associations or named_scopes required - end - end - - # TODO: Add any instance methods required -end diff --git a/app/api/model_extensions/library_tube.rb b/app/api/model_extensions/library_tube.rb deleted file mode 100644 index d0e34d9480..0000000000 --- a/app/api/model_extensions/library_tube.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true -# Included in {LibraryTube} to provide scopes used by the V1 API -# @note This could easily be in-lined in LibraryTube itself -module ModelExtensions::LibraryTube - def self.included(base) - base.class_eval { scope :include_source_request, -> { includes(source_request: %i[uuid_object request_metadata]) } } - end -end diff --git a/app/api/model_extensions/multiplexed_library_tube.rb b/app/api/model_extensions/multiplexed_library_tube.rb deleted file mode 100644 index be5a1c04a4..0000000000 --- a/app/api/model_extensions/multiplexed_library_tube.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true -# Included in {MultiplexedLibraryTube} to provide scopes used by the V1 API -# @note This could easily be in-lined in MultiplexedLibraryTube itself -module ModelExtensions::MultiplexedLibraryTube - def self.included(base) - base.class_eval { scope :include_source_request, -> { includes(source_request: %i[uuid_object request_metadata]) } } - end -end diff --git a/app/api/model_extensions/order.rb b/app/api/model_extensions/order.rb deleted file mode 100644 index 0c315a99f1..0000000000 --- a/app/api/model_extensions/order.rb +++ /dev/null @@ -1,207 +0,0 @@ -# frozen_string_literal: true -# Included in {Order} -# The intent of this file was to provide methods specific to the V1 API -module ModelExtensions::Order - class RequestOptionForValidation < OpenStruct # rubocop:todo Style/OpenStructUse - delegate :errors, :include_unset_values?, to: :owner - end - - module Validations - def self.included(base) - base.class_eval do - extend DelegateValidation - - delegate_validation :request_options_for_validation, - as: 'request_options', - to: :request_types, - if: :validate_request_options? - end - end - - # The validation of the request options should happen if we are leaving the building state, or if the - # request options have been specified. Once they are specified they are always checked, unless they are - # completely blanked. - def validate_request_options? - not building? or request_options.present? - end - private :validate_request_options? - - def request_types_delegate_validator - DelegateValidation::CompositeValidator.construct( - *::RequestType.find(request_types.flatten).map(&:delegate_validator) - ) - end - - # If this returns true then we check values that have not been set, otherwise we can ignore them. This would - # mean that we should not require values that are unset, until we're moving out of the building state. - def include_unset_values? - not building? - end - - def request_options_for_validation - RequestOptionForValidation.new({ owner: self }.reverse_merge(request_options || {})) - end - end - - def validate_new_record(assets) - if (not new_record?) && asset_group? && assets.present? - raise StandardError, 'requested action is not supported on this resource' - end - - true - end - - # rubocop:todo Metrics/MethodLength - def self.included(base) # rubocop:todo Metrics/AbcSize - base.class_eval do - include Validations - - before_validation :merge_in_structured_request_options - - scope :include_study, -> { includes(study: :uuid_object) } - scope :include_project, -> { includes(project: :uuid_object) } - scope :include_assets, -> { includes(assets: [:uuid_object, { aliquots: Io::Aliquot::PRELOADS }]) } - - has_many :submitted_assets, -> { joins(:asset) }, inverse_of: :order - has_many :assets, through: :submitted_assets, before_add: :validate_new_record do - def <<(associated) - return super(associated) if associated.is_a?(Receptacle) - - Rails.logger.warn("#{associated.class.name} passed to order.assets") - super(associated&.receptacle) - end - end - - scope :that_submitted_asset_id, ->(asset_id) { where(submitted_assets: { asset_id: }).joins(:submitted_assets) } - - validate :extended_validation - def extended_validation - extended_validators.reduce(true) { |valid, validator| validator.validate_order(self) && valid } - end - - # The API can create submissions but we have to prevent someone from changing the study - # and the project once they have been set. - validates_each(:study, :project, on: :update) do |record, attr, _value| - record.errors.add(attr, 'cannot be changed') if record.send(:"will_save_change_to_#{attr}_id?") - end - - def extended_validators - ExtendedValidator.for_submission(self) - end - end - end - - # rubocop:enable Metrics/MethodLength - - class NonNilHash - def initialize(key_style_operation = :symbolize_keys) - @key_style_operation = key_style_operation - @store = ActiveSupport::HashWithIndifferentAccess.new - end - - def deep_merge(hash) - @store.deep_merge!(hash.try(@key_style_operation) || {}) - self - end - - def [](*keys) - node_and_leaf(*keys) { |node, leaf| node.fetch(leaf, nil) } - end - - def []=(*keys_and_values) - value = keys_and_values.pop - return if value.nil? - - node_and_leaf(*keys_and_values) { |node, leaf| node[leaf] = value } - end - - def fetch(*keys_and_default) - default = keys_and_default.pop - node_and_leaf(*keys_and_default) { |node, left| node.fetch(left, default) } - end - - def to_hash - {}.deep_merge(@store) - end - - def node_and_leaf(*keys) - leaf = keys.pop - node = keys.inject(@store) { |h, k| h[k] ||= ActiveSupport::HashWithIndifferentAccess.new } - yield(node, leaf) - end - private :node_and_leaf - end - - def request_type_multiplier - yield(request_types.last.to_s.to_sym) if request_types.present? - end - - # rubocop:todo Metrics/MethodLength - def request_options_structured # rubocop:todo Metrics/AbcSize - NonNilHash - .new(:stringify_keys) - .tap do |json| - NonNilHash - .new - .deep_merge(request_options) - .tap do |attributes| - json['read_length'] = attributes[:read_length].try(:to_i) - json['library_type'] = attributes[:library_type] - json['fragment_size_required', 'from'] = attributes[:fragment_size_required_from].try(:to_i) - json['fragment_size_required', 'to'] = attributes[:fragment_size_required_to].try(:to_i) - json['pcr_cycles'] = attributes[:pcr_cycles].try(:to_i) - json['bait_library'] = attributes[:bait_library_name] - json['primer_panel_name'] = attributes[:primer_panel_name] - json['sequencing_type'] = attributes[:sequencing_type] - json['insert_size'] = attributes[:insert_size].try(:to_i) - request_type_multiplier { |id| json['number_of_lanes'] = attributes[:multiplier, id] } - end - end - .to_hash - end - - # rubocop:enable Metrics/MethodLength - - # rubocop:todo Metrics/MethodLength - def request_options_structured=(values) # rubocop:todo Metrics/AbcSize - @request_options_structured = - NonNilHash - .new - .tap do |attributes| - NonNilHash - .new(:stringify_keys) - .deep_merge(values) - .tap do |json| - # NOTE: Be careful with the names here to ensure that they match up, exactly with what is in a template. - # If the template uses symbol names then these need to be symbols too. - attributes[:read_length] = json['read_length'] - attributes['library_type'] = json['library_type'] - attributes['fragment_size_required_from'] = json['fragment_size_required', 'from'] || - json['fragment_size_required_from'] - attributes['fragment_size_required_to'] = json['fragment_size_required', 'to'] || - json['fragment_size_required_to'] - attributes['pcr_cycles'] = json['pcr_cycles'] - attributes[:bait_library_name] = json['bait_library'] - attributes[:primer_panel_name] = json['primer_panel_name'] - attributes[:sequencing_type] = json['sequencing_type'] - attributes[:insert_size] = json['insert_size'] - request_type_multiplier { |id| attributes[:multiplier, id] = json['number_of_lanes'] } - end - end - .to_hash - end - - # rubocop:enable Metrics/MethodLength - - def merge_in_structured_request_options - self.request_options ||= {} - self.request_options = self.request_options.deep_merge(@request_options_structured || {}) - end - private :merge_in_structured_request_options - - def request_type_objects - return [] if request_types.blank? - - ::RequestType.find(request_types) - end -end diff --git a/app/api/model_extensions/plate.rb b/app/api/model_extensions/plate.rb deleted file mode 100644 index d7dc0f927e..0000000000 --- a/app/api/model_extensions/plate.rb +++ /dev/null @@ -1,46 +0,0 @@ -# frozen_string_literal: true -# Included in {Plate} -# The intent of this file was to provide methods specific to the V1 API -module ModelExtensions::Plate - module NamedScopeHelpers - def include_plate_named_scope(plate_association) - scope :"include_#{plate_association}", - lambda { includes(plate_association.to_sym => ::ModelExtensions::Plate::PLATE_INCLUDES) } - end - end - - PLATE_INCLUDES = [:plate_metadata, { wells: %i[map transfer_requests_as_target uuid_object] }].freeze - - def self.included(base) - base.class_eval do - scope :include_plate_purpose, -> { includes(:plate_purpose) } - scope :include_plate_metadata, -> { includes(:plate_metadata) } - delegate :pool_id_for_well, to: :plate_purpose, allow_nil: true - end - end - - def library_source_plate - plate_purpose.library_source_plate(self) - end - - def library_source_plates - plate_purpose.library_source_plate(self) - end - - # Adds pre-capture pooling information, we need to delegate this to the stock plate, as we need all the wells - # Currently used in {Transfer::BetweenPlates} to set submission id, we should switch to doing this - # directly via Limber with transfer request collections - def pre_cap_groups # rubocop:todo Metrics/AbcSize - Request - .include_request_metadata - .for_pre_cap_grouping_of(self) - .each_with_object({}) do |request, groups| - groups[request.group_id] = { wells: request.group_into.split(',') }.tap do |pool_information| - pool_information[:pre_capture_plex_level] ||= request.request_metadata.pre_capture_plex_level - - # We supply the submission id to assist with correctly tagging transfer requests later - pool_information[:submission_id] ||= request.submission_id - end unless request.group_id.nil? - end - end -end diff --git a/app/api/model_extensions/project.rb b/app/api/model_extensions/project.rb deleted file mode 100644 index a7ade11dd2..0000000000 --- a/app/api/model_extensions/project.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true -# Included in {Project} -# The intent of this file was to provide methods specific to the V1 API -module ModelExtensions::Project - def self.included(base) - base.class_eval do - has_many :submissions - scope :include_roles, -> { includes(roles: :users) } - end - end - - def roles_as_json - roles.to_h do |role| - [role.name.underscore, role.users.map { |user| { login: user.login, email: user.email, name: user.name } }] - end - end -end diff --git a/app/api/model_extensions/request.rb b/app/api/model_extensions/request.rb deleted file mode 100644 index 84878a6894..0000000000 --- a/app/api/model_extensions/request.rb +++ /dev/null @@ -1,18 +0,0 @@ -# frozen_string_literal: true -# Included in {Request} -# The intent of this file was to provide methods specific to the V1 API -module ModelExtensions::Request - def self.included(base) # rubocop:todo Metrics/AbcSize - base.class_eval do - scope :include_source_asset, - -> { includes(asset: [:uuid_object, :barcodes, :scanned_into_lab_event, { aliquots: %i[sample tag] }]) } - scope :include_target_asset, - -> { includes(target_asset: [:uuid_object, :barcodes, { aliquots: %i[sample tag] }]) } - - scope :include_study, -> { includes(study: :uuid_object) } - scope :include_project, -> { includes(project: :uuid_object) } - scope :include_request_type, -> { includes(:request_type) } - scope :include_submission, -> { includes(submission: :uuid_object) } - end - end -end diff --git a/app/api/model_extensions/robot.rb b/app/api/model_extensions/robot.rb deleted file mode 100644 index 051ec874d9..0000000000 --- a/app/api/model_extensions/robot.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true -# Included in {Robot} -# The intent of this file was to provide methods specific to the V1 API -module ModelExtensions::Robot - def json_for_properties - robot_properties.to_h { |prop| [prop.key, prop.value] } - end -end diff --git a/app/api/model_extensions/sample.rb b/app/api/model_extensions/sample.rb deleted file mode 100644 index 5827f1fd32..0000000000 --- a/app/api/model_extensions/sample.rb +++ /dev/null @@ -1,24 +0,0 @@ -# frozen_string_literal: true -# Included in {Sample} -# The intent of this file was to provide methods specific to the V1 API -# @todo Rails relationships should probably be moved to Sample -module ModelExtensions::Sample - def self.included(base) - base.class_eval do - scope :include_studies, -> { includes(studies: :study_metadata) } - - has_one :primary_study_samples, -> { order(:study_id) }, class_name: 'StudySample' - has_one :primary_study, through: :primary_study_samples, source: :study - has_one :primary_study_metadata, through: :primary_study, source: :study_metadata - has_one :study_reference_genome, through: :primary_study_metadata, source: :reference_genome - end - end - - def sample_reference_genome_name - sample_reference_genome.try(:name) - end - - def sample_reference_genome_name=(name) - sample_metadata.reference_genome = ReferenceGenome.find_by(name:) - end -end diff --git a/app/api/model_extensions/sample_manifest.rb b/app/api/model_extensions/sample_manifest.rb deleted file mode 100644 index ff3b1c7dca..0000000000 --- a/app/api/model_extensions/sample_manifest.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: true -# Included in {SampleManifest} -# The intent of this file was to provide methods specific to the V1 API -module ModelExtensions::SampleManifest - def self.included(base) - base.class_eval do - scope :include_samples, - -> do - includes( - samples: [ - :uuid_object, - { sample_metadata: :reference_genome, primary_study: { study_metadata: :reference_genome } } - ] - ) - end - delegate :io_samples, to: :core_behaviour - end - end -end diff --git a/app/api/model_extensions/sample_tube.rb b/app/api/model_extensions/sample_tube.rb deleted file mode 100644 index 2ea20952f3..0000000000 --- a/app/api/model_extensions/sample_tube.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true -# Included in {SampleTube} -# The intent of this file was to provide methods specific to the V1 API -# @todo Rails relationships should be moved to SampleTube -module ModelExtensions::SampleTube - def self.included(base) - base.class_eval { has_many :library_tubes, through: :links_as_parent, source: :descendant, validate: false } - end -end diff --git a/app/api/model_extensions/stamp.rb b/app/api/model_extensions/stamp.rb deleted file mode 100644 index 50b6c74ca1..0000000000 --- a/app/api/model_extensions/stamp.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true -# Included in {Stamp} -# Handles the translation of V1 API input to more standard rails attributes -module ModelExtensions::Stamp - def stamp_details=(details) - stamp_qcables.build(details.map { |d| locate_qcable(d) }) - end - - private - - def locate_qcable(d) - d['qcable'] = Uuid.find_by(external_id: d['qcable']).resource - d - end -end diff --git a/app/api/model_extensions/study.rb b/app/api/model_extensions/study.rb deleted file mode 100644 index 7ebd82c705..0000000000 --- a/app/api/model_extensions/study.rb +++ /dev/null @@ -1,11 +0,0 @@ -# frozen_string_literal: true -# Included in {Study} -# The intent of this file was to provide methods specific to the V1 API -module ModelExtensions::Study - def self.included(base) - base.class_eval do - scope :include_samples, -> { includes(:samples) } - scope :include_projects, -> { includes(:projects) } - end - end -end diff --git a/app/api/model_extensions/submission.rb b/app/api/model_extensions/submission.rb deleted file mode 100644 index 40b4015ff7..0000000000 --- a/app/api/model_extensions/submission.rb +++ /dev/null @@ -1,23 +0,0 @@ -# frozen_string_literal: true -# Included in {Submission} -# The intent of this file was to provide methods specific to the V1 API -module ModelExtensions::Submission - def self.included(base) - base.class_eval do - scope :include_orders, - lambda { - includes( - orders: { - study: :uuid_object, - project: :uuid_object, - assets: [:uuid_object, { aliquots: Io::Aliquot::PRELOADS }] - } - ) - } - - def order - orders.first - end - end - end -end diff --git a/app/api/model_extensions/tag_layout.rb b/app/api/model_extensions/tag_layout.rb deleted file mode 100644 index e102810b67..0000000000 --- a/app/api/model_extensions/tag_layout.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true -# Included in {TagLayout} -# The intent of this file was to provide methods specific to the V1 API -module ModelExtensions::TagLayout - def self.included(base) - base.class_eval do - extend ModelExtensions::Plate::NamedScopeHelpers - - include_plate_named_scope :plate - - scope :include_tag_group, -> { includes(tag_group: :tags, tag2_group: :tags) } - end - end -end diff --git a/app/api/model_extensions/tube.rb b/app/api/model_extensions/tube.rb deleted file mode 100644 index 9d2b5a3807..0000000000 --- a/app/api/model_extensions/tube.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true -# Included in {Tube} -# The intent of this file was to provide methods specific to the V1 API -module ModelExtensions::Tube - def self.included(base) - base.class_eval { scope :include_purpose, -> { includes(:purpose) } } - end -end diff --git a/app/api/model_extensions/well.rb b/app/api/model_extensions/well.rb deleted file mode 100644 index 59aec08b7a..0000000000 --- a/app/api/model_extensions/well.rb +++ /dev/null @@ -1,25 +0,0 @@ -# frozen_string_literal: true -# Included in {Well} -# The intent of this file was to provide methods specific to the V1 API -module ModelExtensions::Well - def self.included(base) - base.class_eval do - scope :for_api_plate_json, - -> do - preload( - :map, - :transfer_requests_as_target, # Should be :transfer_requests_as_target - # :uuid_object is included elsewhere, and trying to also include it here - # actually disrupts the eager loading. - plate: :uuid_object, - aliquots: Io::Aliquot::PRELOADS - ) - end - end - end - - # Compatibility for v1 API maintains legacy 'type' for assets - def legacy_asset_type - sti_type - end -end diff --git a/app/middleware/api/endpoint_handler.rb b/app/middleware/api/endpoint_handler.rb deleted file mode 100644 index 69963c988d..0000000000 --- a/app/middleware/api/endpoint_handler.rb +++ /dev/null @@ -1,259 +0,0 @@ -# frozen_string_literal: true -# {include:file:docs/api_v1.md} -module Api - # Sinatra application which provides routing for the V1 API - # Automatically generates routes from the files listed under `app/api/endpoints` - # used in {Api::RootService} which in turn gets mounted in `config/routes.rb` - class EndpointHandler < ::Core::Service - class << self - def registered_mimetypes - @registered_mimetypes || [] - end - - # We can't use the built in provides, as the accepted mimetimes are fixed when the route is set up. - def file_requested(bool) - condition { request.acceptable_media_types.prioritize(registered_mimetypes).present? == bool } - end - - def file_attached(bool) - condition { registered_mimetypes.include?(request.content_type) == bool } - end - - # rubocop:todo Metrics/MethodLength - def file_addition(action, http_method) # rubocop:todo Metrics/AbcSize - send( - http_method, - %r{/([\da-f]{8}(?:-[\da-f]{4}){3}-[\da-f]{12})(?:/([^/]+(?:/[^/]+)*))?}, - file_attached: true - ) do - if request.acceptable_media_types.prioritize(registered_mimetypes).present? - raise Core::Service::ContentFiltering::InvalidRequestedContentTypeOnFile - end - - report('file') do - filename = /filename="([^"]*)"/.match(request.env['HTTP_CONTENT_DISPOSITION']).try(:[], 1) || 'unnamed_file' - begin - file = Tempfile.new(filename) - file.binmode - file.unlink - file.write(request.body.read) - - # Be kind... - file.rewind - request.body.rewind - uuid_in_url, parts = params[:captures][0], params[:captures][1].try(:split, '/') || [] - uuid = Uuid.find_by(external_id: uuid_in_url) or raise ActiveRecord::RecordNotFound, 'UUID does not exist' - handle_request(:instance, request, action, parts) do |request| - request.io = lookup_for_class(uuid.resource.class) { |e| raise e } - request.target = request.io.eager_loading_for(uuid.resource.class).include_uuid.find(uuid.resource_id) - request.file = file - request.filename = filename - end - ensure - file.close! - end - end - end - end - - # rubocop:enable Metrics/MethodLength - - # rubocop:todo Metrics/MethodLength - def file_model_addition(action, http_method) # rubocop:todo Metrics/AbcSize - send(http_method, %r{/([^\d/][^/]+(?:/[^/]+){0,2})}, file_attached: true) do - if request.acceptable_media_types.prioritize(registered_mimetypes).present? - raise Core::Service::ContentFiltering::InvalidRequestedContentType - end - - report('model') do - filename = /filename="([^"]*)"/.match(request.env['HTTP_CONTENT_DISPOSITION']).try(:[], 1) || 'unnamed_file' - begin - file = Tempfile.new(filename) - file.write(request.body.read) - - # Be kind... - file.rewind - request.body.rewind - determine_model_from_parts(*params[:captures].join.split('/')) do |model, parts| - handle_request(:model, request, action, parts) do |request| - request.io = lookup_for_class(model) { |_| nil } - request.target = model - request.file = file - request.filename = filename - end - end - ensure - file.close! - end - end - end - end - - # rubocop:enable Metrics/MethodLength - - def file_model_action(_action, http_method) - send(http_method, %r{/([^\d/][^/]+(?:/[^/]+){0,2})}, file_requested: true) do - report('model') { raise Core::Service::ContentFiltering::InvalidRequestedContentType } - end - end - - def file_action(action, http_method) # rubocop:todo Metrics/AbcSize, Metrics/MethodLength - send( - http_method, - %r{/([\da-f]{8}(?:-[\da-f]{4}){3}-[\da-f]{12})(?:/([^/]+(?:/[^/]+)*))?}, - file_requested: true - ) do - report('file') do - uuid_in_url, parts = params[:captures][0], params[:captures][1].try(:split, '/') || [] - uuid = Uuid.find_by(external_id: uuid_in_url) or raise ActiveRecord::RecordNotFound, 'UUID does not exist' - - file_through = - return_file(request, action, parts) do |request| - request.io = lookup_for_class(uuid.resource.class) { |e| raise e } - request.target = request.io.eager_loading_for(uuid.resource.class).include_uuid.find(uuid.resource_id) - end - uuid.resource.__send__(file_through) { |file| send_file file.path, filename: file.filename } - end - end - end - - def instance_action(action, http_method) # rubocop:todo Metrics/AbcSize, Metrics/MethodLength - send( - http_method, - %r{/([\da-f]{8}(?:-[\da-f]{4}){3}-[\da-f]{12})(?:/([^/]+(?:/[^/]+)*))?}, - file_attached: false, - file_requested: false - ) do - report('instance') do - uuid_in_url, parts = params[:captures][0], params[:captures][1].try(:split, '/') || [] - uuid = Uuid.find_by(external_id: uuid_in_url) or raise ActiveRecord::RecordNotFound, 'UUID does not exist' - handle_request(:instance, request, action, parts) do |request| - request.io = lookup_for_class(uuid.resource.class) { |e| raise e } - request.target = request.io.eager_loading_for(uuid.resource.class).include_uuid.find(uuid.resource_id) - end - end - end - end - - def model_action(action, http_method) - send(http_method, %r{/([^\d/][^/]+(?:/[^/]+){0,2})}, file_attached: false, file_requested: false) do - report('model') do - determine_model_from_parts(*params[:captures].join.split('/')) do |model, parts| - handle_request(:model, request, action, parts) do |request| - request.io = lookup_for_class(model) { |_| nil } - request.target = model - end - end - end - end - end - - def register_mimetype(mimetype) - @registered_mimetypes ||= [] - @registered_mimetypes.push(mimetype).uniq! - end - end - - delegate :registered_mimetypes, to: :class - - def lookup_for_class(model) - ::Core::Io::Registry.instance.lookup_for_class(model) - rescue ::Core::Registry::UnregisteredError => e - yield(e) - end - private :lookup_for_class - - # Report the performance and status of any request - def report(handler) - start = Time.zone.now - Rails.logger.info("API[start]: #{handler}: #{request.fullpath}") - yield - ensure - Rails.logger.info("API[handled]: #{handler}: #{request.fullpath} in #{Time.zone.now - start}s") - end - private :report - - # Not ideal but at least this allows us to pick up the appropriate model from the URL. - def determine_model_from_parts(*parts) # rubocop:todo Metrics/MethodLength - parts - .length - .downto(1) do |n| - model_name, remainder = parts.slice(0, n), parts.slice(n, parts.length) - model_constant = model_name.join('/').classify - begin - constant = model_constant.constantize - rescue NameError - # Using const_defined? disrupts rails eager loading 'magic' - constant = nil - end - next unless constant - - return yield(constant, remainder) - end - raise StandardError, "Cannot route #{parts.join('/').inspect}" - end - private :determine_model_from_parts - - # rubocop:todo Metrics/MethodLength - def handle_request(handler, http_request, action, parts) # rubocop:todo Metrics/AbcSize - endpoint_lookup, io_lookup = - case handler - when :instance - %i[endpoint_for_object lookup_for_object] - when :model - %i[endpoint_for_class lookup_for_class] - else - raise StandardError, "Unexpected handler #{handler.inspect}" - end - - request = - ::Core::Service::Request.new(requested_url = http_request.fullpath) do |request| - request.service = self - request.path = parts - request.json = @json - Rails.logger.info("API[payload]: #{@json}") - yield(request) - end - - endpoint = send(endpoint_lookup, request.target) - Rails.logger.info("API[endpoint]: #{handler}: #{requested_url} handled by #{endpoint.inspect}") - body(request.send(handler, action, endpoint)) - end - - # rubocop:enable Metrics/MethodLength - - # rubocop:todo Metrics/MethodLength - def return_file(http_request, action, parts) # rubocop:todo Metrics/AbcSize - request = - ::Core::Service::Request.new(requested_url = http_request.fullpath) do |request| - request.service = self - request.path = parts - request.json = @json - yield(request) - end - - endpoint = endpoint_for_object(request.target) - file_through = request.instance(action, endpoint).handled_by.file_through(request_accepted) - raise Core::Service::ContentFiltering::InvalidRequestedContentType if file_through.nil? - - Rails.logger.info("API[endpoint]: File: #{requested_url} handled by #{endpoint.inspect}") - file_through - end - - # rubocop:enable Metrics/MethodLength - - ACTIONS_TO_HTTP_VERBS = { create: :post, read: :get, update: :put, delete: :delete }.freeze - - ACTIONS_TO_HTTP_VERBS.each do |action, verb| - instance_action(action, verb) - model_action(action, verb) - file_action(action, verb) - file_model_action(action, verb) - end - - { create_from_file: :post, update_from_file: :put }.each do |action, verb| - file_addition(action, verb) - file_model_addition(action, verb) - end - end -end diff --git a/app/middleware/api/root_service.rb b/app/middleware/api/root_service.rb deleted file mode 100644 index 28cc35f687..0000000000 --- a/app/middleware/api/root_service.rb +++ /dev/null @@ -1,70 +0,0 @@ -# frozen_string_literal: true -# {include:file:docs/api_v1.md} -module Api - # Sinatra application which provides routing for the V1 API - # Automatically generates routes from the files listed under `app/api/endpoints` - # This particular class handles the actual root response, other endpoints are - # handled by {Api::EndpointHandler} - class RootService < ::Core::Service - # @note This is partly a hack but it suffices to keep the dynamic ability to write endpoints. - ALL_SERVICES_AVAILABLE = - Dir - .glob(File.join(Rails.root, %w[app api endpoints ** *.rb])) # rubocop:todo Rails/RootPathnameMethods - .to_h do |file| - handler = file.gsub(%r{^.+/(endpoints/.+).rb$}, '\1').camelize.constantize - [handler.root.tr('/', '_'), handler] - end - - use Api::EndpointHandler - - module RootResponse - # rubocop:todo Metrics/MethodLength - def services(services) # rubocop:todo Metrics/AbcSize - self.object = services - def @owner.each(&block) - ::Core::Io::Buffer.new(block) do |buffer| - ::Core::Io::Json::Stream - .new(buffer) - .open do |stream| - stream.attribute('revision', 2) - object.each do |model_in_json, endpoint| - stream.block(model_in_json) do |nested_stream| - nested_stream.block('actions') do |actions_stream| - endpoint - .model_handler - .send(:actions, endpoint.model_handler, response: self, endpoint: endpoint) - .map { |action, url| actions_stream.attribute(action, url) } - end - end - end - end - end - end - end - # rubocop:enable Metrics/MethodLength - end - - # It appears that if you go through a service like nginx or mongrel cluster(?) that the trailing - # slash gets stripped off any requests, so we have to account for that with the root actions. - get(%r{/?}) do - result = - report('root') do - ::Core::Service::Request - .new(request.fullpath) do |request| - request.service = self - request.path = '/' - end - .response do |response| - class << response - include RootResponse - end - response.services(ALL_SERVICES_AVAILABLE) - end - end - - body(result) - end - - %i[post put delete].each { |action| send(action, %r{/?}) { raise MethodNotAllowed, [:get] } } - end -end diff --git a/app/models/asset_audit.rb b/app/models/asset_audit.rb index 4a5da9e51f..a72270f210 100644 --- a/app/models/asset_audit.rb +++ b/app/models/asset_audit.rb @@ -4,7 +4,8 @@ # @see https://github.com/sanger/asset_audits AssetAudits, also known as process tracker and lab activity class AssetAudit < ApplicationRecord include Uuid::Uuidable - include ::Io::AssetAudit::ApiIoSupport + + # include ::Io::AssetAudit::ApiIoSupport belongs_to :asset, class_name: 'Labware' diff --git a/app/models/asset_creation.rb b/app/models/asset_creation.rb index 5fb045ea46..a9beef0361 100644 --- a/app/models/asset_creation.rb +++ b/app/models/asset_creation.rb @@ -11,7 +11,8 @@ class ParentAssociation < ApplicationRecord include Uuid::Uuidable include Asset::Ownership::ChangesOwner - extend ModelExtensions::Plate::NamedScopeHelpers + + # extend ModelExtensions::Plate::NamedScopeHelpers belongs_to :user validates :user, presence: true diff --git a/app/models/asset_group.rb b/app/models/asset_group.rb index 6e607f79a4..34dabc2f17 100644 --- a/app/models/asset_group.rb +++ b/app/models/asset_group.rb @@ -3,7 +3,7 @@ # Primarily used to group together receptacles as part of an {Order order}. class AssetGroup < ApplicationRecord include Uuid::Uuidable - include ModelExtensions::AssetGroup + # include ModelExtensions::AssetGroup include SharedBehaviour::Named belongs_to :study diff --git a/app/models/bait_library_layout.rb b/app/models/bait_library_layout.rb index 5268464655..10d30b0272 100644 --- a/app/models/bait_library_layout.rb +++ b/app/models/bait_library_layout.rb @@ -1,7 +1,8 @@ # frozen_string_literal: true class BaitLibraryLayout < ApplicationRecord include Uuid::Uuidable - include ModelExtensions::BaitLibraryLayout + + # include ModelExtensions::BaitLibraryLayout # So we can track who is requesting the layout of the bait libraries belongs_to :user diff --git a/app/models/library_tube.rb b/app/models/library_tube.rb index 55570e19f3..0a0d4b110b 100644 --- a/app/models/library_tube.rb +++ b/app/models/library_tube.rb @@ -2,7 +2,6 @@ class LibraryTube < Tube include Api::LibraryTubeIo::Extensions - include ModelExtensions::LibraryTube include Asset::SharedLibraryTubeBehaviour def self.stock_asset_type diff --git a/app/models/multiplexed_library_tube.rb b/app/models/multiplexed_library_tube.rb index 9d5453273b..4fe38ee977 100644 --- a/app/models/multiplexed_library_tube.rb +++ b/app/models/multiplexed_library_tube.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true class MultiplexedLibraryTube < Tube - include ModelExtensions::MultiplexedLibraryTube include Api::MultiplexedLibraryTubeIo::Extensions include Asset::SharedLibraryTubeBehaviour diff --git a/app/models/order.rb b/app/models/order.rb index a6a3f51233..83bfcdea32 100644 --- a/app/models/order.rb +++ b/app/models/order.rb @@ -22,7 +22,6 @@ class Order < ApplicationRecord # rubocop:todo Metrics/ClassLength include Submission::ProjectValidation include Submission::RequestOptionsBehaviour include Submission::AccessionBehaviour - include ModelExtensions::Order self.inheritance_column = 'sti_type' self.per_page = 500 @@ -88,6 +87,16 @@ class Order < ApplicationRecord # rubocop:todo Metrics/ClassLength ) } + has_many :submitted_assets, -> { joins(:asset) }, inverse_of: :order + has_many :assets, through: :submitted_assets, before_add: :validate_new_record do + def <<(associated) + return super if associated.is_a?(Receptacle) + + Rails.logger.warn("#{associated.class.name} passed to order.assets") + super(associated&.receptacle) + end + end + delegate :role, to: :order_role, allow_nil: true class << self @@ -108,7 +117,7 @@ def complete_building end def assets=(assets_to_add) - super(assets_to_add.map { |a| a.is_a?(Receptacle) ? a : a.receptacle }) + assets_to_add.map { |a| a.is_a?(Receptacle) ? a : a.receptacle } end # We can't destroy orders once the submission has been finalized for building @@ -257,6 +266,10 @@ def first_request_type @first_request_type ||= RequestType.find(request_types.first) end + def request_type_multiplier + yield(request_types.last.to_s.to_sym) if request_types.present? + end + # Return the list of input fields to edit when creating a new submission # Unless you are doing something fancy, fall back on the defaults def input_field_infos diff --git a/app/models/plate.rb b/app/models/plate.rb index 9b5403fc57..eda0333f26 100644 --- a/app/models/plate.rb +++ b/app/models/plate.rb @@ -15,7 +15,6 @@ # class Plate < Labware # rubocop:todo Metrics/ClassLength include Api::PlateIo::Extensions - include ModelExtensions::Plate include Transfer::Associations include Transfer::State::PlateState include Asset::Ownership::Owned diff --git a/app/models/plate_creation.rb b/app/models/plate_creation.rb index e23e01e636..dcdd3650ab 100644 --- a/app/models/plate_creation.rb +++ b/app/models/plate_creation.rb @@ -11,7 +11,7 @@ def self.included(base) module Children def self.included(base) base.class_eval do - include_plate_named_scope :child + # include_plate_named_scope :child belongs_to :child, class_name: 'Plate' validates_unassigned(:child) @@ -33,7 +33,7 @@ def create_children! end end - include_plate_named_scope :parent + # include_plate_named_scope :parent include Children # This is the child that is created from the parent. It cannot be assigned before validation. diff --git a/app/models/pooled_plate_creation.rb b/app/models/pooled_plate_creation.rb index d826357625..cfed5f0c49 100644 --- a/app/models/pooled_plate_creation.rb +++ b/app/models/pooled_plate_creation.rb @@ -11,7 +11,7 @@ class PooledPlateCreation < AssetCreation # This is the child that is created from the parent. It cannot be assigned before validation. has_many :parents, through: :parent_associations, class_name: 'Labware' - include_plate_named_scope :parents + # include_plate_named_scope :parents def parent parents.first diff --git a/app/models/project.rb b/app/models/project.rb index fb37798b02..50e32577a1 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -6,7 +6,6 @@ class Project < ApplicationRecord # It has to be here, as there are has_many through: :orders associations in modules has_many :orders include Api::ProjectIo::Extensions - include ModelExtensions::Project include Api::Messages::FlowcellIo::ProjectExtensions self.per_page = 500 diff --git a/app/models/request.rb b/app/models/request.rb index d69f40c290..ec5106e4be 100644 --- a/app/models/request.rb +++ b/app/models/request.rb @@ -6,7 +6,6 @@ # The progress of a request is tracked through its {Request::Statemachine state machine}. class Request < ApplicationRecord # rubocop:todo Metrics/ClassLength # Include - include ModelExtensions::Request include Aliquot::DeprecatedBehaviours::Request include Api::RequestIo::Extensions include Uuid::Uuidable diff --git a/app/models/robot.rb b/app/models/robot.rb index bae5d9ad1e..e8ba37a3ca 100644 --- a/app/models/robot.rb +++ b/app/models/robot.rb @@ -1,7 +1,8 @@ # frozen_string_literal: true class Robot < ApplicationRecord include Uuid::Uuidable - include ModelExtensions::Robot + + # include ModelExtensions::Robot validates :name, presence: true validates :location, presence: true diff --git a/app/models/sample.rb b/app/models/sample.rb index b4cfbf7937..69fd4d65a4 100644 --- a/app/models/sample.rb +++ b/app/models/sample.rb @@ -62,7 +62,6 @@ class Current < ActiveSupport::CurrentAttributes self.per_page = 500 - include ModelExtensions::Sample include Api::SampleIo::Extensions include Uuid::Uuidable include StandardNamedScopes diff --git a/app/models/sample_manifest.rb b/app/models/sample_manifest.rb index 7b9525715a..6da7cc64b6 100644 --- a/app/models/sample_manifest.rb +++ b/app/models/sample_manifest.rb @@ -17,7 +17,6 @@ # studies over time. class SampleManifest < ApplicationRecord # rubocop:todo Metrics/ClassLength include Uuid::Uuidable - include ModelExtensions::SampleManifest include SampleManifest::BarcodePrinterBehaviour include SampleManifest::CoreBehaviour extend SampleManifest::StateMachine diff --git a/app/models/sample_tube.rb b/app/models/sample_tube.rb index 210cd2a30c..afa110b838 100644 --- a/app/models/sample_tube.rb +++ b/app/models/sample_tube.rb @@ -1,7 +1,6 @@ # frozen_string_literal: true class SampleTube < Tube include Api::SampleTubeIo::Extensions - include ModelExtensions::SampleTube include StandardNamedScopes self.stock_message_template = 'TubeStockResourceIo' diff --git a/app/models/stamp.rb b/app/models/stamp.rb index eccf327d73..7d92e74527 100644 --- a/app/models/stamp.rb +++ b/app/models/stamp.rb @@ -5,7 +5,6 @@ class Stamp < ApplicationRecord include Uuid::Uuidable - include ModelExtensions::Stamp class StampQcable < ApplicationRecord self.table_name = ('stamp_qcables') diff --git a/app/models/study.rb b/app/models/study.rb index 84bf3ac864..7d8e322107 100644 --- a/app/models/study.rb +++ b/app/models/study.rb @@ -39,7 +39,7 @@ class Study < ApplicationRecord # rubocop:todo Metrics/ClassLength # Includes / Extendes include StudyReport::StudyDetails - include ModelExtensions::Study + # include ModelExtensions::Study include Api::StudyIo::Extensions include Uuid::Uuidable include EventfulRecord diff --git a/app/models/submission.rb b/app/models/submission.rb index 7d3b6e4e2c..8dbb81fad2 100644 --- a/app/models/submission.rb +++ b/app/models/submission.rb @@ -18,7 +18,6 @@ class Submission < ApplicationRecord # rubocop:todo Metrics/ClassLength include Uuid::Uuidable extend Submission::StateMachine include Submission::DelayedJobBehaviour - include ModelExtensions::Submission include Submission::Priorities PER_ORDER_REQUEST_OPTIONS = %w[pre_capture_plex_level gigabases_expected].freeze diff --git a/app/models/supplier.rb b/app/models/supplier.rb index b226387918..fc9f2be109 100644 --- a/app/models/supplier.rb +++ b/app/models/supplier.rb @@ -1,7 +1,7 @@ # frozen_string_literal: true class Supplier < ApplicationRecord include Uuid::Uuidable - include ::Io::Supplier::ApiIoSupport + # include ::Io::Supplier::ApiIoSupport include SampleManifest::Associations include SharedBehaviour::Named diff --git a/app/models/tag_layout.rb b/app/models/tag_layout.rb index e85e0a368e..1f941195c9 100644 --- a/app/models/tag_layout.rb +++ b/app/models/tag_layout.rb @@ -7,7 +7,7 @@ # doesn't (for example, a 96 tag group would occupy an entire 96 well plate). class TagLayout < ApplicationRecord include Uuid::Uuidable - include ModelExtensions::TagLayout + # include ModelExtensions::TagLayout include Asset::Ownership::ChangesOwner attr_accessor :tags_per_well diff --git a/app/models/transfer.rb b/app/models/transfer.rb index 86d9f3210e..e309cef35d 100644 --- a/app/models/transfer.rb +++ b/app/models/transfer.rb @@ -17,7 +17,7 @@ class Transfer < ApplicationRecord # You can only transfer from one plate to another once, anything else is an error. belongs_to :source, class_name: 'Plate' validates :source, presence: true - scope :include_source, -> { includes(source: ModelExtensions::Plate::PLATE_INCLUDES) } + # scope :include_source, -> { includes(source: ModelExtensions::Plate::PLATE_INCLUDES) } belongs_to :destination, class_name: 'Labware' diff --git a/app/models/transfer/between_plates.rb b/app/models/transfer/between_plates.rb index acfffefa31..72979b019d 100644 --- a/app/models/transfer/between_plates.rb +++ b/app/models/transfer/between_plates.rb @@ -3,10 +3,10 @@ # is a hash from source to destination well location and destination is the target plate for # the transfers. class Transfer::BetweenPlates < Transfer - extend ::ModelExtensions::Plate::NamedScopeHelpers + # extend ::ModelExtensions::Plate::NamedScopeHelpers - include_plate_named_scope :source - include_plate_named_scope :destination + # include_plate_named_scope :source + # include_plate_named_scope :destination include TransfersBySchema include TransfersToKnownDestination diff --git a/app/models/transfer/between_plates_by_submission.rb b/app/models/transfer/between_plates_by_submission.rb index 89bfa54316..f22d762d92 100644 --- a/app/models/transfer/between_plates_by_submission.rb +++ b/app/models/transfer/between_plates_by_submission.rb @@ -2,10 +2,10 @@ # This is effectively pooling: all wells that have come from the same submission will be transferred # into the same well on the destination plate. class Transfer::BetweenPlatesBySubmission < Transfer - extend ::ModelExtensions::Plate::NamedScopeHelpers + # extend ::ModelExtensions::Plate::NamedScopeHelpers - include_plate_named_scope :source - include_plate_named_scope :destination + # include_plate_named_scope :source + # include_plate_named_scope :destination include TransfersToKnownDestination include ControlledDestinations diff --git a/app/models/tube.rb b/app/models/tube.rb index 24b47e2f02..da7d49cff8 100644 --- a/app/models/tube.rb +++ b/app/models/tube.rb @@ -2,7 +2,6 @@ # A Tube is a piece of {Labware} class Tube < Labware include Barcode::Barcodeable - include ModelExtensions::Tube include Tag::Associations include Asset::Ownership::Unowned include Transfer::Associations diff --git a/app/models/tube_creation.rb b/app/models/tube_creation.rb index 74d4f59aad..e7eccc2806 100644 --- a/app/models/tube_creation.rb +++ b/app/models/tube_creation.rb @@ -8,7 +8,7 @@ class ChildTube < ApplicationRecord end belongs_to :parent, class_name: 'Plate' - include_plate_named_scope :parent + # include_plate_named_scope :parent has_many :child_tubes, class_name: 'TubeCreation::ChildTube' has_many :children, through: :child_tubes, source: :tube diff --git a/app/models/well.rb b/app/models/well.rb index 2607705fa7..8375b24446 100644 --- a/app/models/well.rb +++ b/app/models/well.rb @@ -6,7 +6,6 @@ # eg. A1, H12. class Well < Receptacle # rubocop:todo Metrics/ClassLength include Api::WellIo::Extensions - include ModelExtensions::Well include Cherrypick::VolumeByNanoGrams include Cherrypick::VolumeByNanoGramsPerMicroLitre include Cherrypick::VolumeByMicroLitre diff --git a/config/routes.rb b/config/routes.rb index c9c46204c2..45a86075c8 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -19,8 +19,6 @@ get '/500', to: 'errors#internal_server_error' get '/503', to: 'errors#service_unavailable' - mount Api::RootService.new => '/api/1' unless ENV['DISABLE_V1_API'] - # @todo Update v2 resources exceptions to reflect resources (e.g., `, except: %i[update]` for `lot`), # and more. Include all actions in the except block for immutable resources. # See [Y25-236](https://github.com/sanger/sequencescape/issues/4812). diff --git a/features/api/asset_groups.feature b/features/api/asset_groups.feature deleted file mode 100644 index abf7ba0f37..0000000000 --- a/features/api/asset_groups.feature +++ /dev/null @@ -1,51 +0,0 @@ -@api @json @asset_group @single-sign-on @new-api -Feature: Access asset groups through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to create, read and update individual asset groups through their UUID - And I want to be able to perform other operations to individual asset groups - And I want to be able to do all of this only knowing the UUID of a asset group - And I understand I will never be able to delete a asset group through its UUID - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - @read - Scenario: Reading the JSON for a UUID - Given I have an "active" study called "Testing asset groups" - And the UUID for the study "Testing asset groups" is "11111111-2222-3333-4444-555555555555" - - Given the study "Testing asset groups" has an asset group called "Testing the API" - And the UUID for the asset group "Testing the API" is "00000000-1111-2222-3333-444444444444" - - When I GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "asset_group": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - "name": "Testing the API", - - "study": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-555555555555" - }, - "name": "Testing asset groups" - }, - "assets": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/assets" - } - } - } - } - """ diff --git a/features/api/barcode_printers.feature b/features/api/barcode_printers.feature deleted file mode 100644 index ca40fdf6a1..0000000000 --- a/features/api/barcode_printers.feature +++ /dev/null @@ -1,50 +0,0 @@ -@api @json @barcode_printer @single-sign-on @new-api -Feature: Access barcode printers through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to create, read and update individual barcode printers through their UUID - And I want to be able to perform other operations to individual barcode printers - And I want to be able to do all of this only knowing the UUID of a barcode printer - And I understand I will never be able to delete a barcode printer through its UUID - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - @read - Scenario Outline: Reading the JSON for a barcode printer - Given the "" barcode printer " printer" exists - And the UUID for the barcode printer " printer" is "00000000-1111-2222-3333-444444444444" - - When I GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "barcode_printer": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - "name": " printer", - "active": true, - "service": { - "url": "DEPRECATED" - }, - "type": { - "name": "", - "layout": - } - } - } - """ - - Scenarios: - | printer_type | label_layout | - | 1D Tube | 2 | - | 96 Well Plate | 1 | - | 384 Well Plate | 6 | diff --git a/features/api/batches.feature b/features/api/batches.feature deleted file mode 100644 index d8f05b35fe..0000000000 --- a/features/api/batches.feature +++ /dev/null @@ -1,81 +0,0 @@ -@api @json @batch @single-sign-on @new-api -Feature: Access batches through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to create, read and update individual batches through their UUID - And I want to be able to perform other operations to individual batches - And I want to be able to do all of this only knowing the UUID of a batch - And I understand I will never be able to delete a batch through its UUID - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - Given I have a pipeline called "Testing the API" - And the UUID for the pipeline "Testing the API" is "11111111-2222-3333-4444-555555555555" - And the pipeline "Testing the API" accepts "Single ended sequencing" requests - - @read - Scenario: Reading the JSON for a UUID - Given the batch exists with ID 1 - And the UUID for the batch with ID 1 is "00000000-1111-2222-3333-444444444444" - And the last batch is for the "Testing the API" pipeline - - Given the user with login "John Smith" exists - And "John Smith" is the owner of batch with ID 1 - - When I GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "batch": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - "pipeline": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-555555555555" - } - }, - "user": { - "login": "John Smith" - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - "state": "pending", - "requests": [ ] - } - } - """ - - @read @authorised - Scenario: Reading the JSON for a UUID when authorised - Given the batch exists with ID 1 - And the UUID for the batch with ID 1 is "00000000-1111-2222-3333-444444444444" - And the last batch is for the "Testing the API" pipeline - - When I make an authorised GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "batch": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - "pipeline": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-555555555555" - } - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - "state": "pending", - "requests": [ ] - } - } - """ diff --git a/features/api/bulk_transfers.feature b/features/api/bulk_transfers.feature deleted file mode 100644 index c354d8fbbb..0000000000 --- a/features/api/bulk_transfers.feature +++ /dev/null @@ -1,252 +0,0 @@ -@api @json @transfer @single-sign-on @new-api -Feature: Conduct multiple transfers through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to perform transfers between arbitary number of plates - - Background: - Given all of this is happening at exactly "23-Oct-2010 23:00:00+01:00" - - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API - And I have a "full" authorised user with the key "cucumber" - - @read - Scenario: Reading the JSON for a bulk transfer between two plates - Given a transfer plate called "Source plate A" exists - And the UUID for the plate "Source plate A" is "11111111-2222-3333-4444-000000000001" - And a transfer plate called "Source plate B" exists - And the UUID for the plate "Source plate B" is "11111111-2222-3333-4444-000000000002" - And a transfer plate called "Destination plate A" exists - And the UUID for the plate "Destination plate A" is "11111111-2222-3333-4444-000000000003" - And a transfer plate called "Destination plate B" exists - And the UUID for the plate "Destination plate B" is "11111111-2222-3333-4444-000000000004" - Given a user with UUID "99999999-8888-7777-6666-555555555555" exists - - Given the UUID of the next bulk transfer created will be "00000000-1111-2222-3333-444444444444" - When I make an authorised POST with the following JSON to the API path "/bulk_transfers": - """ - { - "bulk_transfer": { - "well_transfers":[ - { - "source_uuid": "11111111-2222-3333-4444-000000000001", "source_location":"A1", - "destination_uuid": "11111111-2222-3333-4444-000000000003", "destination_location":"A1" - }, - { - "source_uuid": "11111111-2222-3333-4444-000000000001", "source_location":"B1", - "destination_uuid": "11111111-2222-3333-4444-000000000004", "destination_location":"A1" - }, - { - "source_uuid": "11111111-2222-3333-4444-000000000002", "source_location":"A1", - "destination_uuid": "11111111-2222-3333-4444-000000000003", "destination_location":"B1" - }, - { - "source_uuid": "11111111-2222-3333-4444-000000000002", "source_location":"B1", - "destination_uuid": "11111111-2222-3333-4444-000000000004", "destination_location":"B1" - } - ], - "user": "99999999-8888-7777-6666-555555555555" - } - } - """ - Then the HTTP response should be "201 Created" - Then the transfers from the plate "Source plate A" to the plate "Destination plate A" should be: - | source | destination | - | A1 | A1 | - Then the transfers from the plate "Source plate A" to the plate "Destination plate B" should be: - | source | destination | - | B1 | A1 | - Then the transfers from the plate "Source plate B" to the plate "Destination plate A" should be: - | source | destination | - | A1 | B1 | - Then the transfers from the plate "Source plate B" to the plate "Destination plate B" should be: - | source | destination | - | B1 | B1 | - - And the JSON should match the following for the specified fields: - """ - { - "bulk_transfer": { - "transfers": { - "size":4, - "actions": { "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/transfers" } - }, - "user": {"uuid": "99999999-8888-7777-6666-555555555555"} - } - } - """ - Given the number of results returned by the API per page is 5 - When I GET the API path "/00000000-1111-2222-3333-444444444444/transfers" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "transfers": [ - { - "source": { - "uuid": "11111111-2222-3333-4444-000000000001" - }, - "destination": { - "uuid": "11111111-2222-3333-4444-000000000003" - }, - "transfers": { - "A1": ["A1"] - } - }, - { - "source": { - "uuid": "11111111-2222-3333-4444-000000000001" - }, - "destination": { - "uuid": "11111111-2222-3333-4444-000000000004" - }, - "transfers": { - "B1": ["A1"] - } - }, - { - "source": { - "uuid": "11111111-2222-3333-4444-000000000002" - }, - "destination": { - "uuid": "11111111-2222-3333-4444-000000000003" - }, - "transfers": { - "A1": ["B1"] - } - }, - { - "source": { - "uuid": "11111111-2222-3333-4444-000000000002" - }, - "destination": { - "uuid": "11111111-2222-3333-4444-000000000004" - }, - "transfers": { - "B1": ["B1"] - } - } - ] - } - """ - - Scenario: Trtansfering the same well to two locations - Given a transfer plate called "Source plate A" exists - And the UUID for the plate "Source plate A" is "11111111-2222-3333-4444-000000000001" - And a transfer plate called "Destination plate A" exists - And the UUID for the plate "Destination plate A" is "11111111-2222-3333-4444-000000000003" - - - Given a user with UUID "99999999-8888-7777-6666-555555555555" exists - - Given the UUID of the next bulk transfer created will be "00000000-1111-2222-3333-444444444444" - - When I make an authorised POST with the following JSON to the API path "/bulk_transfers": - """ - { - "bulk_transfer": { - "well_transfers":[ - { - "source_uuid": "11111111-2222-3333-4444-000000000001", "source_location":"A1", - "destination_uuid": "11111111-2222-3333-4444-000000000003", "destination_location":"A1" - }, - { - "source_uuid": "11111111-2222-3333-4444-000000000001", "source_location":"B1", - "destination_uuid": "11111111-2222-3333-4444-000000000003", "destination_location":"A1" - }, - { - "source_uuid": "11111111-2222-3333-4444-000000000001", "source_location":"A1", - "destination_uuid": "11111111-2222-3333-4444-000000000003", "destination_location":"B1" - }, - { - "source_uuid": "11111111-2222-3333-4444-000000000001", "source_location":"B1", - "destination_uuid": "11111111-2222-3333-4444-000000000003", "destination_location":"B1" - } - ], - "user": "99999999-8888-7777-6666-555555555555" - } - } - """ - Then the HTTP response should be "201 Created" - - Then the transfers from the plate "Source plate A" to the plate "Destination plate A" should be: - | source | destination | - | A1 | A1 | - | A1 | B1 | - | B1 | A1 | - | A1 | B1 | - - And the JSON should match the following for the specified fields: - """ - { - "bulk_transfer": { - "transfers": { - "size":1, - "actions": { "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/transfers" } - }, - "user": {"uuid": "99999999-8888-7777-6666-555555555555"} - } - } - """ - Given the number of results returned by the API per page is 5 - When I GET the API path "/00000000-1111-2222-3333-444444444444/transfers" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "transfers": [ - { - "source": { - "uuid": "11111111-2222-3333-4444-000000000001" - }, - "destination": { - "uuid": "11111111-2222-3333-4444-000000000003" - }, - "transfers": { - "A1": ["A1","B1"], - "B1": ["A1","B1"] - } - } - ] - } - """ - - @read - Scenario: Creating with an invalid target - Given a transfer plate called "Source plate A" exists - And the UUID for the plate "Source plate A" is "11111111-2222-3333-4444-000000000001" - And a library tube called "Invalid Destination" exists - And the UUID for the library tube "Invalid Destination" is "11111111-2222-3333-4444-000000000003" - - Given a user with UUID "99999999-8888-7777-6666-555555555555" exists - - Given the UUID of the next bulk transfer created will be "00000000-1111-2222-3333-444444444444" - - When I make an authorised POST with the following JSON to the API path "/bulk_transfers": - """ - { - "bulk_transfer": { - "well_transfers":[ - { - "source_uuid": "11111111-2222-3333-4444-000000000001", "source_location":"A1", - "destination_uuid": "11111111-2222-3333-4444-000000000003", "destination_location":"A1" - } - ], - "user": "99999999-8888-7777-6666-555555555555" - } - } - """ - Then the HTTP response should be "422" - - And the JSON should match the following for the specified fields: - """ - { - "content": { - "destination":["is not a plate"] - } - } - """ - diff --git a/features/api/custom_metadatum_collections.feature b/features/api/custom_metadatum_collections.feature deleted file mode 100644 index 411a905d78..0000000000 --- a/features/api/custom_metadatum_collections.feature +++ /dev/null @@ -1,100 +0,0 @@ -@api @json @plate @single-sign-on @new-api -Feature: Access plates through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to see and update asset metadata - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API - And I have a "full" authorised user with the key "cucumber" - - @read - Scenario: Reading the JSON for a UUID - Given a custom metadatum collection exists with ID 7 - And the UUID for the custom metadatum collection with ID 7 is "00000000-1111-2222-3333-444444444444" - - When I GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - - """ - { - "custom_metadatum_collection": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - - "asset": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444445" - } - }, - - "user": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444446" - } - }, - - "metadata": { "Key1": "Value1", "Key2": "Value2"}, - - "uuid": "00000000-1111-2222-3333-444444444444" - } - - } - - """ - - Scenario: Creating a custom_metadatum_collection - - Given the labware and the user exist and have UUID - When I make an authorised POST with the following JSON to the API path "/custom_metadatum_collections": - """ - { - "custom_metadatum_collection": { - "user": "00000000-1111-2222-3333-444444444446", - "asset": "00000000-1111-2222-3333-444444444445", - "metadata": {"Key1": "Value1", "Key2": "Value2"} - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "custom_metadatum_collection": { - "user": { - "uuid":"00000000-1111-2222-3333-444444444446" - }, - "asset": { - "uuid":"00000000-1111-2222-3333-444444444445" - }, - "metadata": {"Key1": "Value1", "Key2": "Value2"} - } - } - """ - - Scenario: Updating metadata - - Given a custom metadatum collection exists with ID 1 - And the UUID for the custom metadatum collection with ID 1 is "00000000-1111-2222-3333-444444444444" - When I make an authorised PUT with the following JSON to the API path "/00000000-1111-2222-3333-444444444444": - """ - { - "custom_metadatum_collection": { - "metadata": {"Key1": "Value1", "Key3": "Value3", "Key4": "Value4"} - } - } - """ - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "custom_metadatum_collection": { - "metadata": {"Key1": "Value1", "Key3": "Value3", "Key4": "Value4"} - } - } - """ diff --git a/features/api/illumina_b/bottom_of_the_pipeline.feature b/features/api/illumina_b/bottom_of_the_pipeline.feature deleted file mode 100644 index def3cbd06a..0000000000 --- a/features/api/illumina_b/bottom_of_the_pipeline.feature +++ /dev/null @@ -1,261 +0,0 @@ -@api @json @single-sign-on @new-api @barcode-service -Feature: The bottom of the illumina_b pipeline - At the bottom of the illumina_b pipeline individual wells of the final plate are transferred into the - MX library tubes on a 1:1 basis. Once an MX library tube has been processed the act of changing its - state to "passed" (or "failed", or whatever really), causes the illumin_b library creation requests, - that run from the wells of the stock plate to the tube, to also be updated. - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API - And I have a "full" authorised user with the key "cucumber" - - Given a user with UUID "99999999-8888-7777-6666-555555555555" exists - - Given the plate barcode webservice returns "1000001" - And the plate barcode webservice returns "1000002" - - Given the UUID for the plate purpose "ILB_STD_INPUT" is "11111111-2222-3333-4444-000000000001" - And the UUID for the purpose "ILB_STD_STOCK" is "88888888-1111-2222-3333-000000000001" - And the UUID for the transfer template "Transfer wells to specific tubes by submission" is "22222222-3333-4444-5555-000000000001" - And the UUID for the transfer template "Transfer from tube to tube by submission" is "22222222-3333-4444-5555-000000000002" - And the UUID for the search "Find assets by barcode" is "33333333-4444-5555-6666-000000000001" - And the UUID of the next plate creation created will be "55555556-6666-7777-8888-000000000001" - And the UUID of the next state change created will be "44444444-5555-6666-7777-000000000001" - - Given a "ILB_STD_INPUT" plate called "Testing the API" exists - And the UUID for the plate "Testing the API" is "00000000-1111-2222-3333-000000000001" - And all wells on the plate "Testing the API" have unique samples - - @authorised - Scenario: Dealing with the MX library tube at the end of the pipeline - Given "A1-H6" of the plate with UUID "00000000-1111-2222-3333-000000000001" have been submitted to "Illumina-B - Multiplexed WGS - HiSeq Paired end sequencing" - And "A7-H12" of the plate with UUID "00000000-1111-2222-3333-000000000001" have been submitted to "Illumina-B - Multiplexed WGS - HiSeq Paired end sequencing" - - Given all submissions have been worked until the last plate of the "Illumina-B STD" pipeline - And all plates have sequential UUIDs based on "00000000-1111-2222-3333" - And all multiplexed library tubes have sequential UUIDs based on "00000000-1111-2222-3333-9999" - - # Find the last plate by barcode - Then log "Find the last plate by barcode" for debugging - When I POST the following JSON to the API path "/33333333-4444-5555-6666-000000000001/first": - """ - { - "search": { - "barcode": "1221000002781" - } - } - """ - Then the HTTP response should be "301 Moved Permanently" - And the JSON should match the following for the specified fields: - """ - { - "plate": { - "name": "Plate DN1000002N", - "uuid": "00000000-1111-2222-3333-000000000002" - } - } - """ - - # Create the stock MX library tubes from the plate - Then log "Create the stock MX library tubes from the plate" for debugging - When I make an authorised POST with the following JSON to the API path "/tube_creations": - """ - { - "tube_creation": { - "user": "99999999-8888-7777-6666-555555555555", - "parent": "00000000-1111-2222-3333-000000000002", - "child_purpose": "88888888-1111-2222-3333-000000000001" - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "tube_creation": { - "children": { - "size": 2 - } - } - } - """ - And all stock multiplexed library tubes have sequential UUIDs based on "98989898-1111-2222-3333" - - # Make the transfers from the plate to the appropriate stock MX library tubes - Then log "Make the transfers from the plate to the appropriate stock MX library tubes" for debugging - When I make an authorised POST with the following JSON to the API path "/22222222-3333-4444-5555-000000000001": - """ - { - "transfer": { - "user": "99999999-8888-7777-6666-555555555555", - "source": "00000000-1111-2222-3333-000000000002", - "targets": [ "98989898-1111-2222-3333-000000000001", "98989898-1111-2222-3333-000000000002" ] - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "transfer": { - "source": { - "uuid": "00000000-1111-2222-3333-000000000002" - }, - "transfers": { - "A1": { - "uuid": "98989898-1111-2222-3333-000000000001", - "stock_plate": { - "barcode": { "ean13": "1221000001777" } - } - }, - "B1": { - "uuid": "98989898-1111-2222-3333-000000000002", - "stock_plate": { - "barcode": { "ean13": "1221000001777" } - } - } - } - } - } - """ - - Then the aliquots of the stock multiplexed library tube with UUID "98989898-1111-2222-3333-000000000002" should be the same as the wells "A7-H12" of the plate "Testing the API" - And the name of the stock multiplexed library tube with UUID "98989898-1111-2222-3333-000000000002" should be "DN1000001M A7:H12" - And the aliquots of the stock multiplexed library tube with UUID "98989898-1111-2222-3333-000000000001" should be the same as the wells "A1-H6" of the plate "Testing the API" - And the name of the stock multiplexed library tube with UUID "98989898-1111-2222-3333-000000000001" should be "DN1000001M A1:H6" - - # Transfer from the stock MX tubes to the MX tubes - Then log "Make the transfers from first stock tube to one MX tube" for debugging - When I make an authorised POST with the following JSON to the API path "/22222222-3333-4444-5555-000000000002": - """ - { - "transfer": { - "user": "99999999-8888-7777-6666-555555555555", - "source": "98989898-1111-2222-3333-000000000001" - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "transfer": { - "source": { - "uuid": "98989898-1111-2222-3333-000000000001" - }, - "destination": { - "uuid": "00000000-1111-2222-3333-999900000001" - } - } - } - """ - Then the aliquots of the multiplexed library tube with UUID "00000000-1111-2222-3333-999900000001" should be the same as the wells "A1-H6" of the plate "Testing the API" - And the name of the multiplexed library tube with UUID "00000000-1111-2222-3333-999900000001" should be "DN1000001M A1:H6" - - Then log "Make the transfers from second stock tube to one MX tube" for debugging - When I make an authorised POST with the following JSON to the API path "/22222222-3333-4444-5555-000000000002": - """ - { - "transfer": { - "user": "99999999-8888-7777-6666-555555555555", - "source": "98989898-1111-2222-3333-000000000002" - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "transfer": { - "source": { - "uuid": "98989898-1111-2222-3333-000000000002" - }, - "destination": { - "uuid": "00000000-1111-2222-3333-999900000002" - } - } - } - """ - Then the aliquots of the multiplexed library tube with UUID "00000000-1111-2222-3333-999900000002" should be the same as the wells "A7-H12" of the plate "Testing the API" - And the name of the multiplexed library tube with UUID "00000000-1111-2222-3333-999900000002" should be "DN1000001M A7:H12" - - # Change the state of one tube to ensure it doesn't affect the other - Then log "Change the state of one tube to ensure it doesn't affect the other" for debugging - When I make an authorised POST with the following JSON to the API path "/state_changes": - """ - { - "state_change": { - "user": "99999999-8888-7777-6666-555555555555", - "target": "00000000-1111-2222-3333-999900000001", - "target_state": "started" - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "state_change": { - "target": { - "uuid": "00000000-1111-2222-3333-999900000001" - }, - "target_state": "started", - "previous_state": "pending" - } - } - """ - - Then the state of the multiplexed library tube with UUID "00000000-1111-2222-3333-999900000001" should be "started" - And the state of all the transfer requests to the multiplexed library tube with UUID "00000000-1111-2222-3333-999900000001" should be "started" - And the state of all the illumina-b library creation requests to the multiplexed library tube with UUID "00000000-1111-2222-3333-999900000001" should be "started" - - Then the state of the multiplexed library tube with UUID "00000000-1111-2222-3333-999900000002" should be "pending" - And the state of all the transfer requests to the multiplexed library tube with UUID "00000000-1111-2222-3333-999900000002" should be "pending" - And the state of all the illumina-b library creation requests to the multiplexed library tube with UUID "00000000-1111-2222-3333-999900000002" should be "started" - - # Now passing should adjust the state of the pulldown library creation request - Then log "Now passing should adjust the state of the pulldown library creation request" for debugging - When I make an authorised POST with the following JSON to the API path "/state_changes": - """ - { - "state_change": { - "user": "99999999-8888-7777-6666-555555555555", - "target": "00000000-1111-2222-3333-999900000001", - "target_state": "passed" - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "state_change": { - "target": { - "uuid": "00000000-1111-2222-3333-999900000001" - }, - "target_state": "passed", - "previous_state": "started" - } - } - """ - - Then the state of the multiplexed library tube with UUID "00000000-1111-2222-3333-999900000001" should be "passed" - And the state of all the transfer requests to the multiplexed library tube with UUID "00000000-1111-2222-3333-999900000001" should be "passed" - - When I make an authorised POST with the following JSON to the API path "/state_changes": - """ - { - "state_change": { - "user": "99999999-8888-7777-6666-555555555555", - "target": "00000000-1111-2222-3333-999900000001", - "target_state": "qc_complete" - } - } - """ - Then the HTTP response should be "201 Created" - - And the state of all the illumina-b library creation requests to the multiplexed library tube with UUID "00000000-1111-2222-3333-999900000001" should be "passed" - diff --git a/features/api/illumina_b/stock_plate_state.feature b/features/api/illumina_b/stock_plate_state.feature deleted file mode 100644 index c10ee35726..0000000000 --- a/features/api/illumina_b/stock_plate_state.feature +++ /dev/null @@ -1,87 +0,0 @@ -@api @json @plate @single-sign-on @new-api @barcode-service -Feature: Illumina-b stock DNA plate state varies based on the presence of submissions - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - Given the Baracoda barcode service returns "SQPD-1000001" - And a "ILB_STD_INPUT" plate called "Testing the API" exists - And the UUID for the plate "Testing the API" is "00000000-1111-2222-3333-000000000001" - - Scenario: A full stock plate with no submissions is in the pending state - Given all wells on the plate "Testing the API" have unique samples - - When I GET the API path "/00000000-1111-2222-3333-000000000001" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "plate": { - "uuid": "00000000-1111-2222-3333-000000000001", - "state": "pending" - } - } - """ - - Scenario: An empty stock plate with no submissions is in the pending state - When I GET the API path "/00000000-1111-2222-3333-000000000001" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "plate": { - "uuid": "00000000-1111-2222-3333-000000000001", - "state": "pending" - } - } - """ - - Scenario: An empty stock plate with submissions is in the pending state - Given the plate with UUID "00000000-1111-2222-3333-000000000001" has been submitted to "Illumina-B - Multiplexed WGS - HiSeq Paired end sequencing" - - When I GET the API path "/00000000-1111-2222-3333-000000000001" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "plate": { - "uuid": "00000000-1111-2222-3333-000000000001", - "state": "pending" - } - } - """ - - Scenario: When the stock plate has full wells that do not have submissions it should be pending - Given all wells on the plate "Testing the API" have unique samples - And "A1-H6" of the plate with UUID "00000000-1111-2222-3333-000000000001" have been submitted to "Illumina-B - Multiplexed WGS - HiSeq Paired end sequencing" - - When I GET the API path "/00000000-1111-2222-3333-000000000001" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "plate": { - "uuid": "00000000-1111-2222-3333-000000000001", - "state": "pending" - } - } - """ - - Scenario: When the stock plate has submissions on all of its full wells then its state is 'passed' - Given all wells on the plate "Testing the API" have unique samples - And the plate with UUID "00000000-1111-2222-3333-000000000001" has been submitted to "Illumina-B - Multiplexed WGS - HiSeq Paired end sequencing" - - When I GET the API path "/00000000-1111-2222-3333-000000000001" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "plate": { - "uuid": "00000000-1111-2222-3333-000000000001", - "state": "passed" - } - } - """ diff --git a/features/api/illumina_b/top_of_the_pipeline.feature b/features/api/illumina_b/top_of_the_pipeline.feature deleted file mode 100644 index 5e01fa94eb..0000000000 --- a/features/api/illumina_b/top_of_the_pipeline.feature +++ /dev/null @@ -1,235 +0,0 @@ -@api @json @single-sign-on @new-api @barcode-service -Feature: The top of the Illumina-B pipeline - At the top of the illumina b pipeline a stock plate arrives and an illumina-b is processed. - "Processed" means that the plate is created from the stock plate, the entire contents of the stock - plate is transferred to it, and the plate is started. The act of starting the plate should change the - state of the illumina b library creation requests it is the source asset for, but any other state changes - should have no affect on these requests. - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API - And I have a "full" authorised user with the key "cucumber" - - Given a user with UUID "99999999-8888-7777-6666-555555555555" exists - - Given the Baracoda barcode service returns "SQPD-1000002" - - And the UUID for the transfer template "Transfer columns 1-12" is "22222222-3333-4444-5555-000000000001" - And the UUID for the search "Find assets by barcode" is "33333333-4444-5555-6666-000000000001" - And the UUID of the next plate creation created will be "55555555-6666-7777-8888-000000000001" - And the UUID of the next state change created will be "44444444-5555-6666-7777-000000000001" - - @authorised - Scenario: Dealing with the initial plate in the pipeline - Given the UUID for the plate purpose "ILB_STD_INPUT" is "11111111-2222-3333-4444-000000000001" - And a full plate called "Testing the API" exists with purpose "ILB_STD_INPUT" and barcode "SQPD-1000001" - # And a "ILB_STD_INPUT" plate called "Testing the API" exists - And the UUID for the plate "Testing the API" is "00000000-1111-2222-3333-000000000001" - # And all wells on the plate "Testing the API" have unique samples - - Given the plate with UUID "00000000-1111-2222-3333-000000000001" has been submitted to "Illumina-B - Multiplexed WGS - HiSeq Paired end sequencing" - - Given the UUID for the plate purpose "ILB_STD_COVARIS" is "11111111-2222-3333-4444-000000000002" - And the UUID of the next plate created will be "00000000-1111-2222-3333-000000000002" - - # Find the plate by barcode - When I POST the following JSON to the API path "/33333333-4444-5555-6666-000000000001/first": - """ - { - "search": { - "barcode": "SQPD-1000001" - } - } - """ - Then the HTTP response should be "301 Moved Permanently" - And the JSON should match the following for the specified fields: - """ - { - "plate": { - "name": "Testing the API", - "uuid": "00000000-1111-2222-3333-000000000001", - "state": "passed" - } - } - """ - - # Create the child plate - When I make an authorised POST with the following JSON to the API path "/plate_creations": - """ - { - "plate_creation": { - "user": "99999999-8888-7777-6666-555555555555", - "parent": "00000000-1111-2222-3333-000000000001", - "child_purpose": "11111111-2222-3333-4444-000000000002" - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "plate_creation": { - "actions": { - "read": "http://www.example.com/api/1/55555555-6666-7777-8888-000000000001" - }, - "parent": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-000000000001" - } - }, - "child": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-000000000002" - } - }, - "child_purpose": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-000000000002" - } - }, - - "uuid": "55555555-6666-7777-8888-000000000001" - } - } - """ - - # Make the transfers between the two plates - When I make an authorised POST with the following JSON to the API path "/22222222-3333-4444-5555-000000000001": - """ - { - "transfer": { - "user": "99999999-8888-7777-6666-555555555555", - "source": "00000000-1111-2222-3333-000000000001", - "destination": "00000000-1111-2222-3333-000000000002" - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "transfer": { - "source": { - "uuid": "00000000-1111-2222-3333-000000000001" - }, - "destination": { - "uuid": "00000000-1111-2222-3333-000000000002" - }, - "transfers": { - "A1": "A1", - "A2": "A2", - - "B1": "B1", - "B2": "B2", - - "C1": "C1", - "C2": "C2", - - "D1": "D1", - "D2": "D2", - - "E1": "E1", - "E2": "E2", - - "F1": "F1", - "F2": "F2", - - "G1": "G1", - "G2": "G2", - - "H1": "H1", - "H2": "H2" - } - } - } - """ - - # Find the child plate by barcode - When I POST the following JSON to the API path "/33333333-4444-5555-6666-000000000001/first": - """ - { - "search": { - "barcode": "SQPD-1000002" - } - } - """ - Then the HTTP response should be "301 Moved Permanently" - And the JSON should match the following for the specified fields: - """ - { - "plate": { - "name": "Plate SQPD-1000002", - "uuid": "00000000-1111-2222-3333-000000000002" - } - } - """ - - # Change the state of the plate to started - When I make an authorised POST with the following JSON to the API path "/state_changes": - """ - { - "state_change": { - "user": "99999999-8888-7777-6666-555555555555", - "target": "00000000-1111-2222-3333-000000000002", - "target_state": "started" - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "state_change": { - "actions": { - "read": "http://www.example.com/api/1/44444444-5555-6666-7777-000000000001" - }, - "target": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-000000000002" - } - }, - "target_state": "started", - "previous_state": "pending" - } - } - """ - - # Check all of the states are correct - Then the state of the plate with UUID "00000000-1111-2222-3333-000000000002" should be "started" - And the state of all the transfer requests to the plate with UUID "00000000-1111-2222-3333-000000000002" should be "started" - And the state of all the illumina-b library creation requests from the plate with UUID "00000000-1111-2222-3333-000000000001" should be "started" - - # Now change the state of the plate to passed - When I make an authorised POST with the following JSON to the API path "/state_changes": - """ - { - "state_change": { - "user": "99999999-8888-7777-6666-555555555555", - "target": "00000000-1111-2222-3333-000000000002", - "target_state": "passed" - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "state_change": { - "target": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-000000000002" - } - }, - "target_state": "passed", - "previous_state": "started" - } - } - """ - - # Check all of the states are correct - Then the state of the plate with UUID "00000000-1111-2222-3333-000000000002" should be "passed" - And the state of all the transfer requests to the plate with UUID "00000000-1111-2222-3333-000000000002" should be "passed" - And the state of all the illumina-b library creation requests from the plate with UUID "00000000-1111-2222-3333-000000000001" should be "started" diff --git a/features/api/index_tag_layout_templates.feature b/features/api/index_tag_layout_templates.feature deleted file mode 100644 index a15424d205..0000000000 --- a/features/api/index_tag_layout_templates.feature +++ /dev/null @@ -1,105 +0,0 @@ -@api @json @tag2_layout_template @single-sign-on @new-api -Feature: Access tag 2 layout templates through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to create, read and update individual index tag layout templates through their UUID - And I want to be able to perform other operations to individual index tag layout templates - And I want to be able to do all of this only knowing the UUID of a index tag layout template - And I understand I will never be able to delete a index tag layout template through its UUID - - Background: - Given all of this is happening at exactly "23-Oct-2010 23:00:00+01:00" - - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API - And I have a "full" authorised user with the key "cucumber" - - Given the tag 2 layout template "Test tag layout" exists - And the UUID for the tag 2 layout template "Test tag layout" is "00000000-1111-2222-3333-444444444444" - - @read - Scenario: Reading the JSON for a UUID - - When I GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "tag2_layout_template": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - "name": "Test tag layout", - - "tag": { - "name": "Tag 1", - "oligo": "AAA" - } - } - } - """ - - @tag_layout @create @barcode-service - Scenario: Creating a tag layout from a tag 2 layout template - Given the Baracoda barcode service returns "SQPD-1000001" - - Given the UUID of the next tag 2 layout created will be "00000000-1111-2222-3333-000000000002" - - Given a "Stock plate" plate called "Testing the tagging" exists - And the UUID for the plate "Testing the tagging" is "11111111-2222-3333-4444-000000000001" - And all wells on the plate "Testing the tagging" have unique samples - - Given a "Tag 2 Tube" tube called "test tube" exists - And the UUID for the last tube is "11111111-2222-3333-4444-900000000001" - - When I make an authorised POST with the following JSON to the API path "/00000000-1111-2222-3333-444444444444": - """ - { - "tag2_layout": { - "source": "11111111-2222-3333-4444-900000000001", - "plate": "11111111-2222-3333-4444-000000000001" - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "tag2_layout": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-000000000002" - }, - "plate": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-000000000001" - } - }, - "source": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-900000000001" - } - }, - - "uuid": "00000000-1111-2222-3333-000000000002", - - "tag": { - "name": "Tag 1", - "oligo": "AAA" - } - } - } - """ - - Then the tag 2 layout on the plate "Testing the tagging" should be: - | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | - | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | - | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | - | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | - | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | - | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | - | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | - | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | AAA | diff --git a/features/api/library_creation_requests.feature b/features/api/library_creation_requests.feature deleted file mode 100644 index b766550330..0000000000 --- a/features/api/library_creation_requests.feature +++ /dev/null @@ -1,46 +0,0 @@ -@api @json @library_creation_request @single-sign-on @new-api -Feature: Access library creation requests through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to create, read and update individual library creation requests through their UUID - And I want to be able to perform other operations to individual library creation requests - And I want to be able to do all of this only knowing the UUID of a library creation request - And I understand I will never be able to delete a library creation request through its UUID - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - Given I have a project called "My project" - And the UUID for the project "My project" is "11111111-1111-2222-3333-444444444444" - - Given I have an active study called "Testing the sequencing requests API" - And the UUID for the study "Testing the sequencing requests API" is "11111111-2222-3333-4444-000000000000" - And I have an empty library tube called "tube_1" - And the UUID for the library tube "tube_1" is "11111111-3333-4444-5555-666666666666" - - @read - Scenario: Reading the JSON for a UUID - Given I have already made a "Library creation" request with ID 1 within the study "Testing the sequencing requests API" for the project "My project" - And the UUID for the library creation request with ID 1 is "00000000-1111-2222-3333-444444444444" - - When I GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "library_creation_request": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - - "type": "Library creation", - "library_type": "Standard" - } - } - """ diff --git a/features/api/library_events.feature b/features/api/library_events.feature deleted file mode 100644 index fd41e6fd68..0000000000 --- a/features/api/library_events.feature +++ /dev/null @@ -1,47 +0,0 @@ -@api @json @broadcast_events @single-sign-on @new-api @barcode-service -Feature: Create library event through the API - In order to be able to track individual library steps - Without buttong even more buisness logic in the plate purposes - I should be able to create lab events via the API - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API - And I have a "full" authorised user with the key "cucumber" - And a user with UUID "99999999-8888-7777-6666-555555555555" exists - - Given the Baracoda barcode service returns "SQPD-1000001" - Given the Baracoda barcode service returns "SQPD-1000002" - And a "Cherrypicked" plate called "Testing the API" exists - And the UUID for the plate "Testing the API" is "00000000-1111-2222-3333-000000000001" - - Scenario: Creating an event - When I make an authorised POST with the following JSON to the API path "/library_events": - """ - { - "library_event": { - "user": "99999999-8888-7777-6666-555555555555", - "seed": "00000000-1111-2222-3333-000000000001", - "event_type": "created_the_best_plate" - } - } - """ - Then the HTTP response should be "201 Created" - # We COULD return the actual event body here. But it would be slow, and - # probably not all that useful. - And the JSON should match the following for the specified fields: - """ - { - "library_event": { - "user": { - "uuid":"99999999-8888-7777-6666-555555555555" - }, - "seed": { - "uuid":"00000000-1111-2222-3333-000000000001" - }, - "event_type":"created_the_best_plate" - } - } - """ diff --git a/features/api/multiplexed_library_creation_requests.feature b/features/api/multiplexed_library_creation_requests.feature deleted file mode 100644 index 4bef28ca9b..0000000000 --- a/features/api/multiplexed_library_creation_requests.feature +++ /dev/null @@ -1,51 +0,0 @@ -@api @json @multiplexed_library_creation_request @single-sign-on @new-api -Feature: Access multiplexed library creation requests through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to create, read and update individual multiplexed library creation requests through their UUID - And I want to be able to perform other operations to individual multiplexed library creation requests - And I want to be able to do all of this only knowing the UUID of a multiplexed library creation request - And I understand I will never be able to delete a multiplexed library creation request through its UUID - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - Given I have a project called "My project" - And the UUID for the project "My project" is "11111111-1111-2222-3333-444444444444" - - Given I have an active study called "Testing the sequencing requests API" - And the UUID for the study "Testing the sequencing requests API" is "11111111-2222-3333-4444-000000000000" - And I have an empty library tube called "tube_1" - And the UUID for the library tube "tube_1" is "11111111-3333-4444-5555-666666666666" - - @read - Scenario: Reading the JSON for a UUID - Given I have already made a "Multiplexed library creation" request with ID 1 within the study "Testing the sequencing requests API" for the project "My project" - And the UUID for the multiplexed library creation request with ID 1 is "00000000-1111-2222-3333-444444444444" - - When I GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "multiplexed_library_creation_request": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - - "type": "Multiplexed library creation", - "library_type": "Standard", - "fragment_size": { - "from": "1", - "to": "20" - }, - "state": "pending" - } - } - """ diff --git a/features/api/npg/11438075_request_xml_exception_on_nil_study.feature b/features/api/npg/11438075_request_xml_exception_on_nil_study.feature deleted file mode 100644 index 8b37a31509..0000000000 --- a/features/api/npg/11438075_request_xml_exception_on_nil_study.feature +++ /dev/null @@ -1,28 +0,0 @@ -@npg @api @request @npg_request -Feature: A request with no study should not raise an exception when viewing the XML - - Background: - Given all of this is happening at exactly "14-Feb-2011 23:00:00+01:00" - - Scenario: A request with a study - Given I have a request 123 with a study 999 - And I am on the XML show page for request 123 - Then ignoring "sample_id|read_length|properties|asset_id|target_asset_id" the XML response should be: - """ - - - 123 - 2011-02-14 22:00:00 +0000 - 2011-02-14 22:00:00 +0000 - - - 76 - 9 - 7 - - pending - - - abc123 - - """ diff --git a/features/api/object_service.feature b/features/api/object_service.feature deleted file mode 100644 index 3e5343b1d1..0000000000 --- a/features/api/object_service.feature +++ /dev/null @@ -1,440 +0,0 @@ -@api @json @object_service @single-sign-on @new-api -Feature: Access objects through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to create, read and update individual resources through their UUID - And I want to be able to perform other operations to individual resources - And I want to be able to do all of this only knowing the UUID of a resource - And I understand I will never be able to delete a resource through its UUID - - Background: - Given all of this is happening at exactly "23-Oct-2010 23:00:00+01:00" - - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API - And I have a "full" authorised user with the key "cucumber" - - Given there are no samples - - @create @error - Scenario: Creating an object but sending the wrong 'Content-Type' - When I POST the following "text/plain" to the API path "/samples": - """ - { - "sample": { - "sanger": { - "name": "this_is_valid_json_but_wrong_content_type" - } - } - } - """ - Then the HTTP response should be "415 Invalid Request" - And the JSON should be: - """ - { - "general": [ "the 'Content-Type' can only be 'application/json' or a supported filetype eg.'sequencescape/qc_file'" ] - } - """ - - @paging - Scenario: Retrieving the first page of objects when none exist - When I GET the API path "/samples" - Then the HTTP response should be "200 OK" - And the JSON should be: - """ - { - "actions": { - "create": "http://www.example.com/api/1/samples", - "read": "http://www.example.com/api/1/samples/1", - "first": "http://www.example.com/api/1/samples/1", - "last": "http://www.example.com/api/1/samples/1" - }, - "size": 0, - "samples": [ ] - } - """ - - # "TODO": This should be an error but there is no way to support that at the moment - @paging @error - Scenario: Retrieving past the end of the pages - When I GET the API path "/samples/2" - Then the HTTP response should be "404 Not Found" - And the JSON should be: - """ - { - "general": [ "past the end of the results" ] - } - """ - - @paging @error - Scenario: Retrieving before the start of the pages - When I GET the API path "/samples/0" - Then the HTTP response should be "404 Not Found" - And the JSON should be: - """ - { - "general": [ "before the start of the results" ] - } - """ - - @paging - Scenario: Retrieving the page of objects when only one page exists - Given the sample named "testing_the_object_service" exists with ID 1 - And the UUID for the sample "testing_the_object_service" is "00000000-1111-2222-3333-444444444444" - - When I GET the API path "/samples" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "actions": { - "create": "http://www.example.com/api/1/samples", - "read": "http://www.example.com/api/1/samples/1", - "first": "http://www.example.com/api/1/samples/1", - "last": "http://www.example.com/api/1/samples/1" - }, - "size": 1, - "samples": [ - { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444", - "update": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - "sanger": { - "name": "testing_the_object_service" - } - } - ] - } - """ - - # "TODO[xxx]": order doesn't appear to be guaranteed when run with 'rake cucumber' - @paging - Scenario Outline: Retrieving the pages of objects - Given 3 samples exist with the core name "testing_the_object_service" and IDs starting at 1 - And all samples have sequential UUIDs based on "11111111-2222-3333-4444" - - When I GET the API path "/samples/" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "actions": { - "create": "http://www.example.com/api/1/samples", - "first": "http://www.example.com/api/1/samples/1", - "read": "http://www.example.com/api/1/samples/", - , - "last": "http://www.example.com/api/1/samples/3" - }, - "size": 3, - "samples": [ - { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-", - "update": "http://www.example.com/api/1/11111111-2222-3333-4444-" - }, - - "uuid": "11111111-2222-3333-4444-", - "sanger": { - "name": "testing_the_object_service-" - } - } - ] - } - """ - - Examples: - | page | index | id | uuid | extra paging | - | 1 | 1 | 1 | 000000000001 | "next": "http://www.example.com/api/1/samples/2" | - | 2 | 2 | 2 | 000000000002 | "next": "http://www.example.com/api/1/samples/3", "previous": "http://www.example.com/api/1/samples/1" | - | 3 | 3 | 3 | 000000000003 | "previous": "http://www.example.com/api/1/samples/2" | - - @update @error - Scenario: Updating the object associated with the UUID which gives an error - Given the sample named "testing_the_object_service" exists with ID 1 - And the UUID for the sample "testing_the_object_service" is "00000000-1111-2222-3333-444444444444" - - When I PUT the following JSON to the API path "/00000000-1111-2222-3333-444444444444": - """ - { - "sample": { - "sanger": { - "name": "weird green jelly like thing" - } - } - } - """ - Then the HTTP response should be "422 Unprocessable Entity" - And the JSON should be: - """ - { - "content": { - "sanger.name": [ "is read-only" ] - } - } - """ - - @update - Scenario: Updating the object associated with the UUID - Given the sample named "testing_the_object_service" exists with ID 1 - And the UUID for the sample "testing_the_object_service" is "00000000-1111-2222-3333-444444444444" - - When I PUT the following JSON to the API path "/00000000-1111-2222-3333-444444444444": - """ - { - "sample": { - "taxonomy": { - "organism": "weird green jelly like thing" - } - } - } - """ - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "sample": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444", - "update": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - "sanger": { - "name": "testing_the_object_service" - }, - "taxonomy": { - "organism": "weird green jelly like thing" - } - } - } - """ - - @read @error - Scenario: Reading the JSON for a UUID that does not exist - When I GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "404 Not Found" - And the JSON should be: - """ - { - "general": [ "UUID does not exist" ] - } - """ - - @read @error - Scenario: Reading the JSON for a UUID but 'Accept' header incorrect - Given the sample named "testing_the_object_service" exists with ID 1 - And the UUID for the sample "testing_the_object_service" is "00000000-1111-2222-3333-444444444444" - - When I GET the "text/plain" from the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "406 Unacceptable" - And the JSON should be: - """ - { - "general": [ "the 'Accept' header can only be 'application/json' or a supported filetype eg.'sequencescape/qc_file'" ] - } - """ - - @read - Scenario Outline: Reading the JSON for a UUID - Given the sample named "testing_the_object_service" exists with ID 1 - And the UUID for the sample "testing_the_object_service" is "00000000-1111-2222-3333-444444444444" - - Given the sample "testing_the_object_service" is in sample tubes with sequential IDs starting at 1 - And all sample tubes have sequential UUIDs based on "11111111-2222-3333-4444" - - When I GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "sample": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444", - "update": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - "sanger": { - "name": "testing_the_object_service" - }, - - "receptacles": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/receptacles" - }, - "size": - } - } - } - """ - - Examples: - | number of sample tubes | - | 1 | - | 3 | - - @action @error - Scenario: Performing an unknown action upon an object - Given the sample named "testing_the_object_service" exists with ID 1 - And the UUID for the sample "testing_the_object_service" is "00000000-1111-2222-3333-444444444444" - - Given the sample "testing_the_object_service" is in 3 sample tubes with sequential IDs starting at 1 - And all sample tubes have sequential UUIDs based on "11111111-2222-3333-4444" - - When I GET the API path "/00000000-1111-2222-3333-444444444444/flirby_wirby" - Then the HTTP response should be "501 Not Implemented" - And the JSON should be: - """ - { - "general": [ "requested action is not supported on this resource" ] - } - """ - - @authorisation - Scenario: The client is unauthorised so does not see the update action - Given the "create" action on samples requires authorisation - - When I GET the API path "/samples" - Then the HTTP response should be "200 OK" - And the JSON should be: - """ - { - "actions": { - "first": "http://www.example.com/api/1/samples/1", - "read": "http://www.example.com/api/1/samples/1", - "last": "http://www.example.com/api/1/samples/1" - }, - "size": 0, - "samples": [ ] - } - """ - - @authorisation - Scenario: The client is authorised so does see the update action - Given the "create" action on samples requires authorisation - - When I make an authorised GET the API path "/samples" - Then the HTTP response should be "200 OK" - And the JSON should be: - """ - { - "actions": { - "first": "http://www.example.com/api/1/samples/1", - "read": "http://www.example.com/api/1/samples/1", - "last": "http://www.example.com/api/1/samples/1", - "create": "http://www.example.com/api/1/samples" - }, - "size": 0, - "samples": [ ] - } - """ - - @authorisation @update - Scenario: The client is authorised and attempts to perform update action - Given the "update" action on a sample requires authorisation - - Given the sample named "testing_the_object_service" exists with ID 1 - And the UUID for the sample "testing_the_object_service" is "00000000-1111-2222-3333-444444444444" - - When I make an authorised PUT with the following JSON to the API path "/00000000-1111-2222-3333-444444444444": - """ - { - "sample": { - "taxonomy": { - "organism": "weird green jelly like thing" - } - } - } - """ - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "sample": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444", - "update": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - "sanger": { - "name": "testing_the_object_service" - }, - "taxonomy": { - "organism": "weird green jelly like thing" - } - } - } - """ - - @authorisation @update @error - Scenario: The client is unauthorised and attempts to perform update action - Given the "update" action on a sample requires authorisation - - Given the sample named "testing_the_object_service" exists with ID 1 - And the UUID for the sample "testing_the_object_service" is "00000000-1111-2222-3333-444444444444" - - When I PUT the following JSON to the API path "/00000000-1111-2222-3333-444444444444": - """ - { - "sample": { - "taxonomy": { - "organism": "weird green jelly like thing" - } - } - } - """ - Then the HTTP response should be "501 Internal Error" - And the JSON should be: - """ - { - "general": [ "requested action is not supported on this resource" ] - } - """ - -@authorisation @update @error - Scenario: The client has partial privileges and attempts to perform update action - Given the "create" action on samples requires tag_plates authorisation - Given the "update" action on a sample requires authorisation - - When I make an authorised GET the API path "/samples" - Then the HTTP response should be "200 OK" - And the JSON should be: - """ - { - "actions": { - "first": "http://www.example.com/api/1/samples/1", - "read": "http://www.example.com/api/1/samples/1", - "last": "http://www.example.com/api/1/samples/1", - "create": "http://www.example.com/api/1/samples" - }, - "size": 0, - "samples": [] - } - """ - - Given the sample named "testing_the_object_service" exists with ID 1 - And the UUID for the sample "testing_the_object_service" is "00000000-1111-2222-3333-444444444444" - - When I PUT the following JSON to the API path "/00000000-1111-2222-3333-444444444444": - """ - { - "sample": { - "taxonomy": { - "organism": "weird green jelly like thing" - } - } - } - """ - Then the HTTP response should be "501 Internal Error" - And the JSON should be: - """ - { - "general": [ "requested action is not supported on this resource" ] - } - """ diff --git a/features/api/order_templates.feature b/features/api/order_templates.feature deleted file mode 100644 index 067f383ef3..0000000000 --- a/features/api/order_templates.feature +++ /dev/null @@ -1,46 +0,0 @@ -@api @json @order @single-sign-on @new-api -Feature: Access order templates through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to create, read and update individual order templates through their UUID - And I want to be able to perform other operations to individual order templates - And I want to be able to do all of this only knowing the UUID of a order template - And I understand I will never be able to delete a order template through its UUID - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API - And I have a "full" authorised user with the key "cucumber" - - @read - Scenario: Reading all of the order templates that the system has - Given an order template called "Simple sequencing" with UUID "00000000-1111-2222-3333-444444444444" - When I GET the API path "/order_templates" - Then the HTTP response should be "200 OK" - - @read - Scenario: Reading the JSON for a UUID - Given an order template called "Simple sequencing" with UUID "00000000-1111-2222-3333-444444444444" - - When I GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "order_template": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - "orders": { - "actions": { - "create": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/orders" - } - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - "name": "Simple sequencing" - } - } - """ diff --git a/features/api/pipelines.feature b/features/api/pipelines.feature deleted file mode 100644 index 13aec911f3..0000000000 --- a/features/api/pipelines.feature +++ /dev/null @@ -1,186 +0,0 @@ -@api @json @pipeline @single-sign-on @new-api @ap -Feature: Access pipelines through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to create, read and update individual pipelines through their UUID - And I want to be able to perform other operations to individual pipelines - And I want to be able to do all of this only knowing the UUID of a pipeline - And I understand I will never be able to delete a pipeline through its UUID - - Background: - Given all of this is happening at exactly "23-Oct-2010 23:00:00+01:00" - - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API - And I have a "full" authorised user with the key "cucumber" - - Given the UUID for the pipeline "Cluster formation PE" is "00000000-1111-2222-3333-444444444444" - - @read - Scenario: Reading the JSON for a UUID - When I GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "pipeline": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - "batches": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/batches" - } - }, - "requests": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/requests" - } - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - "name": "Cluster formation PE" - } - } - """ - And the JSON "pipeline.batches.actions.create" should not exist - - @read @request - Scenario Outline: Non-pending or held requests should not show up - Given I have a request for "Cluster formation PE" - And the last request is in the "" state - Given all requests have sequential UUIDs based on "99999999-1111-2222-3333" - - When I GET the API path "/00000000-1111-2222-3333-444444444444/requests" - Then the HTTP response should be "200 OK" - And the JSON should be: - """ - { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/requests/1", - "first": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/requests/1", - "last": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/requests/1" - }, - "size": 0, - "requests": [ ] - } - """ - - Examples: - | state | - | started | - | failed | - | passed | - | cancelled | - | blocked | - - @read @authorised - Scenario: Reading the JSON for a UUID - When I make an authorised GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "pipeline": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - "batches": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/batches", - "create": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/batches" - } - }, - "requests": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/requests" - } - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - "name": "Cluster formation PE" - } - } - """ - - @create @batch @authorised @error - Scenario Outline: Attempting to create a batch with invalid request details - Given the UUID for the pipeline "HiSeq 2500 PE (spiked in controls)" is "00000000-1111-2222-3333-444444444445" - - Given there are 4 "Illumina-A HiSeq 2500 Paired end sequencing" requests with IDs starting at 1 - And all requests have sequential UUIDs based on "11111111-2222-3333-4444" - - Given a "Library creation" request with ID 10 - And the UUID for the request with ID 10 is "99999999-1111-2222-3333-444444444444" - - When I make an authorised POST with the following JSON to the API path "/00000000-1111-2222-3333-444444444445/batches": - """ - { - "batch": { - "requests": [ ] - } - } - """ - Then the HTTP response should be "422 Unprocessible Entity" - And the JSON should be: - """ - { - "content": { - "requests": [ ] - } - } - """ - - Scenarios: - | uuids | errors | - | "11111111-2222-3333-4444-000000000001", "11111111-2222-3333-4444-000000000002", "11111111-2222-3333-4444-000000000003" | "too many requests specified" | - | "99999999-1111-2222-3333-444444444444" | "has incorrect type" | - - - @create @batch @authorised - Scenario: Create a batch of requests for our pipeline - Given the UUID of the next batch created will be "22222222-3333-4444-5555-666666666666" - - Given there are 4 "Paired end sequencing" requests with IDs starting at 1 - And all of the requests have appropriate assets with samples - And all requests have sequential UUIDs based on "11111111-2222-3333-4444" - When I make an authorised POST with the following JSON to the API path "/00000000-1111-2222-3333-444444444444/batches": - """ - { - "batch": { - "requests": [ - "11111111-2222-3333-4444-000000000001", - "11111111-2222-3333-4444-000000000002", - "11111111-2222-3333-4444-000000000003" - ] - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "batch": { - "actions": { - "read": "http://www.example.com/api/1/22222222-3333-4444-5555-666666666666" - }, - "pipeline": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - } - }, - "user": { - "login": "John Smith" - }, - - "state": "pending", - "requests": [ - { "uuid": "11111111-2222-3333-4444-000000000001" }, - { "uuid": "11111111-2222-3333-4444-000000000002" }, - { "uuid": "11111111-2222-3333-4444-000000000003" } - ] - } - } - """ diff --git a/features/api/plate_creations.feature b/features/api/plate_creations.feature deleted file mode 100644 index 6d74b77e6f..0000000000 --- a/features/api/plate_creations.feature +++ /dev/null @@ -1,136 +0,0 @@ -@api @json @plate_creation @single-sign-on @new-api @barcode-service -Feature: Access plate creations through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to create, read and update individual plate creations through their UUID - And I want to be able to perform other operations to individual plate creations - And I want to be able to do all of this only knowing the UUID of a plate creation - And I understand I will never be able to delete a plate creation through its UUID - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API - And I have a "full" authorised user with the key "cucumber" - - Given a user with UUID "99999999-8888-7777-6666-555555555555" exists - - Given the Baracoda barcode service returns "SQPD-1000001" - And the Baracoda barcode service returns "SQPD-1000002" - - Given a plate purpose called "Parent plate purpose" with UUID "11111111-2222-3333-4444-000000000001" - And a plate purpose called "Child plate purpose" with UUID "11111111-2222-3333-4444-000000000002" - - Given a "Parent plate purpose" plate called "Testing the API" exists - And the UUID for the plate "Testing the API" is "00000000-1111-2222-3333-000000000001" - - @create - Scenario: Creating a plate creation - Given the UUID of the next plate creation created will be "55555555-6666-7777-8888-000000000001" - And the UUID of the next plate created will be "00000000-1111-2222-3333-000000000002" - - When I make an authorised POST with the following JSON to the API path "/plate_creations": - """ - { - "plate_creation": { - "user": "99999999-8888-7777-6666-555555555555", - "parent": "00000000-1111-2222-3333-000000000001", - "child_purpose": "11111111-2222-3333-4444-000000000002" - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "plate_creation": { - "actions": { - "read": "http://www.example.com/api/1/55555555-6666-7777-8888-000000000001" - }, - "parent": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-000000000001" - } - }, - "child": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-000000000002" - } - }, - "child_purpose": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-000000000002" - } - }, - - "uuid": "55555555-6666-7777-8888-000000000001" - } - } - """ - - Then the child plate of the last plate creation is a child of the parent plate - - @create @error - Scenario Outline: Creating a plate creation which results in an error - When I make an authorised POST with the following JSON to the API path "/plate_creations": - """ - { - "plate_creation": { - - } - } - """ - Then the HTTP response should be "422 Unprocessable Entity" - And the JSON should be: - """ - { - "content": { - - } - } - """ - - Scenarios: - | json | error | - | "parent": "00000000-1111-2222-3333-000000000001", "child_purpose": "11111111-2222-3333-4444-000000000002" | "user": [ "can't be blank" ] | - | "user": "99999999-8888-7777-6666-555555555555", "parent": "00000000-1111-2222-3333-000000000001" | "child_purpose": [ "can't be blank" ] | - | "user": "99999999-8888-7777-6666-555555555555", "child_purpose": "11111111-2222-3333-4444-000000000002" | "parent": [ "can't be blank" ] | - - @read - Scenario: Reading the JSON for a UUID - Given the plate creation exists with ID 1 - And the UUID for the plate creation with ID 1 is "55555555-6666-7777-8888-000000000001" - And the UUID for the parent plate of the plate creation with ID 1 is "00000000-1111-2222-3333-000000000001" - And the UUID for the child plate of the plate creation with ID 1 is "00000000-1111-2222-3333-000000000002" - And the UUID for the child plate purpose of the plate creation with ID 1 is "11111111-2222-3333-4444-000000000002" - - When I GET the API path "/55555555-6666-7777-8888-000000000001" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "plate_creation": { - "actions": { - "read": "http://www.example.com/api/1/55555555-6666-7777-8888-000000000001" - }, - "parent": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-000000000001" - } - }, - "child": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-000000000002" - } - }, - "child_purpose": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-000000000002" - } - }, - - "uuid": "55555555-6666-7777-8888-000000000001" - } - } - """ diff --git a/features/api/projects.feature b/features/api/projects.feature deleted file mode 100644 index 5152b3dc6f..0000000000 --- a/features/api/projects.feature +++ /dev/null @@ -1,49 +0,0 @@ -@api @json @project @single-sign-on @new-api -Feature: Access projects through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to create, read and update individual projects through their UUID - And I want to be able to perform other operations to individual projects - And I want to be able to do all of this only knowing the UUID of a project - And I understand I will never be able to delete a project through its UUID - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - @read - Scenario: Reading the JSON for a UUID - Given a project called "Testing the API" with ID 927493825 - Given the project "Testing the API" a budget division "Human variation" - And the UUID for the project "Testing the API" is "00000000-1111-2222-3333-444444444444" - - When I GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "project": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - - "name": "Testing the API", - "project_manager": "Unallocated", - "cost_code": "Some Cost Code", - "funding_comments": null, - "collaborators": null, - "external_funding_source": null, - "budget_division": "Human variation", - "budget_cost_centre": null, - "funding_model": "Internal", - - "roles": { - } - } - } - """ diff --git a/features/api/pulldown/bait_library_assignment.feature b/features/api/pulldown/bait_library_assignment.feature deleted file mode 100644 index c903ee67da..0000000000 --- a/features/api/pulldown/bait_library_assignment.feature +++ /dev/null @@ -1,301 +0,0 @@ -@api @json @single-sign-on @new-api @bait_library @barcode-service -Feature: Assigning bait libraries to a plate - The bait libraries are actually assigned based on the submission from the user but to provide client - applications with the ability to preview this information it is (optionally) a two-step process. - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - Given a user with UUID "99999999-8888-7777-6666-555555555555" exists - - Given the UUID for the search "Find assets by barcode" is "33333333-4444-5555-6666-000000000001" - - Given the Baracoda barcode service returns "SQPD-1000001" - And the Baracoda barcode service returns "SQPD-1000002" - - # Setup the plates so that they flow appropriately. This is a bit of a cheat in that it's only - # a direct link and that we're faking out the pipeline work but it suffices. - Given I have an ISC submission template - Given a "SC stock DNA" plate called "Testing bait libraries" exists - And all wells on the plate "Testing bait libraries" have unique samples - And the UUID for the plate "Testing bait libraries" is "00000000-1111-2222-3333-000000000001" - - Given "A1-H6" of the plate with UUID "00000000-1111-2222-3333-000000000001" have been submitted to "Pulldown ISC - HiSeq Paired end sequencing" with the following request options: - | read_length | 100 | - | bait_library_name | Human all exon 50MB | - - Given "A7-H12" of the plate with UUID "00000000-1111-2222-3333-000000000001" have been submitted to "Pulldown ISC - HiSeq Paired end sequencing" with the following request options: - | read_length | 100 | - | bait_library_name | Mouse all exon | - - Given a "SC hyb" plate called "Target for bait libraries" exists as a child of "Testing bait libraries" - And the "Transfer columns 1-12" transfer template has been used between "Testing bait libraries" and "Target for bait libraries" - And the UUID for the plate "Target for bait libraries" is "00000000-1111-2222-3333-000000000002" - - Scenario: Previewing the assignment of the bait libraries - When I make an authorised POST with the following JSON to the API path "/bait_library_layouts/preview": - """ - { - "bait_library_layout": { - "user": "99999999-8888-7777-6666-555555555555", - "plate": "00000000-1111-2222-3333-000000000002" - } - } - """ - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "bait_library_layout": { - "plate": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-000000000002" - } - }, - "layout": { - "A1": "Human all exon 50MB", - "A2": "Human all exon 50MB", - "A3": "Human all exon 50MB", - "A4": "Human all exon 50MB", - "A5": "Human all exon 50MB", - "A6": "Human all exon 50MB", - "A7": "Mouse all exon", - "A8": "Mouse all exon", - "A9": "Mouse all exon", - "A10": "Mouse all exon", - "A11": "Mouse all exon", - "A12": "Mouse all exon", - - "B1": "Human all exon 50MB", - "B2": "Human all exon 50MB", - "B3": "Human all exon 50MB", - "B4": "Human all exon 50MB", - "B5": "Human all exon 50MB", - "B6": "Human all exon 50MB", - "B7": "Mouse all exon", - "B8": "Mouse all exon", - "B9": "Mouse all exon", - "B10": "Mouse all exon", - "B11": "Mouse all exon", - "B12": "Mouse all exon", - - "C1": "Human all exon 50MB", - "C2": "Human all exon 50MB", - "C3": "Human all exon 50MB", - "C4": "Human all exon 50MB", - "C5": "Human all exon 50MB", - "C6": "Human all exon 50MB", - "C7": "Mouse all exon", - "C8": "Mouse all exon", - "C9": "Mouse all exon", - "C10": "Mouse all exon", - "C11": "Mouse all exon", - "C12": "Mouse all exon", - - "D1": "Human all exon 50MB", - "D2": "Human all exon 50MB", - "D3": "Human all exon 50MB", - "D4": "Human all exon 50MB", - "D5": "Human all exon 50MB", - "D6": "Human all exon 50MB", - "D7": "Mouse all exon", - "D8": "Mouse all exon", - "D9": "Mouse all exon", - "D10": "Mouse all exon", - "D11": "Mouse all exon", - "D12": "Mouse all exon", - - "E1": "Human all exon 50MB", - "E2": "Human all exon 50MB", - "E3": "Human all exon 50MB", - "E4": "Human all exon 50MB", - "E5": "Human all exon 50MB", - "E6": "Human all exon 50MB", - "E7": "Mouse all exon", - "E8": "Mouse all exon", - "E9": "Mouse all exon", - "E10": "Mouse all exon", - "E11": "Mouse all exon", - "E12": "Mouse all exon", - - "F1": "Human all exon 50MB", - "F2": "Human all exon 50MB", - "F3": "Human all exon 50MB", - "F4": "Human all exon 50MB", - "F5": "Human all exon 50MB", - "F6": "Human all exon 50MB", - "F7": "Mouse all exon", - "F8": "Mouse all exon", - "F9": "Mouse all exon", - "F10": "Mouse all exon", - "F11": "Mouse all exon", - "F12": "Mouse all exon", - - "G1": "Human all exon 50MB", - "G2": "Human all exon 50MB", - "G3": "Human all exon 50MB", - "G4": "Human all exon 50MB", - "G5": "Human all exon 50MB", - "G6": "Human all exon 50MB", - "G7": "Mouse all exon", - "G8": "Mouse all exon", - "G9": "Mouse all exon", - "G10": "Mouse all exon", - "G11": "Mouse all exon", - "G12": "Mouse all exon", - - "H1": "Human all exon 50MB", - "H2": "Human all exon 50MB", - "H3": "Human all exon 50MB", - "H4": "Human all exon 50MB", - "H5": "Human all exon 50MB", - "H6": "Human all exon 50MB", - "H7": "Mouse all exon", - "H8": "Mouse all exon", - "H9": "Mouse all exon", - "H10": "Mouse all exon", - "H11": "Mouse all exon", - "H12": "Mouse all exon" - } - } - } - """ - Then there should be no bait library layouts - - Scenario: Assigning bait libraries - When I make an authorised POST with the following JSON to the API path "/bait_library_layouts": - """ - { - "bait_library_layout": { - "user": "99999999-8888-7777-6666-555555555555", - "plate": "00000000-1111-2222-3333-000000000002" - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "bait_library_layout": { - "plate": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-000000000002" - } - }, - "layout": { - "A1": "Human all exon 50MB", - "A2": "Human all exon 50MB", - "A3": "Human all exon 50MB", - "A4": "Human all exon 50MB", - "A5": "Human all exon 50MB", - "A6": "Human all exon 50MB", - "A7": "Mouse all exon", - "A8": "Mouse all exon", - "A9": "Mouse all exon", - "A10": "Mouse all exon", - "A11": "Mouse all exon", - "A12": "Mouse all exon", - - "B1": "Human all exon 50MB", - "B2": "Human all exon 50MB", - "B3": "Human all exon 50MB", - "B4": "Human all exon 50MB", - "B5": "Human all exon 50MB", - "B6": "Human all exon 50MB", - "B7": "Mouse all exon", - "B8": "Mouse all exon", - "B9": "Mouse all exon", - "B10": "Mouse all exon", - "B11": "Mouse all exon", - "B12": "Mouse all exon", - - "C1": "Human all exon 50MB", - "C2": "Human all exon 50MB", - "C3": "Human all exon 50MB", - "C4": "Human all exon 50MB", - "C5": "Human all exon 50MB", - "C6": "Human all exon 50MB", - "C7": "Mouse all exon", - "C8": "Mouse all exon", - "C9": "Mouse all exon", - "C10": "Mouse all exon", - "C11": "Mouse all exon", - "C12": "Mouse all exon", - - "D1": "Human all exon 50MB", - "D2": "Human all exon 50MB", - "D3": "Human all exon 50MB", - "D4": "Human all exon 50MB", - "D5": "Human all exon 50MB", - "D6": "Human all exon 50MB", - "D7": "Mouse all exon", - "D8": "Mouse all exon", - "D9": "Mouse all exon", - "D10": "Mouse all exon", - "D11": "Mouse all exon", - "D12": "Mouse all exon", - - "E1": "Human all exon 50MB", - "E2": "Human all exon 50MB", - "E3": "Human all exon 50MB", - "E4": "Human all exon 50MB", - "E5": "Human all exon 50MB", - "E6": "Human all exon 50MB", - "E7": "Mouse all exon", - "E8": "Mouse all exon", - "E9": "Mouse all exon", - "E10": "Mouse all exon", - "E11": "Mouse all exon", - "E12": "Mouse all exon", - - "F1": "Human all exon 50MB", - "F2": "Human all exon 50MB", - "F3": "Human all exon 50MB", - "F4": "Human all exon 50MB", - "F5": "Human all exon 50MB", - "F6": "Human all exon 50MB", - "F7": "Mouse all exon", - "F8": "Mouse all exon", - "F9": "Mouse all exon", - "F10": "Mouse all exon", - "F11": "Mouse all exon", - "F12": "Mouse all exon", - - "G1": "Human all exon 50MB", - "G2": "Human all exon 50MB", - "G3": "Human all exon 50MB", - "G4": "Human all exon 50MB", - "G5": "Human all exon 50MB", - "G6": "Human all exon 50MB", - "G7": "Mouse all exon", - "G8": "Mouse all exon", - "G9": "Mouse all exon", - "G10": "Mouse all exon", - "G11": "Mouse all exon", - "G12": "Mouse all exon", - - "H1": "Human all exon 50MB", - "H2": "Human all exon 50MB", - "H3": "Human all exon 50MB", - "H4": "Human all exon 50MB", - "H5": "Human all exon 50MB", - "H6": "Human all exon 50MB", - "H7": "Mouse all exon", - "H8": "Mouse all exon", - "H9": "Mouse all exon", - "H10": "Mouse all exon", - "H11": "Mouse all exon", - "H12": "Mouse all exon" - } - } - } - """ - - # Check that the bait libraries have been properly assigned to the wells of the plate - Then the bait library for "A1-H6" of the plate "Target for bait libraries" should be "Human all exon 50MB" - And the bait library for "A7-H12" of the plate "Target for bait libraries" should be "Mouse all exon" - diff --git a/features/api/pulldown/bottom_of_the_pipeline.feature b/features/api/pulldown/bottom_of_the_pipeline.feature deleted file mode 100644 index b5f858d009..0000000000 --- a/features/api/pulldown/bottom_of_the_pipeline.feature +++ /dev/null @@ -1,155 +0,0 @@ -@api @json @single-sign-on @new-api @barcode-service -Feature: The bottom of the pulldown pipeline - At the bottom of the pulldown pipeline individual wells of the final plate are transfered into the - MX library tubes on a 1:1 basis. Once an MX library tube has been processed the act of changing its - state to "passed" (or "failed", or whatever really), causes the pulldown library creation requests, - that run from the wells of the stock plate to the tube, to also be updated. - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API - And I have a "full" authorised user with the key "cucumber" - - Given a user with UUID "99999999-8888-7777-6666-555555555555" exists - - Given the Baracoda barcode service returns "SQPD-1000001" - And the Baracoda barcode service returns "SQPD-1000002" - - And I have an ISC submission template - - Given the UUID for the plate purpose "WGS stock DNA" is "11111111-2222-3333-4444-000000000001" - And the UUID for the transfer template "Transfer wells to MX library tubes by submission" is "22222222-3333-4444-5555-000000000001" - And the UUID for the search "Find assets by barcode" is "33333333-4444-5555-6666-000000000001" - And the UUID of the next plate creation created will be "55555555-6666-7777-8888-000000000001" - And the UUID of the next state change created will be "44444444-5555-6666-7777-000000000001" - - Given a "WGS stock DNA" plate called "Testing the API" exists - And the UUID for the plate "Testing the API" is "00000000-1111-2222-3333-000000000001" - And 8 wells on the plate "Testing the API" have unique samples - - @authorised - Scenario: Dealing with the MX library tube at the end of the pipeline - Given "A1-D1" of the plate with UUID "00000000-1111-2222-3333-000000000001" have been submitted to "Pulldown ISC - HiSeq Paired end sequencing" - And "E1-H1" of the plate with UUID "00000000-1111-2222-3333-000000000001" have been submitted to "Pulldown ISC - HiSeq Paired end sequencing" - - Given all submissions have been worked until the last plate of the "Pulldown ISC" pipeline - And all plates have sequential UUIDs based on "00000000-1111-2222-3333" - And all multiplexed library tubes have sequential UUIDs based on "00000000-1111-2222-3333-9999" - - # Find the last plate by barcode - Then log "Find the last plate by barcode" for debugging - When I POST the following JSON to the API path "/33333333-4444-5555-6666-000000000001/first": - """ - { - "search": { - "barcode": "SQPD-1000002" - } - } - """ - Then the HTTP response should be "301 Moved Permanently" - And the JSON should match the following for the specified fields: - """ - { - "plate": { - "name": "Plate SQPD-1000002", - "uuid": "00000000-1111-2222-3333-000000000002" - } - } - """ - - # Make the transfers from the plate to the appropriate MX library tubes - Then log "Make the transfers from the plate to the appropriate MX library tubes" for debugging - When I make an authorised POST with the following JSON to the API path "/22222222-3333-4444-5555-000000000001": - """ - { - "transfer": { - "user": "99999999-8888-7777-6666-555555555555", - "source": "00000000-1111-2222-3333-000000000002" - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "transfer": { - "source": { - "uuid": "00000000-1111-2222-3333-000000000002" - }, - "transfers": { - "A1": { "uuid": "00000000-1111-2222-3333-999900000001" }, - "B1": { "uuid": "00000000-1111-2222-3333-999900000002" } - } - } - } - """ - - Then the aliquots of the multiplexed library tube with UUID "00000000-1111-2222-3333-999900000001" should be the same as the wells "A1-D1" of the plate "Testing the API" - And the name of the multiplexed library tube with UUID "00000000-1111-2222-3333-999900000001" should be "SQPD-1000001 A1:D1" - And the aliquots of the multiplexed library tube with UUID "00000000-1111-2222-3333-999900000002" should be the same as the wells "E1-H1" of the plate "Testing the API" - And the name of the multiplexed library tube with UUID "00000000-1111-2222-3333-999900000002" should be "SQPD-1000001 E1:H1" - - # Change the state of one tube to ensure it doesn't affect the other - Then log "Change the state of one tube to ensure it doesn't affect the other" for debugging - When I make an authorised POST with the following JSON to the API path "/state_changes": - """ - { - "state_change": { - "user": "99999999-8888-7777-6666-555555555555", - "target": "00000000-1111-2222-3333-999900000001", - "target_state": "started" - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "state_change": { - "target": { - "uuid": "00000000-1111-2222-3333-999900000001" - }, - "target_state": "started", - "previous_state": "pending" - } - } - """ - - Then the state of the multiplexed library tube with UUID "00000000-1111-2222-3333-999900000001" should be "started" - And the state of all the transfer requests to the multiplexed library tube with UUID "00000000-1111-2222-3333-999900000001" should be "started" - And the state of all the pulldown library creation requests to the multiplexed library tube with UUID "00000000-1111-2222-3333-999900000001" should be "started" - - Then the state of the multiplexed library tube with UUID "00000000-1111-2222-3333-999900000002" should be "pending" - And the state of all the transfer requests to the multiplexed library tube with UUID "00000000-1111-2222-3333-999900000002" should be "pending" - And the state of all the pulldown library creation requests to the multiplexed library tube with UUID "00000000-1111-2222-3333-999900000002" should be "started" - - # Now passing should adjust the state of the pulldown library creation request - Then log "Now passing should adjust the state of the pulldown library creation request" for debugging - When I make an authorised POST with the following JSON to the API path "/state_changes": - """ - { - "state_change": { - "user": "99999999-8888-7777-6666-555555555555", - "target": "00000000-1111-2222-3333-999900000001", - "target_state": "passed" - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "state_change": { - "target": { - "uuid": "00000000-1111-2222-3333-999900000001" - }, - "target_state": "passed", - "previous_state": "started" - } - } - """ - Then the state of the multiplexed library tube with UUID "00000000-1111-2222-3333-999900000001" should be "passed" - And the state of all the transfer requests to the multiplexed library tube with UUID "00000000-1111-2222-3333-999900000001" should be "passed" - And the state of all the pulldown library creation requests to the multiplexed library tube with UUID "00000000-1111-2222-3333-999900000001" should be "passed" diff --git a/features/api/pulldown/custom_pooling.feature b/features/api/pulldown/custom_pooling.feature deleted file mode 100644 index 1d812d5f76..0000000000 --- a/features/api/pulldown/custom_pooling.feature +++ /dev/null @@ -1,60 +0,0 @@ -@api @json @single-sign-on @new-api -Feature: Custom pooling within the pulldown pipeline - During the ISC pulldown pipeline there is a stage were custom pooling is required. The pooling is - initially based on the submissions, done using a preview, but is then governed by the lab tech who - may pool things differently because of the chemistry involved. - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - Given a user with UUID "99999999-8888-7777-6666-555555555555" exists - - Given the UUID for the transfer template "Custom pooling" is "00000000-1111-2222-3333-444444444444" - - Given a transfer plate called "Source plate" exists - And the UUID for the plate "Source plate" is "11111111-2222-3333-4444-000000000001" - And a transfer plate called "Destination plate" exists - And the UUID for the plate "Destination plate" is "11111111-2222-3333-4444-000000000002" - - Scenario: Pooling is based on the transfers from the client - When I make an authorised POST with the following JSON to the API path "/00000000-1111-2222-3333-444444444444": - """ - { - "transfer": { - "user": "99999999-8888-7777-6666-555555555555", - "source": "11111111-2222-3333-4444-000000000001", - "destination": "11111111-2222-3333-4444-000000000002", - "transfers": { - "A1": "B1", - "B1": "A1" - } - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "transfer": { - "source": { - "uuid": "11111111-2222-3333-4444-000000000001" - }, - "destination": { - "uuid": "11111111-2222-3333-4444-000000000002" - }, - "transfers": { - "A1": "B1", - "B1": "A1" - } - } - } - """ - - Then the transfers from the plate "Source plate" to the plate "Destination plate" should be: - | source | destination | - | A1 | B1 | - | B1 | A1 | diff --git a/features/api/pulldown/submissions.feature b/features/api/pulldown/submissions.feature deleted file mode 100644 index 10c36df2ae..0000000000 --- a/features/api/pulldown/submissions.feature +++ /dev/null @@ -1,233 +0,0 @@ -@api @json @pulldown @submission_template @submission @single-sign-on @new-api @barcode-service -Feature: Creating submissions for pulldown - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API - And I have a "full" authorised user with the key "cucumber" - - And I have an ISC submission template - - Given I have an "active" study called "Testing submission creation" - And the UUID for the study "Testing submission creation" is "22222222-3333-4444-5555-000000000000" - - Given I have a project called "Testing submission creation" - And the UUID for the project "Testing submission creation" is "22222222-3333-4444-5555-000000000001" - - Given the Baracoda barcode service returns "SQPD-1000001" - - Given a "WGS stock DNA" plate called "Testing the pulldown submissions" exists - And all of the wells on the plate "Testing the pulldown submissions" are in an asset group called "Testing the pulldown submissions" owned by the study "Testing submission creation" - And the UUID for the asset group "Testing the pulldown submissions" is "88888888-1111-2222-3333-000000000000" - - Given the UUID of the next submission created will be "11111111-2222-3333-4444-555555555555" - And the UUID of the next order created will be "11111111-2222-3333-4444-666666666666" - - Scenario: A submission should error if you set an incorrect request option on construction - Given the UUID for the submission template "Pulldown WGS - HiSeq paired end sequencing" is "00000000-1111-2222-3333-444444444444" - - When I POST the following JSON to the API path "/00000000-1111-2222-3333-444444444444/orders": - """ - { - "order": { - "project": "22222222-3333-4444-5555-000000000001", - "study": "22222222-3333-4444-5555-000000000000", - "asset_group_name": "Testing the pulldown submissions", - "request_options": { - "read_length": 22 - } - } - } - """ - Then the HTTP response should be "422 Unprocessable Entity" - And the JSON should be: - """ - { - "content": { - "request_options.read_length": ["is '22' should be 50, 75, 100, or 150"] - } - } - """ - - @create - Scenario: A submission for a pulldown pipeline that uses bait libraries - Given the UUID for the submission template "Pulldown ISC - HiSeq paired end sequencing" is "00000000-1111-2222-3333-444444444444" - - When I POST the following JSON to the API path "/00000000-1111-2222-3333-444444444444/orders": - """ - { - "order": { - "project": "22222222-3333-4444-5555-000000000001", - "study": "22222222-3333-4444-5555-000000000000", - "asset_group_name": "Testing the pulldown submissions", - "request_options": { - "read_length": 100, - "bait_library": "Human all exon 50MB" - } - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "order": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-666666666666", - "update": "http://www.example.com/api/1/11111111-2222-3333-4444-666666666666" - }, - "study": { - "actions": { - "read": "http://www.example.com/api/1/22222222-3333-4444-5555-000000000000" - }, - "name": "Testing submission creation" - }, - "project": { - "actions": { - "read": "http://www.example.com/api/1/22222222-3333-4444-5555-000000000001" - }, - "name": "Testing submission creation" - } - } - } - """ - - When I POST the following JSON to the API path "/submissions": - """ - { - "submission": { - "orders": [ - "11111111-2222-3333-4444-666666666666" - ] - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "submission": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-555555555555", - "update": "http://www.example.com/api/1/11111111-2222-3333-4444-555555555555", - "submit": "http://www.example.com/api/1/11111111-2222-3333-4444-555555555555/submit" - }, - "state": "building", - "orders": [ - { - "uuid": "11111111-2222-3333-4444-666666666666" - } - ] - } - } - """ - - When I POST the following JSON to the API path "/11111111-2222-3333-4444-555555555555/submit": - """ - { - "submission": { - } - } - """ - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "submission": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-555555555555" - }, - - "state": "pending" - } - } - """ - - # Check that all of the library creation requests have the correct information on them - Given all pending delayed jobs have been processed - Then all "Pulldown ISC" requests should have the following details: - | fragment_size_required_from | 100 | - | fragment_size_required_to | 400 | - | bait_library.name | Human all exon 50MB | - - @create - Scenario: Attempting to set the fragment sizes to anything other than the default values should use the specified values - Given the UUID for the submission template "Pulldown ISC - HiSeq paired end sequencing" is "00000000-1111-2222-3333-444444444444" - - When I POST the following JSON to the API path "/00000000-1111-2222-3333-444444444444/orders": - """ - { - "order": { - "project": "22222222-3333-4444-5555-000000000001", - "study": "22222222-3333-4444-5555-000000000000", - "asset_group_name": "Testing the pulldown submissions", - "request_options": { - "read_length": 100, - "bait_library": "Human all exon 50MB", - "fragment_size_required": { - "from": 99, - "to": 999 - } - } - } - } - """ - Then the HTTP response should be "201 Created" - - When I POST the following JSON to the API path "/submissions": - """ - { - "submission": { - "orders": [ - "11111111-2222-3333-4444-666666666666" - ] - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "submission": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-555555555555", - "update": "http://www.example.com/api/1/11111111-2222-3333-4444-555555555555", - "submit": "http://www.example.com/api/1/11111111-2222-3333-4444-555555555555/submit" - }, - "state": "building", - "orders": [ - { - "uuid": "11111111-2222-3333-4444-666666666666" - } - ] - } - } - """ - - When I POST the following JSON to the API path "/11111111-2222-3333-4444-555555555555/submit": - """ - { - "submission": { - } - } - """ - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "submission": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-555555555555" - }, - - "state": "pending" - } - } - """ - - # Check that all of the library creation requests have the correct information on them - Given all pending delayed jobs have been processed - Then all "Pulldown ISC" requests should have the following details: - | fragment_size_required_from | 99 | - | fragment_size_required_to | 999 | diff --git a/features/api/qc_files.feature.IGNORE b/features/api/qc_files.feature.IGNORE deleted file mode 100644 index deaa075293..0000000000 --- a/features/api/qc_files.feature.IGNORE +++ /dev/null @@ -1,113 +0,0 @@ -@api @json @plate @single-sign-on @new-api -Feature: Access plate QC Information through the api - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to attach an arbitary number of QC files to plates - And I should be able to retrieve a list of attached QC files - AND I should be able to retrieve individual QC files - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - And all of this is happening at exactly "23-Oct-2010 23:00:00+01:00" - - Given I am using the latest version of the API - And I have a "full" authorised user with the key "cucumber" - - Given the plate exists with ID 1 - And the plate with ID 1 has a barcode of "1220000001831" - And the UUID for the plate with ID 1 is "00000000-1111-2222-3333-444444444444" - And the plate with ID 1 has a plate purpose of "Stock plate" - And the UUID for the plate purpose "Stock plate" is "11111111-2222-3333-4444-555555555555" - - @read @authorised - Scenario: Reading the JSON for a UUID - Given the plate with ID 1 has attached QC data with a UUID of "11111111-2222-3333-4444-666666666666" - - When I make an authorised GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "plate": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - "qc_files" : { - "size": 1, - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/qc_files", - "create": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/qc_files" - } - } - } - } - """ - When I GET the API path "/00000000-1111-2222-3333-444444444444/qc_files" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "actions":{ - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/qc_files/1", - "first": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/qc_files/1", - "last": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/qc_files/1" - }, - "size":1, - "qc_files":[ - { - "created_at":"2010-10-23 23:00:00 +0100", - "updated_at":"2010-10-23 23:00:00 +0100", - "filename":"example_file.txt", - "actions":{"read":"http://www.example.com/api/1/11111111-2222-3333-4444-666666666666"}, - "uuid":"11111111-2222-3333-4444-666666666666" - } - ] - } - """ - When I GET the "sequencescape/qc_file" from the API path "/11111111-2222-3333-4444-666666666666" - Then the HTTP response should be "200 OK" - And the HTTP "Content-Type" should be "sequencescape/qc_file" - And the content should be the Qc Data - When I GET the API path "/11111111-2222-3333-4444-666666666666" - Then the HTTP response should be "200 OK" - And the HTTP "Content-Type" should be "application/json" - And the JSON should match the following for the specified fields: - """ - { - "qc_file": - { - "created_at":"2010-10-23 23:00:00 +0100", - "updated_at":"2010-10-23 23:00:00 +0100", - "filename":"example_file.txt", - "actions":{"read":"http://www.example.com/api/1/11111111-2222-3333-4444-666666666666"}, - "uuid":"11111111-2222-3333-4444-666666666666" - } - } - """ - - @read @authorised - Scenario: Storing QC data - When I make an authorised GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - When I make an authorised POST with the QC file to the API path "/00000000-1111-2222-3333-444444444444/qc_files" - Then the HTTP response should be "201 created" - And the JSON should match the following for the specified fields: - """ - { - "qc_file": - { - "filename":"example_file.txt" - } - } - """ - And the plate with ID 1 should have attached QC data - - @read @authorised - Scenario: Other resources respond correctly - Given the plate with ID 1 has attached QC data with a UUID of "11111111-2222-3333-4444-666666666666" - When I GET the "sequencescape/qc_file" from the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "406 Failure" - - When I GET the "sequencescape/qc_file" from the API path "/00000000-1111-2222-3333-444444444444/qc_files" - Then the HTTP response should be "406 Failure" diff --git a/features/api/reference_genomes.feature b/features/api/reference_genomes.feature deleted file mode 100644 index fccf6736c7..0000000000 --- a/features/api/reference_genomes.feature +++ /dev/null @@ -1,95 +0,0 @@ -@api @json @reference_genome @single-sign-on @new-api -Feature: Access reference genomes through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to create, read and update individual reference genomes through their UUID - And I want to be able to perform other operations to individual reference genomes - And I want to be able to do all of this only knowing the UUID of a reference genome - And I understand I will never be able to delete a reference genome through its UUID - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API - And I have a "full" authorised user with the key "cucumber" - - @create - Scenario: Creating a reference genome - Given the UUID of the next reference genome created will be "00000000-1111-2222-3333-444444444444" - And a user with an api key of "I-am-authenticated" exists - When I make an authorised POST with the following JSON to the API path "/reference_genomes": - """ - {"reference_genome": { "name": "testing-of-creation"}} - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "reference_genome": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - "name": "testing-of-creation", - "uuid": "00000000-1111-2222-3333-444444444444" - } - } - """ - - @create @error - Scenario: Creating a reference genome which results in an error - Given a reference genome called "testing-of-creation" with UUID "00000000-1111-2222-3333-444444444444" - When I make an authorised POST with the following JSON to the API path "/reference_genomes": - """ - {"reference_genome": { "name": "testing-of-creation"}} - """ - Then the HTTP response should be "422 Unprocessable Entity" - And the JSON should be: - """ - { - "content": { - "name": ["of reference genome already present in database"] - } - } - """ - - @read - Scenario: Reading the JSON for a reference genome UUID - Given a reference genome called "testing-of-reading" with UUID "00000000-1111-2222-3333-444444444444" - - When I GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "reference_genome": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - "name": "testing-of-reading", - "uuid": "00000000-1111-2222-3333-444444444444" - } - } - """ - - @read - Scenario: Updating the JSON for a reference genome UUID - Given a reference genome called "testing-of-reading" with UUID "00000000-1111-2222-3333-444444444444" - - When I make an authorised PUT with the following JSON to the API path "/00000000-1111-2222-3333-444444444444": - """ - {"reference_genome": { "name": "testing-of-update"}} - """ - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "reference_genome": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - "name": "testing-of-update", - "uuid": "00000000-1111-2222-3333-444444444444" - } - } - """ diff --git a/features/api/requests.feature b/features/api/requests.feature deleted file mode 100644 index 9eb7bb170e..0000000000 --- a/features/api/requests.feature +++ /dev/null @@ -1,73 +0,0 @@ -@api @json @request @single-sign-on @new-api -Feature: Access requests through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to create, read and update individual requests through their UUID - And I want to be able to perform other operations to individual requests - And I want to be able to do all of this only knowing the UUID of a request - And I understand I will never be able to delete a request through its UUID - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - Given I have a project called "My project" - And the UUID for the project "My project" is "11111111-1111-2222-3333-444444444444" - - Given I have an active study called "Testing the requests API" - And the UUID for the study "Testing the requests API" is "11111111-2222-3333-4444-000000000000" - And I have an empty library tube called "tube_1" - And the UUID for the library tube "tube_1" is "11111111-3333-4444-5555-666666666666" - - @paging - Scenario Outline: Retrieving the page of requests when only one page exists - Given I have already made a "" request with ID 1 within the study "Testing the requests API" for the project "My project" - And the UUID for the request with ID 1 is "00000000-1111-2222-3333-444444444444" - - When I GET the API path "/requests" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "actions": { - "read": "http://www.example.com/api/1/requests/1", - "first": "http://www.example.com/api/1/requests/1", - "last": "http://www.example.com/api/1/requests/1" - }, - "requests": [ - { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - "state": "pending", - - "type": "", - "fragment_size": { - "from": "", - "to": "" - }, - - "source_asset": { - "type": "", - "name": "Testing the requests API - Source asset 1" - }, - "target_asset": { - "type": "", - "name": "Testing the requests API - Target asset 1" - } - } - ] - } - """ - - Examples: - | request type | request type name | asset type | fragment size from | fragment size to | - | library creation | Library creation | sample_tubes | 1 | 20 | - | multiplexed library creation | Multiplexed library creation | sample_tubes | 1 | 20 | - | sequencing | Illumina-C Paired end sequencing | library_tubes | 1 | 21 | - | sequencing | Illumina-C Single ended sequencing | library_tubes | 1 | 21 | diff --git a/features/api/sample_manifests/mx_library_tubes.feature b/features/api/sample_manifests/mx_library_tubes.feature deleted file mode 100644 index 804e265d00..0000000000 --- a/features/api/sample_manifests/mx_library_tubes.feature +++ /dev/null @@ -1,161 +0,0 @@ -@api @json @sample_manifest @mx_library @single-sign-on @new-api @barcode-service -Feature: Access sample manifests through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to create, read and update individual sample manifests through their UUID - And I want to be able to perform other operations to individual sample manifests - And I want to be able to do all of this only knowing the UUID of a sample manifest - And I understand I will never be able to delete a sample manifest through its UUID - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API - And I have a "full" authorised user with the key "cucumber" - - Given I have an "active" study called "Testing sample manifests" - And the UUID for the study "Testing sample manifests" is "22222222-3333-4444-5555-000000000000" - - Given a supplier called "John's Genes" with ID 2 - And the UUID for the supplier "John's Genes" is "33333333-1111-2222-3333-444444444444" - - @read - Scenario: Reading the JSON for a UUID - Given the sample manifest exists with ID 1 - And the UUID for the sample manifest with ID 1 is "00000000-1111-2222-3333-444444444444" - And the sample manifest with ID 1 is owned by study "Testing sample manifests" - And the sample manifest with ID 1 is supplied by "John's Genes" - And the sample manifest with ID 1 is for 2 libraries - And the Sanger sample IDs will be sequentially generated - Given the "1D Tube" barcode printer "d999bc" exists - Given the sample manifest with ID 1 has been processed - And library tubes are barcoded sequentially from 100 - When I GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "sample_manifest": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - "study": { - "actions": { - "read": "http://www.example.com/api/1/22222222-3333-4444-5555-000000000000" - } - }, - "supplier": { - "actions": { - "read": "http://www.example.com/api/1/33333333-1111-2222-3333-444444444444" - } - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - "state": "pending", - "last_errors": null, - - "samples": [] - } - } - """ - - # NOTE: The 'container' element is not really empty here, I just can't guarantee the barcode inside it! - @create - Scenario: Creating a sample tube sample manifest through a study - Given the UUID of the next sample manifest created will be "00000000-1111-2222-3333-444444444444" - And the Sanger sample IDs will be sequentially generated - - When I POST the following JSON to the API path "/22222222-3333-4444-5555-000000000000/sample_manifests/create_for_multiplexed_libraries": - """ - { - "sample_manifest": { - "supplier": "33333333-1111-2222-3333-444444444444", - "count": 2 - } - } - """ - Then the HTTP response should be "410 GONE" - And the JSON should match the following for the specified fields: - """ - { "general": ["requested action is no longer supported"] } - """ - - @update - Scenario: Updating a manifest - Given I have a tag group called "Test tag group" with 2 tags - And the UUID for the tag group "Test tag group" is "11111111-2222-3333-5555-000000000001" - Given I have a tag group called "Test tag group 2" with 1 tags - And the UUID for the tag group "Test tag group 2" is "11111111-2222-3333-5555-000000000002" - Given the sample manifest exists with ID 1 - And the UUID for the sample manifest with ID 1 is "00000000-1111-2222-3333-444444444444" - And the sample manifest with ID 1 is owned by study "Testing sample manifests" - And the sample manifest with ID 1 is supplied by "John's Genes" - And the sample manifest with ID 1 is for 2 libraries - And the Sanger sample IDs will be sequentially generated - Given the "1D Tube" barcode printer "d999bc" exists - Given the sample manifest with ID 1 has been processed - And library tubes are barcoded sequentially from 100 - And the samples in manifest 1 have sequential UUIDs based on "11111111-2222-3333-4444" - - When I PUT the following JSON to the API path "/00000000-1111-2222-3333-444444444444": - """ - { - "sample_manifest": { - "samples": [ - { - "container": { "barcode": "NT100F" }, - "supplier": { - "sample_name": "flurby_wurby_sample", - "measurements": { - "volume": "100", - "concentration": "10" - } - }, - "library_information": { - "tag":{ - "tag_group":"11111111-2222-3333-5555-000000000001", - "tag_index":"1" - }, - "tag2":{ - "tag_group":"11111111-2222-3333-5555-000000000002", - "tag_index":"1" - }, - "library_type": "standard", - "insert_size_from": 100, - "insert_size_to": 100 - } - }, - { - "container": { "barocde": "NT100F" }, - "supplier": { - "sample_name": "hurdy_gurdy_sample", - "measurements": { - "volume": "200", - "concentration": "5" - } - }, - "library_information": { - "tag":{ - "tag_group":"11111111-2222-3333-5555-000000000001", - "tag_index":"2" - }, - "tag2":{ - "tag_group":"11111111-2222-3333-5555-000000000002", - "tag_index":"1" - }, - "library_type": "standard", - "insert_size_from": 100, - "insert_size_to": 100 - } - } - ] - } - } - """ - Then the HTTP response should be "410 OK" - And the JSON should match the following for the specified fields: - """ - { "general": ["requested action is no longer supported"] } - """ - diff --git a/features/api/sample_manifests/plates.feature b/features/api/sample_manifests/plates.feature deleted file mode 100644 index a9f0dc9139..0000000000 --- a/features/api/sample_manifests/plates.feature +++ /dev/null @@ -1,120 +0,0 @@ -@api @json @sample_manifest @plate @single-sign-on @new-api @barcode-service -Feature: Access sample manifests through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to create, read and update individual sample manifests through their UUID - And I want to be able to perform other operations to individual sample manifests - And I want to be able to do all of this only knowing the UUID of a sample manifest - And I understand I will never be able to delete a sample manifest through its UUID - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API - - Given I have an "active" study called "Testing sample manifests" - And the UUID for the study "Testing sample manifests" is "22222222-3333-4444-5555-000000000000" - - Given a supplier called "John's Genes" with ID 2 - And the UUID for the supplier "John's Genes" is "33333333-1111-2222-3333-444444444444" - - Given the "96 Well Plate" barcode printer "d999bc" exists - And the Baracoda barcode service returns "SQPD-1234567" - - @read - Scenario: Reading the JSON for a UUID - Given the sample manifest exists with ID 1 - And the UUID for the sample manifest with ID 1 is "00000000-1111-2222-3333-444444444444" - And the sample manifest with ID 1 is owned by study "Testing sample manifests" - And the sample manifest with ID 1 is supplied by "John's Genes" - And the sample manifest with ID 1 is for 1 plate - - Given the sample manifest with ID 1 has been processed - - When I GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "sample_manifest": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - "study": { - "actions": { - "read": "http://www.example.com/api/1/22222222-3333-4444-5555-000000000000" - } - }, - "supplier": { - "actions": { - "read": "http://www.example.com/api/1/33333333-1111-2222-3333-444444444444" - } - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - "state": "pending", - "last_errors": null, - - "samples": [] - } - } - """ - - @update - Scenario: Updating a manifest - Given the sample manifest exists with ID 1 - And the UUID for the sample manifest with ID 1 is "00000000-1111-2222-3333-444444444444" - And the sample manifest with ID 1 is owned by study "Testing sample manifests" - And the sample manifest with ID 1 is supplied by "John's Genes" - And the sample manifest with ID 1 is for 1 plate - - Given the sample manifest with ID 1 has been processed - And all samples have a Sanger sample ID based on "WTCCC" - And all samples have sequential UUIDs based on "11111111-2222-3333-4444" - - When I PUT the following JSON to the API path "/00000000-1111-2222-3333-444444444444": - """ - { - "sample_manifest": { - "samples": [ - { - "uuid": "11111111-2222-3333-4444-000000000002", - - "supplier": { - "sample_name": "flurby_wurby_sample", - "measurements": { - "volume": "100", - "concentration": "10" - } - } - } - ] - } - } - """ - Then the HTTP response should be "410 GONE" - And the JSON should match the following for the specified fields: - """ - { "general": ["requested action is no longer supported"] } - """ - - @create - Scenario: Creating a plate sample manifest through a study - Given the UUID of the next sample manifest created will be "00000000-1111-2222-3333-444444444444" - And the Sanger sample IDs will be sequentially generated - - When I POST the following JSON to the API path "/22222222-3333-4444-5555-000000000000/sample_manifests/create_for_plates": - """ - { - "sample_manifest": { - "supplier": "33333333-1111-2222-3333-444444444444", - "count": 1 - } - } - """ - Then the HTTP response should be "410 GONE" - And the JSON should match the following for the specified fields: - """ - { "general": ["requested action is no longer supported"] } - """ diff --git a/features/api/sample_manifests/sample_tubes.feature b/features/api/sample_manifests/sample_tubes.feature deleted file mode 100644 index 0f6fcfd1f3..0000000000 --- a/features/api/sample_manifests/sample_tubes.feature +++ /dev/null @@ -1,83 +0,0 @@ -@api @json @sample_manifest @sample_tube @single-sign-on @new-api @barcode-service -Feature: Access sample manifests through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to create, read and update individual sample manifests through their UUID - And I want to be able to perform other operations to individual sample manifests - And I want to be able to do all of this only knowing the UUID of a sample manifest - And I understand I will never be able to delete a sample manifest through its UUID - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - Given I have an "active" study called "Testing sample manifests" - And the UUID for the study "Testing sample manifests" is "22222222-3333-4444-5555-000000000000" - - Given a supplier called "John's Genes" with ID 2 - And the UUID for the supplier "John's Genes" is "33333333-1111-2222-3333-444444444444" - - @read - Scenario: Reading the JSON for a UUID - Given the sample manifest exists with ID 1 - And the UUID for the sample manifest with ID 1 is "00000000-1111-2222-3333-444444444444" - And the sample manifest with ID 1 is owned by study "Testing sample manifests" - And the sample manifest with ID 1 is supplied by "John's Genes" - And the sample manifest with ID 1 is for 1 sample tube - - Given the "1D Tube" barcode printer "d999bc" exists - Given the sample manifest with ID 1 has been processed - And the barcode of the last sample tube is "9999" - - When I GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "sample_manifest": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - "study": { - "actions": { - "read": "http://www.example.com/api/1/22222222-3333-4444-5555-000000000000" - } - }, - "supplier": { - "actions": { - "read": "http://www.example.com/api/1/33333333-1111-2222-3333-444444444444" - } - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - "state": "pending", - "last_errors": null, - - "samples": [] - } - } - """ - - # NOTE: The 'container' element is not really empty here, I just can't guarantee the barcode inside it! - @create - Scenario: Creating a sample tube sample manifest through a study - Given the UUID of the next sample manifest created will be "00000000-1111-2222-3333-444444444444" - And the Sanger sample IDs will be sequentially generated - - When I POST the following JSON to the API path "/22222222-3333-4444-5555-000000000000/sample_manifests/create_for_tubes": - """ - { - "sample_manifest": { - "supplier": "33333333-1111-2222-3333-444444444444", - "count": 1 - } - } - """ - Then the HTTP response should be "410 GONE" - And the JSON should match the following for the specified fields: - """ - { "general": ["requested action is no longer supported"] } - """ diff --git a/features/api/sample_tubes.feature b/features/api/sample_tubes.feature deleted file mode 100644 index 39624cd684..0000000000 --- a/features/api/sample_tubes.feature +++ /dev/null @@ -1,71 +0,0 @@ -@api @json @sample_tube @single-sign-on @new-api -Feature: Access sample tubes through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to create, read and update individual sample tubes through their UUID - And I want to be able to perform other operations to individual sample tubes - And I want to be able to do all of this only knowing the UUID of a sample tube - And I understand I will never be able to delete a sample tube through its UUID - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - @read - Scenario: Reading the JSON for a UUID - Given a sample tube called "Testing the API" with ID 1 - And the UUID for the sample tube "Testing the API" is "00000000-1111-2222-3333-444444444444" - And the barcode for the sample tube "Testing the API" is "NT42F" - - Given a sample called "sample_testing_the_api" exists - And the UUID for the sample "sample_testing_the_api" is "00000000-1111-2222-3333-888888888888" - And the sample "sample_testing_the_api" is in the sample tube "Testing the API" - - When I GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "sample_tube": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - - "name": "Testing the API", - "qc_state": "", - "closed": false, - "concentration": null, - "volume": null, - - "barcode": { - "prefix": "NT", - "number": "42", - "ean13": "3980000042705", - "two_dimensional": null, - "type": 2 - }, - - "aliquots": [ - { - "sample": { - } - } - ], - "requests": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/requests" - } - }, - "library_tubes": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/library_tubes" - } - } - } - } - """ diff --git a/features/api/samples.feature b/features/api/samples.feature deleted file mode 100644 index 42d85f0d7c..0000000000 --- a/features/api/samples.feature +++ /dev/null @@ -1,158 +0,0 @@ -@api @json @sample @single-sign-on @new-api -Feature: Access samples through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to read individual samples through their UUID - And I want to be able to perform other operations to individual samples - And I want to be able to do all of this only knowing the UUID of a sample - And I understand I will never be able to delete a sample through its UUID - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API - And I have a "full" authorised user with the key "cucumber" - - @read - Scenario: Reading the JSON for a UUID - Given a sample called "testing_the_api" with UUID "00000000-1111-2222-3333-444444444444" - And the fields of the sample_metadata for the sample called "testing_the_api" are prepopulated - And the sample called "testing_the_api" is Male - And the GC content of the sample called "testing_the_api" is Neutral - And the DNA source of the sample called "testing_the_api" is Genomic - And the SRA status of the sample called "testing_the_api" is Hold - And the sample called "testing_the_api" is 10 weeks old - And the dosage of the sample called "testing_the_api" is 10 something - And the reference genome for sample "testing_the_api" is "RefGenome" - - When I GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "sample": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - - "sanger": { - "name": "testing_the_api", - "sample_id": null, - "resubmitted": null, - "description": "sample_description" - }, - "supplier": { - "sample_name": "supplier_name", - "storage_conditions": "sample_storage_conditions", - - "collection": { - "date": "date_of_sample_collection" - }, - "extraction": { - "date": "date_of_sample_extraction", - "method": "sample_extraction_method" - }, - "purification": { - "purified": "sample_purified", - "method": "purification_method" - }, - "measurements": { - "volume": "volume", - "concentration": "concentration", - "gc_content": "Neutral", - "gender": "Male", - "concentration_determined_by": "concentration_determined_by" - } - }, - "source": { - "dna_source": "Genomic", - "cohort": "cohort", - "country": "country_of_origin", - "region": "geographical_region", - "ethnicity": "ethnicity", - "control": null - }, - "family": { - "mother": "mother", - "father": "father", - "replicate": "replicate", - "sibling": "sibling" - }, - "taxonomy": { - "id": null, - "strain": "sample_strain_att", - "common_name": "sample_common_name", - "organism": "organism" - }, - "reference": { - "genome": "RefGenome" - }, - "data_release": { - "visibility": "Hold", - "public_name": "sample_public_name", - "description": "sample_description", - - "metagenomics": { - "genotype": "genotype", - "phenotype": "phenotype", - "age": "10 weeks", - "developmental_stage": "developmental_stage", - "cell_type": "cell_type", - "disease_state": "disease_state", - "compound": "compound", - "dose": "10 something", - "immunoprecipitate": "immunoprecipitate", - "growth_condition": "growth_condition", - "rnai": "rnai", - "organism_part": "organism_part", - "time_point": "time_point", - "treatment": "treatment", - "subject": "subject", - "disease": "disease" - }, - "managed": { - "treatment": "treatment", - "subject": "subject", - "disease": "disease" - } - } - } - } - """ - -@read - Scenario: JSON rendering bug - Given a sample called "testing_the_api" with UUID "00000000-1111-2222-3333-444444444444" - And the fields of the sample_metadata for the sample called "testing_the_api" are prepopulated - And the sample called "testing_the_api" is Male - And the GC content of the sample called "testing_the_api" is Neutral - And the DNA source of the sample called "testing_the_api" is Genomic - And the SRA status of the sample called "testing_the_api" is Hold - And the sample called "testing_the_api" is 10 weeks old - And the dosage of the sample called "testing_the_api" is 10 something - And the description of the sample called "testing_the_api" contains quotes - - When I GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "sample": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - - "sanger": { - "name": "testing_the_api", - "sample_id": null, - "resubmitted": null, - "description": "something \"with\" quotes" - } - } - } - """ diff --git a/features/api/searches.feature b/features/api/searches.feature deleted file mode 100644 index c4124dfd34..0000000000 --- a/features/api/searches.feature +++ /dev/null @@ -1,38 +0,0 @@ -@api @json @search @single-sign-on @new-api -Feature: Access searches through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to create, read and update individual searches through their UUID - And I want to be able to perform other operations to individual searches - And I want to be able to do all of this only knowing the UUID of a search - And I understand I will never be able to delete a search through its UUID - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - @read - Scenario: Reading the JSON for a UUID - Given the UUID for the search "Find assets by barcode" is "00000000-1111-2222-3333-444444444444" - - When I GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "search": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444", - "first": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/first", - "last": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/last", - "all": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/all" - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - "name": "Find assets by barcode" - } - } - """ diff --git a/features/api/searches/find_asset_by_barcode.feature b/features/api/searches/find_asset_by_barcode.feature deleted file mode 100644 index d0b7e71419..0000000000 --- a/features/api/searches/find_asset_by_barcode.feature +++ /dev/null @@ -1,125 +0,0 @@ -@api @json @asset @search @single-sign-on @new-api @barcode_search -Feature: Searching for assets by barcode - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - @search_assets @single - Scenario Outline: Looking up a single asset by barcode - Given the UUID for the search "Find assets by barcode" is "00000000-1111-2222-3333-444444444444" - - Given a called "Testing the API 1" with ID 1 - And the "Testing the API 1" has a barcode of "" - And the UUID for the "Testing the API 1" is "11111111-2222-3333-4444-000000000001" - - Given a called "Testing the API 2" with ID 2 - And the "Testing the API 2" has a barcode of "" - And the UUID for the "Testing the API 2" is "11111111-2222-3333-4444-000000000002" - - When I POST the following JSON to the API path "/00000000-1111-2222-3333-444444444444/first": - """ - { - "search": { - "barcode": - } - } - """ - Then the HTTP response should be "301 Moved Permanently" - And the JSON should match the following for the specified fields: - """ - { - "": { - "name": "Testing the API 2", - "uuid": "11111111-2222-3333-4444-000000000002" - } - } - """ - Examples: - | asset_type | model_name | barcode | barcode_2 | - # | control plate | plate | 1220000123724 | 1220000999701 | - # | dilution plate | plate | 1220000123724 | 1220000999701 | - # | gel dilution plate | plate | 1930000123708 | 1930000999686 | - # | pico assay a plate | plate | 4330000123802 | 4330000999780 | - # | pico assay b plate | plate | 4340000123849 | 4340000999826 | - # | pico assay plate | plate | 4330000123802 | 4330000999780 | - # | pico dilution plate | plate | 4360000123694 | 4360000999671 | - # | plate | plate | 1220000123724 | 1220000999701 | - # | working dilution plate | plate | 6250000123818 | 6250000999796 | - | sample tube | sample_tube | 3980012344750 | 3980012345764 | - - - - @single @sample_tube @error - Scenario: Looking up a non-existant barcode - Given the UUID for the search "Find assets by barcode" is "00000000-1111-2222-3333-444444444444" - - When I POST the following JSON to the API path "/00000000-1111-2222-3333-444444444444/first": - """ - { - "search": { - "barcode": 3980012345764 - } - } - """ - Then the HTTP response should be "404 Not Found" - And the JSON should be: - """ - { "general": [ "no resources found with that search criteria" ] } - """ - - @multiple @sample_tube - Scenario: Looking up multiple assets by barcode - Given the UUID for the search "Find assets by barcode" is "00000000-1111-2222-3333-444444444444" - - Given a sample tube called "Testing the API 1" with ID 1 - And the sample tube "Testing the API 1" has a barcode of "3980012344750" - And the UUID for the sample tube "Testing the API 1" is "11111111-2222-3333-4444-000000000001" - - Given a sample tube called "Testing the API 2" with ID 2 - And the sample tube "Testing the API 2" has a barcode of "3980012345764" - And the UUID for the sample tube "Testing the API 2" is "11111111-2222-3333-4444-000000000002" - - When I POST the following JSON to the API path "/00000000-1111-2222-3333-444444444444/all": - """ - { - "search": { - "barcode": 3980012345764 - } - } - """ - Then the HTTP response should be "300 Multiple Choices" - And the JSON should match the following for the specified fields: - """ - { - "searches": [ - { - "name": "Testing the API 2", - "uuid": "11111111-2222-3333-4444-000000000002" - } - ] - } - """ - - @multiple @sample_tube @error - Scenario: Looking up a non-existant barcode with all - Given the UUID for the search "Find assets by barcode" is "00000000-1111-2222-3333-444444444444" - - When I POST the following JSON to the API path "/00000000-1111-2222-3333-444444444444/all": - """ - { - "search": { - "barcode": 3980012345764 - } - } - """ - Then the HTTP response should be "300 Multiple Choices" - And the JSON should be: - """ - { - "searches": [], - "size": 0 - } - """ diff --git a/features/api/searches/find_deprecated.feature b/features/api/searches/find_deprecated.feature deleted file mode 100644 index 956c1eda05..0000000000 --- a/features/api/searches/find_deprecated.feature +++ /dev/null @@ -1,27 +0,0 @@ -@api @json @asset @search @single-sign-on @new-api @barcode_search -Feature: Searching for assets with a deprecated search - Background: - Given all of this is happening at exactly "12-Jun-2012 23:00:00+01:00" - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API - And I have a "full" authorised user with the key "cucumber" - - Given the UUID for the search "Find pulldown plates" is "00000000-1111-2222-3333-444444444444" - - Scenario: I should see a deprecation warning - When I POST the following JSON to the API path "/00000000-1111-2222-3333-444444444444/all": - """ - { - "search": { - "state": ["pending","started","failed","passed"] - } - } - """ - - Then the HTTP response should be "410 Gone" - And the JSON should match the following for the specified fields: - """ - {"general": ["requested action is no longer supported"]} - """ diff --git a/features/api/searches/find_lot_by_batch_id.feature b/features/api/searches/find_lot_by_batch_id.feature deleted file mode 100644 index 8dbfba3559..0000000000 --- a/features/api/searches/find_lot_by_batch_id.feature +++ /dev/null @@ -1,81 +0,0 @@ -@api @json @asset @search @single-sign-on @new-api @barcode-service -Feature: Searching for a lot by batch id - Background: - Given all of this is happening at exactly "23-Oct-2010 23:00:00+01:00" - - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - Given the UUID for the search "Find lot by batch id" is "00000000-1111-2222-3333-444444444444" - - @single - Scenario: looking for a tag lot by batch id - Given I have a lot type for testing called "Test Lot Type" - And the tag layout template "Test tag layout" exists - And the lot exists with the attributes: - | lot_number | lot_type | received_at | template | - | 1234567890 | Test Lot Type | 2014-02-01 | Test tag layout | - And a plate template exists - And I have a reporter lot type for testing called "Test Reporter Lot Type" - And the lot exists with the attributes: - | lot_number | lot_type | received_at | template | - | 1234567891 | Test Reporter Lot Type | 2014-02-01 | test_plate_template | - - And I have a qc library created - - When I POST the following JSON to the API path "/00000000-1111-2222-3333-444444444444/first": - """ - { - "search": { - "batch_id": "12345" - } - } - """ - Then the HTTP response should be "301 Moved permanently" - And the JSON should match the following for the specified fields: - """ - { - "lot":{ - "lot_number":"1234567890", - "template_name":"Test tag layout" - } - } - """ - - @single - Scenario: looking for a reporter lot by batch id - Given I have a lot type for testing called "Test Lot Type" - And the tag layout template "Test tag layout" exists - And the lot exists with the attributes: - | lot_number | lot_type | received_at | template | - | 1234567890 | Test Lot Type | 2014-02-01 | Test tag layout | - And a plate template exists - And I have a reporter lot type for testing called "Test Reporter Lot Type" - And the lot exists with the attributes: - | lot_number | lot_type | received_at | template | - | 1234567891 | Test Reporter Lot Type | 2014-02-01 | test_plate_template | - - And I have a qc library created - And the library is testing a reporter - - When I POST the following JSON to the API path "/00000000-1111-2222-3333-444444444444/first": - """ - { - "search": { - "batch_id": "12345" - } - } - """ - Then the HTTP response should be "301 Moved permanently" - And the JSON should match the following for the specified fields: - """ - { - "lot":{ - "lot_number":"1234567891", - "template_name":"test_plate_template" - } - } - """ diff --git a/features/api/searches/find_lot_by_lot_number.feature b/features/api/searches/find_lot_by_lot_number.feature deleted file mode 100644 index ce52ab35de..0000000000 --- a/features/api/searches/find_lot_by_lot_number.feature +++ /dev/null @@ -1,38 +0,0 @@ -@api @json @user @search @single-sign-on @new-api -Feature: Searching for lots by lot number - Background: - Given all of this is happening at exactly "23-Oct-2010 23:00:00+01:00" - - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - Given the UUID for the search "Find lot by lot number" is "00000000-1111-2222-3333-444444444444" - - @single - Scenario: looking for an existing user by swipecard code - Given I have a lot type for testing called "Test Lot Type" - And the tag layout template "Test tag layout" exists - And the lot exists with the attributes: - | lot_number | lot_type | received_at | template | - | 1234567890 | Test Lot Type | 2014-02-01 | Test tag layout | - When I POST the following JSON to the API path "/00000000-1111-2222-3333-444444444444/first": - """ - { - "search": { - "lot_number": "1234567890" - } - } - """ - Then the HTTP response should be "301 Moved permanently" - And the JSON should match the following for the specified fields: - """ - { - "lot":{ - "lot_number":"1234567890", - "template_name":"Test tag layout" - } - } - """ diff --git a/features/api/searches/find_outstanding_illumina_b_pre_pcr.feature b/features/api/searches/find_outstanding_illumina_b_pre_pcr.feature deleted file mode 100644 index 9343f0fa3e..0000000000 --- a/features/api/searches/find_outstanding_illumina_b_pre_pcr.feature +++ /dev/null @@ -1,50 +0,0 @@ -@api @json @asset @search @single-sign-on @new-api @barcode_search @barcode-service -Feature: The search interface should return outstanding Pre-PCR plates - Background: - Given all of this is happening at exactly "12-Jun-2012 23:00:00+01:00" - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - Given the UUID for the search "Find outstanding Illumina-B pre-PCR plates" is "00000000-1111-2222-3333-444444444444" - - Given a "Stock Plate" plate called "stock plate" exists with barcode "SQPD-1000001" - And a "ILB_STD_PREPCR" plate called "Pending PrePCR" exists with barcode "SQPD-1000002" - And the UUID for the plate "Pending PrePCR" is "00000000-1111-2222-3333-000000000001" - And a "ILB_STD_PREPCR" plate called "Started PrePCR" exists with barcode "SQPD-1000003" - And the UUID for the plate "Started PrePCR" is "00000000-1111-2222-3333-000000000002" - And a "ILB_STD_PREPCR" plate called "Passed PrePCR" exists with barcode "SQPD-1000004" - And the UUID for the plate "Passed PrePCR" is "00000000-1111-2222-3333-000000000003" - And pending transfer requests exist between 1 wells on "stock plate" and "Pending PrePCR" - And started transfer requests exist between 1 wells on "stock plate" and "Started PrePCR" - And passed transfer requests exist between 1 wells on "stock plate" and "Passed PrePCR" - - Scenario: I should be able to find Illumina-B Plates - When I POST the following JSON to the API path "/00000000-1111-2222-3333-444444444444/all": - """ - { - "search": { - } - } - """ - - Then the HTTP response should be "300 Multiple Choices" - And the JSON should match the following for the specified fields: - """ - { - "size":2, - "searches":[{ - "name":"Pending PrePCR", - "plate_purpose":{"name":"ILB_STD_PREPCR"}, - "uuid":"00000000-1111-2222-3333-000000000001", - "state":"pending" - }, { - "name":"Started PrePCR", - "plate_purpose":{"name":"ILB_STD_PREPCR"}, - "uuid":"00000000-1111-2222-3333-000000000002", - "state":"started" - }] - } - """ diff --git a/features/api/searches/find_plates_for_user.feature b/features/api/searches/find_plates_for_user.feature deleted file mode 100644 index 72f703c179..0000000000 --- a/features/api/searches/find_plates_for_user.feature +++ /dev/null @@ -1,81 +0,0 @@ -@api @json @asset @search @single-sign-on @new-api @barcode_search @barcode-service -Feature: Searching for assets by barcode - Background: - Given all of this is happening at exactly "12-Jun-2012 23:00:00+01:00" - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API - And I have a "full" authorised user with the key "cucumber" - - Given the UUID for the search "Find Illumina-C plates for user" is "00000000-1111-2222-3333-444444444446" - - Given a "Stock Plate" plate called "stock plate" exists with barcode "SQPD-1000001" - And a "ILC Stock" plate called "Testing the API A" exists with barcode "SQPD-1000002" - And the UUID for the plate "Testing the API A" is "00000000-1111-2222-3333-000000000001" - And all wells on the plate "Testing the API A" have unique samples - And passed transfer requests exist between 1 wells on "stock plate" and "Testing the API A" - And a "ILC AL Libs" plate called "Testing the API B" exists with barcode "SQPD-1000003" - And the UUID for the plate "Testing the API B" is "00000000-1111-2222-3333-000000000002" - And a "ILC Lib PCR" plate called "Testing the API C" exists with barcode "SQPD-1000004" - And the UUID for the plate "Testing the API C" is "00000000-1111-2222-3333-000000000003" - And a "ILC Lib PCR-XP" plate called "Testing the API D" exists with barcode "SQPD-1000005" - And the UUID for the plate "Testing the API D" is "00000000-1111-2222-3333-000000000004" - And a "Cherrypicked" plate called "Testing the API E" exists with barcode "SQPD-1000006" - And the UUID for the plate "Testing the API D" is "00000000-1111-2222-3333-000000000005" - And pending transfer requests exist between 1 wells on "stock plate" and "Testing the API B" - And pending transfer requests exist between 1 wells on "stock plate" and "Testing the API C" - And pending transfer requests exist between 1 wells on "stock plate" and "Testing the API D" - - Scenario: I should be able to find plates for a particular user - Given user "plate_owner" exists with barcode "owner" - Given the UUID of the last user created is "00000000-1111-2222-3333-100000000001" - Given user "plateless" exists with barcode "plateless" - Given the UUID of the last user created is "00000000-1111-2222-3333-100000000002" - And there is an asset link between "Stock Plate" and "Testing the API B" - - Given the plate "Testing the API B" is started by "plate_owner" - Given the plate "Testing the API C" is started by "plate_owner" - Given the plate "Testing the API E" is started by "plate_owner" - - When I POST the following JSON to the API path "/00000000-1111-2222-3333-444444444446/all": - """ - { - "search": { - "state": ["pending","started","failed","passed"], - "user_uuid": "00000000-1111-2222-3333-100000000001" - } - } - """ - Then the HTTP response should be "300 Multiple Choices" - And the JSON should match the following for the specified fields: - """ - {"size":2, - "searches": - [ - {"name":"Testing the API C", - "plate_purpose":{"name":"ILC Lib PCR"}, - "uuid":"00000000-1111-2222-3333-000000000003", - "state":"started"}, - {"name":"Testing the API B", - "plate_purpose":{"name":"ILC AL Libs"}, - "uuid":"00000000-1111-2222-3333-000000000002", - "state":"started"} - ] - } - """ - When I POST the following JSON to the API path "/00000000-1111-2222-3333-444444444446/all": - """ - { - "search": { - "state": ["pending","started","failed","passed"], - "user_uuid": "00000000-1111-2222-3333-100000000002" - } - } - """ - Then the HTTP response should be "300 Multiple Choices" - And the JSON should match the following for the specified fields: - """ - {"size":0 - } - """ diff --git a/features/api/searches/find_project_study_sample_by_name.feature b/features/api/searches/find_project_study_sample_by_name.feature deleted file mode 100644 index fde06773ca..0000000000 --- a/features/api/searches/find_project_study_sample_by_name.feature +++ /dev/null @@ -1,62 +0,0 @@ -@api @json @study @project @sample @search @single-sign-on @new-api -Feature: Searching for studies, projects and samples by name - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API - And I have a "full" authorised user with the key "cucumber" - Given there are no samples - - @single - Scenario Outline: Looking for a single entry - Given the UUID for the search "Find by name" is "00000000-1111-2222-3333-444444444444" - - Given a called "Testing_the_API_1" with ID 2 - And the UUID for the "Testing_the_API_1" is "11111111-2222-3333-4444-000000000001" - - Given a called "Testing_the_API_2" with ID 3 - And the UUID for the "Testing_the_API_2" is "11111111-2222-3333-4444-000000000002" - - When I POST the following JSON to the API path "/00000000-1111-2222-3333-444444444444/first": - """ - { - "search": { - "name": "Testing_the_API_2" - } - } - """ - Then the HTTP response should be "301 Moved Permanently" - And the JSON should match the following for the specified fields: - """ - { - "": { - "uuid": "11111111-2222-3333-4444-000000000002", - - } - } - """ - - Examples: - | model | name json | - | project | "name": "Testing_the_API_2" | - | study | "name": "Testing_the_API_2" | - | sample | "sanger": { "name": "Testing_the_API_2" } | - - @single - Scenario: Looking for a non-existant entry - Given the UUID for the search "Find assets by barcode" is "00000000-1111-2222-3333-444444444444" - - When I POST the following JSON to the API path "/00000000-1111-2222-3333-444444444444/first": - """ - { - "search": { - "name": "Testing the API 2" - } - } - """ - Then the HTTP response should be "404 Not Found" - And the JSON should be: - """ - { "general": [ "no resources found with that search criteria" ] } - """ diff --git a/features/api/searches/find_qcables_by_barcode.feature b/features/api/searches/find_qcables_by_barcode.feature deleted file mode 100644 index 2db8dc78e4..0000000000 --- a/features/api/searches/find_qcables_by_barcode.feature +++ /dev/null @@ -1,76 +0,0 @@ -@api @json @user @search @single-sign-on @new-api @barcode_search @barcode-service -Feature: Searching for qcables by asset barcode - Background: - Given all of this is happening at exactly "23-Oct-2010 23:00:00+01:00" - - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - Given the UUID for the search "Find qcable by barcode" is "00000000-1111-2222-3333-444444444444" - - Given I have a lot type for testing called "Test Lot Type" - And the tag layout template "Test tag layout" exists - And the lot exists with the attributes: - | lot_number | lot_type | received_at | template | - | 1234567890 | Test Lot Type | 2014-02-01 | Test tag layout | - And I have two qcables - - - @single - Scenario: looking for a single barcode - - When I POST the following JSON to the API path "/00000000-1111-2222-3333-444444444444/first": - """ - { - "search": { - "barcode": "SQPD-1000001" - } - } - """ - Then the HTTP response should be "301 Moved permanently" - And the JSON should match the following for the specified fields: - """ - { - "qcable":{ - "state": "created", - "barcode" : { - "machine" : "SQPD-1000001" - } - } - } - """ - - @multiple - Scenario: looking for multiple barcodes - - When I POST the following JSON to the API path "/00000000-1111-2222-3333-444444444444/all": - """ - { - "search": { - "barcode": ["SQPD-1000001","SQPD-1000002"] - } - } - """ - Then the HTTP response should be "300 Multiple Choices" - And the JSON should match the following for the specified fields: - """ - { - "searches":[ - { - "state": "created", - "barcode" : { - "machine" : "SQPD-1000001" - } - }, - { - "state": "created", - "barcode" : { - "machine" : "SQPD-1000002" - } - } - ] - } - """ diff --git a/features/api/searches/find_robots_by_barcode.feature b/features/api/searches/find_robots_by_barcode.feature deleted file mode 100644 index 44f715bd71..0000000000 --- a/features/api/searches/find_robots_by_barcode.feature +++ /dev/null @@ -1,54 +0,0 @@ -@api @json @asset @search @single-sign-on @new-api @barcode_search -Feature: Searching for robots by barcode - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - @search_assets @single - Scenario: Looking up a single robot by barcode - Given the UUID for the search "Find robot by barcode" is "00000000-1111-2222-3333-444444444444" - - Given a robot exists with barcode "3" - - When I POST the following JSON to the API path "/00000000-1111-2222-3333-444444444444/first": - """ - { - "search": { - "barcode": 4880000003807 - } - } - """ - Then the HTTP response should be "301 Moved Permanently" - And the JSON should match the following for the specified fields: - """ - { - "robot": { - "name": "myrobot" - } - } - """ - - - @single @sample_tube @error - Scenario: Looking up with a bed barcode should fail - Given the UUID for the search "Find robot by barcode" is "00000000-1111-2222-3333-444444444444" - - Given a robot exists with barcode "3" - - When I POST the following JSON to the API path "/00000000-1111-2222-3333-444444444444/first": - """ - { - "search": { - "barcode": 580000003824 - } - } - """ - Then the HTTP response should be "404 Not Found" - And the JSON should be: - """ - { "general": [ "no resources found with that search criteria" ] } - """ - diff --git a/features/api/searches/find_source_assets_by_destination_asset_barcode.feature b/features/api/searches/find_source_assets_by_destination_asset_barcode.feature deleted file mode 100644 index ff9d8e15ba..0000000000 --- a/features/api/searches/find_source_assets_by_destination_asset_barcode.feature +++ /dev/null @@ -1,75 +0,0 @@ -@api @json @asset @search @single-sign-on @new-api @barcode_search @destination_barcode_search -Feature: Searching for assets by barcode - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - Given the UUID for the search "Find source assets by destination asset barcode" is "00000000-1111-2222-3333-444444444444" - - @multiple @plate - Scenario: Looking up multiple source assets by destination asset barcode - Given a plate called "Testing the API 1" with ID 1 - And the plate "Testing the API 1" has a barcode of "1220099999705" - And the UUID for the plate "Testing the API 1" is "11111111-2222-3333-4444-000000000001" - - Given a plate called "Testing the API 2" with ID 2 - And the plate "Testing the API 2" has a barcode of "1220000222748" - And the UUID for the plate "Testing the API 2" is "11111111-2222-3333-4444-000000000002" - - Given a plate called "Testing the API 3" with ID 3 - And the plate "Testing the API 3" has a barcode of "1220000333802" - And the UUID for the plate "Testing the API 3" is "11111111-2222-3333-4444-000000000003" - - Given plate "11111111-2222-3333-4444-000000000002" is a source plate of "11111111-2222-3333-4444-000000000001" - And plate "11111111-2222-3333-4444-000000000003" is a source plate of "11111111-2222-3333-4444-000000000001" - - When I POST the following JSON to the API path "/00000000-1111-2222-3333-444444444444/all": - """ - { - "search": { - "barcode": 1220099999705 - } - } - """ - Then the HTTP response should be "300 Multiple Choices" - And the JSON should match the following for the specified fields: - """ - { - "searches": [ - { - "name": "Testing the API 2", - "uuid": "11111111-2222-3333-4444-000000000002", - "barcode": { - "ean13": "1220000222748" - } - }, - { - "name": "Testing the API 3", - "uuid": "11111111-2222-3333-4444-000000000003", - "barcode": { - "ean13": "1220000333802" - } - } - ] - } - """ - - @multiple @plate @error - Scenario: Looking up multiple source assets by non-existant destination asset barcode - When I POST the following JSON to the API path "/00000000-1111-2222-3333-444444444444/all": - """ - { - "search": { - "barcode": 1220099999705 - } - } - """ - Then the HTTP response should be "300 Multiple Choices" - And the JSON should be: - """ - { - "size": 0, - "searches": [] - } - """ diff --git a/features/api/searches/find_user_by_login.feature b/features/api/searches/find_user_by_login.feature deleted file mode 100644 index bf7af4dd47..0000000000 --- a/features/api/searches/find_user_by_login.feature +++ /dev/null @@ -1,72 +0,0 @@ -@api @json @user @search @single-sign-on @new-api -Feature: Searching for users by login - Background: - Given all of this is happening at exactly "23-Oct-2010 23:00:00+01:00" - - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - Given the UUID for the search "Find user by login" is "00000000-1111-2222-3333-444444444444" - - @single - Scenario: looking for an existing user by login - Given user "user_login" exists - When I POST the following JSON to the API path "/00000000-1111-2222-3333-444444444444/first": - """ - { - "search": { - "login": "user_login" - } - } - """ - Then the HTTP response should be "301 Moved permanently" - And the JSON should match the following for the specified fields: - """ - { - "user":{ - "login":"user_login", - "first_name":"User Login", - "email":"user_login@example.com" - } - } - """ - @multiple - Scenario: looking for many existing users by login - Given user "user_login" exists - When I POST the following JSON to the API path "/00000000-1111-2222-3333-444444444444/all": - """ - { - "search": { - "login": "user_login" - } - } - """ - Then the HTTP response should be "300 Multiple Content" - And the JSON should match the following for the specified fields: - """ - { - "searches": [ - { - "login":"user_login", - "first_name":"User Login", - "email":"user_login@example.com" - } - ] - } - """ - @error - Scenario: looking for a non-existing login - When I POST the following JSON to the API path "/00000000-1111-2222-3333-444444444444/first": - """ - { - "search": { - "login": "user_login" - } - } - """ - Then the HTTP response should be "404 Not Found" - - diff --git a/features/api/searches/find_user_by_swipcard_code.feature b/features/api/searches/find_user_by_swipcard_code.feature deleted file mode 100644 index 24986594c9..0000000000 --- a/features/api/searches/find_user_by_swipcard_code.feature +++ /dev/null @@ -1,36 +0,0 @@ -@api @json @user @search @single-sign-on @new-api -Feature: Searching for users by swipecard code - Background: - Given all of this is happening at exactly "23-Oct-2010 23:00:00+01:00" - - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - Given the UUID for the search "Find user by swipecard code" is "00000000-1111-2222-3333-444444444444" - - @single - Scenario: looking for an existing user by swipecard code - Given the user exists with ID 1 and the following attributes: - | name | value | - | first_name | me | - | swipecard_code | code | - When I POST the following JSON to the API path "/00000000-1111-2222-3333-444444444444/first": - """ - { - "search": { - "swipecard_code": "code" - } - } - """ - Then the HTTP response should be "301 Moved permanently" - And the JSON should match the following for the specified fields: - """ - { - "user":{ - "first_name":"me" - } - } - """ diff --git a/features/api/sequencing_requests.feature b/features/api/sequencing_requests.feature deleted file mode 100644 index c6cbb683f2..0000000000 --- a/features/api/sequencing_requests.feature +++ /dev/null @@ -1,46 +0,0 @@ -@api @json @sequencing_request @single-sign-on @new-api -Feature: Access sequencing requests through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to create, read and update individual sequencing requests through their UUID - And I want to be able to perform other operations to individual sequencing requests - And I want to be able to do all of this only knowing the UUID of a sequencing request - And I understand I will never be able to delete a sequencing request through its UUID - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - Given I have a project called "My project" - And the UUID for the project "My project" is "11111111-1111-2222-3333-444444444444" - - Given I have an active study called "Testing the sequencing requests API" - And the UUID for the study "Testing the sequencing requests API" is "11111111-2222-3333-4444-000000000000" - And I have an empty library tube called "tube_1" - And the UUID for the library tube "tube_1" is "11111111-3333-4444-5555-666666666666" - - @read - Scenario: Reading the JSON for a UUID - Given I have already made a "Paired end sequencing" request with ID 1 within the study "Testing the sequencing requests API" for the project "My project" - And the UUID for the sequencing request with ID 1 is "00000000-1111-2222-3333-444444444444" - - When I GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "sequencing_request": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - - "type": "Paired end sequencing", - "read_length": 76 - } - } - """ diff --git a/features/api/studies.feature b/features/api/studies.feature deleted file mode 100644 index 588706c239..0000000000 --- a/features/api/studies.feature +++ /dev/null @@ -1,83 +0,0 @@ -@api @json @study @single-sign-on @new-api @study_api -Feature: Access studies through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to create, read and update individual studies through their UUID - And I want to be able to perform other operations to individual studies - And I want to be able to do all of this only knowing the UUID of a study - And I understand I will never be able to delete a study through its UUID - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - @read - Scenario: Reading the JSON for a UUID - Given a study called "Testing the API" with ID 8274 - And a study "Testing the API" is pending - And the UUID for the study "Testing the API" is "00000000-1111-2222-3333-444444444444" - And the faculty sponsor for study "Testing the API" is "John Smith" - And the reference genome for study "Testing the API" is "RefGenome" - - When I GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "study": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - "name": "Testing the API", - - "ethically_approved": false, - "state": "pending", - "abbreviation": "WTCCC", - - "type": "Not specified", - "sac_sponsor": "John Smith", - "reference_genome": null, - "accession_number": null, - "description": "Some study on something", - "abstract": null, - - "contaminated_human_dna": "No", - "contains_human_dna": "No", - "remove_x_and_autosomes": false, - "separate_y_chromosome_data": false, - "commercially_available": "No", - "data_release_sort_of_study": "genomic sequencing", - "data_release_strategy": "open", - "reference_genome": "RefGenome", - - "samples": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/samples" - } - }, - "projects": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/projects" - } - }, - "asset_groups": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/asset_groups" - } - }, - "sample_manifests": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/sample_manifests", - "create_for_plates": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/sample_manifests/create_for_plates", - "create_for_tubes": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/sample_manifests/create_for_tubes", - "create_for_multiplexed_libraries": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/sample_manifests/create_for_multiplexed_libraries" - } - } - } - } - """ diff --git a/features/api/suppliers.feature b/features/api/suppliers.feature deleted file mode 100644 index 4c3e6c07f3..0000000000 --- a/features/api/suppliers.feature +++ /dev/null @@ -1,48 +0,0 @@ -@api @json @supplier @single-sign-on @new-api -Feature: Access suppliers through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to create, read and update individual suppliers through their UUID - And I want to be able to perform other operations to individual suppliers - And I want to be able to do all of this only knowing the UUID of a supplier - And I understand I will never be able to delete a supplier through its UUID - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - @read - Scenario: Reading the JSON for a UUID - Given a supplier called "John's Genes" with ID 1 - And the UUID for the supplier "John's Genes" is "00000000-1111-2222-3333-444444444444" - - When I GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "supplier": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - "sample_manifests": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/sample_manifests" - } - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - "name": "John's Genes", - "email": null, - "address": null, - "contact_name": null, - "phone_number": null, - "fax": null, - "url": null, - "abbreviation": null - } - } - """ diff --git a/features/api/tag_layout_templates.feature b/features/api/tag_layout_templates.feature deleted file mode 100644 index 903143beb7..0000000000 --- a/features/api/tag_layout_templates.feature +++ /dev/null @@ -1,772 +0,0 @@ -@wip @api @json @tag_layout_template @single-sign-on @new-api -Feature: Access tag layout templates through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to create, read and update individual tag layout templates through their UUID - And I want to be able to perform other operations to individual tag layout templates - And I want to be able to do all of this only knowing the UUID of a tag layout template - And I understand I will never be able to delete a tag layout template through its UUID - - Background: - Given all of this is happening at exactly "23-Oct-2010 23:00:00+01:00" - - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API - And I have a "full" authorised user with the key "cucumber" - - @tag_layout @create @barcode-service - Scenario: Creating a tag layout from a tag layout template - Given the Baracoda barcode service returns "SQPD-1000001" - Given the Baracoda barcode service returns "SQPD-1000002" - - Given the tag layout template "Test tag layout" exists - And the UUID for the tag layout template "Test tag layout" is "00000000-1111-2222-3333-444444444444" - And the tag group for tag layout template "Test tag layout" is called "Tag group 1" - And the tag group for tag layout template "Test tag layout" contains the following tags: - | index | oligo | - | 1 | AAAA | - | 2 | CCCC | - | 3 | TTTT | - | 4 | GGGG | - | 5 | AACC | - | 6 | TTGG | - | 7 | AATT | - | 8 | CCGG | - And the UUID of the next tag layout created will be "00000000-1111-2222-3333-000000000002" - - Given a "Stock plate" plate called "Testing the API" exists - And the UUID for the plate "Testing the API" is "11111111-2222-3333-4444-000000000002" - And all wells on the plate "Testing the API" have unique samples - - Given a "Stock plate" plate called "Testing the tagging" exists - And the UUID for the plate "Testing the tagging" is "11111111-2222-3333-4444-000000000001" - And the wells for the plate "Testing the API" have been pooled in columns to the plate "Testing the tagging" - - When I make an authorised POST with the following JSON to the API path "/00000000-1111-2222-3333-444444444444": - """ - { - "tag_layout": { - "plate": "11111111-2222-3333-4444-000000000001" - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "tag_layout": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-000000000002" - }, - "plate": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-000000000001" - } - }, - - "uuid": "00000000-1111-2222-3333-000000000002", - "direction": "column", - - "tag_group": { - "name": "Tag group 1", - "tags": { - "1": "AAAA", - "2": "CCCC", - "3": "TTTT", - "4": "GGGG", - "5": "AACC", - "6": "TTGG", - "7": "AATT", - "8": "CCGG" - } - } - } - } - """ - - Then the tag layout on the plate "Testing the tagging" should be: - | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | - | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | - | TTTT | TTTT | TTTT | TTTT | TTTT | TTTT | TTTT | TTTT | TTTT | TTTT | TTTT | TTTT | - | GGGG | GGGG | GGGG | GGGG | GGGG | GGGG | GGGG | GGGG | GGGG | GGGG | GGGG | GGGG | - | AACC | AACC | AACC | AACC | AACC | AACC | AACC | AACC | AACC | AACC | AACC | AACC | - | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | - | AATT | AATT | AATT | AATT | AATT | AATT | AATT | AATT | AATT | AATT | AATT | AATT | - | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | - - @tag_layout @create @barcode-service - Scenario: Creating a tag layout from an inverted tag layout template - Given the Baracoda barcode service returns "SQPD-1000001" - Given the Baracoda barcode service returns "SQPD-1000002" - - Given the inverted tag layout template "Test inverted tag layout" exists - And the UUID for the tag layout template "Test inverted tag layout" is "00000000-1111-2222-3333-444444444444" - And the tag group for tag layout template "Test inverted tag layout" is called "Tag group 1" - And the tag group for tag layout template "Test inverted tag layout" contains the following tags: - | index | oligo | - | 1 | AAAA | - | 2 | CCCC | - | 3 | TTTT | - | 4 | GGGG | - | 5 | AACC | - | 6 | TTGG | - | 7 | AATT | - | 8 | CCGG | - And the UUID of the next tag layout created will be "00000000-1111-2222-3333-000000000002" - - Given a "Stock plate" plate called "Testing the API" exists - And the UUID for the plate "Testing the API" is "11111111-2222-3333-4444-000000000002" - And all wells on the plate "Testing the API" have unique samples - - Given a "Stock plate" plate called "Testing the tagging" exists - And the UUID for the plate "Testing the tagging" is "11111111-2222-3333-4444-000000000001" - And the wells for the plate "Testing the API" have been pooled in columns to the plate "Testing the tagging" - - When I make an authorised POST with the following JSON to the API path "/00000000-1111-2222-3333-444444444444": - """ - { - "tag_layout": { - "plate": "11111111-2222-3333-4444-000000000001" - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "tag_layout": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-000000000002" - }, - "plate": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-000000000001" - } - }, - - "uuid": "00000000-1111-2222-3333-000000000002", - "direction": "inverse column", - - "tag_group": { - "name": "Tag group 1", - "tags": { - "1": "AAAA", - "2": "CCCC", - "3": "TTTT", - "4": "GGGG", - "5": "AACC", - "6": "TTGG", - "7": "AATT", - "8": "CCGG" - } - } - } - } - """ - - Then the tag layout on the plate "Testing the tagging" should be: - | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | - | AATT | AATT | AATT | AATT | AATT | AATT | AATT | AATT | AATT | AATT | AATT | AATT | - | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | - | AACC | AACC | AACC | AACC | AACC | AACC | AACC | AACC | AACC | AACC | AACC | AACC | - | GGGG | GGGG | GGGG | GGGG | GGGG | GGGG | GGGG | GGGG | GGGG | GGGG | GGGG | GGGG | - | TTTT | TTTT | TTTT | TTTT | TTTT | TTTT | TTTT | TTTT | TTTT | TTTT | TTTT | TTTT | - | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | - | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | - - - @tag_layout @create @barcode-service - Scenario: Creating a tag layout from a tag layout template where wells have been failed - Given the Baracoda barcode service returns "SQPD-1000001" - Given the Baracoda barcode service returns "SQPD-1000002" - - Given the tag layout template "Test tag layout" exists - And the UUID for the tag layout template "Test tag layout" is "00000000-1111-2222-3333-444444444444" - And the tag group for tag layout template "Test tag layout" is called "Tag group 1" - And the tag group for tag layout template "Test tag layout" contains the following tags: - | index | oligo | - | 1 | TAGCTTGT | - | 2 | CGATGTTT | - | 3 | GCCAATGT | - | 4 | ACAGTGGT | - | 5 | ATCACGTT | - | 6 | GATCAGCG | - | 7 | CAGATCTG | - | 8 | TTAGGCAT | - | 9 | GGCTACAG | - | 10 | CTTGTACT | - | 11 | ACTTGATG | - | 12 | TGACCACT | - | 13 | TGGTTGTT | - | 14 | TCTCGGTT | - | 15 | TAAGCGTT | - | 16 | TCCGTCTT | - | 17 | TGTACCTT | - | 18 | TTCTGTGT | - | 19 | TCTGCTGT | - | 20 | TTGGAGGT | - | 21 | TCGAGCGT | - | 22 | TGATACGT | - | 23 | TGCATAGT | - | 24 | TTGACTCT | - | 25 | TGCGATCT | - | 26 | TTCCTGCT | - | 27 | TAGTGACT | - | 28 | TACAGGAT | - | 29 | TCCTCAAT | - | 30 | TGTGGTTG | - | 31 | TAGTCTTG | - | 32 | TTCCATTG | - | 33 | TCGAAGTG | - | 34 | TAACGCTG | - | 35 | TTGGTATG | - | 36 | TGAACTGG | - | 37 | TACTTCGG | - | 38 | TCTCACGG | - | 39 | TCAGGAGG | - | 40 | TAAGTTCG | - | 41 | TCCAGTCG | - | 42 | TGTATGCG | - | 43 | TCATTGAG | - | 44 | TGGCTCAG | - | 45 | TATGCCAG | - | 46 | TCAGATTC | - | 47 | TACTAGTC | - | 48 | TTCAGCTC | - | 49 | TGTCTATC | - | 50 | TATGTGGC | - | 51 | TTACTCGC | - | 52 | TCGTTAGC | - | 53 | TACCGAGC | - | 54 | TGTTCTCC | - | 55 | TTCGCACC | - | 56 | TTGCGTAC | - | 57 | TCTACGAC | - | 58 | TGACAGAC | - | 59 | TAGAACAC | - | 60 | TCATCCTA | - | 61 | TGCTGATA | - | 62 | TAGACGGA | - | 63 | TGTGAAGA | - | 64 | TCTCTTCA | - | 65 | TTGTTCCA | - | 66 | TGAAGCCA | - | 67 | TACCACCA | - | 68 | TGCGTGAA | - | 69 | GGTGAGTT | - | 70 | GATCTCTT | - | 71 | GTGTCCTT | - | 72 | GACGGATT | - | 73 | GCAACATT | - | 74 | GGTCGTGT | - | 75 | GAATCTGT | - | 76 | GTACATCT | - | 77 | GAGGTGCT | - | 78 | GCATGGCT | - | 79 | GTTAGCCT | - | 80 | GTCGCTAT | - | 81 | GGAATGAT | - | 82 | GAGCCAAT | - | 83 | GCTCCTTG | - | 84 | GTAAGGTG | - | 85 | GAGGATGG | - | 86 | GTTGTCGG | - | 87 | GGATTAGG | - | 88 | GATAGAGG | - | 89 | GTGTGTCG | - | 90 | GCAATCCG | - | 91 | GACCTTAG | - | 92 | GCCTGTTC | - | 93 | GCACTGTC | - | 94 | GCTAACTC | - | 95 | GATTCATC | - | 96 | GTCTTGGC | - - And the UUID of the next tag layout created will be "00000000-1111-2222-3333-000000000002" - - Given a "Stock plate" plate called "Testing the API" exists - And the UUID for the plate "Testing the API" is "11111111-2222-3333-4444-000000000002" - And all wells on the plate "Testing the API" have unique samples - - Given a "Stock plate" plate called "Testing the tagging" exists - And the UUID for the plate "Testing the tagging" is "11111111-2222-3333-4444-000000000001" - And the wells for the plate "Testing the API" have been pooled to the plate "Testing the tagging" according to the pooling strategy 96 - And "F11-F12" of the plate "Testing the tagging" have been failed - And "G12-G12" of the plate "Testing the tagging" have been failed - - When I make an authorised POST with the following JSON to the API path "/00000000-1111-2222-3333-444444444444": - """ - { - "tag_layout": { - "plate": "11111111-2222-3333-4444-000000000001" - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "tag_layout": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-000000000002" - }, - "plate": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-000000000001" - } - }, - - "uuid": "00000000-1111-2222-3333-000000000002", - "direction": "column", - - "tag_group": { - "name": "Tag group 1", - "tags": { - "1": "TAGCTTGT", - "2": "CGATGTTT", - "3": "GCCAATGT", - "4": "ACAGTGGT", - "5": "ATCACGTT", - "6": "GATCAGCG", - "7": "CAGATCTG", - "8": "TTAGGCAT", - "9": "GGCTACAG", - "10": "CTTGTACT", - "11": "ACTTGATG", - "12": "TGACCACT", - "13": "TGGTTGTT", - "14": "TCTCGGTT", - "15": "TAAGCGTT", - "16": "TCCGTCTT", - "17": "TGTACCTT", - "18": "TTCTGTGT", - "19": "TCTGCTGT", - "20": "TTGGAGGT", - "21": "TCGAGCGT", - "22": "TGATACGT", - "23": "TGCATAGT", - "24": "TTGACTCT", - "25": "TGCGATCT", - "26": "TTCCTGCT", - "27": "TAGTGACT", - "28": "TACAGGAT", - "29": "TCCTCAAT", - "30": "TGTGGTTG", - "31": "TAGTCTTG", - "32": "TTCCATTG", - "33": "TCGAAGTG", - "34": "TAACGCTG", - "35": "TTGGTATG", - "36": "TGAACTGG", - "37": "TACTTCGG", - "38": "TCTCACGG", - "39": "TCAGGAGG", - "40": "TAAGTTCG", - "41": "TCCAGTCG", - "42": "TGTATGCG", - "43": "TCATTGAG", - "44": "TGGCTCAG", - "45": "TATGCCAG", - "46": "TCAGATTC", - "47": "TACTAGTC", - "48": "TTCAGCTC", - "49": "TGTCTATC", - "50": "TATGTGGC", - "51": "TTACTCGC", - "52": "TCGTTAGC", - "53": "TACCGAGC", - "54": "TGTTCTCC", - "55": "TTCGCACC", - "56": "TTGCGTAC", - "57": "TCTACGAC", - "58": "TGACAGAC", - "59": "TAGAACAC", - "60": "TCATCCTA", - "61": "TGCTGATA", - "62": "TAGACGGA", - "63": "TGTGAAGA", - "64": "TCTCTTCA", - "65": "TTGTTCCA", - "66": "TGAAGCCA", - "67": "TACCACCA", - "68": "TGCGTGAA", - "69": "GGTGAGTT", - "70": "GATCTCTT", - "71": "GTGTCCTT", - "72": "GACGGATT", - "73": "GCAACATT", - "74": "GGTCGTGT", - "75": "GAATCTGT", - "76": "GTACATCT", - "77": "GAGGTGCT", - "78": "GCATGGCT", - "79": "GTTAGCCT", - "80": "GTCGCTAT", - "81": "GGAATGAT", - "82": "GAGCCAAT", - "83": "GCTCCTTG", - "84": "GTAAGGTG", - "85": "GAGGATGG", - "86": "GTTGTCGG", - "87": "GGATTAGG", - "88": "GATAGAGG", - "89": "GTGTGTCG", - "90": "GCAATCCG", - "91": "GACCTTAG", - "92": "GCCTGTTC", - "93": "GCACTGTC", - "94": "GCTAACTC", - "95": "GATTCATC", - "96": "GTCTTGGC" - } - } - } - } - """ - - Then the tag layout on the plate "Testing the tagging" should be: - | TAGCTTGT | GGCTACAG | TGTACCTT | TGCGATCT | TCGAAGTG | TCCAGTCG | TGTCTATC | TCTACGAC | TTGTTCCA | GCAACATT | GGAATGAT | GTGTGTCG | - | CGATGTTT | CTTGTACT | TTCTGTGT | TTCCTGCT | TAACGCTG | TGTATGCG | TATGTGGC | TGACAGAC | TGAAGCCA | GGTCGTGT | GAGCCAAT | GCAATCCG | - | GCCAATGT | ACTTGATG | TCTGCTGT | TAGTGACT | TTGGTATG | TCATTGAG | TTACTCGC | TAGAACAC | TACCACCA | GAATCTGT | GCTCCTTG | GACCTTAG | - | ACAGTGGT | TGACCACT | TTGGAGGT | TACAGGAT | TGAACTGG | TGGCTCAG | TCGTTAGC | TCATCCTA | TGCGTGAA | GTACATCT | GTAAGGTG | GCCTGTTC | - | ATCACGTT | TGGTTGTT | TCGAGCGT | TCCTCAAT | TACTTCGG | TATGCCAG | TACCGAGC | TGCTGATA | GGTGAGTT | GAGGTGCT | GAGGATGG | GCACTGTC | - | GATCAGCG | TCTCGGTT | TGATACGT | TGTGGTTG | TCTCACGG | TCAGATTC | TGTTCTCC | TAGACGGA | GATCTCTT | GCATGGCT | | | - | CAGATCTG | TAAGCGTT | TGCATAGT | TAGTCTTG | TCAGGAGG | TACTAGTC | TTCGCACC | TGTGAAGA | GTGTCCTT | GTTAGCCT | GGATTAGG | | - | TTAGGCAT | TCCGTCTT | TTGACTCT | TTCCATTG | TAAGTTCG | TTCAGCTC | TTGCGTAC | TCTCTTCA | GACGGATT | GTCGCTAT | GATAGAGG | GTCTTGGC | - - @tag_layout @create @barcode-service - Scenario: Creating a tag layout with substitutions from a tag layout template - Given the Baracoda barcode service returns "SQPD-1000001" - Given the Baracoda barcode service returns "SQPD-1000002" - - Given the tag layout template "Test tag layout" exists - And the UUID for the tag layout template "Test tag layout" is "00000000-1111-2222-3333-444444444444" - And the tag group for tag layout template "Test tag layout" is called "Tag group 1" - And the tag group for tag layout template "Test tag layout" contains the following tags: - | index | oligo | - | 1 | AAAA | - | 2 | CCCC | - | 3 | TTTT | - | 4 | GGGG | - | 5 | AACC | - | 6 | TTGG | - | 7 | AATT | - | 8 | CCGG | - And the UUID of the next tag layout created will be "00000000-1111-2222-3333-000000000002" - - Given a "Stock plate" plate called "Testing the API" exists - And the UUID for the plate "Testing the API" is "11111111-2222-3333-4444-000000000002" - And all wells on the plate "Testing the API" have unique samples - - Given a "Stock plate" plate called "Testing the tagging" exists - And the UUID for the plate "Testing the tagging" is "11111111-2222-3333-4444-000000000001" - And the wells for the plate "Testing the API" have been pooled in columns to the plate "Testing the tagging" - - When I make an authorised POST with the following JSON to the API path "/00000000-1111-2222-3333-444444444444": - """ - { - "tag_layout": { - "plate": "11111111-2222-3333-4444-000000000001", - "substitutions": { - "8": "7", - "7": "8" - } - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "tag_layout": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-000000000002" - }, - "plate": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-000000000001" - } - }, - - "uuid": "00000000-1111-2222-3333-000000000002", - "direction": "column", - - "tag_group": { - "name": "Tag group 1", - "tags": { - "1": "AAAA", - "2": "CCCC", - "3": "TTTT", - "4": "GGGG", - "5": "AACC", - "6": "TTGG", - "7": "AATT", - "8": "CCGG" - } - }, - "substitutions": { - "8": "7", - "7": "8" - } - } - } - """ - - Then the tag layout on the plate "Testing the tagging" should be: - | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | - | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | - | TTTT | TTTT | TTTT | TTTT | TTTT | TTTT | TTTT | TTTT | TTTT | TTTT | TTTT | TTTT | - | GGGG | GGGG | GGGG | GGGG | GGGG | GGGG | GGGG | GGGG | GGGG | GGGG | GGGG | GGGG | - | AACC | AACC | AACC | AACC | AACC | AACC | AACC | AACC | AACC | AACC | AACC | AACC | - | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | - | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | - | AATT | AATT | AATT | AATT | AATT | AATT | AATT | AATT | AATT | AATT | AATT | AATT | - - @tag_layout @create @barcode-service - Scenario: Creating a tag layout where the pools are factors of the number of rows on the plate - Given the Baracoda barcode service returns "SQPD-1000001" - Given the Baracoda barcode service returns "SQPD-1000002" - - Given the tag layout template "Test tag layout" exists - And the UUID for the tag layout template "Test tag layout" is "00000000-1111-2222-3333-444444444444" - And the tag group for tag layout template "Test tag layout" is called "Tag group 1" - And the tag group for tag layout template "Test tag layout" contains the following tags: - | index | oligo | - | 1 | AAAA | - | 2 | CCCC | - | 3 | TTTT | - | 4 | GGGG | - | 5 | AACC | - | 6 | TTGG | - | 7 | AATT | - | 8 | CCGG | - | 9 | GAGA | - | 10 | CACA | - And the UUID of the next tag layout created will be "00000000-1111-2222-3333-000000000002" - - Given a "Stock plate" plate called "Testing the API" exists - And the UUID for the plate "Testing the API" is "11111111-2222-3333-4444-000000000002" - And all wells on the plate "Testing the API" have unique samples - - Given a "Stock plate" plate called "Testing the tagging" exists - And the UUID for the plate "Testing the tagging" is "11111111-2222-3333-4444-000000000001" - And the wells for the plate "Testing the API" have been pooled to the plate "Testing the tagging" according to the pooling strategy 8, 4, 8, 4, 8, 4, 8, 4, 8, 4, 8, 4, 8, 4, 8, 4 - - When I make an authorised POST with the following JSON to the API path "/00000000-1111-2222-3333-444444444444": - """ - { - "tag_layout": { - "plate": "11111111-2222-3333-4444-000000000001" - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "tag_layout": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-000000000002" - }, - "plate": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-000000000001" - } - }, - - "uuid": "00000000-1111-2222-3333-000000000002", - "direction": "column", - - "tag_group": { - "name": "Tag group 1", - "tags": { - "1": "AAAA", - "2": "CCCC", - "3": "TTTT", - "4": "GGGG", - "5": "AACC", - "6": "TTGG", - "7": "AATT", - "8": "CCGG" - } - }, - "substitutions": { } - } - } - """ - - Then the tag layout on the plate "Testing the tagging" should be: - | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | - | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | - | TTTT | TTTT | TTTT | TTTT | TTTT | TTTT | TTTT | TTTT | TTTT | TTTT | TTTT | TTTT | - | GGGG | GGGG | GGGG | GGGG | GGGG | GGGG | GGGG | GGGG | GGGG | GGGG | GGGG | GGGG | - | AACC | AACC | AACC | AACC | AACC | AACC | AACC | AACC | AACC | AACC | AACC | AACC | - | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | - | AATT | AATT | AATT | AATT | AATT | AATT | AATT | AATT | AATT | AATT | AATT | AATT | - | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | - - @tag_layout @create @barcode-service - Scenario: Creating a tag layout where the pools are awkwardly sized and cause overlaps - Given the Baracoda barcode service returns "SQPD-1000001" - Given the Baracoda barcode service returns "SQPD-1000002" - - Given the tag layout template "Test tag layout" exists - And the UUID for the tag layout template "Test tag layout" is "00000000-1111-2222-3333-444444444444" - And the tag group for tag layout template "Test tag layout" is called "Tag group 1" - And the tag group for tag layout template "Test tag layout" contains the following tags: - | index | oligo | - | 1 | AAAA | - | 2 | CCCC | - | 3 | TTTT | - | 4 | GGGG | - | 5 | AACC | - | 6 | TTGG | - | 7 | AATT | - | 8 | CCGG | - | 9 | GAGA | - | 10 | CACA | - And the UUID of the next tag layout created will be "00000000-1111-2222-3333-000000000002" - - Given a "Stock plate" plate called "Testing the API" exists - And the UUID for the plate "Testing the API" is "11111111-2222-3333-4444-000000000002" - And all wells on the plate "Testing the API" have unique samples - - Given a "Stock plate" plate called "Testing the tagging" exists - And the UUID for the plate "Testing the tagging" is "11111111-2222-3333-4444-000000000001" - And the wells for the plate "Testing the API" have been pooled to the plate "Testing the tagging" according to the pooling strategy 8, 2, 10, 4, 8, 2, 10, 4, 8, 2, 10, 4, 8, 8, 8 - - When I make an authorised POST with the following JSON to the API path "/00000000-1111-2222-3333-444444444444": - """ - { - "tag_layout": { - "plate": "11111111-2222-3333-4444-000000000001" - } - } - """ - Then the HTTP response should be "201 Created" - - And the JSON should match the following for the specified fields: - """ - { - "tag_layout": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-000000000002" - }, - "plate": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-000000000001" - } - }, - - "uuid": "00000000-1111-2222-3333-000000000002", - "direction": "column", - - "tag_group": { - "name": "Tag group 1", - "tags": { - "1": "AAAA", - "2": "CCCC", - "3": "TTTT", - "4": "GGGG", - "5": "AACC", - "6": "TTGG", - "7": "AATT", - "8": "CCGG" - } - }, - "substitutions": { } - } - } - """ - - Then the tag layout on the plate "Testing the tagging" should be: - | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | AAAA | - | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | CCCC | - | TTTT | TTTT | GAGA | TTTT | TTTT | GAGA | TTTT | TTTT | GAGA | TTTT | TTTT | TTTT | - | GGGG | GGGG | CACA | GGGG | GGGG | CACA | GGGG | GGGG | CACA | GGGG | GGGG | GGGG | - | AACC | AACC | AACC | AACC | AACC | AACC | AACC | AACC | AACC | AACC | AACC | AACC | - | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | TTGG | - | AATT | AATT | AATT | AATT | AATT | AATT | AATT | AATT | AATT | AATT | AATT | AATT | - | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | CCGG | - - @tag_layout @create @barcode-service - Scenario: Creating a tag layout of an entire plate using 96 tags - Given the Baracoda barcode service returns "SQPD-1000001" - Given the Baracoda barcode service returns "SQPD-1000002" - - Given the tag layout template "Test tag layout" exists - And the UUID for the tag layout template "Test tag layout" is "00000000-1111-2222-3333-444444444444" - And the tag group for tag layout template "Test tag layout" is called "Tag group 1" - And the tag group for tag layout template "Test tag layout" has 96 tags - And the UUID of the next tag layout created will be "00000000-1111-2222-3333-000000000002" - - Given a "Stock plate" plate called "Testing the API" exists - And the UUID for the plate "Testing the API" is "11111111-2222-3333-4444-000000000002" - And all wells on the plate "Testing the API" have unique samples - - Given a "Stock plate" plate called "Testing the tagging" exists - And the UUID for the plate "Testing the tagging" is "11111111-2222-3333-4444-000000000001" - And the wells for the plate "Testing the API" have been pooled to the plate "Testing the tagging" according to the pooling strategy 96 - - When I make an authorised POST with the following JSON to the API path "/00000000-1111-2222-3333-444444444444": - """ - { - "tag_layout": { - "plate": "11111111-2222-3333-4444-000000000001" - } - } - """ - Then the HTTP response should be "201 Created" - - Then the tag layout on the plate "Testing the tagging" should be: - | TAG1 | TAG9 | TAG17 | TAG25 | TAG33 | TAG41 | TAG49 | TAG57 | TAG65 | TAG73 | TAG81 | TAG89 | - | TAG2 | TAG10 | TAG18 | TAG26 | TAG34 | TAG42 | TAG50 | TAG58 | TAG66 | TAG74 | TAG82 | TAG90 | - | TAG3 | TAG11 | TAG19 | TAG27 | TAG35 | TAG43 | TAG51 | TAG59 | TAG67 | TAG75 | TAG83 | TAG91 | - | TAG4 | TAG12 | TAG20 | TAG28 | TAG36 | TAG44 | TAG52 | TAG60 | TAG68 | TAG76 | TAG84 | TAG92 | - | TAG5 | TAG13 | TAG21 | TAG29 | TAG37 | TAG45 | TAG53 | TAG61 | TAG69 | TAG77 | TAG85 | TAG93 | - | TAG6 | TAG14 | TAG22 | TAG30 | TAG38 | TAG46 | TAG54 | TAG62 | TAG70 | TAG78 | TAG86 | TAG94 | - | TAG7 | TAG15 | TAG23 | TAG31 | TAG39 | TAG47 | TAG55 | TAG63 | TAG71 | TAG79 | TAG87 | TAG95 | - | TAG8 | TAG16 | TAG24 | TAG32 | TAG40 | TAG48 | TAG56 | TAG64 | TAG72 | TAG80 | TAG88 | TAG96 | - - - @tag_layout @create @barcode-service - Scenario: Creating a tag layout where one of the wells is empty - Given the Baracoda barcode service returns "SQPD-1000001" - Given the Baracoda barcode service returns "SQPD-1000002" - - Given the tag layout template "Test tag layout" exists - And the UUID for the tag layout template "Test tag layout" is "00000000-1111-2222-3333-444444444444" - And the tag group for tag layout template "Test tag layout" is called "Tag group 1" - And the tag group for tag layout template "Test tag layout" has 96 tags - And the UUID of the next tag layout created will be "00000000-1111-2222-3333-000000000002" - - Given a "Stock plate" plate called "Testing the API" exists - And the UUID for the plate "Testing the API" is "11111111-2222-3333-4444-000000000002" - And all wells on the plate "Testing the API" have unique samples - And H12 on the plate "Testing the API" is empty - - Given a "Stock plate" plate called "Testing the tagging" exists - And the UUID for the plate "Testing the tagging" is "11111111-2222-3333-4444-000000000001" - And the wells for the plate "Testing the API" have been pooled to the plate "Testing the tagging" according to the pooling strategy 95 - - When I make an authorised POST with the following JSON to the API path "/00000000-1111-2222-3333-444444444444": - """ - { - "tag_layout": { - "plate": "11111111-2222-3333-4444-000000000001" - } - } - """ - Then the HTTP response should be "201 Created" - - Then the tag layout on the plate "Testing the tagging" should be: - | TAG1 | TAG9 | TAG17 | TAG25 | TAG33 | TAG41 | TAG49 | TAG57 | TAG65 | TAG73 | TAG81 | TAG89 | - | TAG2 | TAG10 | TAG18 | TAG26 | TAG34 | TAG42 | TAG50 | TAG58 | TAG66 | TAG74 | TAG82 | TAG90 | - | TAG3 | TAG11 | TAG19 | TAG27 | TAG35 | TAG43 | TAG51 | TAG59 | TAG67 | TAG75 | TAG83 | TAG91 | - | TAG4 | TAG12 | TAG20 | TAG28 | TAG36 | TAG44 | TAG52 | TAG60 | TAG68 | TAG76 | TAG84 | TAG92 | - | TAG5 | TAG13 | TAG21 | TAG29 | TAG37 | TAG45 | TAG53 | TAG61 | TAG69 | TAG77 | TAG85 | TAG93 | - | TAG6 | TAG14 | TAG22 | TAG30 | TAG38 | TAG46 | TAG54 | TAG62 | TAG70 | TAG78 | TAG86 | TAG94 | - | TAG7 | TAG15 | TAG23 | TAG31 | TAG39 | TAG47 | TAG55 | TAG63 | TAG71 | TAG79 | TAG87 | TAG95 | - | TAG8 | TAG16 | TAG24 | TAG32 | TAG40 | TAG48 | TAG56 | TAG64 | TAG72 | TAG80 | TAG88 | | diff --git a/features/api/tag_layouts.feature b/features/api/tag_layouts.feature deleted file mode 100644 index e50694c94e..0000000000 --- a/features/api/tag_layouts.feature +++ /dev/null @@ -1,181 +0,0 @@ -@api @json @tag_layout @single-sign-on @new-api -Feature: Access tag layouts through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to create, read and update individual tag layouts through their UUID - And I want to be able to perform other operations to individual tag layouts - And I want to be able to do all of this only knowing the UUID of a tag layout - And I understand I will never be able to delete a tag layout through its UUID - - Background: - Given all of this is happening at exactly "23-Oct-2010 23:00:00+01:00" - - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API - And I have a "full" authorised user with the key "cucumber" - Given a user with UUID "99999999-8888-7777-6666-555555555555" exists - - @read - Scenario: Reading the JSON for a UUID - Given the tag layout exists with ID 1 - And the UUID for the tag layout with ID 1 is "00000000-1111-2222-3333-444444444444" - And the tag group for tag layout with ID 1 is called "Example Tag Group" - And the UUID for the plate associated with the tag layout with ID 1 is "11111111-2222-3333-4444-000000000001" - - When I GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "tag_layout": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - "plate": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-000000000001" - } - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - "direction": "column", - "walking_by": "wells of plate", - - "tag_group": { - "name": "Example Tag Group", - "tags": { - "1": "ACGT", - "2": "TGCA" - } - }, - "substitutions": { } - } - } - """ - - - @tag_layout @create @barcode-service - Scenario: Creating a tag layout of an entire plate using 96 tags by pools - Given the Baracoda barcode service returns "SQPD-1000001" - Given the Baracoda barcode service returns "SQPD-1000002" - - Given the tag group "Example Tag Group" exists - And the UUID for the tag group "Example Tag Group" is "00000000-1111-2222-3333-444444444444" - And the tag group "Example Tag Group" has 96 tags - Given a "Stock plate" plate called "Testing the API" exists - And the UUID for the plate "Testing the API" is "11111111-2222-3333-4444-000000000002" - And all wells on the plate "Testing the API" have unique samples - - Given a "Stock plate" plate called "Testing the tagging" exists - And the UUID for the plate "Testing the tagging" is "11111111-2222-3333-4444-000000000001" - And the wells for the plate "Testing the API" have been pooled to the plate "Testing the tagging" according to the pooling strategy 12, 8, 20, 12, 8, 20, 16 - - When I make an authorised POST with the following JSON to the API path "/tag_layouts": - """ - { - "tag_layout": { - "plate": "11111111-2222-3333-4444-000000000001", - "user": "99999999-8888-7777-6666-555555555555", - "tag_group": "00000000-1111-2222-3333-444444444444", - "direction": "column", - "walking_by": "manual by plate", - "initial_tag": 0 - } - } - """ - Then the HTTP response should be "201 Created" - - Then the tag layout on the plate "Testing the tagging" should be: - | TAG1 | TAG9 | TAG17 | TAG25 | TAG33 | TAG41 | TAG49 | TAG57 | TAG65 | TAG73 | TAG81 | TAG89 | - | TAG2 | TAG10 | TAG18 | TAG26 | TAG34 | TAG42 | TAG50 | TAG58 | TAG66 | TAG74 | TAG82 | TAG90 | - | TAG3 | TAG11 | TAG19 | TAG27 | TAG35 | TAG43 | TAG51 | TAG59 | TAG67 | TAG75 | TAG83 | TAG91 | - | TAG4 | TAG12 | TAG20 | TAG28 | TAG36 | TAG44 | TAG52 | TAG60 | TAG68 | TAG76 | TAG84 | TAG92 | - | TAG5 | TAG13 | TAG21 | TAG29 | TAG37 | TAG45 | TAG53 | TAG61 | TAG69 | TAG77 | TAG85 | TAG93 | - | TAG6 | TAG14 | TAG22 | TAG30 | TAG38 | TAG46 | TAG54 | TAG62 | TAG70 | TAG78 | TAG86 | TAG94 | - | TAG7 | TAG15 | TAG23 | TAG31 | TAG39 | TAG47 | TAG55 | TAG63 | TAG71 | TAG79 | TAG87 | TAG95 | - | TAG8 | TAG16 | TAG24 | TAG32 | TAG40 | TAG48 | TAG56 | TAG64 | TAG72 | TAG80 | TAG88 | TAG96 | - - @tag_layout @create @barcode-service - Scenario: Creating a tag layout of an entire plate using 96 tags by pools with empty wells - Given the Baracoda barcode service returns "SQPD-1000001" - Given the Baracoda barcode service returns "SQPD-1000002" - Given the tag group "Example Tag Group" exists - And the UUID for the tag group "Example Tag Group" is "00000000-1111-2222-3333-444444444444" - And the tag group "Example Tag Group" has 96 tags - Given a "Stock plate" plate called "Testing the API" exists - And the UUID for the plate "Testing the API" is "11111111-2222-3333-4444-000000000002" - And all wells on the plate "Testing the API" have unique samples - - Given a "Stock plate" plate called "Testing the tagging" exists - And the UUID for the plate "Testing the tagging" is "11111111-2222-3333-4444-000000000001" - And the wells for the plate "Testing the API" have been pooled to the plate "Testing the tagging" according to the pooling strategy 12, 8, 20, 12, 8, 20, 16 - And well "B6" on the plate "Testing the tagging" is empty - - When I make an authorised POST with the following JSON to the API path "/tag_layouts": - """ - { - "tag_layout": { - "plate": "11111111-2222-3333-4444-000000000001", - "user": "99999999-8888-7777-6666-555555555555", - "tag_group": "00000000-1111-2222-3333-444444444444", - "direction": "column", - "walking_by": "manual by plate", - "initial_tag": 0 - } - } - """ - Then the HTTP response should be "201 Created" - - Then the tag layout on the plate "Testing the tagging" should be: - | TAG1 | TAG9 | TAG17 | TAG25 | TAG33 | TAG41 | TAG48 | TAG56 | TAG64 | TAG72 | TAG80 | TAG88 | - | TAG2 | TAG10 | TAG18 | TAG26 | TAG34 | | TAG49 | TAG57 | TAG65 | TAG73 | TAG81 | TAG89 | - | TAG3 | TAG11 | TAG19 | TAG27 | TAG35 | TAG42 | TAG50 | TAG58 | TAG66 | TAG74 | TAG82 | TAG90 | - | TAG4 | TAG12 | TAG20 | TAG28 | TAG36 | TAG43 | TAG51 | TAG59 | TAG67 | TAG75 | TAG83 | TAG91 | - | TAG5 | TAG13 | TAG21 | TAG29 | TAG37 | TAG44 | TAG52 | TAG60 | TAG68 | TAG76 | TAG84 | TAG92 | - | TAG6 | TAG14 | TAG22 | TAG30 | TAG38 | TAG45 | TAG53 | TAG61 | TAG69 | TAG77 | TAG85 | TAG93 | - | TAG7 | TAG15 | TAG23 | TAG31 | TAG39 | TAG46 | TAG54 | TAG62 | TAG70 | TAG78 | TAG86 | TAG94 | - | TAG8 | TAG16 | TAG24 | TAG32 | TAG40 | TAG47 | TAG55 | TAG63 | TAG71 | TAG79 | TAG87 | TAG95 | - - - @tag_layout @create @barcode-service - Scenario: Creating a tag layout of an entire plate using 96 tags by pools with an offset - Given the Baracoda barcode service returns "SQPD-1000001" - Given the Baracoda barcode service returns "SQPD-1000002" - Given the tag group "Example Tag Group" exists - And the UUID for the tag group "Example Tag Group" is "00000000-1111-2222-3333-444444444444" - And the tag group "Example Tag Group" has 106 tags - - Given a "Stock plate" plate called "Testing the API" exists - And the UUID for the plate "Testing the API" is "11111111-2222-3333-4444-000000000002" - And all wells on the plate "Testing the API" have unique samples - - Given a "Stock plate" plate called "Testing the tagging" exists - And the UUID for the plate "Testing the tagging" is "11111111-2222-3333-4444-000000000001" - And the wells for the plate "Testing the API" have been pooled to the plate "Testing the tagging" according to the pooling strategy 12, 8, 20, 12, 8, 20, 16 - - When I make an authorised POST with the following JSON to the API path "/tag_layouts": - """ - { - "tag_layout": { - "plate": "11111111-2222-3333-4444-000000000001", - "user": "99999999-8888-7777-6666-555555555555", - "tag_group": "00000000-1111-2222-3333-444444444444", - "direction": "column", - "walking_by": "manual by plate", - "initial_tag": 10 - } - } - """ - Then the HTTP response should be "201 Created" - - Then the tag layout on the plate "Testing the tagging" should be: - | TAG11 | TAG19 | TAG27 | TAG35 | TAG43 | TAG51 | TAG59 | TAG67 | TAG75 | TAG83 | TAG91 | TAG99 | - | TAG12 | TAG20 | TAG28 | TAG36 | TAG44 | TAG52 | TAG60 | TAG68 | TAG76 | TAG84 | TAG92 | TAG100 | - | TAG13 | TAG21 | TAG29 | TAG37 | TAG45 | TAG53 | TAG61 | TAG69 | TAG77 | TAG85 | TAG93 | TAG101 | - | TAG14 | TAG22 | TAG30 | TAG38 | TAG46 | TAG54 | TAG62 | TAG70 | TAG78 | TAG86 | TAG94 | TAG102 | - | TAG15 | TAG23 | TAG31 | TAG39 | TAG47 | TAG55 | TAG63 | TAG71 | TAG79 | TAG87 | TAG95 | TAG103 | - | TAG16 | TAG24 | TAG32 | TAG40 | TAG48 | TAG56 | TAG64 | TAG72 | TAG80 | TAG88 | TAG96 | TAG104 | - | TAG17 | TAG25 | TAG33 | TAG41 | TAG49 | TAG57 | TAG65 | TAG73 | TAG81 | TAG89 | TAG97 | TAG105 | - | TAG18 | TAG26 | TAG34 | TAG42 | TAG50 | TAG58 | TAG66 | TAG74 | TAG82 | TAG90 | TAG98 | TAG106 | diff --git a/features/api/tag_qc/lot_types.feature b/features/api/tag_qc/lot_types.feature deleted file mode 100644 index c2a685accc..0000000000 --- a/features/api/tag_qc/lot_types.feature +++ /dev/null @@ -1,97 +0,0 @@ -@api @json @single-sign-on @new-api -Feature: Access lots through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to create, read and update individual lots through their UUID - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - Given I have a lot type for testing called "Test Lot Type" - And the UUID for the lot type "Test Lot Type" is "11111111-2222-3333-4444-555555555555" - Given the tag layout template "Test tag layout" exists - And the UUID for the tag layout template "Test tag layout" is "00000000-1111-2222-3333-666666666666" - And the tag group for tag layout template "Test tag layout" is called "Tag group 1" - And the tag group for tag layout template "Test tag layout" contains the following tags: - | index | oligo | - | 1 | ACTG | - | 2 | GTCA | - - @read @authorised - Scenario: Reading the JSON for a UUID - - When I make an authorised GET of the API path "/11111111-2222-3333-4444-555555555555" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "lot_type": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-555555555555" - }, - - "name": "Test Lot Type", - "template_class": "TagLayoutTemplate", - - "uuid": "11111111-2222-3333-4444-555555555555" - } - } - """ - - - @create @authorised @barcode-service - Scenario: Creating a lot - Given the UUID of the next lot created will be "00000000-1111-2222-3333-444444444444" - And a user with UUID "99999999-8888-7777-6666-555555555555" exists - - When I make an authorised POST with the following JSON to the API path "/11111111-2222-3333-4444-555555555555/lots": - """ - { - "lot": { - "lot_number": "1234567890", - "user": "99999999-8888-7777-6666-555555555555", - "received_at": "2014-02-01", - "template": "00000000-1111-2222-3333-666666666666" - } - } - """ - Then the HTTP response should be "201 Created" - - And the JSON should match the following for the specified fields: - """ - { - "lot": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - "lot_type": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-555555555555" - } - }, - "template": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-666666666666" - } - }, - "qcables": { - "size": 0, - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/qcables" - } - }, - - "template_name": "Test tag layout", - "lot_type_name": "Test Lot Type", - "lot_number": "1234567890", - "received_at": "2014-02-01", - - "uuid": "00000000-1111-2222-3333-444444444444" - } - } - """ - diff --git a/features/api/tag_qc/lots.feature b/features/api/tag_qc/lots.feature deleted file mode 100644 index 561fb9e7dd..0000000000 --- a/features/api/tag_qc/lots.feature +++ /dev/null @@ -1,144 +0,0 @@ -@api @json @single-sign-on @new-api -Feature: Access lots through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to create, read and update individual lots through their UUID - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - Given I have a lot type for testing called "Test Lot Type" - And the UUID for the lot type "Test Lot Type" is "11111111-2222-3333-4444-555555555555" - Given the tag layout template "Test tag layout" exists - And the UUID for the tag layout template "Test tag layout" is "00000000-1111-2222-3333-666666666666" - And the tag group for tag layout template "Test tag layout" is called "Tag group 1" - And the tag group for tag layout template "Test tag layout" contains the following tags: - | index | oligo | - | 1 | ACTG | - | 2 | GTCA | - Given the lot exists with the attributes: - | lot_number | lot_type | received_at | template | - | 1234567890 | Test Lot Type | 2014-02-01 | Test tag layout | - And the UUID for the lot with lot number "1234567890" is "00000000-1111-2222-3333-444444444444" - - @read @authorised - Scenario: Reading the JSON for a UUID - - When I make an authorised GET of the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "lot": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - "lot_type": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-555555555555" - } - }, - "template": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-666666666666" - } - }, - "qcables": { - "size": 0, - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/qcables" - } - }, - - "template_name": "Test tag layout", - "lot_type_name": "Test Lot Type", - "lot_number": "1234567890", - "received_at": "2014-02-01", - - "uuid": "00000000-1111-2222-3333-444444444444" - } - } - """ - - - @create @authorised @barcode-service - Scenario: Creating a qcables - Given the UUID of the next qcable created will be "55555555-6666-7777-8888-000000000001" - And the UUID of the next qcable creator created will be "55555555-6666-7777-8888-000000000002" - And a user with UUID "99999999-8888-7777-6666-555555555555" exists - - Given the Baracoda barcode service returns "SQPD-1000001" - - When I make an authorised POST with the following JSON to the API path "/qcable_creators": - """ - { - "qcable_creator": { - "lot": "00000000-1111-2222-3333-444444444444", - "user": "99999999-8888-7777-6666-555555555555", - "count": 1 - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "qcable_creator": { - "actions": { - "read": "http://www.example.com/api/1/55555555-6666-7777-8888-000000000002" - }, - "lot": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - } - }, - "qcables": { - "size": 1, - "actions": { - "read": "http://www.example.com/api/1/55555555-6666-7777-8888-000000000002/qcables" - } - } - - } - } - """ - When I make an authorised GET of the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "lot": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - "lot_type": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-555555555555" - } - }, - "template": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-666666666666" - } - }, - "qcables": { - "size": 1, - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/qcables" - } - }, - - "template_name": "Test tag layout", - "lot_type_name": "Test Lot Type", - "lot_number": "1234567890", - "received_at": "2014-02-01", - - "uuid": "00000000-1111-2222-3333-444444444444" - } - } - """ - diff --git a/features/api/tag_qc/plate_conversion.feature b/features/api/tag_qc/plate_conversion.feature deleted file mode 100644 index 208460088a..0000000000 --- a/features/api/tag_qc/plate_conversion.feature +++ /dev/null @@ -1,61 +0,0 @@ -@api @json @plate_creation @single-sign-on @new-api @barcode-service -Feature: Access plate conversions through the API - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - Given a user with UUID "99999999-8888-7777-6666-555555555555" exists - - Given a plate purpose called "Parent plate purpose" with UUID "11111111-2222-3333-4444-000000000001" - And a plate purpose called "Child plate purpose" with UUID "11111111-2222-3333-4444-000000000002" - And a plate purpose called "Original plate purpose" with UUID "11111111-2222-3333-4444-000000000003" - Given a "Parent plate purpose" plate called "Testing the API" exists with barcode "SQPD-1000001" - And the UUID for the plate "Testing the API" is "00000000-1111-2222-3333-000000000001" - Given a "Original plate purpose" plate called "Converted Plate" exists with barcode "SQPD-1000002" - And the UUID for the plate "Converted Plate" is "00000000-1111-2222-3333-000000000002" - - @create - Scenario: Creating a plate conversion - Given the UUID of the next plate conversion created will be "55555555-6666-7777-8888-000000000001" - - When I make an authorised POST with the following JSON to the API path "/plate_conversions": - """ - { - "plate_conversion": { - "user": "99999999-8888-7777-6666-555555555555", - "target": "00000000-1111-2222-3333-000000000002", - "parent": "00000000-1111-2222-3333-000000000001", - "purpose": "11111111-2222-3333-4444-000000000002" - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "plate_conversion": { - "actions": { - "read": "http://www.example.com/api/1/55555555-6666-7777-8888-000000000001" - }, - "target": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-000000000002" - } - }, - "purpose": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-000000000002" - } - }, - - "uuid": "55555555-6666-7777-8888-000000000001" - } - } - """ - - Then the plate "Converted Plate" has the parent "Testing the API" - diff --git a/features/api/tag_qc/qc_decision.feature b/features/api/tag_qc/qc_decision.feature deleted file mode 100644 index 5f7a371efe..0000000000 --- a/features/api/tag_qc/qc_decision.feature +++ /dev/null @@ -1,76 +0,0 @@ -@api @json @single-sign-on @new-api -Feature: Access stamps through the API - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - Given I have a lot type for testing called "Test Lot Type" - And the UUID for the lot type "Test Lot Type" is "11111111-2222-3333-4444-555555555555" - Given the tag layout template "Test tag layout" exists - And the UUID for the tag layout template "Test tag layout" is "00000000-1111-2222-3333-666666666666" - And the tag group for tag layout template "Test tag layout" is called "Tag group 1" - And the tag group for tag layout template "Test tag layout" contains the following tags: - | index | oligo | - | 1 | ACTG | - | 2 | GTCA | - Given the lot exists with the attributes: - | lot_number | lot_type | received_at | template | - | 1234567890 | Test Lot Type | 2014-02-01 | Test tag layout | - And the UUID for the lot with lot number "1234567890" is "00000000-1111-2222-3333-444444444444" - - Given the Baracoda barcode service returns "SQPD-1000001" - And the Baracoda barcode service returns "SQPD-1000002" - - And lot "1234567890" has 2 created qcables - And all qcables in lot "1234567890" are "pending" - And all qcables have sequential UUIDs based on "55555555-6666-7777-8888-00000000001" - - @create @authorised @barcode-service - Scenario: Creating a Qc Decisions - Given a user with UUID "99999999-8888-7777-6666-555555555555" exists - And the user with UUID "99999999-8888-7777-6666-555555555555" is a 'qa_manager' - - Given the UUID of the next qc decision created will be "55555555-6666-7777-8888-000000000003" - - - When I make an authorised POST with the following JSON to the API path "/qc_decisions": - """ - { - "qc_decision": { - "user": "99999999-8888-7777-6666-555555555555", - "lot": "00000000-1111-2222-3333-444444444444", - "decisions": [ - {"qcable":"55555555-6666-7777-8888-000000000011","decision":"release"}, - {"qcable":"55555555-6666-7777-8888-000000000012","decision":"release"} - ] - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "qc_decision": { - "actions": { - "read": "http://www.example.com/api/1/55555555-6666-7777-8888-000000000003" - }, - "qcables": { - "size": 2, - "actions": { - "read": "http://www.example.com/api/1/55555555-6666-7777-8888-000000000003/qcables" - } - }, - "user": { - "actions": { - "read": "http://www.example.com/api/1/99999999-8888-7777-6666-555555555555" - } - } - } - } - """ - And the qcables in lot "1234567890" should be "available" - diff --git a/features/api/tag_qc/qcable_order.feature b/features/api/tag_qc/qcable_order.feature deleted file mode 100644 index 5fd65b3c20..0000000000 --- a/features/api/tag_qc/qcable_order.feature +++ /dev/null @@ -1,88 +0,0 @@ -@api @json @single-sign-on @new-api @barcode-service -Feature: Access lots through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to create, read and update individual lots through their UUID - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - Given I have a lot type for testing called "Test Lot Type" - And the UUID for the lot type "Test Lot Type" is "11111111-2222-3333-4444-555555555555" - Given the tag layout template "Test tag layout" exists - And the UUID for the tag layout template "Test tag layout" is "00000000-1111-2222-3333-666666666666" - And the tag group for tag layout template "Test tag layout" is called "Tag group 1" - And the tag group for tag layout template "Test tag layout" contains the following tags: - | index | oligo | - | 1 | ACTG | - | 2 | GTCA | - Given the lot exists with the attributes: - | lot_number | lot_type | received_at | template | - | 1234567890 | Test Lot Type | 2014-02-01 | Test tag layout | - And the UUID for the lot with lot number "1234567890" is "00000000-1111-2222-3333-444444444444" - - Given I am set up for testing qcable ordering - - @read @authorised - Scenario: The lots should be sorted properly - - Given the number of results returned by the API per page is 6 - When I make an authorised GET of the API path "/00000000-1111-2222-3333-444444444444/qcables" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/qcables/1", - "first": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/qcables/1", - "last": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/qcables/1" - }, - "size": 6, - "qcables": [ - { - "updated_at": "2010-10-23 23:00:00 +0100", - "barcode": {"machine": "SQPD-1000001"}, - "state": "pending", - "stamp_index": 0, - "stamp_bed": "1" - }, - { - "barcode": {"machine": "SQPD-1000002"}, - "state": "created", - "stamp_index": null, - "stamp_bed": null - }, - { - "updated_at": "2010-10-23 23:20:00 +0100", - "barcode": {"machine": "SQPD-1000003"}, - "state": "pending", - "stamp_index": 3, - "stamp_bed": "3" - }, - { - "updated_at": "2010-10-23 23:20:00 +0100", - "barcode": {"machine": "SQPD-1000004"}, - "state": "pending", - "stamp_index": 2, - "stamp_bed": "5" - }, - { - "updated_at": "2010-10-23 23:00:00 +0100", - "barcode": {"machine": "SQPD-1000005"}, - "state": "pending", - "stamp_index": 1, - "stamp_bed": "2" - }, - { - "barcode": {"machine": "SQPD-1000006"}, - "state": "created", - "stamp_index": null, - "stamp_bed": null - } - ] - } - """ diff --git a/features/api/tag_qc/robots.feature b/features/api/tag_qc/robots.feature deleted file mode 100644 index 6cca9a2a13..0000000000 --- a/features/api/tag_qc/robots.feature +++ /dev/null @@ -1,41 +0,0 @@ -@api @json @single-sign-on @new-api -Feature: Access robots through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to read individual robots through their UUID - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - Given I have a robot for testing called "Marvin" - And the UUID for the robot "Marvin" is "11111111-2222-3333-4444-555555555555" - - @read - Scenario: Reading the JSON for a UUID - - When I make an authorised GET of the API path "/11111111-2222-3333-4444-555555555555" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "robot": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-555555555555" - }, - - "name": "Marvin", - "robot_properties": { - "max_plates" : "3", - "SCRC1":"20001", - "DEST1":"20002", - "DEST2":"20003" - }, - - "uuid": "11111111-2222-3333-4444-555555555555" - } - } - """ diff --git a/features/api/tag_qc/stamps.feature b/features/api/tag_qc/stamps.feature deleted file mode 100644 index 6da906e78d..0000000000 --- a/features/api/tag_qc/stamps.feature +++ /dev/null @@ -1,80 +0,0 @@ -@api @json @single-sign-on @new-api -Feature: Access stamps through the API - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - Given I have a lot type for testing called "Test Lot Type" - And the UUID for the lot type "Test Lot Type" is "11111111-2222-3333-4444-555555555555" - Given the tag layout template "Test tag layout" exists - And the UUID for the tag layout template "Test tag layout" is "00000000-1111-2222-3333-666666666666" - And the tag group for tag layout template "Test tag layout" is called "Tag group 1" - And the tag group for tag layout template "Test tag layout" contains the following tags: - | index | oligo | - | 1 | ACTG | - | 2 | GTCA | - Given the lot exists with the attributes: - | lot_number | lot_type | received_at | template | - | 1234567890 | Test Lot Type | 2014-02-01 | Test tag layout | - And the UUID for the lot with lot number "1234567890" is "00000000-1111-2222-3333-444444444444" - - - Given the Baracoda barcode service returns "SQPD-1000001" - And the Baracoda barcode service returns "SQPD-1000002" - - And lot "1234567890" has 2 created qcables - And all qcables have sequential UUIDs based on "55555555-6666-7777-8888-00000000001" - - Given the UUID of the next stamp created will be "55555555-6666-7777-8888-000000000003" - Given the UUID of the next robot created will be "55555555-6666-7777-8888-000000000004" - And a robot exists - - @create @authorised @barcode-service - Scenario: Creating a stamp - Given a user with UUID "99999999-8888-7777-6666-555555555555" exists - - - When I make an authorised POST with the following JSON to the API path "/stamps": - """ - { - "stamp": { - "tip_lot": "12345", - "user": "99999999-8888-7777-6666-555555555555", - "robot": "55555555-6666-7777-8888-000000000004", - "lot": "00000000-1111-2222-3333-444444444444", - "stamp_details": [ - {"bed":"1", "order":2, "qcable":"55555555-6666-7777-8888-000000000011"}, - {"bed":"2", "order":1, "qcable":"55555555-6666-7777-8888-000000000012"} - ] - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "stamp": { - "actions": { - "read": "http://www.example.com/api/1/55555555-6666-7777-8888-000000000003" - }, - "qcables": { - "size": 2, - "actions": { - "read": "http://www.example.com/api/1/55555555-6666-7777-8888-000000000003/qcables" - } - }, - "user": { - "actions": { - "read": "http://www.example.com/api/1/99999999-8888-7777-6666-555555555555" - } - }, - "tip_lot": "12345" - } - } - """ - And the qcables in lot "1234567890" should be "pending" - diff --git a/features/api/tag_qc/state_change.feature b/features/api/tag_qc/state_change.feature deleted file mode 100644 index a9d18323e8..0000000000 --- a/features/api/tag_qc/state_change.feature +++ /dev/null @@ -1,79 +0,0 @@ -@api @json @single-sign-on @new-api @barcode-service -Feature: Access lots through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to create, read and update individual lots through their UUID - - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - Given I have a lot type for testing called "Test Lot Type" - And the UUID for the lot type "Test Lot Type" is "11111111-2222-3333-4444-555555555555" - Given the tag layout template "Test tag layout" exists - And the UUID for the tag layout template "Test tag layout" is "00000000-1111-2222-3333-666666666666" - And the tag group for tag layout template "Test tag layout" is called "Tag group 1" - And the tag group for tag layout template "Test tag layout" contains the following tags: - | index | oligo | - | 1 | ACTG | - | 2 | GTCA | - Given the lot exists with the attributes: - | lot_number | lot_type | received_at | template | - | 1234567890 | Test Lot Type | 2014-02-01 | Test tag layout | - And the UUID for the lot with lot number "1234567890" is "00000000-1111-2222-3333-444444444444" - Given I have a qcable - - @read @authorised @barcode-service - Scenario: Plates Should Inherit state form their qcable - When I make an authorised GET of the API path "/55555555-6666-7777-8888-000000000004" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "plate": { - "actions": { - "read": "http://www.example.com/api/1/55555555-6666-7777-8888-000000000004" - }, - "state": "created" - } - } - """ - @create @read @authorised - Scenario: Plates should update their state on state change - Given a user with UUID "99999999-8888-7777-6666-555555555555" exists - And all qcables in lot "1234567890" are "available" - Given the UUID of the next state change created will be "55555555-6666-7777-8888-000000000003" - When I make an authorised POST with the following JSON to the API path "/state_changes": - """ - { - "state_change": { - "user": "99999999-8888-7777-6666-555555555555", - "target": "55555555-6666-7777-8888-000000000004", - "target_state": "destroyed", - "reason": "testing this works" - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "state_change": { - "actions": { - "read": "http://www.example.com/api/1/55555555-6666-7777-8888-000000000003" - }, - "target": { - "actions": { - "read": "http://www.example.com/api/1/55555555-6666-7777-8888-000000000004" - } - }, - "target_state": "destroyed", - "previous_state": "available", - "reason": "testing this works" - } - } - """ - And the qcables in lot "1234567890" should be "destroyed" diff --git a/features/api/transfer_templates.feature b/features/api/transfer_templates.feature deleted file mode 100644 index 17ac5ec1c9..0000000000 --- a/features/api/transfer_templates.feature +++ /dev/null @@ -1,317 +0,0 @@ -@api @json @transfer_template @single-sign-on @new-api -Feature: Access transfer templates through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to create, read and update individual transfer templates through their UUID - And I want to be able to perform other operations to individual transfer templates - And I want to be able to do all of this only knowing the UUID of a transfer template - And I understand I will never be able to delete a transfer template through its UUID - - Background: - Given all of this is happening at exactly "23-Oct-2010 23:00:00+01:00" - - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API - And I have a "full" authorised user with the key "cucumber" - - @read - Scenario: Reading the JSON of a transfer template - Given the transfer template called "Test transfers" exists - And the UUID for the transfer template "Test transfers" is "00000000-1111-2222-3333-444444444444" - - When I GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "transfer_template": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - "name": "Test transfers", - "transfers": { - "A1": "A1", - "B1": "B1" - } - } - } - """ - - @read @authenticated - Scenario: Making an authenticated read for the JSON of a transfer template - Given the transfer template called "Test transfers" exists - And the UUID for the transfer template "Test transfers" is "00000000-1111-2222-3333-444444444444" - - When I make an authorised GET for the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "transfer_template": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444", - "create": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444", - "preview": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/preview" - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - "name": "Test transfers", - "transfers": { - "A1": "A1", - "B1": "B1" - } - } - } - """ - - @transfer @create @authenticated - Scenario: Creating a transfer from a transfer template - Given the transfer template called "Test transfers" exists - And the UUID for the transfer template "Test transfers" is "00000000-1111-2222-3333-444444444444" - - Given a transfer plate called "Source plate" exists - And the UUID for the plate "Source plate" is "11111111-2222-3333-4444-000000000001" - And a transfer plate called "Destination plate" exists - And the UUID for the plate "Destination plate" is "11111111-2222-3333-4444-000000000002" - - When I make an authorised POST with the following JSON to the API path "/00000000-1111-2222-3333-444444444444": - """ - { - "transfer": { - "source": "11111111-2222-3333-4444-000000000001", - "destination": "11111111-2222-3333-4444-000000000002" - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "transfer": { - "source": { - "uuid": "11111111-2222-3333-4444-000000000001" - }, - "destination": { - "uuid": "11111111-2222-3333-4444-000000000002" - }, - "transfers": { - "A1": "A1", - "B1": "B1" - } - } - } - """ - - Then the transfers from the plate "Source plate" to the plate "Destination plate" should be: - | source | destination | - | A1 | A1 | - | B1 | B1 | - - - @transfer @create @authenticated - Scenario: Creating a transfer from a transfer template where some source wells are empty - Given the transfer template called "Test transfers" exists - And the UUID for the transfer template "Test transfers" is "00000000-1111-2222-3333-444444444444" - - Given a transfer plate called "Source plate" exists - And the UUID for the plate "Source plate" is "11111111-2222-3333-4444-000000000001" - And the wells "A1-A1" on the plate "Source plate" are empty - And a transfer plate called "Destination plate" exists - And the UUID for the plate "Destination plate" is "11111111-2222-3333-4444-000000000002" - - When I make an authorised POST with the following JSON to the API path "/00000000-1111-2222-3333-444444444444": - """ - { - "transfer": { - "source": "11111111-2222-3333-4444-000000000001", - "destination": "11111111-2222-3333-4444-000000000002" - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "transfer": { - "source": { - "uuid": "11111111-2222-3333-4444-000000000001" - }, - "destination": { - "uuid": "11111111-2222-3333-4444-000000000002" - }, - "transfers": { - "B1": "B1" - } - } - } - """ - - Then the transfers from the plate "Source plate" to the plate "Destination plate" should be: - | source | destination | - | B1 | B1 | - - @transfer @create @authenticated - Scenario: Creating a transfer from a transfer template by pools - Given the pooling transfer template called "Test transfers" exists - And the UUID for the transfer template "Test transfers" is "00000000-1111-2222-3333-444444444444" - - Given a transfer plate called "Source plate" exists - And the UUID for the plate "Source plate" is "11111111-2222-3333-4444-000000000001" - And a transfer plate called "Destination plate" exists as a child of "Source plate" - And the UUID for the plate "Destination plate" is "11111111-2222-3333-4444-000000000002" - - Given "A1-B1" of the plate "Source plate" are part of the same submission - - When I make an authorised POST with the following JSON to the API path "/00000000-1111-2222-3333-444444444444": - """ - { - "transfer": { - "source": "11111111-2222-3333-4444-000000000001", - "destination": "11111111-2222-3333-4444-000000000002" - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "transfer": { - "source": { - "uuid": "11111111-2222-3333-4444-000000000001" - }, - "destination": { - "uuid": "11111111-2222-3333-4444-000000000002" - }, - "transfers": { - "A1": "A1", - "B1": "A1" - } - } - } - """ - - Then the transfers from the plate "Source plate" to the plate "Destination plate" should be: - | source | destination | - | A1 | A1 | - | B1 | A1 | - - @transfer @create @authenticated - Scenario: Creating a transfer from a transfer template by pools where some wells are empty - Given the pooling transfer template called "Test transfers" exists - And the UUID for the transfer template "Test transfers" is "00000000-1111-2222-3333-444444444444" - - Given a transfer plate called "Source plate" exists - And the UUID for the plate "Source plate" is "11111111-2222-3333-4444-000000000001" - And the wells "A1-A1" on the plate "Source plate" are empty - And a transfer plate called "Destination plate" exists as a child of "Source plate" - And the UUID for the plate "Destination plate" is "11111111-2222-3333-4444-000000000002" - - Given "A1-B1" of the plate "Source plate" are part of the same submission - - When I make an authorised POST with the following JSON to the API path "/00000000-1111-2222-3333-444444444444": - """ - { - "transfer": { - "source": "11111111-2222-3333-4444-000000000001", - "destination": "11111111-2222-3333-4444-000000000002" - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "transfer": { - "source": { - "uuid": "11111111-2222-3333-4444-000000000001" - }, - "destination": { - "uuid": "11111111-2222-3333-4444-000000000002" - }, - "transfers": { - "B1": "A1" - } - } - } - """ - - Then the transfers from the plate "Source plate" to the plate "Destination plate" should be: - | source | destination | - | B1 | A1 | - - @transfer @preview @authenticated - Scenario: Previewing a transfer from a transfer template - Given the transfer template called "Test transfers" exists - And the UUID for the transfer template "Test transfers" is "00000000-1111-2222-3333-444444444444" - - Given a transfer plate called "Source plate" exists - And the UUID for the plate "Source plate" is "11111111-2222-3333-4444-000000000001" - And a transfer plate called "Destination plate" exists - And the UUID for the plate "Destination plate" is "11111111-2222-3333-4444-000000000002" - - When I make an authorised POST with the following JSON to the API path "/00000000-1111-2222-3333-444444444444/preview": - """ - { - "transfer": { - "source": "11111111-2222-3333-4444-000000000001", - "destination": "11111111-2222-3333-4444-000000000002" - } - } - """ - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "transfer": { - "source": { - "uuid": "11111111-2222-3333-4444-000000000001" - }, - "destination": { - "uuid": "11111111-2222-3333-4444-000000000002" - }, - "transfers": { - "A1": "A1", - "B1": "B1" - } - } - } - """ - - @transfer @create @authenticated - Scenario: Creating a transfer from a transfer template by multiplex request automatically - Given the multiplex transfer template called "Test transfers" exists - And the UUID for the transfer template "Test transfers" is "00000000-1111-2222-3333-444444444444" - - Given a transfer plate called "Source plate" exists - And the plate "Source plate" is a "ILC Lib PCR-XP" - And the plate "Source plate" has additional wells - And the UUID for the plate "Source plate" is "11111111-2222-3333-4444-000000000001" - - Given "A1-B1" of the plate "Source plate" have been submitted to "Illumina-C Multiplex - HiSeq Paired end sequencing" - And "C1-D1" of the plate "Source plate" have been submitted to "Illumina-C Multiplex - HiSeq Paired end sequencing" - - And all multiplexed library tubes have sequential UUIDs based on "00000000-1111-2222-3333-9999" - - Given the UUID for the last transfer is "11111111-2222-3333-4444-000000000002" - When I GET the API path "/11111111-2222-3333-4444-000000000002" - Then the HTTP response should be "200 OK" - - And the JSON should match the following for the specified fields: - """ - { - "transfer": { - "source": { - "uuid": "11111111-2222-3333-4444-000000000001" - }, - "transfers": { - "C1": { "uuid": "00000000-1111-2222-3333-999900000002" }, - "D1": { "uuid": "00000000-1111-2222-3333-999900000002" } - } - } - } - """ - diff --git a/features/api/transfers.feature b/features/api/transfers.feature deleted file mode 100644 index 85a173f50e..0000000000 --- a/features/api/transfers.feature +++ /dev/null @@ -1,78 +0,0 @@ -@api @json @transfer @single-sign-on @new-api -Feature: Access transfers through the API - In order to actually be able to do anything useful - As an authenticated user of the API - I want to be able to create, read and update individual transfers through their UUID - And I want to be able to perform other operations to individual transfers - And I want to be able to do all of this only knowing the UUID of a transfer - And I understand I will never be able to delete a transfer through its UUID - - Background: - Given all of this is happening at exactly "23-Oct-2010 23:00:00+01:00" - - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - @read - Scenario: Reading the JSON for a transfer between two plates - Given the transfer between plates exists with ID 1 - And the UUID for the transfer between plates with ID 1 is "00000000-1111-2222-3333-444444444444" - And the UUID for the source of the transfer between plates with ID 1 is "11111111-2222-3333-4444-000000000001" - And the UUID for the destination of the transfer between plates with ID 1 is "11111111-2222-3333-4444-000000000002" - - When I GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "transfer": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - "source": { - "uuid": "11111111-2222-3333-4444-000000000001" - }, - "destination": { - "uuid": "11111111-2222-3333-4444-000000000002" - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - "transfers": { - "A1": "A1", - "B1": "B1" - } - } - } - """ - - @read - Scenario: Reading the JSON for a transfer from a plate to a tube - Given the transfer from plate to tube exists with ID 1 - And the UUID for the transfer from plate to tube with ID 1 is "00000000-1111-2222-3333-444444444444" - And the UUID for the source of the transfer from plate to tube with ID 1 is "11111111-2222-3333-4444-000000000001" - And the UUID for the destination of the transfer from plate to tube with ID 1 is "11111111-2222-3333-4444-000000000002" - - When I GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "transfer": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - "source": { - "uuid": "11111111-2222-3333-4444-000000000001" - }, - "destination": { - "uuid": "11111111-2222-3333-4444-000000000002" - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - "transfers": [ "A1", "B1", "C1" ] - } - } - """ diff --git a/features/api/uk10k/full_work_through.feature b/features/api/uk10k/full_work_through.feature deleted file mode 100644 index edecad2ae0..0000000000 --- a/features/api/uk10k/full_work_through.feature +++ /dev/null @@ -1,352 +0,0 @@ -@api @json @uk10k @cancer @order @submission @single-sign-on @new-api -Feature: Full run through of the UK10K submissions - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - Given I have an "active" study called "Testing submission creation" - And the UUID for the study "Testing submission creation" is "22222222-3333-4444-5555-000000000000" - - Given I have a project called "Testing submission creation" - And the UUID for the project "Testing submission creation" is "22222222-3333-4444-5555-000000000001" - - Given the UUID for the order template "Illumina-C - Library creation - Paired end sequencing" is "00000000-1111-2222-3333-444444444444" - And the UUID of the next submission created will be "11111111-2222-3333-4444-555555555555" - And the UUID of the next order created will be "11111111-2222-3333-4444-666666666666" - - Given the UUID for the request type "Illumina-C Library creation" is "99999999-1111-2222-3333-000000000000" - And the UUID for the request type "Illumina-C Paired end sequencing" is "99999999-1111-2222-3333-000000000001" - - @full-workflow @create @update @submit @read - Scenario: Create submission, attach assets, and then submit it - Given 3 sample tubes exist with names based on "sampletube" and IDs starting at 1 - And all sample tubes have receptacles with sequential UUIDs based on "33333333-4444-5555-6666" - - # Retrieving the order template ... - When I GET the API path "/00000000-1111-2222-3333-444444444444" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "order_template": { - "actions": { - "read": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444" - }, - "orders": { - "actions": { - "create": "http://www.example.com/api/1/00000000-1111-2222-3333-444444444444/orders" - } - }, - - "uuid": "00000000-1111-2222-3333-444444444444", - "name": "Illumina-C - Library creation - Paired end sequencing" - } - } - """ - - # Creating ... - When I POST the following JSON to the API path "/00000000-1111-2222-3333-444444444444/orders": - """ - { - "order": { - "project": "22222222-3333-4444-5555-000000000001", - "study": "22222222-3333-4444-5555-000000000000" - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "order": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-666666666666", - "update": "http://www.example.com/api/1/11111111-2222-3333-4444-666666666666" - }, - - "study": { - "actions": { - "read": "http://www.example.com/api/1/22222222-3333-4444-5555-000000000000" - }, - "name": "Testing submission creation" - }, - "project": { - "actions": { - "read": "http://www.example.com/api/1/22222222-3333-4444-5555-000000000001" - }, - "name": "Testing submission creation" - }, - - "assets": [], - - "request_types": [ - { - "uuid": "99999999-1111-2222-3333-000000000000", - "name": "Illumina-C Library creation" - }, - { - "uuid": "99999999-1111-2222-3333-000000000001", - "name": "Illumina-C Paired end sequencing" - } - ], - "request_options": {} - } - } - """ - And the JSON should not contain "uuids_to_ids" within any element of "order.request_types" - - # Attaching the assets and updating the details ... - When I PUT the following JSON to the API path "/11111111-2222-3333-4444-666666666666": - """ - { - "order": { - "assets": [ - "33333333-4444-5555-6666-000000000001", - "33333333-4444-5555-6666-000000000002", - "33333333-4444-5555-6666-000000000003" - ], - "request_options": { - "read_length": 76, - "fragment_size_required": { - "from": 100, - "to": 200 - }, - "library_type": "qPCR only" - } - } - } - """ - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "order": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-666666666666", - "update": "http://www.example.com/api/1/11111111-2222-3333-4444-666666666666" - }, - - "study": { - "actions": { - "read": "http://www.example.com/api/1/22222222-3333-4444-5555-000000000000" - }, - "name": "Testing submission creation" - }, - "project": { - "actions": { - "read": "http://www.example.com/api/1/22222222-3333-4444-5555-000000000001" - }, - "name": "Testing submission creation" - }, - - "assets": [ - { "uuid": "33333333-4444-5555-6666-000000000001" }, - { "uuid": "33333333-4444-5555-6666-000000000002" }, - { "uuid": "33333333-4444-5555-6666-000000000003" } - ], - - "request_types": [ - { - "uuid": "99999999-1111-2222-3333-000000000000", - "name": "Illumina-C Library creation" - }, - { - "uuid": "99999999-1111-2222-3333-000000000001", - "name": "Illumina-C Paired end sequencing" - } - ], - "request_options": { - "read_length": 76, - "fragment_size_required": { - "from": 100, - "to": 200 - }, - "library_type": "qPCR only" - } - } - } - """ - - # Create a submission - When I POST the following JSON to the API path "/submissions": - """ - { - "submission": { - "orders": [ - "11111111-2222-3333-4444-666666666666" - ] - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "submission": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-555555555555" - }, - "state": "building", - "orders": [ - { - "uuid": "11111111-2222-3333-4444-666666666666" - } - ], - "requests": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-555555555555/requests" - } - } - } - } - """ - - # Submitting the submission ... - When I POST the following JSON to the API path "/11111111-2222-3333-4444-555555555555/submit": - """ - """ - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "submission": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-555555555555" - }, - "state": "pending", - "orders": [ - { - "uuid": "11111111-2222-3333-4444-666666666666" - } - ], - "requests": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-555555555555/requests" - } - } - } - } - """ - - # Check that the submission can be processed and creates the correct information in the DB - Given all pending delayed jobs are processed - Then the submission with UUID "11111111-2222-3333-4444-555555555555" is ready - - # Now reload the submission JSON to see that the state is correct ... - Given the number of results returned by the API per page is 6 - When I GET the API path "/11111111-2222-3333-4444-555555555555" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "submission": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-555555555555" - }, - - "state": "ready", - "orders": [ - { - "uuid": "11111111-2222-3333-4444-666666666666" - } - ], - - "requests": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-555555555555/requests" - } - } - } - } - """ - - # And now we'll check that the requests are correct too ... - # ... there should be 3 library creation "requests": one per input asset (sample tube) - # ... there should be 3 paired end sequencing "requests": one per output asset from the above requests - When I GET the API path "/11111111-2222-3333-4444-555555555555/requests" - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "actions": { - "last": "http://www.example.com/api/1/11111111-2222-3333-4444-555555555555/requests/1", - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-555555555555/requests/1", - "first": "http://www.example.com/api/1/11111111-2222-3333-4444-555555555555/requests/1" - }, - "requests": [ - { - "source_asset": { - "uuid": "33333333-4444-5555-6666-000000000001", - "type": "sample_tubes" - }, - "target_asset": null, - - "fragment_size": { - "from": "100", - "to": "200" - }, - "type": "Illumina-C Library creation", - "library_type": "qPCR only" - }, { - "source_asset": { - "uuid": "33333333-4444-5555-6666-000000000002", - "type": "sample_tubes" - }, - "target_asset": null, - - "fragment_size": { - "from": "100", - "to": "200" - }, - "type": "Illumina-C Library creation", - "library_type": "qPCR only" - }, { - "source_asset": { - "uuid": "33333333-4444-5555-6666-000000000003", - "type": "sample_tubes" - }, - "target_asset": null, - - "fragment_size": { - "from": "100", - "to": "200" - }, - "type": "Illumina-C Library creation", - "library_type": "qPCR only" - }, { - "source_asset": null, - "target_asset": null, - - "read_length": 76, - "fragment_size": { - "from": "100", - "to": "200" - }, - "type": "Illumina-C Paired end sequencing" - }, { - "source_asset": null, - "target_asset": null, - - "read_length": 76, - "fragment_size": { - "from": "100", - "to": "200" - }, - "type": "Illumina-C Paired end sequencing" - }, { - "source_asset": null, - "target_asset": null, - - "read_length": 76, - "fragment_size": { - "from": "100", - "to": "200" - }, - "type": "Illumina-C Paired end sequencing" - } - ] - } - """ diff --git a/features/api/uk10k/orders.feature b/features/api/uk10k/orders.feature deleted file mode 100644 index aa56b8bd02..0000000000 --- a/features/api/uk10k/orders.feature +++ /dev/null @@ -1,671 +0,0 @@ -@api @json @uk10k @cancer @order @submission @single-sign-on @new-api -Feature: Creating orders for UK10K - Background: - Given all HTTP requests to the API have the cookie "WTSISignOn" set to "I-am-authenticated" - And the WTSI single sign-on service recognises "I-am-authenticated" as "John Smith" - - Given I am using the latest version of the API -And I have a "full" authorised user with the key "cucumber" - - Given I have an "active" study called "Testing submission creation" - And the UUID for the study "Testing submission creation" is "22222222-3333-4444-5555-000000000000" - - Given I have a project called "Testing submission creation" - And the UUID for the project "Testing submission creation" is "22222222-3333-4444-5555-000000000001" - - Given the UUID for the order template "Illumina-C - Library creation - Paired end sequencing" is "00000000-1111-2222-3333-444444444444" - And the UUID of the next submission created will be "11111111-2222-3333-4444-555555555555" - And the UUID of the next order created will be "11111111-2222-3333-4444-666666666666" - - Given the UUID for the request type "Illumina-C Library creation" is "99999999-1111-2222-3333-000000000000" - And the UUID for the request type "Illumina-C Paired end sequencing" is "99999999-1111-2222-3333-000000000001" - - @create @error - Scenario Outline: Creating a new order with missing initial information - When I POST the following JSON to the API path "/00000000-1111-2222-3333-444444444444/orders": - """ - { - "order": { - - } - } - """ - Then the HTTP response should be "422 Unprocessable Entity" - And the JSON should match the following for the specified fields: - """ - { - "content": { - "": [ "can't be blank" ] - } - } - """ - - Examples: - | field | json | - | study | "project": "22222222-3333-4444-5555-000000000001" | - | project | "study": "22222222-3333-4444-5555-000000000000" | - - @create - Scenario Outline: Creating a new order - When I POST the following JSON to the API path "/00000000-1111-2222-3333-444444444444/orders": - """ - { - "order": { - - "project": "22222222-3333-4444-5555-000000000001", - "study": "22222222-3333-4444-5555-000000000000" - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "order": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-666666666666", - "update": "http://www.example.com/api/1/11111111-2222-3333-4444-666666666666" - }, - "study": { - "actions": { - "read": "http://www.example.com/api/1/22222222-3333-4444-5555-000000000000" - }, - "name": "Testing submission creation" - }, - "project": { - "actions": { - "read": "http://www.example.com/api/1/22222222-3333-4444-5555-000000000001" - }, - "name": "Testing submission creation" - }, - "assets": [], - "request_types": [ - { - "uuid": "99999999-1111-2222-3333-000000000000", - "name": "Illumina-C Library creation" - }, - { - "uuid": "99999999-1111-2222-3333-000000000001", - "name": "Illumina-C Paired end sequencing" - } - ] - } - } - """ - - Examples: - | asset group details | asset group name | - | | 11111111-2222-3333-4444-555555555555 | - | "asset_group_name": "", | 11111111-2222-3333-4444-555555555555 | - | "asset_group_name": "new group", | new group | - - @create @asset_group - Scenario Outline: Creating a new order with an existing asset group - Given the study "Testing submission creation" has an asset group called "Existing asset group" - And the UUID for the asset group "Existing asset group" is "88888888-1111-2222-3333-000000000000" - - Given the sample tube named "Tube 1" exists - And the sample tube "Tube 1" is in the asset group "Existing asset group" - And the UUID for the receptacle in sample tube "Tube 1" is "99999999-1111-2222-3333-444444444444" - - When I POST the following JSON to the API path "/00000000-1111-2222-3333-444444444444/orders": - """ - { - "order": { - "project": "22222222-3333-4444-5555-000000000001", - "study": "22222222-3333-4444-5555-000000000000", - - } - } - """ - Then the HTTP response should be "201 Created" - And the JSON should match the following for the specified fields: - """ - { - "order": { - "actions": { - "read": "http://www.example.com/api/1/11111111-2222-3333-4444-666666666666", - "update": "http://www.example.com/api/1/11111111-2222-3333-4444-666666666666" - }, - "study": { - "actions": { - "read": "http://www.example.com/api/1/22222222-3333-4444-5555-000000000000" - }, - "name": "Testing submission creation" - }, - "project": { - "actions": { - "read": "http://www.example.com/api/1/22222222-3333-4444-5555-000000000001" - }, - "name": "Testing submission creation" - }, - "assets": [ - { - "uuid": "99999999-1111-2222-3333-444444444444" - } - ] - } - } - """ - - Examples: - | asset details | - | "asset_group_name": "Existing asset group" | - | "asset_group": "88888888-1111-2222-3333-000000000000" | - - @update @error @multiplier - Scenario Outline: Invalid request for multiple runs of different requests within an order - Given 3 sample tubes exist with names based on "sampletube" and IDs starting at 1 - And all sample tubes have sequential UUIDs based on "33333333-4444-5555-6666" - - Given I have an order created with the following details based on the template "Illumina-C - Library creation - Paired end sequencing": - | study | 22222222-3333-4444-5555-000000000000 | - | project | 22222222-3333-4444-5555-000000000001 | - | assets | 33333333-4444-5555-6666-000000000001 | - - When I PUT the following JSON to the API path "/11111111-2222-3333-4444-666666666666": - """ - { - "order": { - "request_options": { - "number_of_lanes": , - "fragment_size_required": { - "from": 100, - "to": 200 - } - } - } - } - """ - Then the HTTP response should be "422 Unprocessable Entity" - And the JSON should match the following for the specified fields: - """ - { - "content": { - "request_options": [ ] - } - } - """ - - Examples: - | number of lanes | message | - | 0 | "zero multiplier supplied" | - | -1 | "negative multiplier supplied" | - - @update @multiplier - Scenario Outline: Requesting multiple runs of different requests within an order - Given 3 sample tubes exist with names based on "sampletube" and IDs starting at 1 - And all sample tubes have sequential UUIDs based on "33333333-4444-5555-6666" - - Given I have an order created with the following details based on the template "Illumina-C - Library creation - Paired end sequencing": - | study | 22222222-3333-4444-5555-000000000000 | - | project | 22222222-3333-4444-5555-000000000001 | - | assets | 33333333-4444-5555-6666-000000000001 | - | request_options | read_length: 76, fragment_size_required_from: 100, fragment_size_required_to: 200, library_type: qPCR only | - - When I PUT the following JSON to the API path "/11111111-2222-3333-4444-666666666666": - """ - { - "order": { - "request_options": { - - - "read_length": 76, - "fragment_size_required": { - "from": 100, - "to": 200 - }, - "library_type": "qPCR only" - } - } - } - """ - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "order": { - "request_options": { - - - "read_length": 76, - "fragment_size_required": { - "from": 100, - "to": 200 - }, - "library_type": "qPCR only" - } - } - } - """ - - # Now check that after it's been process the submission has the correct requests - When the order with UUID "11111111-2222-3333-4444-666666666666" has been added to a submission - When the last submission has been submitted - Given all pending delayed jobs are processed - Then the submission with UUID "11111111-2222-3333-4444-555555555555" is ready - Then the submission with UUID "11111111-2222-3333-4444-555555555555" should have 1 "Illumina-C Library creation" request - And the submission with UUID "11111111-2222-3333-4444-555555555555" should have "Illumina-C Paired end sequencing" requests - - Examples: - | json | sequencing requests | - | | 1 | - | "number_of_lanes": 1, | 1 | - | "number_of_lanes": 2, | 2 | - - @update @asset - Scenario: Attaching assets to an order - Given 3 sample tubes exist with names based on "sampletube" and IDs starting at 1 - And all sample tubes have receptacles with sequential UUIDs based on "33333333-4444-5555-6666" - - Given I have an order created with the following details based on the template "Illumina-C - Library creation - Paired end sequencing": - | study | 22222222-3333-4444-5555-000000000000 | - | project | 22222222-3333-4444-5555-000000000001 | - - When I PUT the following JSON to the API path "/11111111-2222-3333-4444-666666666666": - """ - { - "order": { - "assets": [ - "33333333-4444-5555-6666-000000000001", - "33333333-4444-5555-6666-000000000002", - "33333333-4444-5555-6666-000000000003" - ] - } - } - """ - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "order": { - "assets": [ - { - "uuid": "33333333-4444-5555-6666-000000000001" - }, - { - "uuid": "33333333-4444-5555-6666-000000000002" - }, - { - "uuid": "33333333-4444-5555-6666-000000000003" - } - ] - } - } - """ - - @update @asset - Scenario Outline: Modifying the assets attached to an order - Given 3 sample tubes exist with names based on "sampletube" and IDs starting at 1 - And all sample tubes have receptacles with sequential UUIDs based on "33333333-4444-5555-6666" - - Given I have an order created with the following details based on the template "Illumina-C - Library creation - Paired end sequencing": - | study | 22222222-3333-4444-5555-000000000000 | - | project | 22222222-3333-4444-5555-000000000001 | - | assets | 33333333-4444-5555-6666-000000000001 | - - When I PUT the following JSON to the API path "/11111111-2222-3333-4444-666666666666": - """ - { - "order": { - "assets": [] - } - } - """ - Then the HTTP response should be "200 OK" - And the JSON should match the following for the specified fields: - """ - { - "order": { - "assets": [] - } - } - """ - - Examples: - | uuids | assets | - | | | - | "33333333-4444-5555-6666-000000000002" | { "uuid": "33333333-4444-5555-6666-000000000002" } | - | "33333333-4444-5555-6666-000000000002", "33333333-4444-5555-6666-000000000003" | { "uuid": "33333333-4444-5555-6666-000000000002" }, { "uuid": "33333333-4444-5555-6666-000000000003" } | - - @update @error - Scenario Outline: Trying to update invalid request options - Given 3 sample tubes exist with names based on "sampletube" and IDs starting at 1 - And all sample tubes have receptacles with sequential UUIDs based on "33333333-4444-5555-6666" - - Given I have an order created with the following details based on the template "