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

@@ -100,202 +100,248
100 100 if @submission.user_id == session[:user_id]
101 101 render :action => 'compiler_msg', :layout => 'empty'
102 102 else
103 103 flash[:notice] = 'Error viewing source'
104 104 redirect_to :action => 'list'
105 105 end
106 106 end
107 107
108 108 def submission
109 109 @user = User.find(session[:user_id])
110 110 @problems = Problem.find_available_problems
111 111 if params[:id]==nil
112 112 @problem = nil
113 113 @submissions = nil
114 114 else
115 115 @problem = Problem.find_by_name(params[:id])
116 116 if not @problem.available
117 117 redirect_to :action => 'list'
118 118 flash[:notice] = 'Error: submissions for that problem are not viewable.'
119 119 return
120 120 end
121 121 @submissions = Submission.find_all_by_user_problem(@user.id, @problem.id)
122 122 end
123 123 end
124 124
125 125 def result
126 126 if !Configuration.show_grading_result
127 127 redirect_to :action => 'list' and return
128 128 end
129 129 @user = User.find(session[:user_id])
130 130 @submission = Submission.find(params[:id])
131 131 if @submission.user!=@user
132 132 flash[:notice] = 'You are not allowed to view result of other users.'
133 133 redirect_to :action => 'list' and return
134 134 end
135 135 prepare_grading_result(@submission)
136 136 end
137 137
138 138 def load_output
139 139 if !Configuration.show_grading_result or params[:num]==nil
140 140 redirect_to :action => 'list' and return
141 141 end
142 142 @user = User.find(session[:user_id])
143 143 @submission = Submission.find(params[:id])
144 144 if @submission.user!=@user
145 145 flash[:notice] = 'You are not allowed to view result of other users.'
146 146 redirect_to :action => 'list' and return
147 147 end
148 148 case_num = params[:num].to_i
149 149 out_filename = output_filename(@user.login,
150 150 @submission.problem.name,
151 151 @submission.id,
152 152 case_num)
153 153 if !FileTest.exists?(out_filename)
154 154 flash[:notice] = 'Output not found.'
155 155 redirect_to :action => 'list' and return
156 156 end
157 157
158 158 response.headers['Content-Type'] = "application/force-download"
159 159 response.headers['Content-Disposition'] = "attachment; filename=\"output-#{case_num}.txt\""
160 160 response.headers["X-Sendfile"] = out_filename
161 161 response.headers['Content-length'] = File.size(out_filename)
162 162 render :nothing => true
163 163 end
164 164
165 165 def error
166 166 @user = User.find(session[:user_id])
167 167 end
168 168
169 169 # announcement refreshing and hiding methods
170 170
171 171 def announcements
172 172 if params.has_key? 'recent'
173 173 prepare_announcements(params[:recent])
174 174 else
175 175 prepare_announcements
176 176 end
177 177 render(:partial => 'announcement',
178 178 :collection => @announcements,
179 179 :locals => {:announcement_effect => true})
180 180 end
181 181
182 182 protected
183 183
184 184 def prepare_announcements(recent=nil)
185 185 if Configuration.show_tasks_to?(@user)
186 186 @announcements = Announcement.find_published(true)
187 187 else
188 188 @announcements = Announcement.find_published
189 189 end
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
212 258 @user = User.find(session[:user_id])
213 259 if (!Configuration.show_tasks_to?(@user)) and
214 260 ((action_name=='submission') or (action_name=='submit'))
215 261 redirect_to :action => 'list' and return
216 262 end
217 263 end
218 264
219 265 def prepare_grading_result(submission)
220 266 if Configuration.task_grading_info.has_key? submission.problem.name
221 267 grading_info = Configuration.task_grading_info[submission.problem.name]
222 268 else
223 269 # guess task info from problem.full_score
224 270 cases = submission.problem.full_score / 10
225 271 grading_info = {
226 272 'testruns' => cases,
227 273 'testcases' => cases
228 274 }
229 275 end
230 276 @test_runs = []
231 277 if grading_info['testruns'].is_a? Integer
232 278 trun_count = grading_info['testruns']
233 279 trun_count.times do |i|
234 280 @test_runs << [ read_grading_result(@user.login,
235 281 submission.problem.name,
236 282 submission.id,
237 283 i+1) ]
238 284 end
239 285 else
240 286 grading_info['testruns'].keys.sort.each do |num|
241 287 run = []
242 288 testrun = grading_info['testruns'][num]
243 289 testrun.each do |c|
244 290 run << read_grading_result(@user.login,
245 291 submission.problem.name,
246 292 submission.id,
247 293 c)
248 294 end
249 295 @test_runs << run
250 296 end
251 297 end
252 298 end
253 299
254 300 def grading_result_dir(user_name, problem_name, submission_id, case_num)
255 301 return "#{GRADING_RESULT_DIR}/#{user_name}/#{problem_name}/#{submission_id}/test-result/#{case_num}"
256 302 end
257 303
258 304 def output_filename(user_name, problem_name, submission_id, case_num)
259 305 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
260 306 return "#{dir}/output.txt"
261 307 end
262 308
263 309 def read_grading_result(user_name, problem_name, submission_id, case_num)
264 310 dir = grading_result_dir(user_name,problem_name, submission_id, case_num)
265 311 result_file_name = "#{dir}/result"
266 312 if !FileTest.exists?(result_file_name)
267 313 return {:num => case_num, :msg => 'program did not run'}
268 314 else
269 315 results = File.open(result_file_name).readlines
270 316 run_stat = extract_running_stat(results)
271 317 output_filename = "#{dir}/output.txt"
272 318 if FileTest.exists?(output_filename)
273 319 output_file = true
274 320 output_size = File.size(output_filename)
275 321 else
276 322 output_file = false
277 323 output_size = 0
278 324 end
279 325
280 326 return {
281 327 :num => case_num,
282 328 :msg => results[0],
283 329 :run_stat => run_stat,
284 330 :output => output_file,
285 331 :output_size => output_size
286 332 }
287 333 end
288 334 end
289 335
290 336 # copied from grader/script/lib/test_request_helper.rb
291 337 def extract_running_stat(results)
292 338 running_stat_line = results[-1]
293 339
294 340 # extract exit status line
295 341 run_stat = ""
296 342 if !(/[Cc]orrect/.match(results[0]))
297 343 run_stat = results[0].chomp
298 344 else
299 345 run_stat = 'Program exited normally'
300 346 end
301 347
@@ -13,166 +13,170
13 13 cattr_accessor :task_grading_info
14 14 cattr_accessor :contest_time_str
15 15 cattr_accessor :contest_time
16 16
17 17 # set @@cache = true to only reload once.
18 18 Configuration.cache = false
19 19
20 20 Configuration.config_cache = nil
21 21 Configuration.task_grading_info = nil
22 22
23 23 def self.get(key)
24 24 if Configuration.cache
25 25 if Configuration.config_cache == nil
26 26 self.read_config
27 27 end
28 28 return Configuration.config_cache[key]
29 29 else
30 30 return Configuration.read_one_key(key)
31 31 end
32 32 end
33 33
34 34 def self.[](key)
35 35 self.get(key)
36 36 end
37 37
38 38 def self.reload
39 39 self.read_config
40 40 end
41 41
42 42 def self.clear
43 43 Configuration.config_cache = nil
44 44 end
45 45
46 46 def self.cache?
47 47 Configuration.cache
48 48 end
49 49
50 50 def self.enable_caching
51 51 Configuration.cache = true
52 52 end
53 53
54 54 #
55 55 # View decision
56 56 #
57 57 def self.show_submitbox_to?(user)
58 58 mode = get(SYSTEM_MODE_CONF_KEY)
59 59 return false if mode=='analysis'
60 60 if (mode=='contest')
61 61 return false if (user.site!=nil) and
62 62 ((user.site.started!=true) or (user.site.finished?))
63 63 end
64 64 return true
65 65 end
66 66
67 67 def self.show_tasks_to?(user)
68 68 if time_limit_mode?
69 69 return false if not user.contest_started?
70 70 end
71 71 return true
72 72 end
73 73
74 74 def self.show_grading_result
75 75 return (get(SYSTEM_MODE_CONF_KEY)=='analysis')
76 76 end
77 77
78 78 def self.allow_test_request(user)
79 79 mode = get(SYSTEM_MODE_CONF_KEY)
80 80 early_timeout = get(TEST_REQUEST_EARLY_TIMEOUT_KEY)
81 81 if (mode=='contest')
82 82 return false if ((user.site!=nil) and
83 83 ((user.site.started!=true) or
84 84 (early_timeout and (user.site.time_left < 30.minutes))))
85 85 end
86 86 return false if mode=='analysis'
87 87 return true
88 88 end
89 89
90 90 def self.task_grading_info
91 91 if Configuration.task_grading_info==nil
92 92 read_grading_info
93 93 end
94 94 return Configuration.task_grading_info
95 95 end
96 96
97 97 def self.standard_mode?
98 98 return get(SYSTEM_MODE_CONF_KEY) == 'standard'
99 99 end
100 100
101 101 def self.contest_mode?
102 102 return get(SYSTEM_MODE_CONF_KEY) == 'contest'
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?
115 119 return get(SYSTEM_MODE_CONF_KEY) == 'analysis'
116 120 end
117 121
118 122 def self.contest_time_limit
119 123 contest_time_str = Configuration['contest.time_limit']
120 124
121 125 if not defined? Configuration.contest_time_str
122 126 Configuration.contest_time_str = nil
123 127 end
124 128
125 129 if Configuration.contest_time_str != contest_time_str
126 130 Configuration.contest_time_str = contest_time_str
127 131 if tmatch = /(\d+):(\d+)/.match(contest_time_str)
128 132 h = tmatch[1].to_i
129 133 m = tmatch[2].to_i
130 134
131 135 Configuration.contest_time = h.hour + m.minute
132 136 else
133 137 Configuration.contest_time = nil
134 138 end
135 139 end
136 140 return Configuration.contest_time
137 141 end
138 142
139 143 protected
140 144
141 145 def self.convert_type(val,type)
142 146 case type
143 147 when 'string'
144 148 return val
145 149
146 150 when 'integer'
147 151 return val.to_i
148 152
149 153 when 'boolean'
150 154 return (val=='true')
151 155 end
152 156 end
153 157
154 158 def self.read_config
155 159 Configuration.config_cache = {}
156 160 Configuration.find(:all).each do |conf|
157 161 key = conf.key
158 162 val = conf.value
159 163 Configuration.config_cache[key] = Configuration.convert_type(val,conf.value_type)
160 164 end
161 165 end
162 166
163 167 def self.read_one_key(key)
164 168 conf = Configuration.find_by_key(key)
165 169 if conf
166 170 return Configuration.convert_type(conf.value,conf.value_type)
167 171 else
168 172 return nil
169 173 end
170 174 end
171 175
172 176 def self.read_grading_info
173 177 f = File.open(TASK_GRADING_INFO_FILENAME)
174 178 Configuration.task_grading_info = YAML.load(f)
175 179 f.close
176 180 end
177 181
178 182 end
@@ -1,106 +1,108
1 1 class Problem < ActiveRecord::Base
2 2
3 3 belongs_to :description
4 4 has_and_belongs_to_many :contests
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
22 24 if not problem.valid?
23 25 return problem, 'Error importing'
24 26 end
25 27
26 28 problem.full_score = 100
27 29 problem.date_added = Time.new
28 30 problem.test_allowed = true
29 31 problem.output_only = false
30 32 problem.available = false
31 33
32 34 if not problem.save
33 35 return problem, 'Error importing'
34 36 end
35 37
36 38 import_to_db = params.has_key? :import_to_db
37 39
38 40 importer = TestdataImporter.new(problem)
39 41
40 42 if not importer.import_from_file(import_params[:file],
41 43 import_params[:time_limit],
42 44 import_params[:memory_limit],
43 45 import_to_db)
44 46 problem.errors.add_to_base('Import error.')
45 47 end
46 48
47 49 return problem, importer.log_msg
48 50 end
49 51
50 52 def self.download_file_basedir
51 53 return "#{RAILS_ROOT}/data/tasks"
52 54 end
53 55
54 56 protected
55 57
56 58 def self.to_i_or_default(st, default)
57 59 if st!=''
58 60 st.to_i
59 61 else
60 62 default
61 63 end
62 64 end
63 65
64 66 def self.extract_params_and_check(params, problem)
65 67 time_limit = Problem.to_i_or_default(params[:time_limit],
66 68 DEFAULT_TIME_LIMIT)
67 69 memory_limit = Problem.to_i_or_default(params[:memory_limit],
68 70 DEFAULT_MEMORY_LIMIT)
69 71
70 72 if time_limit==0 and time_limit_s!='0'
71 73 problem.errors.add_to_base('Time limit format errors.')
72 74 elsif time_limit<=0 or time_limit >60
73 75 problem.errors.add_to_base('Time limit out of range.')
74 76 end
75 77
76 78 if memory_limit==0 and memory_limit_s!='0'
77 79 problem.errors.add_to_base('Memory limit format errors.')
78 80 elsif memory_limit<=0 or memory_limit >512
79 81 problem.errors.add_to_base('Memory limit out of range.')
80 82 end
81 83
82 84 if params[:file]==nil or params[:file]==''
83 85 problem.errors.add_to_base('No testdata file.')
84 86 end
85 87
86 88 file = params[:file]
87 89
88 90 if problem.errors.length!=0
89 91 return problem
90 92 end
91 93
92 94 problem.name = params[:name]
93 95 if params[:full_name]!=''
94 96 problem.full_name = params[:full_name]
95 97 else
96 98 problem.full_name = params[:name]
97 99 end
98 100
99 101 return {
100 102 :time_limit => time_limit,
101 103 :memory_limit => memory_limit,
102 104 :file => file
103 105 }
104 106 end
105 107
106 108 end
@@ -1,18 +1,18
1 1 <tr class="info-<%= (problem_counter%2==0) ? "even" : "odd" %>">
2 2 <td>
3 3 <%= "#{problem_counter+1}" %>
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>
@@ -1,38 +1,51
1 1 - content_for :head do
2 2 = javascript_include_tag :defaults
3 3 = javascript_include_tag 'announcement_refresh.js'
4 4
5 5 = user_title_bar(@user)
6 6
7 7 .announcementbox{:style => (@announcements.length==0 ? "display:none" : "")}
8 8 %span{:class => 'title'}
9 9 Announcements
10 10 #announcementbox-body
11 11 = render :partial => 'announcement', :collection => @announcements
12 12
13 13 - if Configuration.show_submitbox_to?(@user)
14 14 .submitbox
15 15 = error_messages_for 'submission'
16 16 = render :partial => 'submission_box'
17 17
18 18
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();
38 51
@@ -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
@@ -1,20 +1,34
1 1 # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2 2
3 3 <%
4 4 User.public_class_method :encrypt
5 5
6 6 salt = "abc"
7 7 %>
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