From 941893a774c83802afdc4cc76e1d30c59b6c5585 Mon Sep 17 00:00:00 2001
From: tobi <31960611+tsmethurst@users.noreply.github.com>
Date: Mon, 2 Jan 2023 13:10:50 +0100
Subject: [chore] The Big Middleware and API Refactor (tm) (#1250)
* interim commit: start refactoring middlewares into package under router
* another interim commit, this is becoming a big job
* another fucking massive interim commit
* refactor bookmarks to new style
* ambassador, wiz zeze commits you are spoiling uz
* she compiles, we're getting there
* we're just normal men; we're just innocent men
* apiutil
* whoopsie
* i'm glad noone reads commit msgs haha :blob_sweat:
* use that weirdo go-bytesize library for maxMultipartMemory
* fix media module paths
---
internal/api/client/statuses/statuscreate_test.go | 398 ++++++++++++++++++++++
1 file changed, 398 insertions(+)
create mode 100644 internal/api/client/statuses/statuscreate_test.go
(limited to 'internal/api/client/statuses/statuscreate_test.go')
diff --git a/internal/api/client/statuses/statuscreate_test.go b/internal/api/client/statuses/statuscreate_test.go
new file mode 100644
index 000000000..3648d7520
--- /dev/null
+++ b/internal/api/client/statuses/statuscreate_test.go
@@ -0,0 +1,398 @@
+/*
+ GoToSocial
+ Copyright (C) 2021-2022 GoToSocial Authors admin@gotosocial.org
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see "
+ statusMarkdownExpected = "
This is a post written in markdown
this is a brand new status! #helloworld
", statusReply.Content) + suite.True(statusReply.Sensitive) + suite.Equal(apimodel.VisibilityPrivate, statusReply.Visibility) // even though we set this status to mutuals only, it should serialize to private, because the mastodon api has no idea about mutuals_only + suite.Len(statusReply.Tags, 1) + suite.Equal(apimodel.Tag{ + Name: "helloworld", + URL: "http://localhost:8080/tags/helloworld", + }, statusReply.Tags[0]) + + gtsTag := >smodel.Tag{} + err = suite.db.GetWhere(context.Background(), []db.Where{{Key: "name", Value: "helloworld"}}, gtsTag) + suite.NoError(err) + suite.Equal(statusReply.Account.ID, gtsTag.FirstSeenFromAccountID) +} + +func (suite *StatusCreateTestSuite) TestPostNewStatusMarkdown() { + // set default post language of account 1 to markdown + testAccount := suite.testAccounts["local_account_1"] + testAccount.StatusFormat = "markdown" + a := testAccount + + err := suite.db.UpdateAccount(context.Background(), a) + if err != nil { + suite.FailNow(err.Error()) + } + suite.Equal(a.StatusFormat, "markdown") + + t := suite.testTokens["local_account_1"] + oauthToken := oauth.DBTokenToToken(t) + + recorder := httptest.NewRecorder() + ctx, _ := testrig.CreateGinTestContext(recorder, nil) + ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplications["application_1"]) + ctx.Set(oauth.SessionAuthorizedToken, oauthToken) + ctx.Set(oauth.SessionAuthorizedUser, suite.testUsers["local_account_1"]) + ctx.Set(oauth.SessionAuthorizedAccount, a) + + ctx.Request = httptest.NewRequest(http.MethodPost, fmt.Sprintf("http://localhost:8080/%s", statuses.BasePath), nil) + ctx.Request.Header.Set("accept", "application/json") + ctx.Request.Form = url.Values{ + "status": {statusMarkdown}, + "visibility": {string(apimodel.VisibilityPublic)}, + } + suite.statusModule.StatusCreatePOSTHandler(ctx) + + suite.EqualValues(http.StatusOK, recorder.Code) + + result := recorder.Result() + defer result.Body.Close() + b, err := ioutil.ReadAll(result.Body) + suite.NoError(err) + + statusReply := &apimodel.Status{} + err = json.Unmarshal(b, statusReply) + suite.NoError(err) + + suite.Equal(statusMarkdownExpected, statusReply.Content) +} + +// mention an account that is not yet known to the instance -- it should be looked up and put in the db +func (suite *StatusCreateTestSuite) TestMentionUnknownAccount() { + // first remove remote account 1 from the database so it gets looked up again + remoteAccount := suite.testAccounts["remote_account_1"] + err := suite.db.DeleteAccount(context.Background(), remoteAccount.ID) + suite.NoError(err) + + t := suite.testTokens["local_account_1"] + oauthToken := oauth.DBTokenToToken(t) + + // setup + recorder := httptest.NewRecorder() + ctx, _ := testrig.CreateGinTestContext(recorder, nil) + ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplications["application_1"]) + ctx.Set(oauth.SessionAuthorizedToken, oauthToken) + ctx.Set(oauth.SessionAuthorizedUser, suite.testUsers["local_account_1"]) + ctx.Set(oauth.SessionAuthorizedAccount, suite.testAccounts["local_account_1"]) + ctx.Request = httptest.NewRequest(http.MethodPost, fmt.Sprintf("http://localhost:8080/%s", statuses.BasePath), nil) // the endpoint we're hitting + ctx.Request.Header.Set("accept", "application/json") + ctx.Request.Form = url.Values{ + "status": {"hello @brand_new_person@unknown-instance.com"}, + "visibility": {string(apimodel.VisibilityPublic)}, + } + suite.statusModule.StatusCreatePOSTHandler(ctx) + + suite.EqualValues(http.StatusOK, recorder.Code) + + result := recorder.Result() + defer result.Body.Close() + b, err := ioutil.ReadAll(result.Body) + suite.NoError(err) + + statusReply := &apimodel.Status{} + err = json.Unmarshal(b, statusReply) + suite.NoError(err) + + // if the status is properly formatted, that means the account has been put in the db + suite.Equal(`hello @brand_new_person
`, statusReply.Content) + suite.Equal(apimodel.VisibilityPublic, statusReply.Visibility) +} + +func (suite *StatusCreateTestSuite) TestPostAnotherNewStatus() { + t := suite.testTokens["local_account_1"] + oauthToken := oauth.DBTokenToToken(t) + + // setup + recorder := httptest.NewRecorder() + ctx, _ := testrig.CreateGinTestContext(recorder, nil) + ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplications["application_1"]) + ctx.Set(oauth.SessionAuthorizedToken, oauthToken) + ctx.Set(oauth.SessionAuthorizedUser, suite.testUsers["local_account_1"]) + ctx.Set(oauth.SessionAuthorizedAccount, suite.testAccounts["local_account_1"]) + ctx.Request = httptest.NewRequest(http.MethodPost, fmt.Sprintf("http://localhost:8080/%s", statuses.BasePath), nil) // the endpoint we're hitting + ctx.Request.Header.Set("accept", "application/json") + ctx.Request.Form = url.Values{ + "status": {statusWithLinksAndTags}, + } + suite.statusModule.StatusCreatePOSTHandler(ctx) + + // check response + + // 1. we should have OK from our call to the function + suite.EqualValues(http.StatusOK, recorder.Code) + + result := recorder.Result() + defer result.Body.Close() + b, err := ioutil.ReadAll(result.Body) + suite.NoError(err) + + statusReply := &apimodel.Status{} + err = json.Unmarshal(b, statusReply) + suite.NoError(err) + + suite.Equal("#test alright, should be able to post #links with fragments in them now, let's see........
docs.gotosocial.org/en/latest/user_guide/posts/#links
#gotosocial
(tobi remember to pull the docker image challenge)
here is a rainbow emoji a few times! :rainbow: :rainbow: :rainbow:
here's an emoji that isn't in the db: :test_emoji:
hello @%s this reply should work!
", testrig.NewTestAccounts()["local_account_2"].Username, testrig.NewTestAccounts()["local_account_2"].Username), statusReply.Content) + suite.False(statusReply.Sensitive) + suite.Equal(apimodel.VisibilityPublic, statusReply.Visibility) + suite.Equal(testrig.NewTestStatuses()["local_account_2_status_1"].ID, *statusReply.InReplyToID) + suite.Equal(testrig.NewTestAccounts()["local_account_2"].ID, *statusReply.InReplyToAccountID) + suite.Len(statusReply.Mentions, 1) +} + +// Take a media file which is currently not associated with a status, and attach it to a new status. +func (suite *StatusCreateTestSuite) TestAttachNewMediaSuccess() { + t := suite.testTokens["local_account_1"] + oauthToken := oauth.DBTokenToToken(t) + + attachment := suite.testAttachments["local_account_1_unattached_1"] + + // setup + recorder := httptest.NewRecorder() + ctx, _ := testrig.CreateGinTestContext(recorder, nil) + ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplications["application_1"]) + ctx.Set(oauth.SessionAuthorizedToken, oauthToken) + ctx.Set(oauth.SessionAuthorizedUser, suite.testUsers["local_account_1"]) + ctx.Set(oauth.SessionAuthorizedAccount, suite.testAccounts["local_account_1"]) + ctx.Request = httptest.NewRequest(http.MethodPost, fmt.Sprintf("http://localhost:8080/%s", statuses.BasePath), nil) // the endpoint we're hitting + ctx.Request.Header.Set("accept", "application/json") + ctx.Request.Form = url.Values{ + "status": {"here's an image attachment"}, + "media_ids[]": {attachment.ID}, + } + suite.statusModule.StatusCreatePOSTHandler(ctx) + + // check response + suite.EqualValues(http.StatusOK, recorder.Code) + + result := recorder.Result() + defer result.Body.Close() + b, err := ioutil.ReadAll(result.Body) + suite.NoError(err) + + statusResponse := &apimodel.Status{} + err = json.Unmarshal(b, statusResponse) + suite.NoError(err) + + suite.Equal("", statusResponse.SpoilerText) + suite.Equal("here's an image attachment
", statusResponse.Content) + suite.False(statusResponse.Sensitive) + suite.Equal(apimodel.VisibilityPublic, statusResponse.Visibility) + + // there should be one media attachment + suite.Len(statusResponse.MediaAttachments, 1) + + // get the updated media attachment from the database + gtsAttachment, err := suite.db.GetAttachmentByID(context.Background(), statusResponse.MediaAttachments[0].ID) + suite.NoError(err) + + // convert it to a api attachment + gtsAttachmentAsapi, err := suite.tc.AttachmentToAPIAttachment(context.Background(), gtsAttachment) + suite.NoError(err) + + // compare it with what we have now + suite.EqualValues(statusResponse.MediaAttachments[0], gtsAttachmentAsapi) + + // the status id of the attachment should now be set to the id of the status we just created + suite.Equal(statusResponse.ID, gtsAttachment.StatusID) +} + +func TestStatusCreateTestSuite(t *testing.T) { + suite.Run(t, new(StatusCreateTestSuite)) +} -- cgit v1.2.3