Skip to content

Commit 984c258

Browse files
committed
Validate query and range for the retrieval function
1 parent 2dc3ece commit 984c258

File tree

4 files changed

+67
-3
lines changed

4 files changed

+67
-3
lines changed

lib/sequenceserver/api_errors.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,30 @@ def message
5252
end
5353
end
5454

55+
# InvalidParameterError is a more generic error class that can be
56+
# raised when the frontend sends a request with an invalid parameter
57+
class InvalidParameterError < ValidationError
58+
attr_reader :more_info
59+
60+
def initialize(more_info)
61+
super
62+
@more_info = more_info
63+
end
64+
65+
def http_status
66+
422
67+
end
68+
69+
def title
70+
'Invalid parameter'
71+
end
72+
73+
def message
74+
"The action you're trying to perform is not possible because \
75+
one of the provided parameters is invalid."
76+
end
77+
end
78+
5579
# API errors have an http status, title, message, and additional information
5680
# like stacktrace or information from program output.
5781
APIError = Class.new(Error)

lib/sequenceserver/blast.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ module SequenceServer
66
module BLAST
77
VALID_SEQUENCE_ID = /\A[a-zA-Z0-9\-_.:*#|\[\]]+\z/
88
end
9-
end
9+
end

lib/sequenceserver/database.rb

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,19 @@ def initialize(*args)
3737
alias path name
3838

3939
def retrieve(accession, coords = nil)
40+
fail(
41+
InvalidSequenceIdError,
42+
"Invalid sequence id: #{accession}"
43+
) unless accession =~ SequenceServer::BLAST::VALID_SEQUENCE_ID
44+
4045
cmd = "blastdbcmd -db #{name} -entry '#{accession}'"
46+
4147
if coords
48+
fail(
49+
InvalidParameterError,
50+
"Invalid range coordinates: #{coords}"
51+
) unless coords =~ /[0-9]+-[0-9]*/
52+
4253
cmd << " -range #{coords}"
4354
end
4455
out, = sys(cmd, path: config[:bin])
@@ -52,7 +63,7 @@ def retrieve(accession, coords = nil)
5263
# Returns true if the database contains the given sequence id.
5364
# Returns false otherwise.
5465
def include?(id)
55-
raise ArgumentError, "Invalid sequence id: #{id}" unless id =~ SequenceServer::BLAST::VALID_SEQUENCE_ID
66+
fail ArgumentError, "Invalid sequence id: #{id}" unless id =~ SequenceServer::BLAST::VALID_SEQUENCE_ID
5667

5768
cmd = "blastdbcmd -entry '#{id}' -db #{name}"
5869
sys(cmd, path: config[:bin]) rescue false

spec/database_spec.rb

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,37 @@ module SequenceServer
4343
end
4444
end
4545

46-
describe '#retrieve' do
46+
describe '.retrieve' do
47+
it "retrieves the sequence for a given accession" do
48+
sequence = Database.retrieve("SI2.2.0_06267")
49+
expect(sequence).to include('SI2.2.0_06267')
50+
expect(sequence).to include('MNTLWLSLWDYPGKL') # start of fasta sequence
51+
end
52+
53+
it "retrieves an open sequence range for a given accession" do
54+
sequence = Database.retrieve("SI2.2.0_06267:10-")
55+
expect(sequence).to include('SI2.2.0_06267')
56+
expect(sequence).not_to include('MNTLWLSLWD') # excludes first 10 chars
57+
expect(sequence.lines[1]).to start_with('DYPGKLP') # start at an offset of 10
58+
end
59+
60+
it "retrieves a closed sequence range for a given accession" do
61+
sequence = Database.retrieve("SI2.2.0_06267:1-10")
62+
expect(sequence).to include('SI2.2.0_06267')
63+
expect(sequence.lines.last.size).to eq(10)
64+
end
4765

66+
it "validates the sequence id" do
67+
expect do
68+
Database.retrieve("';hi")
69+
end.to raise_error(SequenceServer::InvalidSequenceIdError)
70+
end
71+
72+
it "validates the range" do
73+
expect do
74+
Database.retrieve("SI2.2.0_06267:';hi")
75+
end.to raise_error(SequenceServer::InvalidParameterError)
76+
end
4877
end
4978
end
5079
end

0 commit comments

Comments
 (0)