1 # Copyright (C) 2007, 2008, 2009, 2010 Heiko Bernloehr (FreeIT.de).
3 # This file is part of ECS.
5 # ECS is free software: you can redistribute it and/or modify it
6 # under the terms of the GNU Affero General Public License as
7 # published by the Free Software Foundation, either version 3 of
8 # the License, or (at your option) any later version.
10 # ECS is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 # Affero General Public License for more details.
15 # You should have received a copy of the GNU Affero General Public
16 # License along with ECS. If not, see <http://www.gnu.org/licenses/>.
21 class MessagesControllerTest < ActionController::TestCase
24 # param2: controller method, e.g. :index
25 # param3: http headers, e.g. { "X-EcsAuthId" => "ganz geheim", ... }
26 # param4: URI path, e.g. "/numlab/solutions/3"
27 # param5: controller params, e.g. { :id => 3, ... }
28 def myrequest(http_method, controller_method, uri_path, http_headers=nil, controller_params={})
29 request.path = uri_path
31 controller_params.merge!(:id => $~.to_s) unless $~.to_s.blank?
32 http_headers.each do |key,value|
33 request.headers[key] = value
35 s = "#{http_method} :#{controller_method}, params: #{controller_params}"
41 myrequest("get", :index,
42 "/#{ressources(:numlab_ex).namespace}/#{ressources(:numlab_ex).ressource}",
43 "X-EcsAuthId" => identities(:ulm_id1).name
46 assert_equal [1,2], assigns(:list).map {|e| e.id}
49 test "show first exercise as a receiver" do
50 myrequest("get", :show,
51 "/#{ressources(:numlab_ex).namespace}/#{ressources(:numlab_ex).ressource}/#{messages(:numlab_ex1).id}",
52 "X-EcsAuthId" => identities(:ulm_id1).name
55 assert_equal "Hallo Ihr da im Radio.", @response.body.strip
56 assert_equal "X-EcsSender: "+memberships(:stgt_wuv).id.to_s, "X-EcsSender: "+@response.header['X-EcsSender']
57 assert_equal "X-EcsReceiverCommunities: "+communities(:wuv).id.to_s, "X-EcsReceiverCommunities: "+@response.header['X-EcsReceiverCommunities']
60 test "show solution" do
61 myrequest("get", :show,
62 "/#{ressources(:numlab_solutions).namespace}/#{ressources(:numlab_solutions).ressource}/#{messages(:numlab_sol).id}",
63 "X-EcsAuthId" => identities(:ulm_id1).name
68 # not a receiver or sender of :numlab_ex1
69 test "show forbidden exercise" do
70 myrequest("get", :show,
71 "/#{ressources(:numlab_ex).namespace}/#{ressources(:numlab_ex).ressource}/#{messages(:numlab_ulm_ex1).id}",
72 "X-EcsAuthId" => identities(:numlab_comp_id1).name
77 test "show exercise as original sender but not as a receiver" do
78 myrequest("get", :show,
79 "/#{ressources(:numlab_ex).namespace}/#{ressources(:numlab_ex).ressource}/#{messages(:numlab_ulm_ex1).id}",
80 "X-EcsAuthId" => identities(:ulm_id1).name
83 assert !@response.header.has_key?('X-EcsSender')
84 assert !@response.header.has_key?('X-EcsReceiverCommunities')
87 test "create_X-EcsReceiverMemberships" do
88 mm_count = MembershipMessage.all.count
89 myrequest("post", :create,
90 "/#{ressources(:numlab_ex).namespace}/#{ressources(:numlab_ex).ressource}",
92 "X-EcsAuthId" => identities(:stgt_id1).name,
93 "X-EcsReceiverMemberships" => memberships(:ulm_wuv).id.to_s,
94 "CONTENT_TYPE" => "text/html",
95 "RAW_POST_DATA" => "hallole"
99 assert_equal assigns(:record).sender, assigns(:participant).id
100 assert_equal mm_count+1, MembershipMessage.all.count
101 assert_match /^.*\/numlab\/exercises\/[0-9]+$/, @response.header['Location']
104 test "create_X-EcsReceiverCommunities_single" do
105 mm_count = MembershipMessage.all.count
106 myrequest("post", :create,
107 "/#{ressources(:numlab_ex).namespace}/#{ressources(:numlab_ex).ressource}",
109 "X-EcsAuthId" => identities(:stgt_id1).name,
110 "X-EcsReceiverCommunities" => communities(:suv).name,
111 "CONTENT_TYPE" => "text/html",
112 "RAW_POST_DATA" => "hallole"
116 assert_equal assigns(:record).sender, assigns(:participant).id
117 assert_equal mm_count+1, MembershipMessage.all.count
120 test "create_X-EcsReceiverCommunities_multi" do
121 mm_count = MembershipMessage.all.count
122 myrequest("post", :create,
123 "/#{ressources(:numlab_ex).namespace}/#{ressources(:numlab_ex).ressource}",
125 "X-EcsAuthId" => identities(:stgt_id1).name,
126 "X-EcsReceiverCommunities" => communities(:suv).name + "," + communities(:public).name,
127 "CONTENT_TYPE" => "text/html",
128 "RAW_POST_DATA" => "hallole"
132 assert_equal assigns(:record).sender, assigns(:participant).id
133 assert_equal mm_count+3, MembershipMessage.all.count
136 test "create_X-EcsReceiverCommunities_multi_string_and_number" do
137 mm_count = MembershipMessage.all.count
138 myrequest("post", :create,
139 "/#{ressources(:numlab_ex).namespace}/#{ressources(:numlab_ex).ressource}",
141 "X-EcsAuthId" => identities(:stgt_id1).name,
142 "X-EcsReceiverCommunities" => communities(:suv).name + "," + communities(:public).name,
143 "CONTENT_TYPE" => "text/html",
144 "RAW_POST_DATA" => "hallole"
148 assert_equal assigns(:record).sender, assigns(:participant).id
149 assert_equal mm_count+3, MembershipMessage.all.count
153 myrequest("post", :update,
154 "/#{ressources(:numlab_ex).namespace}/#{ressources(:numlab_ex).ressource}/#{messages(:numlab_ex2).id}",
156 "X-EcsAuthId" => identities(:stgt_id1).name,
157 "X-EcsReceiverMemberships" => memberships(:ulm_wuv).id.to_s,
158 "CONTENT_TYPE" => "text/html",
159 "RAW_POST_DATA" => "neuer Text"
165 test "update with event generation" do
166 ev_count = Event.all.count
167 m= Message.find(messages(:numlab_ex2).id)
168 m.ressource.events= true
170 myrequest("post", :update,
171 "/#{ressources(:numlab_ex).namespace}/#{ressources(:numlab_ex).ressource}/#{messages(:numlab_ex2).id}",
173 "X-EcsAuthId" => identities(:stgt_id1).name,
174 "X-EcsReceiverMemberships" => memberships(:ulm_wuv).id.to_s,
175 "CONTENT_TYPE" => "text/html",
176 "RAW_POST_DATA" => "neuer Text"
180 assert_equal ev_count+1, Event.all.count
181 ev= Event.order(:id).last
182 assert_equal ev.ev_type_id, 3
183 m= Message.find(messages(:numlab_ex2).id)
184 m.ressource.events= false
188 test "update without ownership" do
189 myrequest("post", :update,
190 "/#{ressources(:numlab_ex).namespace}/#{ressources(:numlab_ex).ressource}/#{messages(:numlab_ex2).id}",
192 "X-EcsAuthId" => identities(:ulm_id1).name,
193 "X-EcsReceiverMemberships" => memberships(:ulm_wuv).id.to_s,
194 "CONTENT_TYPE" => "text/html",
195 "RAW_POST_DATA" => "neuer Text"
201 # not a receiver or sender of :numlab_sol
202 test "delete_forbidden_solution" do
203 myrequest("post", :destroy,
204 "/#{ressources(:numlab_solutions).namespace}/#{ressources(:numlab_solutions).ressource}/#{messages(:numlab_sol).id}",
205 "X-EcsAuthId" => identities(:numlab_comp_id1).name
210 # Owner deletes his message for which he is concurrently a receiver.
211 # This should only be possible until he clears its receiver queue. Then the
212 # next delete operation removes the message from ECS and also destroys all other
213 # receiver references.
214 test "delete_postrouted_message_as_owner_and_receiver_with_references_in_place" do
215 refscount= MembershipMessage.where(:message_id => messages(:numlab_ex1)).count
217 myrequest("post", :destroy,
218 "/#{ressources(:numlab_ex).namespace}/#{ressources(:numlab_ex).ressource}/#{messages(:numlab_ex1).id}",
219 "X-EcsAuthId" => identities(:stgt_id1).name
222 myrequest("get", :show,
223 "/#{ressources(:numlab_ex).namespace}/#{ressources(:numlab_ex).ressource}/#{messages(:numlab_ex1).id}",
224 "X-EcsAuthId" => identities(:stgt_id1).name
227 assert MembershipMessage.where(:message_id => messages(:numlab_ex1)).count == refscount - 1
228 # message is only tagged as removed (events on). physically it's still there.
229 assert_nothing_raised { Message.find(messages(:numlab_ex1).id) }
230 # This destroy is processed as role "sender", because the receiver quueue of the sender
231 # participant is now empty. Therefore all receiver references were deleted.
232 myrequest("post", :destroy,
233 "/#{ressources(:numlab_ex).namespace}/#{ressources(:numlab_ex).ressource}/#{messages(:numlab_ex1).id}",
234 "X-EcsAuthId" => identities(:stgt_id1).name
237 myrequest("get", :show,
238 "/#{ressources(:numlab_ex).namespace}/#{ressources(:numlab_ex).ressource}/#{messages(:numlab_ex1).id}",
239 "X-EcsAuthId" => identities(:stgt_id1).name
242 assert_equal 0, MembershipMessage.where(:message_id => messages(:numlab_ex1)).count
243 # message is only tagged as removed (events on). physically it's still there.
244 assert_nothing_raised { Message.find(messages(:numlab_ex1).id) }
247 test "delete_postrouted_message_as_owner_with_references_in_place" do
248 assert MembershipMessage.where(:message_id => messages(:numlab_ulm_ex1)).count > 0
249 myrequest("post", :destroy,
250 "/#{ressources(:numlab_ex).namespace}/#{ressources(:numlab_ex).ressource}/#{messages(:numlab_ulm_ex1).id}",
251 "X-EcsAuthId" => identities(:ulm_id1).name
254 myrequest("get", :show,
255 "/#{ressources(:numlab_ex).namespace}/#{ressources(:numlab_ex).ressource}/#{messages(:numlab_ulm_ex1).id}",
256 "X-EcsAuthId" => identities(:ulm_id1).name
259 assert_equal 0, MembershipMessage.where(:message_id => messages(:numlab_ulm_ex1)).count
260 # message is only tagged as removed (events on). physically it's still there.
261 assert_nothing_raised { Message.find(messages(:numlab_ulm_ex1).id) }
264 test "delete_postrouted_message_as_none_owner_with_references_in_place" do
265 #@request.set_REQUEST_URI("/numlab/exercises/99999")
266 #@request.headers["X-EcsAuthId"] = identities(:stgt_id1).name
267 mm_count = MembershipMessage.all.count
268 # destroy message through receiver and none owner
269 #post :destroy, { :id => messages(:numlab_ulm_ex1).id }
270 myrequest("post", :destroy,
271 "/#{ressources(:numlab_ex).namespace}/#{ressources(:numlab_ex).ressource}/#{messages(:numlab_ulm_ex1).id}",
272 "X-EcsAuthId" => identities(:stgt_id1).name
275 assert_nothing_raised { Message.find(@request.parameters[:id]) }
276 assert_equal 0, MembershipMessage.where(:message_id => @request.parameters[:id]).count
277 assert_equal Membership.find_by_participant_id_and_community_id(participants(:ilias_ulm),communities(:wuv)).id.to_s, @response["X-EcsSender"]
278 assert_equal communities(:wuv).id.to_s, @response["X-EcsReceiverCommunities"]
281 test "delete_none_postrouted_message_as_none_owner_with_last_reference_in_place" do
282 mm_count = MembershipMessage.all.count
283 myrequest("post", :create,
284 "/#{ressources(:numlab_solutions).namespace}/#{ressources(:numlab_solutions).ressource}",
286 "X-EcsAuthId" => identities(:stgt_id1).name,
287 "X-EcsReceiverMemberships" => memberships(:numlab_comp).id.to_s,
288 "CONTENT_TYPE" => "text/plain",
289 "RAW_POST_DATA" => "Diese Nachricht ist volatil.\r\n"
293 assert_equal assigns(:record).sender, assigns(:participant).id
294 assert_equal mm_count+1, MembershipMessage.all.count
295 # destroy message through receiver
296 /[0-9]+$/ =~ response.header['Location']
297 memberships = Membership.receiver(identities(:numlab_comp_id1).participant, $~.to_s.to_i)
298 myrequest("post", :destroy,
299 "/#{ressources(:numlab_solutions).namespace}/#{ressources(:numlab_solutions).ressource}/#{$~.to_s.to_i}",
300 "X-EcsAuthId" => identities(:numlab_comp_id1).name
303 assert_equal $~.to_s, @request.parameters[:id]
304 assert_nothing_raised { Message.find(@request.parameters[:id]) }
305 assert_nil MembershipMessage.find_by_message_id(@request.parameters[:id])
306 assert_equal Membership.find_by_participant_id_and_community_id(participants(:ilias_stgt),communities(:public)).id.to_s, @response["X-EcsSender"]
307 assert_equal communities(:public).id.to_s, @response["X-EcsReceiverCommunities"]
310 test "delete_none_postrouted_message_as_none_owner_with_references_in_place" do
311 #@request.headers["RAW_POST_DATA"] = "Diese Nachricht ist volatil.\r\n"
312 #@request.headers["CONTENT_TYPE"] = "text/plain"
313 #@request.headers["X-EcsAuthId"] = identities(:stgt_id1).name
314 #@request.headers["X-EcsReceiverMemberships"] = memberships(:numlab_comp).id.to_s+","+memberships(:numlab_teacher).id.to_s
315 #@request.set_REQUEST_URI("/numlab/solutions")
316 mm_count = MembershipMessage.all.count
318 myrequest("post", :create,
319 "/#{ressources(:numlab_solutions).namespace}/#{ressources(:numlab_solutions).ressource}",
321 "X-EcsAuthId" => identities(:stgt_id1).name,
322 "X-EcsReceiverMemberships" => memberships(:numlab_comp).id.to_s+","+memberships(:numlab_teacher).id.to_s,
323 "CONTENT_TYPE" => "text/plain",
324 "RAW_POST_DATA" => "Diese Nachricht ist volatil.\r\n"
328 assert_equal assigns(:record).sender, assigns(:participant).id
329 assert_equal mm_count+2, MembershipMessage.all.count
330 /[0-9]+$/ =~ response.header['Location']
331 assert_equal 2, MembershipMessage.where(:message_id => $~.to_s.to_i).count
332 # destroy message through receiver
333 #@request.set_REQUEST_URI("/numlab/solutions")
334 #@request.headers["X-EcsAuthId"] = identities(:numlab_comp_id1).name
335 #post :destroy, { :id => $~.to_s.to_i }
336 myrequest("delete", :destroy,
337 "/#{ressources(:numlab_solutions).namespace}/#{ressources(:numlab_solutions).ressource}/#{$~.to_s.to_i}",
338 "X-EcsAuthId" => identities(:numlab_comp_id1).name
341 assert_equal $~.to_s, @request.parameters[:id]
342 assert_nothing_raised { Message.find(@request.parameters[:id]) }
343 assert_equal 1, MembershipMessage.where(:message_id => $~.to_s.to_i).count
348 test "fifo get idempotent" do
349 myrequest("get", :fifo,
350 "/#{ressources(:numlab_ex).namespace}/#{ressources(:numlab_ex).ressource}",
351 "X-EcsAuthId" => identities(:ulm_id1).name
354 assert_equal "Hallo Ihr da im Radio.", @response.body.strip
355 myrequest("get", :fifo,
356 "/#{ressources(:numlab_ex).namespace}/#{ressources(:numlab_ex).ressource}",
357 "X-EcsAuthId" => identities(:ulm_id1).name
360 assert_equal "Hallo Ihr da im Radio.", @response.body.strip
361 assert_equal Membership.find_by_participant_id_and_community_id(participants(:ilias_stgt),communities(:wuv)).id.to_s, @response["X-EcsSender"]
362 assert_equal communities(:wuv).id.to_s, @response["X-EcsReceiverCommunities"]
365 test "fifo get not idempotent" do
366 myrequest("post", :fifo,
367 "/#{ressources(:numlab_ex).namespace}/#{ressources(:numlab_ex).ressource}",
368 "X-EcsAuthId" => identities(:ulm_id1).name
371 assert_equal "Hallo Ihr da im Radio.", @response.body.strip
372 assert_equal Membership.find_by_participant_id_and_community_id(participants(:ilias_stgt),communities(:wuv)).id.to_s, @response["X-EcsSender"]
373 assert_equal communities(:wuv).id.to_s, @response["X-EcsReceiverCommunities"]
374 myrequest("post", :fifo,
375 "/#{ressources(:numlab_ex).namespace}/#{ressources(:numlab_ex).ressource}",
376 "X-EcsAuthId" => identities(:ulm_id1).name
379 assert_not_equal "Hallo Ihr da im Radio.", @response.body.strip
380 assert_equal "Achtung ein Kartoon.", @response.body.strip
383 test "lifo get idempotent" do
384 myrequest("get", :lifo,
385 "/#{ressources(:numlab_ex).namespace}/#{ressources(:numlab_ex).ressource}",
386 "X-EcsAuthId" => identities(:ulm_id1).name
389 assert_equal "Achtung ein Kartoon.", @response.body.strip
390 myrequest("get", :lifo,
391 "/#{ressources(:numlab_ex).namespace}/#{ressources(:numlab_ex).ressource}",
392 "X-EcsAuthId" => identities(:ulm_id1).name
395 assert_equal "Achtung ein Kartoon.", @response.body.strip
398 test "lifo get not idempotent" do
399 myrequest("post", :lifo,
400 "/#{ressources(:numlab_ex).namespace}/#{ressources(:numlab_ex).ressource}",
401 "X-EcsAuthId" => identities(:ulm_id1).name
404 assert_equal "Achtung ein Kartoon.", @response.body.strip
405 myrequest("post", :lifo,
406 "/#{ressources(:numlab_ex).namespace}/#{ressources(:numlab_ex).ressource}",
407 "X-EcsAuthId" => identities(:ulm_id1).name
410 assert_not_equal "Achtung ein Kartoon.", @response.body.strip
411 assert_equal "Hallo Ihr da im Radio.", @response.body.strip
417 test "create_auths_url" do
418 request.headers["X-EcsAuthId"] = identities(:stgt_id1).name
419 request.headers["X-EcsReceiverMemberships"] = memberships(:ulm_wuv).id.to_s
420 request.headers["CONTENT_TYPE"] = "application/json"
421 request.path = "/sys/auths"
422 post :create, body: '{"url":"https://ilias.uni-stuttgart.de/goto.php?target=crs_95034&client_id=USTGT"}'
426 test "create_auths_realm" do
427 request.headers["X-EcsAuthId"] = identities(:stgt_id1).name
428 request.headers["X-EcsReceiverMemberships"] = memberships(:ulm_wuv).id.to_s
429 request.headers["CONTENT_TYPE"] = "application/json"
430 request.path = "/sys/auths"
431 post :create, body: '{"realm":"https://ilias.uni-stuttgart.de/goto.php?target=crs_95034&client_id=USTGT"}'
435 test "create_auths_invalid_json_mimetype" do
436 request.headers["X-EcsAuthId"] = identities(:stgt_id1).name
437 request.headers["X-EcsReceiverMemberships"] = memberships(:ulm_wuv).id.to_s
438 request.headers["CONTENT_TYPE"] = "text/html"
439 request.path = "/sys/auths"
440 post :create, body: '{"realm":"Universität Stuttgart"}'
442 assert_equal "Body format has to be in JSON", assigns(:http_error).to_s
446 # test "create_auths_invalid_json_body" do
447 # mm_count = MembershipMessage.all.count
448 # myrequest("post", :create,
451 # "X-EcsAuthId" => identities(:stgt_id1).name,
452 # "X-EcsReceiverMemberships" => memberships(:ulm_wuv).id.to_s,
453 # "CONTENT_TYPE" => "application/json",
454 # "RAW_POST_DATA" => '{"realm"::"https://ilias.uni-stuttgart.de/goto.php?target=crs_95034&client_id=USTGT"}'
457 # assert_response 400
458 # assert_equal "Invalid JSON body", assigns(:http_error).to_s
461 test "create_auths_eov_younger_than_sov" do
462 raw_post_data = <<-'HERE'
464 "realm":"https://ilias.uni-stuttgart.de/goto.php?target=crs_95034&client_id=USTGT",
465 "sov": "2011-03-08T23:25:27+01:00",
466 "eov": "2011-03-08T23:25:17+01:00"
469 request.headers["X-EcsAuthId"] = identities(:stgt_id1).name
470 request.headers["X-EcsReceiverMemberships"] = memberships(:ulm_wuv).id.to_s
471 request.headers["CONTENT_TYPE"] = "application/json"
472 request.path = "/sys/auths"
473 post :create, body: raw_post_data
475 assert_equal "invalid times either in sov or eov", assigns(:http_error).to_s
478 test "create_auths_sov_younger_than_current_time" do
479 raw_post_data = <<-'HERE'
481 "realm":"https://ilias.uni-stuttgart.de/goto.php?target=crs_95034&client_id=USTGT",
482 "sov": "2011-03-08T23:25:27+01:00"
485 request.headers["X-EcsAuthId"] = identities(:stgt_id1).name
486 request.headers["X-EcsReceiverMemberships"] = memberships(:ulm_wuv).id.to_s
487 request.headers["CONTENT_TYPE"] = "application/json"
488 request.path = "/sys/auths"
489 post :create, body: raw_post_data
491 assert_equal "sov time is younger then current time", assigns(:http_error).to_s
494 test "create_auths_eov_too_young" do
495 raw_post_data = <<-"HERE"
497 "realm":"https://ilias.uni-stuttgart.de/goto.php?target=crs_95034&client_id=USTGT",
498 "eov": "#{(Time.now + 1.second).xmlschema}"
501 request.headers["X-EcsAuthId"] = identities(:stgt_id1).name
502 request.headers["X-EcsReceiverMemberships"] = memberships(:ulm_wuv).id.to_s
503 request.headers["CONTENT_TYPE"] = "application/json"
504 #request.path = "/sys/auths"
505 request.path = "/sys/auths"
506 post :create, body: raw_post_data
508 assert_equal "eov time is too young", assigns(:http_error).to_s
511 # test "delete_auths" do
512 # #@request.headers["X-EcsAuthId"] = identities(:ulm_id1).name
513 # #@request.set_REQUEST_URI("/sys/auths/#{auths(:valid).one_touch_hash}")
514 # auths_count= Auth.all.length
515 # messages_count= Message.all.length
516 # auth_valid_id= auths(:valid).id
517 # message_auth_valid_id= messages(:auth_valid).id
518 # request.headers["X-EcsAuthId"] = identities(:ulm_id1).name
519 # request.path = "/sys/auths/#{auths(:valid).one_touch_hash}"
521 # assert_response 200
522 # assert_equal messages_count-1, Message.all.length
523 # assert_equal auths_count-1, Auth.all.length
524 # assert_raise(ActiveRecord::RecordNotFound){Auth.find(auth_valid_id)}
525 # assert_raise(ActiveRecord::RecordNotFound){Message.find(message_auth_valid_id)}
531 test "create anonymous client" do
532 @request.headers["CONTENT_TYPE"] = "application/json"
533 @request.set_REQUEST_URI("/numlab/exercises")
534 mm_count = MembershipMessage.all.count
537 assert_match /ecs_anonymous=.*/, @response.headers["Set-Cookie"].to_s
538 assert_equal mm_count+1, MembershipMessage.all.count
539 end if ECS_CONFIG["participants"]["allow_anonymous"]