Description:
shows problems availabe in contests
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r278:a0c2d497b31a - - 9 files changed: 217 inserted, 38 deleted

@@ -190,22 +190,68
190 190 if recent!=nil
191 191 recent_id = recent.to_i
192 192 @announcements = @announcements.find_all { |a| a.id > recent_id }
193 193 end
194 194 end
195 195
196 + def problem_list_by_user_contests(user)
197 + contest_problems = []
198 + pin = {}
199 + user.contests.each do |contest|
200 + available_problems = contest.problems.available
201 + contest_problems << {
202 + :contest => contest,
203 + :problems => available_problems
204 + }
205 + available_problems.each {|p| pin[p.id] = true}
206 + end
207 + other_avaiable_problems = Problem.available.find_all {|p| pin[p.id]==nil and p.contests.length==0}
208 + contest_problems << {
209 + :contest => nil,
210 + :problems => other_avaiable_problems
211 + }
212 + return contest_problems
213 + end
214 +
215 + def problem_list_for_user(user, contest_problems=nil)
216 + if not Configuration.multicontests?
217 + return Problem.find_available_problems
218 + else
219 + if contest_problems==nil
220 + contest_problems = problem_list_by_user_contests(user)
221 + end
222 +
223 + problems = []
224 + collected = {}
225 + contest_problems.each do |cp|
226 + cp[:problems].each do |problem|
227 + if not collected[problem.id]
228 + problems << problem
229 + collected[problem.id] = true
230 + end
231 + end
232 + end
233 + return problems
234 + end
235 + end
236 +
196 237 def prepare_list_information
197 - @problems = Problem.find_available_problems
198 - @prob_submissions = Array.new
199 238 @user = User.find(session[:user_id])
239 + if not Configuration.multicontests?
240 + @problems = problem_list_for_user(@user)
241 + else
242 + @contest_problems = problem_list_by_user_contests(@user)
243 + @problems = problem_list_for_user(@user, @contest_problems)
244 + end
245 + @prob_submissions = {}
200 246 @problems.each do |p|
201 247 sub = Submission.find_last_by_user_and_problem(@user.id,p.id)
202 248 if sub!=nil
203 - @prob_submissions << { :count => sub.number, :submission => sub }
249 + @prob_submissions[p.id] = { :count => sub.number, :submission => sub }
204 250 else
205 - @prob_submissions << { :count => 0, :submission => nil }
251 + @prob_submissions[p.id] = { :count => 0, :submission => nil }
206 252 end
207 253 end
208 254 prepare_announcements
209 255 end
210 256
211 257 def check_viewability
@@ -103,12 +103,16
103 103 end
104 104
105 105 def self.indv_contest_mode?
106 106 return get(SYSTEM_MODE_CONF_KEY) == 'indv-contest'
107 107 end
108 108
109 + def self.multicontests?
110 + return get('system.multicontests') == true
111 + end
112 +
109 113 def self.time_limit_mode?
110 114 mode = get(SYSTEM_MODE_CONF_KEY)
111 115 return ((mode == 'contest') or (mode == 'indv-contest'))
112 116 end
113 117
114 118 def self.analysis_mode?
@@ -5,17 +5,19
5 5 has_many :test_pairs, :dependent => :delete_all
6 6
7 7 validates_presence_of :name
8 8 validates_format_of :name, :with => /^\w+$/
9 9 validates_presence_of :full_name
10 10
11 + named_scope :available, :conditions => {:available => true}
12 +
11 13 DEFAULT_TIME_LIMIT = 1
12 14 DEFAULT_MEMORY_LIMIT = 32
13 15
14 16 def self.find_available_problems
15 - find(:all, :conditions => {:available => true}, :order => "date_added DESC")
17 + Problem.available.all(:order => "date_added DESC")
16 18 end
17 19
18 20 def self.create_from_import_form_params(params, old_problem=nil)
19 21 problem = old_problem || Problem.new
20 22 import_params = Problem.extract_params_and_check(params, problem)
21 23
@@ -4,15 +4,15
4 4 </td>
5 5 <td>
6 6 <%= "#{problem.full_name} (#{problem.name})" %>
7 7 <%= link_to_description_if_any "[#{t 'main.problem_desc'}]", problem %>
8 8 </td>
9 9 <td align="center">
10 - <%= @prob_submissions[problem_counter][:count] %>
10 + <%= @prob_submissions[problem.id][:count] %>
11 11 </td>
12 12 <td>
13 13 <%= render :partial => 'submission_short',
14 14 :locals => {
15 - :submission => @prob_submissions[problem_counter][:submission],
15 + :submission => @prob_submissions[problem.id][:submission],
16 16 :problem_name => problem.name }%>
17 17 </td>
18 18 </tr>
@@ -19,19 +19,32
19 19 %hr/
20 20
21 21 - if (Configuration.contest_mode?) and (@user.site!=nil) and (@user.site.started!=true)
22 22 %p=t 'main.start_soon'
23 23
24 24 - if Configuration.show_tasks_to?(@user)
25 + - if not Configuration.multicontests?
25 26 %table.info
26 27 %tr.info-head
27 28 %th
28 29 %th Tasks
29 30 %th # of sub(s)
30 31 %th Results
31 32 = render :partial => 'problem', :collection => @problems
33 + - else
34 + - @contest_problems.each do |cp|
35 + %h2{:class =>'contest-title'}
36 + = "#{cp[:contest] ? cp[:contest].title : 'Public problems'}"
37 + %table.info
38 + %tr.info-head
39 + %th
40 + %th Tasks
41 + %th # of sub(s)
42 + %th Results
43 + = render :partial => 'problem', :collection => cp[:problems]
44 +
32 45
33 46 %hr/
34 47
35 48 %script{:type => 'text/javascript'}
36 49 = "Announcement.refreshUrl = '#{url_for :controller => 'main', :action => 'announcements'}';"
37 50 Announcement.registerRefreshEventTimer();
@@ -1,56 +1,159
1 -
2 1 require File.dirname(__FILE__) + '/../spec_helper'
3 2
4 - describe MainController do
3 + module ConfigHelperMethods
4 + def enable_multicontest
5 + c = Configuration.new(:key => 'system.multicontests',
6 + :value_type => 'boolean',
7 + :value => 'true')
8 + c.save
9 + end
10 +
11 + def disable_multicontest
12 + c = Configuration.new(:key => 'system.multicontests',
13 + :value_type => 'boolean',
14 + :value => 'false')
15 + c.save
16 + end
17 + end
18 +
19 + describe MainController, "when a user comes to list page" do
20 +
21 + it "should redirect user to login page when unlogged-in user try to access main/list" do
22 + get 'list'
23 + response.should redirect_to(:action => 'login')
24 + end
25 +
26 + end
27 +
28 + describe MainController, "when a logged in user comes to list page, with multicontests off" do
29 + integrate_views
30 +
31 + include ConfigHelperMethods
32 +
33 + fixtures :users
34 + fixtures :problems
35 + fixtures :contests
36 +
37 + before(:each) do
38 + disable_multicontest
39 + end
40 +
41 + it "should list available problems" do
42 + john = users(:john)
43 + get "list", {}, {:user_id => john.id}
44 +
45 + response.should render_template 'main/list'
46 + response.should have_text(/add/)
47 + response.should have_text(/easy_problem/)
48 + response.should have_text(/hard_problem/)
49 + end
50 +
51 + end
52 +
53 + describe MainController, "when a logged in user comes to list page, with multicontests on" do
54 + integrate_views
55 +
56 + include ConfigHelperMethods
57 +
58 + fixtures :users
59 + fixtures :problems
60 + fixtures :contests
61 +
62 + before(:each) do
63 + enable_multicontest
64 + end
65 +
66 + it "should list only available public problems to users with no contest assigned" do
67 + john = users(:john)
68 + get "list", {}, {:user_id => john.id}
69 +
70 + response.should render_template('main/list')
71 + response.should have_text(/add/)
72 + response.should_not have_text(/easy_problem/)
73 + response.should_not have_text(/hard_problem/)
74 + end
75 +
76 + it "should list available problems on a specific contest" do
77 + james = users(:james)
78 + get "list", {}, {:user_id => james.id}
79 +
80 + response.should render_template('main/list')
81 + response.should have_text(/add/)
82 + response.should have_text(/easy_problem/)
83 + response.should_not have_text(/hard_problem/)
84 + end
85 +
86 + it "should shows available problems by contests" do
87 + james = users(:james)
88 + get "list", {}, {:user_id => james.id}
89 +
90 + response.should render_template('main/list')
91 + response.should have_text(Regexp.new('Contest A.*easy_problem', Regexp::MULTILINE))
92 + end
93 +
94 + it "should shows available problems by contests; problems belonging to more the one contest should appear many times" do
95 + jack = users(:jack)
96 + get "list", {}, {:user_id => jack.id}
97 +
98 + response.should render_template('main/list')
99 + response.should have_text(Regexp.new('Contest A.*easy_problem.*Contest B.*easy_problem', Regexp::MULTILINE))
100 + response.should have_text(Regexp.new('Contest B.*hard_problem', Regexp::MULTILINE))
101 + end
102 + end
103 +
104 + describe MainController, "when a user loads sources and compiler messages" do
5 105
6 106 before(:each) do
7 107 @problem = mock(Problem, :name => 'test', :output_only => false)
8 108 @language = mock(Language, :name => 'cpp', :ext => 'cpp')
9 109 @submission = mock(Submission,
10 110 :id => 1,
11 111 :user_id => 1,
12 112 :problem => @problem,
13 113 :language => @language,
14 114 :source => 'sample source',
15 115 :compiler_message => 'none')
116 +
16 117 @user = mock(User, :id => 1, :login => 'john')
118 + @user.should_receive(:update_start_time).at_most(:once)
119 +
17 120 @another_user = mock(User, :id => 2, :login => 'mary')
18 - end
121 + @another_user.should_receive(:update_start_time).at_most(:once)
19 122
20 - it "should redirect user to login page when unlogged-in user try to access main/list" do
21 - get 'list'
22 - response.should redirect_to(:action => 'login')
123 + User.should_receive(:find).
124 + with(1).any_number_of_times.
125 + and_return(@user)
126 + User.should_receive(:find).
127 + with(2).any_number_of_times.
128 + and_return(@another_user)
129 + Submission.should_receive(:find).
130 + any_number_of_times.with(@submission.id.to_s).
131 + and_return(@submission)
23 132 end
24 133
25 134 it "should let user sees her own source" do
26 - Submission.should_receive(:find).with(@submission.id.to_s).and_return(@submission)
27 - User.should_receive(:find).with(1).and_return(@user)
28 - @user.should_receive(:update_start_time)
135 + @submission.should_receive(:download_filename).and_return("foo.c")
29 136 get 'source', {:id => @submission.id}, {:user_id => 1}
30 137 response.should be_success
31 138 end
32 139
33 140 it "should let user sees her own compiler message" do
34 - Submission.should_receive(:find).with(@submission.id.to_s).and_return(@submission)
35 - User.should_receive(:find).with(1).and_return(@user)
36 141 get 'compiler_msg', {:id => @submission.id}, {:user_id => 1}
37 142 response.should be_success
38 143 end
39 144
40 145 it "should not let user sees other user's source" do
41 - Submission.should_receive(:find).with(@submission.id.to_s).and_return(@submission)
42 - User.should_receive(:find).with(2).and_return(@another_user)
43 146 get 'source', {:id => @submission.id}, {:user_id => 2}
44 147 flash[:notice].should =~ /[Ee]rror/
45 148 response.should redirect_to(:action => 'list')
46 149 end
47 150
48 151 it "should not let user sees other user's compiler message" do
49 - Submission.should_receive(:find).with(@submission.id.to_s).and_return(@submission)
50 - User.should_receive(:find).with(2).and_return(@another_user)
51 152 get 'compiler_msg', {:id => @submission.id}, {:user_id => 2}
52 153 flash[:notice].should =~ /[Ee]rror/
53 154 response.should redirect_to(:action => 'list')
54 155 end
55 156
56 157 end
158 +
159 +
@@ -1,11 +1,24
1 1 # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2 2 one:
3 3 id: 1
4 4 name: add
5 5 full_name: add_full_name
6 6 available: true
7 +
7 8 two:
8 9 id: 2
9 10 name: subtract
10 11 full_name: subtract_full_name
11 12 available: false
13 +
14 + easy:
15 + name: easy_problem
16 + full_name: Easy Problem
17 + available: true
18 + contests: contest_a, contest_b
19 +
20 + hard:
21 + name: hard_problem
22 + full_name: Hard Problem
23 + available: true
24 + contests: contest_b
@@ -8,13 +8,27
8 8
9 9 john:
10 10 login: john
11 11 full_name: john
12 12 hashed_password: <%= User.encrypt("hello",salt) %>
13 13 salt: <%= salt %>
14 +
14 15 mary:
15 16 login: mary
16 17 full_name: mary
17 18 hashed_password: <%= User.encrypt("goodbye",salt) %>
18 19 salt: <%= salt %>
19 20 roles: admin
20 21
22 + james:
23 + login: james
24 + full_name: James
25 + hashed_password: <%= User.encrypt("morning",salt) %>
26 + salt: <%= salt %>
27 + contests: contest_a
28 +
29 + jack:
30 + login: jack
31 + full_name: Jack
32 + hashed_password: <%= User.encrypt("morning",salt) %>
33 + salt: <%= salt %>
34 + contests: contest_a, contest_b
@@ -1,20 +1,4
1 1 require File.dirname(__FILE__) + '/../test_helper'
2 2
3 3 class MainControllerTest < ActionController::TestCase
4 - fixtures :users
5 - fixtures :problems
6 -
7 - def test_should_redirect_new_user_to_login
8 - get :list
9 - assert_redirected_to :controller => 'main', :action => 'login'
10 4 end
11 -
12 - def test_should_list_available_problems_if_logged_in
13 - john = users(:john)
14 - get :list, {}, {:user_id => john.id}
15 -
16 - assert_template 'main/list'
17 - assert_select "table tr:nth-child(2)", :text => /\(add\)/
18 - end
19 -
20 - end
You need to be logged in to leave comments. Login now