# coding:utf-8 import zlib from nose.tools import * from mock import * from flanker.mime.message.headers import MimeHeaders from flanker.mime.message.errors import DecodingError from cStringIO import StringIO from .... import * def headers_case_insensitivity_test(): h = MimeHeaders() h['Content-Type'] = 1 eq_(1, h['Content-Type']) eq_(1, h['conTenT-TyPE']) ok_('cOnTenT-TyPE' in h) ok_('Content-Type' in h) eq_(1, h.get('Content-Type')) eq_(None, h.get('Content-Type2')) eq_([('Content-Type', 1)], h.items()) def headers_order_preserved_test(): headers = [('mime-version', '1'), ('rEceived', '2'), ('mime-version', '3'), ('ReceiveD', '4')] h = MimeHeaders(headers) # various types of iterations should_be = [('Mime-Version', '1'), ('Received', '2'), ('Mime-Version', '3'), ('Received', '4')] eq_(should_be, h.items()) ok_(isinstance(h.items(), list)) eq_(should_be, [p for p in h.iteritems()]) # iterate over keys keys = ['Mime-Version', 'Received', 'Mime-Version', 'Received'] eq_(keys, [p for p in h]) eq_(keys, h.keys()) def headers_boolean_test(): eq_(False, bool(MimeHeaders())) eq_(True, bool(MimeHeaders([('A', 1)]))) def headers_to_string_test(): ok_(str(MimeHeaders([('A', 1)]))) def headers_multiple_values_test(): headers = [('mime-version', '1'), ('rEceived', '2'), ('mime-version', '3'), ('ReceiveD', '4')] h = MimeHeaders(headers) eq_(['1', '3'], h.getall('Mime-Version')) # set re-sets all values for the message h['Mime-Version'] = '5' eq_(['5'], h.getall('Mime-Version')) # use add to add more values h.add('Received', '6') eq_(['2', '4', '6'], h.getall('Received')) # use prepend to insert header in the begining of the list h.prepend('Received', '0') eq_(['0', '2', '4', '6'], h.getall('Received')) # delete removes it all! del h['RECEIVED'] eq_([], h.getall('Received')) def headers_length_test(): h = MimeHeaders() eq_(0, len(h)) headers = [('mime-version', '1'), ('rEceived', '2'), ('mime-version', '3'), ('ReceiveD', '4')] h = MimeHeaders(headers) eq_(4, len(h)) def headers_alternation_test(): headers = [('mime-version', '1'), ('rEceived', '2'), ('mime-version', '3'), ('ReceiveD', '4')] h = MimeHeaders(headers) assert_false(h.have_changed()) h.prepend('Received', 'Yo') ok_(h.have_changed()) h = MimeHeaders(headers) del h['Mime-Version'] ok_(h.have_changed()) h = MimeHeaders(headers) h['Mime-Version'] = 'a' ok_(h.have_changed()) h = MimeHeaders(headers) h.add('Mime-Version', 'a') ok_(h.have_changed()) h = MimeHeaders(headers) h.getall('Mime-Version') h.get('o') assert_false(h.have_changed()) def headers_transform_test(): headers = [('mime-version', '1'), ('rEceived', '2'), ('mime-version', '3'), ('ReceiveD', '4')] h = MimeHeaders(headers) # transform tracks whether anything actually changed h.transform(lambda key,val: (key, val)) assert_false(h.have_changed()) # ok, now something have changed, make sure we've preserved order and did not collapse anything h.transform(lambda key,val: ("X-{0}".format(key), "t({0})".format(val))) ok_(h.have_changed()) eq_([('X-Mime-Version', 't(1)'), ('X-Received', 't(2)'), ('X-Mime-Version', 't(3)'), ('X-Received', 't(4)')], h.items()) def headers_parsing_empty_test(): h = MimeHeaders.from_stream(StringIO("")) eq_(0, len(h)) def headers_parsing_ridiculously_long_line_test(): val = "abcdefg"*100000 header = "Hello: {0}\r\n".format(val) assert_raises( DecodingError, MimeHeaders.from_stream, StringIO(header)) def headers_parsing_binary_stuff_survives_test(): value = zlib.compress("abcdefg") header = "Hello: {0}\r\n".format(value) assert_raises( DecodingError, MimeHeaders.from_stream, StringIO(header)) def broken_sequences_test(): headers = StringIO(" hello this is a bad header\nGood: this one is ok") headers = MimeHeaders.from_stream(headers) eq_(1, len(headers)) eq_("this one is ok", headers["Good"]) def bilingual_message_test(): headers = MimeHeaders.from_stream(StringIO(BILINGUAL)) eq_(21, len(headers)) eq_(u"Simple text. How are you? Как ты поживаешь?", headers['Subject']) received_headers = headers.getall('Received') eq_(5, len(received_headers)) ok_('c2cs24435ybk' in received_headers[0]) def headers_roundtrip_test(): headers = MimeHeaders.from_stream(StringIO(BILINGUAL)) out = StringIO() headers.to_stream(out) headers2 = MimeHeaders.from_stream(StringIO(out.getvalue())) eq_(21, len(headers2)) eq_(u"Simple text. How are you? Как ты поживаешь?", headers['Subject']) received_headers = headers.getall('Received') eq_(5, len(received_headers)) ok_('c2cs24435ybk' in received_headers[0]) eq_(headers['Content-Transfer-Encoding'], headers2['Content-Transfer-Encoding']) eq_(headers['DKIM-Signature'], headers2['DKIM-Signature']) def test_folding_combinations(): message = """From mrc@example.com Mon Feb 8 02:53:47 PST 1993\nTo: sasha\r\n continued\n line\nFrom: single line \r\nSubject: hello, how are you\r\n today?""" headers = MimeHeaders.from_stream(StringIO(message)) eq_('sasha continued line', headers['To']) eq_('single line ', headers['From']) eq_("hello, how are you today?", headers['Subject'])