18
21
from grackle.client import (
23
UnsupportedDisplayType,
28
def make_message(message_id, body='body', headers=None, hidden=False):
31
headers['Message-Id'] = message_id
33
'message_id': message_id,
35
'thread_id': message_id,
36
'date': headers.get('date', '2005-01-01'),
37
'subject': headers.get('subject', 'subject'),
38
'author': headers.get('author', 'author'),
41
'replies': headers.get('in-reply-to', None),
47
def make_mime_message(message_id, body='body', headers=None, hidden=False,
48
attachment_type=None):
49
message = MIMEMultipart()
50
message.attach(MIMEText(body))
51
if attachment_type is not None:
52
attachment = Message()
53
attachment.set_payload('attactment data.')
54
attachment['Content-Type'] = attachment_type
55
attachment['Content-Disposition'] = 'attachment; filename="file.ext"'
56
message.attach(attachment)
57
return make_message(message_id, message.get_payload(), headers, hidden)
24
60
def threaded_messages(messages):
28
64
for message in messages:
29
if message.get('in_reply_to') is None:
65
if message.get('replies') is None:
30
66
threads[message['message_id']] = [message]
33
69
pending.append(message)
34
70
for message in pending:
35
threads[message['in_reply_to']].append(message)
71
threads[message['replies']].append(message)
36
72
return threads.values()
85
126
(k, v) for k, v in message['headers'].iteritems()
86
127
if k in parameters['headers'])
87
128
message['headers'] = headers
129
if display_type == 'headers-only':
131
elif display_type == 'text-only' and self.is_multipart(message):
133
part.get_payload() for part in message['body']
134
if part.get_content_type() == 'text/plain']
135
message['body'] = '\n\n'.join(text_parts)
136
elif display_type == 'all' and self.is_multipart(message):
137
parts = [str(part.get_payload()) for part in message['body']]
138
message['body'] = '\n\n'.join(parts)
88
139
max_body = parameters.get('max_body_length')
89
if max_body is not None:
140
if max_body is not None and display_type != 'headers-only':
90
141
message['body'] = message['body'][:max_body]
91
142
new_messages.append(message)
92
143
messages = new_messages
263
321
def test_get_messages_by_id(self):
264
322
client = GrackleClient('localhost', 8437)
265
with ForkedFake.from_client(client,
267
[{'message_id': 'foo'},
268
{'message_id': 'bar'}]}):
324
'baz': [make_message('foo'), make_message('bar')]}
325
with ForkedFakeService.from_client(client, archive):
269
326
response = client.get_messages('baz', message_ids=['foo'])
270
327
message, = response['messages']
271
328
self.assertEqual('foo', message['message_id'])
273
330
def test_get_messages_batching(self):
274
331
client = GrackleClient('localhost', 8438)
275
with ForkedFake.from_client(client,
277
[{'message_id': 'foo'},
278
{'message_id': 'bar'}]}):
332
archive = {'baz': [make_message('foo'), make_message('bar')]}
333
with ForkedFakeService.from_client(client, archive):
279
334
response = client.get_messages('baz', limit=1)
280
335
self.assertEqual(1, len(response['messages']))
281
336
messages = response['messages']
288
343
def get_messages_member_order_test(self, key):
289
344
client = GrackleClient('localhost', 8439)
290
with ForkedFake.from_client(client,
291
{'baz': [{'message_id': 'foo', key: '2011-03-25'},
292
{'message_id': 'bar', key: '2011-03-24'}]}):
347
make_message('foo', headers={key: '2011-03-25'}),
348
make_message('bar', headers={key: '2011-03-24'}),
350
with ForkedFakeService.from_client(client, archive):
293
351
response = client.get_messages('baz')
294
352
self.assertIDOrder(['foo', 'bar'], response['messages'])
295
353
response = client.get_messages('baz', order=key)
305
363
self.get_messages_member_order_test('subject')
307
365
def test_get_messages_thread_subject_order(self):
368
make_message('bar', headers={'subject': 'y'}),
369
make_message('qux', headers={'subject': 'z'}),
370
make_message('foo', headers={'subject': 'x',
371
'in-reply-to': 'qux'}),
308
373
client = GrackleClient('localhost', 8439)
309
with ForkedFake.from_client(client, {'baz': [
310
{'message_id': 'bar', 'subject': 'y'},
311
{'message_id': 'qux', 'subject': 'z'},
312
{'message_id': 'foo', 'subject': 'x', 'in_reply_to': 'qux'},
374
with ForkedFakeService.from_client(client, archive):
314
375
response = client.get_messages('baz')
315
376
self.assertIDOrder(['bar', 'qux', 'foo'], response['messages'])
316
377
response = client.get_messages('baz', order='subject')
321
382
def test_get_messages_thread_oldest_order(self):
322
383
client = GrackleClient('localhost', 8439)
323
with ForkedFake.from_client(client, {'baz': [
324
{'message_id': 'bar', 'date': 'x'},
325
{'message_id': 'qux', 'date': 'z'},
326
{'message_id': 'foo', 'date': 'y', 'in_reply_to': 'qux'},
386
make_message('bar', headers={'date': 'x'}),
387
make_message('qux', headers={'date': 'z'}),
388
make_message('foo', headers={'date': 'y',
389
'in-reply-to': 'qux'}),
391
with ForkedFakeService.from_client(client, archive):
328
392
response = client.get_messages('baz')
329
393
self.assertIDOrder(['bar', 'qux', 'foo'], response['messages'])
330
394
response = client.get_messages('baz', order='date')
335
399
def test_get_messages_thread_newest_order(self):
336
400
client = GrackleClient('localhost', 8439)
337
with ForkedFake.from_client(client, {'baz': [
338
{'message_id': 'bar', 'date': 'x'},
339
{'message_id': 'qux', 'date': 'w'},
340
{'message_id': 'foo', 'date': 'y', 'in_reply_to': 'bar'},
341
{'message_id': 'baz', 'date': 'z', 'in_reply_to': 'qux'},
403
make_message('bar', headers={'date': 'x'}),
404
make_message('qux', headers={'date': 'w'}),
405
make_message('foo', headers={'date': 'y',
406
'in-reply-to': 'bar'}),
407
make_message('baz', headers={'date': 'z',
408
'in-reply-to': 'qux'}),
410
with ForkedFakeService.from_client(client, archive):
343
411
response = client.get_messages('baz', order='date')
344
412
self.assertIDOrder(
345
413
['qux', 'bar', 'foo', 'baz'], response['messages'])
350
418
def test_get_messages_unsupported_order(self):
351
419
client = GrackleClient('localhost', 8439)
352
with ForkedFake.from_client(client,
353
{'baz': [{'message_id': 'foo', 'date': '2011-03-25'},
354
{'message_id': 'bar', 'date': '2011-03-24'}]}):
422
make_message('foo', headers={'date': '2011-03-25'}),
423
make_message('foo', headers={'date': '2011-03-24'}),
425
with ForkedFakeService.from_client(client, archive):
355
426
with ExpectedException(UnsupportedOrder, ''):
356
427
client.get_messages('baz', order='nonsense')
358
429
def test_get_messages_headers_no_headers(self):
359
430
client = GrackleClient('localhost', 8440)
360
with ForkedFake.from_client(client,
362
{'message_id': 'foo'}
431
archive = {'baz': [make_message('foo')]}
432
with ForkedFakeService.from_client(client, archive):
364
433
response = client.get_messages('baz', headers=[
365
434
'Subject', 'Date', 'X-Launchpad-Message-Rationale'])
366
435
first_message = response['messages'][0]
394
462
def test_get_messages_max_body_length(self):
395
463
client = GrackleClient('localhost', 8443)
396
with ForkedFake.from_client(client,
398
{'message_id': 'foo', 'body': u'abcdefghi'}
464
archive = {'baz': [make_message('foo', body=u'abcdefghi')]}
465
with ForkedFakeService.from_client(client, archive):
400
466
response = client.get_messages('baz', max_body_length=3)
401
467
first_message = response['messages'][0]
402
468
self.assertEqual('abc', first_message['body'])
404
470
def test_include_hidden(self):
405
471
client = GrackleClient('localhost', 8444)
406
with ForkedFake.from_client(client,
408
{'message_id': 'foo', 'hidden': True},
409
{'message_id': 'bar', 'hidden': False}
474
make_message('foo', hidden=True),
475
make_message('bar', hidden=False),
477
with ForkedFakeService.from_client(client, archive):
411
478
response = client.get_messages('baz', include_hidden=True)
412
479
self.assertMessageIDs(['bar', 'foo'], response['messages'])
413
480
response = client.get_messages('baz', include_hidden=False)
414
481
self.assertMessageIDs(['bar'], response['messages'])
483
def test_display_type_unknown_value(self):
484
client = GrackleClient('localhost', 8445)
485
archive = {'baz': [make_message('foo', body=u'abcdefghi')]}
486
with ForkedFakeService.from_client(client, archive):
487
with ExpectedException(UnsupportedDisplayType, ''):
488
client.get_messages('baz', display_type='unknown')
490
def test_display_type_headers_only(self):
491
client = GrackleClient('localhost', 8446)
494
make_message('foo', body=u'abcdefghi',
495
headers={'From': 'me', 'To': 'you'})]}
496
with ForkedFakeService.from_client(client, archive):
497
response = client.get_messages('baz', display_type='headers-only')
498
first_message = response['messages'][0]
499
self.assertEqual('foo', first_message['message_id'])
501
{'From': 'me', 'Message-Id': 'foo', 'To': 'you'},
502
first_message['headers'])
503
self.assertNotIn('body', first_message)
505
def test_display_type_text_only(self):
506
client = GrackleClient('localhost', 8446)
511
headers={'From': 'me', 'To': 'you'},
512
attachment_type='text/x-diff')]}
513
with ForkedFakeService.from_client(client, archive):
514
response = client.get_messages('baz', display_type='text-only')
515
first_message = response['messages'][0]
516
self.assertEqual('foo', first_message['message_id'])
517
self.assertEqual('me', first_message['headers']['From'])
518
self.assertEqual('you', first_message['headers']['To'])
519
self.assertEqual('abcdefghi', first_message['body'])
521
def test_display_type_all(self):
522
client = GrackleClient('localhost', 8447)
527
headers={'From': 'me', 'To': 'you'},
528
attachment_type='text/x-diff')]}
529
with ForkedFakeService.from_client(client, archive):
530
response = client.get_messages('baz', display_type='all')
531
first_message = response['messages'][0]
532
self.assertEqual('foo', first_message['message_id'])
533
self.assertEqual('me', first_message['headers']['From'])
534
self.assertEqual('you', first_message['headers']['To'])
536
'abcdefghi\n\nattactment data.', first_message['body'])