def test_api_expand_recurring(db, api_client): acct = db.session.query(Account).filter_by(id=ACCOUNT_ID).one() ns_id = acct.namespace.public_id event = add_recurring_event(db, acct) # 3 existing test events in database + 1 new one events = api_client.get_data('/events?expand_recurring=false', ns_id) assert len(events) == 4 # Make sure the recurrence info is on the recurring event for e in events: if e['title'] == 'recurring-weekly': assert e.get('recurrence') is not None thirty_weeks = event.start.replace(weeks=+30).isoformat() starts_after = event.start.replace(days=-1).isoformat() recur = 'expand_recurring=true&starts_after={}&ends_before={}'.format( urllib.quote_plus(starts_after), urllib.quote_plus(thirty_weeks)) all_events = api_client.get_data('/events?' + recur, ns_id) assert len(all_events) == 30 # the ordering should be correct prev = all_events[0]['when']['start_time'] for e in all_events[1:]: assert e['when']['start_time'] > prev prev = e['when']['start_time'] events = api_client.get_data('/events?' + recur + '&limit=5', ns_id) assert len(events) == 5 events = api_client.get_data('/events?' + recur + '&offset=5', ns_id) assert events[0]['id'] == all_events[5]['id'] events = api_client.get_data('/events?' + recur + '&view=count', ns_id) assert events.get('count') == 30
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_api_expand_recurring_before_after(db, api_client): acct = db.session.query(Account).filter_by(id=ACCOUNT_ID).one() ns_id = acct.namespace.public_id event = add_recurring_event(db, acct) starts_after = event.start.replace(weeks=+15) ends_before = starts_after.replace(days=+1) recur = 'expand_recurring=true&starts_after={}&ends_before={}'.format( urlsafe(starts_after), urlsafe(ends_before)) all_events = api_client.get_data('/events?' + recur, ns_id) assert len(all_events) == 1 recur = 'expand_recurring=true&starts_after={}&starts_before={}'.format( urlsafe(starts_after), urlsafe(ends_before)) all_events = api_client.get_data('/events?' + recur, ns_id) assert len(all_events) == 1 recur = 'expand_recurring=true&ends_after={}&starts_before={}'.format( urlsafe(starts_after), urlsafe(ends_before)) all_events = api_client.get_data('/events?' + recur, ns_id) assert len(all_events) == 1 recur = 'expand_recurring=true&ends_after={}&ends_before={}'.format( urlsafe(starts_after), urlsafe(ends_before)) all_events = api_client.get_data('/events?' + recur, ns_id) assert len(all_events) == 1
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()) cursor = get_cursor(api_client, ts) # Create, then modify a tag; then modify it again tag = json.loads(api_client.post_data('/tags/', {'name': 'foo'}).data) tag_id = tag['id'] api_client.put_data('/tags/{}'.format(tag_id), {'name': 'bar'}) api_client.put_data('/tags/{}'.format(tag_id), {'name': 'baz'}) # Modify a thread, then modify it again thread_id = api_client.get_data('/threads/')[0]['id'] thread_path = '/threads/{}'.format(thread_id) api_client.put_data(thread_path, {'add_tags': [tag_id]}) api_client.put_data(thread_path, {'remove_tags': [tag_id]}) sync_data = api_client.get_data('/delta?cursor={}'.format(cursor)) assert len(sync_data['deltas']) == 3 first_delta = sync_data['deltas'][0] assert first_delta['object'] == 'tag' and first_delta['event'] == 'create' # Check that successive modifies are condensed. second_delta = sync_data['deltas'][1] assert (second_delta['object'] == 'tag' and second_delta['event'] == 'modify') assert second_delta['attributes']['name'] == 'baz' third_delta = sync_data['deltas'][2] assert (third_delta['object'] == 'thread' and third_delta['event'] == 'modify')
def test_update_draft(api_client): original_draft = {"subject": "original 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"] assert version == 0 # Sleep so that timestamp on updated draft is different. gevent.sleep(1) 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 assert updated_version > 0 drafts = api_client.get_data("/drafts") assert len(drafts) == 1 assert drafts[0]["id"] == updated_public_id # Check that the thread is updated too. thread = api_client.get_data("/threads/{}".format(drafts[0]["thread_id"])) assert thread["subject"] == "updated draft" assert thread["first_message_timestamp"] == drafts[0]["date"] assert thread["last_message_timestamp"] == drafts[0]["date"]
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_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_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_api_get(contacts_provider, contact_sync, db, api_client): contacts_provider.supply_contact('Contact One', '*****@*****.**') contacts_provider.supply_contact('Contact Two', '*****@*****.**') contact_sync.provider = contacts_provider contact_sync.sync() acct = db.session.query(Account).filter_by(id=ACCOUNT_ID).one() ns_id = acct.namespace.public_id contact_list = api_client.get_data('/contacts', ns_id) contact_ids = [contact['id'] for contact in contact_list] c1found = False c2found = False for c_id in contact_ids: contact = api_client.get_data('/contacts/' + c_id, ns_id) if contact['name'] == 'Contact One': c1found = True if contact['name'] == 'Contact Two': c2found = True assert c1found assert c2found
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_api_get(contacts_provider, contact_sync, db, api_client, default_namespace): contacts_provider.supply_contact("Contact One", "*****@*****.**") contacts_provider.supply_contact("Contact Two", "*****@*****.**") contact_sync.provider = contacts_provider contact_sync.sync() ns_id = default_namespace.public_id contact_list = api_client.get_data("/contacts", ns_id) contact_ids = [contact["id"] for contact in contact_list] c1found = False c2found = False for c_id in contact_ids: contact = api_client.get_data("/contacts/" + c_id, ns_id) if contact["name"] == "Contact One": c1found = True if contact["name"] == "Contact Two": c2found = True assert c1found assert c2found
def test_delete_tag(api_client, default_namespace, thread): post_resp = api_client.post_data('/tags/', {'name': 'foo'}) tag_resp = json.loads(post_resp.data) tag_id = tag_resp['id'] thread_id = api_client.get_data('/threads')[0]['id'] api_client.put_data('/threads/{}'.format(thread_id), {'add_tags': ['foo']}) del_resp = api_client.delete('/tags/' + tag_id) assert del_resp.status_code == 200 tag_data = api_client.get_data('/tags/{}'.format(tag_id)) assert tag_data['message'] == 'No tag found' thread = api_client.get_data('/threads/{}'.format(thread_id)) assert 'foo' not in [tag['name'] for tag in thread['tags']] del_resp = api_client.delete('/tags/!' + tag_id) assert del_resp.status_code == 400 assert json.loads(del_resp.data)['message'].startswith('Invalid id') del_resp = api_client.delete('/tags/0000000000000000000000000') assert del_resp.status_code == 404 del_resp = api_client.delete('/tags/inbox') assert del_resp.status_code == 400 assert 'user-created' in json.loads(del_resp.data)['message']
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'] participant_id = participants[0]['id'] url = '/events/{}?'.format(event_id) url += 'action=rsvp&participant_id={}&rsvp={}'.format(participant_id, rsvp) e_resp_data = api_client.get_data(url, ns_id) participants = e_resp_data['participants'] assert len(participants) == 5 assert participants[0]['status'] == rsvp e_resp_data = api_client.get_data('/events/' + e_resp_data['id'], ns_id) participants = e_resp_data['participants'] assert len(participants) == 5 assert participants[0]['status'] == rsvp
def test_delete_remote_draft(db, api_client): from inbox.models.message import Message # Non-Inbox created draft, therefore don't set inbox_uid message = Message() message.namespace_id = NAMESPACE_ID message.thread_id = 1 message.received_date = datetime.utcnow() message.size = len('') message.is_draft = True message.is_read = True message.sanitized_body = '' message.snippet = '' db.session.add(message) db.session.commit() drafts = api_client.get_data('/drafts') assert len(drafts) == 1 public_id = drafts[0]['id'] version = drafts[0]['version'] assert public_id == message.public_id and version == message.version api_client.delete('/drafts/{}'.format(public_id), {'version': version}) # Check that drafts were deleted drafts = api_client.get_data('/drafts') assert not drafts
def test_send(patch_network_functions, api_client, example_draft, syncback_service, default_account): 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 }) # TODO(emfree) do this more rigorously gevent.sleep(0.5) 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_update_draft(api_client): original_draft = {'subject': 'original 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'] assert version == 0 # Sleep so that timestamp on updated draft is different. gevent.sleep(1) 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 assert updated_version > 0 drafts = api_client.get_data('/drafts') assert len(drafts) == 1 assert drafts[0]['id'] == updated_public_id # Check that the thread is updated too. thread = api_client.get_data('/threads/{}'.format(drafts[0]['thread_id'])) assert thread['subject'] == 'updated draft' assert thread['first_message_timestamp'] == drafts[0]['date'] assert thread['last_message_timestamp'] == drafts[0]['date']
def test_api_get(events_provider, event_sync, db, api_client): events_provider.supply_event('subj', '', 0, 1, False, False) events_provider.supply_event('subj2', '', 0, 1, False, False) event_sync.provider_instance = events_provider event_sync.poll() acct = db.session.query(Account).filter_by(id=ACCOUNT_ID).one() ns_id = acct.namespace.public_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['subject'] == 'subj': c1found = True if event['subject'] == 'subj2': c2found = True assert c1found assert c2found
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_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_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_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_get_with_id(api_client, uploaded_file_ids, filename): # See comment in uploaded_file_ids() if filename == 'piece-jointe.jpg': filename = u'pièce-jointe.jpg' in_file = api_client.get_data(u'/files?filename={}'.format(filename))[0] data = api_client.get_data('/files/{}'.format(in_file['id'])) assert data['filename'] == filename
def test_filter_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', 'description': 'Local Holidays'} resp = api_client.post_data('/calendars', c_data, ns_id) resp_data = json.loads(resp.data) cal_id = resp_data['id'] _filter = "?filter=Holidays" resp_data = api_client.get_data('/calendars' + _filter, ns_id)[0] assert resp_data['namespace'] == ns_id assert resp_data['name'] == c_data['name'] assert resp_data['description'] == 'Local Holidays' assert resp_data['read_only'] is False assert resp_data['object'] == 'calendar' assert resp_data['event_ids'] == [] _filter = "?filter=Local%20Holidays" resp_data = api_client.get_data('/calendars' + _filter, ns_id) assert len(resp_data) == 1 cal = db.session.query(Calendar).filter_by(public_id=cal_id).one() db.session.delete(cal) db.session.commit()
def test_move_to_read_only_calendar(db, api_client): acct = db.session.query(Account).filter_by(id=ACCOUNT_ID).one() ns_id = acct.namespace.public_id calendar_list = api_client.get_data('/calendars', ns_id) read_only_calendar = None writeable_calendar = None writeable_event = None for c in calendar_list: if c['read_only']: read_only_calendar = c else: writeable_calendar = c for e_id in c['event_ids']: e = api_client.get_data('/events/' + e_id, ns_id) if not e['read_only']: writeable_event = e break assert read_only_calendar assert writeable_event assert writeable_calendar e_id = writeable_event['id'] e_data = {'calendar_id': read_only_calendar['id']} resp = api_client.put_data('/events/' + e_id, e_data, ns_id) assert resp.status_code != 200
def test_api_get(contacts_provider, contact_sync, db, api_client): contacts_provider.supply_contact('Contact One', '*****@*****.**') contacts_provider.supply_contact('Contact Two', '*****@*****.**') contact_sync.provider_instance = contacts_provider contact_sync.poll() acct = db.session.query(Account).filter_by(id=ACCOUNT_ID).one() ns_id = acct.namespace.public_id contact_list = api_client.get_data('/contacts', ns_id) contact_ids = [contact['id'] for contact in contact_list] c1found = False c2found = False for c_id in contact_ids: contact = api_client.get_data('/contacts/' + c_id, ns_id) if contact['name'] == 'Contact One': c1found = True if contact['name'] == 'Contact Two': c2found = True assert c1found assert c2found
def test_delete_calendar_deletes_events(db, api_client): acct = db.session.query(Account).filter_by(id=ACCOUNT_ID).one() ns_id = acct.namespace.public_id c_data = {'name': 'TBD'} resp = api_client.post_data('/calendars', c_data, ns_id) resp_data = json.loads(resp.data) cal_id = resp_data['id'] e_data = { 'calendar_id': cal_id, 'title': 'subj', 'description': 'body1', 'when': { 'time': 1 }, 'location': 'InboxHQ' } api_client.post_data('/events', e_data, ns_id) _filter = "?filter=TBD" cal_list = api_client.get_data('/calendars' + _filter, ns_id) event_id = cal_list[0]['event_ids'][0] resp = api_client.get_data('/events/' + event_id, ns_id) resp = api_client.delete('/calendars/' + cal_id, ns_id) assert resp.status_code == 200 resp = api_client.get_data('/events/' + event_id, ns_id) assert resp['type'] == 'invalid_request_error'
def test_filter_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', 'description': 'Local Holidays'} resp = api_client.post_data('/calendars', c_data, ns_id) resp_data = json.loads(resp.data) cal_id = resp_data['id'] _filter = "?filter=Holidays" resp_data = api_client.get_data('/calendars' + _filter, ns_id)[0] assert resp_data['namespace_id'] == ns_id assert resp_data['name'] == c_data['name'] assert resp_data['description'] == 'Local Holidays' assert resp_data['read_only'] is False assert resp_data['object'] == 'calendar' assert resp_data['event_ids'] == [] _filter = "?filter=Local%20Holidays" resp_data = api_client.get_data('/calendars' + _filter, ns_id) assert len(resp_data) == 1 cal = db.session.query(Calendar).filter_by(public_id=cal_id).one() db.session.delete(cal) db.session.commit()
def test_delete_tag(api_client, default_namespace): post_resp = api_client.post_data('/tags/', {'name': 'foo'}) tag_resp = json.loads(post_resp.data) tag_id = tag_resp['id'] thread_id = api_client.get_data('/threads')[0]['id'] api_client.put_data('/threads/{}'.format(thread_id), {'add_tags': ['foo']}) del_resp = api_client.delete('/tags/' + tag_id) assert del_resp.status_code == 200 tag_data = api_client.get_data('/tags/{}'.format(tag_id)) assert tag_data['message'] == 'No tag found' thread = api_client.get_data('/threads/{}'.format(thread_id)) assert 'foo' not in [tag['name'] for tag in thread['tags']] del_resp = api_client.delete('/tags/!' + tag_id) assert del_resp.status_code == 400 assert json.loads(del_resp.data)['message'].startswith('Invalid id') del_resp = api_client.delete('/tags/0000000000000000000000000') assert del_resp.status_code == 404 del_resp = api_client.delete('/tags/inbox') assert del_resp.status_code == 400 assert 'user-created' in json.loads(del_resp.data)['message']
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_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_api_get(contacts_provider, contact_sync, db, api_client, default_namespace): contacts_provider.supply_contact('Contact One', '*****@*****.**') contacts_provider.supply_contact('Contact Two', '*****@*****.**') contact_sync.provider = contacts_provider contact_sync.sync() ns_id = default_namespace.public_id contact_list = api_client.get_data('/contacts', ns_id) contact_ids = [contact['id'] for contact in contact_list] c1found = False c2found = False for c_id in contact_ids: contact = api_client.get_data('/contacts/' + c_id, ns_id) if contact['name'] == 'Contact One': c1found = True if contact['name'] == 'Contact Two': c2found = True assert c1found assert c2found
def test_get_invalid(api_client): bad_tag_id = '0000000000000000000000000' tag_data = api_client.get_data('/tags/{}'.format(bad_tag_id)) assert tag_data['message'] == 'No tag found' bad_tag_id = 'asdf!' tag_data = api_client.get_data('/tags/{}'.format(bad_tag_id)) assert 'is not a valid id' in tag_data['message']
def test_get_invalid(api_client): bad_tag_id = '0000000000000000000000000' tag_data = api_client.get_data('/tags/{}'.format(bad_tag_id)) assert tag_data['message'] == 'No tag found' bad_tag_id = 'asdf!' tag_data = api_client.get_data('/tags/{}'.format(bad_tag_id)) assert 'Invalid id' in tag_data['message']
def test_reject_incompatible_reply_thread_and_message(api_client): # TODO(emfree) set up this state instead of making assumptions about the # contents of the test dump. message = api_client.get_data("/messages")[0] thread = api_client.get_data("/threads")[-1] assert thread["id"] != message["thread_id"] reply_draft = {"subject": "test reply", "reply_to_message_id": message["id"], "thread_id": thread["id"]} r = api_client.post_data("/drafts", reply_draft) assert r.status_code == 400
def test_ordering(api_client, db): ordered_results = api_client.get_data('/messages') ordered_dates = [result['date'] for result in ordered_results] assert ordered_dates == sorted(ordered_dates, reverse=True) ordered_results = api_client.get_data('/messages?limit=3') expected_public_ids = [public_id for public_id, in db.session.query(Message.public_id). order_by(desc(Message.received_date)).limit(3)] assert expected_public_ids == [r['id'] for r in ordered_results]
def test_unread_cascades_to_messages(log, api_client, default_account, thread, message): thread_id = api_client.get_data('/threads/')[0]['id'] thread_path = '/threads/{}'.format(thread_id) api_client.put_data(thread_path, {'add_tags': ['unread']}) messages = api_client.get_data('/messages?thread_id={}'.format(thread_id)) assert all([msg['unread'] for msg in messages]) api_client.put_data(thread_path, {'remove_tags': ['unread']}) messages = api_client.get_data('/messages?thread_id={}'.format(thread_id)) assert not any([msg['unread'] for msg in messages])
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_unread_cascades_to_messages(patch_network_functions, log, api_client, syncback_service, default_account): thread_id = api_client.get_data('/threads/')[0]['id'] thread_path = '/threads/{}'.format(thread_id) api_client.put_data(thread_path, {'add_tags': ['unread']}) gevent.sleep(3) messages = api_client.get_data('/messages?thread_id={}'.format(thread_id)) assert all([msg['unread'] for msg in messages]) api_client.put_data(thread_path, {'remove_tags': ['unread']}) gevent.sleep(3) messages = api_client.get_data('/messages?thread_id={}'.format(thread_id)) assert not any([msg['unread'] for msg in messages])
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_reject_incompatible_reply_thread_and_message(api_client): # TODO(emfree) set up this state instead of making assumptions about the # contents of the test dump. message = api_client.get_data('/messages')[0] thread = api_client.get_data('/threads')[-1] assert thread['id'] != message['thread_id'] reply_draft = { 'subject': 'test reply', 'reply_to_message_id': message['id'], 'thread_id': thread['id'] } r = api_client.post_data('/drafts', reply_draft) assert r.status_code == 400
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 r = api_client.put_data('/tags/{}'.format(public_id), {'name': 'bar'}) assert json.loads(r.data)['name'] == 'bar' updated_tag_data = api_client.get_data('/tags/{}'.format(public_id)) assert updated_tag_data['name'] == 'bar' assert updated_tag_data['id'] == public_id
def test_distinct_results(api_client, db): """Test that limit and offset parameters work correctly when joining on multiple matching messages per thread.""" # Create a thread with multiple messages on it. first_thread = db.session.query(Thread).filter( Thread.namespace_id == NAMESPACE_ID).get(1) add_fake_message(db.session, NAMESPACE_ID, first_thread, from_addr=[('', '*****@*****.**')], received_date=datetime.datetime.utcnow()) add_fake_message(db.session, NAMESPACE_ID, first_thread, from_addr=[('', '*****@*****.**')], received_date=datetime.datetime.utcnow()) # Now create another thread with the same participants older_date = datetime.datetime.utcnow() - datetime.timedelta(hours=1) second_thread = db.session.query(Thread).filter( Thread.namespace_id == NAMESPACE_ID).get(2) add_fake_message(db.session, NAMESPACE_ID, second_thread, from_addr=[('', '*****@*****.**')], received_date=older_date) add_fake_message(db.session, NAMESPACE_ID, second_thread, from_addr=[('', '*****@*****.**')], received_date=older_date) filtered_results = api_client.get_data('/[email protected]' '&limit=1&offset=0') assert len(filtered_results) == 1 assert filtered_results[0]['id'] == first_thread.public_id filtered_results = api_client.get_data('/[email protected]' '&limit=1&offset=1') assert len(filtered_results) == 1 assert filtered_results[0]['id'] == second_thread.public_id filtered_results = api_client.get_data('/[email protected]' '&limit=2&offset=0') assert len(filtered_results) == 2 filtered_results = api_client.get_data('/[email protected]' '&limit=2&offset=1') assert len(filtered_results) == 1
def test_create_and_get_draft(api_client, example_draft): r = api_client.post_data('/drafts', example_draft) public_id = json.loads(r.data)['id'] assert r.status_code == 200 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 saved_draft['state'] == 'draft' 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
def test_get_invalid(api_client, uploaded_file_ids): data = api_client.get_data('/files/0000000000000000000000000') assert data['message'].startswith("Couldn't find file") data = api_client.get_data('/files/!') assert data['message'].startswith("Invalid id") data = api_client.get_data('/files/0000000000000000000000000/download') assert data['message'].startswith("Couldn't find file") data = api_client.get_data('/files/!/download') assert data['message'].startswith("Invalid id") r = api_client.delete('/files/0000000000000000000000000') assert r.status_code == 404 r = api_client.delete('/files/!') assert r.status_code == 400
def test_api_participant_reply_invalid_participant(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 event_id = e_resp_data['id'] url = '/events/{}?'.format(event_id) url += 'action=rsvp&participant_id={}&rsvp={}'.format('bad', 'yes') e_resp_data = api_client.get_data(url, ns_id) assert e_resp_data['type'] == 'invalid_request_error'