package com.zegoggles.smssync.mail; import android.net.Uri; import android.provider.CallLog; import android.provider.Telephony; import com.fsck.k9.mail.Address; import com.fsck.k9.mail.Message; import com.fsck.k9.mail.internet.MimeHeader; import com.zegoggles.smssync.contacts.ContactGroupIds; import com.zegoggles.smssync.preferences.AddressStyle; import org.apache.james.mime4j.util.MimeUtil; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.robolectric.Robolectric; import org.robolectric.RobolectricTestRunner; import java.util.Date; import java.util.HashMap; import java.util.Map; import static org.fest.assertions.api.Assertions.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; import static org.mockito.MockitoAnnotations.initMocks; @RunWith(RobolectricTestRunner.class) public class MessageGeneratorTest { private MessageGenerator generator; @Mock private PersonLookup personLookup; @Mock private HeaderGenerator headerGenerator; @Mock private MmsSupport mmsSupport; @Mock private Address me; @Mock private ContactGroupIds groupIds; @Before public void before() { initMocks(this); me = new Address("mine@mine.com", "me"); generator = new MessageGenerator(Robolectric.application, me, AddressStyle.NAME, headerGenerator, personLookup, false, null, mmsSupport ); } @Test public void testShouldReturnNullIfMessageHasNoAddress() throws Exception { Map<String, String> map = new HashMap<String, String>(); Message msg = generator.messageForDataType(map, DataType.SMS); assertThat(msg).isNull(); } @Test public void testShouldGenerateSubjectWithNameForSMS() throws Exception { PersonRecord record = new PersonRecord(1, "Test Testor", null, null); Message msg = generator.messageForDataType(mockMessage("1234", record), DataType.SMS); assertThat(msg).isNotNull(); assertThat(msg.getSubject()).isEqualTo("SMS with Test Testor"); } @Test public void testShouldGenerateSMSMessageWithCorrectEncoding() throws Exception { PersonRecord record = new PersonRecord(1, "Test Testor", null, null); Message msg = generator.messageForDataType(mockMessage("1234", record), DataType.SMS); assertThat(msg.getHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING)).isEqualTo(new String[] { MimeUtil.ENC_QUOTED_PRINTABLE }); } @Test public void testShouldGenerateSubjectWithNameForMMS() throws Exception { PersonRecord personRecord = new PersonRecord(1, "Foo Bar", "foo@bar.com", "1234"); MmsSupport.MmsDetails details = new MmsSupport.MmsDetails(true, "foo", personRecord, new Address("foo@bar.com")); when(mmsSupport.getDetails(any(Uri.class), any(AddressStyle.class))).thenReturn(details); Message msg = generator.messageForDataType(mockMessage("1234", personRecord), DataType.MMS); assertThat(msg).isNotNull(); assertThat(msg.getSubject()).isEqualTo("SMS with Foo Bar"); } @Test public void testShouldGenerateMMSMessageWithCorrectEncoding() throws Exception { PersonRecord personRecord = new PersonRecord(1, "Foo Bar", "foo@bar.com", "1234"); MmsSupport.MmsDetails details = new MmsSupport.MmsDetails(true, "foo", personRecord, new Address("foo@bar.com")); when(mmsSupport.getDetails(any(Uri.class), any(AddressStyle.class))).thenReturn(details); Message msg = generator.messageForDataType(mockMessage("1234", personRecord), DataType.MMS); assertThat(msg.getHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING)).isEqualTo(new String[] { MimeUtil.ENC_7BIT }); } @Test public void testShouldGenerateMessageForCallLogOutgoing() throws Exception { PersonRecord record = new PersonRecord(-1, "Test Testor", null, null); Message msg = generator.messageForDataType(mockCalllogMessage("1234", CallLog.Calls.OUTGOING_TYPE, record), DataType.CALLLOG); assertThat(msg).isNotNull(); assertThat(msg.getSubject()).isEqualTo("Call with Test Testor"); assertThat(msg.getFrom()[0]).isEqualTo(me); assertThat(msg.getRecipients(Message.RecipientType.TO)[0].toString()).isEqualTo("Test Testor <unknown.number@unknown.email>"); } @Test public void testShouldGenerateMessageForCallLogIncoming() throws Exception { PersonRecord record = new PersonRecord(-1, "Test Testor", null, null); Message msg = generator.messageForDataType(mockCalllogMessage("1234", CallLog.Calls.INCOMING_TYPE, record), DataType.CALLLOG); assertThat(msg).isNotNull(); assertThat(msg.getSubject()).isEqualTo("Call with Test Testor"); assertThat(msg.getFrom()[0].toString()).isEqualTo("Test Testor <unknown.number@unknown.email>"); assertThat(msg.getRecipients(Message.RecipientType.TO)[0]).isEqualTo(me); } @Test public void testShouldGenerateMessageForCallLogMissed() throws Exception { PersonRecord record = new PersonRecord(-1, "Test Testor", null, null); Message msg = generator.messageForDataType(mockCalllogMessage("1234", CallLog.Calls.MISSED_TYPE, record), DataType.CALLLOG); assertThat(msg).isNotNull(); assertThat(msg.getSubject()).isEqualTo("Call with Test Testor"); assertThat(msg.getFrom()[0].toString()).isEqualTo("Test Testor <unknown.number@unknown.email>"); assertThat(msg.getRecipients(Message.RecipientType.TO)[0]).isEqualTo(me); } @Test public void testShouldGenerateMessageForCallLogIncomingUnknown() throws Exception { PersonRecord record = new PersonRecord(0, null, null, "-1"); Message msg = generator.messageForDataType(mockCalllogMessage("", CallLog.Calls.INCOMING_TYPE, record), DataType.CALLLOG); assertThat(msg).isNotNull(); assertThat(msg.getSubject()).isEqualTo("Call with Unknown"); assertThat(msg.getFrom()[0].toString()).isEqualTo("Unknown <unknown.number@unknown.email>"); assertThat(msg.getRecipients(Message.RecipientType.TO)[0]).isEqualTo(me); } @Test public void testShouldGenerateCallLogMessageWithCorrectEncoding() throws Exception { PersonRecord record = new PersonRecord(-1, "Test Testor", null, null); Message msg = generator.messageForDataType(mockCalllogMessage("1234", CallLog.Calls.OUTGOING_TYPE, record), DataType.CALLLOG); assertThat(msg.getHeader(MimeHeader.HEADER_CONTENT_TRANSFER_ENCODING)).isEqualTo(new String[] { MimeUtil.ENC_QUOTED_PRINTABLE }); } @Test public void testShouldGenerateSubjectWithNameAndNumberForSMS() throws Exception { PersonRecord record = new PersonRecord(1, "Test Testor", "test@test.com", "1234"); Message msg = generator.messageForDataType(mockMessage("1234", record), DataType.SMS); assertThat(msg).isNotNull(); assertThat(msg.getSubject()).isEqualTo("SMS with Test Testor"); } @Test public void shouldGenerateCorrectFromHeaderWithUsersEmailAddress() throws Exception { PersonRecord record = new PersonRecord(1, "Test Testor", "test@test.com", "1234"); Message msg = generator.messageForDataType(mockMessage("1234", record), DataType.SMS); assertThat(msg).isNotNull(); assertThat(msg.getFrom()[0]).isEqualTo(me); } @Test public void shouldGenerateCorrectToHeader() throws Exception { PersonRecord record = new PersonRecord(1, "Test Testor", "test@test.com", "1234"); Message msg = generator.messageForDataType(mockMessage("1234", record), DataType.SMS); assertThat(msg).isNotNull(); assertThat(msg.getRecipients(Message.RecipientType.TO)[0].toString()) .isEqualTo("Test Testor <test@test.com>"); } @Test public void shouldGenerateCorrectHeaders() throws Exception { PersonRecord record = new PersonRecord(1, "Test Testor", "test@test.com", "1234"); Map<String, String> map = mockMessage("1234", record); Date date = new Date(); map.put(Telephony.TextBasedSmsColumns.DATE, String.valueOf(date.getTime())); map.put(Telephony.TextBasedSmsColumns.TYPE, "0"); Message msg = generator.messageForDataType(map, DataType.SMS); assertThat(msg).isNotNull(); verify(headerGenerator).setHeaders(any(Message.class), any(Map.class), eq(DataType.SMS), anyString(), eq(record), eq(date), eq(0)); } @Test public void shouldGenerateCorrectToHeaderWhenUserisRecipient() throws Exception { PersonRecord record = new PersonRecord(1, "Test Testor", "test@test.com", "1234"); Map<String, String> map = mockMessage("1234", record); map.put(Telephony.TextBasedSmsColumns.TYPE, "1"); Message msg = generator.messageForDataType(map, DataType.SMS); assertThat(msg).isNotNull(); assertThat(msg.getFrom()[0].toString()) .isEqualTo("Test Testor <test@test.com>"); assertThat(msg.getRecipients(Message.RecipientType.TO)[0]).isEqualTo(me); } @Test public void testShouldUseNumberIfNameIsUnknown() throws Exception { PersonRecord record = new PersonRecord(-1, null, null, "1234"); Message msg = generator.messageForDataType(mockMessage("1234", record), DataType.SMS); assertThat(msg).isNotNull(); assertThat(msg.getSubject()).isEqualTo("SMS with 1234"); } @Test public void shouldOnlyIncludePeopleFromContactIdsIfSpecified() throws Exception { MessageGenerator generator = new MessageGenerator(Robolectric.application, me, AddressStyle.NAME, headerGenerator, personLookup, false, groupIds, mmsSupport ); PersonRecord record = new PersonRecord(1, "Test Testor", "test@test.com", "1234"); Map<String, String> map = mockMessage("1234", record); map.put(Telephony.TextBasedSmsColumns.TYPE, "1"); when(groupIds.contains(record)).thenReturn(false); assertThat(generator.messageForDataType(map, DataType.SMS)).isNull(); when(groupIds.contains(record)).thenReturn(true); assertThat(generator.messageForDataType(map, DataType.SMS)).isNotNull(); } private Map<String, String> mockMessage(String address, PersonRecord record) { Map<String, String> map = new HashMap<String, String>(); map.put(Telephony.TextBasedSmsColumns.ADDRESS, address); when(personLookup.lookupPerson(eq(address))).thenReturn(record); return map; } private Map<String, String> mockCalllogMessage(String address, int type, PersonRecord record) { Map<String, String> map = new HashMap<String, String>(); map.put(CallLog.Calls.NUMBER, address); map.put(CallLog.Calls.TYPE, String.valueOf(type)); when(personLookup.lookupPerson(eq(address))).thenReturn(record); return map; } }