Example #1
0
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
Example #2
0
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')
Example #3
0
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()
Example #4
0
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')
Example #5
0
def test_send_rejected_with_wrong_version(api_client, example_draft):
    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,
        'version': 222
    })
    assert r.status_code == 409
Example #6
0
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
Example #7
0
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()
Example #8
0
def test_draft_not_persisted_if_sending_fails(recipients_refused, api_client,
                                              db):
    api_client.post_data('/send', {
        'to': [{
            'email': '*****@*****.**'
        }],
        'subject': 'some unique subject'
    })
    assert db.session.query(Message).filter_by(
        subject='some unique subject').first() is None
Example #9
0
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
Example #10
0
def test_sent_messages_shown_in_delta(patch_smtp, api_client, example_draft):
    ts = int(time.time())
    r = api_client.post_data('/delta/generate_cursor', {'start': ts})
    cursor = json.loads(r.data)['cursor']
    r = api_client.post_data('/send', example_draft)
    message_id = json.loads(r.data)['id']
    deltas = api_client.get_data('/delta?cursor={}'.format(cursor))['deltas']
    message_delta = next((d for d in deltas if d['id'] == message_id), None)
    assert message_delta is not None
    assert message_delta['object'] == 'message'
    assert message_delta['event'] == 'create'
Example #11
0
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 <*****@*****.**>'
Example #12
0
def test_sent_messages_shown_in_delta(patch_smtp, api_client, example_draft):
    ts = int(time.time())
    r = api_client.post_data('/delta/generate_cursor', {'start': ts})
    cursor = json.loads(r.data)['cursor']
    r = api_client.post_data('/send', example_draft)
    message_id = json.loads(r.data)['id']
    deltas = api_client.get_data('/delta?cursor={}'.format(cursor))['deltas']
    message_delta = next((d for d in deltas if d['id'] == message_id), None)
    assert message_delta is not None
    assert message_delta['object'] == 'message'
    assert message_delta['event'] == 'create'
Example #13
0
def test_reply_headers_set(db, patch_smtp, api_client, example_draft, thread,
                           message):
    message.message_id_header = '<*****@*****.**>'
    db.session.commit()
    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
Example #14
0
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)
Example #15
0
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)
Example #16
0
def test_delete_draft(api_client, thread, message):
    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 len(thread['draft_ids']) > 0
    api_client.delete('/drafts/{}'.format(public_id),
                      {'version': version})
    thread = api_client.get_data('/threads/{}'.format(thread_public_id))
    assert thread
    assert len(thread['draft_ids']) == 0
Example #17
0
def test_malformed_subject_rejected(api_client, example_draft_bad_subject):
    r = api_client.post_data('/send', example_draft_bad_subject)
    assert r.status_code == 400

    decoded = json.loads(r.get_data())
    assert decoded['type'] == 'invalid_request_error'
    assert decoded['message'] == '"subject" should be a string'
Example #18
0
def test_malformed_subject_rejected(api_client, example_draft_bad_subject):
    r = api_client.post_data('/send', example_draft_bad_subject)
    assert r.status_code == 400

    decoded = json.loads(r.get_data())
    assert decoded['type'] == 'invalid_request_error'
    assert decoded['message'] == '"subject" should be a string'
Example #19
0
def test_api_participant_reply_invalid_action(db, api_client, calendar):
    e_data = {
        'title':
        'Friday Office Party',
        'when': {
            'time': 1407542195
        },
        'calendar_id':
        calendar.public_id,
        'participants': [{
            'email': '*****@*****.**'
        }, {
            'email': '*****@*****.**'
        }, {
            'email': '*****@*****.**'
        }, {
            'email': '*****@*****.**'
        }, {
            'email': '*****@*****.**'
        }]
    }

    e_resp = api_client.post_data('/events', e_data)
    e_resp_data = json.loads(e_resp.data)
    assert len(e_resp_data['participants']) == 5
    assert e_resp_data['id']
Example #20
0
def test_api_create_multiple(db, api_client, calendar):
    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)
    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 test_api_create(db, api_client, calendar):
    e_data = {
        'title': 'Friday Office Party',
        'when': {'time': 1407542195},
        'calendar_id': calendar.public_id,
        'participants': [{
            'name': 'alyssa p. hacker',
            'email': '*****@*****.**'
        }]
    }

    e_resp = api_client.post_data('/events', e_data)
    e_resp_data = json.loads(e_resp.data)

    assert len(e_resp_data['participants']) == 1
    participant = e_resp_data['participants'][0]
    assert participant['name'] == e_data['participants'][0]['name']
    assert participant['email'] == e_data['participants'][0]['email']
    assert participant['status'] == 'noreply'

    e_resp_data = api_client.get_data('/events/' + e_resp_data['id'])

    assert len(e_resp_data['participants']) == 1
    participant = e_resp_data['participants'][0]
    assert participant['name'] == e_data['participants'][0]['name']
    assert participant['email'] == e_data['participants'][0]['email']
    assert participant['status'] == 'noreply'
def test_api_remove_participant(db, api_client, calendar):
    e_data = {
        'title': 'Friday Office Party',
        'when': {'time': 1407542195},
        'calendar_id': calendar.public_id,
        'participants': [{'email': '*****@*****.**'},
                         {'email': '*****@*****.**'},
                         {'email': '*****@*****.**'},
                         {'email': '*****@*****.**'},
                         {'email': '*****@*****.**'}]
    }

    e_resp = api_client.post_data('/events', e_data)
    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_resp_data['participants']
               if e['email'] == p['email']]
        assert len(res) == 1
        assert res[0]['name'] is None

    event_id = e_resp_data['id']
    e_data['participants'].pop()
    e_resp = api_client.put_data('/events/' + event_id, e_data)
    e_resp_data = json.loads(e_resp.data)
    assert len(e_resp_data['participants']) == 4
    for i, p in enumerate(e_resp_data['participants']):
        res = [e for e in e_resp_data['participants']
               if e['email'] == p['email']]
        assert len(res) == 1
        assert p['name'] is None
def test_api_create_multiple(db, api_client, calendar):
    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)
    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'
Example #24
0
def test_api_update_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_update_data = {'title': 'new title'}
    e_put_resp = api_client.put_data('/events/' + e_id, e_update_data)
    e_put_data = json.loads(e_put_resp.data)

    assert e_put_data['object'] == 'event'
    assert e_put_data['namespace_id'] == default_account.namespace.public_id
    assert e_put_data['id'] == e_id
    assert e_put_data['title'] == 'new title'
    assert e_put_data['when']['object'] == 'time'
    assert e_put_data['when']['time'] == e_data['when']['time']
Example #25
0
def test_attachment_has_same_id(api_client, uploaded_file_ids, draft):
    attachment_id = uploaded_file_ids.pop()
    draft['file_ids'] = [attachment_id]
    r = api_client.post_data('/drafts', draft)
    assert r.status_code == 200
    draft_resp = json.loads(r.data)
    assert attachment_id in [x['id'] for x in draft_resp['files']]
Example #26
0
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
Example #27
0
def test_api_update_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_update_data = {'title': 'new title'}
    e_put_resp = api_client.put_data('/events/' + e_id, e_update_data)
    e_put_data = json.loads(e_put_resp.data)

    assert e_put_data['object'] == 'event'
    assert e_put_data['namespace_id'] == default_account.namespace.public_id
    assert e_put_data['id'] == e_id
    assert e_put_data['title'] == 'new title'
    assert e_put_data['when']['object'] == 'time'
    assert e_put_data['when']['time'] == e_data['when']['time']
Example #28
0
def test_reply_headers_set(db, patch_smtp, api_client, example_draft, thread,
                           message):
    message.message_id_header = '<*****@*****.**>'
    db.session.commit()
    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
Example #29
0
def test_api_create(db, api_client, calendar):
    e_data = {
        'title':
        'Friday Office Party',
        'when': {
            'time': 1407542195
        },
        'calendar_id':
        calendar.public_id,
        'participants': [{
            'name': 'alyssa p. hacker',
            'email': '*****@*****.**'
        }]
    }

    e_resp = api_client.post_data('/events', e_data)
    e_resp_data = json.loads(e_resp.data)

    assert len(e_resp_data['participants']) == 1
    participant = e_resp_data['participants'][0]
    assert participant['name'] == e_data['participants'][0]['name']
    assert participant['email'] == e_data['participants'][0]['email']
    assert participant['status'] == 'noreply'

    e_resp_data = api_client.get_data('/events/' + e_resp_data['id'])

    assert len(e_resp_data['participants']) == 1
    participant = e_resp_data['participants'][0]
    assert participant['name'] == e_data['participants'][0]['name']
    assert participant['email'] == e_data['participants'][0]['email']
    assert participant['status'] == 'noreply'
Example #30
0
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']
    version = json.loads(r.data)['version']

    updated_draft = {
        'subject': 'updated draft',
        'body': 'updated draft',
        'version': version
    }
    r = api_client.put_data('/drafts/{}'.format(original_public_id),
                            updated_draft)
    assert r.status_code == 200
    updated_public_id = json.loads(r.data)['id']
    updated_version = json.loads(r.data)['version']
    assert updated_version != version

    conflicting_draft = {
        'subject': 'conflicting draft',
        'body': 'conflicting draft',
        'version': version
    }
    r = api_client.put_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
Example #31
0
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']
Example #32
0
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']
    version = json.loads(r.data)['version']

    updated_draft = {
        'subject': 'updated draft',
        'body': 'updated draft',
        'version': version
    }
    r = api_client.put_data('/drafts/{}'.format(original_public_id),
                            updated_draft)
    assert r.status_code == 200
    updated_public_id = json.loads(r.data)['id']
    updated_version = json.loads(r.data)['version']
    assert updated_version != version

    conflicting_draft = {
        'subject': 'conflicting draft',
        'body': 'conflicting draft',
        'version': version
    }
    r = api_client.put_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
Example #33
0
def test_api_create(db, api_client, calendar, default_account):
    e_data = {
        'title': 'Friday Office Party',
        'calendar_id': calendar.public_id,
        'when': {
            'time': 1407542195
        },
        'location': 'Inbox HQ',
    }

    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['location'] == e_data['location']
    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']
Example #34
0
def test_delete_draft(api_client, thread, message):
    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 len(thread['draft_ids']) > 0
    api_client.delete('/drafts/{}'.format(public_id), {'version': version})
    thread = api_client.get_data('/threads/{}'.format(thread_public_id))
    assert thread
    assert len(thread['draft_ids']) == 0
Example #35
0
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 <*****@*****.**>'
Example #36
0
def test_create_draft_with_attachments(api_client, attachments, example_draft):
    attachment_ids = []
    upload_path = api_client.full_path('/files')
    for filename, path in attachments:
        data = {'file': (open(path, 'rb'), filename)}
        r = api_client.client.post(upload_path, data=data)
        assert r.status_code == 200
        attachment_id = json.loads(r.data)[0]['id']
        attachment_ids.append(attachment_id)

    first_attachment = attachment_ids.pop()

    example_draft['file_ids'] = [first_attachment]
    r = api_client.post_data('/drafts', example_draft)
    assert r.status_code == 200
    returned_draft = json.loads(r.data)
    draft_public_id = returned_draft['id']
    assert returned_draft['version'] == 0
    example_draft['version'] = returned_draft['version']
    assert len(returned_draft['files']) == 1

    attachment_ids.append(first_attachment)
    example_draft['file_ids'] = attachment_ids
    r = api_client.put_data('/drafts/{}'.format(draft_public_id),
                            example_draft)
    assert r.status_code == 200
    returned_draft = json.loads(r.data)
    assert len(returned_draft['files']) == 3
    assert returned_draft['version'] == 1
    example_draft['version'] = returned_draft['version']

    # Make sure we can't delete the files now
    for file_id in attachment_ids:
        r = api_client.delete('/files/{}'.format(file_id))
        assert r.status_code == 400

    # Now remove the attachment
    example_draft['file_ids'] = [first_attachment]
    r = api_client.put_data('/drafts/{}'.format(draft_public_id),
                            example_draft)

    draft_data = api_client.get_data('/drafts/{}'.format(draft_public_id))
    assert len(draft_data['files']) == 1
    assert draft_data['version'] == 2
    example_draft['version'] = draft_data['version']

    example_draft['file_ids'] = []
    r = api_client.put_data('/drafts/{}'.format(draft_public_id),
                            example_draft)
    draft_data = api_client.get_data('/drafts/{}'.format(draft_public_id))
    assert r.status_code == 200
    assert len(draft_data['files']) == 0
    assert draft_data['version'] == 3

    # now that they're not attached, we should be able to delete them
    for file_id in attachment_ids:
        r = api_client.delete('/files/{}'.format(file_id))
        assert r.status_code == 200
Example #37
0
def test_create_draft_with_attachments(api_client, attachments, example_draft):
    attachment_ids = []
    upload_path = api_client.full_path('/files')
    for filename, path in attachments:
        data = {'file': (open(path, 'rb'), filename)}
        r = api_client.client.post(upload_path, data=data)
        assert r.status_code == 200
        attachment_id = json.loads(r.data)[0]['id']
        attachment_ids.append(attachment_id)

    first_attachment = attachment_ids.pop()

    example_draft['file_ids'] = [first_attachment]
    r = api_client.post_data('/drafts', example_draft)
    assert r.status_code == 200
    returned_draft = json.loads(r.data)
    draft_public_id = returned_draft['id']
    assert returned_draft['version'] == 0
    example_draft['version'] = returned_draft['version']
    assert len(returned_draft['files']) == 1

    attachment_ids.append(first_attachment)
    example_draft['file_ids'] = attachment_ids
    r = api_client.put_data('/drafts/{}'.format(draft_public_id),
                            example_draft)
    assert r.status_code == 200
    returned_draft = json.loads(r.data)
    assert len(returned_draft['files']) == 3
    assert returned_draft['version'] == 1
    example_draft['version'] = returned_draft['version']

    # Make sure we can't delete the files now
    for file_id in attachment_ids:
        r = api_client.delete('/files/{}'.format(file_id))
        assert r.status_code == 400

    # Now remove the attachment
    example_draft['file_ids'] = [first_attachment]
    r = api_client.put_data('/drafts/{}'.format(draft_public_id),
                            example_draft)

    draft_data = api_client.get_data('/drafts/{}'.format(draft_public_id))
    assert len(draft_data['files']) == 1
    assert draft_data['version'] == 2
    example_draft['version'] = draft_data['version']

    example_draft['file_ids'] = []
    r = api_client.put_data('/drafts/{}'.format(draft_public_id),
                            example_draft)
    draft_data = api_client.get_data('/drafts/{}'.format(draft_public_id))
    assert r.status_code == 200
    assert len(draft_data['files']) == 0
    assert draft_data['version'] == 3

    # now that they're not attached, we should be able to delete them
    for file_id in attachment_ids:
        r = api_client.delete('/files/{}'.format(file_id))
        assert r.status_code == 200
Example #38
0
def test_body_construction(patch_smtp, api_client):
    api_client.post_data('/send',
                         {'to': [{'email': '*****@*****.**'}],
                          'subject': 'Banalities',
                          'body': '<html>Hello there</html>'})
    _, msg = patch_smtp[-1]
    parsed = mime.from_string(msg)
    assert len(parsed.parts) == 2
    plain_part_found = False
    html_part_found = False
    for part in parsed.parts:
        if part.content_type.value == 'text/plain':
            plain_part_found = True
            assert part.body.strip() == 'Hello there'
        elif part.content_type.value == 'text/html':
            html_part_found = True
            assert part.body.strip() == '<html>Hello there</html>'
    assert plain_part_found and html_part_found
Example #39
0
def test_account_validation(api_client, db, default_namespace):

    draft = {
        'body': '<html><body><h2>Sea, birds and sand.</h2></body></html>'
    }

    r = api_client.post_data('/drafts', draft)
    assert r.status_code == 200

    namespace_id = json.loads(r.data)['namespace_id']
    account = db.session.query(Namespace).filter(
        Namespace.public_id == namespace_id).first().account

    account.sync_state = 'invalid'
    db.session.commit()

    r = api_client.post_data('/drafts', draft)
    assert r.status_code == 403
Example #40
0
def test_smtp_ssl_verification_bad_cert_legacy(db, bad_cert_smtp_server,
                                               example_draft,
                                               local_smtp_account,
                                               api_legacy_client):

    error_msg = 'SMTP server SSL certificate verify failed'

    ns_public_id = local_smtp_account.namespace.public_id
    r = api_legacy_client.post_data('/send', example_draft, ns_public_id)
    assert r.status_code == 503
    assert json.loads(r.data)['message'] == error_msg
Example #41
0
def test_create_draft_replying_to_message(api_client, message):
    message = api_client.get_data('/messages')[0]
    reply_draft = {
        'subject': 'test reply',
        'body': 'test reply',
        'reply_to_message_id': message['id']
    }
    r = api_client.post_data('/drafts', reply_draft)
    data = json.loads(r.data)
    assert data['reply_to_message_id'] == message['id']
    assert data['thread_id'] == message['thread_id']
Example #42
0
def test_create_draft_replying_to_message(api_client, message):
    message = api_client.get_data('/messages')[0]
    reply_draft = {
        'subject': 'test reply',
        'body': 'test reply',
        'reply_to_message_id': message['id']
    }
    r = api_client.post_data('/drafts', reply_draft)
    data = json.loads(r.data)
    assert data['reply_to_message_id'] == message['id']
    assert data['thread_id'] == message['thread_id']
Example #43
0
def test_smtp_ssl_verification_bad_cert_legacy(db, bad_cert_smtp_server,
                                               example_draft,
                                               local_smtp_account,
                                               api_legacy_client):

    error_msg = 'SMTP server SSL certificate verify failed'

    ns_public_id = local_smtp_account.namespace.public_id
    r = api_legacy_client.post_data('/send', example_draft, ns_public_id)
    assert r.status_code == 503
    assert json.loads(r.data)['message'] == error_msg
Example #44
0
def test_sending_from_email_multiple_aliases(patch_smtp, patch_token_manager,
                                             api_client):
    res = api_client.post_data('/send',
                               {'to': [{'email': '*****@*****.**'}],
                                'from': [{'name': 'admin',
                                          'email': '*****@*****.**'},
                                         {'name': 'the rock',
                                          'email': '*****@*****.**'}],
                                'subject': 'Banalities',
                                'body': '<html>Hello there</html>'})
    assert res.status_code == 400

    res = api_client.post_data('/send',
                               {'to': [{'email': '*****@*****.**'}],
                                'reply_to': [{'name': 'admin',
                                              'email': '*****@*****.**'},
                                             {'name': 'the rock',
                                              'email': '*****@*****.**'}],
                                'subject': 'Banalities',
                                'body': '<html>Hello there</html>'})
    assert res.status_code == 400
Example #45
0
def test_drafts_filter(api_client, example_draft):
    r = api_client.post_data('/drafts', example_draft)
    thread_id = json.loads(r.data)['thread_id']

    reply_draft = {
        'subject': 'test reply',
        'body': 'test reply',
        'thread_id': thread_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_id))
    assert len(results) == 2

    results = api_client.get_data('/drafts?offset={}&thread_id={}'.format(
        1, thread_id))
    assert len(results) == 1
Example #46
0
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')
    assert not drafts

    message = api_client.get_data('/messages/{}'.format(draft_public_id))
    assert message['object'] == 'message'
Example #47
0
def test_body_construction(patch_smtp, api_client):
    api_client.post_data(
        '/send', {
            'to': [{
                'email': '*****@*****.**'
            }],
            'subject': 'Banalities',
            'body': '<html>Hello there</html>'
        })
    _, msg = patch_smtp[-1]
    parsed = mime.from_string(msg)
    assert len(parsed.parts) == 2
    plain_part_found = False
    html_part_found = False
    for part in parsed.parts:
        if part.content_type.value == 'text/plain':
            plain_part_found = True
            assert part.body.strip() == 'Hello there'
        elif part.content_type.value == 'text/html':
            html_part_found = True
            assert part.body.strip() == '<html>Hello there</html>'
    assert plain_part_found and html_part_found
Example #48
0
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()
Example #49
0
def test_sending_from_email_multiple_aliases(patch_smtp, patch_token_manager,
                                             api_client):
    res = api_client.post_data(
        '/send', {
            'to': [{
                'email': '*****@*****.**'
            }],
            'from': [{
                'name': 'admin',
                'email': '*****@*****.**'
            }, {
                'name': 'the rock',
                'email': '*****@*****.**'
            }],
            'subject':
            'Banalities',
            'body':
            '<html>Hello there</html>'
        })
    assert res.status_code == 400

    res = api_client.post_data(
        '/send', {
            'to': [{
                'email': '*****@*****.**'
            }],
            'reply_to': [{
                'name': 'admin',
                'email': '*****@*****.**'
            }, {
                'name': 'the rock',
                'email': '*****@*****.**'
            }],
            'subject':
            'Banalities',
            'body':
            '<html>Hello there</html>'
        })
    assert res.status_code == 400
Example #50
0
def test_drafts_filter(api_client, example_draft):
    r = api_client.post_data('/drafts', example_draft)
    thread_id = json.loads(r.data)['thread_id']

    reply_draft = {
        'subject': 'test reply',
        'body': 'test reply',
        'thread_id': thread_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_id))
    assert len(results) == 2

    results = api_client.get_data('/drafts?offset={}&thread_id={}'
                                  .format(1, thread_id))
    assert len(results) == 1
Example #51
0
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())
Example #52
0
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')
    assert not drafts

    message = api_client.get_data('/messages/{}'.format(draft_public_id))
    assert message['object'] == 'message'
Example #53
0
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())
def test_api_create_no_email(db, api_client, calendar):
    e_data = {
        'title': 'Friday Office Party',
        'when': {'time': 1407542195},
        'calendar_id': calendar.public_id,
        'participants': [{
            'name': 'alyssa p. hacker',
        }]
    }

    e_resp = api_client.post_data('/events', e_data)
    e_resp_data = json.loads(e_resp.data)

    assert e_resp_data["type"] == "invalid_request_error"
Example #55
0
def test_add_to_read_only_calendar(db, api_client):
    cal_list = api_client.get_data('/calendars')
    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)
    assert resp.status_code == 400
Example #56
0
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
Example #57
0
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()
Example #58
0
def test_rsvp_updates_status(patch_smtp, api_client, example_rsvp,
                             imported_event):
    assert len(imported_event.participants) == 1
    assert imported_event.participants[0]['email'] == '*****@*****.**'
    assert imported_event.participants[0]['status'] == 'noreply'

    r = api_client.post_data('/send-rsvp', example_rsvp)
    assert r.status_code == 200
    dct = json.loads(r.data)

    # Check that the event's status got updated
    assert len(dct['participants']) == 1
    assert dct['participants'][0]['email'] == '*****@*****.**'
    assert dct['participants'][0]['status'] == 'yes'
    assert dct['participants'][0]['comment'] == 'I will come.'
def test_api_participant_reply_invalid_event2(db, api_client, calendar):
    e_data = {
        'title': 'Friday Office Party',
        'when': {'time': 1407542195},
        'calendar_id': calendar.public_id,
        'participants': [{'email': '*****@*****.**'},
                         {'email': '*****@*****.**'},
                         {'email': '*****@*****.**'},
                         {'email': '*****@*****.**'},
                         {'email': '*****@*****.**'}]
    }

    e_resp = api_client.post_data('/events', e_data)
    e_resp_data = json.loads(e_resp.data)
    assert len(e_resp_data['participants']) == 5