Resyncing from head 10895:11795
[rails.git] / test / unit / message_test.rb
1 require File.dirname(__FILE__) + '/../test_helper'
2
3 class MessageTest < Test::Unit::TestCase
4   fixtures :messages, :users
5
6   EURO = "\xe2\x82\xac" #euro symbol
7
8   # This needs to be updated when new fixtures are added
9   # or removed.
10   def test_check_message_count
11     assert_equal 2, Message.count
12   end
13
14   def test_check_empty_message_fails
15     message = Message.new
16     assert !message.valid?
17     assert message.errors.invalid?(:title)
18     assert message.errors.invalid?(:body)
19     assert message.errors.invalid?(:sent_on)
20     assert true, message.message_read
21   end
22   
23   def test_validating_msgs
24     message = messages(:one)
25     assert message.valid?
26     massage = messages(:two)
27     assert message.valid?
28   end
29   
30   def test_invalid_send_recipient
31     message = messages(:one)
32     message.sender = nil
33     message.recipient = nil
34     assert !message.valid?
35
36     assert_raise(ActiveRecord::RecordNotFound) { User.find(0) }
37     message.from_user_id = 0
38     message.to_user_id = 0
39     assert_raise(ActiveRecord::RecordInvalid) {message.save!}
40   end
41
42   def test_utf8_roundtrip
43     (1..255).each do |i|
44       assert_message_ok('c', i)
45       assert_message_ok(EURO, i)
46     end
47   end
48
49   def test_length_oversize
50     assert_raise(ActiveRecord::RecordInvalid) { make_message('c', 256).save! }
51     assert_raise(ActiveRecord::RecordInvalid) { make_message(EURO, 256).save! }
52   end
53
54   def test_invalid_utf8
55     # See e.g http://en.wikipedia.org/wiki/UTF-8 for byte sequences
56     # FIXME - Invalid Unicode characters can still be encoded into "valid" utf-8 byte sequences - maybe check this too?
57     invalid_sequences = ["\xC0",         # always invalid utf8
58                          "\xC2\x4a",     # 2-byte multibyte identifier, followed by plain ASCII
59                          "\xC2\xC2",     # 2-byte multibyte identifier, followed by another one
60                          "\x4a\x82",     # plain ASCII, followed by multibyte continuation
61                          "\x82\x82",     # multibyte continuations without multibyte identifier
62                          "\xe1\x82\x4a", # three-byte identifier, contination and (incorrectly) plain ASCII
63                         ]
64     invalid_sequences.each do |char|
65       begin
66         # create a message and save to the database
67         msg = make_message(char, 1)
68         # if the save throws, thats fine and the test should pass, as we're
69         # only testing invalid sequences anyway.
70         msg.save! 
71
72         # get the saved message back and check that it is identical - i.e: 
73         # its OK to accept invalid UTF-8 as long as we return it unmodified.
74         db_msg = msg.class.find(msg.id)
75         assert_equal char, db_msg.title, "Database silently truncated message title"
76
77       rescue ActiveRecord::RecordInvalid
78         # because we only test invalid sequences it is OK to barf on them
79       end
80     end
81   end  
82
83   def make_message(char, count)
84     message = messages(:one)
85     message.title = char * count
86     return message
87   end
88
89   def assert_message_ok(char, count)
90     message = make_message(char, count)
91     assert message.save!
92     response = message.class.find(message.id) # stand by for some ├╝ber-generalisation...
93     assert_equal char * count, response.title, "message with #{count} #{char} chars (i.e. #{char.length*count} bytes) fails"
94   end
95
96 end