Skip to content

Commit cce3d79

Browse files
authored
Merge pull request #210 from edx/feature/limit-responses
Add a default response size and a response size limit.
2 parents fe3f570 + 7281673 commit cce3d79

File tree

7 files changed

+38
-15
lines changed

7 files changed

+38
-15
lines changed

api/comment_threads.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
get "#{APIPREFIX}/threads" do # retrieve threads by course
23
threads = CommentThread.where({"course_id" => params["course_id"]})
34
if params[:commentable_ids]
@@ -46,7 +47,11 @@
4647
error 400, [t(:param_must_be_a_number_greater_than_zero, :param => 'resp_limit')].to_json
4748
end
4849
else
49-
resp_limit = nil
50+
resp_limit = CommentService.config["thread_response_default_size"]
51+
end
52+
size_limit = CommentService.config["thread_response_size_limit"]
53+
unless (resp_limit <= size_limit)
54+
error 400, [t(:param_exceeds_limit, :param => resp_limit, :limit => size_limit)].to_json
5055
end
5156
presenter.to_hash(bool_with_responses, resp_skip, resp_limit, bool_recursive).to_json
5257
end

config/application.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@ elasticsearch_server: <%= ENV['SEARCH_SERVER'] || 'http://localhost:9200' %>
44
max_deep_search_comment_count: 5000
55
default_locale: <%= ENV['SERVICE_LANGUAGE'] || 'en-US' %>
66
manual_pagination_batch_size: <%= ENV['MANUAL_PAGINATION_BATCH_SIZE'] || 500 %>
7+
thread_response_default_size: <%= ENV['THREAD_RESPONSE_DEFAULT_SIZE'] || 100 %>
8+
thread_response_size_limit: <%= ENV['THREAD_RESPONSE_SIZE_LIMIT'] || 200 %>

locale/en-US.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ en-US:
88
blocked_content_with_body_hash: "blocked content with body hash %{hash}"
99
param_must_be_a_non_negative_number: "%{param} must be a non-negative number"
1010
param_must_be_a_number_greater_than_zero: "%{param} must be a number greater than zero"
11+
param_exceeds_limit: "%{param} exceeds limit: %{limit}"
1112
cannot_specify_group_id_and_group_ids: "Cannot specify both group_id and group_ids as filters."

locale/x-test.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,5 @@ x-test:
88
blocked_content_with_body_hash: "##x-test## blocked content with body hash %{hash}"
99
param_must_be_a_non_negative_number: "##x-test## %{param} must be a non-negative number"
1010
param_must_be_a_number_greater_than_zero: "##x-test## %{param} must be a number greater than zero"
11+
param_exceeds_limit: "##x-test## %{param} exceeds limit: %{limit}"
12+
cannot_specify_group_id_and_group_ids: "##x-test## Cannot specify both group_id and group_ids as filters."

spec/api/comment_thread_spec.rb

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -542,22 +542,33 @@ def test_unicode_data(text)
542542

543543
include_examples 'unicode data'
544544

545+
context 'error conditions' do
546+
subject do
547+
resp_limit = CommentService.config["thread_response_size_limit"]
548+
get "/api/v1/threads/#{thread.id}", resp_limit: resp_limit+1
549+
end
550+
551+
it "returns an error when the limit is exceeded" do
552+
expect(subject.status).to eq 400
553+
end
554+
end
555+
545556
context "response pagination" do
546557
before(:each) do
547558
User.all.delete
548559
Content.all.delete
549560
@user = create_test_user(999)
550561
@threads = {}
551562
@comments = {}
552-
[20, 10, 3, 2, 1, 0].each do |n|
563+
[201, 10, 3, 2, 1, 0].each do |n|
553564
thread_key = "t#{n}"
554565
thread = make_thread(@user, thread_key, DFLT_COURSE_ID, "pdq")
555566
@threads[n] = thread
556567
n.times do |i|
557568
# generate n responses in this thread
558569
comment_key = "#{thread_key} r#{i}"
559570
comment = make_comment(@user, thread, comment_key)
560-
i.times do |j|
571+
2.times do |j|
561572
subcomment_key = "#{comment_key} c#{j}"
562573
subcomment = make_comment(@user, comment, subcomment_key)
563574
end
@@ -572,7 +583,7 @@ def thread_result(id, params)
572583
parse(last_response.body)
573584
end
574585

575-
it "returns all responses when no skip/limit params given" do
586+
it "limits responses when no skip/limit params given" do
576587
@threads.each do |n, thread|
577588
res = thread_result thread.id, {}
578589
check_thread_response_paging_json thread, res, 0, nil, false

spec/presenters/thread_spec.rb

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
describe ThreadPresenter do
44

55
context "#to_hash" do
6+
let(:default_resp_limit) { CommentService.config["thread_response_default_size"] }
7+
68
shared_examples "to_hash arguments" do |thread_type, endorse_responses|
79
before(:each) do
810
User.all.delete
@@ -94,28 +96,28 @@
9496
it "handles with_responses=true and recursive=true" do
9597
@threads_with_num_comments.each do |thread, num_comments|
9698
is_endorsed = num_comments > 0 && endorse_responses
97-
hash = ThreadPresenter.new(thread, @reader, false, num_comments, is_endorsed).to_hash(true, 0, nil, true)
99+
hash = ThreadPresenter.new(thread, @reader, false, num_comments, is_endorsed).to_hash(true, 0, default_resp_limit, true)
98100
check_thread_result(@reader, thread, hash)
99-
check_thread_response_paging(thread, hash, 0, nil, false, true)
101+
check_thread_response_paging(thread, hash, 0, default_resp_limit, false, true)
100102
end
101103
end
102104

103105
it "handles with_responses=true and recursive=false" do
104106
@threads_with_num_comments.each do |thread, num_comments|
105107
is_endorsed = num_comments > 0 && endorse_responses
106-
hash = ThreadPresenter.new(thread, @reader, false, num_comments, is_endorsed).to_hash(true, 0, nil, false)
108+
hash = ThreadPresenter.new(thread, @reader, false, num_comments, is_endorsed).to_hash(true, 0, default_resp_limit, false)
107109
check_thread_result(@reader, thread, hash)
108-
check_thread_response_paging(thread, hash)
110+
check_thread_response_paging(thread, hash, 0, default_resp_limit)
109111
end
110112
end
111113

112114
it "handles skip with no limit" do
113115
@threads_with_num_comments.each do |thread, num_comments|
114116
is_endorsed = num_comments > 0 && endorse_responses
115117
[0, 1, 2, 9, 10, 11, 1000].each do |skip|
116-
hash = ThreadPresenter.new(thread, @reader, false, num_comments, is_endorsed).to_hash(true, skip, nil, true)
118+
hash = ThreadPresenter.new(thread, @reader, false, num_comments, is_endorsed).to_hash(true, skip, default_resp_limit, true)
117119
check_thread_result(@reader, thread, hash)
118-
check_thread_response_paging(thread, hash, skip)
120+
check_thread_response_paging(thread, hash, skip, default_resp_limit)
119121
end
120122
end
121123
end

spec/spec_helper.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,10 @@ def check_comment(comment, hash, is_json, recursive=false)
265265

266266

267267
def check_discussion_response_paging(thread, hash, resp_skip=0, resp_limit=nil, is_json=false, recursive=false)
268+
if resp_limit.nil?
269+
resp_limit = CommentService.config["thread_response_default_size"]
270+
end
271+
268272
all_responses = thread.root_comments.sort({"sk" => 1}).to_a
269273
total_responses = all_responses.length
270274
hash["resp_total"].should == total_responses
@@ -277,11 +281,7 @@ def check_discussion_response_paging(thread, hash, resp_skip=0, resp_limit=nil,
277281
check_comment(expected_responses[i], response_hash, is_json, recursive)
278282
end
279283
hash["resp_skip"].to_i.should == resp_skip
280-
if resp_limit.nil?
281-
hash["resp_limit"].should be_nil
282-
else
283-
hash["resp_limit"].to_i.should == resp_limit
284-
end
284+
hash["resp_limit"].to_i.should == resp_limit
285285
end
286286

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

0 commit comments

Comments
 (0)