def test_clean_flags(gm_client, msgs, login): gm_client.add_emails([{}] * 2) local.link_threads(['1', '2']) assert [i['flags'] for i in msgs(local.SRC)] == ['', '', '\\Seen #link'] assert [i['flags'] for i in msgs()] == ['', '#latest', '\\Seen #link'] con_src = local.client(local.SRC, readonly=False) con_all = local.client(local.ALL, readonly=False) con_src.store('3', '-FLAGS', '#link \\Seen') con_src.store('1', '+FLAGS', '#latest') con_src.store('2', '+FLAGS', '#dup') con_all.store('3', '-FLAGS', '#link \\Seen') con_all.store('2', '-FLAGS', '#latest') assert [i['flags'] for i in msgs(local.SRC)] == ['#latest', '#dup', ''] assert [i['flags'] for i in msgs()] == ['', '', ''] local.clean_flags() assert [i['flags'] for i in msgs(local.SRC)] == ['', '', '\\Seen #link'] assert [i['flags'] for i in msgs()] == ['', '#latest', '\\Seen #link'] con_src.store('3', '-FLAGS', '#link \\Seen') con_src.store('2', '+FLAGS', '#err') con_all.store('3', '-FLAGS', '#link \\Seen') con_all.store('2', '-FLAGS', '#latest') assert [i['flags'] for i in msgs(local.SRC)] == ['', '#err', ''] assert [i['flags'] for i in msgs()] == ['', '', ''] cli.main('clean-flags %s' % login.user1) assert [i['flags'] for i in msgs(local.SRC)] == ['', '', '\\Seen #link'] assert [i['flags'] for i in msgs()] == ['', '#latest', '\\Seen #link']
def _msgs(box=None, uids='1:*', *, parsed=False, raw=False): from mailur import local def flags(m): res = re.search('FLAGS \(([^)]*)\)', m).group(1).split() if '\\Recent' in res: res.remove('\\Recent') return ' '.join(res) def msg(res): msg = { 'uid': re.search('UID (\d+)', res[0].decode()).group(1), 'flags': flags(res[0].decode()), 'body': res[1] if raw else email.message_from_bytes(res[1]) } if parsed: parts = email.message_from_bytes(res[1]).get_payload() msg['meta'] = json.loads(parts[0].get_payload()) msg['body'] = parts[1].get_payload() return msg con = local.client(box or local.ALL) res = con.fetch(uids, '(uid flags body[])') return [msg(res[i]) for i in range(0, len(res), 2)]
def test_idle(): def handler(): raise ValueError con = local.client() # just check if timeout works assert not con.idle(handler, timeout=1)
def test_multiappend(patch, msgs): new = [ (None, None, message.binary(str(i)).as_bytes()) for i in range(0, 10) ] con = local.client(None) with patch('gevent.pool.Pool.spawn') as m: m.return_value.value = '' con.multiappend(local.SRC, new) assert not m.called assert len(msgs(local.SRC)) == 10 con.multiappend(local.SRC, new, batch=3) assert m.called assert m.call_count assert m.call_args_list[0][0][2] == new[0:3] assert m.call_args_list[1][0][2] == new[3:6] assert m.call_args_list[2][0][2] == new[6:9] assert m.call_args_list[3][0][2] == new[9:] m.reset_mock() con.multiappend(local.SRC, new, batch=5) assert m.called assert m.call_count assert m.call_args_list[0][0][2] == new[0:5] assert m.call_args_list[1][0][2] == new[5:] con.multiappend(local.SRC, new, batch=3) assert len(msgs(local.SRC)) == 20
def test_batched_uids(gm_client): con = local.client() bsize = 25000 assert [] == con.fetch([str(i) for i in range(1, 100, 2)], 'FLAGS') assert [] == con.fetch([str(i) for i in range(1, bsize, 2)], 'FLAGS') con.select(local.ALL, readonly=False) assert [] == con.store([str(i) for i in range(1, 100, 2)], '+FLAGS', '#') assert [] == con.store([str(i) for i in range(1, bsize, 2)], '+FLAGS', '#') # with one message msg = message.binary('42') msg.add_header('Message-Id', message.gen_msgid()) con.append(local.SRC, None, None, msg.as_bytes()) con.select(local.SRC, readonly=True) assert [b'1 (UID 1 FLAGS (\\Recent))'] == ( con.fetch([str(i) for i in range(1, 100, 2)], 'FLAGS') ) assert [b'1 (UID 1 FLAGS (\\Recent))'] == ( con.fetch([str(i) for i in range(1, bsize, 2)], 'FLAGS') ) con.select(local.SRC, readonly=False) assert [b'1 (UID 1 FLAGS (\\Recent #1))'] == ( con.store([str(i) for i in range(1, 100, 2)], '+FLAGS', '#1') ) assert [b'1 (UID 1 FLAGS (\\Recent #1 #2))'] == ( con.store([str(i) for i in range(1, bsize, 2)], '+FLAGS', '#2') ) gm_client.add_emails([{} for i in range(1, 22)], parse=False) assert local.parse(batch=10) is None
def test_batched_uids(gm_client): con = local.client() bsize = 25000 assert [] == con.fetch([str(i) for i in range(1, 100, 2)], 'FLAGS') assert [] == con.fetch([str(i) for i in range(1, bsize, 2)], 'FLAGS') con.select(local.ALL, readonly=False) assert [] == con.store([str(i) for i in range(1, 100, 2)], '+FLAGS', '#') assert [] == con.store([str(i) for i in range(1, bsize, 2)], '+FLAGS', '#') # with one message msg = message.binary('42') msg.add_header('Message-Id', message.gen_msgid()) con.append(local.SRC, None, None, msg.as_bytes()) con.select(local.SRC, readonly=True) assert [b'1 (UID 1 FLAGS (\\Recent))' ] == (con.fetch([str(i) for i in range(1, 100, 2)], 'FLAGS')) assert [b'1 (UID 1 FLAGS (\\Recent))' ] == (con.fetch([str(i) for i in range(1, bsize, 2)], 'FLAGS')) con.select(local.SRC, readonly=False) assert [b'1 (UID 1 FLAGS (\\Recent #1))' ] == (con.store([str(i) for i in range(1, 100, 2)], '+FLAGS', '#1')) assert [b'1 (UID 1 FLAGS (\\Recent #1 #2))' ] == (con.store([str(i) for i in range(1, bsize, 2)], '+FLAGS', '#2')) gm_client.add_emails([{} for i in range(1, 22)], parse=False) assert local.parse(batch=10) is None
def test_multiappend(patch, msgs): new = [(None, None, message.binary(str(i)).as_bytes()) for i in range(0, 10)] con = local.client(None) with patch('gevent.pool.Pool.spawn') as m: m.return_value.value = '' con.multiappend(local.SRC, new) assert not m.called assert len(msgs(local.SRC)) == 10 con.multiappend(local.SRC, new, batch=3) assert m.called assert m.call_count assert m.call_args_list[0][0][2] == new[0:3] assert m.call_args_list[1][0][2] == new[3:6] assert m.call_args_list[2][0][2] == new[6:9] assert m.call_args_list[3][0][2] == new[9:] m.reset_mock() con.multiappend(local.SRC, new, batch=5) assert m.called assert m.call_count assert m.call_args_list[0][0][2] == new[0:5] assert m.call_args_list[1][0][2] == new[5:] con.multiappend(local.SRC, new, batch=3) assert len(msgs(local.SRC)) == 20
def test_general(gm_client, login, msgs, patch, call): stdout = check_output('mlr -h', shell=True) assert b'Mailur CLI' in stdout gm_client.add_emails([{}, {}], fetch=False, parse=False) assert [i['uid'] for i in msgs(local.SRC)] == [] assert [i['uid'] for i in msgs()] == [] cli.main('%s remote --parse' % login.user1) assert [i['uid'] for i in msgs(local.SRC)] == ['1', '2'] assert [i['uid'] for i in msgs()] == ['1', '2'] with patch('mailur.cli.local') as m: cli.main('%s metadata' % login.user1) assert m.update_metadata.called cli.main('%s metadata' % login.user1) with local.client() as con: con.copy(['1', '2'], local.ALL) puids = con.search('ALL') con.select(local.SRC) ouids = con.search('ALL') assert len(puids) == (2 * len(ouids)) cli.main('%s metadata' % login.user1) con.select(local.ALL) all_puids = con.search('ALL') assert len(all_puids) == 4 local.link_threads(ouids) cli.main('%s parse --fix-duplicates' % login.user1) cli.main('%s metadata' % login.user1) con.select(local.ALL) puids = con.search('ALL') con.select(local.SRC) ouids = con.search('ALL') assert len(puids) == len(ouids) puids_from_msgs = sorted(local.data_msgs.get()) puids_from_pairs = sorted(local.data_uidpairs.get().values()) assert puids_from_msgs == puids_from_pairs with patch('mailur.cli.remote.fetch_folder') as m: cli.main('%s remote' % login.user1) opts = {'batch': 1000, 'threads': 2} assert m.call_args_list == [ call(tag='\\All', **opts), call(tag='\\Junk', **opts), call(tag='\\Trash', **opts), ] m.reset_mock() cli.main('%s remote --tag=\\All' % login.user1) assert m.call_args_list == [call(tag='\\All', **opts)] m.reset_mock() cli.main('%s remote --box=All' % login.user1) assert m.call_args_list == [call(box='All', **opts)]
def test_cli_all_flags(gm_client, msgs, login): gm_client.add_emails([{}] * 5) assert [i['flags'] for i in msgs(local.SRC)] == [''] * 5 assert [i['flags'] for i in msgs()] == [''] * 5 con_src = local.client(local.SRC, readonly=False) con_all = local.client(local.ALL, readonly=False) con_src.store('1:*', '+FLAGS', '#1') con_all.store('1:*', '+FLAGS', '#2') cli.main('sync-flags %s' % login.user1) assert [i['flags'] for i in msgs(local.SRC)] == ['#1'] * 5 assert [i['flags'] for i in msgs()] == ['#1'] * 5 con_src.store('1:*', '+FLAGS', '#2') con_all.store('1:*', '+FLAGS', '#3') cli.main('sync-flags %s --reverse' % login.user1) assert [i['flags'] for i in msgs(local.SRC)] == ['#1 #3'] * 5 assert [i['flags'] for i in msgs()] == ['#1 #3'] * 5
def test_idle(): def handler(res): if handler.first: handler.first = False return raise ValueError handler.first = True con = local.client() # just check if timeout works assert not con.idle({'EXISTS': handler}, timeout=1)
def test_sieve(gm_client, msgs, raises, some): gm_client.add_emails([{ 'from': '"A" <*****@*****.**>' }, { 'from': '"B" <*****@*****.**>' }]) con = local.client(readonly=False) with raises(imap.Error) as e: res = con.sieve('ALL', 'addflag "#0";') assert e.value.args == (some, ) assert some.value.startswith(b'script: line 1: error: unknown command') res = con.sieve( 'ALL', ''' require ["imap4flags"]; if header :contains "Subject" "Subj" { setflag "#subj"; } ''') assert [m['flags'] for m in msgs()] == ['#subj', '#subj'] res = con.sieve('UID *', 'require ["imap4flags"];addflag "#2";') assert res == [some] assert some.value.endswith(b'UID 2 OK') assert [m['flags'] for m in msgs()] == ['#subj', '#subj #2'] res = con.sieve('UID 3', 'require ["imap4flags"];addflag "#2";') assert res == [] assert [m['flags'] for m in msgs()] == ['#subj', '#subj #2'] res = con.sieve( 'ALL', ''' require ["imap4flags"]; if address :is :all "from" "*****@*****.**" { addflag "#1"; } ''') assert res == [some] assert [m['flags'] for m in msgs()] == ['#subj #1', '#subj #2'] res = con.sieve( 'ALL', ''' require ["imap4flags"]; if address :is "from" ["*****@*****.**", "*****@*****.**"] { addflag "#ab"; } ''') assert res == [some, some] assert [m['flags'] for m in msgs()] == ['#subj #1 #ab', '#subj #2 #ab']
def test_literal_size_limit(gm_client, raises): gm_client.add_emails([{} for i in range(0, 20)], parse=False) c = local.client(local.SRC) res = c.search('ALL') uids = res[0].decode().replace(' ', ',') uid = ',1%.127i' % 1 * 8 uids += (uid * 1024 * 9) assert res == c.search('UID %s' % uids) uids += (uid * 1024) with raises(imap.Error) as e: c.search('UID %s' % uids) assert 'Too long argument' in str(e)
def test_literal_size_limit(gm_client, raises): # for query like "UID 1,2,...,150000" should be big enough gm_client.add_emails([{} for i in range(0, 20)], parse=False) c = local.client(local.SRC) all_uids = c.search('ALL') uids = ','.join(str(i) for i in range(1, 150000)) assert all_uids == c.search('UID %s' % uids) uid = ',%i' % (10**6) uids += (uid * 20000) with raises(imap.Error) as e: c.search('UID %s' % uids) assert 'Too long argument' in str(e.value)
def test_literal_size_limit(gm_client, raises): # for query like "UID 1,2,...,150000" should be big enough gm_client.add_emails([{} for i in range(0, 20)], parse=False) c = local.client(local.SRC) all_uids = c.search('ALL') uids = ','.join(str(i) for i in range(1, 150000)) assert all_uids == c.search('UID %s' % uids) uid = ',%i' % (10 ** 6) uids += (uid * 20000) with raises(imap.Error) as e: c.search('UID %s' % uids) assert 'Too long argument' in str(e)
def test_sieve(gm_client, msgs, raises, some): gm_client.add_emails([ {'from': '"A" <*****@*****.**>'}, {'from': '"B" <*****@*****.**>'} ]) con = local.client(readonly=False) with raises(imap.Error) as e: res = con.sieve('ALL', 'addflag "#0";') assert e.value.args == (some,) assert some.value.startswith(b'script: line 1: error: unknown command') res = con.sieve('ALL', ''' require ["imap4flags"]; if header :contains "Subject" "Subj" { setflag "#subj"; } ''') assert [m['flags'] for m in msgs()] == ['#subj', '#subj'] res = con.sieve('UID *', 'require ["imap4flags"];addflag "#2";') assert res == [some] assert some.value.endswith(b'UID 2 OK') assert [m['flags'] for m in msgs()] == ['#subj', '#subj #2'] res = con.sieve('UID 3', 'require ["imap4flags"];addflag "#2";') assert res == [] assert [m['flags'] for m in msgs()] == ['#subj', '#subj #2'] res = con.sieve('ALL', ''' require ["imap4flags"]; if address :is :all "from" "*****@*****.**" { addflag "#1"; } ''') assert res == [some, some] assert [m['flags'] for m in msgs()] == ['#subj #1', '#subj #2'] res = con.sieve('ALL', ''' require ["imap4flags"]; if address :is "from" ["*****@*****.**", "*****@*****.**"] { addflag "#ab"; } ''') assert res == [some, some] assert [m['flags'] for m in msgs()] == ['#subj #1 #ab', '#subj #2 #ab']
def test_clean_flags(gm_client, msgs, login): gm_client.add_emails([{}] * 2) local.link_threads(['1', '2']) assert [i['flags'] for i in msgs(local.SRC)] == ['', ''] assert [i['flags'] for i in msgs()] == ['', ''] con_src = local.client(local.SRC, readonly=False) con_all = local.client(local.ALL, readonly=False) con_src.store('1', '+FLAGS', '#tag1') con_src.store('2', '+FLAGS', '#tag2 #tag3') con_all.store('1', '+FLAGS', '#tag1 #tag3') con_all.store('2', '+FLAGS', '#tag2') assert [i['flags'] for i in msgs(local.SRC)] == ['#tag1', '#tag2 #tag3'] assert [i['flags'] for i in msgs()] == ['#tag1 #tag3', '#tag2'] cli.main('clean-flags %s #tag1' % login.user1) assert [i['flags'] for i in msgs(local.SRC)] == ['', '#tag2 #tag3'] assert [i['flags'] for i in msgs()] == ['#tag3', '#tag2'] cli.main('clean-flags %s #tag2 #tag3' % login.user1) assert [i['flags'] for i in msgs(local.SRC)] == ['', ''] assert [i['flags'] for i in msgs()] == ['', '']
def test_cli_idle(gm_client, msgs, login, patch): spawn(lambda: cli.main('sync %s --timeout=300' % login.user1)) sleep(2) gm_client.add_emails([{}] * 4, fetch=False, parse=False) sleep(2) assert len(msgs(local.SRC)) == 4 assert len(msgs()) == 4 local.parse('all') gm_client.add_emails([{}], fetch=False, parse=False) sleep(2) assert len(msgs(local.SRC)) == 5 assert len(msgs()) == 5 con_src = local.client(local.SRC, readonly=False) con_src.store('1:*', '+FLAGS', '#1') sleep(2) assert [i['flags'] for i in msgs(local.SRC)] == ['#1'] * 5 assert [i['flags'] for i in msgs()] == ['#1'] * 5
def setup(new_users, gm_client, sendmail, patch_conf): from mailur import imap, local, remote global con_local, con_gmail con_local = local.client(None) con_gmail = local.connect(*local.master_login(username=test2)) remote.data_account({ 'username': '******', 'password': '******', 'imap_host': 'imap.gmail.com', 'smtp_host': 'smtp.gmail.com', }) yield con_local.logout() con_gmail.logout() imap.clean_pool(test1) imap.clean_pool(test2)
def test_fetch_and_parse(clean_users, gm_client, some): lm = local.client() gmail.fetch_folder() local.parse() def gm_uidnext(): res = lm.getmetadata(local.SRC, 'gmail/uidnext/all') assert res == [(b'Src (/private/gmail/uidnext/all {12}', some), b')'] return some.value def mlr_uidnext(): res = lm.getmetadata(local.ALL, 'uidnext') assert res == [(b'All (/private/uidnext {1}', some), b')'] return some.value assert gm_uidnext().endswith(b',1') assert lm.getmetadata(local.ALL, 'uidnext') == [b'All (/private/uidnext NIL)'] gm_client.add_emails() assert gm_uidnext().endswith(b',2') assert mlr_uidnext() == b'2' assert lm.select(local.SRC) == [b'1'] assert lm.select(local.ALL) == [b'1'] gm_client.add_emails([{'txt': '1'}, {'txt': '2'}]) assert gm_uidnext().endswith(b',4') assert mlr_uidnext() == b'4' assert lm.select(local.SRC) == [b'3'] assert lm.select(local.ALL) == [b'3'] gmail.fetch_folder() local.parse('all') assert gm_uidnext().endswith(b',4') assert mlr_uidnext() == b'4' assert lm.select(local.SRC) == [b'3'] assert lm.select(local.ALL) == [b'3'] assert lm.status(local.ALL, '(UIDNEXT)') == [b'All (UIDNEXT 7)']
def test_cli_idle(gm_client, msgs, login, patch): with patch('mailur.gmail.get_credentials') as m: m.return_value = login.user2, 'user' spawn(lambda: cli.main('sync %s --timeout=300' % login.user1)) sleep(3) gm_client.add_emails([{}] * 4, fetch=False, parse=False) sleep(2) assert len(msgs(local.SRC)) == 4 assert len(msgs()) == 4 local.parse('all') gm_client.add_emails([{}], fetch=False, parse=False) sleep(1) assert len(msgs(local.SRC)) == 5 assert len(msgs()) == 5 con_src = local.client(local.SRC, readonly=False) con_src.store('1:*', '+FLAGS', '#1') sleep(1) assert [i['flags'] for i in msgs(local.SRC)] == ['#1'] * 5 assert [i['flags'] for i in msgs()] == ['#latest #1'] * 5
def test_fetch_and_parse(gm_client, some, raises): lm = local.client() remote.fetch() local.parse() def gm_uidnext(): account = remote.data_account.get() key = ':'.join((account['imap_host'], account['username'], '\\All')) res = remote.data_uidnext.key(key) assert res return res[1] def mlr_uidnext(): return local.data_uidnext.get() assert gm_uidnext() == 1 assert mlr_uidnext() is None gm_client.add_emails() assert gm_uidnext() == 2 assert mlr_uidnext() == 2 assert lm.select(local.SRC) == [b'1'] assert lm.select(local.ALL) == [b'1'] gm_client.add_emails([{'txt': '1'}, {'txt': '2'}]) assert gm_uidnext() == 4 assert mlr_uidnext() == 4 assert lm.select(local.SRC) == [b'3'] assert lm.select(local.ALL) == [b'3'] remote.fetch() local.parse('all') assert gm_uidnext() == 4 assert mlr_uidnext() == 4 assert lm.select(local.SRC) == [b'3'] assert lm.select(local.ALL) == [b'3'] assert lm.status(local.ALL, '(UIDNEXT)') == [b'mlr/All (UIDNEXT 7)']
def _msgs(box=None, uids='1:*', *, parsed=False, raw=False, policy=None): from mailur import local, message def flags(m): res = re.search('FLAGS \(([^)]*)\)', m).group(1).split() if '\\Recent' in res: res.remove('\\Recent') return ' '.join(res) def msg(res): msg = { 'uid': re.search('UID (\d+)', res[0].decode()).group(1), 'flags': flags(res[0].decode()), } if parsed: body = email.message_from_bytes(res[1], policy=policy) parts = [p.get_payload() for p in body.get_payload()] txt = [p.get_payload() for p in parts[1]] msg['meta'] = json.loads(parts[0]) msg['body'] = txt[0] msg['body_txt'] = txt[1] if len(txt) > 1 else None msg['body_end'] = parts[2] if len(parts) > 2 else None msg['body_full'] = body msg['raw'] = res[1] else: body = res[1] if not raw: body = email.message_from_bytes(res[1], policy=policy) msg['body'] = body return msg policy = policy if policy else message.policy con = local.client(box or local.ALL) res = con.fetch(uids, '(uid flags body[])') return [msg(res[i]) for i in range(0, len(res), 2)]
def test_local(gm_client, msgs): gm_client.add_emails([{}] * 5) assert [i['flags'] for i in msgs(local.SRC)] == [''] * 5 assert [i['flags'] for i in msgs()] == [''] * 5 con_src = local.client(local.SRC, readonly=False) con_all = local.client(local.ALL, readonly=False) con_src.store('1:*', '+FLAGS', '#1') con_all.store('1:*', '+FLAGS', '#2') local.sync_flags_to_all() assert [i['flags'] for i in msgs(local.SRC)] == ['#1'] * 5 assert [i['flags'] for i in msgs()] == ['#1'] * 5 con_src.store('1,2', '+FLAGS', '#2') con_all.store('2,3', '+FLAGS', '#3') local.sync_flags_to_all() assert [i['flags'] for i in msgs(local.SRC)] == ['#1 #2', '#1 #2', '#1', '#1', '#1'] assert [i['flags'] for i in msgs()] == ['#2 #1', '#2 #1', '#1', '#1', '#1'] con_all.store('1:*', '-FLAGS', '#1 #2') con_all.store('1:*', '+FLAGS', '#3') local.sync_flags_to_src() assert [i['flags'] for i in msgs(local.SRC)] == ['#3'] * 5 assert [i['flags'] for i in msgs()] == ['#3'] * 5 con_src.store('1,2', '+FLAGS', '#2') con_all.store('2,3', '+FLAGS', '#4') local.sync_flags_to_src() assert [i['flags'] for i in msgs(local.SRC)] == ['#3', '#3 #4', '#3 #4', '#3', '#3'] assert [i['flags'] for i in msgs()] == ['#3', '#3 #4', '#3 #4', '#3', '#3'] con_all.store('1:*', '-FLAGS', '#3 #4') local.sync_flags_to_src() assert [i['flags'] for i in msgs(local.SRC)] == [''] * 5 assert [i['flags'] for i in msgs()] == [''] * 5 local.sync_flags_to_src() con_all.store('1:*', '+FLAGS', '#err') assert [i['flags'] for i in msgs(local.SRC)] == [''] * 5 assert [i['flags'] for i in msgs()] == ['#err'] * 5 con_src.store('1:*', '+FLAGS', '#err') con_all.store('1:*', '-FLAGS', '#err') local.sync_flags_to_all() assert [i['flags'] for i in msgs(local.SRC)] == ['#err'] * 5 assert [i['flags'] for i in msgs()] == [''] * 5 con_src.store('1:*', '-FLAGS', '#err') assert [i['flags'] for i in msgs(local.SRC)] == [''] * 5 assert [i['flags'] for i in msgs()] == [''] * 5 # idle spawn(local.sync_flags) sleep(1) con_src.store('1:*', '+FLAGS', '#1') for i in range(2, 6): con_src.store('%s' % i, '+FLAGS', '#%s' % i) sleep(1) assert [i['flags'] for i in msgs(local.SRC) ] == ['#1', '#1 #2', '#1 #3', '#1 #4', '#1 #5'] assert [i['flags'] for i in msgs()] == ['#1', '#2 #1', '#1 #3', '#1 #4', '#1 #5']
def thread(box=local.SRC, criteria='ALL'): with local.client(box) as con: return con.thread('REFS UTF-8 %s' % criteria)
def test_update_threads(clean_users, gm_client, msgs): gm_client.add_emails([{}]) res = msgs() assert ['#latest'] == [i['flags'] for i in res] local.parse('all') res = msgs() assert ['#latest'] == [i['flags'] for i in res] gm_client.add_emails([{}]) res = msgs() assert ['#latest', '#latest'] == [i['flags'] for i in res] gm_client.add_emails([{'in_reply_to': '<101@mlr>'}]) res = msgs() assert ['', '#latest', '#latest'] == [i['flags'] for i in res] gm_client.add_emails([{'refs': '<101@mlr> <102@mlr>'}]) res = msgs() assert ['', '', '', '#latest'] == [i['flags'] for i in res] local.parse('all') res = msgs() assert ['', '', '', '#latest'] == [i['flags'] for i in res] local.parse('uid *') res = msgs() assert ['', '', '', '#latest'] == [i['flags'] for i in res] con = local.client() local.update_threads(con, 'all') res = msgs() assert ['', '', '', '#latest'] == [i['flags'] for i in res] local.update_threads(con, 'UID 1') res = msgs() assert ['', '', '', '#latest'] == [i['flags'] for i in res] local.update_threads(con) res = msgs() assert ['', '', '', '#latest'] == [i['flags'] for i in res] gm_client.add_emails([{ 'refs': '<non-exist@mlr>' }, { 'refs': '<non-exist@mlr> <101@mlr>' }]) res = msgs() assert [i['flags'] for i in res] == ['', '', '', '', '#latest', '#latest'] gm_client.add_emails([{'labels': 't1'}, {'labels': 't2'}], parse=False) local.parse('UID 6:*') res = msgs() assert [i['flags'] for i in res] == [ '', '', '', '', '#latest', '#latest', '#latest t1', '#latest t2' ] local.update_threads(con, 'UID *') res = msgs() assert [i['flags'] for i in res] == [ '', '', '', '', '#latest', '#latest', '#latest t1', '#latest t2' ]
def test_local(gm_client, msgs): gm_client.add_emails([{}] * 5) assert [i['flags'] for i in msgs(local.SRC)] == [''] * 5 assert [i['flags'] for i in msgs()] == [''] * 5 con_src = local.client(local.SRC, readonly=False) con_all = local.client(local.ALL, readonly=False) con_src.store('1:*', '+FLAGS', '#1') con_all.store('1:*', '+FLAGS', '#2') local.sync_flags_to_all() assert [i['flags'] for i in msgs(local.SRC)] == ['#1'] * 5 assert [i['flags'] for i in msgs()] == ['#1'] * 5 con_src.store('1,2', '+FLAGS', '#2') con_all.store('2,3', '+FLAGS', '#3') local.sync_flags_to_all() assert [i['flags'] for i in msgs(local.SRC)] == [ '#1 #2', '#1 #2', '#1', '#1', '#1' ] assert [i['flags'] for i in msgs()] == [ '#2 #1', '#2 #1', '#1', '#1', '#1' ] con_all.store('1:*', '-FLAGS', '#1 #2') con_all.store('1:*', '+FLAGS', '#3') local.sync_flags_to_src() assert [i['flags'] for i in msgs(local.SRC)] == ['#3'] * 5 assert [i['flags'] for i in msgs()] == ['#3'] * 5 con_src.store('1,2', '+FLAGS', '#2') con_all.store('2,3', '+FLAGS', '#4') local.sync_flags_to_src() assert [i['flags'] for i in msgs(local.SRC)] == [ '#3', '#3 #4', '#3 #4', '#3', '#3' ] assert [i['flags'] for i in msgs()] == [ '#3', '#3 #4', '#3 #4', '#3', '#3' ] con_all.store('1:*', '-FLAGS', '#3 #4') local.sync_flags_to_src() assert [i['flags'] for i in msgs(local.SRC)] == [''] * 5 assert [i['flags'] for i in msgs()] == [''] * 5 local.sync_flags_to_src() con_all.store('1:*', '+FLAGS', '#err') assert [i['flags'] for i in msgs(local.SRC)] == [''] * 5 assert [i['flags'] for i in msgs()] == ['#err'] * 5 con_src.store('1:*', '+FLAGS', '#err') con_all.store('1:*', '-FLAGS', '#err') local.sync_flags_to_all() assert [i['flags'] for i in msgs(local.SRC)] == ['#err'] * 5 assert [i['flags'] for i in msgs()] == [''] * 5 con_src.store('1:*', '-FLAGS', '#err') assert [i['flags'] for i in msgs(local.SRC)] == [''] * 5 assert [i['flags'] for i in msgs()] == [''] * 5 # idle spawn(local.sync_flags) sleep(1) con_src.store('1:*', '+FLAGS', '#1') for i in range(2, 6): con_src.store('%s' % i, '+FLAGS', '#%s' % i) sleep(1) assert [i['flags'] for i in msgs(local.SRC)] == [ '#1', '#1 #2', '#1 #3', '#1 #4', '#1 #5' ] assert [i['flags'] for i in msgs()] == [ '#1', '#2 #1', '#1 #3', '#1 #4', '#1 #5' ]
def thread(box=local.SRC): with local.client(box) as con: return con.thread('REFS UTF-8 ALL')
def test_cli_idle_gmail(gm_client, msgs, login, patch): actions = [] def fetch(con, uids, fields): responces = getattr(gm_client, 'fetch', None) if 'CHANGEDSINCE' in fields: index = fields.split()[-1] if index == '5)': return ('OK', [ b'4 (X-GM-MSGID 10400 ' b'X-GM-LABELS ("\\Inbox" "\\Starred" "mlr/thrid/777") ' b'FLAGS (\\Seen) UID 104 MODSEQ (427368))' ]) return ('OK', []) elif responces: return responces.pop() elif 'X-GM-LABELS' in fields: if con.current_box != local.SRC: return ('OK', [ b'1 (X-GM-MSGID 10100 X-GM-LABELS () ' b'FLAGS (\\Seen) UID 101 MODSEQ (427368))' ]) return ('OK', [ (b'2 (X-GM-MSGID 10200 X-GM-LABELS () ' b'FLAGS (\\Seen) UID 102 MODSEQ (427368))'), (b'3 (X-GM-MSGID 10300 X-GM-LABELS () ' b'FLAGS (\\Seen) UID 103 MODSEQ (427368))'), (b'4 (X-GM-MSGID 10400 X-GM-LABELS () ' b'FLAGS (\\Seen) UID 104 MODSEQ (427368))'), (b'6 (X-GM-MSGID 10600 X-GM-LABELS (\\Draft) ' b'FLAGS (\\Seen) UID 106 MODSEQ (427368))'), ]) return con._uid('FETCH', uids, fields) def search(con, charset, *criteria): if 'X-GM-MSGID' in criteria[0]: uid = int(criteria[0].split()[-1]) // 100 return ('OK', [(b'%d' % uid)]) return con._uid('SEARCH', charset, *criteria) def store(con, uids, cmd, flags): if 'X-GM-LABELS' in cmd: actions.append((uids, cmd, sorted(flags.split()))) return ('OK', []) return con._uid('STORE', uids, cmd, flags) gm_client.fake_fetch = fetch gm_client.fake_search = search gm_client.fake_store = store spawn(lambda: cli.main('%s sync --timeout=300' % login.user1)) sleep(5) gm_client.add_emails([{}] * 4, fetch=False, parse=False) sleep(3) assert len(msgs(local.SRC)) == 4 assert len(msgs()) == 4 local.parse('all') gm_client.add_emails([{}], fetch=False, parse=False) sleep(3) assert len(msgs(local.SRC)) == 5 assert len(msgs()) == 5 expected_flags = ['', '', '', '\\Flagged \\Seen #inbox', ''] assert [i['flags'] for i in msgs(local.SRC)] == expected_flags assert [i['flags'] for i in msgs()] == expected_flags con_src = local.client(local.SRC, readonly=False) con_src.store('1:*', '+FLAGS', '#1') sleep(3) expected_flags = [(f + ' #1').strip() for f in expected_flags] assert [i['flags'] for i in msgs(local.SRC)] == expected_flags assert [i['flags'] for i in msgs()] == expected_flags assert actions == [ ('101', '-X-GM-LABELS', ['\\Spam']), ('101', '+X-GM-LABELS', ['\\Inbox']), # move to \\All ('101', '-X-GM-LABELS', ['\\Trash']), ('101', '+X-GM-LABELS', ['\\Inbox']), # move to \\All ('104', '+X-GM-LABELS', ['\\Inbox', '\\Starred']), ('104', '+X-GM-LABELS', ['\\Inbox', '\\Starred']), ('101', '-X-GM-LABELS', ['\\Spam']), ('101', '+X-GM-LABELS', ['\\Inbox']), # move to \\All ('101', '-X-GM-LABELS', ['\\Trash']), ('101', '+X-GM-LABELS', ['\\Inbox']), # move to \\All ] actions.clear() con_src = local.client(local.SRC, readonly=False) con_src.store('2', '+FLAGS', '#inbox') sleep(3) con_src.store('2', '+FLAGS', '#trash') sleep(3) expected_flags[1] = '#inbox #1 #trash' assert [i['flags'] for i in msgs(local.SRC)] == expected_flags assert [i['flags'] for i in msgs()] == expected_flags assert actions == [ ('102', '+X-GM-LABELS', ['\\Inbox']), ('102', '-X-GM-LABELS', ['\\Inbox']), ('102', '+X-GM-LABELS', ['\\Trash']), ]