Ejemplo n.º 1
0
def test_thread_received_recent_date(db, api_client, default_account):
    date1 = datetime.datetime(2015, 1, 1, 0, 0, 0)
    date2 = datetime.datetime(2012, 1, 1, 0, 0, 0)

    thread1 = add_fake_thread(db.session, default_account.namespace.id)

    date_dict = dict()

    add_fake_message(db.session, default_account.namespace.id, thread1,
                     subject="Test Thread 1", received_date=date1,
                     add_sent_category=True)
    add_fake_message(db.session, default_account.namespace.id, thread1,
                     subject="Test Thread 1", received_date=date2)

    date_dict["Test Thread 1"] = date2

    thread2 = add_fake_thread(db.session, default_account.namespace.id)
    add_fake_message(db.session, default_account.namespace.id, thread2,
                     subject="Test Thread 2", received_date=date1,
                     add_sent_category=True)

    date_dict["Test Thread 2"] = date1

    resp = api_client.get_raw('/threads/')
    assert resp.status_code == 200
    threads = json.loads(resp.data)

    for thread in threads:
        assert date_dict[thread['subject']] == \
            datetime.datetime.fromtimestamp(
                thread['last_message_received_timestamp'])
Ejemplo n.º 2
0
def test_namespace_deletion(db, default_account):
    from inbox.models import Account, Thread, Message
    from inbox.models.util import delete_namespace

    models = [Thread, Message]

    namespace = default_account.namespace
    namespace_id = namespace.id
    account_id = default_account.id

    account = db.session.query(Account).get(account_id)
    assert account

    thread = add_fake_thread(db.session, namespace_id)

    message = add_fake_message(db.session, namespace_id, thread)

    for m in models:
        c = db.session.query(m).filter(m.namespace_id == namespace_id).count()
        print "count for", m, ":", c
        assert c != 0

    fake_account = add_generic_imap_account(db.session)
    fake_account_id = fake_account.id

    assert fake_account_id != account.id and \
        fake_account.namespace.id != namespace_id

    thread = add_fake_thread(db.session, fake_account.namespace.id)
    thread_id = thread.id

    message = add_fake_message(db.session, fake_account.namespace.id, thread)
    message_id = message.id

    assert len(
        db.session.query(Namespace).filter(
            Namespace.id == namespace_id).all()) > 0

    # Delete namespace, verify data corresponding to this namespace /only/
    # is deleted
    delete_namespace(account_id, namespace_id)
    db.session.commit()

    assert len(
        db.session.query(Namespace).filter(
            Namespace.id == namespace_id).all()) == 0

    account = db.session.query(Account).get(account_id)
    assert not account

    for m in models:
        assert db.session.query(m).filter(
            m.namespace_id == namespace_id).count() == 0

    fake_account = db.session.query(Account).get(fake_account_id)
    assert fake_account

    thread = db.session.query(Thread).get(thread_id)
    message = db.session.query(Message).get(message_id)
    assert thread and message
Ejemplo n.º 3
0
def test_generic_grouping(db, default_account):
    thread = add_fake_thread(db.session, default_account.namespace.id)
    message = add_fake_message(db.session,
                               default_account.namespace.id,
                               thread,
                               subject="Golden Gate Park next Sat")
    folder = Folder(account=default_account,
                    name='Inbox',
                    canonical_name='inbox')
    ImapUid(message=message,
            account_id=default_account.id,
            msg_uid=2222,
            folder=folder)

    thread = add_fake_thread(db.session, default_account.namespace.id)

    account = add_generic_imap_account(db.session)
    message = add_fake_message(db.session,
                               account.namespace.id,
                               thread,
                               subject="Golden Gate Park next Sat")

    thread = fetch_corresponding_thread(db.session,
                                        default_account.namespace.id, message)
    assert thread is None, ("fetch_similar_threads should "
                            "heed namespace boundaries")
Ejemplo n.º 4
0
def test_thread_count(db, api_client, default_account):
    date1 = datetime.datetime(2015, 1, 1, 0, 0, 0)
    date2 = datetime.datetime(2012, 1, 1, 0, 0, 0)
    date3 = datetime.datetime(2010, 1, 1, 0, 0, 0)
    date4 = datetime.datetime(2009, 1, 1, 0, 0, 0)
    date5 = datetime.datetime(2008, 1, 1, 0, 0, 0)

    thread1 = add_fake_thread(db.session, default_account.namespace.id)
    thread2 = add_fake_thread(db.session, default_account.namespace.id)

    test_subject = "test_thread_view_count_with_category"

    for thread in [thread1, thread2]:
        add_fake_message(db.session, default_account.namespace.id, thread,
                         subject=test_subject, received_date=date1)
        add_fake_message(db.session, default_account.namespace.id, thread,
                         subject=test_subject, received_date=date2,
                         add_sent_category=True)
        add_fake_message(db.session, default_account.namespace.id, thread,
                         subject=test_subject, received_date=date3)
        add_fake_message(db.session, default_account.namespace.id, thread,
                         subject=test_subject, received_date=date4,
                         add_sent_category=True)
        add_fake_message(db.session, default_account.namespace.id, thread,
                         subject=test_subject, received_date=date5)

    resp = api_client.get_raw('/threads/?view=count&in=sent')
    assert resp.status_code == 200
    threads = json.loads(resp.data)
    assert threads['count'] == 2
Ejemplo n.º 5
0
def test_namespace_deletion(db, default_account):
    from inbox.models import Account, Thread, Message
    from inbox.models.util import delete_namespace

    models = [Thread, Message]

    namespace = default_account.namespace
    namespace_id = namespace.id
    account_id = default_account.id

    account = db.session.query(Account).get(account_id)
    assert account

    thread = add_fake_thread(db.session, namespace_id)

    message = add_fake_message(db.session, namespace_id, thread)

    for m in models:
        c = db.session.query(m).filter(
            m.namespace_id == namespace_id).count()
        print "count for", m, ":", c
        assert c != 0

    fake_account = add_generic_imap_account(db.session)
    fake_account_id = fake_account.id

    assert fake_account_id != account.id and \
        fake_account.namespace.id != namespace_id

    thread = add_fake_thread(db.session, fake_account.namespace.id)
    thread_id = thread.id

    message = add_fake_message(db.session, fake_account.namespace.id, thread)
    message_id = message.id

    assert len(db.session.query(Namespace).filter(Namespace.id == namespace_id).all()) > 0

    # Delete namespace, verify data corresponding to this namespace /only/
    # is deleted
    delete_namespace(account_id, namespace_id)
    db.session.commit()

    assert len(db.session.query(Namespace).filter(Namespace.id == namespace_id).all()) == 0

    account = db.session.query(Account).get(account_id)
    assert not account

    for m in models:
        assert db.session.query(m).filter(
            m.namespace_id == namespace_id).count() == 0

    fake_account = db.session.query(Account).get(fake_account_id)
    assert fake_account

    thread = db.session.query(Thread).get(thread_id)
    message = db.session.query(Message).get(message_id)
    assert thread and message
Ejemplo n.º 6
0
def test_distinct_results(api_client, db, default_namespace):
    """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 = add_fake_thread(db.session, default_namespace.id)
    add_fake_message(db.session, default_namespace.id, first_thread,
                     from_addr=[('', '*****@*****.**')],
                     received_date=datetime.datetime.utcnow(),
                     add_sent_category=True)
    add_fake_message(db.session, default_namespace.id, first_thread,
                     from_addr=[('', '*****@*****.**')],
                     received_date=datetime.datetime.utcnow(),
                     add_sent_category=True)

    # Now create another thread with the same participants
    older_date = datetime.datetime.utcnow() - datetime.timedelta(hours=1)
    second_thread = add_fake_thread(db.session, default_namespace.id)
    add_fake_message(db.session, default_namespace.id, second_thread,
                     from_addr=[('', '*****@*****.**')],
                     received_date=older_date,
                     add_sent_category=True)
    add_fake_message(db.session, default_namespace.id, second_thread,
                     from_addr=[('', '*****@*****.**')],
                     received_date=older_date,
                     add_sent_category=True)

    second_thread.recentdate = older_date
    db.session.commit()

    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

    # Ensure that it works when using the _in filter
    filtered_results = api_client.get_data('/threads?in=sent'
                                           '&limit=2&offset=0')
    assert len(filtered_results) == 2

    filtered_results = api_client.get_data('/threads?in=sent'
                                           '&limit=1&offset=0')
    assert len(filtered_results) == 1
Ejemplo n.º 7
0
def test_file_transactions(db, default_namespace):
    from inbox.models.message import Message

    account = default_namespace.account
    thread = add_fake_thread(db.session, default_namespace.id)
    mime_msg = mime.create.multipart("mixed")
    mime_msg.append(
        mime.create.text("plain", "This is a message with attachments"),
        mime.create.attachment("image/png", "filler", "attached_image.png", "attachment"),
        mime.create.attachment("application/pdf", "filler", "attached_file.pdf", "attachment"),
    )
    msg = Message.create_from_synced(account, 22, "[Gmail]/All Mail", datetime.utcnow(), mime_msg.to_string())
    msg.thread = thread
    db.session.add(msg)
    db.session.commit()

    assert len(msg.parts) == 2
    assert all(part.content_disposition == "attachment" for part in msg.parts)

    block_ids = [part.block.id for part in msg.parts]

    with db.session.no_autoflush:
        transaction = get_latest_transaction(db.session, "file", block_ids[0], default_namespace.id)
        assert transaction.command == "insert"

        transaction = get_latest_transaction(db.session, "file", block_ids[1], default_namespace.id)
        assert transaction.command == "insert"
Ejemplo n.º 8
0
def test_message_updates_create_thread_transaction(db, default_namespace):
    with db.session.no_autoflush:
        thr = add_fake_thread(db.session, default_namespace.id)
        msg = add_fake_message(db.session, default_namespace.id, thr)

        transaction = get_latest_transaction(db.session, "thread", thr.id, default_namespace.id)
        assert transaction.record_id == thr.id and transaction.object_type == "thread"
        assert transaction.command == "update"

        # An update to one of the message's propagated_attributes creates a
        # revision for the thread
        msg.is_read = True
        db.session.commit()

        new_transaction = get_latest_transaction(db.session, "thread", thr.id, default_namespace.id)
        assert new_transaction.id != transaction.id
        assert new_transaction.record_id == thr.id and new_transaction.object_type == "thread"
        assert new_transaction.command == "update"

        # An update to one of its other attributes does not
        msg.subject = "Ice cubes and dogs"
        db.session.commit()

        same_transaction = get_latest_transaction(db.session, "thread", thr.id, default_namespace.id)
        assert same_transaction.id == new_transaction.id
Ejemplo n.º 9
0
def test_basic_message_grouping(db, default_namespace):
    first_thread = add_fake_thread(db.session, default_namespace.id)
    first_thread.subject = 'Some kind of test'

    add_fake_message(db.session, default_namespace.id,
                     thread=first_thread,
                     subject='Some kind of test',
                     from_addr=[('Karim Hamidou', '*****@*****.**')],
                     to_addr=[('Eben Freeman', '*****@*****.**')],
                     bcc_addr=[('Some person', '*****@*****.**')])

    msg2 = add_fake_message(db.session, default_namespace.id, thread=None,
                            subject='Re: Some kind of test',
                            from_addr=[('Some random dude',
                                        '*****@*****.**')],
                            to_addr=[('Karim Hamidou', '*****@*****.**')])

    matched_thread = fetch_corresponding_thread(db.session,
                                                default_namespace.id, msg2)
    assert matched_thread is None, "the algo shouldn't thread different convos"

    msg3 = add_fake_message(db.session, default_namespace.id, thread=None)
    msg3.subject = 'Re: Some kind of test'
    msg3.from_addr = [('Eben Freeman', '*****@*****.**')]
    msg3.to_addr = [('Karim Hamidou', '*****@*****.**')]

    matched_thread = fetch_corresponding_thread(db.session, default_namespace.id, msg3)
    assert matched_thread is first_thread, "Should match on participants"
Ejemplo n.º 10
0
def test_basic_message_grouping(db, default_namespace):
    first_thread = add_fake_thread(db.session, default_namespace.id)
    first_thread.subject = 'Some kind of test'

    add_fake_message(db.session,
                     default_namespace.id,
                     thread=first_thread,
                     subject='Some kind of test',
                     from_addr=[('Karim Hamidou', '*****@*****.**')],
                     to_addr=[('Eben Freeman', '*****@*****.**')],
                     bcc_addr=[('Some person', '*****@*****.**')])

    msg2 = add_fake_message(db.session,
                            default_namespace.id,
                            thread=None,
                            subject='Re: Some kind of test',
                            from_addr=[('Some random dude', '*****@*****.**')
                                       ],
                            to_addr=[('Karim Hamidou', '*****@*****.**')])

    matched_thread = fetch_corresponding_thread(db.session,
                                                default_namespace.id, msg2)
    assert matched_thread is None, "the algo shouldn't thread different convos"

    msg3 = add_fake_message(db.session, default_namespace.id, thread=None)
    msg3.subject = 'Re: Some kind of test'
    msg3.from_addr = [('Eben Freeman', '*****@*****.**')]
    msg3.to_addr = [('Karim Hamidou', '*****@*****.**')]

    matched_thread = fetch_corresponding_thread(db.session,
                                                default_namespace.id, msg3)
    assert matched_thread is first_thread, "Should match on participants"
Ejemplo n.º 11
0
def test_folder_delete(db, generic_account, folder_client, api_version):
    headers = dict()
    headers['Api-Version'] = api_version

    # Make a new message
    generic_thread = add_fake_thread(db.session, generic_account.namespace.id)
    gen_message = add_fake_message(db.session, generic_account.namespace.id,
                                   generic_thread)
    g_data = folder_client.get_raw('/folders/')
    # Add message to folder
    generic_folder = json.loads(g_data.data)[0]
    data = {"folder_id": generic_folder['id']}
    folder_client.put_data('/messages/{}'.format(gen_message.public_id), data)

    # Test that DELETE requests 403 on folders with items in them
    d_data = folder_client.delete('/folders/{}'.format(generic_folder['id']))
    assert d_data.status_code == 400

    # Make an empty folder
    resp = folder_client.post_data('/folders/',
                                   {"display_name": "Empty_Folder"})
    empty_folder = json.loads(resp.data)
    # Test that DELETE requests delete empty folders
    d_data = folder_client.delete('/folders/{}'.format(empty_folder['id']))
    assert d_data.status_code == 200

    if api_version == API_VERSIONS[0]:
        # Did we update things optimistically?
        category_id = empty_folder['id']
        category = db.session.query(Category).filter(
            Category.public_id == category_id).one()
        assert category.deleted_at != EPOCH
        assert category.is_deleted is True

    db.session.rollback()
Ejemplo n.º 12
0
def test_label_delete(db, gmail_account, label_client, api_version):
    headers = dict()
    headers['Api-Version'] = api_version

    # Make a new message
    gmail_thread = add_fake_thread(db.session, gmail_account.namespace.id)
    gmail_message = add_fake_message(db.session, gmail_account.namespace.id,
                                     gmail_thread)
    g_data = label_client.get_raw('/labels/', headers=headers)
    # Add label to message
    gmail_label = json.loads(g_data.data)[0]
    data = {"labels": [gmail_label['id']]}
    label_client.put_data('/messages/{}'.format(gmail_message.public_id),
                          data,
                          headers=headers)

    # DELETE requests should work on labels whether or not messages have them
    d_data = label_client.delete('/labels/{}'.format(gmail_label['id']),
                                 headers=headers)
    assert d_data.status_code == 200

    if api_version == API_VERSIONS[0]:
        # Optimistic update.
        category_id = gmail_label['id']
        category = db.session.query(Category).filter(
            Category.public_id == category_id).one()
        assert category.deleted_at != EPOCH
        assert category.is_deleted is True
Ejemplo n.º 13
0
def test_label_delete(db, gmail_account, label_client, api_version):
    headers = dict()
    headers['Api-Version'] = api_version

    # Make a new message
    gmail_thread = add_fake_thread(db.session, gmail_account.namespace.id)
    gmail_message = add_fake_message(db.session,
                                     gmail_account.namespace.id, gmail_thread)
    g_data = label_client.get_raw('/labels/', headers=headers)
    # Add label to message
    gmail_label = json.loads(g_data.data)[0]
    data = {"labels": [gmail_label['id']]}
    label_client.put_data('/messages/{}'.format(gmail_message.public_id), data,
                          headers=headers)

    # DELETE requests should work on labels whether or not messages have them
    d_data = label_client.delete('/labels/{}'.format(gmail_label['id']),
                                 headers=headers)
    assert d_data.status_code == 200

    if api_version == API_VERSIONS[0]:
        # Optimistic update.
        category_id = gmail_label['id']
        category = db.session.query(Category).filter(
            Category.public_id == category_id).one()
        assert category.deleted_at != EPOCH
        assert category.is_deleted is True
Ejemplo n.º 14
0
def test_category_delete(db, gmail_account):
    """ Ensure that all associated MessageCategories are deleted
        when a Category is deleted """

    api_client = new_api_client(db, gmail_account.namespace)
    po_data = api_client.post_data('/labels/', {"display_name": "Test_Label"})
    assert po_data.status_code == 200

    category_public_id = json.loads(po_data.data)['id']
    category = db.session.query(Category).filter(
        Category.public_id == category_public_id).one()
    category_id = category.id

    for i in xrange(10):
        generic_thread = add_fake_thread(db.session,
                                         gmail_account.namespace.id)
        gen_message = add_fake_message(db.session, gmail_account.namespace.id,
                                       generic_thread)
        data = {"label_ids": [category_public_id]}
        resp = api_client.put_data(
            '/messages/{}'.format(gen_message.public_id), data)
        assert resp.status_code == 200

    associated_mcs = db.session.query(MessageCategory). \
        filter(MessageCategory.category_id == category_id).all()
    assert len(associated_mcs) == 10

    db.session.delete(category)
    db.session.commit()

    assert db.session.query(MessageCategory). \
        filter(MessageCategory.category_id == category_id).all() == []
Ejemplo n.º 15
0
def test_category_delete(db, gmail_account):
    """ Ensure that all associated MessageCategories are deleted
        when a Category is deleted """

    api_client = new_api_client(db, gmail_account.namespace)
    po_data = api_client.post_data('/labels/',
                                   {"display_name": "Test_Label"})
    assert po_data.status_code == 200

    category_public_id = json.loads(po_data.data)['id']
    category = db.session.query(Category).filter(
        Category.public_id == category_public_id).one()
    category_id = category.id

    for i in xrange(10):
        generic_thread = add_fake_thread(db.session,
                                         gmail_account.namespace.id)
        gen_message = add_fake_message(db.session,
                                       gmail_account.namespace.id,
                                       generic_thread)
        data = {"label_ids": [category_public_id]}
        resp = api_client.put_data('/messages/{}'.
                                   format(gen_message.public_id), data)
        assert resp.status_code == 200

    associated_mcs = db.session.query(MessageCategory). \
        filter(MessageCategory.category_id == category_id).all()
    assert len(associated_mcs) == 10

    db.session.delete(category)
    db.session.commit()

    assert db.session.query(MessageCategory). \
        filter(MessageCategory.category_id == category_id).all() == []
Ejemplo n.º 16
0
def test_message_delete(db, gmail_account):
    """ Ensure that all associated MessageCategories are deleted
        when a Message is deleted """

    api_client = new_api_client(db, gmail_account.namespace)

    generic_thread = add_fake_thread(db.session, gmail_account.namespace.id)
    gen_message = add_fake_message(db.session,
                                   gmail_account.namespace.id,
                                   generic_thread)

    category_ids = []
    for i in xrange(10):
        po_data = api_client.post_data('/labels/',
                                       {"display_name": str(i)})
        assert po_data.status_code == 200

        category_ids.append(json.loads(po_data.data)['id'])

    data = {"label_ids": category_ids}
    resp = api_client.put_data('/messages/{}'.
                               format(gen_message.public_id), data)
    assert resp.status_code == 200

    associated_mcs = db.session.query(MessageCategory). \
        filter(MessageCategory.message_id == gen_message.id).all()
    assert len(associated_mcs) == 10

    db.session.delete(gen_message)
    db.session.commit()

    assert db.session.query(MessageCategory). \
        filter(MessageCategory.message_id == gen_message.id).all() == []
Ejemplo n.º 17
0
def test_file_transactions(db, default_namespace):
    from inbox.models.message import Message

    account = default_namespace.account
    thread = add_fake_thread(db.session, default_namespace.id)
    mime_msg = mime.create.multipart('mixed')
    mime_msg.append(
        mime.create.text('plain', 'This is a message with attachments'),
        mime.create.attachment('image/png', 'filler', 'attached_image.png',
                               'attachment'),
        mime.create.attachment('application/pdf', 'filler',
                               'attached_file.pdf', 'attachment'))
    msg = Message.create_from_synced(account, 22, '[Gmail]/All Mail',
                                     datetime.utcnow(), mime_msg.to_string())
    msg.thread = thread
    db.session.add(msg)
    db.session.commit()

    assert len(msg.parts) == 2
    assert all(part.content_disposition == 'attachment' for part in msg.parts)

    block_ids = [part.block.id for part in msg.parts]

    with db.session.no_autoflush:
        transaction = get_latest_transaction(db.session, 'file', block_ids[0],
                                             default_namespace.id)
        assert transaction.command == 'insert'

        transaction = get_latest_transaction(db.session, 'file', block_ids[1],
                                             default_namespace.id)
        assert transaction.command == 'insert'
Ejemplo n.º 18
0
def test_message_delete(db, gmail_account):
    """ Ensure that all associated MessageCategories are deleted
        when a Message is deleted """

    api_client = new_api_client(db, gmail_account.namespace)

    generic_thread = add_fake_thread(db.session, gmail_account.namespace.id)
    gen_message = add_fake_message(db.session, gmail_account.namespace.id,
                                   generic_thread)

    category_ids = []
    for i in xrange(10):
        po_data = api_client.post_data('/labels/', {"display_name": str(i)})
        assert po_data.status_code == 200

        category_ids.append(json.loads(po_data.data)['id'])

    data = {"label_ids": category_ids}
    resp = api_client.put_data('/messages/{}'.format(gen_message.public_id),
                               data)
    assert resp.status_code == 200

    associated_mcs = db.session.query(MessageCategory). \
        filter(MessageCategory.message_id == gen_message.id).all()
    assert len(associated_mcs) == 10

    db.session.delete(gen_message)
    db.session.commit()

    assert db.session.query(MessageCategory). \
        filter(MessageCategory.message_id == gen_message.id).all() == []
Ejemplo n.º 19
0
def test_message_label_updates(db, api_client, default_account, api_version,
                               custom_label):
    """Check that you can update a message (optimistically or not),
    and that the update is queued in the ActionLog."""

    headers = dict()
    headers['Api-Version'] = api_version

    # Gmail threads, messages have a 'labels' field
    gmail_thread = add_fake_thread(db.session, default_account.namespace.id)
    gmail_message = add_fake_message(db.session,
                                     default_account.namespace.id, gmail_thread)

    resp_data = api_client.get_data(
        '/messages/{}'.format(gmail_message.public_id), headers=headers)

    assert resp_data['labels'] == []

    category = custom_label.category
    update = dict(labels=[category.public_id])

    resp = api_client.put_data(
        '/messages/{}'.format(gmail_message.public_id), update,
                              headers=headers)

    resp_data = json.loads(resp.data)

    if api_version == API_VERSIONS[0]:
        assert len(resp_data['labels']) == 1
        assert resp_data['labels'][0]['id'] == category.public_id
    else:
        assert resp_data['labels'] == []
Ejemplo n.º 20
0
def test_message_updates_create_thread_transaction(db, default_namespace):
    with db.session.no_autoflush:
        thr = add_fake_thread(db.session, default_namespace.id)
        msg = add_fake_message(db.session, default_namespace.id, thr)

        transaction = get_latest_transaction(db.session, 'thread', thr.id,
                                             default_namespace.id)
        assert (transaction.record_id == thr.id
                and transaction.object_type == 'thread')
        assert transaction.command == 'update'

        # An update to one of the message's propagated_attributes creates a
        # revision for the thread
        msg.is_read = True
        db.session.commit()

        new_transaction = get_latest_transaction(db.session, 'thread', thr.id,
                                                 default_namespace.id)
        assert new_transaction.id != transaction.id
        assert (new_transaction.record_id == thr.id
                and new_transaction.object_type == 'thread')
        assert new_transaction.command == 'update'

        # An update to one of its other attributes does not
        msg.subject = 'Ice cubes and dogs'
        db.session.commit()

        same_transaction = get_latest_transaction(db.session, 'thread', thr.id,
                                                  default_namespace.id)
        assert same_transaction.id == new_transaction.id
Ejemplo n.º 21
0
def test_message_label_updates(db, api_client, default_account, api_version,
                               custom_label):
    """Check that you can update a message (optimistically or not),
    and that the update is queued in the ActionLog."""

    headers = dict()
    headers['Api-Version'] = api_version

    # Gmail threads, messages have a 'labels' field
    gmail_thread = add_fake_thread(db.session, default_account.namespace.id)
    gmail_message = add_fake_message(db.session, default_account.namespace.id,
                                     gmail_thread)

    resp_data = api_client.get_data('/messages/{}'.format(
        gmail_message.public_id),
                                    headers=headers)

    assert resp_data['labels'] == []

    category = custom_label.category
    update = dict(labels=[category.public_id])

    resp = api_client.put_data('/messages/{}'.format(gmail_message.public_id),
                               update,
                               headers=headers)

    resp_data = json.loads(resp.data)

    if api_version == API_VERSIONS[0]:
        assert len(resp_data['labels']) == 1
        assert resp_data['labels'][0]['id'] == category.public_id
    else:
        assert resp_data['labels'] == []
Ejemplo n.º 22
0
def test_thread_sent_recent_date(db, api_client, default_account):
    date1 = datetime.datetime(2015, 1, 1, 0, 0, 0)
    date2 = datetime.datetime(2012, 1, 1, 0, 0, 0)
    date3 = datetime.datetime(2010, 1, 1, 0, 0, 0)
    date4 = datetime.datetime(2009, 1, 1, 0, 0, 0)
    date5 = datetime.datetime(2008, 1, 1, 0, 0, 0)

    thread1 = add_fake_thread(db.session, default_account.namespace.id)

    test_subject = "test_thread_sent_recent_date"

    add_fake_message(db.session, default_account.namespace.id, thread1,
                     subject=test_subject, received_date=date1)
    add_fake_message(db.session, default_account.namespace.id, thread1,
                     subject=test_subject, received_date=date2,
                     add_sent_category=True)
    add_fake_message(db.session, default_account.namespace.id, thread1,
                     subject=test_subject, received_date=date3)
    add_fake_message(db.session, default_account.namespace.id, thread1,
                     subject=test_subject, received_date=date4,
                     add_sent_category=True)
    add_fake_message(db.session, default_account.namespace.id, thread1,
                     subject=test_subject, received_date=date5)

    resp = api_client.get_raw('/threads/')
    assert resp.status_code == 200
    threads = json.loads(resp.data)

    for thread in threads:  # should only be one
        assert datetime.datetime.fromtimestamp(
            thread['last_message_sent_timestamp']) == date2
Ejemplo n.º 23
0
def test_accounttransactions(db, default_namespace):
    account = default_namespace.account

    transaction = get_latest_transaction(db.session, 'account',
                                         default_namespace.account.id,
                                         default_namespace.id)
    assert transaction.command == 'insert'
    transaction_id = transaction.id

    # Verify an AccountTransaction is created
    accounttransactions = db.session.query(AccountTransaction).filter(
        AccountTransaction.namespace_id == default_namespace.id).all()
    assert len(accounttransactions) == 1
    accounttransaction = accounttransactions[0]
    assert accounttransaction.namespace_id == default_namespace.id
    assert accounttransaction.command == 'insert'
    assert accounttransaction.object_type == 'account'
    assert accounttransaction.record_id == default_namespace.account.id
    accounttransaction_id = accounttransaction.id

    with db.session.no_autoflush:
        # No Transaction or AccountTransaction records created

        account.last_synced_events = datetime.utcnow()
        db.session.commit()
        transaction = get_latest_transaction(db.session, 'account',
                                             default_namespace.account.id,
                                             default_namespace.id)
        assert transaction.id == transaction_id
        accounttransactions = db.session.query(AccountTransaction).filter(
            AccountTransaction.namespace_id == default_namespace.id).all()
        assert len(accounttransactions) == 1
        assert accounttransactions[0].id == accounttransaction_id

        # Only Transaction record created

        thread = add_fake_thread(db.session, default_namespace.id)
        transaction = get_latest_transaction(db.session, 'thread', thread.id,
                                             default_namespace.id)
        assert transaction.id > transaction_id
        accounttransactions = db.session.query(AccountTransaction).filter(
            AccountTransaction.namespace_id == default_namespace.id).all()
        assert len(accounttransactions) == 1
        assert accounttransactions[0].id == accounttransaction_id

        # Both Transaction or AccountTransaction records created

        account.sync_state = 'invalid'
        db.session.commit()
        transaction = get_latest_transaction(db.session, 'account',
                                             default_namespace.account.id,
                                             default_namespace.id)
        assert transaction.id > transaction_id
        assert transaction.command == 'update'
        accounttransactions = db.session.query(AccountTransaction).filter(
            AccountTransaction.namespace_id == default_namespace.id).all()
        assert len(accounttransactions) == 2
        assert accounttransactions[1].id != accounttransaction_id
        assert accounttransactions[1].command == 'update'
Ejemplo n.º 24
0
def test_thread_count(db, api_client, default_account):
    date1 = datetime.datetime(2015, 1, 1, 0, 0, 0)
    date2 = datetime.datetime(2012, 1, 1, 0, 0, 0)
    date3 = datetime.datetime(2010, 1, 1, 0, 0, 0)
    date4 = datetime.datetime(2009, 1, 1, 0, 0, 0)
    date5 = datetime.datetime(2008, 1, 1, 0, 0, 0)

    thread1 = add_fake_thread(db.session, default_account.namespace.id)
    thread2 = add_fake_thread(db.session, default_account.namespace.id)

    test_subject = "test_thread_view_count_with_category"

    for thread in [thread1, thread2]:
        add_fake_message(db.session,
                         default_account.namespace.id,
                         thread,
                         subject=test_subject,
                         received_date=date1)
        add_fake_message(db.session,
                         default_account.namespace.id,
                         thread,
                         subject=test_subject,
                         received_date=date2,
                         add_sent_category=True)
        add_fake_message(db.session,
                         default_account.namespace.id,
                         thread,
                         subject=test_subject,
                         received_date=date3)
        add_fake_message(db.session,
                         default_account.namespace.id,
                         thread,
                         subject=test_subject,
                         received_date=date4,
                         add_sent_category=True)
        add_fake_message(db.session,
                         default_account.namespace.id,
                         thread,
                         subject=test_subject,
                         received_date=date5)

    resp = api_client.get_raw('/threads/?view=count&in=sent')
    assert resp.status_code == 200
    threads = json.loads(resp.data)
    assert threads['count'] == 2
Ejemplo n.º 25
0
def test_namespace_delete_cascade(db, default_account):
    from inbox.models import Account, Thread, Message

    models = [Thread, Message]

    namespace = default_account.namespace
    namespace_id = namespace.id
    account_id = default_account.id

    account = db.session.query(Account).get(account_id)
    assert account

    thread = add_fake_thread(db.session, namespace_id)

    add_fake_message(db.session, namespace_id, thread)

    for m in models:
        c = db.session.query(m).filter(m.namespace_id == namespace_id).count()
        print "count for", m, ":", c
        assert c != 0

    fake_account = add_generic_imap_account(db.session)
    fake_account_id = fake_account.id

    assert fake_account_id != account.id and \
        fake_account.namespace.id != namespace_id

    thread = add_fake_thread(db.session, fake_account.namespace.id)

    add_fake_message(db.session, fake_account.namespace.id, thread)

    assert len(
        db.session.query(Namespace).filter(
            Namespace.id == namespace_id).all()) > 0

    # This test is separate from test_namespace_deletion because we want to
    # do a raw SQLAlchemy delete rather than using delete_namespace, which does
    # a bunch of extra work to ensure that objects associated with a Namespace
    # are actually deleted.
    db.session.query(Namespace).filter(Namespace.id == namespace_id).delete()
    db.session.commit()

    assert len(
        db.session.query(Namespace).filter(
            Namespace.id == namespace_id).all()) == 0
Ejemplo n.º 26
0
def create_from_synced(db, account, raw_message):
    thread = add_fake_thread(db.session, account.namespace.id)
    received_date = datetime.datetime.utcnow()
    m = Message.create_from_synced(account, 22, '[Gmail]/All Mail',
                                   received_date, raw_message)
    m.thread = thread
    db.session.add(m)
    db.session.commit()
    return m
Ejemplo n.º 27
0
def create_from_synced(db, account, raw_message):
    thread = add_fake_thread(db.session, account.namespace.id)
    received_date = datetime.datetime.utcnow()
    m = Message.create_from_synced(account, 22, '[Gmail]/All Mail',
                                   received_date, raw_message)
    m.thread = thread
    db.session.add(m)
    db.session.commit()
    return m
Ejemplo n.º 28
0
def test_accounttransactions(db, default_namespace):
    account = default_namespace.account

    transaction = get_latest_transaction(db.session, "account", default_namespace.account.id, default_namespace.id)
    assert transaction.command == "insert"
    transaction_id = transaction.id

    # Verify an AccountTransaction is created
    accounttransactions = (
        db.session.query(AccountTransaction).filter(AccountTransaction.namespace_id == default_namespace.id).all()
    )
    assert len(accounttransactions) == 1
    accounttransaction = accounttransactions[0]
    assert accounttransaction.namespace_id == default_namespace.id
    assert accounttransaction.command == "insert"
    assert accounttransaction.object_type == "account"
    assert accounttransaction.record_id == default_namespace.account.id
    accounttransaction_id = accounttransaction.id

    with db.session.no_autoflush:
        # No Transaction or AccountTransaction records created

        account.last_synced_events = datetime.utcnow()
        db.session.commit()
        transaction = get_latest_transaction(db.session, "account", default_namespace.account.id, default_namespace.id)
        assert transaction.id == transaction_id
        accounttransactions = (
            db.session.query(AccountTransaction).filter(AccountTransaction.namespace_id == default_namespace.id).all()
        )
        assert len(accounttransactions) == 1
        assert accounttransactions[0].id == accounttransaction_id

        # Only Transaction record created

        thread = add_fake_thread(db.session, default_namespace.id)
        transaction = get_latest_transaction(db.session, "thread", thread.id, default_namespace.id)
        assert transaction.id > transaction_id
        accounttransactions = (
            db.session.query(AccountTransaction).filter(AccountTransaction.namespace_id == default_namespace.id).all()
        )
        assert len(accounttransactions) == 1
        assert accounttransactions[0].id == accounttransaction_id

        # Both Transaction or AccountTransaction records created

        account.sync_state = "invalid"
        db.session.commit()
        transaction = get_latest_transaction(db.session, "account", default_namespace.account.id, default_namespace.id)
        assert transaction.id > transaction_id
        assert transaction.command == "update"
        accounttransactions = (
            db.session.query(AccountTransaction).filter(AccountTransaction.namespace_id == default_namespace.id).all()
        )
        assert len(accounttransactions) == 2
        assert accounttransactions[1].id != accounttransaction_id
        assert accounttransactions[1].command == "update"
Ejemplo n.º 29
0
def test_generic_grouping(db, default_account):
    thread = add_fake_thread(db.session, default_account.namespace.id)
    message = add_fake_message(db.session, default_account.namespace.id,
                               thread, subject="Golden Gate Park next Sat")
    folder = Folder(account=default_account, name='Inbox',
                    canonical_name='inbox')
    ImapUid(message=message, account_id=default_account.id,
            msg_uid=2222, folder=folder)

    thread = add_fake_thread(db.session, default_account.namespace.id)

    account = add_generic_imap_account(db.session)
    message = add_fake_message(db.session, account.namespace.id,
                               thread, subject="Golden Gate Park next Sat")

    thread = fetch_corresponding_thread(db.session,
                                        default_account.namespace.id, message)
    assert thread is None, ("fetch_similar_threads should "
                            "heed namespace boundaries")
Ejemplo n.º 30
0
def test_message_insert_creates_transaction(db, default_namespace):
    with db.session.no_autoflush:
        thr = add_fake_thread(db.session, default_namespace.id)
        msg = add_fake_message(db.session, default_namespace.id, thr)
        transaction = get_latest_transaction(db.session, "message", msg.id, default_namespace.id)
        assert transaction.command == "insert"

        # Test that the thread gets revised too
        transaction = get_latest_transaction(db.session, "thread", thr.id, default_namespace.id)
        assert transaction.command == "update"
Ejemplo n.º 31
0
def test_namespace_delete_cascade(db, default_account):
    from inbox.models import Account, Thread, Message

    models = [Thread, Message]

    namespace = default_account.namespace
    namespace_id = namespace.id
    account_id = default_account.id

    account = db.session.query(Account).get(account_id)
    assert account

    thread = add_fake_thread(db.session, namespace_id)

    add_fake_message(db.session, namespace_id, thread)

    for m in models:
        c = db.session.query(m).filter(
            m.namespace_id == namespace_id).count()
        print "count for", m, ":", c
        assert c != 0

    fake_account = add_generic_imap_account(db.session)
    fake_account_id = fake_account.id

    assert fake_account_id != account.id and \
        fake_account.namespace.id != namespace_id

    thread = add_fake_thread(db.session, fake_account.namespace.id)

    add_fake_message(db.session, fake_account.namespace.id, thread)

    assert len(db.session.query(Namespace).filter(Namespace.id == namespace_id).all()) > 0

    # This test is separate from test_namespace_deletion because we want to
    # do a raw SQLAlchemy delete rather than using delete_namespace, which does
    # a bunch of extra work to ensure that objects associated with a Namespace
    # are actually deleted.
    db.session.query(Namespace).filter(Namespace.id == namespace_id).delete()
    db.session.commit()

    assert len(db.session.query(Namespace).filter(Namespace.id == namespace_id).all()) == 0
Ejemplo n.º 32
0
def test_message_updates_create_transaction(db, default_namespace):
    with db.session.no_autoflush:
        thr = add_fake_thread(db.session, default_namespace.id)
        msg = add_fake_message(db.session, default_namespace.id, thr)

        msg.is_read = True
        db.session.commit()
        transaction = get_latest_transaction(db.session, "message", msg.id, default_namespace.id)
        assert transaction.record_id == msg.id
        assert transaction.object_type == "message"
        assert transaction.command == "update"
Ejemplo n.º 33
0
def test_message_insert_creates_transaction(db, default_namespace):
    with db.session.no_autoflush:
        thr = add_fake_thread(db.session, default_namespace.id)
        msg = add_fake_message(db.session, default_namespace.id, thr)
        transaction = get_latest_transaction(db.session, 'message', msg.id,
                                             default_namespace.id)
        assert transaction.command == 'insert'

        # Test that the thread gets revised too
        transaction = get_latest_transaction(db.session, 'thread', thr.id,
                                             default_namespace.id)
        assert transaction.command == 'update'
Ejemplo n.º 34
0
def test_object_type_distinguishes_messages_and_drafts(db, default_namespace):
    with db.session.no_autoflush:
        thr = add_fake_thread(db.session, default_namespace.id)
        msg = add_fake_message(db.session, default_namespace.id, thr)
        msg.is_draft = 1
        db.session.commit()
        transaction = get_latest_transaction(db.session, "draft", msg.id, default_namespace.id)
        assert transaction.command == "update"
        db.session.delete(msg)
        db.session.commit()
        transaction = get_latest_transaction(db.session, "draft", msg.id, default_namespace.id)
        assert transaction.command == "delete"
Ejemplo n.º 35
0
def test_message_updates_create_transaction(db, default_namespace):
    with db.session.no_autoflush:
        thr = add_fake_thread(db.session, default_namespace.id)
        msg = add_fake_message(db.session, default_namespace.id, thr)

        msg.is_read = True
        db.session.commit()
        transaction = get_latest_transaction(db.session, 'message', msg.id,
                                             default_namespace.id)
        assert transaction.record_id == msg.id
        assert transaction.object_type == 'message'
        assert transaction.command == 'update'
Ejemplo n.º 36
0
def test_thread_received_recent_date(db, api_client, default_account):
    date1 = datetime.datetime(2015, 1, 1, 0, 0, 0)
    date2 = datetime.datetime(2012, 1, 1, 0, 0, 0)

    thread1 = add_fake_thread(db.session, default_account.namespace.id)

    date_dict = dict()

    add_fake_message(db.session,
                     default_account.namespace.id,
                     thread1,
                     subject="Test Thread 1",
                     received_date=date1,
                     add_sent_category=True)
    add_fake_message(db.session,
                     default_account.namespace.id,
                     thread1,
                     subject="Test Thread 1",
                     received_date=date2)

    date_dict["Test Thread 1"] = date2

    thread2 = add_fake_thread(db.session, default_account.namespace.id)
    add_fake_message(db.session,
                     default_account.namespace.id,
                     thread2,
                     subject="Test Thread 2",
                     received_date=date1,
                     add_sent_category=True)

    date_dict["Test Thread 2"] = date1

    resp = api_client.get_raw('/threads/')
    assert resp.status_code == 200
    threads = json.loads(resp.data)

    for thread in threads:
        assert date_dict[thread['subject']] == \
            datetime.datetime.fromtimestamp(
                thread['last_message_received_timestamp'])
Ejemplo n.º 37
0
def test_generic_drafts_flag_constrained_by_folder(db, generic_account,
                                                   folder_role):
    msg_uid = 22
    thread = add_fake_thread(db.session, generic_account.namespace.id)
    message = add_fake_message(db.session, generic_account.namespace.id,
                               thread)
    folder = add_fake_folder(db.session, generic_account)
    add_fake_imapuid(db.session, generic_account.id, message, folder, msg_uid)

    new_flags = {msg_uid: Flags(('\\Draft',), None)}
    update_metadata(generic_account.id, folder.id, folder_role, new_flags,
                    db.session)
    assert message.is_draft == (folder_role == 'drafts')
Ejemplo n.º 38
0
def test_generic_drafts_flag_constrained_by_folder(db, generic_account,
                                                   folder_role):
    msg_uid = 22
    thread = add_fake_thread(db.session, generic_account.namespace.id)
    message = add_fake_message(db.session, generic_account.namespace.id,
                               thread)
    folder = add_fake_folder(db.session, generic_account)
    add_fake_imapuid(db.session, generic_account.id, message, folder, msg_uid)

    new_flags = {msg_uid: Flags(('\\Draft', ), None)}
    update_metadata(generic_account.id, folder.id, folder_role, new_flags,
                    db.session)
    assert message.is_draft == (folder_role == 'drafts')
Ejemplo n.º 39
0
def test_object_type_distinguishes_messages_and_drafts(db, default_namespace):
    with db.session.no_autoflush:
        thr = add_fake_thread(db.session, default_namespace.id)
        msg = add_fake_message(db.session, default_namespace.id, thr)
        msg.is_draft = 1
        db.session.commit()
        transaction = get_latest_transaction(db.session, 'draft', msg.id,
                                             default_namespace.id)
        assert transaction.command == 'update'
        db.session.delete(msg)
        db.session.commit()
        transaction = get_latest_transaction(db.session, 'draft', msg.id,
                                             default_namespace.id)
        assert transaction.command == 'delete'
Ejemplo n.º 40
0
def test_message_category_updates_create_transaction(db, default_namespace):
    with db.session.no_autoflush:
        thr = add_fake_thread(db.session, default_namespace.id)
        msg = add_fake_message(db.session, default_namespace.id, thr)
        cat = add_fake_category(db.session, default_namespace.id, "category")
        thread_trx_before_category_change = get_latest_transaction(db.session, "thread", thr.id, default_namespace.id)

        msg.categories = [cat]
        db.session.commit()
        latest_message_trx = get_latest_transaction(db.session, "message", msg.id, default_namespace.id)
        thread_trx_after_category_change = get_latest_transaction(db.session, "thread", thr.id, default_namespace.id)

        assert latest_message_trx.command == "update"
        assert thread_trx_before_category_change.id != thread_trx_after_category_change.id
Ejemplo n.º 41
0
def test_transaction_creation_for_self_referential_message_relationship(db, default_namespace):
    # Make sure that updating the self-refential relationship
    # `Message.reply_to_message` does not create a spurious update delta for
    # the parent message.
    thr = add_fake_thread(db.session, default_namespace.id)
    msg = add_fake_message(db.session, default_namespace.id, thr)
    reply = add_fake_message(db.session, default_namespace.id, thr)
    reply.reply_to_message = msg
    db.session.commit()
    assert reply.reply_to_message_id is not None
    assert msg.reply_to_message_id is None
    transaction = get_latest_transaction(db.session, "message", msg.id, default_namespace.id)
    assert transaction.record_id == msg.id
    assert transaction.object_type == "message"
    assert transaction.command == "insert"
Ejemplo n.º 42
0
def test_message_from_synced(db, new_message_from_synced, default_namespace):
    thread = add_fake_thread(db.session, default_namespace.id)
    m = new_message_from_synced
    assert m.namespace_id == default_namespace.id
    assert m.to_addr == [['Alice', '*****@*****.**']]
    assert m.cc_addr == [['Bob', '*****@*****.**']]
    assert m.subject == 'Hello'
    assert m.body == '<html>Hello World!</html>'
    assert m.data_sha256
    m.thread = thread
    db.session.add(m)
    db.session.commit()

    assert (db.session.query(Block).filter(
        Block.namespace_id == default_namespace.id).count() == 0)
    assert len(m.parts) == 0
Ejemplo n.º 43
0
def folder_and_message_maps(db, default_account):
    folder_map, message_map = {}, {}
    for name in ('all', 'trash', 'spam'):
        # Create a folder
        display_name = name.capitalize() if name != 'all' else 'All Mail'
        folder = add_fake_folder(db.session, default_account, display_name, name)
        thread = add_fake_thread(db.session, default_account.namespace.id)
        # Create a message in the folder
        message = add_fake_message(db.session, default_account.namespace.id,
                                   thread)
        add_fake_imapuid(db.session, default_account.id, message, folder, 13)
        update_message_metadata(db.session, default_account, message, False)
        db.session.commit()
        folder_map[name] = folder
        message_map[name] = message
    return folder_map, message_map
Ejemplo n.º 44
0
def test_message_from_synced(db, new_message_from_synced, default_namespace):
    thread = add_fake_thread(db.session, default_namespace.id)
    m = new_message_from_synced
    assert m.namespace_id == default_namespace.id
    assert m.to_addr == [['Alice', '*****@*****.**']]
    assert m.cc_addr == [['Bob', '*****@*****.**']]
    assert m.subject == 'Hello'
    assert m.body == '<html>Hello World!</html>'
    assert m.data_sha256
    m.thread = thread
    db.session.add(m)
    db.session.commit()

    assert (db.session.query(Block).filter(
            Block.namespace_id == default_namespace.id).count() == 0)
    assert len(m.parts) == 0
Ejemplo n.º 45
0
def test_reject_incompatible_reply_thread_and_message(
        db, api_client, message, thread, default_namespace):
    alt_thread = add_fake_thread(db.session, default_namespace.id)
    add_fake_message(db.session, default_namespace.id, alt_thread)

    thread = api_client.get_data('/threads')[0]
    alt_message_id = api_client.get_data('/threads')[1]['message_ids'][0]
    alt_message = api_client.get_data('/messages/{}'.format(alt_message_id))
    assert thread['id'] != alt_message['thread_id']
    reply_draft = {
        'subject': 'test reply',
        'reply_to_message_id': alt_message['id'],
        'thread_id': thread['id']
    }
    r = api_client.post_data('/drafts', reply_draft)
    assert r.status_code == 400
Ejemplo n.º 46
0
def test_thread_sent_recent_date(db, api_client, default_account):
    date1 = datetime.datetime(2015, 1, 1, 0, 0, 0)
    date2 = datetime.datetime(2012, 1, 1, 0, 0, 0)
    date3 = datetime.datetime(2010, 1, 1, 0, 0, 0)
    date4 = datetime.datetime(2009, 1, 1, 0, 0, 0)
    date5 = datetime.datetime(2008, 1, 1, 0, 0, 0)

    thread1 = add_fake_thread(db.session, default_account.namespace.id)

    test_subject = "test_thread_sent_recent_date"

    add_fake_message(db.session,
                     default_account.namespace.id,
                     thread1,
                     subject=test_subject,
                     received_date=date1)
    add_fake_message(db.session,
                     default_account.namespace.id,
                     thread1,
                     subject=test_subject,
                     received_date=date2,
                     add_sent_category=True)
    add_fake_message(db.session,
                     default_account.namespace.id,
                     thread1,
                     subject=test_subject,
                     received_date=date3)
    add_fake_message(db.session,
                     default_account.namespace.id,
                     thread1,
                     subject=test_subject,
                     received_date=date4,
                     add_sent_category=True)
    add_fake_message(db.session,
                     default_account.namespace.id,
                     thread1,
                     subject=test_subject,
                     received_date=date5)

    resp = api_client.get_raw('/threads/')
    assert resp.status_code == 200
    threads = json.loads(resp.data)

    for thread in threads:  # should only be one
        assert datetime.datetime.fromtimestamp(
            thread['last_message_sent_timestamp']) == date2
Ejemplo n.º 47
0
def folder_and_message_maps(db, default_account):
    folder_map, message_map = {}, {}
    for name in ('all', 'trash', 'spam'):
        # Create a folder
        display_name = name.capitalize() if name != 'all' else 'All Mail'
        folder = add_fake_folder(db.session, default_account, display_name,
                                 name)
        thread = add_fake_thread(db.session, default_account.namespace.id)
        # Create a message in the folder
        message = add_fake_message(db.session, default_account.namespace.id,
                                   thread)
        add_fake_imapuid(db.session, default_account.id, message, folder, 13)
        update_message_metadata(db.session, default_account, message, False)
        db.session.commit()
        folder_map[name] = folder
        message_map[name] = message
    return folder_map, message_map
Ejemplo n.º 48
0
def test_reject_incompatible_reply_thread_and_message(db, api_client, message,
                                                      thread,
                                                      default_namespace):
    alt_thread = add_fake_thread(db.session, default_namespace.id)
    add_fake_message(db.session, default_namespace.id, alt_thread)

    thread = api_client.get_data('/threads')[0]
    alt_message_id = api_client.get_data('/threads')[1]['message_ids'][0]
    alt_message = api_client.get_data('/messages/{}'.format(alt_message_id))
    assert thread['id'] != alt_message['thread_id']
    reply_draft = {
        'subject': 'test reply',
        'reply_to_message_id': alt_message['id'],
        'thread_id': thread['id']
    }
    r = api_client.post_data('/drafts', reply_draft)
    assert r.status_code == 400
Ejemplo n.º 49
0
def test_object_deletions_create_transaction(db, default_namespace):
    with db.session.no_autoflush:
        thr = add_fake_thread(db.session, default_namespace.id)
        msg = add_fake_message(db.session, default_namespace.id, thr)
        db.session.delete(msg)
        db.session.commit()
        transaction = get_latest_transaction(db.session, "message", msg.id, default_namespace.id)
        assert transaction.record_id == msg.id
        assert transaction.object_type == "message"
        assert transaction.command == "delete"

        db.session.delete(thr)
        db.session.commit()
        transaction = get_latest_transaction(db.session, "thread", thr.id, default_namespace.id)
        assert transaction.record_id == thr.id
        assert transaction.object_type == "thread"
        assert transaction.command == "delete"
Ejemplo n.º 50
0
def test_transaction_creation_for_self_referential_message_relationship(
        db, default_namespace):
    # Make sure that updating the self-refential relationship
    # `Message.reply_to_message` does not create a spurious update delta for
    # the parent message.
    thr = add_fake_thread(db.session, default_namespace.id)
    msg = add_fake_message(db.session, default_namespace.id, thr)
    reply = add_fake_message(db.session, default_namespace.id, thr)
    reply.reply_to_message = msg
    db.session.commit()
    assert reply.reply_to_message_id is not None
    assert msg.reply_to_message_id is None
    transaction = get_latest_transaction(db.session, 'message', msg.id,
                                         default_namespace.id)
    assert transaction.record_id == msg.id
    assert transaction.object_type == 'message'
    assert transaction.command == 'insert'
Ejemplo n.º 51
0
def test_ordering(api_client, db, default_namespace):
    for i in range(3):
        thr = add_fake_thread(db.session, default_namespace.id)
        received_date = (datetime.datetime.utcnow() +
                         datetime.timedelta(seconds=22 * (i + 1)))
        add_fake_message(db.session, default_namespace.id,
                         thr, received_date=received_date)
    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).
        filter(Message.namespace_id == default_namespace.id).
        order_by(desc(Message.received_date)).limit(3)]
    assert expected_public_ids == [r['id'] for r in ordered_results]
Ejemplo n.º 52
0
def test_self_send(db, default_namespace):
    first_thread = add_fake_thread(db.session, default_namespace.id)
    first_thread.subject = 'Some kind of test'

    add_fake_message(db.session, default_namespace.id,
                     thread=first_thread,
                     subject='Some kind of test',
                     from_addr=[('Karim Hamidou', '*****@*****.**')],
                     to_addr=[('Karim Hamidou', '*****@*****.**')])

    msg2 = add_fake_message(db.session, default_namespace.id,
                            thread=None,
                            subject='Re: Some kind of test',
                            from_addr=[('Karim Hamidou', '*****@*****.**')],
                            to_addr=[('Karim Hamidou', '*****@*****.**')])

    matched_thread = fetch_corresponding_thread(db.session,
                                                default_namespace.id, msg2)
    assert matched_thread is first_thread, "Should match on self-send"
Ejemplo n.º 53
0
def test_thread_delete(db, gmail_account):
    """ Ensure that all associated Messages are deleted
        when a Thread is deleted."""

    generic_thread = add_fake_thread(db.session, gmail_account.namespace.id)
    generic_message = add_fake_message(db.session, gmail_account.namespace.id,
                                       generic_thread)
    assert db.session.query(Thread). \
        filter(Thread.id == generic_thread.id).all() == [generic_thread]
    assert db.session.query(Message). \
        filter(Message.id == generic_message.id).all() == [generic_message]

    db.session.delete(generic_thread)
    db.session.commit()

    assert db.session.query(Thread). \
        filter(Thread.id == generic_thread.id).all() == []
    assert db.session.query(Message). \
        filter(Message.id == generic_message.id).all() == []
Ejemplo n.º 54
0
def test_message_category_updates_create_transaction(db, default_namespace):
    with db.session.no_autoflush:
        thr = add_fake_thread(db.session, default_namespace.id)
        msg = add_fake_message(db.session, default_namespace.id, thr)
        cat = add_fake_category(db.session, default_namespace.id, 'category')
        thread_trx_before_category_change = get_latest_transaction(
            db.session, 'thread', thr.id, default_namespace.id)

        msg.categories = [cat]
        db.session.commit()
        latest_message_trx = get_latest_transaction(db.session, 'message',
                                                    msg.id,
                                                    default_namespace.id)
        thread_trx_after_category_change = get_latest_transaction(
            db.session, 'thread', thr.id, default_namespace.id)

        assert latest_message_trx.command == 'update'
        assert thread_trx_before_category_change.id != \
            thread_trx_after_category_change.id
Ejemplo n.º 55
0
def test_self_send(db, default_namespace):
    first_thread = add_fake_thread(db.session, default_namespace.id)
    first_thread.subject = 'Some kind of test'

    add_fake_message(db.session, default_namespace.id,
                     thread=first_thread,
                     subject='Some kind of test',
                     from_addr=[('Karim Hamidou', '*****@*****.**')],
                     to_addr=[('Karim Hamidou', '*****@*****.**')])

    msg2 = add_fake_message(db.session, default_namespace.id,
                            thread=None,
                            subject='Re: Some kind of test',
                            from_addr=[('Karim Hamidou', '*****@*****.**')],
                            to_addr=[('Karim Hamidou', '*****@*****.**')])

    matched_thread = fetch_corresponding_thread(db.session,
                                                default_namespace.id, msg2)
    assert matched_thread is first_thread, "Should match on self-send"
Ejemplo n.º 56
0
def test_object_deletions_create_transaction(db, default_namespace):
    with db.session.no_autoflush:
        thr = add_fake_thread(db.session, default_namespace.id)
        msg = add_fake_message(db.session, default_namespace.id, thr)
        db.session.delete(msg)
        db.session.commit()
        transaction = get_latest_transaction(db.session, 'message', msg.id,
                                             default_namespace.id)
        assert transaction.record_id == msg.id
        assert transaction.object_type == 'message'
        assert transaction.command == 'delete'

        db.session.delete(thr)
        db.session.commit()
        transaction = get_latest_transaction(db.session, 'thread', thr.id,
                                             default_namespace.id)
        assert transaction.record_id == thr.id
        assert transaction.object_type == 'thread'
        assert transaction.command == 'delete'
Ejemplo n.º 57
0
def add_completely_fake_account(db, email='*****@*****.**'):
    from inbox.models.backends.gmail import GmailAuthCredentials
    fake_account = add_fake_gmail_account(db.session, email_address=email)
    calendar = add_fake_calendar(db.session, fake_account.namespace.id)
    for i in random_range(1, 10):
        add_fake_event(db.session,
                       fake_account.namespace.id,
                       calendar=calendar,
                       title='%s' % i)

    # Add fake Threads, Messages and ImapUids.
    folder = add_fake_folder(db.session, fake_account)
    for i in random_range(1, 4):
        th = add_fake_thread(db.session, fake_account.namespace.id)

        for j in random_range(1, 3):
            msg = add_fake_msg_with_calendar_part(db.session,
                                                  fake_account,
                                                  'fake part',
                                                  thread=th)
            db.session.add(msg)
            db.session.flush()

            for k in random_range(1, 2):
                add_fake_imapuid(db.session, fake_account.id, msg, folder,
                                 int('%s%s' % (msg.id, k)))
    # Add fake contacts
    for i in random_range(1, 5):
        add_fake_contact(db.session, fake_account.namespace.id, uid=str(i))

    auth_creds = GmailAuthCredentials()
    auth_creds.gmailaccount = fake_account
    auth_creds.scopes = "email"
    auth_creds.g_id_token = "test"
    auth_creds.client_id = "test"
    auth_creds.client_secret = "test"
    auth_creds.refresh_token = "test"
    auth_creds.is_valid = True
    db.session.add(auth_creds)
    db.session.commit()

    return fake_account
Ejemplo n.º 58
0
def test_thread_delete(db, gmail_account):
    """ Ensure that all associated Messages are deleted
        when a Thread is deleted."""

    generic_thread = add_fake_thread(db.session, gmail_account.namespace.id)
    generic_message = add_fake_message(db.session,
                                       gmail_account.namespace.id,
                                       generic_thread)
    assert db.session.query(Thread). \
        filter(Thread.id == generic_thread.id).all() == [generic_thread]
    assert db.session.query(Message). \
        filter(Message.id == generic_message.id).all() == [generic_message]

    db.session.delete(generic_thread)
    db.session.commit()

    assert db.session.query(Thread). \
        filter(Thread.id == generic_thread.id).all() == []
    assert db.session.query(Message). \
        filter(Message.id == generic_message.id).all() == []
Ejemplo n.º 59
0
def test_ordering(api_client, db, default_namespace):
    for i in range(3):
        thr = add_fake_thread(db.session, default_namespace.id)
        received_date = (datetime.datetime.utcnow() +
                         datetime.timedelta(seconds=22 * (i + 1)))
        add_fake_message(db.session,
                         default_namespace.id,
                         thr,
                         received_date=received_date)
    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).filter(
            Message.namespace_id == default_namespace.id).order_by(
                desc(Message.received_date)).limit(3)
    ]
    assert expected_public_ids == [r['id'] for r in ordered_results]
Ejemplo n.º 60
0
def test_message_labels(db, gmail_account):
    # Because we're using the gmail_account namespace
    api_client = new_api_client(db, gmail_account.namespace)

    # Gmail threads, messages have a 'labels' field
    gmail_thread = add_fake_thread(db.session, gmail_account.namespace.id)
    gmail_message = add_fake_message(db.session,
                                     gmail_account.namespace.id, gmail_thread)

    resp_data = api_client.get_data(
        '/threads/{}'.format(gmail_thread.public_id))

    assert resp_data['id'] == gmail_thread.public_id
    assert resp_data['object'] == 'thread'
    assert 'labels' in resp_data and 'folders' not in resp_data

    resp_data = api_client.get_data(
        '/messages/{}'.format(gmail_message.public_id))

    assert resp_data['id'] == gmail_message.public_id
    assert resp_data['object'] == 'message'
    assert 'labels' in resp_data and 'folders' not in resp_data