def test_api_get(db, api_client): acct = db.session.query(Account).filter_by(id=ACCOUNT_ID).one() ns_id = acct.namespace.public_id e_data = {'title': 'subj', 'when': {'time': 1}, 'location': 'InboxHQ'} e_data2 = {'title': 'subj2', 'when': {'time': 1}, 'location': 'InboxHQ'} api_client.post_data('/events', e_data, ns_id) api_client.post_data('/events', e_data2, ns_id) event_list = api_client.get_data('/events', ns_id) event_ids = [event['id'] for event in event_list] c1found = False c2found = False for c_id in event_ids: event = api_client.get_data('/events/' + c_id, ns_id) if event['title'] == 'subj': c1found = True if event['title'] == 'subj2': c2found = True assert c1found assert c2found
def test_create_tag(api_client, default_namespace): ns_id = default_namespace.public_id post_resp = api_client.post_data('/tags/', {'name': 'foo'}) assert post_resp.status_code == 200 tag_resp = json.loads(post_resp.data) assert tag_resp['name'] == 'foo' assert tag_resp['namespace_id'] == ns_id tag_id = tag_resp['id'] # Check getting the tag tag_data = api_client.get_data('/tags/{}'.format(tag_id)) assert tag_data['name'] == 'foo' assert tag_data['namespace_id'] == ns_id assert tag_data['id'] == tag_id # Check listing the tag assert 'foo' in [tag['name'] for tag in api_client.get_data('/tags/')] # Make sure we can specify the namespace that we are creating the tag in bad_ns_id = 0000000000000000000000000 tag_data = {'name': 'foo3', 'namespace_id': bad_ns_id} put_resp = api_client.post_data('/tags/', tag_data) assert put_resp.status_code == 400 assert 'foo3' not in [tag['name'] for tag in api_client.get_data('/tags/')]
def test_search_response(db, api_client, search_engine): endpoint = '/messages/search' resp = api_client.post_data(endpoint + '?limit={}&offset={}'. format(1, 0), {}) assert resp.status_code == 200 result_dict = json.loads(resp.data) results = result_dict['results'] assert len(results) == 1 search_repr = results[0]['object'] message_id = search_repr['id'] api_repr = api_client.get_data('/messages/{}'.format(message_id)) assert search_repr['to'] == api_repr['to'] assert search_repr['from'] == api_repr['from'] assert search_repr['cc'] == api_repr['cc'] assert search_repr['bcc'] == api_repr['bcc'] assert search_repr['files'] == api_repr['files'] endpoint = '/threads/search' resp = api_client.post_data(endpoint + '?limit={}&offset={}'. format(1, 0), {}) assert resp.status_code == 200 result_dict = json.loads(resp.data) results = result_dict['results'] assert len(results) == 1 search_repr = results[0]['object'] thread_id = search_repr['id'] api_repr = api_client.get_data('/threads/{}'.format(thread_id)) assert sorted(search_repr['tags']) == sorted(api_repr['tags']) assert search_repr['participants'] == api_repr['participants']
def test_conflicting_updates(api_client): original_draft = { 'subject': 'parent draft', 'body': 'parent draft' } r = api_client.post_data('/drafts', original_draft) original_public_id = json.loads(r.data)['id'] updated_draft = { 'subject': 'updated draft', 'body': 'updated draft' } r = api_client.post_data('/drafts/{}'.format(original_public_id), updated_draft) assert r.status_code == 200 updated_public_id = json.loads(r.data)['id'] conflicting_draft = { 'subject': 'conflicting draft', 'body': 'conflicting draft' } r = api_client.post_data('/drafts/{}'.format(original_public_id), conflicting_draft) assert r.status_code == 409 drafts = api_client.get_data('/drafts') assert len(drafts) == 1 assert drafts[0]['id'] == updated_public_id
def test_add_remove_tags(api_client): assert 'foo' not in [tag['name'] for tag in api_client.get_data('/tags/')] assert 'bar' not in [tag['name'] for tag in api_client.get_data('/tags/')] api_client.post_data('/tags/', {'name': 'foo'}) api_client.post_data('/tags/', {'name': 'bar'}) thread_id = api_client.get_data('/threads/')[0]['id'] thread_path = '/threads/{}'.format(thread_id) api_client.put_data(thread_path, {'add_tags': ['foo']}) api_client.put_data(thread_path, {'add_tags': ['bar']}) tag_names = [tag['name'] for tag in api_client.get_data(thread_path)['tags']] assert 'foo' in tag_names assert 'bar' in tag_names # Check that tag was only applied to this thread another_thread_id = api_client.get_data('/threads/')[1]['id'] tag_names = get_tag_names( api_client.get_data('/threads/{}'.format(another_thread_id))) assert 'foo' not in tag_names api_client.put_data(thread_path, {'remove_tags': ['foo']}) api_client.put_data(thread_path, {'remove_tags': ['bar']}) tag_names = get_tag_names(api_client.get_data(thread_path)) assert 'foo' not in tag_names assert 'bar' not in tag_names
def test_lens_tx(api_client, db): api_client.post_data('/drafts/', { 'subject': 'Calaveras Dome / Hammer Dome', 'to': [{'name': 'Somebody', 'email': '*****@*****.**'}], 'cc': [{'name': 'Another Person', 'email': '*****@*****.**'}] }) transaction = db.session.query(Transaction). \ filter(Transaction.table_name == 'spoolmessage'). \ order_by(desc(Transaction.id)).first() draft = db.session.query(SpoolMessage). \ order_by(desc(SpoolMessage.id)).first() thread = draft.thread filter = Lens(subject='/Calaveras/') assert filter.match(transaction) filter = Lens(subject='Calaveras') assert not filter.match(transaction) filter = Lens(from_addr='*****@*****.**') assert filter.match(transaction) filter = Lens(from_addr='/inboxapp/') assert filter.match(transaction) filter = Lens(cc_addr='/Another/') assert filter.match(transaction) early_ts = calendar.timegm(thread.subjectdate.utctimetuple()) - 1 late_ts = calendar.timegm(thread.subjectdate.utctimetuple()) + 1 filter = Lens(started_before=late_ts) assert filter.match(transaction) filter = Lens(started_before=early_ts) assert not filter.match(transaction) filter = Lens(started_after=late_ts) assert not filter.match(transaction) filter = Lens(started_after=early_ts) assert filter.match(transaction) filter = Lens(last_message_after=early_ts) assert filter.match(transaction) filter = Lens(last_message_after=late_ts) assert not filter.match(transaction) filter = Lens(subject='/Calaveras/', any_email='Nobody') assert not filter.match(transaction) filter = Lens(subject='/Calaveras/', any_email='/inboxapp/') assert filter.match(transaction) with pytest.raises(ValueError): filter = Lens(subject='/*/')
def test_api_get(db, api_client, calendar): e_data = {'title': 'subj', 'when': {'time': 1}, 'calendar_id': calendar.public_id, 'location': 'InboxHQ'} e_data2 = {'title': 'subj2', 'when': {'time': 1}, 'calendar_id': calendar.public_id, 'location': 'InboxHQ'} api_client.post_data('/events', e_data) api_client.post_data('/events', e_data2) event_list = api_client.get_data('/events') event_ids = [event['id'] for event in event_list] c1found = False c2found = False for c_id in event_ids: event = api_client.get_data('/events/' + c_id) if event['title'] == 'subj': c1found = True if event['title'] == 'subj2': c2found = True assert c1found assert c2found
def test_delete_draft(api_client): original_draft = { 'subject': 'parent draft', 'body': 'parent draft' } r = api_client.post_data('/drafts', original_draft) draft_public_id = json.loads(r.data)['id'] version = json.loads(r.data)['version'] updated_draft = { 'subject': 'updated draft', 'body': 'updated draft', 'version': version } r = api_client.post_data('/drafts/{}'.format(draft_public_id), updated_draft) updated_public_id = json.loads(r.data)['id'] updated_version = json.loads(r.data)['version'] r = api_client.delete('/drafts/{}'.format(updated_public_id), {'version': updated_version}) # Check that drafts were deleted drafts = api_client.get_data('/drafts') assert not drafts
def test_drafts_filter(api_client, example_draft): r = api_client.post_data('/drafts', example_draft) public_id = json.loads(r.data)['id'] r = api_client.get_data('/drafts') matching_saved_drafts = [draft for draft in r if draft['id'] == public_id] thread_public_id = matching_saved_drafts[0]['thread_id'] reply_draft = { 'subject': 'test reply', 'body': 'test reply', 'thread_id': thread_public_id } r = api_client.post_data('/drafts', reply_draft) _filter = '?thread_id=0000000000000000000000000' results = api_client.get_data('/drafts' + _filter) assert len(results) == 0 results = api_client.get_data('/drafts?thread_id={}' .format(thread_public_id)) assert len(results) == 2 results = api_client.get_data('/drafts?offset={}&thread_id={}' .format(1, thread_public_id)) assert len(results) == 1
def test_update_draft(api_client): original_draft = { 'subject': 'parent draft', 'body': 'parent draft' } r = api_client.post_data('/drafts', original_draft) draft_public_id = json.loads(r.data)['id'] version = json.loads(r.data)['version'] updated_draft = { 'subject': 'updated draft', 'body': 'updated draft', 'version': version } r = api_client.post_data('/drafts/{}'.format(draft_public_id), updated_draft) updated_public_id = json.loads(r.data)['id'] updated_version = json.loads(r.data)['version'] assert updated_public_id == draft_public_id and \ updated_version != version drafts = api_client.get_data('/drafts') assert len(drafts) == 1 assert drafts[0]['id'] == updated_public_id
def test_api_list(db, api_client): acct = db.session.query(Account).filter_by(id=ACCOUNT_ID).one() ns_id = acct.namespace.public_id e_data = {'title': 'subj', 'description': 'body1', 'when': {'time': 1}, 'location': 'InboxHQ'} e_data2 = {'title': 'subj2', 'description': 'body2', 'when': {'time': 1}, 'location': 'InboxHQ'} api_client.post_data('/events', e_data, ns_id) api_client.post_data('/events', e_data2, ns_id) event_list = api_client.get_data('/events', ns_id) event_titles = [event['title'] for event in event_list] assert 'subj' in event_titles assert 'subj2' in event_titles event_descriptions = [event['description'] for event in event_list] assert 'body1' in event_descriptions assert 'body2' in event_descriptions event_ids = [event['id'] for event in event_list] for e_id in event_ids: ev = db.session.query(Event).filter_by(public_id=e_id).one() db.session.delete(ev) db.session.commit()
def test_delete_draft(api_client): original_draft = {"subject": "parent draft", "body": "parent draft"} r = api_client.post_data("/drafts", original_draft) draft_public_id = json.loads(r.data)["id"] version = json.loads(r.data)["version"] updated_draft = {"subject": "updated draft", "body": "updated draft", "version": version} r = api_client.put_data("/drafts/{}".format(draft_public_id), updated_draft) updated_public_id = json.loads(r.data)["id"] updated_version = json.loads(r.data)["version"] r = api_client.delete("/drafts/{}".format(updated_public_id), {"version": updated_version}) # Check that drafts were deleted drafts = api_client.get_data("/drafts") assert not drafts # Check that no orphaned threads are around threads = api_client.get_data("/threads?subject=parent%20draft") assert not threads threads = api_client.get_data("/threads?subject=updated%20draft") assert not threads # And check that threads aren't deleted if they still have messages. thread_public_id = api_client.get_data("/threads")[0]["id"] reply_draft = {"subject": "test reply", "body": "test reply", "thread_id": thread_public_id} r = api_client.post_data("/drafts", reply_draft) public_id = json.loads(r.data)["id"] version = json.loads(r.data)["version"] thread = api_client.get_data("/threads/{}".format(thread_public_id)) assert "drafts" in [t["name"] for t in thread["tags"]] api_client.delete("/drafts/{}".format(public_id), {"version": version}) thread = api_client.get_data("/threads/{}".format(thread_public_id)) assert thread assert "drafts" not in [t["name"] for t in thread["tags"]]
def test_send_draft(db, api_client, example_draft, default_account): r = api_client.post_data('/drafts', example_draft) assert r.status_code == 200 public_id = json.loads(r.data)['id'] version = json.loads(r.data)['version'] r = api_client.post_data('/send', {'draft_id': public_id, 'version': version}) assert r.status_code == 200 draft = api_client.get_data('/drafts/{}'.format(public_id)) assert draft is not None assert draft['object'] != 'draft' with crispin_client(default_account.id, default_account.provider) as c: criteria = ['NOT DELETED', 'SUBJECT "{0}"'.format( example_draft['subject'])] c.conn.select_folder(default_account.drafts_folder.name, readonly=False) draft_uids = c.conn.search(criteria) assert not draft_uids, 'Message still in Drafts folder' c.conn.select_folder(default_account.sent_folder.name, readonly=False) sent_uids = c.conn.search(criteria) assert sent_uids, 'Message missing from Sent folder' c.conn.delete_messages(sent_uids) c.conn.expunge()
def test_api_list(db, api_client, calendar): e_data = {'title': 'subj', 'description': 'body1', 'calendar_id': calendar.public_id, 'when': {'time': 1}, 'location': 'InboxHQ'} e_data2 = {'title': 'subj2', 'description': 'body2', 'calendar_id': calendar.public_id, 'when': {'time': 1}, 'location': 'InboxHQ'} api_client.post_data('/events', e_data) api_client.post_data('/events', e_data2) event_list = api_client.get_data('/events') event_titles = [event['title'] for event in event_list] assert 'subj' in event_titles assert 'subj2' in event_titles event_descriptions = [event['description'] for event in event_list] assert 'body1' in event_descriptions assert 'body2' in event_descriptions event_ids = [event['id'] for event in event_list] for e_id in event_ids: ev = db.session.query(Event).filter_by(public_id=e_id).one() db.session.delete(ev) db.session.commit()
def test_send(api_client, example_draft, real_syncback_service, monkeypatch): # We're not testing the actual SMTP sending or syncback here, so # monkey-patch to make this run faster. monkeypatch.setattr('inbox.sendmail.base.get_sendmail_client', lambda *args, **kwargs: MockSMTPClient()) monkeypatch.setattr('inbox.actions.save_draft', lambda *args, **kwargs: None) monkeypatch.setattr('inbox.actions.delete_draft', lambda *args, **kwargs: None) r = api_client.post_data('/drafts', example_draft) draft_public_id = json.loads(r.data)['id'] r = api_client.post_data('/send', {'draft_id': draft_public_id}) # TODO(emfree) do this more rigorously gevent.sleep(1) drafts = api_client.get_data('/drafts') threads_with_drafts = api_client.get_data('/threads?tag=drafts') assert not drafts assert not threads_with_drafts sent_threads = api_client.get_data('/threads?tag=sent') assert len(sent_threads) == 1 message = api_client.get_data('/messages/{}'.format(draft_public_id)) assert message['state'] == 'sent' assert message['object'] == 'message'
def test_quoted_printable_encoding_avoided_for_compatibility( patch_smtp, api_client): # Test that messages with long lines don't get quoted-printable encoded, # for maximum server compatibility. api_client.post_data( '/send', {'to': [{'email': '*****@*****.**'}], 'subject': 'In Catilinam', 'body': 'Etenim quid est, Catilina, quod iam amplius exspectes, si ' 'neque nox tenebris obscurare coeptus nefarios neque privata domus ' 'parietibus continere voces conjurationis tuae potest? Si ' 'illustrantur, si erumpunt omnia? Muta iam istam mentem, mihi crede! ' 'obliviscere caedis atque incendiorum. Teneris undique: luce sunt ' 'clariora nobis tua consilia omnia; quae iam mecum licet recognoscas.' ' Meministine me ante diem duodecimum Kalendas Novembres dicere in ' 'senatu, fore in armis certo die, qui dies futurus esset ante diem ' 'sextum Kalendas Novembres, C. Manlium, audaciae satellitem atque ' 'administrum tuae? Num me fefellit, Catilina, non modo res tanta, tam' ' atrox, tamque incredibilis, verum id quod multo magis admirandum, ' 'dies? '}) _, msg = patch_smtp[-1] parsed = mime.from_string(msg) assert len(parsed.parts) == 2 for part in parsed.parts: if part.content_type.value == 'text/html': assert part.content_encoding[0] == 'base64' elif part.content_type.value == 'text/plain': assert part.content_encoding[0] in ('7bit', 'base64')
def test_send_existing_draft(patch_smtp, api_client, example_draft): r = api_client.post_data('/drafts', example_draft) draft_public_id = json.loads(r.data)['id'] version = json.loads(r.data)['version'] r = api_client.post_data('/send', {'draft_id': draft_public_id, 'version': version}) assert r.status_code == 200 # Test that the sent draft can't be sent again. r = api_client.post_data('/send', {'draft_id': draft_public_id, 'version': version}) assert r.status_code == 400 drafts = api_client.get_data('/drafts') threads_with_drafts = api_client.get_data('/threads?tag=drafts') assert not drafts assert not threads_with_drafts sent_threads = api_client.get_data('/threads?tag=sent') assert len(sent_threads) == 1 message = api_client.get_data('/messages/{}'.format(draft_public_id)) assert message['object'] == 'message'
def test_reply_headers_set(patch_smtp, api_client, example_draft): thread_id = api_client.get_data('/threads')[0]['id'] api_client.post_data('/send', {'to': [{'email': '*****@*****.**'}], 'thread_id': thread_id}) _, msg = patch_smtp[-1] parsed = mime.from_string(msg) assert 'In-Reply-To' in parsed.headers assert 'References' in parsed.headers
def test_send_rejected_without_recipients(api_client): r = api_client.post_data('/drafts', {'subject': 'Hello there'}) draft_public_id = json.loads(r.data)['id'] version = json.loads(r.data)['version'] r = api_client.post_data('/send', {'draft_id': draft_public_id, 'version': version}) assert r.status_code == 400
def test_create_event(db, api_client, calendar): e_data = {'title': 'subj', 'description': 'body1', 'calendar_id': calendar.public_id, 'when': {'time': 1}, 'location': 'InboxHQ'} e_data2 = {'title': 'subj2', 'description': 'body2', 'calendar_id': calendar.public_id, 'when': {'time': 1}, 'location': 'InboxHQ'} api_client.post_data('/events', e_data) api_client.post_data('/events', e_data2) db.session.commit()
def test_create_event(db, api_client): acct = db.session.query(Account).filter_by(id=ACCOUNT_ID).one() ns_id = acct.namespace.public_id e_data = {'title': 'subj', 'description': 'body1', 'when': {'time': 1}, 'location': 'InboxHQ'} e_data2 = {'title': 'subj2', 'description': 'body2', 'when': {'time': 1}, 'location': 'InboxHQ'} api_client.post_data('/events', e_data, ns_id) api_client.post_data('/events', e_data2, ns_id) db.session.commit()
def test_rate_limiting(patch_network_functions, api_client): """Test that sending is rate-limited appropriately. (Relies on a low value for DAILY_SENDING_LIMIT being set in the test config, for performance.)""" for _ in range(7): r = api_client.post_data('/send', {'to': [{'email': '*****@*****.**'}]}) assert r.status_code == 200 r = api_client.post_data('/send', {'to': [{'email': '*****@*****.**'}]}) assert r.status_code == 429
def test_sending_from_email_alias(patch_smtp, api_client): api_client.post_data('/send', {'to': [{'email': '*****@*****.**'}], 'from': [{'name': 'admin', 'email': '*****@*****.**'}], 'subject': 'Banalities', 'body': '<html>Hello there</html>'}) _, msg = patch_smtp[-1] parsed = mime.from_string(msg) assert 'From' in parsed.headers assert parsed.headers['From'] == 'admin <*****@*****.**>'
def test_get_all_drafts(api_client, example_draft): r = api_client.post_data("/drafts", example_draft) first_public_id = json.loads(r.data)["id"] r = api_client.post_data("/drafts", example_draft) second_public_id = json.loads(r.data)["id"] drafts = api_client.get_data("/drafts") assert len(drafts) == 2 assert first_public_id != second_public_id assert {first_public_id, second_public_id} == {draft["id"] for draft in drafts} assert all(item["state"] == "draft" and item["object"] == "draft" for item in drafts)
def test_recipient_validation(api_client): r = api_client.post_data('/drafts', {'to': '*****@*****.**'}) assert r.status_code == 400 r = api_client.post_data('/drafts', {'to': [{'name': 'foo'}]}) assert r.status_code == 400 r = api_client.post_data('/send', {'to': [{'email': 'foo'}]}) assert r.status_code == 400 r = api_client.post_data('/drafts', {'to': [{'name': 'Good Recipient', 'email': '*****@*****.**'}, '*****@*****.**']}) assert r.status_code == 400
def test_events_are_condensed(api_client): """Test that multiple revisions of the same object are rolled up in the delta response.""" ts = int(time.time()) api_client.post_data('/tags/', {'name': 'foo'}) cursor = get_cursor(api_client, ts) thread_id = api_client.get_data('/threads/')[0]['id'] thread_path = '/threads/{}'.format(thread_id) api_client.put_data(thread_path, {'add_tags': ['foo']}) api_client.put_data(thread_path, {'remove_tags': ['foo']}) sync_data = api_client.get_data('/delta?cursor={}'.format(cursor)) assert len(sync_data['deltas']) == 2
def test_drafts_filter(api_client, example_draft): r = api_client.post_data("/drafts", example_draft) public_id = json.loads(r.data)["id"] r = api_client.get_data("/drafts") matching_saved_drafts = [draft for draft in r if draft["id"] == public_id] thread_public_id = matching_saved_drafts[0]["thread"] reply_draft = {"subject": "test reply", "body": "test reply", "reply_to_thread": thread_public_id} r = api_client.post_data("/drafts", reply_draft) results = api_client.get_data("/drafts?thread={}".format(thread_public_id)) assert len(results) == 2
def test_get_all_drafts(api_client, example_draft): r = api_client.post_data('/drafts', example_draft) first_public_id = json.loads(r.data)['id'] r = api_client.post_data('/drafts', example_draft) second_public_id = json.loads(r.data)['id'] drafts = api_client.get_data('/drafts') assert len(drafts) == 2 assert first_public_id != second_public_id assert {first_public_id, second_public_id} == {draft['id'] for draft in drafts} assert all(item['object'] == 'draft' for item in drafts)
def test_delete_draft(api_client): original_draft = {"subject": "parent draft", "body": "parent draft"} r = api_client.post_data("/drafts", original_draft) draft_public_id = json.loads(r.data)["id"] updated_draft = {"subject": "updated draft", "body": "updated draft"} r = api_client.post_data("/drafts/{}".format(draft_public_id), updated_draft) updated_public_id = json.loads(r.data)["id"] r = api_client.delete("/drafts/{}".format(updated_public_id)) # Check that drafts were deleted drafts = api_client.get_data("/drafts") assert not drafts
def test_add_to_default_calendar(db, api_client): acct = db.session.query(Account).filter_by(id=ACCOUNT_ID).one() default_calendar = acct.default_calendar ns_id = acct.namespace.public_id old_length = len(default_calendar.events) e_data = {'title': 'subj', 'description': 'body1', 'when': {'time': 1}, 'location': 'InboxHQ'} api_client.post_data('/events', e_data, ns_id) cal_list = api_client.get_data('/calendars', ns_id) event_list = cal_list[0]['event_ids'] assert len(event_list) == old_length + 1
def test_api_create_bad_status(db, api_client): acct = db.session.query(Account).filter_by(id=ACCOUNT_ID).one() ns_id = acct.namespace.public_id e_data = { 'subject': 'Friday Office Party', 'when': { 'time': 1407542195 }, 'participants': [{ 'name': 'alyssa p. hacker', 'email': '*****@*****.**', 'status': 'bad' }] } e_resp = api_client.post_data('/events', e_data, ns_id) e_resp_data = json.loads(e_resp.data) assert e_resp_data["type"] == "invalid_request_error"
def test_create_draft_replying_to_thread(api_client): thread = api_client.get_data('/threads')[0] thread_id = thread['id'] latest_message_id = thread['message_ids'][-1] reply_draft = { 'subject': 'test reply', 'body': 'test reply', 'thread_id': thread_id } r = api_client.post_data('/drafts', reply_draft) draft_id = json.loads(r.data)['id'] drafts = api_client.get_data('/drafts') assert len(drafts) == 1 assert thread_id == drafts[0]['thread_id'] assert drafts[0]['reply_to_message_id'] == latest_message_id thread_data = api_client.get_data('/threads/{}'.format(thread_id)) assert draft_id in thread_data['draft_ids']
def test_api_create(contacts_provider, contact_sync, db, api_client): acct = db.session.query(Account).filter_by(id=ACCOUNT_ID).one() ns_id = acct.namespace.public_id c_data = {'name': 'Contact One', 'email': '*****@*****.**'} c_resp = api_client.post_data('/contacts', c_data, ns_id) c_resp_data = json.loads(c_resp.data) assert c_resp_data['object'] == 'contact' assert c_resp_data['namespace_id'] == acct.namespace.public_id assert c_resp_data['email'] == c_data['email'] assert c_resp_data['name'] == c_data['name'] assert 'id' in c_resp_data c_id = c_resp_data['id'] c_get_resp = api_client.get_data('/contacts/' + c_id, ns_id) assert c_get_resp['object'] == 'contact' assert c_get_resp['namespace_id'] == acct.namespace.public_id assert c_get_resp['email'] == c_data['email'] assert c_get_resp['name'] == c_data['name'] assert c_get_resp['id'] == c_id
def test_api_create_status_no(db, api_client): acct = db.session.query(Account).filter_by(id=ACCOUNT_ID).one() ns_id = acct.namespace.public_id e_data = { 'title': 'Friday Office Party', 'when': {'time': 1407542195}, 'participants': [{ 'email': '*****@*****.**', 'status': 'no' }] } e_resp = api_client.post_data('/events', e_data, ns_id) e_resp_data = json.loads(e_resp.data) assert len(e_resp_data['participants']) == 1 participant = e_resp_data['participants'][0] assert participant['name'] is None assert participant['email'] == e_data['participants'][0]['email'] assert participant['status'] == e_data['participants'][0]['status']
def test_get_calendar(db, api_client): acct = db.session.query(Account).filter_by(id=ACCOUNT_ID).one() ns_id = acct.namespace.public_id c_data = {'name': 'Holidays'} resp = api_client.post_data('/calendars', c_data, ns_id) resp_data = json.loads(resp.data) cal_id = resp_data['id'] resp_data = api_client.get_data('/calendars/' + cal_id, ns_id) assert resp_data['namespace'] == ns_id assert resp_data['name'] == c_data['name'] assert resp_data['description'] is None assert resp_data['read_only'] is False assert resp_data['object'] == 'calendar' assert resp_data['event_ids'] == [] cal = db.session.query(Calendar).filter_by(public_id=cal_id).one() db.session.delete(cal) db.session.commit()
def test_file_filtering(api_client, uploaded_file_ids, draft): for f_id in uploaded_file_ids: results = api_client.get_data('/files?file_id={}'.format(f_id)) assert len(results) == 1 # Attach the files to a draft and search there draft['file_ids'] = uploaded_file_ids r = api_client.post_data('/drafts', draft) assert r.status_code == 200 draft_resp = json.loads(r.data) assert len(draft_resp['files']) == 3 d_id = draft_resp['id'] results = api_client.get_data('/files?message_id={}'.format(d_id)) assert all([d_id in f['message_ids'] for f in results]) assert len(results) == 3 results = api_client.get_data('/files?message_id={}&limit=1'.format(d_id)) assert len(results) == 1 results = api_client.get_data('/files?message_id={}&offset=2'.format(d_id)) assert len(results) == 1 results = api_client.get_data('/files?filename=LetMeSendYouEmail.wav') assert len(results) == 1 results = api_client.get_data('/files?content_type=audio%2Fx-wav') assert len(results) == 1 results = api_client.get_data('/files?content_type=image%2Fjpeg') assert len(results) == 2 results = api_client.get_data( '/files?content_type=image%2Fjpeg&view=count') assert results["count"] == 2 results = api_client.get_data('/files?content_type=image%2Fjpeg&view=ids') assert len(results) == 2
def test_event_generation(api_client): """Tests that deltas are returned in response to client sync API calls. Doesn't test formatting of individual deltas in the response.""" ts = int(time.time()) api_client.post_data('/tags/', {'name': 'foo'}) cursor_response = api_client.post_data('/delta/generate_cursor', {'start': ts}) cursor = json.loads(cursor_response.data)['cursor'] sync_data = api_client.get_data('/delta?cursor={}'.format(cursor)) assert len(sync_data['deltas']) == 1 api_client.post_data('/contacts/', { 'name': 'test', 'email': '*****@*****.**' }) sync_data = api_client.get_data('/delta?cursor={}'.format(cursor)) assert len(sync_data['deltas']) == 2 thread_id = api_client.get_data('/threads/')[0]['id'] thread_path = '/threads/{}'.format(thread_id) api_client.put_data(thread_path, {'add_tags': ['foo']}) sync_data = api_client.get_data('/delta?cursor={}'.format(cursor)) assert len(sync_data['deltas']) == 3 time.sleep(1) ts = int(time.time()) # Test result limiting for _ in range(5): api_client.put_data(thread_path, {'remove_tags': ['foo']}) api_client.put_data(thread_path, {'add_tags': ['foo']}) cursor_response = api_client.post_data('/delta/generate_cursor', {'start': ts}) cursor = json.loads(cursor_response.data)['cursor'] sync_data = api_client.get_data('/delta?cursor={0}&limit={1}'.format( cursor, 8)) assert len(sync_data['deltas']) == 8 cursor = sync_data['cursor_end'] sync_data = api_client.get_data('/delta?cursor={0}'.format(cursor)) assert len(sync_data['deltas']) == 2
def test_api_participant_reply(db, api_client, rsvp): acct = db.session.query(Account).filter_by(id=ACCOUNT_ID).one() ns_id = acct.namespace.public_id e_data = { 'title': 'Friday Office Party', 'when': {'time': 1407542195}, 'participants': [{'email': '*****@*****.**'}, {'email': '*****@*****.**'}, {'email': '*****@*****.**'}, {'email': '*****@*****.**'}, {'email': '*****@*****.**'}] } e_resp = api_client.post_data('/events', e_data, ns_id) e_resp_data = json.loads(e_resp.data) assert len(e_resp_data['participants']) == 5 event_id = e_resp_data['id'] participants = e_resp_data['participants'] url = '/events/{}?'.format(event_id)
def test_contacts_updated(api_client): """Tests that draft-contact associations are properly created and updated.""" draft = { 'to': [{ 'email': '*****@*****.**' }, { 'email': '*****@*****.**' }] } r = api_client.post_data('/drafts', draft) assert r.status_code == 200 draft_id = json.loads(r.data)['id'] draft_version = json.loads(r.data)['version'] r = api_client.get_data('/[email protected]') assert len(r) == 1 updated_draft = { 'to': [{ 'email': '*****@*****.**' }, { 'email': '*****@*****.**' }], 'version': draft_version } r = api_client.put_data('/drafts/{}'.format(draft_id), updated_draft) assert r.status_code == 200 r = api_client.get_data('/[email protected]') assert len(r) == 1 r = api_client.get_data('/[email protected]') assert len(r) == 0 r = api_client.get_data('/[email protected]') assert len(r) == 1
def test_read_update_tags(api_client): r = api_client.post_data('/tags/', {'name': 'foo'}) public_id = json.loads(r.data)['id'] tag_data = api_client.get_data('/tags/{}'.format(public_id)) assert tag_data['name'] == 'foo' assert tag_data['id'] == public_id tag_ns_id = tag_data['namespace_id'] r = api_client.put_data('/tags/{}'.format(public_id), {'name': 'bar'}) assert json.loads(r.data)['name'] == 'bar' # include namespace r = api_client.put_data('/tags/{}'.format(public_id), { 'name': 'baz', 'namespace_id': tag_ns_id }) assert json.loads(r.data)['name'] == 'baz' updated_tag_data = api_client.get_data('/tags/{}'.format(public_id)) assert updated_tag_data['name'] == 'baz' assert updated_tag_data['id'] == public_id
def test_delete_draft(api_client): original_draft = {'subject': 'parent draft', 'body': 'parent draft'} r = api_client.post_data('/drafts', original_draft) draft_public_id = json.loads(r.data)['id'] version = json.loads(r.data)['version'] updated_draft = { 'subject': 'updated draft', 'body': 'updated draft', 'version': version } r = api_client.put_data('/drafts/{}'.format(draft_public_id), updated_draft) updated_public_id = json.loads(r.data)['id'] updated_version = json.loads(r.data)['version'] r = api_client.delete('/drafts/{}'.format(updated_public_id), {'version': updated_version}) # Check that drafts were deleted drafts = api_client.get_data('/drafts') assert not drafts
def test_add_remove_tag_by_public_id(api_client): assert 'foo bar' not in [ tag['name'] for tag in api_client.get_data('/tags/') ] post_resp = api_client.post_data('/tags/', {'name': 'foo bar'}) public_id = json.loads(post_resp.data)['id'] thread_id = api_client.get_data('/threads')[0]['id'] thread_path = '/threads/{}'.format(thread_id) r = api_client.put_data(thread_path, {'add_tags': [public_id]}) assert r.status_code == 200 tag_names = [ tag['name'] for tag in api_client.get_data(thread_path)['tags'] ] assert 'foo bar' in tag_names r = api_client.put_data(thread_path, {'remove_tags': [public_id]}) assert r.status_code == 200 tag_names = get_tag_names(api_client.get_data(thread_path)) assert 'foo bar' not in tag_names
def test_create_and_get_draft(api_client, example_draft): r = api_client.post_data('/drafts', example_draft) assert r.status_code == 200 public_id = json.loads(r.data)['id'] version = json.loads(r.data)['version'] assert version == 0 r = api_client.get_data('/drafts') matching_saved_drafts = [draft for draft in r if draft['id'] == public_id] assert len(matching_saved_drafts) == 1 saved_draft = matching_saved_drafts[0] assert all(saved_draft[k] == v for k, v in example_draft.iteritems()) # Check that thread gets the draft tag threads_with_drafts = api_client.get_data('/threads?tag=drafts') assert len(threads_with_drafts) == 1 # Check that thread doesn't get the attachment tag, in this case thread_tags = threads_with_drafts[0]['tags'] assert not any('attachment' == tag['name'] for tag in thread_tags)
def test_create_nonbool_all_day(events_provider, event_sync, db, api_client): acct = db.session.query(Account).filter_by(id=ACCOUNT_ID).one() ns_id = acct.namespace.public_id e_data = { 'subject': '', 'start': -1407543195, 'end': 1407542195, 'busy': True, 'all_day': 'False' } event_list = api_client.get_data('/events', ns_id) length_before = len(event_list) e_resp = api_client.post_data('/events', e_data, ns_id) e_resp_data = json.loads(e_resp.data) assert e_resp_data["type"] == "invalid_request_error" event_list = api_client.get_data('/events', ns_id) length_after = len(event_list) assert length_before == length_after
def test_api_delete(db, api_client, calendar, default_account): e_data = { 'title': '', 'calendar_id': calendar.public_id, 'when': { 'time': 1407542195 }, } e_resp = api_client.post_data('/events', e_data) e_resp_data = json.loads(e_resp.data) assert e_resp_data['object'] == 'event' assert e_resp_data['title'] == e_data['title'] assert e_resp_data['when']['time'] == e_data['when']['time'] assert 'id' in e_resp_data e_id = e_resp_data['id'] e_delete_resp = api_client.delete('/events/' + e_id) assert e_delete_resp.status_code == 200 e_resp = api_client.get_data('/events/' + e_id) assert e_resp['status'] == 'cancelled'
def test_is_attachment_filtering(api_client, uploaded_file_ids, draft): """Attach files to draft, make sure we can use is_attachment specifier""" old_total = len(api_client.get_data('/files')) old_orphan = len(api_client.get_data('/files?is_attachment=0')) old_attach = len(api_client.get_data('/files?is_attachment=1')) assert old_attach + old_orphan == old_total draft['file_ids'] = [uploaded_file_ids.pop()] r = api_client.post_data('/drafts', draft) assert r.status_code == 200 draft_resp = json.loads(r.data) assert len(draft_resp['files']) == 1 new_total = len(api_client.get_data('/files')) new_orphan = len(api_client.get_data('/files?is_attachment=0')) new_attach = len(api_client.get_data('/files?is_attachment=1')) assert new_attach + new_orphan == new_total assert new_attach == old_attach + 1 assert new_orphan == old_orphan - 1 assert new_total == old_total
def test_api_add_participant(db, api_client): acct = db.session.query(Account).filter_by(id=ACCOUNT_ID).one() ns_id = acct.namespace.public_id e_data = { 'subject': 'Friday Office Party', 'when': { 'time': 1407542195 }, 'participants': [{ 'email': '*****@*****.**' }, { 'email': '*****@*****.**' }, { 'email': '*****@*****.**' }, { 'email': '*****@*****.**' }, { 'email': '*****@*****.**' }] } e_resp = api_client.post_data('/events', e_data, ns_id) e_resp_data = json.loads(e_resp.data) assert len(e_resp_data['participants']) == 5 for i, p in enumerate(e_resp_data['participants']): assert p['email'] == e_data['participants'][i]['email'] assert p['name'] is None event_id = e_resp_data['id'] e_data['participants'].append({'email': '*****@*****.**'}) e_resp = api_client.put_data('/events/' + event_id, e_data, ns_id) e_resp_data = json.loads(e_resp.data) assert len(e_resp_data['participants']) == 6 for i, p in enumerate(e_resp_data['participants']): assert p['email'] == e_data['participants'][i]['email'] assert p['name'] is None
def test_bcc_in_recipients_but_stripped_from_headers(patch_smtp, api_client): r = api_client.post_data( '/send', { 'to': [{ 'email': '*****@*****.**' }], 'cc': [{ 'email': '*****@*****.**' }], 'bcc': [{ 'email': '*****@*****.**' }], 'subject': 'Banalities' }) assert r.status_code == 200 recipients, msg = patch_smtp[0] assert set(recipients) == { '*****@*****.**', '*****@*****.**', '*****@*****.**' } parsed = mime.from_string(msg) assert 'Bcc' not in parsed.headers assert parsed.headers.get('To') == '*****@*****.**' assert parsed.headers.get('Cc') == '*****@*****.**'
def test_update_draft(api_client): original_draft = {'subject': 'parent draft', 'body': 'parent draft'} r = api_client.post_data('/drafts', original_draft) draft_public_id = json.loads(r.data)['id'] version = json.loads(r.data)['version'] updated_draft = { 'subject': 'updated draft', 'body': 'updated draft', 'version': version } r = api_client.put_data('/drafts/{}'.format(draft_public_id), updated_draft) updated_public_id = json.loads(r.data)['id'] updated_version = json.loads(r.data)['version'] assert updated_public_id == draft_public_id and \ updated_version != version drafts = api_client.get_data('/drafts') assert len(drafts) == 1 assert drafts[0]['id'] == updated_public_id
def test_api_participant_reply_invalid_rsvp(db, api_client): acct = db.session.query(Account).filter_by(id=ACCOUNT_ID).one() ns_id = acct.namespace.public_id e_data = { 'subject': 'Friday Office Party', 'when': { 'time': 1407542195 }, 'participants': [{ 'email': '*****@*****.**' }, { 'email': '*****@*****.**' }, { 'email': '*****@*****.**' }, { 'email': '*****@*****.**' }, { 'email': '*****@*****.**' }] } e_resp = api_client.post_data('/events', e_data, ns_id) e_resp_data = json.loads(e_resp.data) assert len(e_resp_data['participants']) == 5 event_id = e_resp_data['id'] participants = e_resp_data['participants'] participant_id = participants[0]['id'] url = '/events/{}?'.format(event_id) url += 'action=rsvp&participant_id={}&rsvp={}'.format( participant_id, 'bad') e_resp_data = api_client.get_data(url, ns_id) assert e_resp_data['type'] == 'api_error'
def test_add_to_read_only_calendar(db, api_client): acct = db.session.query(Account).filter_by(id=ACCOUNT_ID).one() ns_id = acct.namespace.public_id cal_list = api_client.get_data('/calendars', ns_id) assert len(cal_list) == 2 ro_cal = None for c in cal_list: if c['read_only']: ro_cal = c assert ro_cal e_data = { 'calendar_id': ro_cal['id'], 'title': 'subj', 'description': 'body1', 'when': { 'time': 1 }, 'location': 'InboxHQ' } resp = api_client.post_data('/events', e_data, ns_id) assert resp.status_code != 200
def test_api_create_no_title(db, api_client, calendar, default_account): e_data = { 'title': '', 'calendar_id': calendar.public_id, 'when': { 'time': 1407542195 }, } e_resp = api_client.post_data('/events', e_data) e_resp_data = json.loads(e_resp.data) assert e_resp_data['object'] == 'event' assert e_resp_data['namespace_id'] == default_account.namespace.public_id assert e_resp_data['title'] == e_data['title'] assert e_resp_data['when']['time'] == e_data['when']['time'] assert 'id' in e_resp_data e_id = e_resp_data['id'] e_get_resp = api_client.get_data('/events/' + e_id) assert e_get_resp['object'] == 'event' assert e_get_resp['namespace_id'] == default_account.namespace.public_id assert e_get_resp['id'] == e_id assert e_get_resp['title'] == e_data['title'] assert e_get_resp['when']['time'] == e_data['when']['time']
def test_api_delete(db, api_client): acct = db.session.query(Account).filter_by(id=ACCOUNT_ID).one() ns_id = acct.namespace.public_id e_data = { 'title': '', 'when': { 'time': 1407542195 }, } e_resp = api_client.post_data('/events', e_data, ns_id) e_resp_data = json.loads(e_resp.data) assert e_resp_data['object'] == 'event' assert e_resp_data['namespace_id'] == acct.namespace.public_id assert e_resp_data['title'] == e_data['title'] assert e_resp_data['when']['time'] == e_data['when']['time'] assert 'id' in e_resp_data e_id = e_resp_data['id'] api_client.delete('/events/' + e_id, ns_id=ns_id) event = api_client.get_data('/events/' + e_id, ns_id) assert event['type'] == 'invalid_request_error'
def test_api_create_multiple(db, api_client, calendar): acct = db.session.query(Account).filter_by(id=ACCOUNT_ID).one() ns_id = acct.namespace.public_id e_data = { 'title': 'Friday Office Party', 'when': { 'time': 1407542195 }, 'calendar_id': calendar.public_id, 'participants': [{ 'email': '*****@*****.**', }, { 'email': '*****@*****.**', }] } e_resp = api_client.post_data('/events', e_data, ns_id) e_resp_data = json.loads(e_resp.data) assert len(e_resp_data['participants']) == 2 for participant in e_resp_data['participants']: res = [ e for e in e_data['participants'] if e['email'] == participant['email'] ] assert len(res) == 1 participant0 = e_resp_data['participants'][0] participant1 = e_resp_data['participants'][1] assert participant0['name'] is None assert participant0['status'] == 'noreply' assert participant1['name'] is None assert participant1['status'] == 'noreply'
def _verify_create(ns_id, api_client, e_data): e_resp = api_client.post_data('/events', e_data, ns_id) if e_resp.status_code != 200: raise CreateError() e_resp_data = json.loads(e_resp.data) assert e_resp_data['object'] == 'event' assert e_resp_data['namespace_id'] == ns_id assert e_resp_data['title'] == e_data['title'] assert e_resp_data['location'] == e_data['location'] for k, v in e_data['when'].iteritems(): assert arrow.get(e_resp_data['when'][k]) == arrow.get(v) assert 'id' in e_resp_data e_id = e_resp_data['id'] e_get_resp = api_client.get_data('/events/' + e_id, ns_id) assert e_get_resp['object'] == 'event' assert e_get_resp['namespace_id'] == ns_id assert e_get_resp['id'] == e_id assert e_get_resp['title'] == e_data['title'] for k, v in e_data['when'].iteritems(): assert arrow.get(e_get_resp['when'][k]) == arrow.get(v) return e_resp_data
def test_smtp_ssl_verification_bad_cert(db, api_client, bad_cert_smtp_server, example_draft, local_smtp_account): ns_public_id = local_smtp_account.namespace.public_id r = api_client.post_data('/send', example_draft, ns_public_id) assert r.status_code == 503 assert json.loads(r.data)['message'] == 'SSL certificate verify failed'
def test_message_search(db, api_client, search_engine): message = db.session.query(Message).get(2) subject = message.subject to_addr = message.to_addr[0][1] from_addr = message.from_addr[0][1] cc_addr = message.cc_addr[0][1] bcc_addr = message.bcc_addr #received_date = message.received_date endpoint = '/messages/search' # No query i.e. return all resp = api_client.post_data(endpoint, {}) assert resp.status_code == 200 result_dict = json.loads(resp.data) total = result_dict['total'] results = result_dict['results'] assert total == 16 and len(results) == 16 third_msg_id = results[2]['object']['id'] resp = api_client.post_data(endpoint + '?limit={}&offset={}'. format(2, 2), {}) assert resp.status_code == 200 result_dict = json.loads(resp.data) total = result_dict['total'] results = result_dict['results'] assert total > 2 and len(results) == 2 assert results[0]['object']['id'] == third_msg_id # Simple field match-phrase queries: data = dict(query=[{'thread_id': 'e6z26rjrxs2gu8at6gsa8svr1'}]) resp = api_client.post_data(endpoint, data) assert resp.status_code == 200 result_dict = json.loads(resp.data) results = result_dict['results'] assert len(results) == 1 data = dict(query=[{'cc': cc_addr}]) resp = api_client.post_data(endpoint, data) assert resp.status_code == 200 result_dict = json.loads(resp.data) results = result_dict['results'] assert len(results) == 1 data = dict(query=[{'bcc': bcc_addr}]) resp = api_client.post_data(endpoint, data) assert resp.status_code == 200 result_dict = json.loads(resp.data) results = result_dict['results'] assert len(results) == 0 data = dict(query=[{'from': from_addr}]) resp = api_client.post_data(endpoint, data) assert resp.status_code == 200 result_dict = json.loads(resp.data) results = result_dict['results'] assert len(results) == 1 data = dict(query=[{'subject': subject}]) resp = api_client.post_data(endpoint, data) assert resp.status_code == 200 result_dict = json.loads(resp.data) results = result_dict['results'] assert len(results) == 1 data = dict(query=[{ 'from': from_addr, 'to': to_addr}]) resp = api_client.post_data(endpoint, data) assert resp.status_code == 200 result_dict = json.loads(resp.data) results = result_dict['results'] assert len(results) == 1 data = dict(query=[{'to': '*****@*****.**'}]) resp = api_client.post_data(endpoint + '?limit={}&offset={}'. format(2, 1), data) assert resp.status_code == 200 result_dict = json.loads(resp.data) results = result_dict['results'] assert len(results) == 2 data = dict(query=[{'body': 'Google Search'}]) resp = api_client.post_data(endpoint, data) assert resp.status_code == 200 result_dict = json.loads(resp.data) results = result_dict['results'] assert len(results) == 1 # Simple field match queries: data = dict(query=[{'body': 'reproduce paste'}]) resp = api_client.post_data(endpoint, data) assert resp.status_code == 200 result_dict = json.loads(resp.data) match_phrase_results = result_dict['results'] data = dict(query=[{'body': ['reproduce', 'paste']}]) resp = api_client.post_data(endpoint, data) assert resp.status_code == 200 result_dict = json.loads(resp.data) match_results = result_dict['results'] assert len(match_phrase_results) == 0 and len(match_results) == 1 # All fields, match-phrase query: data = dict(query=[{'all': 'yoga'}]) resp = api_client.post_data(endpoint, data) assert resp.status_code == 200 result_dict = json.loads(resp.data) default_results = result_dict['results'] assert len(default_results) >= 5 default = [(r['object']['id'], r['relevance']) for r in default_results] data = dict(query=[{'all': 'yoga', 'weights': {'from': 2}}]) resp = api_client.post_data(endpoint, data) assert resp.status_code == 200 result_dict = json.loads(resp.data) rescored_results = result_dict['results'] assert len(rescored_results) >= 5 rescored = [(r['object']['id'], r['relevance']) for r in rescored_results] assert rescored != default
def test_cant_create_existing_tag(api_client): api_client.post_data('/tags/', {'name': 'foo'}) r = api_client.post_data('/tags/', {'name': 'foo'}) assert r.status_code == 409
def test_api_update_participant_status(db, api_client): acct = db.session.query(Account).filter_by(id=ACCOUNT_ID).one() ns_id = acct.namespace.public_id e_data = { 'title': 'Friday Office Party', 'when': { 'time': 1407542195 }, 'participants': [{ 'email': '*****@*****.**' }, { 'email': '*****@*****.**' }, { 'email': '*****@*****.**' }, { 'email': '*****@*****.**' }, { 'email': '*****@*****.**' }] } e_resp = api_client.post_data('/events', e_data, ns_id) e_resp_data = json.loads(e_resp.data) assert len(e_resp_data['participants']) == 5 for i, p in enumerate(e_resp_data['participants']): res = [e for e in e_data['participants'] if e['email'] == p['email']] assert len(res) == 1 assert p['name'] is None event_id = e_resp_data['id'] update_data = { 'participants': [{ 'email': '*****@*****.**', 'status': 'yes' }, { 'email': '*****@*****.**', 'status': 'no' }, { 'email': '*****@*****.**', 'status': 'maybe' }, { 'email': '*****@*****.**' }, { 'email': '*****@*****.**' }] } e_resp = api_client.put_data('/events/' + event_id, update_data, ns_id) e_resp_data = json.loads(e_resp.data) # Make sure that nothing changed that we didn't specify assert e_resp_data['title'] == 'Friday Office Party' assert e_resp_data['when']['time'] == 1407542195 assert len(e_resp_data['participants']) == 5 for i, p in enumerate(e_resp_data['participants']): res = [e for e in e_data['participants'] if e['email'] == p['email']] assert len(res) == 1 assert p['name'] is None
def get_cursor(api_client, timestamp): cursor_response = api_client.post_data('/delta/generate_cursor', {'start': timestamp}) return json.loads(cursor_response.data)['cursor']