14 func TestMailAddress(t *testing.T) {
21 "testdata/actor/mastodon.json",
22 `"Oliver Lowe" <otl@hachyderm.io>`,
23 `"Oliver Lowe (followers)" <otl+followers@hachyderm.io>`,
26 "testdata/actor/akkoma.json",
27 `"Kari'boka" <kariboka@social.harpia.red>`,
28 `"Kari'boka (followers)" <kariboka+followers@social.harpia.red>`,
31 "testdata/actor/lemmy.json",
32 "<Spotlight7573@lemmy.world>",
33 "<@>", // zero mail.Address
36 for _, tt := range tests {
37 f, err := os.Open(tt.name)
43 actor, err := DecodeActor(f)
45 t.Errorf("%s: decode actor: %v", tt.name, err)
48 if actor.Address().String() != tt.from {
49 t.Errorf("%s: from address: want %s, got %s", tt.name, tt.from, actor.Address().String())
51 got := actor.FollowersAddress().String()
52 if got != tt.followers {
53 t.Errorf("%s: followers address: want %s, got %s", tt.name, tt.followers, got)
58 func TestMarshalMail(t *testing.T) {
64 "testdata/note/akkoma.json",
66 "kariboka+followers@social.harpia.red",
67 "otl@apubtest2.srcbeat.com",
71 "testdata/note/lemmy.json",
73 "Feathercrown@lemmy.world",
74 "technology@lemmy.world",
78 "testdata/note/mastodon.json",
80 "otl+followers@hachyderm.io",
81 "selfhosted+followers@lemmy.world",
82 "selfhosted@lemmy.world",
88 "technology@lemmy.world",
92 for _, tt := range tests {
93 f, err := os.Open(tt.name)
101 t.Errorf("%s: decode activity: %v", tt.name, err)
104 b, err := MarshalMail(a, nil)
106 t.Errorf("%s: marshal to mail message: %v", tt.name, err)
109 msg, err := mail.ReadMessage(bytes.NewReader(b))
111 t.Errorf("%s: read back message from marshalled activity: %v", tt.name, err)
114 rcptto, err := msg.Header.AddressList("To")
115 if errors.Is(err, mail.ErrHeaderNotPresent) {
116 // whatever; sometimes the Activity has an empty slice.
117 } else if err != nil {
118 t.Errorf("%s: parse To addresses: %v", tt.name, err)
119 t.Log("raw value:", msg.Header.Get("To"))
122 rcptcc, err := msg.Header.AddressList("CC")
123 if errors.Is(err, mail.ErrHeaderNotPresent) {
124 // whatever; sometimes the Activity has an empty slice.
125 } else if err != nil {
126 t.Errorf("%s: parse CC addresses: %v", tt.name, err)
127 t.Log("raw value:", msg.Header.Get("CC"))
132 rcpts := make([]string, len(rcptto)+len(rcptcc))
133 for i, rcpt := range append(rcptto, rcptcc...) {
134 rcpts[i] = rcpt.Address
137 if !reflect.DeepEqual(rcpts, tt.recipients) {
138 t.Errorf("%s: unexpected recipients, want %s got %s", tt.name, tt.recipients, rcpts)
142 if _, err := msg.Body.Read(p); err != nil {
143 // Pages have no content, so skip this case
144 if a.Type == "Page" {
147 t.Errorf("%s: read message body: %v", tt.name, err)
152 func TestUnmarshalMail(t *testing.T) {
153 f, err := os.Open("testdata/outbound.eml")
158 msg, err := mail.ReadMessage(f)
163 t.Skip("skipping network calls to unmarshal mail message to Activity")
165 a, err := UnmarshalMail(msg, nil)
170 t.Fatalf("wanted 1 tag in unmarshalled activity, got %d", len(a.Tag))
172 want := "@henfredemars@infosec.pub"
173 if a.Tag[0].Name != want {
174 t.Errorf("wanted tag name %s, got %s", want, a.Tag[0].Name)
176 if a.MediaType != "text/markdown" {
177 t.Errorf("wrong media type: wanted %s, got %s", "text/markdown", a.MediaType)
180 "https://programming.dev/c/programming",
181 "https://programming.dev/u/starman",
182 "https://hachyderm.io/users/otl/followers",
184 if !reflect.DeepEqual(wantCC, a.CC) {
185 t.Errorf("wanted recipients %s, got %s", wantCC, a.CC)
187 if strings.Contains(a.Content, "\r") {
188 t.Errorf("activity content contains carriage returns")