class DBSMSManager(object): """ SMS manager for DB stored messages """ def __init__(self, path=MESSAGES_DB): super(DBSMSManager, self).__init__() if not exists(path): self.provider = SmsProvider(path) for f in KNOWN_FOLDERS: self.provider.add_folder(f) else: self.provider = SmsProvider(path) def close(self): self.provider.close() def add_message(self, sms, where=None): if not where: folder = KNOWN_FOLDERS[0] else: folder = KNOWN_FOLDERS[where - 1] msg = DBMessage(sms.number, sms.text, _datetime=sms.datetime) self.provider.add_sms(msg, folder=folder) return msg def add_messages(self, sms_list, where=None): return [self.add_message(sms, where) for sms in sms_list] def delete_message(self, sms): # we should delete the containing thread if it's empty self.provider.delete_sms(sms) def get_messages(self): ret = [] for i in range(3): folder = KNOWN_FOLDERS[i] tab = i + 1 for thread in self.provider.list_from_folder(folder): msgs = list(self.provider.list_from_thread(thread)) for msg in msgs: msg.where = tab ret.extend(msgs) return ret
class TestSmsProvider(unittest.TestCase): """Tests for SmsProvider""" def setUp(self): self.provider = SmsProvider(':memory:') self.provider.add_folder(inbox_folder) self.provider.add_folder(outbox_folder) self.provider.add_folder(drafts_folder) def tearDown(self): self.provider.close() def test_add_folder(self): # add a folder and make sure it is there folder = self.provider.add_folder(Folder("Test")) self.assertIn(folder, list(self.provider.list_folders())) # leave everything as found self.provider.delete_folder(folder) self.assertNotIn(folder, list(self.provider.list_folders())) def test_add_sms(self): sms = Message('+3243243223', 'hey how are you?', _datetime=get_tz_aware_now()) sms = self.provider.add_sms(sms) self.assertIn(sms, list(self.provider.list_sms())) # leave everything as found self.provider.delete_sms(sms) self.assertNotIn(sms, list(self.provider.list_sms())) def test_sms_time_storage(self): zones = ['Europe/London', # UTC+0(without DST), UTC+1(with DST) 'Europe/Paris', # UTC+1(without DST), UTC+2(with DST) 'Asia/Jakarta'] # UTC+7(no DST adjustment in 2010) for tzstring in zones: tz = timezone(tzstring) # db resolution is secs now = datetime.now(tz).replace(microsecond=0) sms = Message('+447917267410', tzstring, _datetime=now) sms = self.provider.add_sms(sms) for dbsms in self.provider.list_sms(): if dbsms.text == tzstring: break dbnow = dbsms.datetime.astimezone(tz) self.assertEqual(now, dbnow) # leave everything as found self.provider.delete_sms(sms) self.assertNotIn(sms, list(self.provider.list_sms())) def test_delete_folder(self): # add a folder and make sure it is there folder = self.provider.add_folder(Folder("Test 2")) self.assertIn(folder, list(self.provider.list_folders())) # delete the folder and make sure its gone self.provider.delete_folder(folder) self.assertNotIn(folder, list(self.provider.list_folders())) def test_delete_undeleteable_folder(self): # trying to delete an undeleteable folder shall raise DBError self.assertIn(inbox_folder, list(self.provider.list_folders())) self.assertRaises(DBError, self.provider.delete_folder, inbox_folder) def test_delete_folder_with_threads_attached(self): # add a folder folder = self.provider.add_folder(Folder("Test 2")) self.assertIn(folder, list(self.provider.list_folders())) # attach a couple of threads to the folder t1 = self.provider.add_thread( Thread(get_tz_aware_now(), '+322323233', index=5, folder=folder)) t2 = self.provider.add_thread( Thread(get_tz_aware_now(), '+322323233', index=6, folder=folder)) # make sure they appear self.assertIn(t1, list(self.provider.list_threads())) self.assertIn(t2, list(self.provider.list_threads())) # delete the folder and threads should be gone self.provider.delete_folder(folder) self.assertNotIn(folder, list(self.provider.list_folders())) self.assertNotIn(t1, list(self.provider.list_threads())) self.assertNotIn(t2, list(self.provider.list_threads())) def test_delete_thread(self): # add a thread to inbox and make sure its there t = self.provider.add_thread( Thread(get_tz_aware_now(), '+3443545333', index=3, folder=inbox_folder)) self.assertIn(t, list(self.provider.list_threads())) # delete it and make sure its gone self.provider.delete_thread(t) self.assertNotIn(t, list(self.provider.list_threads())) def test_delete_thread_with_sms_attached(self): # add a thread to inbox t = self.provider.add_thread( Thread(get_tz_aware_now(), '+3443545332', folder=inbox_folder)) # add a message attached to that thread and make sure its present sms = self.provider.add_sms( Message(number='+3443545332', text='how is it going then?', _datetime=get_tz_aware_now(), thread=t)) self.assertIn(sms, list(self.provider.list_sms())) # delete the thread and both the thread and SMS should be gone self.provider.delete_thread(t) self.assertNotIn(sms, list(self.provider.list_sms())) def test_delete_sms(self): # add a thread to inbox t = self.provider.add_thread( Thread(get_tz_aware_now(), '+3443545333', folder=inbox_folder)) # add a message attached to that thread and make sure its present sms = self.provider.add_sms( Message(number='+3443545333', text='how is it going then?', _datetime=get_tz_aware_now(), thread=t)) self.assertIn(sms, list(self.provider.list_sms())) # delete it and make sure its gone self.provider.delete_sms(sms) self.assertNotIn(sms, list(self.provider.list_sms())) # leave it as we found it self.provider.delete_thread(t) def test_list_folders(self): folders = list(self.provider.list_folders()) for folder in [inbox_folder, outbox_folder, drafts_folder]: self.assertIn(folder, folders) def test_list_from_folder(self): # add a folder and attach a thread to it folder = self.provider.add_folder(Folder("Test 3")) t = self.provider.add_thread( Thread(get_tz_aware_now(), '+3443545333', folder=folder)) # add a thread attached to inbox t2 = self.provider.add_thread( Thread(get_tz_aware_now(), '+3443545333', folder=inbox_folder)) # t should be present in threads, but not t2 threads = list(self.provider.list_from_folder(folder)) self.assertIn(t, threads) self.assertNotIn(t2, threads) # leave it as we found it self.provider.delete_folder(folder) self.provider.delete_thread(t2) def test_list_from_folder_and_the_results_order(self): """test that list_from_folder returns a correctly ordered result""" now = get_tz_aware_now() five_min_ago = now - timedelta(minutes=5) # add a couple of threads to inbox_folder, one of them # just got updated/created and the other five minuts ago t = self.provider.add_thread( Thread(now, '+3443545333', folder=inbox_folder)) t2 = self.provider.add_thread( Thread(five_min_ago, '+3443545331', folder=inbox_folder)) # if we list from inbox, t should appear before t2 threads = list(self.provider.list_from_folder(inbox_folder)) self.assertEqual(threads[0], t) self.assertEqual(threads[1], t2) # leave it as we found it self.provider.delete_thread(t) self.provider.delete_thread(t2) def test_list_from_thread(self): """test for list_from_thread""" t = self.provider.add_thread( Thread(get_tz_aware_now(), '+3443545333', folder=inbox_folder)) sms1 = self.provider.add_sms( Message(number='+3443545333', text='test_list_from_thread sms1', _datetime=get_tz_aware_now(), thread=t)) sms2 = self.provider.add_sms( Message(number='+3443545333', text='test_list_from_thread sms2', _datetime=get_tz_aware_now(), thread=t)) # sms1 and sms2 should be present in messages messages = list(self.provider.list_from_thread(t)) self.assertIn(sms1, messages) self.assertIn(sms2, messages) # leave it as we found it self.provider.delete_thread(t) def test_list_from_thread_and_the_results_order(self): """test that list_from_thread returns a correctly ordered result""" number = '+3443545333' now = get_tz_aware_now() five_min_ago = now - timedelta(minutes=5) # add a thread and attach two messages to it, one just sent # and the other is five minutes older t = self.provider.add_thread( Thread(now, number, folder=inbox_folder)) sms1 = self.provider.add_sms( Message(number=number, text='test_list_from_thread sms1', _datetime=now, thread=t)) sms2 = self.provider.add_sms( Message(number=number, text='test_list_from_thread sms2', _datetime=five_min_ago, thread=t)) # sms1 and sms2 should be present in messages messages = list(self.provider.list_from_thread(t)) self.assertEqual(messages[0], sms1) self.assertEqual(messages[1], sms2) # leave it as we found it self.provider.delete_thread(t) def test_list_sms(self): # add a thread to inbox and attach a couple of messages to it t = self.provider.add_thread( Thread(get_tz_aware_now(), '+3443545333', folder=inbox_folder)) sms1 = self.provider.add_sms( Message(number='+3443545333', text='test_list_sms', _datetime=get_tz_aware_now(), thread=t)) sms2 = self.provider.add_sms( Message(number='+3443545333', text='test_list_sms', _datetime=get_tz_aware_now(), thread=t)) # sms1 and sms2 should be present in messages messages = list(self.provider.list_sms()) self.assertIn(sms1, messages) self.assertIn(sms2, messages) # leave it as we found it self.provider.delete_thread(t) def test_list_threads(self): # add two threads to the inbox folder t1 = self.provider.add_thread( Thread(get_tz_aware_now(), '+3643445333', folder=inbox_folder)) t2 = self.provider.add_thread( Thread(get_tz_aware_now(), '+3443545333', folder=inbox_folder)) # make sure they are present if we list them threads = list(self.provider.list_threads()) self.assertIn(t1, threads) self.assertIn(t2, threads) # leave it as we found it self.provider.delete_thread(t1) self.provider.delete_thread(t2) def test_move_thread_from_folder_to_folder(self): # add a thread to inbox_folder and check its present t1 = self.provider.add_thread( Thread(get_tz_aware_now(), '+3643445333', folder=inbox_folder)) threads = list(self.provider.list_from_folder(inbox_folder)) self.assertIn(t1, threads) # create a new folder, move t1 to it and check its there folder = self.provider.add_folder(Folder("Test 4")) self.provider.move_to_folder(t1, folder) threads = list(self.provider.list_from_folder(folder)) self.assertIn(t1, threads) self.provider.delete_folder(folder) # leave it as we found it threads = list(self.provider.list_threads()) self.assertNotIn(t1, threads) def test_move_sms_from_folder_to_folder(self): # add a thread to inbox_folder t = self.provider.add_thread( Thread(get_tz_aware_now(), '+3643445333', folder=inbox_folder)) # add two sms to t1 sms1 = self.provider.add_sms( Message(number='+3443545333', text='test_list_sms', _datetime=get_tz_aware_now(), thread=t)) sms2 = self.provider.add_sms( Message(number='+3443545333', text='test_list_sms 2', _datetime=get_tz_aware_now(), thread=t)) # sms1 and sms2 should be present in thread messages = list(self.provider.list_from_thread(t)) self.assertIn(sms1, messages) self.assertIn(sms2, messages) # now create a new folder and move sms2 there folder = self.provider.add_folder(Folder("Test 6")) self.provider.move_to_folder(sms2, folder) # now only sms1 should be present in original thread inbox_messages = list(self.provider.list_from_thread(t)) new_thread = list(self.provider.list_from_folder(folder))[0] folder_messages = list(self.provider.list_from_thread(new_thread)) self.assertIn(sms1, inbox_messages) self.assertNotIn(sms2, inbox_messages) # and sms2 should be present in folder_messages self.assertIn(sms2, folder_messages) self.assertNotIn(sms1, folder_messages) # leave it as we found it self.provider.delete_folder(folder) self.provider.delete_thread(t) def test_update_sms_flags(self): """test that update_sms_flags works as expected""" # add a thread to inbox_folder number = '+3243242323' t = self.provider.add_thread( Thread(get_tz_aware_now(), number, folder=inbox_folder)) # add one sms to t1 sms1 = self.provider.add_sms( Message(number=number, text='test_update_sms_flags', _datetime=get_tz_aware_now(), thread=t)) self.assertEqual(sms1.flags, READ) # now mark sms1 as unread sms1 = self.provider.update_sms_flags(sms1, UNREAD) self.assertEqual(sms1.flags, UNREAD) # leave it as we found it self.provider.delete_thread(t)