Grand test fixup (#138)

* start fixing up tests

* fix up tests + automate with drone

* fiddle with linting

* messing about with drone.yml

* some more fiddling

* hmmm

* add cache

* add vendor directory

* verbose

* ci updates

* update some little things

* update sig
This commit is contained in:
Tobi Smethurst 2021-08-12 21:03:24 +02:00 committed by GitHub
commit 98263a7de6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2677 changed files with 1090869 additions and 219 deletions

View file

@ -156,7 +156,7 @@ func (suite *MediaCreateTestSuite) TestStatusCreatePOSTImageHandlerSuccessful()
}
// check response
suite.EqualValues(http.StatusAccepted, recorder.Code)
suite.EqualValues(http.StatusOK, recorder.Code)
result := recorder.Result()
defer result.Body.Close()

View file

@ -93,13 +93,13 @@ func (suite *StatusCreateTestSuite) TestPostNewStatus() {
ctx.Set(oauth.SessionAuthorizedAccount, suite.testAccounts["local_account_1"])
ctx.Request = httptest.NewRequest(http.MethodPost, fmt.Sprintf("http://localhost:8080/%s", status.BasePath), nil) // the endpoint we're hitting
ctx.Request.Form = url.Values{
"status": {"this is a brand new status! #helloworld"},
"spoiler_text": {"hello hello"},
"sensitive": {"true"},
"visibility_advanced": {"mutuals_only"},
"likeable": {"false"},
"replyable": {"false"},
"federated": {"false"},
"status": {"this is a brand new status! #helloworld"},
"spoiler_text": {"hello hello"},
"sensitive": {"true"},
"visibility": {string(model.VisibilityMutualsOnly)},
"likeable": {"false"},
"replyable": {"false"},
"federated": {"false"},
}
suite.statusModule.StatusCreatePOSTHandler(ctx)
@ -120,7 +120,7 @@ func (suite *StatusCreateTestSuite) TestPostNewStatus() {
assert.Equal(suite.T(), "hello hello", statusReply.SpoilerText)
assert.Equal(suite.T(), "<p>this is a brand new status! <a href=\"http://localhost:8080/tags/helloworld\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>helloworld</span></a></p>", statusReply.Content)
assert.True(suite.T(), statusReply.Sensitive)
assert.Equal(suite.T(), model.VisibilityPrivate, statusReply.Visibility)
assert.Equal(suite.T(), model.VisibilityPrivate, statusReply.Visibility) // even though we set this status to mutuals only, it should serialize to private, because masto has no idea about mutuals_only
assert.Len(suite.T(), statusReply.Tags, 1)
assert.Equal(suite.T(), model.Tag{
Name: "helloworld",
@ -161,13 +161,11 @@ func (suite *StatusCreateTestSuite) TestPostAnotherNewStatus() {
b, err := ioutil.ReadAll(result.Body)
assert.NoError(suite.T(), err)
fmt.Println(string(b))
statusReply := &model.Status{}
err = json.Unmarshal(b, statusReply)
assert.NoError(suite.T(), err)
assert.Equal(suite.T(), "<p><a href=\"http://localhost:8080/tags/test\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>test</span></a> alright, should be able to post <a href=\"http://localhost:8080/tags/links\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>links</span></a> with fragments in them now, let&#39;s see........<br/><br/><a href=\"https://docs.gotosocial.org/en/latest/user_guide/posts/#links\" rel=\"noopener nofollow noreferrer\" target=\"_blank\">docs.gotosocial.org/en/latest/user_guide/posts/#links</a><br/><a href=\"http://localhost:8080/tags/gotosocial\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>gotosocial</span></a><br/><br/>(tobi remember to pull the docker image challenge)</p>", statusReply.Content)
assert.Equal(suite.T(), "\u003cp\u003e\u003ca href=\"http://localhost:8080/tags/test\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\"\u003e#\u003cspan\u003etest\u003c/span\u003e\u003c/a\u003e alright, should be able to post \u003ca href=\"http://localhost:8080/tags/links\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\"\u003e#\u003cspan\u003elinks\u003c/span\u003e\u003c/a\u003e with fragments in them now, let\u0026#39;s see........\u003cbr/\u003e\u003cbr/\u003e\u003ca href=\"https://docs.gotosocial.org/en/latest/user_guide/posts/#links\" rel=\"noopener nofollow noreferrer\" target=\"_blank\"\u003edocs.gotosocial.org/en/latest/user_guide/posts/#links\u003c/a\u003e\u003cbr/\u003e\u003cbr/\u003e\u003ca href=\"http://localhost:8080/tags/gotosocial\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\"\u003e#\u003cspan\u003egotosocial\u003c/span\u003e\u003c/a\u003e\u003cbr/\u003e\u003cbr/\u003e(tobi remember to pull the docker image challenge)\u003c/p\u003e", statusReply.Content)
}
func (suite *StatusCreateTestSuite) TestPostNewStatusWithEmoji() {

View file

@ -19,18 +19,13 @@
package federation_test
import (
"bytes"
"context"
"crypto/x509"
"encoding/pem"
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"strings"
"testing"
"github.com/go-fed/activity/pub"
"github.com/go-fed/httpsig"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
@ -117,63 +112,31 @@ func (suite *ProtocolTestSuite) TestAuthenticatePostInbox() {
sendingAccount := suite.accounts["remote_account_1"]
inboxAccount := suite.accounts["local_account_1"]
encodedPublicKey, err := x509.MarshalPKIXPublicKey(sendingAccount.PublicKey)
assert.NoError(suite.T(), err)
publicKeyBytes := pem.EncodeToMemory(&pem.Block{
Type: "PUBLIC KEY",
Bytes: encodedPublicKey,
})
publicKeyString := strings.ReplaceAll(string(publicKeyBytes), "\n", "\\n")
// for this test we need the client to return the public key of the activity creator on the 'remote' instance
responseBodyString := fmt.Sprintf(`
{
"@context": [
"https://www.w3.org/ns/activitystreams",
"https://w3id.org/security/v1"
],
"id": "%s",
"type": "Person",
"preferredUsername": "%s",
"inbox": "%s",
"publicKey": {
"id": "%s",
"owner": "%s",
"publicKeyPem": "%s"
}
}`, sendingAccount.URI, sendingAccount.Username, sendingAccount.InboxURI, sendingAccount.PublicKeyURI, sendingAccount.URI, publicKeyString)
// create a transport controller whose client will just return the response body string we specified above
tc := testrig.NewTestTransportController(testrig.NewMockHTTPClient(func(req *http.Request) (*http.Response, error) {
r := ioutil.NopCloser(bytes.NewReader([]byte(responseBodyString)))
return &http.Response{
StatusCode: 200,
Body: r,
}, nil
}), suite.db)
tc := testrig.NewTestTransportController(testrig.NewMockHTTPClient(nil), suite.db)
// now setup module being tested, with the mock transport controller
federator := federation.NewFederator(suite.db, testrig.NewTestFederatingDB(suite.db), tc, suite.config, suite.log, suite.typeConverter, testrig.NewTestMediaHandler(suite.db, suite.storage))
// setup request
request := httptest.NewRequest(http.MethodPost, "http://localhost:8080/users/the_mighty_zork/inbox", nil)
// we need these headers for the request to be validated
request.Header.Set("Signature", activity.SignatureHeader)
request.Header.Set("Date", activity.DateHeader)
request.Header.Set("Digest", activity.DigestHeader)
verifier, err := httpsig.NewVerifier(request)
assert.NoError(suite.T(), err)
ctx := context.Background()
// by the time AuthenticatePostInbox is called, PostInboxRequestBodyHook should have already been called,
// which should have set the account and username onto the request. We can replicate that behavior here:
ctxWithAccount := context.WithValue(ctx, util.APAccount, inboxAccount)
ctxWithActivity := context.WithValue(ctxWithAccount, util.APActivity, activity)
ctxWithVerifier := context.WithValue(ctxWithActivity, util.APRequestingPublicKeyVerifier, verifier)
request := httptest.NewRequest(http.MethodPost, "http://localhost:8080/users/the_mighty_zork/inbox", nil) // the endpoint we're hitting
// we need these headers for the request to be validated
request.Header.Set("Signature", activity.SignatureHeader)
request.Header.Set("Date", activity.DateHeader)
request.Header.Set("Digest", activity.DigestHeader)
// we can pass this recorder as a writer and read it back after
recorder := httptest.NewRecorder()
// trigger the function being tested, and return the new context it creates
newContext, authed, err := federator.AuthenticatePostInbox(ctxWithActivity, recorder, request)
newContext, authed, err := federator.AuthenticatePostInbox(ctxWithVerifier, recorder, request)
assert.NoError(suite.T(), err)
assert.True(suite.T(), authed)

View file

@ -21,12 +21,10 @@ import (
"context"
"testing"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/suite"
"github.com/superseriousbusiness/gotosocial/internal/config"
"github.com/superseriousbusiness/gotosocial/internal/db"
"github.com/superseriousbusiness/gotosocial/internal/db/pg"
"github.com/superseriousbusiness/gotosocial/internal/oauth"
"github.com/superseriousbusiness/gotosocial/testrig"
"github.com/superseriousbusiness/oauth2/v4/models"
)
@ -43,7 +41,7 @@ const ()
// SetupSuite sets some variables on the suite that we can use as consts (more or less) throughout
func (suite *PgClientStoreTestSuite) SetupSuite() {
suite.testClientID = "test-client-id"
suite.testClientID = "01FCVB74EW6YBYAEY7QG9CQQF6"
suite.testClientSecret = "test-client-secret"
suite.testClientDomain = "https://example.org"
suite.testClientUserID = "test-client-user-id"
@ -51,50 +49,13 @@ func (suite *PgClientStoreTestSuite) SetupSuite() {
// SetupTest creates a postgres connection and creates the oauth_clients table before each test
func (suite *PgClientStoreTestSuite) SetupTest() {
log := logrus.New()
log.SetLevel(logrus.TraceLevel)
c := config.Empty()
c.DBConfig = &config.DBConfig{
Type: "postgres",
Address: "localhost",
Port: 5432,
User: "postgres",
Password: "postgres",
Database: "postgres",
ApplicationName: "gotosocial",
}
db, err := pg.NewPostgresService(context.Background(), c, log)
if err != nil {
logrus.Panicf("error creating database connection: %s", err)
}
suite.db = db
models := []interface{}{
&oauth.Client{},
}
for _, m := range models {
if err := suite.db.CreateTable(m); err != nil {
logrus.Panicf("db connection error: %s", err)
}
}
suite.db = testrig.NewTestDB()
testrig.StandardDBSetup(suite.db, nil)
}
// TearDownTest drops the oauth_clients table and closes the pg connection after each test
func (suite *PgClientStoreTestSuite) TearDownTest() {
models := []interface{}{
&oauth.Client{},
}
for _, m := range models {
if err := suite.db.DropTable(m); err != nil {
logrus.Panicf("error dropping table: %s", err)
}
}
if err := suite.db.Stop(context.Background()); err != nil {
logrus.Panicf("error closing db connection: %s", err)
}
suite.db = nil
testrig.StandardDBTeardown(suite.db)
}
func (suite *PgClientStoreTestSuite) TestClientStoreSetAndGet() {

View file

@ -25,7 +25,6 @@ import (
"testing"
"github.com/go-fed/activity/streams"
"github.com/go-fed/activity/streams/vocab"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
"github.com/superseriousbusiness/gotosocial/internal/ap"
@ -375,62 +374,6 @@ func (suite *ASToInternalTestSuite) TestParseGargron() {
// TODO: write assertions here, rn we're just eyeballing the output
}
func (suite *ASToInternalTestSuite) TestParseStatus() {
m := make(map[string]interface{})
err := json.Unmarshal([]byte(statusWithEmojisAndTagsAsActivityJson), &m)
assert.NoError(suite.T(), err)
t, err := streams.ToType(context.Background(), m)
assert.NoError(suite.T(), err)
create, ok := t.(vocab.ActivityStreamsCreate)
assert.True(suite.T(), ok)
obj := create.GetActivityStreamsObject()
assert.NotNil(suite.T(), obj)
first := obj.Begin()
assert.NotNil(suite.T(), first)
rep, ok := first.GetType().(ap.Statusable)
assert.True(suite.T(), ok)
status, err := suite.typeconverter.ASStatusToStatus(rep)
assert.NoError(suite.T(), err)
assert.Len(suite.T(), status.GTSEmojis, 3)
// assert.Len(suite.T(), status.GTSTags, 2) TODO: implement this first so that it can pick up tags
}
func (suite *ASToInternalTestSuite) TestParseStatusWithMention() {
m := make(map[string]interface{})
err := json.Unmarshal([]byte(statusWithMentionsActivityJson), &m)
assert.NoError(suite.T(), err)
t, err := streams.ToType(context.Background(), m)
assert.NoError(suite.T(), err)
create, ok := t.(vocab.ActivityStreamsCreate)
assert.True(suite.T(), ok)
obj := create.GetActivityStreamsObject()
assert.NotNil(suite.T(), obj)
first := obj.Begin()
assert.NotNil(suite.T(), first)
rep, ok := first.GetType().(ap.Statusable)
assert.True(suite.T(), ok)
status, err := suite.typeconverter.ASStatusToStatus(rep)
assert.NoError(suite.T(), err)
fmt.Printf("%+v", status)
assert.Len(suite.T(), status.GTSMentions, 1)
fmt.Println(status.GTSMentions[0])
}
func (suite *ASToInternalTestSuite) TearDownTest() {
testrig.StandardDBTeardown(suite.db)
}

View file

@ -32,6 +32,8 @@ func (c *converter) MastoVisToVis(m model.Visibility) gtsmodel.Visibility {
return gtsmodel.VisibilityUnlocked
case model.VisibilityPrivate:
return gtsmodel.VisibilityFollowersOnly
case model.VisibilityMutualsOnly:
return gtsmodel.VisibilityMutualsOnly
case model.VisibilityDirect:
return gtsmodel.VisibilityDirect
}