Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Y24-190-3: Support Limber with a V2 endpoint for PlateCreations #4439

Open
wants to merge 9 commits into
base: develop-Y24-190
Choose a base branch
from
12 changes: 12 additions & 0 deletions app/controllers/api/v2/plate_creations_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

module Api
module V2
# Provides a JSON API controller for plate creations.
# See: http://jsonapi-resources.com/ for JSONAPI::Resource documentation
class PlateCreationsController < JSONAPI::ResourceController
# By default JSONAPI::ResourceController provides most of the standard
# behaviour, and in many cases this file may be left empty.
end
end
end
130 changes: 130 additions & 0 deletions app/resources/api/v2/plate_creation_resource.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# frozen_string_literal: true

module Api
module V2
# Provides a JSON:API representation of {PlateCreation} for creation of a child plate with a given purpose which
# is linked to a parent plate as one of its children.
# Creation of this resource via a `POST` request will initiate the child plate creation.
# The child plate is returned by this endpoint under the {#child} relationship.
#
# @note This resource cannot be modified after creation: its endpoint will not accept `PATCH` requests.
# @note Access this resource via the `/api/v2/plate_creations/` endpoint.
#
# @example POST request with arguments specified by UUID (deprecated)
# POST /api/v2/plate_creations/
# {
# "data": {
# "type": "plate_creations",
# "attributes": {
# "parent_uuid": "11111111-2222-3333-4444-555555666666",
# "child_purpose_uuid": "22222222-3333-4444-5555-666666777777",
# "user_uuid": "33333333-4444-5555-6666-777777888888"
# }
# }
# }
#
# @example POST request with arguments specified by relationship
# POST /api/v2/plate_creations/
# {
# "data": {
# "type": "plate_creations",
# "attributes": {},
# "relationships": {
# "parent": {
# "data": { "type": "plates", "id": "123" }
# },
# "child_purpose": {
# "data": { "type": "plate_purposes", "id": "234" }
# },
# "user": {
# "data": { "type": "users", "id": "345" }
# }
# }
# }
# }
#
# @example GET request for all PlateCreation resources
# GET /api/v2/plate_creations/
#
# @example GET request for a PlateCreation with ID 123
# GET /api/v2/plate_creations/123/
#
# For more information about JSON:API see the [JSON:API Specifications](https://jsonapi.org/format/)
# or look at the [JSONAPI::Resources](http://jsonapi-resources.com/) package for Sequencescape's implementation
# of the JSON:API standard.
class PlateCreationResource < BaseResource
###
# Attributes
###

# @!attribute [w] child_purpose_uuid
# This is declared for convenience where the {PlatePurpose} is not available to set as a relationship.
# Setting this attribute alongside the `child_purpose` relationship will prefer the relationship value.
# @deprecated Use the `child_purpose` relationship instead.
# @param value [String] The UUID of the {PlatePurpose} to use when creating the child plate.
# @return [Void]
# @see #child_purpose
attribute :child_purpose_uuid, writeonly: true

def child_purpose_uuid=(value)
@model.child_purpose = PlatePurpose.with_uuid(value).first
end

# @!attribute [w] parent_uuid
# This is declared for convenience where the parent {Plate} is not available to set as a relationship.
# Setting this attribute alongside the `parent` relationship will prefer the relationship value.
# @deprecated Use the `parent` relationship instead.
# @param value [String] The UUID of the {Plate} to become the parent of the created child plate.
# @return [Void]
# @see #parent
attribute :parent_uuid, writeonly: true

def parent_uuid=(value)
@model.parent = Plate.with_uuid(value).first
end

# @!attribute [w] user_uuid
# This is declared for convenience where the {User} is not available to set as a relationship.
# Setting this attribute alongside the `user` relationship will prefer the relationship value.
# @deprecated Use the `user` relationship instead.
# @param value [String] The UUID of the {User} who initiated this plate creation.
# @return [Void]
# @see #user
attribute :user_uuid, writeonly: true

def user_uuid=(value)
@model.user = User.with_uuid(value).first
end

# @!attribute [r] uuid
# @return [String] The UUID of the plate creation.
attribute :uuid, readonly: true

###
# Relationships
###

# @!attribute [r] child
# @return [Api::V2::PlateResource] The child plate created by this resource.
has_one :child, class_name: 'Plate', readonly: true

# @!attribute [rw] child_purpose
# Setting this relationship alongside the `child_purpose_uuid` attribute will override the attribute value.
# The purpose which the child plate should be created with.
# @return [Api::V2::PlatePurposeResource]
# @note This relationship is required.
has_one :child_purpose, class_name: 'PlatePurpose'

# @!attribute [rw] parent
# Setting this relationship alongside the `parent_uuid` attribute will override the attribute value.
# @return [Api::V2::PlateResource] The plate to become the parent of the created child plate.
has_one :parent, class_name: 'Plate'

# @!attribute [rw] user
# Setting this relationship alongside the `user_uuid` attribute will override the attribute value.
# @return [Api::V2::UserResource] The user who initiated this plate creation.
# @note This relationship is required.
has_one :user
end
end
end
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
jsonapi_resources :orders
jsonapi_resources :pick_lists
jsonapi_resources :plate_conversions, except: %i[update]
jsonapi_resources :plate_creations, except: %i[update]
jsonapi_resources :plate_purposes, except: %i[update]
jsonapi_resources :plate_templates
jsonapi_resources :plates
Expand Down
12 changes: 12 additions & 0 deletions spec/factories/plate_creation_factories.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# frozen_string_literal: true

FactoryBot.define do
factory(:plate_creation) do
# Without this, create_children! tries to go to Baracoda for a barcode.
sanger_barcode { create(:sequencescape22) }

child_purpose factory: %i[plate_purpose]
parent factory: %i[full_plate], well_count: 2
user
end
end
12 changes: 0 additions & 12 deletions spec/factories/pulldown_factories.rb
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,6 @@
walking_algorithm { 'TagLayout::WalkWellsOfPlate' }
end

factory(:plate_creation) do
user
sanger_barcode { create(:sequencescape22) }
parent factory: %i[full_plate], well_count: 2
child_purpose factory: %i[plate_purpose]

# PlateCreation inherits from AssetCreation that will try to call
# Baracoda to obtain a new barcode. As this is not needed for the
# tests we disable it, however is needed for some cucumber tests
skip_create if Rails.env.test?
end

factory(:tube_creation) do
user
parent factory: %i[full_plate], well_count: 2
Expand Down
3 changes: 2 additions & 1 deletion spec/rails_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@
config.include Rails.application.routes.url_helpers

config.include ApiV2Helper, with: :api_v2
config.include ApiV2Matchers
config.include ApiV2AttributeMatchers
config.include ApiV2RelationshipMatchers
config.include RSpec::Longrun::DSL

Capybara.add_selector(:data_behavior) { xpath { |name| XPath.css("[data-behavior='#{name}']") } }
Expand Down
6 changes: 3 additions & 3 deletions spec/requests/api/v2/bait_library_layouts_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

require 'rails_helper'
require './spec/requests/api/v2/shared_examples/api_key_authenticatable'
require './spec/requests/api/v2/shared_examples/post_requests'
require './spec/requests/api/v2/shared_examples/requests'

describe 'Bait Library Layouts API', with: :api_v2 do
let(:model_class) { BaitLibraryLayout }
Expand Down Expand Up @@ -70,13 +70,13 @@
context 'with plate' do
let(:related_name) { 'plate' }

it_behaves_like 'a POST request including a has_one relationship'
it_behaves_like 'a GET request including a has_one relationship'
end

context 'with user' do
let(:related_name) { 'user' }

it_behaves_like 'a POST request including a has_one relationship'
it_behaves_like 'a GET request including a has_one relationship'
end
end
end
Expand Down
10 changes: 5 additions & 5 deletions spec/requests/api/v2/plate_conversions_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

require 'rails_helper'
require './spec/requests/api/v2/shared_examples/api_key_authenticatable'
require './spec/requests/api/v2/shared_examples/post_requests'
require './spec/requests/api/v2/shared_examples/requests'

describe 'Plate Conversions API', with: :api_v2 do
let(:model_class) { PlateConversion }
Expand Down Expand Up @@ -93,25 +93,25 @@
context 'with parent' do
let(:related_name) { 'parent' }

it_behaves_like 'a POST request including a has_one relationship'
it_behaves_like 'a GET request including a has_one relationship'
end

context 'with purpose' do
let(:related_name) { 'purpose' }

it_behaves_like 'a POST request including a has_one relationship'
it_behaves_like 'a GET request including a has_one relationship'
end

context 'with target' do
let(:related_name) { 'target' }

it_behaves_like 'a POST request including a has_one relationship'
it_behaves_like 'a GET request including a has_one relationship'
end

context 'with user' do
let(:related_name) { 'user' }

it_behaves_like 'a POST request including a has_one relationship'
it_behaves_like 'a GET request including a has_one relationship'
end
end
end
Expand Down
Loading
Loading