Ejemplo n.º 1
0
def test_reconcile_message(db, config):
    from inbox.models.util import reconcile_message
    from inbox.sendmail.base import create_draft
    from inbox.models.account import Account
    from inbox.models.message import Message
    from inbox.log import get_logger
    log = get_logger()

    account = db.session.query(Account).get(ACCOUNT_ID)
    draft = create_draft(db.session, account)

    assert draft.inbox_uid == draft.public_id, 'draft has incorrect inbox_uid'
    inbox_uid = draft.inbox_uid

    message = Message()
    message.thread_id = THREAD_ID
    message.received_date = datetime.utcnow()
    message.size = len('')
    message.is_draft = True
    message.is_read = True
    message.sanitized_body = ''
    message.snippet = ''
    message.inbox_uid = draft.inbox_uid
    db.session.add(message)
    db.session.commit()

    reconcile_message(db.session, log, inbox_uid, message)

    assert draft.resolved_message and draft.resolved_message.id == message.id,\
        'draft not reconciled correctly'

    assert message.public_id != draft.public_id, \
        'message has incorrect public_id'
Ejemplo n.º 2
0
def test_delete_remote_draft(db, api_client):
    from inbox.models.message import Message

    # Non-Inbox created draft, therefore don't set inbox_uid
    message = Message()
    message.namespace_id = NAMESPACE_ID
    message.thread_id = 1
    message.received_date = datetime.utcnow()
    message.size = len('')
    message.is_draft = True
    message.is_read = True
    message.sanitized_body = ''
    message.snippet = ''

    db.session.add(message)
    db.session.commit()

    drafts = api_client.get_data('/drafts')
    assert len(drafts) == 1

    public_id = drafts[0]['id']
    version = drafts[0]['version']

    assert public_id == message.public_id and version == message.version

    api_client.delete('/drafts/{}'.format(public_id), {'version': version})

    # Check that drafts were deleted
    drafts = api_client.get_data('/drafts')
    assert not drafts
Ejemplo n.º 3
0
def create_imap_message(db_session, log, account, folder, msg):
    """ IMAP-specific message creation logic.

    This is the one function in this file that gets to take an account
    object instead of an account_id, because we need to relate the
    account to ImapUids for versioning to work, since it needs to look
    up the namespace.

    Returns
    -------
    imapuid : inbox.models.tables.imap.ImapUid
        New db object, which links to new Message and Block objects through
        relationships. All new objects are uncommitted.
    """
    new_msg = Message(account=account, mid=msg.uid, folder_name=folder.name,
                      received_date=msg.internaldate, flags=msg.flags,
                      body_string=msg.body)

    imapuid = ImapUid(account=account, folder=folder, msg_uid=msg.uid,
                      message=new_msg)
    imapuid.update_imap_flags(msg.flags, msg.g_labels)

    new_msg.is_draft = imapuid.is_draft
    new_msg.is_read = imapuid.is_seen

    update_contacts_from_message(db_session, new_msg, account.id)

    # NOTE: This might be a good place to add FolderItem entries for
    # non-Gmail backends.

    return imapuid
Ejemplo n.º 4
0
def test_message_body_storage(config, sample_input, encrypt):
    message = Message()
    config["ENCRYPT_SECRETS"] = encrypt
    message.body = None
    assert message._compacted_body is None
    message.body = sample_input
    assert message._compacted_body.startswith(
        (b"\x01" if encrypt else b"\x00") + b"\x00\x00\x00\x00"
    )
    assert message.body == sample_input
Ejemplo n.º 5
0
def test_delete_remote_draft(db, api_client):
    from inbox.models.message import Message

    # Non-Inbox created draft, therefore don't set inbox_uid
    message = Message()
    message.namespace_id = NAMESPACE_ID
    message.thread_id = 1
    message.received_date = datetime.utcnow()
    message.size = len('')
    message.is_draft = True
    message.is_read = True
    message.sanitized_body = ''
    message.snippet = ''

    db.session.add(message)
    db.session.commit()

    drafts = api_client.get_data('/drafts')
    assert len(drafts) == 1

    public_id = drafts[0]['id']
    version = drafts[0]['version']

    assert public_id == message.public_id and version == message.version

    api_client.delete('/drafts/{}'.format(public_id),
                      {'version': version})

    # Check that drafts were deleted
    drafts = api_client.get_data('/drafts')
    assert not drafts
Ejemplo n.º 6
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'
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 create_imap_message(db_session, log, account, folder, msg):
    """ IMAP-specific message creation logic.

    This is the one function in this file that gets to take an account
    object instead of an account_id, because we need to relate the
    account to ImapUids for versioning to work, since it needs to look
    up the namespace.

    Returns
    -------
    imapuid : inbox.models.tables.imap.ImapUid
        New db object, which links to new Message and Block objects through
        relationships. All new objects are uncommitted.
    """
    new_msg = Message.create_from_synced(account=account, mid=msg.uid,
                                         folder_name=folder.name,
                                         received_date=msg.internaldate,
                                         body_string=msg.body)

    # Check to see if this is a copy of a message that was first created by the
    # Inbox API. If so, don't create a new object; just use the old one.
    existing_copy = reconcile_message(new_msg, db_session)
    if existing_copy is not None:
        new_msg = existing_copy

    imapuid = ImapUid(account=account, folder=folder, msg_uid=msg.uid,
                      message=new_msg)
    imapuid.update_imap_flags(msg.flags, msg.g_labels)

    new_msg.is_draft = imapuid.is_draft
    new_msg.is_read = imapuid.is_seen

    update_contacts_from_message(db_session, new_msg, account.namespace)

    return imapuid
Ejemplo n.º 9
0
def create_imap_message(db_session, log, account, folder, msg):
    """ IMAP-specific message creation logic.

    This is the one function in this file that gets to take an account
    object instead of an account_id, because we need to relate the
    account to ImapUids for versioning to work, since it needs to look
    up the namespace.

    Returns
    -------
    imapuid : inbox.models.tables.imap.ImapUid
        New db object, which links to new Message and Block objects through
        relationships. All new objects are uncommitted.
    """
    new_msg = Message.create_from_synced(account=account, mid=msg.uid,
                                         folder_name=folder.name,
                                         received_date=msg.internaldate,
                                         body_string=msg.body)

    # Check to see if this is a copy of a message that was first created by the
    # Inbox API. If so, don't create a new object; just use the old one.
    existing_copy = reconcile_message(new_msg, db_session)
    if existing_copy is not None:
        new_msg = existing_copy

    imapuid = ImapUid(account=account, folder=folder, msg_uid=msg.uid,
                      message=new_msg)
    imapuid.update_imap_flags(msg.flags, msg.g_labels)

    new_msg.is_draft = imapuid.is_draft
    new_msg.is_read = imapuid.is_seen

    update_contacts_from_message(db_session, new_msg, account.namespace)

    return imapuid
Ejemplo n.º 10
0
def test_adding_message_to_thread(db):
    """recompute_thread_labels is not invoked when a new message is added
     (only when UID metadata changes, or when a UID is deleted). Test that
     tag changes work when adding messages to a thread."""
    account = db.session.query(Account).get(ACCOUNT_ID)
    account.namespace.create_canonical_tags()
    thread = db.session.query(Thread).get(THREAD_ID)
    account.trash_folder = Folder(name='Trash', account=account)
    fld_item = FolderItem(thread=thread, folder=account.trash_folder)

    folder_names = [folder.name for folder in thread.folders]
    m = Message(namespace_id=account.namespace.id,
                subject='test message',
                thread_id=thread.id,
                received_date=datetime.datetime.now(),
                size=64,
                sanitized_body="body",
                snippet="snippet")

    uid = ImapUid(account=account,
                  message=m,
                  g_labels=['\\Inbox', 'test-label'],
                  msg_uid=22L,
                  folder_id=account.inbox_folder.id)
    uid.folder = account.inbox_folder
    uid2 = ImapUid(account=account,
                   message=m,
                   g_labels=['test-2'],
                   msg_uid=24L,
                   folder_id=account.trash_folder.id)
    uid2.folder = account.trash_folder

    thread.messages.append(m)
    add_any_new_thread_labels(thread, uid, db.session)
    add_any_new_thread_labels(thread, uid2, db.session)

    folder_names = [folder.name for folder in thread.folders]
    for folder in folder_names:
        assert folder in ['Inbox', 'Trash', 'test-label', 'test-2', '[Gmail]/All Mail', '[Gmail]/Important'],\
            "all folders should be present"

    # Now, remove the message
    m.imapuids.remove(uid2)
    db.session.delete(uid2)
    db.session.flush()

    recompute_thread_labels(thread, db.session)
    folder_names = [folder.name for folder in thread.folders]
    assert 'test-2' not in folder_names,\
        "test-2 label should have been removed from thread"
Ejemplo n.º 11
0
def create_imap_message(db_session, log, account, folder, msg):
    """ IMAP-specific message creation logic.

    This is the one function in this file that gets to take an account
    object instead of an account_id, because we need to relate the
    account to ImapUids for versioning to work, since it needs to look
    up the namespace.

    Returns
    -------
    imapuid : inbox.models.tables.imap.ImapUid
        New db object, which links to new Message and Block objects through
        relationships. All new objects are uncommitted.
    """
    new_msg = Message(account=account,
                      mid=msg.uid,
                      folder_name=folder.name,
                      received_date=msg.internaldate,
                      flags=msg.flags,
                      body_string=msg.body)

    imapuid = ImapUid(account=account,
                      folder=folder,
                      msg_uid=msg.uid,
                      message=new_msg)
    imapuid.update_imap_flags(msg.flags, msg.g_labels)

    new_msg.is_draft = imapuid.is_draft
    new_msg.is_read = imapuid.is_seen

    update_contacts_from_message(db_session, new_msg, account.id)

    # NOTE: This might be a good place to add FolderItem entries for
    # non-Gmail backends.

    return imapuid