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"
def test_update_contacts_from_message(db, default_namespace, thread): # Check that only one Contact is created for repeatedly-referenced # addresses. add_fake_message(db.session, default_namespace.id, thread, from_addr=[('', '*****@*****.**')], cc_addr=[('', '*****@*****.**')]) assert db.session.query(Contact).filter_by( email_address='*****@*****.**').count() == 1 # Check that existing Contacts are used when we process a new message # referencing them. add_fake_message(db.session, default_namespace.id, thread, from_addr=[('', '*****@*****.**')], cc_addr=[('', '*****@*****.**')], to_addr=[('', '*****@*****.**'), ('', '*****@*****.**')]) assert db.session.query(Contact).filter( Contact.email_address.like('*****@*****.**'), Contact.namespace_id == default_namespace.id).count() == 3 alpha = db.session.query(Contact).filter_by( email_address='*****@*****.**', namespace_id=default_namespace.id).one() assert len(alpha.message_associations) == 4
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
def test_update_metadata(db, folder): """Check that threads are updated correctly when a label that we haven't seen before is added to multiple threads -- previously, this would fail with an IntegrityError because autoflush was disabled.""" first_thread = add_fake_thread(db.session, NAMESPACE_ID) second_thread = add_fake_thread(db.session, NAMESPACE_ID) uids = [] first_thread_uids = (22222, 22223) for msg_uid in first_thread_uids: message = add_fake_message(db.session, NAMESPACE_ID, first_thread) uids.append(add_fake_imapuid(db.session, ACCOUNT_ID, message, folder, msg_uid)) second_thread_uids = (22224, 22226) for msg_uid in second_thread_uids: message = add_fake_message(db.session, NAMESPACE_ID, second_thread) uids.append(add_fake_imapuid(db.session, ACCOUNT_ID, message, folder, msg_uid)) db.session.add_all(uids) db.session.commit() msg_uids = first_thread_uids + second_thread_uids new_flags = {msg_uid: GmailFlags((), (u"\\some_new_label",)) for msg_uid in msg_uids} update_metadata(ACCOUNT_ID, db.session, folder.name, folder.id, msg_uids, new_flags) db.session.commit() assert "some_new_label" in [tag.name for tag in first_thread.tags] assert "some_new_label" in [tag.name for tag in second_thread.tags]
def test_update_contacts_from_message(db): thread = db.session.query(Thread).filter_by( namespace_id=NAMESPACE_ID).first() # Check that only one Contact is created for repeatedly-referenced # addresses. add_fake_message(db.session, NAMESPACE_ID, thread, from_addr=[('', '*****@*****.**')], cc_addr=[('', '*****@*****.**')]) assert db.session.query(Contact).filter_by( email_address='*****@*****.**').count() == 1 # Check that existing Contacts are used when we process a new message # referencing them. add_fake_message(db.session, NAMESPACE_ID, thread, from_addr=[('', '*****@*****.**')], cc_addr=[('', '*****@*****.**')], to_addr=[('', '*****@*****.**'), ('', '*****@*****.**')]) assert db.session.query(Contact).filter( Contact.email_address.like('*****@*****.**')).count() == 3 alpha = db.session.query(Contact).filter_by( email_address='*****@*****.**').one() assert len(alpha.message_associations) == 4
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
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"
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) new_namespace = Namespace() db.session.add(new_namespace) db.session.commit() message = add_fake_message(db.session, new_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")
def test_namespace_limiting(db, test_client): dt = datetime.datetime.utcnow() subject = dt.isoformat() db.session.add(Namespace()) db.session.commit() namespaces = db.session.query(Namespace).all() assert len(namespaces) > 1 for ns in namespaces: thread = Thread(namespace=ns, subjectdate=dt, recentdate=dt, subject=subject) add_fake_message(db.session, ns.id, thread, received_date=dt, subject=subject) db.session.add(Block(namespace=ns, filename=subject)) db.session.commit() for ns in namespaces: r = json.loads(test_client.get('/n/{}/threads?subject={}'. format(ns.public_id, subject)).data) assert len(r) == 1 r = json.loads(test_client.get('/n/{}/messages?subject={}'. format(ns.public_id, subject)).data) assert len(r) == 1 r = json.loads(test_client.get('/n/{}/files?filename={}'. format(ns.public_id, subject)).data) assert len(r) == 1
def test_update_metadata(db): """Check that threads are updated correctly when a label that we haven't seen before is added to multiple threads -- previously, this would with an IntegrityError because autoflush was disabled.""" first_thread = db.session.query(Thread).get(1) second_thread = db.session.query(Thread).get(2) folder = db.session.query(Folder).filter( Folder.account_id == ACCOUNT_ID, Folder.name == '[Gmail]/All Mail').one() uids = [] first_thread_uids = (22222, 22223) for msg_uid in first_thread_uids: message = add_fake_message(db.session, NAMESPACE_ID, first_thread) uids.append(ImapUid(account_id=ACCOUNT_ID, message=message, msg_uid=msg_uid, folder=folder)) second_thread_uids = (22224, 22226) for msg_uid in second_thread_uids: message = add_fake_message(db.session, NAMESPACE_ID, second_thread) uids.append(ImapUid(account_id=ACCOUNT_ID, message=message, msg_uid=msg_uid, folder=folder)) db.session.add_all(uids) db.session.commit() msg_uids = first_thread_uids + second_thread_uids new_flags = {msg_uid: GmailFlags((), (u'\\some_new_label',)) for msg_uid in msg_uids} update_metadata(ACCOUNT_ID, db.session, folder.name, folder.id, msg_uids, new_flags) db.session.commit() assert 'some_new_label' in [tag.name for tag in first_thread.tags] assert 'some_new_label' in [tag.name for tag in second_thread.tags]
def sorted_gmail_messages(db, default_account, sorted_gmail_threads, folder): thread1, thread2, thread3 = sorted_gmail_threads message1 = add_fake_message( db.session, default_account.namespace.id, thread=thread1, g_msgid=1, from_addr=[{ "name": "Ben Bitdiddle", "email": "*****@*****.**" }], to_addr=[{ "name": "Barrack Obama", "email": "*****@*****.**" }], received_date=datetime.datetime(2015, 7, 9, 23, 50, 7), subject="YOO!", ) add_fake_imapuid(db.session, default_account.id, message1, folder, 3000) message2 = add_fake_message( db.session, default_account.namespace.id, thread=thread2, g_msgid=2, from_addr=[{ "name": "Ben Bitdiddle", "email": "*****@*****.**" }], to_addr=[{ "name": "Barrack Obama", "email": "*****@*****.**" }], received_date=datetime.datetime(2014, 7, 9, 23, 50, 7), subject="Hey!", ) add_fake_imapuid(db.session, default_account.id, message2, folder, 3001) message3 = add_fake_message( db.session, default_account.namespace.id, thread=thread3, g_msgid=3, from_addr=[{ "name": "Ben Bitdiddle", "email": "*****@*****.**" }], to_addr=[{ "name": "Barrack Obama", "email": "*****@*****.**" }], received_date=datetime.datetime(2013, 7, 9, 23, 50, 7), subject="Sup?", ) add_fake_imapuid(db.session, default_account.id, message3, folder, 3002) return [message1, message2, message3]
def test_message_updates_create_transaction(db): with session_scope() as db_session: with db_session.no_autoflush: thr = add_fake_thread(db_session, NAMESPACE_ID) msg = add_fake_message(db_session, NAMESPACE_ID, thr) msg.is_read = True db_session.commit() transaction = get_latest_transaction(db_session, 'message', msg.id, NAMESPACE_ID) assert transaction.record_id == msg.id assert transaction.object_type == 'message' assert transaction.command == 'update' msg = add_fake_message(db_session, NAMESPACE_ID, thr) msg.state = 'sent' db_session.commit() transaction = get_latest_transaction(db_session, 'message', msg.id, NAMESPACE_ID) assert transaction.record_id == msg.id assert transaction.object_type == 'message' assert transaction.command == 'update' msg = add_fake_message(db_session, NAMESPACE_ID, thr) msg.is_draft = True db_session.commit() transaction = get_latest_transaction(db_session, 'message', msg.id, NAMESPACE_ID) assert transaction.record_id == msg.id assert transaction.object_type == 'message' assert transaction.command == 'update'
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"
def test_namespace_limiting(db, api_client, default_namespaces): dt = datetime.datetime.utcnow() subject = dt.isoformat() namespaces = db.session.query(Namespace).all() assert len(namespaces) > 1 for ns in namespaces: thread = Thread(namespace=ns, subjectdate=dt, recentdate=dt, subject=subject) add_fake_message(db.session, ns.id, thread, received_date=dt, subject=subject) db.session.add(Block(namespace=ns, filename=subject)) db.session.commit() for ns in namespaces: r = api_client.get_data("/threads?subject={}".format(subject)) assert len(r) == 1 r = api_client.get_data("/messages?subject={}".format(subject)) assert len(r) == 1 r = api_client.get_data("/files?filename={}".format(subject)) assert len(r) == 1
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"
def test_update_metadata(db, folder): """Check that threads are updated correctly when a label that we haven't seen before is added to multiple threads -- previously, this would fail with an IntegrityError because autoflush was disabled.""" first_thread = add_fake_thread(db.session, NAMESPACE_ID) second_thread = add_fake_thread(db.session, NAMESPACE_ID) uids = [] first_thread_uids = (22222, 22223) for msg_uid in first_thread_uids: message = add_fake_message(db.session, NAMESPACE_ID, first_thread) uids.append( add_fake_imapuid(db.session, ACCOUNT_ID, message, folder, msg_uid)) second_thread_uids = (22224, 22226) for msg_uid in second_thread_uids: message = add_fake_message(db.session, NAMESPACE_ID, second_thread) uids.append( add_fake_imapuid(db.session, ACCOUNT_ID, message, folder, msg_uid)) db.session.add_all(uids) db.session.commit() msg_uids = first_thread_uids + second_thread_uids new_flags = { msg_uid: GmailFlags((), (u'\\some_new_label', )) for msg_uid in msg_uids } update_metadata(ACCOUNT_ID, db.session, folder.name, folder.id, msg_uids, new_flags) db.session.commit() assert 'some_new_label' in [tag.name for tag in first_thread.tags] assert 'some_new_label' in [tag.name for tag in second_thread.tags]
def different_imap_messages(db, generic_account, different_sorted_imap_threads, different_imap_folder): thread1, thread2, thread3 = different_sorted_imap_threads message1 = add_fake_message(db.session, generic_account.namespace.id, thread=thread1, from_addr=[{ 'name': '', 'email': '*****@*****.**' }], to_addr=[{ 'name': 'Ben Bitdiddle', 'email': '*****@*****.**' }], received_date=datetime.datetime( 2015, 7, 9, 23, 50, 7), subject='LOL') add_fake_imapuid(db.session, generic_account.id, message1, different_imap_folder, 5000) message2 = add_fake_message(db.session, generic_account.namespace.id, thread=thread2, from_addr=[{ 'name': '', 'email': '*****@*****.**' }], to_addr=[{ 'name': 'Ben Bitdiddle', 'email': '*****@*****.**' }], received_date=datetime.datetime( 2014, 7, 9, 23, 50, 7), subject='ROTFLMO') add_fake_imapuid(db.session, generic_account.id, message2, different_imap_folder, 5001) message3 = add_fake_message(db.session, generic_account.namespace.id, thread=thread3, from_addr=[{ 'name': '', 'email': '*****@*****.**' }], to_addr=[{ 'name': 'Ben Bitdiddle', 'email': '*****@*****.**' }], received_date=datetime.datetime( 2013, 7, 9, 23, 50, 7), subject='ROFLCOPTER') add_fake_imapuid(db.session, generic_account.id, message3, different_imap_folder, 5002) return [message1, message2, message3]
def sorted_imap_messages(db, generic_account, sorted_imap_threads, imap_folder): thread1, thread2, thread3 = sorted_imap_threads message1 = add_fake_message(db.session, generic_account.namespace.id, thread=thread1, from_addr=[{ 'name': '', 'email': '*****@*****.**' }], to_addr=[{ 'name': 'Ben Bitdiddle', 'email': '*****@*****.**' }], received_date=datetime.datetime( 2015, 7, 9, 23, 50, 7), subject='YOO!') add_fake_imapuid(db.session, generic_account.id, message1, imap_folder, 2000) message2 = add_fake_message(db.session, generic_account.namespace.id, thread=thread2, from_addr=[{ 'name': '', 'email': '*****@*****.**' }], to_addr=[{ 'name': 'Ben Bitdiddle', 'email': '*****@*****.**' }], received_date=datetime.datetime( 2014, 7, 9, 23, 50, 7), subject='Hey!') add_fake_imapuid(db.session, generic_account.id, message2, imap_folder, 2001) message3 = add_fake_message(db.session, generic_account.namespace.id, thread=thread3, from_addr=[{ 'name': '', 'email': '*****@*****.**' }], to_addr=[{ 'name': 'Ben Bitdiddle', 'email': '*****@*****.**' }], received_date=datetime.datetime( 2013, 7, 9, 23, 50, 7), subject='Sup?') add_fake_imapuid(db.session, generic_account.id, message3, imap_folder, 2002) return [message1, message2, message3]
def sorted_gmail_messages(db, default_account, sorted_gmail_threads, folder): thread1, thread2, thread3 = sorted_gmail_threads message1 = add_fake_message(db.session, default_account.namespace.id, thread=thread1, from_addr=[{ 'name': 'Ben Bitdiddle', 'email': '*****@*****.**' }], to_addr=[{ 'name': 'Barrack Obama', 'email': '*****@*****.**' }], g_msgid=1, received_date=datetime.datetime( 2015, 7, 9, 23, 50, 7), subject='YOO!') add_fake_imapuid(db.session, default_account.id, message1, folder, 3000) message2 = add_fake_message(db.session, default_account.namespace.id, thread=thread2, from_addr=[{ 'name': 'Ben Bitdiddle', 'email': '*****@*****.**' }], to_addr=[{ 'name': 'Barrack Obama', 'email': '*****@*****.**' }], g_msgid=2, received_date=datetime.datetime( 2014, 7, 9, 23, 50, 7), subject='Hey!') add_fake_imapuid(db.session, default_account.id, message2, folder, 3001) message3 = add_fake_message(db.session, default_account.namespace.id, thread=thread3, from_addr=[{ 'name': 'Ben Bitdiddle', 'email': '*****@*****.**' }], to_addr=[{ 'name': 'Barrack Obama', 'email': '*****@*****.**' }], g_msgid=3, received_date=datetime.datetime( 2013, 7, 9, 23, 50, 7), subject='Sup?') add_fake_imapuid(db.session, default_account.id, message3, folder, 3002) return [message1, message2, message3]
def test_received_before_after(db, api_client, default_namespace): thread = add_fake_thread(db.session, default_namespace.id) message = add_fake_message(db.session, default_namespace.id, thread, to_addr=[('Bob', '*****@*****.**')], from_addr=[('Alice', '*****@*****.**')], received_date=datetime.datetime(year=1999, day=20, month=03), subject='some subject') thread2 = add_fake_thread(db.session, default_namespace.id) message2 = add_fake_message(db.session, default_namespace.id, thread, to_addr=[('Bob', '*****@*****.**')], from_addr=[('Alice', '*****@*****.**')], received_date=datetime.datetime(year=2000, day=20, month=03), subject='another subject') inbox = Category(namespace_id=message.namespace_id, name='inbox', display_name='Inbox', type_='label') message.categories.add(inbox) thread.subject = message.subject message2.categories.add(inbox) thread2.subject = message2.subject db.session.commit() received_date = message.received_date t_epoch = dt_to_timestamp(datetime.datetime(year=1998, month=2, day=3)) t_firstmsg = dt_to_timestamp(received_date) results = api_client.get_data('/messages?received_before={}' .format(t_epoch)) assert len(results) == 0 # received_before should be inclusive (i.e: match <=, not just <). results = api_client.get_data('/messages?received_before={}' .format(t_firstmsg)) assert len(results) == 1 t1 = dt_to_timestamp(received_date + datetime.timedelta(days=1)) results = api_client.get_data('/messages?received_after={}' .format(t1)) assert len(results) == 1 results = api_client.get_data( '/messages?received_before={}&received_after={}'.format(t1, t_firstmsg)) assert len(results) == 0 # bogus values results = api_client.get_data( '/messages?received_before={}&received_after={}'.format(t_epoch, t1)) assert len(results) == 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
def test_namespace_deletion(db, default_account): from inbox.models import (Account, Thread, Message, Block, Contact, Event, Transaction) 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_fake_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 # Delete namespace, verify data corresponding to this namespace /only/ # is deleted delete_namespace(account_id, namespace_id) db.session.commit() 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
def test_namespace_deletion(db, default_account): from inbox.models import (Account, Thread, Message, Block, Contact, Event, Transaction) 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_fake_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 # Delete namespace, verify data corresponding to this namespace /only/ # is deleted delete_namespace(account_id, namespace_id) db.session.commit() 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
def stub_message(db, new_message_from_synced, default_namespace, thread): message = add_fake_message( db.session, default_namespace.id, thread, subject="Golden Gate Park next Sat", from_addr=[("alice", "*****@*****.**")], to_addr=[("bob", "*****@*****.**")], ) message.snippet = "Banh mi paleo pickled, sriracha" message.body = """ Banh mi paleo pickled, sriracha biodiesel chambray seitan mumblecore mustache. Raw denim gastropub 8-bit, butcher PBR sartorial photo booth Pinterest blog Portland roof party cliche bitters aesthetic. Ugh. """ message = add_fake_message( db.session, default_namespace.id, thread, subject="Re:Golden Gate Park next Sat", from_addr=[("bob", "*****@*****.**")], to_addr=[("alice", "*****@*****.**")], cc_addr=[("Cheryl", "*****@*****.**")], ) message.snippet = "Bushwick meggings ethical keffiyeh" message.body = """ Bushwick meggings ethical keffiyeh. Chambray lumbersexual wayfarers, irony Banksy cred bicycle rights scenester artisan tote bag YOLO gastropub. """ draft = add_fake_message( db.session, default_namespace.id, thread, subject="Re:Golden Gate Park next Sat", from_addr=[("alice", "*****@*****.**")], to_addr=[("bob", "*****@*****.**")], cc_addr=[("Cheryl", "*****@*****.**")], ) draft.snippet = "Hey there friend writing a draft" draft.body = """ DIY tousled Tumblr, VHS meditation 3 wolf moon listicle fingerstache viral bicycle rights. Thundercats kale chips church-key American Apparel. """ draft.is_draft = True draft.reply_to_message = message db.session.commit() return message
def test_generic_grouping(db, generic_account): thread = add_fake_thread(db.session, NAMESPACE_ID) message = add_fake_message(db.session, NAMESPACE_ID, thread, subject="Golden Gate Park next Sat") imapuid = ImapUid(message=message, account_id=ACCOUNT_ID, msg_uid=2222) thread = add_fake_thread(db.session, generic_account.namespace.id) message = add_fake_message(db.session, NAMESPACE_ID + 1, thread, subject="Golden Gate Park next Sat") thread = fetch_corresponding_thread(db.session, generic_account.namespace.id, message) assert thread is None, ("fetch_similar_threads should " "heed namespace boundaries")
def test_handle_noreply_addresses(db, default_namespace, thread): add_fake_message(db.session, default_namespace.id, thread, from_addr=[('Alice', '*****@*****.**')]) add_fake_message(db.session, default_namespace.id, thread, from_addr=[('Bob', '*****@*****.**')]) noreply_contact = db.session.query(Contact).filter( Contact.namespace == default_namespace, Contact.email_address == '*****@*****.**').one() assert noreply_contact.name is None add_fake_message(db.session, default_namespace.id, thread, from_addr=[('Alice', '*****@*****.**')]) add_fake_message(db.session, default_namespace.id, thread, from_addr=[('Alice Lastname', '*****@*****.**')]) contact = db.session.query(Contact).filter( Contact.namespace == default_namespace, Contact.email_address == '*****@*****.**').first() assert contact.name is not None
def stub_message(db, new_message_from_synced): NAMESPACE_ID = default_namespace(db).id # new_msg = new_message_from_synced # fake_thread = add_fake_thread(db.session, NAMESPACE_ID) # new_msg.thread = fake_thread # db.session.add_all([new_msg, fake_thread]) # db.session.commit() # return new_msg thread = add_fake_thread(db.session, NAMESPACE_ID) message = add_fake_message(db.session, NAMESPACE_ID, thread, subject="Golden Gate Park next Sat", from_addr=[('alice', '*****@*****.**')], to_addr=[('bob', '*****@*****.**')]) message.snippet = 'Banh mi paleo pickled, sriracha' message.sanitized_body = """ Banh mi paleo pickled, sriracha biodiesel chambray seitan mumblecore mustache. Raw denim gastropub 8-bit, butcher PBR sartorial photo booth Pinterest blog Portland roof party cliche bitters aesthetic. Ugh. """ message = add_fake_message(db.session, NAMESPACE_ID, thread, subject="Re:Golden Gate Park next Sat", from_addr=[('bob', '*****@*****.**')], to_addr=[('alice', '*****@*****.**')], cc_addr=[('Cheryl', '*****@*****.**')]) message.snippet = 'Bushwick meggings ethical keffiyeh' message.sanitized_body = """ Bushwick meggings ethical keffiyeh. Chambray lumbersexual wayfarers, irony Banksy cred bicycle rights scenester artisan tote bag YOLO gastropub. """ draft = add_fake_message(db.session, NAMESPACE_ID, thread, subject="Re:Golden Gate Park next Sat", from_addr=[('alice', '*****@*****.**')], to_addr=[('bob', '*****@*****.**')], cc_addr=[('Cheryl', '*****@*****.**')]) draft.snippet = 'Hey there friend writing a draft' draft.sanitized_body = """ DIY tousled Tumblr, VHS meditation 3 wolf moon listicle fingerstache viral bicycle rights. Thundercats kale chips church-key American Apparel. """ draft.is_draft = True draft.reply_to_message = message db.session.commit() return message
def stub_message(db): namespace_id = default_namespace(db).id # new_msg = new_message_from_synced # fake_thread = add_fake_thread(db.session, NAMESPACE_ID) # new_msg.thread = fake_thread # db.session.add_all([new_msg, fake_thread]) # db.session.commit() # return new_msg thread = add_fake_thread(db.session, namespace_id) message = add_fake_message(db.session, namespace_id, thread, subject="Golden Gate Park next Sat", from_addr=[('alice', '*****@*****.**')], to_addr=[('bob', '*****@*****.**')]) message.snippet = 'Banh mi paleo pickled, sriracha' message.body = """ Banh mi paleo pickled, sriracha biodiesel chambray seitan mumblecore mustache. Raw denim gastropub 8-bit, butcher PBR sartorial photo booth Pinterest blog Portland roof party cliche bitters aesthetic. Ugh. """ message = add_fake_message(db.session, namespace_id, thread, subject="Re:Golden Gate Park next Sat", from_addr=[('bob', '*****@*****.**')], to_addr=[('alice', '*****@*****.**')], cc_addr=[('Cheryl', '*****@*****.**')]) message.snippet = 'Bushwick meggings ethical keffiyeh' message.body = """ Bushwick meggings ethical keffiyeh. Chambray lumbersexual wayfarers, irony Banksy cred bicycle rights scenester artisan tote bag YOLO gastropub. """ draft = add_fake_message(db.session, namespace_id, thread, subject="Re:Golden Gate Park next Sat", from_addr=[('alice', '*****@*****.**')], to_addr=[('bob', '*****@*****.**')], cc_addr=[('Cheryl', '*****@*****.**')]) draft.snippet = 'Hey there friend writing a draft' draft.body = """ DIY tousled Tumblr, VHS meditation 3 wolf moon listicle fingerstache viral bicycle rights. Thundercats kale chips church-key American Apparel. """ draft.is_draft = True draft.reply_to_message = message db.session.commit() return message
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()
def test_deleting_from_a_message_with_multiple_uids(db): # Now check that deleting a imapuid from a message with # multiple uids doesn't delete the message itself ACCOUNT_ID = 1 NAMESPACE_ID = 1 account = db.session.query(Account).get(ACCOUNT_ID) inbox_folder = account.inbox_folder sent_folder = account.sent_folder thread = add_fake_thread(db.session, NAMESPACE_ID,) message = add_fake_message(db.session, NAMESPACE_ID, thread) sent_uid = ImapUid(message=message, account=account, folder=sent_folder, msg_uid=1337) inbox_uid = ImapUid(message=message, account=account, folder=inbox_folder, msg_uid=2222) db.session.add(sent_uid) db.session.add(inbox_uid) db.session.commit() remove_messages(ACCOUNT_ID, db.session, [2222], inbox_folder.name) msg = db.session.query(Message).get(message.id) assert msg is not None, "the associated message should not have been deleted" assert len(msg.imapuids) == 1, "the message should have only one imapuid"
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
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() == []
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() == []
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'] == []
def test_adding_and_removing_message_on_thread_increments_version( db, thread, default_namespace): assert thread.version == 0 message = add_fake_message(db.session, default_namespace.id, thread) thread.messages.remove(message) db.session.commit() assert thread.version == 2
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
def test_folder_delete(db, generic_account, folder_client): # 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 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
def test_unread(db, default_namespace): from inbox.models import Thread thread = add_fake_thread(db.session, default_namespace.id) thread_id = thread.id message = add_fake_message(db.session, default_namespace.id, thread) db.session.commit() unread_tag = default_namespace.tags['unread'] if unread_tag in thread.tags: assert message.is_read is False thread.remove_tag(unread_tag) db.session.commit() thread = db.session.query(Thread).get(thread_id) assert unread_tag not in thread.tags for m in thread.messages: assert m.is_read is True thread.apply_tag(unread_tag) db.session.commit() thread = db.session.query(Thread).get(thread_id) assert unread_tag in thread.tags for m in thread.messages: assert m.is_read is False
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
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
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
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'] == []
def sorted_imap_messages(db, generic_account, sorted_imap_threads, folder): thread1, thread2, thread3 = sorted_imap_threads message1 = add_fake_message(db.session, generic_account.namespace.id, thread=thread1, from_addr=[{'name': '', 'email': '*****@*****.**'}], to_addr=[{'name': 'Ben Bitdiddle', 'email': '*****@*****.**'}], received_date=datetime. datetime(2015, 7, 9, 23, 50, 7), subject='YOO!') add_fake_imapuid(db.session, generic_account.id, message1, folder, 2000) message2 = add_fake_message(db.session, generic_account.namespace.id, thread=thread2, from_addr=[{'name': '', 'email': '*****@*****.**'}], to_addr=[{'name': 'Ben Bitdiddle', 'email': '*****@*****.**'}], received_date=datetime. datetime(2014, 7, 9, 23, 50, 7), subject='Hey!') add_fake_imapuid(db.session, generic_account.id, message2, folder, 2001) message3 = add_fake_message(db.session, generic_account.namespace.id, thread=thread3, from_addr=[{'name': '', 'email': '*****@*****.**'}], to_addr=[{'name': 'Ben Bitdiddle', 'email': '*****@*****.**'}], received_date=datetime. datetime(2013, 7, 9, 23, 50, 7), subject='Sup?') add_fake_imapuid(db.session, generic_account.id, message3, folder, 2002) imap_ids.extend([2000, 2001, 2002]) return [message1, message2, message3]
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'
def test_reply_to_message_cascade(db, default_namespace, thread, message): reply = add_fake_message(db.session, default_namespace.id, thread) reply.reply_to_message = message db.session.commit() db.session.expire_all() db.session.delete(message) db.session.commit()
def different_imap_messages(db, generic_account, different_sorted_imap_threads, different_imap_folder): thread1, thread2, thread3 = different_sorted_imap_threads message1 = add_fake_message(db.session, generic_account.namespace.id, thread=thread1, from_addr=[{'name': '', 'email': '*****@*****.**'}], to_addr=[{'name': 'Ben Bitdiddle', 'email': '*****@*****.**'}], received_date=datetime. datetime(2015, 7, 9, 23, 50, 7), subject='LOL') add_fake_imapuid(db.session, generic_account.id, message1, different_imap_folder, 5000) message2 = add_fake_message(db.session, generic_account.namespace.id, thread=thread2, from_addr=[{'name': '', 'email': '*****@*****.**'}], to_addr=[{'name': 'Ben Bitdiddle', 'email': '*****@*****.**'}], received_date=datetime. datetime(2014, 7, 9, 23, 50, 7), subject='ROTFLMO') add_fake_imapuid(db.session, generic_account.id, message2, different_imap_folder, 5001) message3 = add_fake_message(db.session, generic_account.namespace.id, thread=thread3, from_addr=[{'name': '', 'email': '*****@*****.**'}], to_addr=[{'name': 'Ben Bitdiddle', 'email': '*****@*****.**'}], received_date=datetime. datetime(2013, 7, 9, 23, 50, 7), subject='ROFLCOPTER') add_fake_imapuid(db.session, generic_account.id, message3, different_imap_folder, 5002) return [message1, message2, message3]
def test_folders_labels_delete(db, api_client, generic_account, gmail_account): api_client = new_api_client(db, generic_account.namespace) # Generic IMAP threads, messages have a 'folders' field generic_thread = add_fake_thread(db.session, generic_account.namespace.id) generic_message = add_fake_message(db.session, generic_account.namespace.id, generic_thread) resp = api_client.post_data('/folders/', {"display_name": "Test_Folder"}) assert resp.status_code == 200 generic_folder = json.loads(resp.data) data = {"folder_id": generic_folder['id']} # Add message to folder api_client.put_data('/messages/{}'.format(generic_message.public_id), data) # try deleting folder that contains a message delete_data = api_client.delete('/folders/{}'.format(generic_folder['id'])) assert delete_data.status_code == 403 resp = api_client.post_data('/folders/', {"display_name": "Test_Folder2"}) empty_folder = json.loads(resp.data) # try deleting folder that contains a message delete_data = api_client.delete('/folders/{}'.format(empty_folder['id'])) assert delete_data.status_code == 200 # Because we're using the generic_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 = api_client.post_data('/labels/', {"display_name": "Test_Labels"}) assert resp.status_code == 200 gmail_label = json.loads(resp.data) data = {"folder_id": gmail_label['id']} # Add label to message api_client.put_data('/messages/{}'.format(gmail_message.public_id), data) # try deleting label delete_data = api_client.delete('/labels/{}'.format(gmail_label['id'])) assert delete_data.status_code == 200
def test_threads_only_deleted_when_no_messages_left(db, default_account, default_namespace, message, thread, folder, imapuid): msg_uid = imapuid.msg_uid handler = DeleteHandler(account_id=default_account.id, namespace_id=default_namespace.id, uid_accessor=lambda m: m.imapuids, message_ttl=0) # Add another message onto the thread add_fake_message(db.session, default_namespace.id, thread) remove_deleted_uids(default_account.id, db.session, [msg_uid], folder.id) handler.check() # Check that the orphaned message was deleted. with pytest.raises(ObjectDeletedError): message.id # Would raise ObjectDeletedError if thread was deleted. thread.id