package com.fsck.k9.provider;
import java.util.Arrays;
import java.util.Collections;
import java.util.GregorianCalendar;
import android.database.Cursor;
import android.database.SQLException;
import android.net.Uri;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import android.test.ProviderTestCase2;
import com.fsck.k9.Account;
import com.fsck.k9.Preferences;
import com.fsck.k9.mail.Message;
import com.fsck.k9.mail.MessagingException;
import com.fsck.k9.mail.internet.MimeMessage;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@RunWith(AndroidJUnit4.class)
public class EmailProviderTest extends ProviderTestCase2<EmailProvider> {
private MimeMessage message;
private MimeMessage laterMessage;
private MimeMessage reply;
private MimeMessage replyAtSameTime;
public EmailProviderTest() {
super(EmailProvider.class, EmailProvider.AUTHORITY);
}
private void buildMessages() throws MessagingException {
message = new MimeMessage();
message.setSubject("Test Subject");
message.setSentDate(new GregorianCalendar(2016, 1, 2).getTime(), false);
message.setMessageId("<uid001@email.com>");
laterMessage = new MimeMessage();
laterMessage.setSubject("Test Subject2");
laterMessage.setSentDate(new GregorianCalendar(2016, 1, 3).getTime(), false);
reply = new MimeMessage();
reply.setSubject("Re: Test Subject");
reply.setSentDate(new GregorianCalendar(2016, 1, 3).getTime(), false);
reply.setMessageId("<uid002@email.com>");
reply.setInReplyTo("<uid001@email.com>");
replyAtSameTime = new MimeMessage();
replyAtSameTime.setSubject("Re: Test Subject");
replyAtSameTime.setSentDate(new GregorianCalendar(2016, 1, 2).getTime(), false);
replyAtSameTime.setMessageId("<uid002@email.com>");
replyAtSameTime.setInReplyTo("<uid001@email.com>");
}
@Before
@Override
public void setUp() throws Exception {
setContext(InstrumentationRegistry.getTargetContext());
super.setUp();
buildMessages();
}
@Test
public void onCreate_shouldReturnTrue() {
assertNotNull(getProvider());
boolean returnValue = getProvider().onCreate();
assertEquals(true, returnValue);
}
@Test(expected = IllegalArgumentException.class)
public void query_withInvalidURI_throwsIllegalArgumentException() {
getProvider().query(
Uri.parse("content://com.google.www"),
new String[] {},
"",
new String[] {},
"");
}
@Test(expected = IllegalArgumentException.class)
public void query_forMessagesWithInvalidAccount_throwsIllegalArgumentException() {
Cursor cursor = getProvider().query(
Uri.parse("content://" + EmailProvider.AUTHORITY + "/account/1/messages"),
new String[] {},
"",
new String[] {},
"");
assertNotNull(cursor);
}
@Test(expected = IllegalArgumentException.class)
public void query_forMessagesWithAccountAndWithoutRequiredFields_throwsIllegalArgumentException() {
Account account = Preferences.getPreferences(getContext()).newAccount();
account.getUuid();
Cursor cursor = getProvider().query(
Uri.parse("content://" + EmailProvider.AUTHORITY + "/account/" + account.getUuid() + "/messages"),
new String[] {},
"",
new String[] {},
"");
assertNotNull(cursor);
assertTrue(cursor.isAfterLast());
}
@Test(expected = SQLException.class) //Handle this better?
public void query_forMessagesWithAccountAndRequiredFieldsWithNoOrderBy_throwsSQLiteException() {
Account account = Preferences.getPreferences(getContext()).newAccount();
account.getUuid();
Cursor cursor = getProvider().query(
Uri.parse("content://" + EmailProvider.AUTHORITY + "/account/" + account.getUuid() + "/messages"),
new String[] {
EmailProvider.MessageColumns.ID,
EmailProvider.MessageColumns.FOLDER_ID,
EmailProvider.ThreadColumns.ROOT
},
"",
new String[] {},
"");
assertNotNull(cursor);
assertTrue(cursor.isAfterLast());
}
@Test
public void query_forMessagesWithEmptyAccountAndRequiredFieldsAndOrderBy_providesEmptyResult() {
Account account = Preferences.getPreferences(getContext()).newAccount();
account.getUuid();
Cursor cursor = getProvider().query(
Uri.parse("content://" + EmailProvider.AUTHORITY + "/account/" + account.getUuid() + "/messages"),
new String[] {
EmailProvider.MessageColumns.ID,
EmailProvider.MessageColumns.FOLDER_ID,
EmailProvider.ThreadColumns.ROOT,
EmailProvider.MessageColumns.SUBJECT
},
"",
new String[] {},
EmailProvider.MessageColumns.DATE);
assertNotNull(cursor);
assertFalse(cursor.moveToFirst());
}
@Test
public void query_forMessagesWithAccountAndRequiredFieldsAndOrderBy_providesResult() throws MessagingException {
Account account = Preferences.getPreferences(getContext()).newAccount();
account.getUuid();
account.getLocalStore().getFolder("Inbox").appendMessages(Collections.singletonList(message));
Cursor cursor = getProvider().query(
Uri.parse("content://" + EmailProvider.AUTHORITY + "/account/" + account.getUuid() + "/messages"),
new String[] {
EmailProvider.MessageColumns.ID,
EmailProvider.MessageColumns.FOLDER_ID,
EmailProvider.ThreadColumns.ROOT,
EmailProvider.MessageColumns.SUBJECT },
"",
new String[] {},
EmailProvider.MessageColumns.DATE);
assertNotNull(cursor);
assertTrue(cursor.moveToFirst());
assertEquals(message.getSubject(), cursor.getString(3));
}
@Test
public void query_forMessagesWithAccountAndRequiredFieldsAndOrderBy_sortsCorrectly() throws MessagingException {
Account account = Preferences.getPreferences(getContext()).newAccount();
account.getUuid();
account.getLocalStore().getFolder("Inbox").appendMessages(Arrays.asList(message, laterMessage));
Cursor cursor = getProvider().query(
Uri.parse("content://" + EmailProvider.AUTHORITY + "/account/" + account.getUuid() + "/messages"),
new String[] {
EmailProvider.MessageColumns.ID,
EmailProvider.MessageColumns.FOLDER_ID,
EmailProvider.ThreadColumns.ROOT,
EmailProvider.MessageColumns.SUBJECT
},
"",
new String[] {},
EmailProvider.MessageColumns.DATE + " DESC");
assertNotNull(cursor);
assertTrue(cursor.moveToFirst());
assertEquals(laterMessage.getSubject(), cursor.getString(3));
cursor.moveToNext();
assertEquals(message.getSubject(), cursor.getString(3));
}
@Test
public void query_forThreadedMessages_sortsCorrectly() throws MessagingException {
Account account = Preferences.getPreferences(getContext()).newAccount();
account.getUuid();
account.getLocalStore().getFolder("Inbox").appendMessages(Arrays.asList(message, laterMessage));
Cursor cursor = getProvider().query(
Uri.parse("content://" + EmailProvider.AUTHORITY + "/account/" + account.getUuid() +
"/messages/threaded"),
new String[] {
EmailProvider.MessageColumns.ID,
EmailProvider.MessageColumns.FOLDER_ID,
EmailProvider.ThreadColumns.ROOT,
EmailProvider.MessageColumns.SUBJECT,
EmailProvider.MessageColumns.DATE
},
"",
new String[] {},
EmailProvider.MessageColumns.DATE + " DESC");
assertNotNull(cursor);
assertTrue(cursor.moveToFirst());
assertEquals(laterMessage.getSubject(), cursor.getString(3));
cursor.moveToNext();
assertEquals(message.getSubject(), cursor.getString(3));
}
@Test
public void query_forThreadedMessages_showsThreadOfEmailOnce() throws MessagingException {
Account account = Preferences.getPreferences(getContext()).newAccount();
account.getUuid();
account.getLocalStore().getFolder("Inbox").appendMessages(Collections.singletonList(message));
account.getLocalStore().getFolder("Inbox").appendMessages(Collections.singletonList(reply));
Cursor cursor = getProvider().query(
Uri.parse("content://" + EmailProvider.AUTHORITY + "/account/" + account.getUuid() +
"/messages/threaded"),
new String[] {
EmailProvider.MessageColumns.ID,
EmailProvider.MessageColumns.FOLDER_ID,
EmailProvider.ThreadColumns.ROOT,
EmailProvider.MessageColumns.SUBJECT,
EmailProvider.MessageColumns.DATE,
EmailProvider.SpecialColumns.THREAD_COUNT
},
"",
new String[] {},
EmailProvider.MessageColumns.DATE + " DESC");
assertNotNull(cursor);
assertTrue(cursor.moveToFirst());
assertEquals(2, cursor.getInt(5));
assertFalse(cursor.moveToNext());
}
@Test
public void query_forThreadedMessages_showsThreadOfEmailWithSameSendTimeOnce() throws MessagingException {
Account account = Preferences.getPreferences(getContext()).newAccount();
account.getUuid();
account.getLocalStore().getFolder("Inbox").appendMessages(Collections.singletonList(message));
account.getLocalStore().getFolder("Inbox").appendMessages(Collections.singletonList(replyAtSameTime));
Cursor cursor = getProvider().query(
Uri.parse("content://" + EmailProvider.AUTHORITY + "/account/" + account.getUuid() +
"/messages/threaded"),
new String[] {
EmailProvider.MessageColumns.ID,
EmailProvider.MessageColumns.FOLDER_ID,
EmailProvider.ThreadColumns.ROOT,
EmailProvider.MessageColumns.SUBJECT,
EmailProvider.MessageColumns.DATE,
EmailProvider.SpecialColumns.THREAD_COUNT
},
"",
new String[] {},
EmailProvider.MessageColumns.DATE + " DESC");
assertNotNull(cursor);
assertTrue(cursor.moveToFirst());
assertEquals(2, cursor.getInt(5));
assertFalse(cursor.moveToNext());
}
@Test
public void query_forAThreadOfMessages_returnsMessage() throws MessagingException {
Account account = Preferences.getPreferences(getContext()).newAccount();
account.getUuid();
Message message = new MimeMessage();
message.setSubject("Test Subject");
message.setSentDate(new GregorianCalendar(2016, 1, 2).getTime(), false);
account.getLocalStore().getFolder("Inbox").appendMessages(Collections.singletonList(message));
//Now get the thread id we just put in.
Cursor cursor = getProvider().query(
Uri.parse("content://" + EmailProvider.AUTHORITY + "/account/" + account.getUuid() + "/messages"),
new String[] {
EmailProvider.MessageColumns.ID,
EmailProvider.MessageColumns.FOLDER_ID,
EmailProvider.ThreadColumns.ROOT,
},
"",
new String[] {},
EmailProvider.MessageColumns.DATE);
assertNotNull(cursor);
cursor.moveToFirst();
String threadId = cursor.getString(2);
//Now check the message is listed under that thread
Cursor threadCursor = getProvider().query(
Uri.parse("content://" + EmailProvider.AUTHORITY + "/account/" + account.getUuid() +
"/thread/" + threadId),
new String[] {
EmailProvider.MessageColumns.ID,
EmailProvider.MessageColumns.FOLDER_ID,
EmailProvider.ThreadColumns.ROOT,
EmailProvider.MessageColumns.SUBJECT,
EmailProvider.MessageColumns.DATE
},
"",
new String[] {},
EmailProvider.MessageColumns.DATE);
assertNotNull(threadCursor);
assertTrue(threadCursor.moveToFirst());
assertEquals(message.getSubject(), threadCursor.getString(3));
}
}