31
32
def make_message(message_id, body='body', headers=None, hidden=False):
32
33
if headers is None:
34
headers['Message-Id'] = message_id
36
'message_id': message_id,
38
'thread_id': message_id,
39
'date': headers.get('date', '2005-01-01'),
40
'subject': headers.get('subject', 'subject'),
41
'author': headers.get('author', 'author'),
44
'replies': headers.get('in-reply-to', None),
36
'Message-Id': message_id,
42
message_headers.update(headers.items())
44
message.set_payload(body)
45
for key, value in message_headers.items():
47
return make_json_message(message_id, message.as_string(), hidden)
50
50
def make_mime_message(message_id, body='body', headers=None, hidden=False,
51
51
attachment_type=None):
52
message = MIMEMultipart()
53
message.attach(MIMEText(body))
52
parts = MIMEMultipart()
53
parts.attach(MIMEText(body))
54
54
if attachment_type is not None:
55
55
attachment = Message()
56
56
attachment.set_payload('attactment data.')
57
57
attachment['Content-Type'] = attachment_type
58
58
attachment['Content-Disposition'] = 'attachment; filename="file.ext"'
59
message.attach(attachment)
60
return make_message(message_id, message.get_payload(), headers, hidden)
59
parts.attach(attachment)
60
return make_message(message_id, parts.as_string(), headers, hidden)
63
63
class ForkedFakeService:
133
133
self.logger = logging.getLogger('http')
134
134
BaseHTTPRequestHandler.__init__(self, *args, **kwargs)
137
"""Create an archive or message on PUT."""
138
scheme, netloc, path, params, query_string, fragments = (
140
parts = path.split('/')
141
if parts[1] != 'archive':
142
# This is an unknonwn operation?
145
# This expected path is /archive/archive_id.
147
self.server.store.put_archive(parts[2])
148
self.send_response(httplib.CREATED)
152
self.send_error(httplib.BAD_REQUEST)
154
# This expected path is /archive/archive_id/message_id.
156
message = self.rfile.read(int(self.headers['content-length']))
157
self.server.store.put_message(parts[2], parts[3], message)
158
self.send_response(httplib.CREATED)
162
self.send_error(httplib.BAD_REQUEST)
136
164
def do_POST(self):
137
"""Create a message on POST."""
138
message = self.rfile.read(int(self.headers['content-length']))
139
if message == 'This is a message':
140
self.send_response(httplib.CREATED)
144
self.send_error(httplib.BAD_REQUEST)
165
"""Change a message on POST."""
166
scheme, netloc, path, params, query_string, fragments = (
168
parts = path.split('/')
169
if parts[1] != 'archive':
170
# This is an unknonwn operation?
173
# This expected path is /archive/archive_id/message_id.
175
# This expected path is /archive/archive_id/message_id.
176
response = self.server.store.hide_message(
177
parts[2], parts[3], query_string)
178
self.send_response(httplib.OK)
180
self.wfile.write(simplejson.dumps(response))
182
self.send_error(httplib.BAD_REQUEST)
146
184
def do_GET(self):
147
185
"""Retrieve a list of messages on GET."""
167
205
self.logger.info(message)
208
class TestPutArchive(TestCase):
210
def test_put_message(self):
211
client = GrackleClient('localhost', 8410)
212
message_archives = {}
213
with ForkedFakeService.from_client(client, message_archives):
214
client.put_archive('arch1')
215
response = client.get_messages('arch1')
216
self.assertEqual(0, len(response['messages']))
170
219
class TestPutMessage(TestCase):
172
221
def test_put_message(self):
173
222
client = GrackleClient('localhost', 8420)
174
with ForkedFakeService.from_client(client):
175
client.put_message('arch1', 'asdf', StringIO('This is a message'))
223
message_archives = {'arch1': []}
224
with ForkedFakeService.from_client(client, message_archives):
225
client.put_message('arch1', 'id1', StringIO('This is a message'))
226
response = client.get_messages('arch1')
227
self.assertEqual(1, len(response['messages']))
228
message = response['messages'][0]
229
self.assertEqual('id1', message['message_id'])
231
def test_put_message_without_archive(self):
232
client = GrackleClient('localhost', 8421)
233
message_archives = {'arch1': []}
234
with ForkedFakeService.from_client(client, message_archives):
176
235
with ExpectedException(Exception, 'wtf'):
177
client.put_message('arch1', 'asdf',
178
StringIO('This is not a message'))
236
client.put_message('no-archive', 'id1', StringIO('message'))
181
239
class TestGetMessages(TestCase):
223
281
def get_messages_member_order_test(self, key):
224
282
client = GrackleClient('localhost', 8439)
227
make_message('foo', headers={key: '2011-03-25'}),
228
make_message('bar', headers={key: '2011-03-24'}),
289
make_message('foo', headers={header_name: '2011-03-25'}),
290
make_message('bar', headers={header_name: '2011-03-24'}),
230
292
with ForkedFakeService.from_client(client, archive):
231
293
response = client.get_messages('baz')
378
440
first_message = response['messages'][0]
379
441
self.assertEqual('foo', first_message['message_id'])
380
442
self.assertEqual(
381
{'From': 'me', 'Message-Id': 'foo', 'To': 'you'},
382
first_message['headers'])
443
archive['baz'][0]['headers'], first_message['headers'])
383
444
self.assertNotIn('body', first_message)
385
446
def test_display_type_text_only(self):
396
457
self.assertEqual('foo', first_message['message_id'])
397
458
self.assertEqual('me', first_message['headers']['From'])
398
459
self.assertEqual('you', first_message['headers']['To'])
399
self.assertEqual('abcdefghi', first_message['body'])
460
self.assertEqual(archive['baz'][0]['body'], first_message['body'])
401
462
def test_display_type_all(self):
402
463
client = GrackleClient('localhost', 8447)
412
473
self.assertEqual('foo', first_message['message_id'])
413
474
self.assertEqual('me', first_message['headers']['From'])
414
475
self.assertEqual('you', first_message['headers']['To'])
416
'abcdefghi\n\nattactment data.', first_message['body'])
476
self.assertEqual(archive['baz'][0]['body'], first_message['body'])
418
478
def test_date_range(self):
419
479
client = GrackleClient('localhost', 8448)
456
516
with ForkedFakeService.from_client(client, archive):
457
517
with ExpectedException(UnparsableDateRange, ''):
458
518
client.get_messages('baz', date_range='2012-01..12-02..12-03')
521
class TestHideMessages(TestCase):
523
def test_hide_message_true(self):
524
client = GrackleClient('localhost', 8470)
527
make_message('foo', hidden=False),
529
with ForkedFakeService.from_client(client, archive):
530
response = client.hide_message('baz', 'foo', hidden=True)
531
self.assertEqual('foo', response['message_id'])
532
self.assertIs(True, response['hidden'])
534
def test_hide_message_false(self):
535
client = GrackleClient('localhost', 8470)
538
make_message('foo', hidden=True),
540
with ForkedFakeService.from_client(client, archive):
541
response = client.hide_message('baz', 'foo', hidden=False)
542
self.assertEqual('foo', response['message_id'])
543
self.assertIs(False, response['hidden'])