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