start updating tests to remove repetition

This commit is contained in:
tsmethurst 2022-06-01 16:11:02 +02:00
parent 098aa4f781
commit 1a3f974223
3 changed files with 220 additions and 23 deletions

View file

@ -23,6 +23,7 @@
"encoding/json"
"io"
"net/http"
"strings"
"codeberg.org/gruf/go-store/kv"
"github.com/sirupsen/logrus"
@ -83,8 +84,9 @@ func (suite *DereferencerStandardTestSuite) mockTransportController() transport.
logrus.Debugf("received request for %s", req.URL)
responseBytes := []byte{}
responseType := ""
responseLength := 0
responseContentType := ""
responseContentLength := 0
responseCode := http.StatusOK
if note, ok := suite.testRemoteStatuses[req.URL.String()]; ok {
// the request is for a note that we have stored
@ -97,7 +99,7 @@ func (suite *DereferencerStandardTestSuite) mockTransportController() transport.
panic(err)
}
responseBytes = noteJson
responseType = "application/activity+json"
responseContentType = "application/activity+json"
}
if person, ok := suite.testRemotePeople[req.URL.String()]; ok {
@ -111,7 +113,7 @@ func (suite *DereferencerStandardTestSuite) mockTransportController() transport.
panic(err)
}
responseBytes = personJson
responseType = "application/activity+json"
responseContentType = "application/activity+json"
}
if group, ok := suite.testRemoteGroups[req.URL.String()]; ok {
@ -125,7 +127,7 @@ func (suite *DereferencerStandardTestSuite) mockTransportController() transport.
panic(err)
}
responseBytes = groupJson
responseType = "application/activity+json"
responseContentType = "application/activity+json"
}
if service, ok := suite.testRemoteServices[req.URL.String()]; ok {
@ -138,28 +140,32 @@ func (suite *DereferencerStandardTestSuite) mockTransportController() transport.
panic(err)
}
responseBytes = serviceJson
responseType = "application/activity+json"
responseContentType = "application/activity+json"
}
if attachment, ok := suite.testRemoteAttachments[req.URL.String()]; ok {
responseBytes = attachment.Data
responseType = attachment.ContentType
responseContentType = attachment.ContentType
}
if strings.Contains(req.URL.String(), ".well-known/webfinger") {
responseCode, responseBytes, responseContentType, _ = testrig.WebfingerResponse(req)
}
if len(responseBytes) != 0 {
// we found something, so print what we're going to return
logrus.Debugf("returning response %s", string(responseBytes))
}
responseLength = len(responseBytes)
responseContentLength = len(responseBytes)
reader := bytes.NewReader(responseBytes)
readCloser := io.NopCloser(reader)
response := &http.Response{
StatusCode: 200,
StatusCode: responseCode,
Body: readCloser,
ContentLength: int64(responseLength),
ContentLength: int64(responseContentLength),
Header: http.Header{
"content-type": {responseType},
"content-type": {responseContentType},
},
}

View file

@ -25,6 +25,7 @@
"io"
"io/ioutil"
"net/http"
"strings"
"codeberg.org/gruf/go-store/kv"
"github.com/stretchr/testify/suite"
@ -118,6 +119,22 @@ func (suite *ProcessingStandardTestSuite) SetupTest() {
suite.sentHTTPRequests[req.URL.String()] = requestBytes
}
if strings.Contains(req.URL.String(), ".well-known/webfinger") {
responseCode, responseBytes, responseContentType, responseContentLength := testrig.WebfingerResponse(req)
reader := bytes.NewReader(responseBytes)
readCloser := io.NopCloser(reader)
response := &http.Response{
StatusCode: responseCode,
Body: readCloser,
ContentLength: int64(responseContentLength),
Header: http.Header{
"content-type": {responseContentType},
},
}
return response, nil
}
if req.URL.String() == suite.testAccounts["remote_account_1"].URI {
// the request is for remote account 1
satan := suite.testAccounts["remote_account_1"]

View file

@ -20,10 +20,15 @@
import (
"bytes"
"io/ioutil"
"encoding/json"
"io"
"net/http"
"strings"
"github.com/sirupsen/logrus"
"github.com/superseriousbusiness/activity/pub"
"github.com/superseriousbusiness/activity/streams"
apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
"github.com/superseriousbusiness/gotosocial/internal/concurrency"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/federation"
@ -44,24 +49,101 @@ func NewTestTransportController(client pub.HttpClient, db db.DB, fedWorker *conc
return transport.NewController(db, NewTestFederatingDB(db, fedWorker), &federation.Clock{}, client)
}
// NewMockHTTPClient returns a client that conforms to the pub.HttpClient interface,
// but will always just execute the given `do` function, allowing responses to be mocked.
// NewMockHTTPClient returns a client that conforms to the pub.HttpClient interface.
//
// If 'do' is nil, then a no-op function will be used instead, that just returns status 200.
// If do is nil, then a standard response set will be mocked out, which includes models stored in the
// testrig, and webfinger responses as well.
//
// If do is not nil, then the given do function will always be used, which allows callers
// to customize how the client is mocked.
//
// Note that you should never ever make ACTUAL http calls with this thing.
func NewMockHTTPClient(do func(req *http.Request) (*http.Response, error)) pub.HttpClient {
if do == nil {
return &mockHTTPClient{
do: func(req *http.Request) (*http.Response, error) {
r := ioutil.NopCloser(bytes.NewReader([]byte{}))
return &http.Response{
StatusCode: 200,
Body: r,
}, nil
},
do = func(req *http.Request) (*http.Response, error) {
responseCode := http.StatusNotFound
responseBytes := []byte(`{"error":"404 not found"}`)
responseContentType := "application/json"
responseContentLength := len(responseBytes)
if strings.Contains(req.URL.String(), ".well-known/webfinger") {
responseCode, responseBytes, responseContentType, responseContentLength = WebfingerResponse(req)
} else {
if note, ok := suite.testRemoteStatuses[req.URL.String()]; ok {
// the request is for a note that we have stored
noteI, err := streams.Serialize(note)
if err != nil {
panic(err)
}
noteJson, err := json.Marshal(noteI)
if err != nil {
panic(err)
}
responseBytes = noteJson
responseContentType = "application/activity+json"
}
if person, ok := suite.testRemotePeople[req.URL.String()]; ok {
// the request is for a person that we have stored
personI, err := streams.Serialize(person)
if err != nil {
panic(err)
}
personJson, err := json.Marshal(personI)
if err != nil {
panic(err)
}
responseBytes = personJson
responseContentType = "application/activity+json"
}
if group, ok := suite.testRemoteGroups[req.URL.String()]; ok {
// the request is for a person that we have stored
groupI, err := streams.Serialize(group)
if err != nil {
panic(err)
}
groupJson, err := json.Marshal(groupI)
if err != nil {
panic(err)
}
responseBytes = groupJson
responseContentType = "application/activity+json"
}
if service, ok := suite.testRemoteServices[req.URL.String()]; ok {
serviceI, err := streams.Serialize(service)
if err != nil {
panic(err)
}
serviceJson, err := json.Marshal(serviceI)
if err != nil {
panic(err)
}
responseBytes = serviceJson
responseContentType = "application/activity+json"
}
if attachment, ok := suite.testRemoteAttachments[req.URL.String()]; ok {
responseBytes = attachment.Data
responseContentType = attachment.ContentType
}
}
logrus.Debugf("returning response %s", string(responseBytes))
reader := bytes.NewReader(responseBytes)
readCloser := io.NopCloser(reader)
return &http.Response{
StatusCode: responseCode,
Body: readCloser,
ContentLength: int64(responseContentLength),
Header: http.Header{
"content-type": {responseContentType},
},
}, nil
}
}
return &mockHTTPClient{
do: do,
}
@ -74,3 +156,95 @@ type mockHTTPClient struct {
func (m *mockHTTPClient) Do(req *http.Request) (*http.Response, error) {
return m.do(req)
}
func WebfingerResponse(req *http.Request) (responseCode int, responseBytes []byte, responseContentType string, responseContentLength int) {
var wfr *apimodel.WellKnownResponse
switch req.URL.String() {
case "https://unknown-instance.com/.well-known/webfinger?resource=acct:some_group@unknown-instance.com":
wfr = &apimodel.WellKnownResponse{
Subject: "acct:some_group@unknown-instance.com",
Links: []apimodel.Link{
{
Rel: "self",
Type: "application/activity+json",
Href: "https://unknown-instance.com/groups/some_group",
},
},
}
case "https://owncast.example.org/.well-known/webfinger?resource=acct:rgh@owncast.example.org":
wfr = &apimodel.WellKnownResponse{
Subject: "acct:rgh@example.org",
Links: []apimodel.Link{
{
Rel: "self",
Type: "application/activity+json",
Href: "https://owncast.example.org/federation/user/rgh",
},
},
}
case "https://unknown-instance.com/.well-known/webfinger?resource=acct:brand_new_person@unknown-instance.com":
wfr = &apimodel.WellKnownResponse{
Subject: "acct:brand_new_person@unknown-instance.com",
Links: []apimodel.Link{
{
Rel: "self",
Type: "application/activity+json",
Href: "https://unknown-instance.com/users/brand_new_person",
},
},
}
case "https://turnip.farm/.well-known/webfinger?resource=acct:turniplover6969@turnip.farm":
wfr = &apimodel.WellKnownResponse{
Subject: "acct:turniplover6969@turnip.farm",
Links: []apimodel.Link{
{
Rel: "self",
Type: "application/activity+json",
Href: "https://turnip.farm/users/turniplover6969",
},
},
}
case "https://fossbros-anonymous.io/.well-known/webfinger?resource=acct:foss_satan@fossbros-anonymous.io":
wfr = &apimodel.WellKnownResponse{
Subject: "acct:foss_satan@fossbros-anonymous.io",
Links: []apimodel.Link{
{
Rel: "self",
Type: "application/activity+json",
Href: "https://fossbros-anonymous.io/users/foss_satan",
},
},
}
case "https://example.org/.well-known/webfinger?resource=acct:some_user@example.org":
wfr = &apimodel.WellKnownResponse{
Subject: "acct:some_user@example.org",
Links: []apimodel.Link{
{
Rel: "self",
Type: "application/activity+json",
Href: "https://example.org/users/some_user",
},
},
}
}
if wfr == nil {
logrus.Debugf("webfinger response not available for %s", req.URL)
responseCode = http.StatusNotFound
responseBytes = []byte(`{"error":"not found"}`)
responseContentType = "application/json"
responseContentLength = len(responseBytes)
return
}
wfrJson, err := json.Marshal(wfr)
if err != nil {
panic(err)
}
responseCode = http.StatusOK
responseBytes = wfrJson
responseContentType = "application/json"
responseContentLength = len(wfrJson)
return
}