Skip to content

Commit

Permalink
Add basic outline for ONT request
Browse files Browse the repository at this point in the history
- Validate all attributes as needed
- Add associations with library type and data_type
- Add pipeline validation for library_type/data_type
  • Loading branch information
James Glover committed Jun 10, 2022
1 parent ea797ab commit 06c0348
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 2 deletions.
10 changes: 10 additions & 0 deletions app/models/ont/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,15 @@ module Ont
# Ont::Request
class Request < ApplicationRecord
include Material

belongs_to :library_type
belongs_to :data_type

validates :cost_code, presence: true
validates :number_of_flowcells, numericality: { only_integer: true, greater_than: 0 }
validates :external_study_id, uuid: true

validates :library_type, pipeline: :ont
validates :data_type, pipeline: :ont
end
end
34 changes: 34 additions & 0 deletions app/validators/pipeline_validator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# frozen_string_literal: true

# Validates that attribute belongs to the configured pipeline
# @example
# validates :library_type, pipeline: :ont
# Requires that the associated attribute responds to
class PipelineValidator < ActiveModel::EachValidator
def initialize(options)
super

# We'll give some helpful errors if we configure it wrong
raise ArgumentError, 'No target pipeline specified' if expected.nil?
raise ArgumentError, "#{expected} is not a recognised pipeline" unless valid_pipeline?
end

def validate_each(record, attribute, value)
return if value.blank?

actual = value.pipeline
return if actual == expected.to_s

record.errors.add(attribute, :pipeline_invalid, { expected: expected, actual: actual })
end

private

def expected
options[:with]
end

def valid_pipeline?
Pipelines::ENUMS.key?(expected)
end
end
1 change: 1 addition & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ en:
errors:
messages:
uuid: is not a valid uuid
pipeline_invalid: is in %{actual} not %{expected} pipeline
attributes:
cost_code:
blank: must be present
Expand Down
3 changes: 3 additions & 0 deletions spec/factories/ont/requests.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,8 @@
factory :ont_request, class: 'Ont::Request' do
external_study_id
cost_code

association :library_type, :ont
association :data_type, :ont
end
end
76 changes: 74 additions & 2 deletions spec/models/ont/request_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,80 @@
require './spec/support/read_only'

RSpec.describe Ont::Request, type: :model, ont: true do
before do
set_read_only(described_class, false)
describe '#valid?' do
subject { build :ont_request, attributes }

context 'with all required attributes' do
let(:attributes) { {} }

it { is_expected.to be_valid }
end

context 'without a costcode' do
let(:attributes) { { cost_code: '' } }

it { is_expected.not_to be_valid }
end

context 'without an external_study_id' do
let(:attributes) { { external_study_id: '' } }

it { is_expected.not_to be_valid }
end

context 'with a non uuid external_study_id' do
let(:attributes) { { external_study_id: '2' } }

it { is_expected.not_to be_valid }
end

context 'without a number of flowcells' do
let(:attributes) { { number_of_flowcells: '' } }

it { is_expected.not_to be_valid }
end

context 'with a negative of flowcells' do
let(:attributes) { { number_of_flowcells: -3 } }

it { is_expected.not_to be_valid }
end

context 'with a non-integer of flowcells' do
let(:attributes) { { number_of_flowcells: 3.5 } }

it { is_expected.not_to be_valid }
end
end

describe '#library_type' do
subject(:request) { build(:ont_request, attributes) }

context 'when set' do
let(:library_type) { build :library_type, :ont }
let(:attributes) { { library_type: library_type } }

it { expect(request.library_type).to eq library_type }
it { is_expected.to be_valid }
end

context 'when from a different pipeline' do
let(:library_type) { build :library_type, :pacbio }
let(:attributes) { { library_type: library_type } }

it { is_expected.not_to be_valid }
end
end

describe '#data_type' do
subject { build(:ont_request, attributes).data_type }

context 'when set' do
let(:data_type) { build :data_type, :ont }
let(:attributes) { { data_type: data_type } }

it { is_expected.to eq data_type }
end
end

context 'material' do
Expand Down
42 changes: 42 additions & 0 deletions spec/validators/pipeline_validator_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# frozen_string_literal: true

require 'rails_helper'

RSpec.describe PipelineValidator do
describe '#validate_each' do
let(:record_class) { Ont::Request }
let(:record) { record_class.new }
let(:attribute) { :library_type }
let(:pipeline) { :ont }

before do
described_class.new(attributes: [attribute], with: pipeline).validate_each(record, attribute, value)
end

context 'with a nil value' do
let(:value) { nil }

# We'll allow nil here, and let the presence validator handle that if
# required
it 'does not add an error to the record' do
expect(record.errors.full_messages).to be_empty
end
end

context 'with the incorrect pipeline' do
let(:value) { build :library_type, :pacbio }

it 'adds an error to the record' do
expect(record.errors.full_messages).to include('Library type is in pacbio not ont pipeline')
end
end

context 'with the correct pipeline' do
let(:value) { build :library_type, pipeline }

it 'does not add an error to the record' do
expect(record.errors.full_messages).to be_empty
end
end
end
end

0 comments on commit 06c0348

Please sign in to comment.