Test that GET on message#new can't send a message
[rails.git] / test / controllers / message_controller_test.rb
1 require "test_helper"
2
3 class MessageControllerTest < ActionController::TestCase
4   fixtures :users
5
6   ##
7   # test all routes which lead to this controller
8   def test_routes
9     assert_routing(
10       { :path => "/user/username/inbox", :method => :get },
11       { :controller => "message", :action => "inbox", :display_name => "username" }
12     )
13     assert_routing(
14       { :path => "/user/username/outbox", :method => :get },
15       { :controller => "message", :action => "outbox", :display_name => "username" }
16     )
17     assert_routing(
18       { :path => "/message/new/username", :method => :get },
19       { :controller => "message", :action => "new", :display_name => "username" }
20     )
21     assert_routing(
22       { :path => "/message/new/username", :method => :post },
23       { :controller => "message", :action => "new", :display_name => "username" }
24     )
25     assert_routing(
26       { :path => "/message/read/1", :method => :get },
27       { :controller => "message", :action => "read", :message_id => "1" }
28     )
29     assert_routing(
30       { :path => "/message/mark/1", :method => :post },
31       { :controller => "message", :action => "mark", :message_id => "1" }
32     )
33     assert_routing(
34       { :path => "/message/reply/1", :method => :get },
35       { :controller => "message", :action => "reply", :message_id => "1" }
36     )
37     assert_routing(
38       { :path => "/message/reply/1", :method => :post },
39       { :controller => "message", :action => "reply", :message_id => "1" }
40     )
41     assert_routing(
42       { :path => "/message/delete/1", :method => :post },
43       { :controller => "message", :action => "delete", :message_id => "1" }
44     )
45   end
46
47   ##
48   # test fetching new message page when not logged in
49   def test_new_no_login
50     # Check that the new message page requires us to login
51     get :new, :display_name => users(:public_user).display_name
52     assert_redirected_to login_path(:referer => new_message_path(:display_name => users(:public_user).display_name))
53   end
54
55   ##
56   # test fetching new message page when logged in
57   def test_new_form
58     # Login as a normal user
59     session[:user] = users(:normal_user).id
60
61     # Check that the new message page loads
62     get :new, :display_name => users(:public_user).display_name
63     assert_response :success
64     assert_template "new"
65     assert_select "title", "OpenStreetMap | Send message"
66     assert_select "form[action='#{new_message_path(:display_name => users(:public_user).display_name)}']", :count => 1 do
67       assert_select "input#message_title", :count => 1
68       assert_select "textarea#message_body", :count => 1
69       assert_select "input[type='submit'][value='Send']", :count => 1
70     end
71   end
72
73   ##
74   # test fetching new message page with body and title
75   def test_new_get_with_params
76     # Login as a normal user
77     session[:user] = users(:normal_user).id
78
79     # Check that we can't send a message from a GET request
80     assert_difference "ActionMailer::Base.deliveries.size", 0 do
81       assert_difference "Message.count", 0 do
82         get :new,
83             :display_name => users(:public_user).display_name,
84             :message => { :title => "Test Message", :body => "Test message body" }
85       end
86     end
87     assert_response :success
88     assert_template "new"
89     assert_select "title", "OpenStreetMap | Send message"
90     assert_select "form[action='#{new_message_path(:display_name => users(:public_user).display_name)}']", :count => 1 do
91       assert_select "input#message_title", :count => 1 do
92         assert_select "[value='Test Message']"
93       end
94       assert_select "textarea#message_body", :text => "Test message body", :count => 1
95       assert_select "input[type='submit'][value='Send']", :count => 1
96     end
97   end
98
99   ##
100   # test posting new message page with no body
101   def test_new_post_no_body
102     # Login as a normal user
103     session[:user] = users(:normal_user).id
104
105     # Check that the subject is preserved over errors
106     assert_difference "ActionMailer::Base.deliveries.size", 0 do
107       assert_difference "Message.count", 0 do
108         post :new,
109              :display_name => users(:public_user).display_name,
110              :message => { :title => "Test Message", :body => "" }
111       end
112     end
113     assert_response :success
114     assert_template "new"
115     assert_select "title", "OpenStreetMap | Send message"
116     assert_select "form[action='#{new_message_path(:display_name => users(:public_user).display_name)}']", :count => 1 do
117       assert_select "input#message_title", :count => 1 do
118         assert_select "[value='Test Message']"
119       end
120       assert_select "textarea#message_body", :text => "", :count => 1
121       assert_select "input[type='submit'][value='Send']", :count => 1
122     end
123   end
124
125   ##
126   # test posting new message page with no title
127   def test_new_post_no_title
128     # Login as a normal user
129     session[:user] = users(:normal_user).id
130
131     # Check that the body text is preserved over errors
132     assert_difference "ActionMailer::Base.deliveries.size", 0 do
133       assert_difference "Message.count", 0 do
134         post :new,
135              :display_name => users(:public_user).display_name,
136              :message => { :title => "", :body => "Test message body" }
137       end
138     end
139     assert_response :success
140     assert_template "new"
141     assert_select "title", "OpenStreetMap | Send message"
142     assert_select "form[action='#{new_message_path(:display_name => users(:public_user).display_name)}']", :count => 1 do
143       assert_select "input#message_title", :count => 1 do
144         assert_select "[value='']"
145       end
146       assert_select "textarea#message_body", :text => "Test message body", :count => 1
147       assert_select "input[type='submit'][value='Send']", :count => 1
148     end
149   end
150
151   ##
152   # test posting new message page sends message
153   def test_new_post_send
154     # Login as a normal user
155     session[:user] = users(:normal_user).id
156
157     # Check that sending a message works
158     assert_difference "ActionMailer::Base.deliveries.size", 1 do
159       assert_difference "Message.count", 1 do
160         post :new,
161              :display_name => users(:public_user).display_name,
162              :message => { :title => "Test Message", :body => "Test message body" }
163       end
164     end
165     assert_redirected_to inbox_path(:display_name => users(:normal_user).display_name)
166     assert_equal "Message sent", flash[:notice]
167     e = ActionMailer::Base.deliveries.first
168     assert_equal [users(:public_user).email], e.to
169     assert_equal "[OpenStreetMap] Test Message", e.subject
170     assert_match /Test message body/, e.text_part.decoded
171     assert_match /Test message body/, e.html_part.decoded
172     ActionMailer::Base.deliveries.clear
173     m = Message.last
174     assert_equal users(:normal_user).id, m.from_user_id
175     assert_equal users(:public_user).id, m.to_user_id
176     assert_in_delta Time.now, m.sent_on, 2
177     assert_equal "Test Message", m.title
178     assert_equal "Test message body", m.body
179     assert_equal "markdown", m.body_format
180
181     # Asking to send a message with a bogus user name should fail
182     get :new, :display_name => "non_existent_user"
183     assert_response :not_found
184     assert_template "user/no_such_user"
185     assert_select "h1", "The user non_existent_user does not exist"
186   end
187
188   ##
189   # test the new action message limit
190   def test_new_limit
191     # Login as a normal user
192     session[:user] = users(:normal_user).id
193
194     # Check that sending a message fails when the message limit is hit
195     assert_no_difference "ActionMailer::Base.deliveries.size" do
196       assert_no_difference "Message.count" do
197         with_message_limit(0) do
198           post :new,
199                :display_name => users(:public_user).display_name,
200                :message => { :title => "Test Message", :body => "Test message body" }
201           assert_response :success
202           assert_template "new"
203           assert_select ".error", /wait a while/
204         end
205       end
206     end
207   end
208
209   ##
210   # test the reply action
211   def test_reply
212     unread_message = create(:message, :unread, :sender => users(:normal_user), :recipient => users(:public_user))
213
214     # Check that the message reply page requires us to login
215     get :reply, :message_id => unread_message.id
216     assert_redirected_to login_path(:referer => reply_message_path(:message_id => unread_message.id))
217
218     # Login as the wrong user
219     session[:user] = users(:second_public_user).id
220
221     # Check that we can't reply to somebody else's message
222     get :reply, :message_id => unread_message.id
223     assert_redirected_to login_path(:referer => reply_message_path(:message_id => unread_message.id))
224     assert_equal "You are logged in as `pulibc_test2' but the message you have asked to reply to was not sent to that user. Please login as the correct user in order to reply.", flash[:notice]
225
226     # Login as the right user
227     session[:user] = users(:public_user).id
228
229     # Check that the message reply page loads
230     get :reply, :message_id => unread_message.id
231     assert_response :success
232     assert_template "new"
233     assert_select "title", "OpenStreetMap | Re: #{unread_message.title}"
234     assert_select "form[action='#{new_message_path(:display_name => users(:normal_user).display_name)}']", :count => 1 do
235       assert_select "input#message_title[value='Re: #{unread_message.title}']", :count => 1
236       assert_select "textarea#message_body", :count => 1
237       assert_select "input[type='submit'][value='Send']", :count => 1
238     end
239     assert_equal true, Message.find(unread_message.id).message_read
240
241     # Asking to reply to a message with no ID should fail
242     assert_raise ActionController::UrlGenerationError do
243       get :reply
244     end
245
246     # Asking to reply to a message with a bogus ID should fail
247     get :reply, :message_id => 99999
248     assert_response :not_found
249     assert_template "no_such_message"
250   end
251
252   ##
253   # test the read action
254   def test_read
255     unread_message = create(:message, :unread, :sender => users(:normal_user), :recipient => users(:public_user))
256
257     # Check that the read message page requires us to login
258     get :read, :message_id => unread_message.id
259     assert_redirected_to login_path(:referer => read_message_path(:message_id => unread_message.id))
260
261     # Login as the wrong user
262     session[:user] = users(:second_public_user).id
263
264     # Check that we can't read the message
265     get :read, :message_id => unread_message.id
266     assert_redirected_to login_path(:referer => read_message_path(:message_id => unread_message.id))
267     assert_equal "You are logged in as `pulibc_test2' but the message you have asked to read was not sent by or to that user. Please login as the correct user in order to read it.", flash[:notice]
268
269     # Login as the message sender
270     session[:user] = users(:normal_user).id
271
272     # Check that the message sender can read the message
273     get :read, :message_id => unread_message.id
274     assert_response :success
275     assert_template "read"
276     assert_equal false, Message.find(unread_message.id).message_read
277
278     # Login as the message recipient
279     session[:user] = users(:public_user).id
280
281     # Check that the message recipient can read the message
282     get :read, :message_id => unread_message.id
283     assert_response :success
284     assert_template "read"
285     assert_equal true, Message.find(unread_message.id).message_read
286
287     # Asking to read a message with no ID should fail
288     assert_raise ActionController::UrlGenerationError do
289       get :read
290     end
291
292     # Asking to read a message with a bogus ID should fail
293     get :read, :message_id => 99999
294     assert_response :not_found
295     assert_template "no_such_message"
296   end
297
298   ##
299   # test the inbox action
300   def test_inbox
301     read_message = create(:message, :read, :recipient => users(:normal_user))
302     # Check that the inbox page requires us to login
303     get :inbox, :display_name => users(:normal_user).display_name
304     assert_redirected_to login_path(:referer => inbox_path(:display_name => users(:normal_user).display_name))
305
306     # Login
307     session[:user] = users(:normal_user).id
308
309     # Check that we can view our inbox when logged in
310     get :inbox, :display_name => users(:normal_user).display_name
311     assert_response :success
312     assert_template "inbox"
313     assert_select "table.messages", :count => 1 do
314       assert_select "tr", :count => 2
315       assert_select "tr#inbox-#{read_message.id}.inbox-row", :count => 1
316     end
317
318     # Check that we can't view somebody else's inbox when logged in
319     get :inbox, :display_name => users(:public_user).display_name
320     assert_redirected_to inbox_path(:display_name => users(:normal_user).display_name)
321   end
322
323   ##
324   # test the outbox action
325   def test_outbox
326     create(:message, :sender => users(:normal_user))
327
328     # Check that the outbox page requires us to login
329     get :outbox, :display_name => users(:normal_user).display_name
330     assert_redirected_to login_path(:referer => outbox_path(:display_name => users(:normal_user).display_name))
331
332     # Login
333     session[:user] = users(:normal_user).id
334
335     # Check that we can view our outbox when logged in
336     get :outbox, :display_name => users(:normal_user).display_name
337     assert_response :success
338     assert_template "outbox"
339     assert_select "table.messages", :count => 1 do
340       assert_select "tr", :count => 2
341       assert_select "tr.inbox-row", :count => 1
342     end
343
344     # Check that we can't view somebody else's outbox when logged in
345     get :outbox, :display_name => users(:public_user).display_name
346     assert_redirected_to outbox_path(:display_name => users(:normal_user).display_name)
347   end
348
349   ##
350   # test the mark action
351   def test_mark
352     unread_message = create(:message, :unread, :sender => users(:normal_user), :recipient => users(:public_user))
353
354     # Check that the marking a message requires us to login
355     post :mark, :message_id => unread_message.id
356     assert_response :forbidden
357
358     # Login as a user with no messages
359     session[:user] = users(:second_public_user).id
360
361     # Check that marking a message we didn't send or receive fails
362     post :mark, :message_id => unread_message.id
363     assert_response :not_found
364     assert_template "no_such_message"
365
366     # Login as the message recipient
367     session[:user] = users(:public_user).id
368
369     # Check that the marking a message read works
370     post :mark, :message_id => unread_message.id, :mark => "read"
371     assert_redirected_to inbox_path(:display_name => users(:public_user).display_name)
372     assert_equal true, Message.find(unread_message.id).message_read
373
374     # Check that the marking a message unread works
375     post :mark, :message_id => unread_message.id, :mark => "unread"
376     assert_redirected_to inbox_path(:display_name => users(:public_user).display_name)
377     assert_equal false, Message.find(unread_message.id).message_read
378
379     # Check that the marking a message read via XHR works
380     xhr :post, :mark, :message_id => unread_message.id, :mark => "read"
381     assert_response :success
382     assert_template "mark"
383     assert_equal true, Message.find(unread_message.id).message_read
384
385     # Check that the marking a message unread via XHR works
386     xhr :post, :mark, :message_id => unread_message.id, :mark => "unread"
387     assert_response :success
388     assert_template "mark"
389     assert_equal false, Message.find(unread_message.id).message_read
390
391     # Asking to mark a message with no ID should fail
392     assert_raise ActionController::UrlGenerationError do
393       post :mark
394     end
395
396     # Asking to mark a message with a bogus ID should fail
397     post :mark, :message_id => 99999
398     assert_response :not_found
399     assert_template "no_such_message"
400   end
401
402   ##
403   # test the delete action
404   def test_delete
405     read_message = create(:message, :read, :recipient => users(:normal_user), :sender => users(:public_user))
406     sent_message = create(:message, :unread, :recipient => users(:public_user), :sender => users(:normal_user))
407
408     # Check that the deleting a message requires us to login
409     post :delete, :message_id => read_message.id
410     assert_response :forbidden
411
412     # Login as a user with no messages
413     session[:user] = users(:second_public_user).id
414
415     # Check that deleting a message we didn't send or receive fails
416     post :delete, :message_id => read_message.id
417     assert_response :not_found
418     assert_template "no_such_message"
419
420     # Login as the message recipient
421     session[:user] = users(:normal_user).id
422
423     # Check that the deleting a received message works
424     post :delete, :message_id => read_message.id
425     assert_redirected_to inbox_path(:display_name => users(:normal_user).display_name)
426     assert_equal "Message deleted", flash[:notice]
427     m = Message.find(read_message.id)
428     assert_equal true, m.from_user_visible
429     assert_equal false, m.to_user_visible
430
431     # Check that the deleting a sent message works
432     post :delete, :message_id => sent_message.id, :referer => outbox_path(:display_name => users(:normal_user).display_name)
433     assert_redirected_to outbox_path(:display_name => users(:normal_user).display_name)
434     assert_equal "Message deleted", flash[:notice]
435     m = Message.find(sent_message.id)
436     assert_equal false, m.from_user_visible
437     assert_equal true, m.to_user_visible
438
439     # Asking to delete a message with no ID should fail
440     assert_raise ActionController::UrlGenerationError do
441       post :delete
442     end
443
444     # Asking to delete a message with a bogus ID should fail
445     post :delete, :message_id => 99999
446     assert_response :not_found
447     assert_template "no_such_message"
448   end
449
450   private
451
452   def with_message_limit(value)
453     max_messages_per_hour = Object.send("remove_const", "MAX_MESSAGES_PER_HOUR")
454     Object.const_set("MAX_MESSAGES_PER_HOUR", value)
455
456     yield
457
458     Object.send("remove_const", "MAX_MESSAGES_PER_HOUR")
459     Object.const_set("MAX_MESSAGES_PER_HOUR", max_messages_per_hour)
460   end
461 end