~didrocks/unity/altf10

« back to all changes in this revision

Viewing changes to grackle/tests/test_client.py

  • Committer: Curtis Hovey
  • Date: 2012-02-29 23:55:28 UTC
  • Revision ID: curtis.hovey@canonical.com-20120229235528-7wphq02b2y9vt7ni
Implemented a partial put into the MemoryStore.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
 
18
18
from testtools import ExpectedException
19
19
 
20
 
from grackle.client import GrackleClient
21
 
from grackle.error import (
22
 
    ArchiveIdExists,
 
20
from grackle.client import (
 
21
    GrackleClient,
23
22
    UnparsableDateRange,
24
23
    UnsupportedDisplayType,
25
24
    UnsupportedOrder,
26
25
    )
27
 
from grackle.service import ForkedFakeService
28
26
from grackle.store import (
29
 
    make_json_message,
30
27
    MemoryStore,
31
28
    )
32
29
 
34
31
def make_message(message_id, body='body', headers=None, hidden=False):
35
32
    if headers is None:
36
33
        headers = {}
37
 
    message_headers = {
38
 
        'Message-Id': message_id,
39
 
        'date': '2005-01-01',
40
 
        'subject': 'subject',
41
 
        'from': 'author',
42
 
        'replies': '',
 
34
    headers['Message-Id'] = message_id
 
35
    message = {
 
36
        'message_id': message_id,
 
37
        'headers': headers,
 
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'),
 
42
        'hidden': hidden,
 
43
        'attachments': [],
 
44
        'replies': headers.get('in-reply-to', None),
 
45
        'body': body,
43
46
        }
44
 
    message_headers.update(headers.items())
45
 
    message = Message()
46
 
    message.set_payload(body)
47
 
    for key, value in message_headers.items():
48
 
        message[key] = value
49
 
    return make_json_message(message_id, message.as_string(), hidden)
 
47
    return message
50
48
 
51
49
 
52
50
def make_mime_message(message_id, body='body', headers=None, hidden=False,
53
51
                      attachment_type=None):
54
 
    parts = MIMEMultipart()
55
 
    parts.attach(MIMEText(body))
 
52
    message = MIMEMultipart()
 
53
    message.attach(MIMEText(body))
56
54
    if attachment_type is not None:
57
55
        attachment = Message()
58
56
        attachment.set_payload('attactment data.')
59
57
        attachment['Content-Type'] = attachment_type
60
58
        attachment['Content-Disposition'] = 'attachment; filename="file.ext"'
61
 
        parts.attach(attachment)
62
 
    return make_message(message_id, parts.as_string(), headers, hidden)
63
 
 
64
 
 
65
 
class XXXForkedFakeService:
 
59
        message.attach(attachment)
 
60
    return make_message(message_id, message.get_payload(), headers, hidden)
 
61
 
 
62
 
 
63
class ForkedFakeService:
66
64
    """A Grackle service fake, as a ContextManager."""
67
65
 
68
66
    def __init__(self, port, message_archives=None, write_logs=False):
114
112
        """Start the HTTP server."""
115
113
        service = HTTPServer(('', self.port), FakeGrackleRequestHandler)
116
114
        service.store = MemoryStore(self.message_archives)
 
115
        for archive_id, messages in service.store.message_archives.iteritems():
 
116
            for message in messages:
 
117
                message.setdefault('headers', {})
117
118
        self.is_ready()
118
119
        if self.write_logs:
119
120
            logging.basicConfig(
132
133
        self.logger = logging.getLogger('http')
133
134
        BaseHTTPRequestHandler.__init__(self, *args, **kwargs)
134
135
 
135
 
    def do_PUT(self):
136
 
        """Create an archive or message on PUT."""
137
 
        scheme, netloc, path, params, query_string, fragments = (
138
 
            urlparse(self.path))
139
 
        parts = path.split('/')
140
 
        if parts[1] != 'archive':
141
 
            # This is an unknonwn operation?
142
 
            return
143
 
        if len(parts) == 3:
144
 
            # This expected path is /archive/archive_id.
145
 
            try:
146
 
                self.server.store.put_archive(parts[2])
147
 
                self.send_response(httplib.CREATED)
148
 
                self.end_headers()
149
 
                self.wfile.close()
150
 
            except Exception, error:
151
 
                self.send_response(
152
 
                    httplib.BAD_REQUEST, error.__doc__)
153
 
        if len(parts) == 4:
154
 
            # This expected path is /archive/archive_id/message_id.
155
 
            try:
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)
159
 
                self.end_headers()
160
 
                self.wfile.close()
161
 
            except:
162
 
                self.send_error(httplib.BAD_REQUEST)
163
 
 
164
136
    def do_POST(self):
165
 
        """Change a message on POST."""
 
137
        """Create a message on POST."""
 
138
        message = self.rfile.read(int(self.headers['content-length']))
166
139
        scheme, netloc, path, params, query_string, fragments = (
167
140
            urlparse(self.path))
168
141
        parts = path.split('/')
169
 
        if parts[1] != 'archive':
170
 
            # This is an unknonwn operation?
171
 
            return
172
 
        if len(parts) == 4:
 
142
        if parts[1] == 'archive':
173
143
            # This expected path is /archive/archive_id/message_id.
174
 
            try:
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)
179
 
                self.end_headers()
180
 
                self.wfile.write(simplejson.dumps(response))
181
 
            except:
182
 
                self.send_error(httplib.BAD_REQUEST)
 
144
            self.server.store.put_message(parts[2], parts[3], message)
 
145
        if message == 'This is a message':
 
146
            self.send_response(httplib.CREATED)
 
147
            self.end_headers()
 
148
            self.wfile.close()
 
149
        else:
 
150
            self.send_error(httplib.BAD_REQUEST)
183
151
 
184
152
    def do_GET(self):
185
153
        """Retrieve a list of messages on GET."""
205
173
        self.logger.info(message)
206
174
 
207
175
 
208
 
class TestPutArchive(TestCase):
209
 
 
210
 
    def test_put_archive(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']))
217
 
 
218
 
    def test_put_archive_existing_archive(self):
219
 
        client = GrackleClient('localhost', 8411)
220
 
        message_archives = {'arch1': []}
221
 
        with ForkedFakeService.from_client(client, message_archives):
222
 
            with ExpectedException(ArchiveIdExists, ''):
223
 
                client.put_archive('arch1')
224
 
 
225
 
 
226
176
class TestPutMessage(TestCase):
227
177
 
228
178
    def test_put_message(self):
229
179
        client = GrackleClient('localhost', 8420)
230
180
        message_archives = {'arch1': []}
231
 
        with ForkedFakeService.from_client(client, message_archives):
 
181
        service = ForkedFakeService.from_client(client, message_archives)
 
182
        with service:
232
183
            client.put_message('arch1', 'id1', StringIO('This is a message'))
233
184
            response = client.get_messages('arch1')
234
 
        self.assertEqual(1, len(response['messages']))
235
 
        message = response['messages'][0]
236
 
        self.assertEqual('id1', message['message_id'])
 
185
            self.assertEqual(1, len(response['messages']))
 
186
            message = response['messages'][0]
 
187
            self.assertEqual('id1', message['message_id'])
237
188
 
238
 
    def test_put_message_without_archive(self):
 
189
    def test_put_message_without_message(self):
239
190
        client = GrackleClient('localhost', 8421)
240
191
        message_archives = {'arch1': []}
241
192
        with ForkedFakeService.from_client(client, message_archives):
242
193
            with ExpectedException(Exception, 'wtf'):
243
 
                client.put_message('no-archive', 'id1', StringIO('message'))
 
194
                client.put_message('arch1', 'id1',
 
195
                    StringIO('This is not a message'))
244
196
 
245
197
 
246
198
class TestGetMessages(TestCase):
287
239
 
288
240
    def get_messages_member_order_test(self, key):
289
241
        client = GrackleClient('localhost', 8439)
290
 
        if key == 'author':
291
 
            header_name = 'from'
292
 
        else:
293
 
            header_name = key
294
242
        archive = {
295
243
            'baz': [
296
 
                make_message('foo', headers={header_name: '2011-03-25'}),
297
 
                make_message('bar', headers={header_name: '2011-03-24'}),
 
244
                make_message('foo', headers={key: '2011-03-25'}),
 
245
                make_message('bar', headers={key: '2011-03-24'}),
298
246
             ]}
299
247
        with ForkedFakeService.from_client(client, archive):
300
248
            response = client.get_messages('baz')
447
395
        first_message = response['messages'][0]
448
396
        self.assertEqual('foo', first_message['message_id'])
449
397
        self.assertEqual(
450
 
            archive['baz'][0]['headers'], first_message['headers'])
 
398
            {'From': 'me', 'Message-Id': 'foo', 'To': 'you'},
 
399
            first_message['headers'])
451
400
        self.assertNotIn('body', first_message)
452
401
 
453
402
    def test_display_type_text_only(self):
464
413
        self.assertEqual('foo', first_message['message_id'])
465
414
        self.assertEqual('me', first_message['headers']['From'])
466
415
        self.assertEqual('you', first_message['headers']['To'])
467
 
        self.assertEqual(archive['baz'][0]['body'], first_message['body'])
 
416
        self.assertEqual('abcdefghi', first_message['body'])
468
417
 
469
418
    def test_display_type_all(self):
470
419
        client = GrackleClient('localhost', 8447)
480
429
        self.assertEqual('foo', first_message['message_id'])
481
430
        self.assertEqual('me', first_message['headers']['From'])
482
431
        self.assertEqual('you', first_message['headers']['To'])
483
 
        self.assertEqual(archive['baz'][0]['body'], first_message['body'])
 
432
        self.assertEqual(
 
433
            'abcdefghi\n\nattactment data.', first_message['body'])
484
434
 
485
435
    def test_date_range(self):
486
436
        client = GrackleClient('localhost', 8448)
523
473
        with ForkedFakeService.from_client(client, archive):
524
474
            with ExpectedException(UnparsableDateRange, ''):
525
475
                client.get_messages('baz', date_range='2012-01..12-02..12-03')
526
 
 
527
 
 
528
 
class TestHideMessages(TestCase):
529
 
 
530
 
    def test_hide_message_true(self):
531
 
        client = GrackleClient('localhost', 8470)
532
 
        archive = {
533
 
            'baz': [
534
 
                make_message('foo', hidden=False),
535
 
            ]}
536
 
        with ForkedFakeService.from_client(client, archive):
537
 
            response = client.hide_message('baz', 'foo', hidden=True)
538
 
        self.assertEqual('foo', response['message_id'])
539
 
        self.assertIs(True, response['hidden'])
540
 
 
541
 
    def test_hide_message_false(self):
542
 
        client = GrackleClient('localhost', 8470)
543
 
        archive = {
544
 
            'baz': [
545
 
                make_message('foo', hidden=True),
546
 
            ]}
547
 
        with ForkedFakeService.from_client(client, archive):
548
 
            response = client.hide_message('baz', 'foo', hidden=False)
549
 
        self.assertEqual('foo', response['message_id'])
550
 
        self.assertIs(False, response['hidden'])