Skip to content

Commit

Permalink
Merge pull request #210 from edx/feature/limit-responses
Browse files Browse the repository at this point in the history
Add a default response size and a response size limit.
  • Loading branch information
tobz authored Nov 3, 2016
2 parents fe3f570 + 7281673 commit cce3d79
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 15 deletions.
7 changes: 6 additions & 1 deletion api/comment_threads.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

get "#{APIPREFIX}/threads" do # retrieve threads by course
threads = CommentThread.where({"course_id" => params["course_id"]})
if params[:commentable_ids]
Expand Down Expand Up @@ -46,7 +47,11 @@
error 400, [t(:param_must_be_a_number_greater_than_zero, :param => 'resp_limit')].to_json
end
else
resp_limit = nil
resp_limit = CommentService.config["thread_response_default_size"]
end
size_limit = CommentService.config["thread_response_size_limit"]
unless (resp_limit <= size_limit)
error 400, [t(:param_exceeds_limit, :param => resp_limit, :limit => size_limit)].to_json
end
presenter.to_hash(bool_with_responses, resp_skip, resp_limit, bool_recursive).to_json
end
Expand Down
2 changes: 2 additions & 0 deletions config/application.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,5 @@ elasticsearch_server: <%= ENV['SEARCH_SERVER'] || 'http://localhost:9200' %>
max_deep_search_comment_count: 5000
default_locale: <%= ENV['SERVICE_LANGUAGE'] || 'en-US' %>
manual_pagination_batch_size: <%= ENV['MANUAL_PAGINATION_BATCH_SIZE'] || 500 %>
thread_response_default_size: <%= ENV['THREAD_RESPONSE_DEFAULT_SIZE'] || 100 %>
thread_response_size_limit: <%= ENV['THREAD_RESPONSE_SIZE_LIMIT'] || 200 %>
1 change: 1 addition & 0 deletions locale/en-US.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ en-US:
blocked_content_with_body_hash: "blocked content with body hash %{hash}"
param_must_be_a_non_negative_number: "%{param} must be a non-negative number"
param_must_be_a_number_greater_than_zero: "%{param} must be a number greater than zero"
param_exceeds_limit: "%{param} exceeds limit: %{limit}"
cannot_specify_group_id_and_group_ids: "Cannot specify both group_id and group_ids as filters."
2 changes: 2 additions & 0 deletions locale/x-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ x-test:
blocked_content_with_body_hash: "##x-test## blocked content with body hash %{hash}"
param_must_be_a_non_negative_number: "##x-test## %{param} must be a non-negative number"
param_must_be_a_number_greater_than_zero: "##x-test## %{param} must be a number greater than zero"
param_exceeds_limit: "##x-test## %{param} exceeds limit: %{limit}"
cannot_specify_group_id_and_group_ids: "##x-test## Cannot specify both group_id and group_ids as filters."
17 changes: 14 additions & 3 deletions spec/api/comment_thread_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -542,22 +542,33 @@ def test_unicode_data(text)

include_examples 'unicode data'

context 'error conditions' do
subject do
resp_limit = CommentService.config["thread_response_size_limit"]
get "/api/v1/threads/#{thread.id}", resp_limit: resp_limit+1
end

it "returns an error when the limit is exceeded" do
expect(subject.status).to eq 400
end
end

context "response pagination" do
before(:each) do
User.all.delete
Content.all.delete
@user = create_test_user(999)
@threads = {}
@comments = {}
[20, 10, 3, 2, 1, 0].each do |n|
[201, 10, 3, 2, 1, 0].each do |n|
thread_key = "t#{n}"
thread = make_thread(@user, thread_key, DFLT_COURSE_ID, "pdq")
@threads[n] = thread
n.times do |i|
# generate n responses in this thread
comment_key = "#{thread_key} r#{i}"
comment = make_comment(@user, thread, comment_key)
i.times do |j|
2.times do |j|
subcomment_key = "#{comment_key} c#{j}"
subcomment = make_comment(@user, comment, subcomment_key)
end
Expand All @@ -572,7 +583,7 @@ def thread_result(id, params)
parse(last_response.body)
end

it "returns all responses when no skip/limit params given" do
it "limits responses when no skip/limit params given" do
@threads.each do |n, thread|
res = thread_result thread.id, {}
check_thread_response_paging_json thread, res, 0, nil, false
Expand Down
14 changes: 8 additions & 6 deletions spec/presenters/thread_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
describe ThreadPresenter do

context "#to_hash" do
let(:default_resp_limit) { CommentService.config["thread_response_default_size"] }

shared_examples "to_hash arguments" do |thread_type, endorse_responses|
before(:each) do
User.all.delete
Expand Down Expand Up @@ -94,28 +96,28 @@
it "handles with_responses=true and recursive=true" do
@threads_with_num_comments.each do |thread, num_comments|
is_endorsed = num_comments > 0 && endorse_responses
hash = ThreadPresenter.new(thread, @reader, false, num_comments, is_endorsed).to_hash(true, 0, nil, true)
hash = ThreadPresenter.new(thread, @reader, false, num_comments, is_endorsed).to_hash(true, 0, default_resp_limit, true)
check_thread_result(@reader, thread, hash)
check_thread_response_paging(thread, hash, 0, nil, false, true)
check_thread_response_paging(thread, hash, 0, default_resp_limit, false, true)
end
end

it "handles with_responses=true and recursive=false" do
@threads_with_num_comments.each do |thread, num_comments|
is_endorsed = num_comments > 0 && endorse_responses
hash = ThreadPresenter.new(thread, @reader, false, num_comments, is_endorsed).to_hash(true, 0, nil, false)
hash = ThreadPresenter.new(thread, @reader, false, num_comments, is_endorsed).to_hash(true, 0, default_resp_limit, false)
check_thread_result(@reader, thread, hash)
check_thread_response_paging(thread, hash)
check_thread_response_paging(thread, hash, 0, default_resp_limit)
end
end

it "handles skip with no limit" do
@threads_with_num_comments.each do |thread, num_comments|
is_endorsed = num_comments > 0 && endorse_responses
[0, 1, 2, 9, 10, 11, 1000].each do |skip|
hash = ThreadPresenter.new(thread, @reader, false, num_comments, is_endorsed).to_hash(true, skip, nil, true)
hash = ThreadPresenter.new(thread, @reader, false, num_comments, is_endorsed).to_hash(true, skip, default_resp_limit, true)
check_thread_result(@reader, thread, hash)
check_thread_response_paging(thread, hash, skip)
check_thread_response_paging(thread, hash, skip, default_resp_limit)
end
end
end
Expand Down
10 changes: 5 additions & 5 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,10 @@ def check_comment(comment, hash, is_json, recursive=false)


def check_discussion_response_paging(thread, hash, resp_skip=0, resp_limit=nil, is_json=false, recursive=false)
if resp_limit.nil?
resp_limit = CommentService.config["thread_response_default_size"]
end

all_responses = thread.root_comments.sort({"sk" => 1}).to_a
total_responses = all_responses.length
hash["resp_total"].should == total_responses
Expand All @@ -277,11 +281,7 @@ def check_discussion_response_paging(thread, hash, resp_skip=0, resp_limit=nil,
check_comment(expected_responses[i], response_hash, is_json, recursive)
end
hash["resp_skip"].to_i.should == resp_skip
if resp_limit.nil?
hash["resp_limit"].should be_nil
else
hash["resp_limit"].to_i.should == resp_limit
end
hash["resp_limit"].to_i.should == resp_limit
end

def check_question_response_paging(thread, hash, resp_skip=0, resp_limit=nil, is_json=false, recursive=false)
Expand Down

0 comments on commit cce3d79

Please sign in to comment.