blob: 8325a1d81771afe495d2f49391a564174dc421d4 [file] [log] [blame]
/****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one *
* or more contributor license agreements. See the NOTICE file *
* distributed with this work for additional information *
* regarding copyright ownership. The ASF licenses this file *
* to you under the Apache License, Version 2.0 (the *
* "License"); you may not use this file except in compliance *
* with the License. You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, *
* software distributed under the License is distributed on an *
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
* KIND, either express or implied. See the License for the *
* specific language governing permissions and limitations *
* under the License. *
****************************************************************/
package org.apache.james.mime4j.field.address;
import org.apache.james.mime4j.MimeException;
import org.apache.james.mime4j.field.address.parser.ParseException;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import junit.framework.TestCase;
public class AddressTest extends TestCase {
public void testExceptionTree() {
// make sure that our ParseException extends MimeException.
assertTrue(MimeException.class.isAssignableFrom(ParseException.class));
}
public void testParse1() throws ParseException {
AddressList addrList = AddressList.parse("John Doe <jdoe@machine(comment). example>");
assertEquals(1, addrList.size());
Mailbox mailbox = (Mailbox)addrList.get(0);
assertEquals("John Doe", mailbox.getName());
assertEquals("jdoe", mailbox.getLocalPart());
assertEquals("machine.example", mailbox.getDomain());
}
public void testParse2() throws ParseException {
AddressList addrList = AddressList.parse("Mary Smith \t \t\t <mary@example.net>");
assertEquals(1, addrList.size());
Mailbox mailbox = (Mailbox)addrList.get(0);
assertEquals("Mary Smith", mailbox.getName());
assertEquals("mary", mailbox.getLocalPart());
assertEquals("example.net", mailbox.getDomain());
}
public void testEmptyGroup() throws ParseException {
AddressList addrList = AddressList.parse("undisclosed-recipients:;");
assertEquals(1, addrList.size());
Group group = (Group)addrList.get(0);
assertEquals(0, group.getMailboxes().size());
assertEquals("undisclosed-recipients", group.getName());
}
public void testMessyGroupAndMailbox() throws ParseException {
AddressList addrList = AddressList.parse("Marketing folks : Jane Smith < jane @ example . net >, \" Jack \\\"Jackie\\\" Jones \" < jjones@example.com > (comment(comment)); ,, (comment) , <@example . net,@example(ignore\\)).com:(ignore)john@(ignore)example.net>");
assertEquals(2, addrList.size());
Group group = (Group)addrList.get(0);
assertEquals("Marketing folks", group.getName());
assertEquals(2, group.getMailboxes().size());
Mailbox mailbox1 = group.getMailboxes().get(0);
Mailbox mailbox2 = group.getMailboxes().get(1);
assertEquals("Jane Smith", mailbox1.getName());
assertEquals("jane", mailbox1.getLocalPart());
assertEquals("example.net", mailbox1.getDomain());
assertEquals(" Jack \"Jackie\" Jones ", mailbox2.getName());
assertEquals("jjones", mailbox2.getLocalPart());
assertEquals("example.com", mailbox2.getDomain());
Mailbox mailbox = (Mailbox)addrList.get(1);
assertEquals("john", mailbox.getLocalPart());
assertEquals("example.net", mailbox.getDomain());
assertEquals(2, mailbox.getRoute().size());
assertEquals("example.net", mailbox.getRoute().get(0));
assertEquals("example.com", mailbox.getRoute().get(1));
}
public void testEmptyAddressList() throws ParseException {
assertEquals(0, AddressList.parse(" \t \t ").size());
assertEquals(0, AddressList.parse(" \t , , , ,,, , \t ").size());
}
public void testSimpleForm() throws ParseException {
AddressList addrList = AddressList.parse("\"a b c d e f g\" (comment) @example.net");
assertEquals(1, addrList.size());
Mailbox mailbox = (Mailbox)addrList.get(0);
assertEquals("a b c d e f g", mailbox.getLocalPart());
assertEquals("example.net", mailbox.getDomain());
}
public void testFlatten() throws ParseException {
AddressList addrList = AddressList.parse("dev : one@example.com, two@example.com; , ,,, marketing:three@example.com ,four@example.com;, five@example.com");
assertEquals(3, addrList.size());
assertEquals(5, addrList.flatten().size());
}
public void testTortureTest() throws ParseException {
// Source: http://mailformat.dan.info/headers/from.html
// (Commented out pending confirmation of legality--I think the local-part is illegal.)
// AddressList.parse("\"Guy Macon\" <guymacon+\" http://www.guymacon.com/ \"00@spamcop.net>");
// Taken mostly from RFC822.
// Just make sure these are recognized as legal address lists;
// there shouldn't be any aspect of the RFC that is tested here
// but not in the other unit tests.
AddressList.parse("Alfred Neuman <Neuman@BBN-TENEXA>");
AddressList.parse("Neuman@BBN-TENEXA");
AddressList.parse("\"George, Ted\" <Shared@Group.Arpanet>");
AddressList.parse("Wilt . (the Stilt) Chamberlain@NBA.US");
// NOTE: In RFC822 8.1.5, the following example did not have "Galloping Gourmet"
// in double-quotes. I can only assume this was a typo, since 6.2.4 specifically
// disallows spaces in unquoted local-part.
AddressList.parse(" Gourmets: Pompous Person <WhoZiWhatZit@Cordon-Bleu>," +
" Childs@WGBH.Boston, \"Galloping Gourmet\"@" +
" ANT.Down-Under (Australian National Television)," +
" Cheapie@Discount-Liquors;," +
" Cruisers: Port@Portugal, Jones@SEA;," +
" Another@Somewhere.SomeOrg");
// NOTE: In RFC822 8.3.3, the following example ended with a lone ">" after
// Tops-20-Host. I can only assume this was a typo, since 6.1 clearly shows
// ">" requires a matching "<".
AddressList.parse("Important folk:" +
" Tom Softwood <Balsa@Tree.Root>," +
" \"Sam Irving\"@Other-Host;," +
" Standard Distribution:" +
" /main/davis/people/standard@Other-Host," +
" \"<Jones>standard.dist.3\"@Tops-20-Host;");
// The following are from a Usenet post by Dan J. Bernstein:
// http://groups.google.com/groups?selm=1996Aug1418.21.01.28081%40koobera.math.uic.edu
AddressList.parse("\":sysmail\"@ Some-Group.\t Some-Org, Muhammed.(I am the greatest) Ali @(the)Vegas.WBA");
AddressList.parse("me@home.com (comment (nested (deeply\\))))");
AddressList.parse("mailing list: me@home.com, route two <you@work.com>, them@play.com ;");
}
public void testLexicalError() {
// ensure that TokenMgrError doesn't get thrown
try {
AddressList.parse(")");
fail("Expected parsing error");
}
catch (ParseException e) {
}
}
public void testNullConstructorAndBadUsage() {
AddressList al = new AddressList(null, false);
assertEquals(0, al.size());
try {
al.get(-1);
fail("Expected index out of bound exception!");
} catch (IndexOutOfBoundsException e) {
}
try {
al.get(0);
fail("Expected index out of bound exception!");
} catch (IndexOutOfBoundsException e) {
}
}
public void testAddressList() throws ParseException {
AddressList addlist = AddressList.parse("foo@example.com, bar@example.com, third@example.com");
List<Address> al = new ArrayList<Address>();
al.add(addlist.get(0));
// shared arraylist
AddressList dl = new AddressList(al, true);
assertEquals(1, dl.size());
al.add(addlist.get(1));
assertEquals(2, dl.size());
// cloned arraylist
AddressList dlcopy = new AddressList(al, false);
assertEquals(2, dlcopy.size());
al.add(addlist.get(2));
assertEquals(2, dlcopy.size());
// check route string
assertEquals(2, dlcopy.flatten().size());
}
public void testInteractiveMain() throws Exception {
PrintStream out_orig = System.out;
InputStream in_orig = System.in;
PrintStream err_orig = System.err;
try {
PipedOutputStream piped = new PipedOutputStream();
PipedInputStream newInput = new PipedInputStream(piped);
PipedInputStream inOut = new PipedInputStream();
PrintStream outPs = new PrintStream(new PipedOutputStream(inOut));
BufferedReader outReader = new BufferedReader(new InputStreamReader(inOut));
PipedInputStream inErr = new PipedInputStream();
PrintStream errPs = new PrintStream(new PipedOutputStream(inErr));
BufferedReader errReader = new BufferedReader(new InputStreamReader(inErr));
System.setIn(newInput);
System.setOut(outPs);
System.setErr(errPs);
Thread t = new Thread() {
@Override
public void run() {
try {
AddressList.main(null);
} catch (Exception e) {
fail("Catched an exception in main: "+e);
}
}
};
t.start();
PrintWriter input = new PrintWriter(piped);
input.write("Test <test@example.com>\r\n");
input.flush();
String out = outReader.readLine();
assertEquals("> Test <test@example.com>", out);
input.write("A <foo@example.com>\r\n");
input.flush();
String out2 = outReader.readLine();
assertEquals("> A <foo@example.com>", out2);
input.write("\"Foo Bar\" <foo>\r\n");
input.flush();
String out3 = errReader.readLine();
assertNotNull(out3);
input.write("quit\r\n");
input.flush();
// we read 2 angular brackets because one was from the previous exception error.
String out4 = outReader.readLine();
assertEquals("> > Goodbye.", out4);
t.join();
} finally {
System.setIn(in_orig);
System.setOut(out_orig);
System.setErr(err_orig);
}
}
public void testEmptyDomainList() {
DomainList dl = new DomainList(null, false);
assertEquals(0, dl.size());
try {
dl.get(-1);
fail("Expected index out of bound exception!");
} catch (IndexOutOfBoundsException e) {
}
try {
dl.get(0);
fail("Expected index out of bound exception!");
} catch (IndexOutOfBoundsException e) {
}
}
public void testDomainList() {
List<String> al = new ArrayList<String>();
al.add("example.com");
// shared arraylist
DomainList dl = new DomainList(al, true);
assertEquals(1, dl.size());
al.add("foo.example.com");
assertEquals(2, dl.size());
// cloned arraylist
DomainList dlcopy = new DomainList(al, false);
assertEquals(2, dlcopy.size());
al.add("bar.example.com");
assertEquals(2, dlcopy.size());
// check route string
assertEquals("@example.com,@foo.example.com", dlcopy.toRouteString());
}
public void testEmptyMailboxList() {
MailboxList ml = new MailboxList(null, false);
assertEquals(0, ml.size());
try {
ml.get(-1);
fail("Expected index out of bound exception!");
} catch (IndexOutOfBoundsException e) {
}
try {
ml.get(0);
fail("Expected index out of bound exception!");
} catch (IndexOutOfBoundsException e) {
}
}
public void testMailboxList() {
List<Mailbox> al = new ArrayList<Mailbox>();
al.add(new Mailbox("local","example.com"));
// shared arraylist
MailboxList ml = new MailboxList(al, true);
assertEquals(1, ml.size());
al.add(new Mailbox("local2", "foo.example.com"));
assertEquals(2, ml.size());
// cloned arraylist
MailboxList mlcopy = new MailboxList(al, false);
assertEquals(2, mlcopy.size());
al.add(new Mailbox("local3", "bar.example.com"));
assertEquals(2, mlcopy.size());
mlcopy.print();
}
public void testGroupSerialization() {
List<Mailbox> al = new ArrayList<Mailbox>();
al.add(new Mailbox("test", "example.com"));
al.add(new Mailbox("Foo!", "foo", "example.com"));
DomainList dl = new DomainList(new ArrayList<String>(Arrays.asList(new String[] {"foo.example.com"})), true);
Mailbox mailbox = new Mailbox("Foo Bar", dl, "foo2", "example.com");
assertSame(dl, mailbox.getRoute());
al.add(mailbox);
Group g = new Group("group", new MailboxList(al, false));
assertEquals("group: test@example.com, Foo! <foo@example.com>, Foo Bar <foo2@example.com>;", g.getDisplayString());
}
public void testEmptyQuotedStringBeforeDotAtomInLocalPart() throws Exception {
/*
* This used to give a StringIndexOutOfBoundsException instead of the expected
* ParseException
*/
try {
AddressList.parse("\"\"bar@bar.com");
fail("ParseException expected");
} catch (ParseException pe) {
}
}
public void testMailboxGetEncodedString() throws Exception {
assertEquals("john.doe@acme.org", new Mailbox("john.doe", "acme.org")
.getEncodedString());
assertEquals("\"john doe\"@acme.org", new Mailbox("john doe",
"acme.org").getEncodedString());
assertEquals("John Doe <john.doe@acme.org>", new Mailbox("John Doe",
"john.doe", "acme.org").getEncodedString());
assertEquals("\"John Doe @Home\" <john.doe@acme.org>", new Mailbox(
"John Doe @Home", "john.doe", "acme.org").getEncodedString());
assertEquals("=?ISO-8859-1?Q?Hans_M=FCller?= <hans.mueller@acme.org>",
new Mailbox("Hans M\374ller", "hans.mueller", "acme.org")
.getEncodedString());
}
public void testGroupGetEncodedString() throws Exception {
List<Mailbox> al = new ArrayList<Mailbox>();
al.add(new Mailbox("test", "example.com"));
al.add(new Mailbox("Foo!", "foo", "example.com"));
al.add(new Mailbox("Hans M\374ller", "hans.mueller", "acme.org"));
Group g = new Group("group @work", new MailboxList(al, false));
assertEquals("\"group @work\": test@example.com, "
+ "Foo! <foo@example.com>, =?ISO-8859-1?Q?Hans_M=FCller?="
+ " <hans.mueller@acme.org>;", g.getEncodedString());
}
public void testEmptyGroupGetEncodedString() throws Exception {
MailboxList emptyMailboxes = new MailboxList(null, true);
Group g = new Group("Undisclosed recipients", emptyMailboxes);
assertEquals("Undisclosed recipients:;", g.getEncodedString());
}
public void testParseAddress() throws Exception {
Address address = Address.parse("Mary Smith <mary@example.net>");
assertTrue(address instanceof Mailbox);
assertEquals("Mary Smith", ((Mailbox) address).getName());
assertEquals("mary@example.net", ((Mailbox) address).getAddress());
address = Address.parse("group: Mary Smith <mary@example.net>;");
assertTrue(address instanceof Group);
assertEquals("group", ((Group) address).getName());
assertEquals("Mary Smith", ((Group) address).getMailboxes().get(0)
.getName());
assertEquals("mary@example.net", ((Group) address).getMailboxes()
.get(0).getAddress());
try {
Group.parse("john.doe@acme.org, jane.doe@acme.org");
fail();
} catch (IllegalArgumentException expected) {
}
}
public void testParseGroup() throws Exception {
Group group = Group
.parse("group: john.doe@acme.org, Mary Smith <mary@example.net>;");
assertEquals("group", group.getName());
MailboxList mailboxes = group.getMailboxes();
assertEquals(2, mailboxes.size());
Mailbox mailbox1 = mailboxes.get(0);
assertNull(mailbox1.getName());
assertEquals("john.doe@acme.org", mailbox1.getAddress());
Mailbox mailbox2 = mailboxes.get(1);
assertEquals("Mary Smith", mailbox2.getName());
assertEquals("mary@example.net", mailbox2.getAddress());
try {
Group.parse("john.doe@acme.org");
fail();
} catch (IllegalArgumentException expected) {
}
try {
Group.parse("g1: john.doe@acme.org;, g2: mary@example.net;");
fail();
} catch (IllegalArgumentException expected) {
}
}
public void testParseMailbox() throws Exception {
Mailbox mailbox1 = Mailbox.parse("john.doe@acme.org");
assertNull(mailbox1.getName());
assertEquals("john.doe@acme.org", mailbox1.getAddress());
Mailbox mailbox2 = Mailbox.parse("Mary Smith <mary@example.net>");
assertEquals("Mary Smith", mailbox2.getName());
assertEquals("mary@example.net", mailbox2.getAddress());
// non-ascii should be allowed in quoted strings
Mailbox mailbox3 = Mailbox
.parse("\"Hans M\374ller\" <hans.mueller@acme.org>");
assertEquals("Hans M\374ller", mailbox3.getName());
assertEquals("hans.mueller@acme.org", mailbox3.getAddress());
try {
Mailbox.parse("g: Mary Smith <mary@example.net>;");
fail();
} catch (IllegalArgumentException expected) {
}
try {
Mailbox.parse("Mary Smith <mary@example.net>, hans.mueller@acme.org");
fail();
} catch (IllegalArgumentException expected) {
}
}
}