github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/pkg/net/mail/message_test.go (about)

     1  // Copyright 2011 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package mail
     6  
     7  import (
     8  	"bytes"
     9  	"io/ioutil"
    10  	"reflect"
    11  	"testing"
    12  	"time"
    13  )
    14  
    15  var parseTests = []struct {
    16  	in     string
    17  	header Header
    18  	body   string
    19  }{
    20  	{
    21  		// RFC 5322, Appendix A.1.1
    22  		in: `From: John Doe <jdoe@machine.example>
    23  To: Mary Smith <mary@example.net>
    24  Subject: Saying Hello
    25  Date: Fri, 21 Nov 1997 09:55:06 -0600
    26  Message-ID: <1234@local.machine.example>
    27  
    28  This is a message just to say hello.
    29  So, "Hello".
    30  `,
    31  		header: Header{
    32  			"From":       []string{"John Doe <jdoe@machine.example>"},
    33  			"To":         []string{"Mary Smith <mary@example.net>"},
    34  			"Subject":    []string{"Saying Hello"},
    35  			"Date":       []string{"Fri, 21 Nov 1997 09:55:06 -0600"},
    36  			"Message-Id": []string{"<1234@local.machine.example>"},
    37  		},
    38  		body: "This is a message just to say hello.\nSo, \"Hello\".\n",
    39  	},
    40  }
    41  
    42  func TestParsing(t *testing.T) {
    43  	for i, test := range parseTests {
    44  		msg, err := ReadMessage(bytes.NewBuffer([]byte(test.in)))
    45  		if err != nil {
    46  			t.Errorf("test #%d: Failed parsing message: %v", i, err)
    47  			continue
    48  		}
    49  		if !headerEq(msg.Header, test.header) {
    50  			t.Errorf("test #%d: Incorrectly parsed message header.\nGot:\n%+v\nWant:\n%+v",
    51  				i, msg.Header, test.header)
    52  		}
    53  		body, err := ioutil.ReadAll(msg.Body)
    54  		if err != nil {
    55  			t.Errorf("test #%d: Failed reading body: %v", i, err)
    56  			continue
    57  		}
    58  		bodyStr := string(body)
    59  		if bodyStr != test.body {
    60  			t.Errorf("test #%d: Incorrectly parsed message body.\nGot:\n%+v\nWant:\n%+v",
    61  				i, bodyStr, test.body)
    62  		}
    63  	}
    64  }
    65  
    66  func headerEq(a, b Header) bool {
    67  	if len(a) != len(b) {
    68  		return false
    69  	}
    70  	for k, as := range a {
    71  		bs, ok := b[k]
    72  		if !ok {
    73  			return false
    74  		}
    75  		if !reflect.DeepEqual(as, bs) {
    76  			return false
    77  		}
    78  	}
    79  	return true
    80  }
    81  
    82  func TestDateParsing(t *testing.T) {
    83  	tests := []struct {
    84  		dateStr string
    85  		exp     time.Time
    86  	}{
    87  		// RFC 5322, Appendix A.1.1
    88  		{
    89  			"Fri, 21 Nov 1997 09:55:06 -0600",
    90  			time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("", -6*60*60)),
    91  		},
    92  		// RFC5322, Appendix A.6.2
    93  		// Obsolete date.
    94  		{
    95  			"21 Nov 97 09:55:06 GMT",
    96  			time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("GMT", 0)),
    97  		},
    98  		// Commonly found format not specified by RFC 5322.
    99  		{
   100  			"Fri, 21 Nov 1997 09:55:06 -0600 (MDT)",
   101  			time.Date(1997, 11, 21, 9, 55, 6, 0, time.FixedZone("", -6*60*60)),
   102  		},
   103  	}
   104  	for _, test := range tests {
   105  		hdr := Header{
   106  			"Date": []string{test.dateStr},
   107  		}
   108  		date, err := hdr.Date()
   109  		if err != nil {
   110  			t.Errorf("Failed parsing %q: %v", test.dateStr, err)
   111  			continue
   112  		}
   113  		if !date.Equal(test.exp) {
   114  			t.Errorf("Parse of %q: got %+v, want %+v", test.dateStr, date, test.exp)
   115  		}
   116  	}
   117  }
   118  
   119  func TestAddressParsing(t *testing.T) {
   120  	tests := []struct {
   121  		addrsStr string
   122  		exp      []*Address
   123  	}{
   124  		// Bare address
   125  		{
   126  			`jdoe@machine.example`,
   127  			[]*Address{{
   128  				Address: "jdoe@machine.example",
   129  			}},
   130  		},
   131  		// RFC 5322, Appendix A.1.1
   132  		{
   133  			`John Doe <jdoe@machine.example>`,
   134  			[]*Address{{
   135  				Name:    "John Doe",
   136  				Address: "jdoe@machine.example",
   137  			}},
   138  		},
   139  		// RFC 5322, Appendix A.1.2
   140  		{
   141  			`"Joe Q. Public" <john.q.public@example.com>`,
   142  			[]*Address{{
   143  				Name:    "Joe Q. Public",
   144  				Address: "john.q.public@example.com",
   145  			}},
   146  		},
   147  		{
   148  			`Mary Smith <mary@x.test>, jdoe@example.org, Who? <one@y.test>`,
   149  			[]*Address{
   150  				{
   151  					Name:    "Mary Smith",
   152  					Address: "mary@x.test",
   153  				},
   154  				{
   155  					Address: "jdoe@example.org",
   156  				},
   157  				{
   158  					Name:    "Who?",
   159  					Address: "one@y.test",
   160  				},
   161  			},
   162  		},
   163  		{
   164  			`<boss@nil.test>, "Giant; \"Big\" Box" <sysservices@example.net>`,
   165  			[]*Address{
   166  				{
   167  					Address: "boss@nil.test",
   168  				},
   169  				{
   170  					Name:    `Giant; "Big" Box`,
   171  					Address: "sysservices@example.net",
   172  				},
   173  			},
   174  		},
   175  		// RFC 5322, Appendix A.1.3
   176  		// TODO(dsymonds): Group addresses.
   177  
   178  		// RFC 2047 "Q"-encoded ISO-8859-1 address.
   179  		{
   180  			`=?iso-8859-1?q?J=F6rg_Doe?= <joerg@example.com>`,
   181  			[]*Address{
   182  				{
   183  					Name:    `Jörg Doe`,
   184  					Address: "joerg@example.com",
   185  				},
   186  			},
   187  		},
   188  		// RFC 2047 "Q"-encoded UTF-8 address.
   189  		{
   190  			`=?utf-8?q?J=C3=B6rg_Doe?= <joerg@example.com>`,
   191  			[]*Address{
   192  				{
   193  					Name:    `Jörg Doe`,
   194  					Address: "joerg@example.com",
   195  				},
   196  			},
   197  		},
   198  		// RFC 2047, Section 8.
   199  		{
   200  			`=?ISO-8859-1?Q?Andr=E9?= Pirard <PIRARD@vm1.ulg.ac.be>`,
   201  			[]*Address{
   202  				{
   203  					Name:    `André Pirard`,
   204  					Address: "PIRARD@vm1.ulg.ac.be",
   205  				},
   206  			},
   207  		},
   208  		// Custom example of RFC 2047 "B"-encoded ISO-8859-1 address.
   209  		{
   210  			`=?ISO-8859-1?B?SvZyZw==?= <joerg@example.com>`,
   211  			[]*Address{
   212  				{
   213  					Name:    `Jörg`,
   214  					Address: "joerg@example.com",
   215  				},
   216  			},
   217  		},
   218  		// Custom example of RFC 2047 "B"-encoded UTF-8 address.
   219  		{
   220  			`=?UTF-8?B?SsO2cmc=?= <joerg@example.com>`,
   221  			[]*Address{
   222  				{
   223  					Name:    `Jörg`,
   224  					Address: "joerg@example.com",
   225  				},
   226  			},
   227  		},
   228  	}
   229  	for _, test := range tests {
   230  		if len(test.exp) == 1 {
   231  			addr, err := ParseAddress(test.addrsStr)
   232  			if err != nil {
   233  				t.Errorf("Failed parsing (single) %q: %v", test.addrsStr, err)
   234  				continue
   235  			}
   236  			if !reflect.DeepEqual([]*Address{addr}, test.exp) {
   237  				t.Errorf("Parse (single) of %q: got %+v, want %+v", test.addrsStr, addr, test.exp)
   238  			}
   239  		}
   240  
   241  		addrs, err := ParseAddressList(test.addrsStr)
   242  		if err != nil {
   243  			t.Errorf("Failed parsing (list) %q: %v", test.addrsStr, err)
   244  			continue
   245  		}
   246  		if !reflect.DeepEqual(addrs, test.exp) {
   247  			t.Errorf("Parse (list) of %q: got %+v, want %+v", test.addrsStr, addrs, test.exp)
   248  		}
   249  	}
   250  }
   251  
   252  func TestAddressFormatting(t *testing.T) {
   253  	tests := []struct {
   254  		addr *Address
   255  		exp  string
   256  	}{
   257  		{
   258  			&Address{Address: "bob@example.com"},
   259  			"<bob@example.com>",
   260  		},
   261  		{
   262  			&Address{Name: "Bob", Address: "bob@example.com"},
   263  			`"Bob" <bob@example.com>`,
   264  		},
   265  		{
   266  			// note the ö (o with an umlaut)
   267  			&Address{Name: "Böb", Address: "bob@example.com"},
   268  			`=?utf-8?q?B=C3=B6b?= <bob@example.com>`,
   269  		},
   270  	}
   271  	for _, test := range tests {
   272  		s := test.addr.String()
   273  		if s != test.exp {
   274  			t.Errorf("Address%+v.String() = %v, want %v", *test.addr, s, test.exp)
   275  		}
   276  	}
   277  }