gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

update_test.go (10154B)


      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 account_test
     19 
     20 import (
     21 	"context"
     22 	"testing"
     23 
     24 	"github.com/stretchr/testify/suite"
     25 	"github.com/superseriousbusiness/gotosocial/internal/ap"
     26 	apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
     27 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
     28 )
     29 
     30 type AccountUpdateTestSuite struct {
     31 	AccountStandardTestSuite
     32 }
     33 
     34 func (suite *AccountStandardTestSuite) checkClientAPIChan(accountID string) {
     35 	msg := <-suite.fromClientAPIChan
     36 
     37 	// Profile update.
     38 	suite.Equal(ap.ActivityUpdate, msg.APActivityType)
     39 	suite.Equal(ap.ObjectProfile, msg.APObjectType)
     40 
     41 	// Correct account updated.
     42 	if msg.OriginAccount == nil {
     43 		suite.FailNow("expected msg.OriginAccount not to be nil")
     44 	}
     45 	suite.Equal(accountID, msg.OriginAccount.ID)
     46 }
     47 
     48 func (suite *AccountUpdateTestSuite) TestAccountUpdateSimple() {
     49 	testAccount := &gtsmodel.Account{}
     50 	*testAccount = *suite.testAccounts["local_account_1"]
     51 
     52 	var (
     53 		ctx          = context.Background()
     54 		locked       = true
     55 		displayName  = "new display name"
     56 		note         = "#hello here i am!"
     57 		noteExpected = `<p><a href="http://localhost:8080/tags/hello" class="mention hashtag" rel="tag nofollow noreferrer noopener" target="_blank">#<span>hello</span></a> here i am!</p>`
     58 	)
     59 
     60 	// Call update function.
     61 	apiAccount, errWithCode := suite.accountProcessor.Update(ctx, testAccount, &apimodel.UpdateCredentialsRequest{
     62 		DisplayName: &displayName,
     63 		Locked:      &locked,
     64 		Note:        &note,
     65 	})
     66 	if errWithCode != nil {
     67 		suite.FailNow(errWithCode.Error())
     68 	}
     69 
     70 	// Returned profile should be updated.
     71 	suite.True(apiAccount.Locked)
     72 	suite.Equal(displayName, apiAccount.DisplayName)
     73 	suite.Equal(noteExpected, apiAccount.Note)
     74 
     75 	// We should have an update in the client api channel.
     76 	suite.checkClientAPIChan(testAccount.ID)
     77 
     78 	// Check database model of account as well.
     79 	dbAccount, err := suite.db.GetAccountByID(ctx, testAccount.ID)
     80 	if err != nil {
     81 		suite.FailNow(err.Error())
     82 	}
     83 	suite.True(*dbAccount.Locked)
     84 	suite.Equal(displayName, dbAccount.DisplayName)
     85 	suite.Equal(noteExpected, dbAccount.Note)
     86 }
     87 
     88 func (suite *AccountUpdateTestSuite) TestAccountUpdateWithMention() {
     89 	testAccount := &gtsmodel.Account{}
     90 	*testAccount = *suite.testAccounts["local_account_1"]
     91 
     92 	var (
     93 		ctx          = context.Background()
     94 		locked       = true
     95 		displayName  = "new display name"
     96 		note         = "#hello here i am!\n\ngo check out @1happyturtle, they have a cool account!"
     97 		noteExpected = "<p><a href=\"http://localhost:8080/tags/hello\" class=\"mention hashtag\" rel=\"tag nofollow noreferrer noopener\" target=\"_blank\">#<span>hello</span></a> here i am!<br><br>go check out <span class=\"h-card\"><a href=\"http://localhost:8080/@1happyturtle\" class=\"u-url mention\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">@<span>1happyturtle</span></a></span>, they have a cool account!</p>"
     98 	)
     99 
    100 	// Call update function.
    101 	apiAccount, errWithCode := suite.accountProcessor.Update(ctx, testAccount, &apimodel.UpdateCredentialsRequest{
    102 		DisplayName: &displayName,
    103 		Locked:      &locked,
    104 		Note:        &note,
    105 	})
    106 	if errWithCode != nil {
    107 		suite.FailNow(errWithCode.Error())
    108 	}
    109 
    110 	// Returned profile should be updated.
    111 	suite.True(apiAccount.Locked)
    112 	suite.Equal(displayName, apiAccount.DisplayName)
    113 	suite.Equal(noteExpected, apiAccount.Note)
    114 
    115 	// We should have an update in the client api channel.
    116 	suite.checkClientAPIChan(testAccount.ID)
    117 
    118 	// Check database model of account as well.
    119 	dbAccount, err := suite.db.GetAccountByID(ctx, testAccount.ID)
    120 	if err != nil {
    121 		suite.FailNow(err.Error())
    122 	}
    123 	suite.True(*dbAccount.Locked)
    124 	suite.Equal(displayName, dbAccount.DisplayName)
    125 	suite.Equal(noteExpected, dbAccount.Note)
    126 }
    127 
    128 func (suite *AccountUpdateTestSuite) TestAccountUpdateWithMarkdownNote() {
    129 	testAccount := &gtsmodel.Account{}
    130 	*testAccount = *suite.testAccounts["local_account_1"]
    131 
    132 	var (
    133 		ctx          = context.Background()
    134 		note         = "*hello* ~~here~~ i am!"
    135 		noteExpected = `<p><em>hello</em> <del>here</del> i am!</p>`
    136 	)
    137 
    138 	// Set status content type of account 1 to markdown for this test.
    139 	testAccount.StatusContentType = "text/markdown"
    140 	if err := suite.db.UpdateAccount(ctx, testAccount, "status_content_type"); err != nil {
    141 		suite.FailNow(err.Error())
    142 	}
    143 
    144 	// Call update function.
    145 	apiAccount, errWithCode := suite.accountProcessor.Update(ctx, testAccount, &apimodel.UpdateCredentialsRequest{
    146 		Note: &note,
    147 	})
    148 	if errWithCode != nil {
    149 		suite.FailNow(errWithCode.Error())
    150 	}
    151 
    152 	// Returned profile should be updated.
    153 	suite.Equal(noteExpected, apiAccount.Note)
    154 
    155 	// We should have an update in the client api channel.
    156 	suite.checkClientAPIChan(testAccount.ID)
    157 
    158 	// Check database model of account as well.
    159 	dbAccount, err := suite.db.GetAccountByID(ctx, testAccount.ID)
    160 	if err != nil {
    161 		suite.FailNow(err.Error())
    162 	}
    163 	suite.NoError(err)
    164 	suite.Equal(noteExpected, dbAccount.Note)
    165 }
    166 
    167 func (suite *AccountUpdateTestSuite) TestAccountUpdateWithFields() {
    168 	testAccount := &gtsmodel.Account{}
    169 	*testAccount = *suite.testAccounts["local_account_1"]
    170 
    171 	var (
    172 		ctx          = context.Background()
    173 		updateFields = []apimodel.UpdateField{
    174 			{
    175 				Name:  func() *string { s := "favourite emoji"; return &s }(),
    176 				Value: func() *string { s := ":rainbow:"; return &s }(),
    177 			},
    178 			{
    179 				Name:  func() *string { s := "my website"; return &s }(),
    180 				Value: func() *string { s := "https://example.org"; return &s }(),
    181 			},
    182 		}
    183 		fieldsExpectedRaw = []apimodel.Field{
    184 			{
    185 				Name:       "favourite emoji",
    186 				Value:      ":rainbow:",
    187 				VerifiedAt: (*string)(nil),
    188 			},
    189 			{
    190 				Name:       "my website",
    191 				Value:      "https://example.org",
    192 				VerifiedAt: (*string)(nil),
    193 			},
    194 		}
    195 		fieldsExpectedParsed = []apimodel.Field{
    196 			{
    197 				Name:       "favourite emoji",
    198 				Value:      ":rainbow:",
    199 				VerifiedAt: (*string)(nil),
    200 			},
    201 			{
    202 				Name:       "my website",
    203 				Value:      "<a href=\"https://example.org\" rel=\"nofollow noreferrer noopener\" target=\"_blank\">https://example.org</a>",
    204 				VerifiedAt: (*string)(nil),
    205 			},
    206 		}
    207 		emojisExpected = []apimodel.Emoji{
    208 			{
    209 				Shortcode:       "rainbow",
    210 				URL:             "http://localhost:8080/fileserver/01AY6P665V14JJR0AFVRT7311Y/emoji/original/01F8MH9H8E4VG3KDYJR9EGPXCQ.png",
    211 				StaticURL:       "http://localhost:8080/fileserver/01AY6P665V14JJR0AFVRT7311Y/emoji/static/01F8MH9H8E4VG3KDYJR9EGPXCQ.png",
    212 				VisibleInPicker: true,
    213 				Category:        "reactions",
    214 			},
    215 		}
    216 	)
    217 
    218 	apiAccount, errWithCode := suite.accountProcessor.Update(ctx, testAccount, &apimodel.UpdateCredentialsRequest{
    219 		FieldsAttributes: &updateFields,
    220 	})
    221 	if errWithCode != nil {
    222 		suite.FailNow(errWithCode.Error())
    223 	}
    224 
    225 	// Returned profile should be updated.
    226 	suite.EqualValues(fieldsExpectedRaw, apiAccount.Source.Fields)
    227 	suite.EqualValues(fieldsExpectedParsed, apiAccount.Fields)
    228 	suite.EqualValues(emojisExpected, apiAccount.Emojis)
    229 
    230 	// We should have an update in the client api channel.
    231 	suite.checkClientAPIChan(testAccount.ID)
    232 
    233 	// Check database model of account as well.
    234 	dbAccount, err := suite.db.GetAccountByID(ctx, testAccount.ID)
    235 	if err != nil {
    236 		suite.FailNow(err.Error())
    237 	}
    238 	suite.Equal(fieldsExpectedParsed[0].Name, dbAccount.Fields[0].Name)
    239 	suite.Equal(fieldsExpectedParsed[0].Value, dbAccount.Fields[0].Value)
    240 	suite.Equal(fieldsExpectedParsed[1].Name, dbAccount.Fields[1].Name)
    241 	suite.Equal(fieldsExpectedParsed[1].Value, dbAccount.Fields[1].Value)
    242 	suite.Equal(fieldsExpectedRaw[0].Name, dbAccount.FieldsRaw[0].Name)
    243 	suite.Equal(fieldsExpectedRaw[0].Value, dbAccount.FieldsRaw[0].Value)
    244 	suite.Equal(fieldsExpectedRaw[1].Name, dbAccount.FieldsRaw[1].Name)
    245 	suite.Equal(fieldsExpectedRaw[1].Value, dbAccount.FieldsRaw[1].Value)
    246 }
    247 
    248 func (suite *AccountUpdateTestSuite) TestAccountUpdateNoteNotFields() {
    249 	// local_account_2 already has some fields set.
    250 	// We want to ensure that the fields don't change
    251 	// even if the account note is updated.
    252 	testAccount := &gtsmodel.Account{}
    253 	*testAccount = *suite.testAccounts["local_account_2"]
    254 
    255 	var (
    256 		ctx             = context.Background()
    257 		fieldsRawBefore = len(testAccount.FieldsRaw)
    258 		fieldsBefore    = len(testAccount.Fields)
    259 		note            = "#hello here i am!"
    260 		noteExpected    = `<p><a href="http://localhost:8080/tags/hello" class="mention hashtag" rel="tag nofollow noreferrer noopener" target="_blank">#<span>hello</span></a> here i am!</p>`
    261 	)
    262 
    263 	// Call update function.
    264 	apiAccount, errWithCode := suite.accountProcessor.Update(ctx, testAccount, &apimodel.UpdateCredentialsRequest{
    265 		Note: &note,
    266 	})
    267 	if errWithCode != nil {
    268 		suite.FailNow(errWithCode.Error())
    269 	}
    270 
    271 	// Returned profile should be updated.
    272 	suite.True(apiAccount.Locked)
    273 	suite.Equal(noteExpected, apiAccount.Note)
    274 	suite.Equal(fieldsRawBefore, len(apiAccount.Source.Fields))
    275 	suite.Equal(fieldsBefore, len(apiAccount.Fields))
    276 
    277 	// We should have an update in the client api channel.
    278 	suite.checkClientAPIChan(testAccount.ID)
    279 
    280 	// Check database model of account as well.
    281 	dbAccount, err := suite.db.GetAccountByID(ctx, testAccount.ID)
    282 	if err != nil {
    283 		suite.FailNow(err.Error())
    284 	}
    285 	suite.True(*dbAccount.Locked)
    286 	suite.Equal(noteExpected, dbAccount.Note)
    287 	suite.Equal(fieldsRawBefore, len(dbAccount.FieldsRaw))
    288 	suite.Equal(fieldsBefore, len(dbAccount.Fields))
    289 }
    290 
    291 func TestAccountUpdateTestSuite(t *testing.T) {
    292 	suite.Run(t, new(AccountUpdateTestSuite))
    293 }