Description:
logs out users after contests changed
Commit status:
[Not Reviewed]
References:
Comments:
0 Commit comments 0 Inline Comments
Unresolved TODOs:
There are no unresolved TODOs
Add another comment

r294:069c049fbc3a - - 22 files changed: 191 inserted, 192 deleted

@@ -0,0 +1,87
1 + require 'spec_helper'
2 + require 'config_spec_helper'
3 + require 'delorean'
4 +
5 + describe "ContestManagements" do
6 + include ConfigSpecHelperMethods
7 +
8 + fixtures :users
9 + fixtures :problems
10 + fixtures :contests
11 + fixtures :roles
12 +
13 + before(:each) do
14 + @admin_user = users(:mary)
15 + @contest_b = contests(:contest_b)
16 + @james = users(:james)
17 + @jack = users(:jack)
18 +
19 + set_contest_time_limit('3:00')
20 + set_indv_contest_mode
21 + end
22 +
23 + it "should reset users' timer when their contests change" do
24 + james_session = open_session
25 + james_session.extend(MainSessionMethods)
26 +
27 + james_login_and_get_main_list(james_session)
28 + james_session.response.should_not have_text(/OVER/)
29 +
30 + Delorean.time_travel_to(190.minutes.since) do
31 + james_session.get_main_list
32 + james_session.response.should have_text(/OVER/)
33 +
34 + james_session.get '/' # logout
35 + james_session.get '/main/list' # clearly log out
36 + james_session.response.should_not render_template 'main/list'
37 +
38 + admin_change_users_contest_to("james", @contest_b, true)
39 +
40 + james_login_and_get_main_list(james_session)
41 + james_session.response.should_not have_text(/OVER/)
42 + end
43 + end
44 +
45 + private
46 +
47 + module MainSessionMethods
48 + def login(login_name, password)
49 + post '/login/login', :login => login_name, :password => password
50 + assert_redirected_to '/main/list'
51 + end
52 +
53 + def get_main_list
54 + get '/main/list'
55 + assert_template 'main/list'
56 + end
57 + end
58 +
59 + module ContestManagementSessionMethods
60 + def change_users_contest_to(user_login_list, contest, reset_timer=false)
61 + post_data = {
62 + :contest => {:id => contest.id},
63 + :operation => 'assign',
64 + :login_list => user_login_list
65 + }
66 + post_data[:reset_timer] = true if reset_timer
67 + post '/user_admin/manage_contest', post_data
68 + end
69 + end
70 +
71 + def admin_change_users_contest_to(user_list, contest, reset_timer)
72 + admin_session = open_session
73 + admin_session.extend(MainSessionMethods)
74 + admin_session.extend(ContestManagementSessionMethods)
75 +
76 + admin_session.login('mary','goodbye')
77 + admin_session.get '/main/list'
78 + admin_session.change_users_contest_to(user_list, contest, reset_timer)
79 + end
80 +
81 + def james_login_and_get_main_list(session)
82 + session.login('james', 'morning')
83 + session.get_main_list
84 + end
85 +
86 + end
87 +
@@ -151,114 +151,121
151 151 @changed = true
152 152 end
153 153 end
154 154
155 155 # contest management
156 156
157 157 def add_to_contest
158 158 user = User.find(params[:id])
159 159 contest = Contest.find(params[:contest_id])
160 160 if user and contest
161 161 user.contests << contest
162 162 end
163 163 redirect_to :action => 'list'
164 164 end
165 165
166 166 def remove_from_contest
167 167 user = User.find(params[:id])
168 168 contest = Contest.find(params[:contest_id])
169 169 if user and contest
170 170 user.contests.delete(contest)
171 171 end
172 172 redirect_to :action => 'list'
173 173 end
174 174
175 175 def contest_management
176 176 end
177 177
178 178 def manage_contest
179 179 contest = Contest.find(params[:contest][:id])
180 180 if !contest
181 181 flash[:notice] = 'You did not choose the contest.'
182 182 redirect_to :action => 'contest_management' and return
183 183 end
184 184
185 185 operation = params[:operation]
186 186
187 187 if not ['add','remove','assign'].include? operation
188 188 flash[:notice] = 'You did not choose the operation to perform.'
189 189 redirect_to :action => 'contest_management' and return
190 190 end
191 191
192 192 lines = params[:login_list]
193 193 if !lines or lines.blank?
194 194 flash[:notice] = 'You entered an empty list.'
195 195 redirect_to :action => 'contest_management' and return
196 196 end
197 197
198 198 note = []
199 + user_ids = {}
199 200 lines.split("\n").each do |line|
200 - puts line
201 201 user = User.find_by_login(line.chomp)
202 - puts user
203 202 if user
204 203 if operation=='add'
205 - user.contests << contest
204 + if ! user.contests.include? contest
205 + user.contests << contest
206 + end
206 207 elsif operation=='remove'
207 208 user.contests.delete(contest)
208 209 else
209 210 user.contests = [contest]
210 211 end
211 -
212 +
212 213 user.contest_stat.destroy if params[:reset_timer]
213 214
214 215 note << user.login
216 + user_ids[user.id] = true
215 217 end
216 218 end
219 +
220 + if params[:reset_timer]
221 + logout_users(user_ids)
222 + end
223 +
217 224 flash[:notice] = 'User(s) ' + note.join(', ') +
218 225 ' were successfully modified. '
219 226 redirect_to :action => 'contest_management'
220 227 end
221 228
222 229 # admin management
223 230
224 231 def admin
225 232 @admins = User.find(:all).find_all {|user| user.admin? }
226 233 end
227 234
228 235 def grant_admin
229 236 login = params[:login]
230 237 user = User.find_by_login(login)
231 238 if user!=nil
232 239 admin_role = Role.find_by_name('admin')
233 240 user.roles << admin_role
234 241 else
235 242 flash[:notice] = 'Unknown user'
236 243 end
237 244 flash[:notice] = 'User added as admins'
238 245 redirect_to :action => 'admin'
239 246 end
240 247
241 248 def revoke_admin
242 249 user = User.find(params[:id])
243 250 if user==nil
244 251 flash[:notice] = 'Unknown user'
245 252 redirect_to :action => 'admin' and return
246 253 elsif user.login == 'root'
247 254 flash[:notice] = 'You cannot revoke admisnistrator permission from root.'
248 255 redirect_to :action => 'admin' and return
249 256 end
250 257
251 258 admin_role = Role.find_by_name('admin')
252 259 user.roles.delete(admin_role)
253 260 flash[:notice] = 'User permission revoked'
254 261 redirect_to :action => 'admin'
255 262 end
256 263
257 264 protected
258 265
259 266 def random_password(length=5)
260 267 chars = 'abcdefghijkmnopqrstuvwxyz23456789'
261 268 newpass = ""
262 269 length.times { newpass << chars[rand(chars.size-1)] }
263 270 return newpass
264 271 end
@@ -279,49 +286,58
279 286 countries[id] = c
280 287 @import_log << "Found #{country[:name]}\n"
281 288 else
282 289 countries[id] = Country.new(:name => country[:name])
283 290 countries[id].save
284 291 @import_log << "Created #{country[:name]}\n"
285 292 end
286 293 end
287 294
288 295 # import sites
289 296 sites = {}
290 297 site_data.each_pair do |id,site|
291 298 s = Site.find_by_name(site[:name])
292 299 if s!=nil
293 300 @import_log << "Found #{site[:name]}\n"
294 301 else
295 302 s = Site.new(:name => site[:name])
296 303 @import_log << "Created #{site[:name]}\n"
297 304 end
298 305 s.password = site[:password]
299 306 s.country = countries[site[:country_id]]
300 307 s.save
301 308 sites[id] = s
302 309 end
303 310
304 311 # import users
305 312 user_data.each_pair do |id,user|
306 313 u = User.find_by_login(user[:login])
307 314 if u!=nil
308 315 @import_log << "Found #{user[:login]}\n"
309 316 else
310 317 u = User.new(:login => user[:login])
311 318 @import_log << "Created #{user[:login]}\n"
312 319 end
313 320 u.full_name = user[:name]
314 321 u.password = user[:password]
315 322 u.country = countries[user[:country_id]]
316 323 u.site = sites[user[:site_id]]
317 324 u.activated = true
318 325 u.email = "empty-#{u.login}@none.com"
319 326 if not u.save
320 327 @import_log << "Errors\n"
321 328 u.errors.each { |attr,msg| @import_log << "#{attr} - #{msg}\n" }
322 329 end
323 330 end
324 331
325 332 end
326 333
334 + def logout_users(user_ids)
335 + sessions = ActiveRecord::SessionStore::Session.find(:all, :conditions => ["updated_at >= ?", 60.minutes.ago])
336 + sessions.each do |session|
337 + if user_ids.has_key? session.data[:user_id]
338 + session.destroy
339 + end
340 + end
341 + end
342 +
327 343 end
@@ -1,57 +1,59
1 1 require 'yaml'
2 2
3 3 #
4 4 # This class also contains various login of the system.
5 5 #
6 6 class Configuration < ActiveRecord::Base
7 7
8 8 SYSTEM_MODE_CONF_KEY = 'system.mode'
9 9 TEST_REQUEST_EARLY_TIMEOUT_KEY = 'contest.test_request.early_timeout'
10 + MULTICONTESTS_KEY = 'system.multicontests'
11 + CONTEST_TIME_LIMIT_KEY = 'contest.time_limit'
10 12
11 13 cattr_accessor :cache
12 14 cattr_accessor :config_cache
13 15 cattr_accessor :task_grading_info_cache
14 16 cattr_accessor :contest_time_str
15 17 cattr_accessor :contest_time
16 18
17 19 # set @@cache = true to only reload once.
18 20 Configuration.cache = false
19 21
20 22 Configuration.config_cache = nil
21 23 Configuration.task_grading_info_cache = nil
22 24
23 25 def self.get(key)
24 26 if Configuration.cache
25 27 if Configuration.config_cache == nil
26 28 self.read_config
27 29 end
28 30 return Configuration.config_cache[key]
29 31 else
30 32 return Configuration.read_one_key(key)
31 33 end
32 34 end
33 35
34 36 def self.[](key)
35 37 self.get(key)
36 38 end
37 39
38 40 def self.reload
39 41 self.read_config
40 42 end
41 43
42 44 def self.clear
43 45 Configuration.config_cache = nil
44 46 end
45 47
46 48 def self.cache?
47 49 Configuration.cache
48 50 end
49 51
50 52 def self.enable_caching
51 53 Configuration.cache = true
52 54 end
53 55
54 56 #
55 57 # View decision
56 58 #
57 59 def self.show_submitbox_to?(user)
@@ -62,111 +64,110
62 64 ((user.site.started!=true) or (user.site.finished?))
63 65 end
64 66 return true
65 67 end
66 68
67 69 def self.show_tasks_to?(user)
68 70 if time_limit_mode?
69 71 return false if not user.contest_started?
70 72 end
71 73 return true
72 74 end
73 75
74 76 def self.show_grading_result
75 77 return (get(SYSTEM_MODE_CONF_KEY)=='analysis')
76 78 end
77 79
78 80 def self.allow_test_request(user)
79 81 mode = get(SYSTEM_MODE_CONF_KEY)
80 82 early_timeout = get(TEST_REQUEST_EARLY_TIMEOUT_KEY)
81 83 if (mode=='contest')
82 84 return false if ((user.site!=nil) and
83 85 ((user.site.started!=true) or
84 86 (early_timeout and (user.site.time_left < 30.minutes))))
85 87 end
86 88 return false if mode=='analysis'
87 89 return true
88 90 end
89 91
90 92 def self.task_grading_info
91 93 if Configuration.task_grading_info_cache==nil
92 94 read_grading_info
93 95 end
94 96 return Configuration.task_grading_info_cache
95 97 end
96 98
97 99 def self.standard_mode?
98 100 return get(SYSTEM_MODE_CONF_KEY) == 'standard'
99 101 end
100 102
101 103 def self.contest_mode?
102 104 return get(SYSTEM_MODE_CONF_KEY) == 'contest'
103 105 end
104 106
105 107 def self.indv_contest_mode?
106 108 return get(SYSTEM_MODE_CONF_KEY) == 'indv-contest'
107 109 end
108 110
109 111 def self.multicontests?
110 - g = get('system.multicontests')
111 - return get('system.multicontests') == true
112 + return get(MULTICONTESTS_KEY) == true
112 113 end
113 114
114 115 def self.time_limit_mode?
115 116 mode = get(SYSTEM_MODE_CONF_KEY)
116 117 return ((mode == 'contest') or (mode == 'indv-contest'))
117 118 end
118 119
119 120 def self.analysis_mode?
120 121 return get(SYSTEM_MODE_CONF_KEY) == 'analysis'
121 122 end
122 123
123 124 def self.contest_time_limit
124 - contest_time_str = Configuration['contest.time_limit']
125 + contest_time_str = Configuration[CONTEST_TIME_LIMIT_KEY]
125 126
126 127 if not defined? Configuration.contest_time_str
127 128 Configuration.contest_time_str = nil
128 129 end
129 130
130 131 if Configuration.contest_time_str != contest_time_str
131 132 Configuration.contest_time_str = contest_time_str
132 133 if tmatch = /(\d+):(\d+)/.match(contest_time_str)
133 134 h = tmatch[1].to_i
134 135 m = tmatch[2].to_i
135 136
136 137 Configuration.contest_time = h.hour + m.minute
137 138 else
138 139 Configuration.contest_time = nil
139 140 end
140 141 end
141 142 return Configuration.contest_time
142 143 end
143 144
144 145 protected
145 146
146 147 def self.convert_type(val,type)
147 148 case type
148 149 when 'string'
149 150 return val
150 151
151 152 when 'integer'
152 153 return val.to_i
153 154
154 155 when 'boolean'
155 156 return (val=='true')
156 157 end
157 158 end
158 159
159 160 def self.read_config
160 161 Configuration.config_cache = {}
161 162 Configuration.find(:all).each do |conf|
162 163 key = conf.key
163 164 val = conf.value
164 165 Configuration.config_cache[key] = Configuration.convert_type(val,conf.value_type)
165 166 end
166 167 end
167 168
168 169 def self.read_one_key(key)
169 170 conf = Configuration.find_by_key(key)
170 171 if conf
171 172 return Configuration.convert_type(conf.value,conf.value_type)
172 173 else
@@ -109,100 +109,97
109 109 def verify_activation_key(key)
110 110 key == activation_key
111 111 end
112 112
113 113 def self.random_password(length=5)
114 114 chars = 'abcdefghjkmnopqrstuvwxyz'
115 115 password = ''
116 116 length.times { password << chars[rand(chars.length - 1)] }
117 117 password
118 118 end
119 119
120 120 def self.find_non_admin_with_prefix(prefix='')
121 121 users = User.find(:all)
122 122 return users.find_all { |u| !(u.admin?) and u.login.index(prefix)==0 }
123 123 end
124 124
125 125 # Contest information
126 126
127 127 def contest_time_left
128 128 if Configuration.contest_mode?
129 129 return nil if site==nil
130 130 return site.time_left
131 131 elsif Configuration.indv_contest_mode?
132 132 time_limit = Configuration.contest_time_limit
133 133 if time_limit == nil
134 134 return nil
135 135 end
136 136 if contest_stat==nil
137 137 return (Time.now.gmtime + time_limit) - Time.now.gmtime
138 138 else
139 139 finish_time = contest_stat.started_at + time_limit
140 140 current_time = Time.now.gmtime
141 141 if current_time > finish_time
142 142 return 0
143 143 else
144 144 return finish_time - current_time
145 145 end
146 146 end
147 147 else
148 148 return nil
149 149 end
150 150 end
151 151
152 152 def contest_finished?
153 153 if Configuration.contest_mode?
154 154 return false if site==nil
155 155 return site.finished?
156 156 elsif Configuration.indv_contest_mode?
157 - time_limit = Configuration.contest_time_limit
158 -
159 - return false if contest_stat==nil
160 -
157 + return false if self.contest_stat(true)==nil
161 158 return contest_time_left == 0
162 159 else
163 160 return false
164 161 end
165 162 end
166 163
167 164 def contest_started?
168 165 if Configuration.contest_mode?
169 166 return true if site==nil
170 167 return site.started
171 168 else
172 169 return true
173 170 end
174 171 end
175 172
176 173 def update_start_time
177 174 stat = self.contest_stat
178 175 if stat == nil
179 176 stat = UserContestStat.new(:user => self,
180 177 :started_at => Time.now.gmtime)
181 178 stat.save
182 179 end
183 180 end
184 181
185 182 def problem_in_user_contests?(problem)
186 183 problem_contests = problem.contests.all
187 184
188 185 if problem_contests.length == 0 # this is public contest
189 186 return true
190 187 end
191 188
192 189 contests.each do |contest|
193 190 if problem_contests.find {|c| c.id == contest.id }
194 191 return true
195 192 end
196 193 end
197 194 return false
198 195 end
199 196
200 197 def available_problems_group_by_contests
201 198 contest_problems = []
202 199 pin = {}
203 200 contests.enabled.each do |contest|
204 201 available_problems = contest.problems.available
205 202 contest_problems << {
206 203 :contest => contest,
207 204 :problems => available_problems
208 205 }
@@ -1,80 +1,80
1 1 CONFIGURATIONS =
2 2 [
3 3 {
4 4 :key => 'system.single_user_mode',
5 5 :value_type => 'boolean',
6 6 :default_value => 'false',
7 7 :description => 'Only admins can log in to the system when running under single user mode.'
8 8 },
9 9
10 10 {
11 11 :key => 'ui.front.title',
12 12 :value_type => 'string',
13 13 :default_value => 'Grader'
14 14 },
15 15
16 16 {
17 17 :key => 'ui.front.welcome_message',
18 18 :value_type => 'string',
19 19 :default_value => 'Welcome!'
20 20 },
21 21
22 22 {
23 23 :key => 'ui.show_score',
24 24 :value_type => 'boolean',
25 25 :default_value => 'true'
26 26 },
27 27
28 28 {
29 29 :key => 'contest.time_limit',
30 30 :value_type => 'string',
31 31 :default_value => 'unlimited',
32 - :description => 'Time limit in format hh:mm, or "unlimited" for contests with no time limits.'
32 + :description => 'Time limit in format hh:mm, or "unlimited" for contests with no time limits. This config is CACHED. Restart the server before the change can take effect.'
33 33 },
34 34
35 35 {
36 36 :key => 'system.mode',
37 37 :value_type => 'string',
38 38 :default_value => 'standard',
39 39 :description => 'Current modes are "standard", "contest", "indv-contest", and "analysis".'
40 40 },
41 41
42 42 {
43 43 :key => 'contest.name',
44 44 :value_type => 'string',
45 45 :default_value => 'Grader',
46 46 :description => 'This name will be shown on the user header bar.'
47 47 },
48 48
49 49 {
50 50 :key => 'contest.multisites',
51 51 :value_type => 'boolean',
52 52 :default_value => 'false',
53 53 :description => 'If the server is in contest mode and this option is true, on the log in of the admin a menu for site selections is shown.'
54 54 },
55 55
56 56 {
57 57 :key => 'system.online_registration',
58 58 :value_type => 'boolean',
59 59 :default_value => 'false',
60 60 :description => 'This option enables online registration.'
61 61 },
62 62
63 63 # If Configuration['system.online_registration'] is true, the
64 64 # system allows online registration, and will use these
65 65 # information for sending confirmation emails.
66 66 {
67 67 :key => 'system.online_registration.smtp',
68 68 :value_type => 'string',
69 69 :default_value => 'smtp.somehost.com'
70 70 },
71 71
72 72 {
73 73 :key => 'system.online_registration.from',
74 74 :value_type => 'string',
75 75 :default_value => 'your.email@address'
76 76 },
77 77
78 78 {
79 79 :key => 'system.admin_email',
80 80 :value_type => 'string',
@@ -1,20 +1,38
1 1
2 2 module ConfigSpecHelperMethods
3 3
4 4 def find_or_create_and_set_config(key, type, value)
5 5 c = Configuration.find_by_key(key)
6 6 c ||= Configuration.new(:key => key,
7 7 :value_type => type)
8 8 c.value = value
9 9 c.save!
10 10 end
11 11
12 12 def enable_multicontest
13 - find_or_create_and_set_config('system.multicontests','boolean','true')
13 + find_or_create_and_set_config(Configuration::MULTICONTESTS_KEY,
14 + 'boolean','true')
14 15 end
15 16
16 17 def disable_multicontest
17 - find_or_create_and_set_config('system.multicontests','boolean','false')
18 + find_or_create_and_set_config(Configuration::MULTICONTESTS_KEY,
19 + 'boolean','false')
20 + end
21 +
22 + def set_indv_contest_mode
23 + find_or_create_and_set_config(Configuration::SYSTEM_MODE_CONF_KEY,
24 + 'string','indv-contest')
18 25 end
19 26
27 + def set_standard_mode
28 + find_or_create_and_set_config(Configuration::SYSTEM_MODE_CONF_KEY,
29 + 'string','standard')
30 + end
31 +
32 + def set_contest_time_limit(limit)
33 + find_or_create_and_set_config(Configuration::CONTEST_TIME_LIMIT_KEY,
34 + 'string',limit)
35 + # clear old value
36 + Configuration.contest_time_str = nil
37 + end
20 38 end
@@ -1,48 +1,50
1 + require 'delorean'
2 +
1 3 require File.dirname(__FILE__) + '/../spec_helper'
2 4 require File.dirname(__FILE__) + '/../config_spec_helper'
3 5
4 6 describe MainController, "when a user comes to list page" do
5 7
6 8 it "should redirect user to login page when unlogged-in user try to access main/list" do
7 9 get 'list'
8 10 response.should redirect_to(:action => 'login')
9 11 end
10 12
11 13 end
12 14
13 15 describe MainController, "when a logged in user comes to list page, with multicontests off" do
14 16 integrate_views
15 17
16 18 include ConfigSpecHelperMethods
17 19
18 20 fixtures :users
19 21 fixtures :problems
20 22 fixtures :contests
21 23
22 24 before(:each) do
23 25 disable_multicontest
24 26 end
25 27
26 28 it "should list available problems" do
27 29 john = users(:john)
28 30 get "list", {}, {:user_id => john.id}
29 31
30 32 response.should render_template 'main/list'
31 33 response.should have_text(/add/)
32 34 response.should have_text(/easy_problem/)
33 35 response.should have_text(/hard_problem/)
34 36 end
35 37
36 38 end
37 39
38 40 describe MainController, "when a logged in user comes to list page, with multicontests on" do
39 41 integrate_views
40 42
41 43 include ConfigSpecHelperMethods
42 44
43 45 fixtures :users
44 46 fixtures :problems
45 47 fixtures :contests
46 48
47 49 before(:each) do
48 50 enable_multicontest
@@ -97,48 +99,95
97 99 :problem => @problem,
98 100 :language => @language,
99 101 :source => 'sample source',
100 102 :compiler_message => 'none')
101 103
102 104 @user = mock(User, :id => 1, :login => 'john')
103 105 @user.should_receive(:update_start_time).at_most(:once)
104 106
105 107 @another_user = mock(User, :id => 2, :login => 'mary')
106 108 @another_user.should_receive(:update_start_time).at_most(:once)
107 109
108 110 User.should_receive(:find).
109 111 with(1).any_number_of_times.
110 112 and_return(@user)
111 113 User.should_receive(:find).
112 114 with(2).any_number_of_times.
113 115 and_return(@another_user)
114 116 Submission.should_receive(:find).
115 117 any_number_of_times.with(@submission.id.to_s).
116 118 and_return(@submission)
117 119 end
118 120
119 121 it "should let user sees her own source" do
120 122 @submission.should_receive(:download_filename).and_return("foo.c")
121 123 get 'source', {:id => @submission.id}, {:user_id => 1}
122 124 response.should be_success
123 125 end
124 126
125 127 it "should let user sees her own compiler message" do
126 128 get 'compiler_msg', {:id => @submission.id}, {:user_id => 1}
127 129 response.should be_success
128 130 end
129 131
130 132 it "should not let user sees other user's source" do
131 133 get 'source', {:id => @submission.id}, {:user_id => 2}
132 134 flash[:notice].should =~ /[Ee]rror/
133 135 response.should redirect_to(:action => 'list')
134 136 end
135 137
136 138 it "should not let user sees other user's compiler message" do
137 139 get 'compiler_msg', {:id => @submission.id}, {:user_id => 2}
138 140 flash[:notice].should =~ /[Ee]rror/
139 141 response.should redirect_to(:action => 'list')
140 142 end
141 143
142 144 end
143 145
144 146
147 + describe MainController, "during individual contest mode" do
148 +
149 + integrate_views
150 +
151 + include ConfigSpecHelperMethods
152 +
153 + fixtures :users
154 + fixtures :problems
155 + fixtures :contests
156 +
157 + before(:each) do
158 + set_contest_time_limit('3:00') # 3 hours
159 + set_indv_contest_mode
160 + end
161 +
162 + it "should allow newly login user to see problem list" do
163 + john = users(:john)
164 + get "list", {}, {:user_id => john.id}
165 +
166 + response.should render_template 'main/list'
167 + response.should have_text(/add/)
168 + response.should have_text(/easy_problem/)
169 + response.should have_text(/hard_problem/)
170 + end
171 +
172 + it "should not show 'contest over' sign before the contest ends" do
173 + john = users(:john)
174 + get "list", {}, {:user_id => john.id}
175 +
176 + Delorean.time_travel_to(179.minutes.since) do
177 + get "list", {}, {:user_id => john.id}
178 + response.should_not have_text(/OVER/)
179 + end
180 + end
181 +
182 + it "should show 'contest over' sign after the contest ends" do
183 + john = users(:john)
184 + get "list", {}, {:user_id => john.id}
185 +
186 + Delorean.time_travel_to(181.minutes.since) do
187 + get "list", {}, {:user_id => john.id}
188 + response.should have_text(/OVER/)
189 + end
190 + end
191 +
192 + end
193 +
@@ -1,3 +1,4
1 1 # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2 2 admin:
3 + name: admin
3 4 rights: graders_right, user_admin_right, problems_right No newline at end of file
@@ -1,11 +1,11
1 1 # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
2 2
3 - one:
4 - name: MyString
3 + first_site:
4 + name: First site
5 5 started: false
6 6 start_time: 2008-04-09 14:08:28
7 7
8 - two:
9 - name: MyString
8 + second_site:
9 + name: Second site
10 10 started: false
11 11 start_time: 2008-04-09 14:08:28
@@ -1,34 +1,38
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 + activated: true
14 15
15 16 mary:
16 17 login: mary
17 18 full_name: mary
18 19 hashed_password: <%= User.encrypt("goodbye",salt) %>
19 20 salt: <%= salt %>
20 21 roles: admin
22 + activated: true
21 23
22 24 james:
23 25 login: james
24 26 full_name: James
25 27 hashed_password: <%= User.encrypt("morning",salt) %>
26 28 salt: <%= salt %>
27 29 contests: contest_a
30 + activated: true
28 31
29 32 jack:
30 33 login: jack
31 34 full_name: Jack
32 35 hashed_password: <%= User.encrypt("morning",salt) %>
33 36 salt: <%= salt %>
34 37 contests: contest_a, contest_b
38 + activated: true
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
deleted file
You need to be logged in to leave comments. Login now