federatingactor_test.go (7112B)
1 // GoToSocial 2 // Copyright (C) GoToSocial Authors admin@gotosocial.org 3 // SPDX-License-Identifier: AGPL-3.0-or-later 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU Affero General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU Affero General Public License for more details. 14 // 15 // You should have received a copy of the GNU Affero General Public License 16 // along with this program. If not, see <http://www.gnu.org/licenses/>. 17 18 package federation_test 19 20 import ( 21 "bytes" 22 "context" 23 "encoding/json" 24 "net/url" 25 "testing" 26 "time" 27 28 "github.com/stretchr/testify/suite" 29 "github.com/superseriousbusiness/gotosocial/internal/federation" 30 "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" 31 "github.com/superseriousbusiness/gotosocial/testrig" 32 ) 33 34 type FederatingActorTestSuite struct { 35 FederatorStandardTestSuite 36 } 37 38 func (suite *FederatingActorTestSuite) TestSendNoRemoteFollowers() { 39 ctx := context.Background() 40 testAccount := suite.testAccounts["local_account_1"] 41 testNote := testrig.NewAPNote( 42 testrig.URLMustParse("http://localhost:8080/users/the_mighty_zork/statuses/01G1TR6BADACCZWQMNF9X21TV5"), 43 testrig.URLMustParse("http://localhost:8080/@the_mighty_zork/statuses/01G1TR6BADACCZWQMNF9X21TV5"), 44 time.Now(), 45 "boobies", 46 "", 47 testrig.URLMustParse(testAccount.URI), 48 []*url.URL{testrig.URLMustParse(testAccount.FollowersURI)}, 49 nil, 50 false, 51 nil, 52 nil, 53 ) 54 testActivity := testrig.WrapAPNoteInCreate(testrig.URLMustParse("http://localhost:8080/whatever_some_create"), testrig.URLMustParse(testAccount.URI), time.Now(), testNote) 55 56 // setup transport controller with a no-op client so we don't make external calls 57 httpClient := testrig.NewMockHTTPClient(nil, "../../testrig/media") 58 tc := testrig.NewTestTransportController(&suite.state, httpClient) 59 60 // setup module being tested 61 federator := federation.NewFederator(&suite.state, testrig.NewTestFederatingDB(&suite.state), tc, suite.typeconverter, testrig.NewTestMediaManager(&suite.state)) 62 63 activity, err := federator.FederatingActor().Send(ctx, testrig.URLMustParse(testAccount.OutboxURI), testActivity) 64 suite.NoError(err) 65 suite.NotNil(activity) 66 67 // because zork has no remote followers, sent messages should be empty (no messages sent to own instance) 68 suite.Empty(httpClient.SentMessages) 69 } 70 71 func (suite *FederatingActorTestSuite) TestSendRemoteFollower() { 72 ctx := context.Background() 73 testAccount := suite.testAccounts["local_account_1"] 74 testRemoteAccount := suite.testAccounts["remote_account_1"] 75 76 err := suite.state.DB.Put(ctx, >smodel.Follow{ 77 ID: "01G1TRWV4AYCDBX5HRWT2EVBCV", 78 CreatedAt: testrig.TimeMustParse("2022-06-02T12:22:21+02:00"), 79 UpdatedAt: testrig.TimeMustParse("2022-06-02T12:22:21+02:00"), 80 AccountID: testRemoteAccount.ID, 81 TargetAccountID: testAccount.ID, 82 ShowReblogs: testrig.TrueBool(), 83 URI: "http://fossbros-anonymous.io/users/foss_satan/follows/01G1TRWV4AYCDBX5HRWT2EVBCV", 84 Notify: testrig.FalseBool(), 85 }) 86 suite.NoError(err) 87 88 testNote := testrig.NewAPNote( 89 testrig.URLMustParse("http://localhost:8080/users/the_mighty_zork/statuses/01G1TR6BADACCZWQMNF9X21TV5"), 90 testrig.URLMustParse("http://localhost:8080/@the_mighty_zork/statuses/01G1TR6BADACCZWQMNF9X21TV5"), 91 testrig.TimeMustParse("2022-06-02T12:22:21+02:00"), 92 "boobies", 93 "", 94 testrig.URLMustParse(testAccount.URI), 95 []*url.URL{testrig.URLMustParse(testAccount.FollowersURI)}, 96 nil, 97 false, 98 nil, 99 nil, 100 ) 101 testActivity := testrig.WrapAPNoteInCreate(testrig.URLMustParse("http://localhost:8080/whatever_some_create"), testrig.URLMustParse(testAccount.URI), testrig.TimeMustParse("2022-06-02T12:22:21+02:00"), testNote) 102 103 httpClient := testrig.NewMockHTTPClient(nil, "../../testrig/media") 104 tc := testrig.NewTestTransportController(&suite.state, httpClient) 105 // setup module being tested 106 federator := federation.NewFederator(&suite.state, testrig.NewTestFederatingDB(&suite.state), tc, suite.typeconverter, testrig.NewTestMediaManager(&suite.state)) 107 108 activity, err := federator.FederatingActor().Send(ctx, testrig.URLMustParse(testAccount.OutboxURI), testActivity) 109 suite.NoError(err) 110 suite.NotNil(activity) 111 112 // because we added 1 remote follower for zork, there should be a url in sentMessage 113 var sent [][]byte 114 if !testrig.WaitFor(func() bool { 115 sentI, ok := httpClient.SentMessages.Load(*testRemoteAccount.SharedInboxURI) 116 if ok { 117 sent, ok = sentI.([][]byte) 118 if !ok { 119 panic("SentMessages entry was not []byte") 120 } 121 return true 122 } 123 return false 124 }) { 125 suite.FailNow("timed out waiting for message") 126 } 127 128 dst := new(bytes.Buffer) 129 err = json.Indent(dst, sent[0], "", " ") 130 suite.NoError(err) 131 suite.Equal(`{ 132 "@context": "https://www.w3.org/ns/activitystreams", 133 "actor": "http://localhost:8080/users/the_mighty_zork", 134 "id": "http://localhost:8080/whatever_some_create", 135 "object": { 136 "attributedTo": "http://localhost:8080/users/the_mighty_zork", 137 "content": "boobies", 138 "id": "http://localhost:8080/users/the_mighty_zork/statuses/01G1TR6BADACCZWQMNF9X21TV5", 139 "published": "2022-06-02T12:22:21+02:00", 140 "tag": [], 141 "to": "http://localhost:8080/users/the_mighty_zork/followers", 142 "type": "Note", 143 "url": "http://localhost:8080/@the_mighty_zork/statuses/01G1TR6BADACCZWQMNF9X21TV5" 144 }, 145 "published": "2022-06-02T12:22:21+02:00", 146 "to": "http://localhost:8080/users/the_mighty_zork/followers", 147 "type": "Create" 148 }`, dst.String()) 149 } 150 151 func TestFederatingActorTestSuite(t *testing.T) { 152 suite.Run(t, new(FederatingActorTestSuite)) 153 } 154 155 func TestIsASMediaType(t *testing.T) { 156 for _, test := range []struct { 157 Input string 158 Expect bool 159 }{ 160 { 161 Input: "application/activity+json", 162 Expect: true, 163 }, 164 { 165 Input: "application/ld+json;profile=https://www.w3.org/ns/activitystreams", 166 Expect: true, 167 }, 168 { 169 Input: "application/ld+json;profile=\"https://www.w3.org/ns/activitystreams\"", 170 Expect: true, 171 }, 172 { 173 Input: "application/ld+json ;profile=https://www.w3.org/ns/activitystreams", 174 Expect: true, 175 }, 176 { 177 Input: "application/ld+json ;profile=\"https://www.w3.org/ns/activitystreams\"", 178 Expect: true, 179 }, 180 { 181 Input: "application/ld+json ; profile=https://www.w3.org/ns/activitystreams", 182 Expect: true, 183 }, 184 { 185 Input: "application/ld+json ; profile=\"https://www.w3.org/ns/activitystreams\"", 186 Expect: true, 187 }, 188 { 189 Input: "application/ld+json; profile=https://www.w3.org/ns/activitystreams", 190 Expect: true, 191 }, 192 { 193 Input: "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"", 194 Expect: true, 195 }, 196 } { 197 if federation.IsASMediaType(test.Input) != test.Expect { 198 t.Errorf("did not get expected result %v for input: %s", test.Expect, test.Input) 199 } 200 } 201 }