gtsocial-umbx

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

statuses_test.go (10560B)


      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 accounts_test
     19 
     20 import (
     21 	"encoding/json"
     22 	"fmt"
     23 	"io/ioutil"
     24 	"net/http"
     25 	"net/http/httptest"
     26 	"testing"
     27 
     28 	"github.com/gin-gonic/gin"
     29 	"github.com/stretchr/testify/suite"
     30 	"github.com/superseriousbusiness/gotosocial/internal/api/client/accounts"
     31 	apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
     32 	"github.com/superseriousbusiness/gotosocial/internal/oauth"
     33 )
     34 
     35 type AccountStatusesTestSuite struct {
     36 	AccountStandardTestSuite
     37 }
     38 
     39 func (suite *AccountStatusesTestSuite) TestGetStatusesPublicOnly() {
     40 	// set up the request
     41 	// we're getting statuses of admin
     42 	targetAccount := suite.testAccounts["admin_account"]
     43 	recorder := httptest.NewRecorder()
     44 	ctx := suite.newContext(recorder, http.MethodGet, nil, fmt.Sprintf("/api/v1/accounts/%s/statuses?limit=20&only_media=false&only_public=true", targetAccount.ID), "")
     45 	ctx.Params = gin.Params{
     46 		gin.Param{
     47 			Key:   accounts.IDKey,
     48 			Value: targetAccount.ID,
     49 		},
     50 	}
     51 
     52 	// call the handler
     53 	suite.accountsModule.AccountStatusesGETHandler(ctx)
     54 
     55 	// 1. we should have OK because our request was valid
     56 	suite.Equal(http.StatusOK, recorder.Code)
     57 
     58 	// 2. we should have no error message in the result body
     59 	result := recorder.Result()
     60 	defer result.Body.Close()
     61 
     62 	// check the response
     63 	b, err := ioutil.ReadAll(result.Body)
     64 	suite.NoError(err)
     65 
     66 	// unmarshal the returned statuses
     67 	apimodelStatuses := []*apimodel.Status{}
     68 	err = json.Unmarshal(b, &apimodelStatuses)
     69 	suite.NoError(err)
     70 	suite.NotEmpty(apimodelStatuses)
     71 
     72 	for _, s := range apimodelStatuses {
     73 		suite.Equal(apimodel.VisibilityPublic, s.Visibility)
     74 	}
     75 
     76 	suite.Equal(`<http://localhost:8080/api/v1/accounts/01F8MH17FWEB39HZJ76B6VXSKF/statuses?limit=20&max_id=01F8MH75CBF9JFX4ZAD54N0W0R&exclude_replies=false&exclude_reblogs=false&pinned=false&only_media=false&only_public=true>; rel="next", <http://localhost:8080/api/v1/accounts/01F8MH17FWEB39HZJ76B6VXSKF/statuses?limit=20&min_id=01G36SF3V6Y6V5BF9P4R7PQG7G&exclude_replies=false&exclude_reblogs=false&pinned=false&only_media=false&only_public=true>; rel="prev"`, result.Header.Get("link"))
     77 }
     78 
     79 func (suite *AccountStatusesTestSuite) TestGetStatusesPublicOnlyMediaOnly() {
     80 	// set up the request
     81 	// we're getting statuses of admin
     82 	targetAccount := suite.testAccounts["admin_account"]
     83 	recorder := httptest.NewRecorder()
     84 	ctx := suite.newContext(recorder, http.MethodGet, nil, fmt.Sprintf("/api/v1/accounts/%s/statuses?limit=20&only_media=true&only_public=true", targetAccount.ID), "")
     85 	ctx.Params = gin.Params{
     86 		gin.Param{
     87 			Key:   accounts.IDKey,
     88 			Value: targetAccount.ID,
     89 		},
     90 	}
     91 
     92 	// call the handler
     93 	suite.accountsModule.AccountStatusesGETHandler(ctx)
     94 
     95 	// 1. we should have OK because our request was valid
     96 	suite.Equal(http.StatusOK, recorder.Code)
     97 
     98 	// 2. we should have no error message in the result body
     99 	result := recorder.Result()
    100 	defer result.Body.Close()
    101 
    102 	// check the response
    103 	b, err := ioutil.ReadAll(result.Body)
    104 	suite.NoError(err)
    105 
    106 	// unmarshal the returned statuses
    107 	apimodelStatuses := []*apimodel.Status{}
    108 	err = json.Unmarshal(b, &apimodelStatuses)
    109 	suite.NoError(err)
    110 	suite.NotEmpty(apimodelStatuses)
    111 
    112 	for _, s := range apimodelStatuses {
    113 		suite.NotEmpty(s.MediaAttachments)
    114 		suite.Equal(apimodel.VisibilityPublic, s.Visibility)
    115 	}
    116 
    117 	suite.Equal(`<http://localhost:8080/api/v1/accounts/01F8MH17FWEB39HZJ76B6VXSKF/statuses?limit=20&max_id=01F8MH75CBF9JFX4ZAD54N0W0R&exclude_replies=false&exclude_reblogs=false&pinned=false&only_media=true&only_public=true>; rel="next", <http://localhost:8080/api/v1/accounts/01F8MH17FWEB39HZJ76B6VXSKF/statuses?limit=20&min_id=01F8MH75CBF9JFX4ZAD54N0W0R&exclude_replies=false&exclude_reblogs=false&pinned=false&only_media=true&only_public=true>; rel="prev"`, result.Header.Get("link"))
    118 }
    119 
    120 func (suite *AccountStatusesTestSuite) TestGetStatusesPinnedOnlyPublicPins() {
    121 	// admin has a couple statuses pinned
    122 	// we're getting pinned statuses of admin, as local account 1
    123 	targetAccount := suite.testAccounts["admin_account"]
    124 	recorder := httptest.NewRecorder()
    125 	ctx := suite.newContext(recorder, http.MethodGet, nil, fmt.Sprintf("/api/v1/accounts/%s/statuses?pinned=true", targetAccount.ID), "")
    126 	ctx.Params = gin.Params{
    127 		gin.Param{
    128 			Key:   accounts.IDKey,
    129 			Value: targetAccount.ID,
    130 		},
    131 	}
    132 
    133 	// call the handler
    134 	suite.accountsModule.AccountStatusesGETHandler(ctx)
    135 
    136 	// 1. we should have OK because our request was valid
    137 	suite.Equal(http.StatusOK, recorder.Code)
    138 
    139 	// 2. we should have no error message in the result body
    140 	result := recorder.Result()
    141 	defer result.Body.Close()
    142 
    143 	// check the response
    144 	b, err := ioutil.ReadAll(result.Body)
    145 	suite.NoError(err)
    146 
    147 	// unmarshal the returned statuses
    148 	apimodelStatuses := []*apimodel.Status{}
    149 	err = json.Unmarshal(b, &apimodelStatuses)
    150 	suite.NoError(err)
    151 	suite.Len(apimodelStatuses, 2)
    152 	suite.Empty(result.Header.Get("link"))
    153 
    154 	for _, s := range apimodelStatuses {
    155 		// Requesting account doesn't own these
    156 		// statuses, so pinned should be false.
    157 		suite.False(s.Pinned)
    158 	}
    159 }
    160 
    161 func (suite *AccountStatusesTestSuite) TestGetStatusesPinnedOnlyNotFollowing() {
    162 	// local account 2 has a followers-only status pinned
    163 	// we're getting pinned statuses of local account 2 with an account that doesn't follow it
    164 	targetAccount := suite.testAccounts["local_account_2"]
    165 	recorder := httptest.NewRecorder()
    166 	ctx := suite.newContext(recorder, http.MethodGet, nil, fmt.Sprintf("/api/v1/accounts/%s/statuses?pinned=true", targetAccount.ID), "")
    167 	ctx.Set(oauth.SessionAuthorizedAccount, suite.testAccounts["admin_account"])
    168 	ctx.Set(oauth.SessionAuthorizedToken, oauth.DBTokenToToken(suite.testTokens["admin_account"]))
    169 	ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplications["application_1"])
    170 	ctx.Set(oauth.SessionAuthorizedUser, suite.testUsers["admin_account"])
    171 	ctx.Params = gin.Params{
    172 		gin.Param{
    173 			Key:   accounts.IDKey,
    174 			Value: targetAccount.ID,
    175 		},
    176 	}
    177 
    178 	// call the handler
    179 	suite.accountsModule.AccountStatusesGETHandler(ctx)
    180 
    181 	// 1. we should have OK because our request was valid
    182 	suite.Equal(http.StatusOK, recorder.Code)
    183 
    184 	// 2. we should have no error message in the result body
    185 	result := recorder.Result()
    186 	defer result.Body.Close()
    187 
    188 	// check the response
    189 	b, err := ioutil.ReadAll(result.Body)
    190 	suite.NoError(err)
    191 
    192 	// unmarshal the returned statuses
    193 	apimodelStatuses := []*apimodel.Status{}
    194 	err = json.Unmarshal(b, &apimodelStatuses)
    195 	suite.NoError(err)
    196 	suite.Empty(apimodelStatuses)
    197 	suite.Empty(result.Header.Get("link"))
    198 }
    199 
    200 func (suite *AccountStatusesTestSuite) TestGetStatusesPinnedOnlyFollowing() {
    201 	// local account 2 has a followers-only status pinned
    202 	// we're getting pinned statuses of local account 2 with an account that *DOES* follow it
    203 	targetAccount := suite.testAccounts["local_account_2"]
    204 	recorder := httptest.NewRecorder()
    205 	ctx := suite.newContext(recorder, http.MethodGet, nil, fmt.Sprintf("/api/v1/accounts/%s/statuses?pinned=true", targetAccount.ID), "")
    206 	ctx.Set(oauth.SessionAuthorizedAccount, suite.testAccounts["local_account_1"])
    207 	ctx.Set(oauth.SessionAuthorizedToken, oauth.DBTokenToToken(suite.testTokens["local_account_1"]))
    208 	ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplications["application_1"])
    209 	ctx.Set(oauth.SessionAuthorizedUser, suite.testUsers["local_account_1"])
    210 	ctx.Params = gin.Params{
    211 		gin.Param{
    212 			Key:   accounts.IDKey,
    213 			Value: targetAccount.ID,
    214 		},
    215 	}
    216 
    217 	// call the handler
    218 	suite.accountsModule.AccountStatusesGETHandler(ctx)
    219 
    220 	// 1. we should have OK because our request was valid
    221 	suite.Equal(http.StatusOK, recorder.Code)
    222 
    223 	// 2. we should have no error message in the result body
    224 	result := recorder.Result()
    225 	defer result.Body.Close()
    226 
    227 	// check the response
    228 	b, err := ioutil.ReadAll(result.Body)
    229 	suite.NoError(err)
    230 
    231 	// unmarshal the returned statuses
    232 	apimodelStatuses := []*apimodel.Status{}
    233 	err = json.Unmarshal(b, &apimodelStatuses)
    234 	suite.NoError(err)
    235 	suite.Len(apimodelStatuses, 1)
    236 	suite.Empty(result.Header.Get("link"))
    237 
    238 	for _, s := range apimodelStatuses {
    239 		// Requesting account doesn't own these
    240 		// statuses, so pinned should be false.
    241 		suite.False(s.Pinned)
    242 	}
    243 }
    244 
    245 func (suite *AccountStatusesTestSuite) TestGetStatusesPinnedOnlyGetOwn() {
    246 	// local account 2 has a followers-only status pinned
    247 	// we're getting pinned statuses of local account 2 with local account 2!
    248 	targetAccount := suite.testAccounts["local_account_2"]
    249 	recorder := httptest.NewRecorder()
    250 	ctx := suite.newContext(recorder, http.MethodGet, nil, fmt.Sprintf("/api/v1/accounts/%s/statuses?pinned=true", targetAccount.ID), "")
    251 	ctx.Set(oauth.SessionAuthorizedAccount, suite.testAccounts["local_account_2"])
    252 	ctx.Set(oauth.SessionAuthorizedToken, oauth.DBTokenToToken(suite.testTokens["local_account_2"]))
    253 	ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplications["application_1"])
    254 	ctx.Set(oauth.SessionAuthorizedUser, suite.testUsers["local_account_2"])
    255 	ctx.Params = gin.Params{
    256 		gin.Param{
    257 			Key:   accounts.IDKey,
    258 			Value: targetAccount.ID,
    259 		},
    260 	}
    261 
    262 	// call the handler
    263 	suite.accountsModule.AccountStatusesGETHandler(ctx)
    264 
    265 	// 1. we should have OK because our request was valid
    266 	suite.Equal(http.StatusOK, recorder.Code)
    267 
    268 	// 2. we should have no error message in the result body
    269 	result := recorder.Result()
    270 	defer result.Body.Close()
    271 
    272 	// check the response
    273 	b, err := ioutil.ReadAll(result.Body)
    274 	suite.NoError(err)
    275 
    276 	// unmarshal the returned statuses
    277 	apimodelStatuses := []*apimodel.Status{}
    278 	err = json.Unmarshal(b, &apimodelStatuses)
    279 	suite.NoError(err)
    280 	suite.Len(apimodelStatuses, 1)
    281 	suite.Empty(result.Header.Get("link"))
    282 
    283 	for _, s := range apimodelStatuses {
    284 		// Requesting account owns pinned statuses.
    285 		suite.True(s.Pinned)
    286 	}
    287 }
    288 
    289 func TestAccountStatusesTestSuite(t *testing.T) {
    290 	suite.Run(t, new(AccountStatusesTestSuite))
    291 }