Blame


1 1d5ddf5d 2024-02-20 o package apub
2 1d5ddf5d 2024-02-20 o
3 1d5ddf5d 2024-02-20 o import (
4 1d5ddf5d 2024-02-20 o "bytes"
5 d3dfb672 2024-03-18 o "errors"
6 1d5ddf5d 2024-02-20 o "net/mail"
7 1d5ddf5d 2024-02-20 o "os"
8 d3dfb672 2024-03-18 o "reflect"
9 d3dfb672 2024-03-18 o "sort"
10 d3dfb672 2024-03-18 o "strings"
11 1d5ddf5d 2024-02-20 o "testing"
12 1d5ddf5d 2024-02-20 o )
13 1d5ddf5d 2024-02-20 o
14 77918b00 2024-03-07 o func TestMailAddress(t *testing.T) {
15 77918b00 2024-03-07 o tests := []struct {
16 77918b00 2024-03-07 o name string
17 77918b00 2024-03-07 o from string
18 77918b00 2024-03-07 o followers string
19 77918b00 2024-03-07 o }{
20 77918b00 2024-03-07 o {
21 77918b00 2024-03-07 o "testdata/actor/mastodon.json",
22 77918b00 2024-03-07 o `"Oliver Lowe" <otl@hachyderm.io>`,
23 77918b00 2024-03-07 o `"Oliver Lowe (followers)" <otl+followers@hachyderm.io>`,
24 77918b00 2024-03-07 o },
25 77918b00 2024-03-07 o {
26 77918b00 2024-03-07 o "testdata/actor/akkoma.json",
27 77918b00 2024-03-07 o `"Kari'boka" <kariboka@social.harpia.red>`,
28 77918b00 2024-03-07 o `"Kari'boka (followers)" <kariboka+followers@social.harpia.red>`,
29 77918b00 2024-03-07 o },
30 77918b00 2024-03-07 o {
31 77918b00 2024-03-07 o "testdata/actor/lemmy.json",
32 77918b00 2024-03-07 o "<Spotlight7573@lemmy.world>",
33 d802abd8 2024-03-12 o "<@>", // zero mail.Address
34 77918b00 2024-03-07 o },
35 77918b00 2024-03-07 o }
36 77918b00 2024-03-07 o for _, tt := range tests {
37 77918b00 2024-03-07 o f, err := os.Open(tt.name)
38 77918b00 2024-03-07 o if err != nil {
39 77918b00 2024-03-07 o t.Error(err)
40 77918b00 2024-03-07 o continue
41 77918b00 2024-03-07 o }
42 77918b00 2024-03-07 o defer f.Close()
43 77918b00 2024-03-07 o actor, err := DecodeActor(f)
44 77918b00 2024-03-07 o if err != nil {
45 77918b00 2024-03-07 o t.Errorf("%s: decode actor: %v", tt.name, err)
46 77918b00 2024-03-07 o continue
47 77918b00 2024-03-07 o }
48 77918b00 2024-03-07 o if actor.Address().String() != tt.from {
49 77918b00 2024-03-07 o t.Errorf("%s: from address: want %s, got %s", tt.name, tt.from, actor.Address().String())
50 77918b00 2024-03-07 o }
51 77918b00 2024-03-07 o got := actor.FollowersAddress().String()
52 77918b00 2024-03-07 o if got != tt.followers {
53 77918b00 2024-03-07 o t.Errorf("%s: followers address: want %s, got %s", tt.name, tt.followers, got)
54 77918b00 2024-03-07 o }
55 77918b00 2024-03-07 o }
56 77918b00 2024-03-07 o }
57 1d5ddf5d 2024-02-20 o
58 77918b00 2024-03-07 o func TestMarshalMail(t *testing.T) {
59 d3dfb672 2024-03-18 o tests := []struct {
60 d3dfb672 2024-03-18 o name string
61 d3dfb672 2024-03-18 o recipients []string
62 d3dfb672 2024-03-18 o }{
63 d3dfb672 2024-03-18 o {
64 d3dfb672 2024-03-18 o "testdata/note/akkoma.json",
65 d3dfb672 2024-03-18 o []string{
66 d3dfb672 2024-03-18 o "kariboka+followers@social.harpia.red",
67 d3dfb672 2024-03-18 o "otl@apubtest2.srcbeat.com",
68 d3dfb672 2024-03-18 o },
69 d3dfb672 2024-03-18 o },
70 d3dfb672 2024-03-18 o {
71 d3dfb672 2024-03-18 o "testdata/note/lemmy.json",
72 d3dfb672 2024-03-18 o []string{
73 d3dfb672 2024-03-18 o "Feathercrown@lemmy.world",
74 d3dfb672 2024-03-18 o "technology@lemmy.world",
75 d3dfb672 2024-03-18 o },
76 d3dfb672 2024-03-18 o },
77 d3dfb672 2024-03-18 o {
78 d3dfb672 2024-03-18 o "testdata/note/mastodon.json",
79 d3dfb672 2024-03-18 o []string{
80 d3dfb672 2024-03-18 o "otl+followers@hachyderm.io",
81 d3dfb672 2024-03-18 o "selfhosted+followers@lemmy.world",
82 d3dfb672 2024-03-18 o "selfhosted@lemmy.world",
83 d3dfb672 2024-03-18 o },
84 d3dfb672 2024-03-18 o },
85 d3dfb672 2024-03-18 o {
86 d3dfb672 2024-03-18 o "testdata/page.json",
87 d3dfb672 2024-03-18 o []string{
88 d3dfb672 2024-03-18 o "technology@lemmy.world",
89 d3dfb672 2024-03-18 o },
90 d3dfb672 2024-03-18 o },
91 1d5ddf5d 2024-02-20 o }
92 d3dfb672 2024-03-18 o for _, tt := range tests {
93 d3dfb672 2024-03-18 o f, err := os.Open(tt.name)
94 77918b00 2024-03-07 o if err != nil {
95 77918b00 2024-03-07 o t.Error(err)
96 77918b00 2024-03-07 o continue
97 77918b00 2024-03-07 o }
98 77918b00 2024-03-07 o defer f.Close()
99 77918b00 2024-03-07 o a, err := Decode(f)
100 77918b00 2024-03-07 o if err != nil {
101 d3dfb672 2024-03-18 o t.Errorf("%s: decode activity: %v", tt.name, err)
102 77918b00 2024-03-07 o continue
103 77918b00 2024-03-07 o }
104 d3dfb672 2024-03-18 o b, err := MarshalMail(a, nil)
105 77918b00 2024-03-07 o if err != nil {
106 d3dfb672 2024-03-18 o t.Errorf("%s: marshal to mail message: %v", tt.name, err)
107 77918b00 2024-03-07 o continue
108 77918b00 2024-03-07 o }
109 184e4de6 2024-03-13 o msg, err := mail.ReadMessage(bytes.NewReader(b))
110 184e4de6 2024-03-13 o if err != nil {
111 d3dfb672 2024-03-18 o t.Errorf("%s: read back message from marshalled activity: %v", tt.name, err)
112 184e4de6 2024-03-13 o continue
113 77918b00 2024-03-07 o }
114 d3dfb672 2024-03-18 o rcptto, err := msg.Header.AddressList("To")
115 d3dfb672 2024-03-18 o if errors.Is(err, mail.ErrHeaderNotPresent) {
116 d3dfb672 2024-03-18 o // whatever; sometimes the Activity has an empty slice.
117 d3dfb672 2024-03-18 o } else if err != nil {
118 d3dfb672 2024-03-18 o t.Errorf("%s: parse To addresses: %v", tt.name, err)
119 d3dfb672 2024-03-18 o t.Log("raw value:", msg.Header.Get("To"))
120 d3dfb672 2024-03-18 o continue
121 d3dfb672 2024-03-18 o }
122 d3dfb672 2024-03-18 o rcptcc, err := msg.Header.AddressList("CC")
123 d3dfb672 2024-03-18 o if errors.Is(err, mail.ErrHeaderNotPresent) {
124 d3dfb672 2024-03-18 o // whatever; sometimes the Activity has an empty slice.
125 d3dfb672 2024-03-18 o } else if err != nil {
126 d3dfb672 2024-03-18 o t.Errorf("%s: parse CC addresses: %v", tt.name, err)
127 d3dfb672 2024-03-18 o t.Log("raw value:", msg.Header.Get("CC"))
128 d3dfb672 2024-03-18 o continue
129 d3dfb672 2024-03-18 o }
130 d3dfb672 2024-03-18 o t.Log(rcptto)
131 d3dfb672 2024-03-18 o t.Log(rcptcc)
132 d3dfb672 2024-03-18 o rcpts := make([]string, len(rcptto)+len(rcptcc))
133 d3dfb672 2024-03-18 o for i, rcpt := range append(rcptto, rcptcc...) {
134 d3dfb672 2024-03-18 o rcpts[i] = rcpt.Address
135 d3dfb672 2024-03-18 o }
136 d3dfb672 2024-03-18 o sort.Strings(rcpts)
137 d3dfb672 2024-03-18 o if !reflect.DeepEqual(rcpts, tt.recipients) {
138 d3dfb672 2024-03-18 o t.Errorf("%s: unexpected recipients, want %s got %s", tt.name, tt.recipients, rcpts)
139 d3dfb672 2024-03-18 o }
140 d3dfb672 2024-03-18 o
141 184e4de6 2024-03-13 o p := make([]byte, 8)
142 d3dfb672 2024-03-18 o if _, err := msg.Body.Read(p); err != nil {
143 d3dfb672 2024-03-18 o // Pages have no content, so skip this case
144 184e4de6 2024-03-13 o if a.Type == "Page" {
145 184e4de6 2024-03-13 o continue
146 184e4de6 2024-03-13 o }
147 d3dfb672 2024-03-18 o t.Errorf("%s: read message body: %v", tt.name, err)
148 184e4de6 2024-03-13 o }
149 1d5ddf5d 2024-02-20 o }
150 77918b00 2024-03-07 o }
151 1d5ddf5d 2024-02-20 o
152 77918b00 2024-03-07 o func TestUnmarshalMail(t *testing.T) {
153 77918b00 2024-03-07 o f, err := os.Open("testdata/outbound.eml")
154 1d5ddf5d 2024-02-20 o if err != nil {
155 1d5ddf5d 2024-02-20 o t.Fatal(err)
156 1d5ddf5d 2024-02-20 o }
157 1d5ddf5d 2024-02-20 o defer f.Close()
158 77918b00 2024-03-07 o msg, err := mail.ReadMessage(f)
159 1d5ddf5d 2024-02-20 o if err != nil {
160 1d5ddf5d 2024-02-20 o t.Fatal(err)
161 1d5ddf5d 2024-02-20 o }
162 77918b00 2024-03-07 o if testing.Short() {
163 77918b00 2024-03-07 o t.Skip("skipping network calls to unmarshal mail message to Activity")
164 1d5ddf5d 2024-02-20 o }
165 d3dfb672 2024-03-18 o a, err := UnmarshalMail(msg, nil)
166 d802abd8 2024-03-12 o if err != nil {
167 1d5ddf5d 2024-02-20 o t.Fatal(err)
168 1d5ddf5d 2024-02-20 o }
169 d802abd8 2024-03-12 o if len(a.Tag) != 1 {
170 d802abd8 2024-03-12 o t.Fatalf("wanted 1 tag in unmarshalled activity, got %d", len(a.Tag))
171 d802abd8 2024-03-12 o }
172 d802abd8 2024-03-12 o want := "@henfredemars@infosec.pub"
173 d802abd8 2024-03-12 o if a.Tag[0].Name != want {
174 d802abd8 2024-03-12 o t.Errorf("wanted tag name %s, got %s", want, a.Tag[0].Name)
175 d802abd8 2024-03-12 o }
176 d3dfb672 2024-03-18 o if a.MediaType != "text/markdown" {
177 d3dfb672 2024-03-18 o t.Errorf("wrong media type: wanted %s, got %s", "text/markdown", a.MediaType)
178 d3dfb672 2024-03-18 o }
179 d3dfb672 2024-03-18 o wantCC := []string{
180 d3dfb672 2024-03-18 o "https://programming.dev/c/programming",
181 d3dfb672 2024-03-18 o "https://programming.dev/u/starman",
182 d3dfb672 2024-03-18 o "https://hachyderm.io/users/otl/followers",
183 d3dfb672 2024-03-18 o }
184 d3dfb672 2024-03-18 o if !reflect.DeepEqual(wantCC, a.CC) {
185 d3dfb672 2024-03-18 o t.Errorf("wanted recipients %s, got %s", wantCC, a.CC)
186 d3dfb672 2024-03-18 o }
187 d3dfb672 2024-03-18 o if strings.Contains(a.Content, "\r") {
188 d3dfb672 2024-03-18 o t.Errorf("activity content contains carriage returns")
189 d3dfb672 2024-03-18 o }
190 d3dfb672 2024-03-18 o t.Log(a)
191 1d5ddf5d 2024-02-20 o }