statusunpin_test.go (4297B)
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 statuses_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/stretchr/testify/suite" 29 "github.com/superseriousbusiness/gotosocial/internal/api/client/statuses" 30 apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" 31 "github.com/superseriousbusiness/gotosocial/internal/config" 32 "github.com/superseriousbusiness/gotosocial/internal/gtserror" 33 "github.com/superseriousbusiness/gotosocial/internal/oauth" 34 "github.com/superseriousbusiness/gotosocial/testrig" 35 ) 36 37 type StatusUnpinTestSuite struct { 38 StatusStandardTestSuite 39 } 40 41 func (suite *StatusUnpinTestSuite) createUnpin( 42 expectedHTTPStatus int, 43 expectedBody string, 44 targetStatusID string, 45 ) (*apimodel.Status, error) { 46 // instantiate recorder + test context 47 recorder := httptest.NewRecorder() 48 ctx, _ := testrig.CreateGinTestContext(recorder, nil) 49 ctx.Set(oauth.SessionAuthorizedAccount, suite.testAccounts["admin_account"]) 50 ctx.Set(oauth.SessionAuthorizedToken, oauth.DBTokenToToken(suite.testTokens["admin_account"])) 51 ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplications["application_1"]) 52 ctx.Set(oauth.SessionAuthorizedUser, suite.testUsers["admin_account"]) 53 54 // create the request 55 ctx.Request = httptest.NewRequest(http.MethodPost, config.GetProtocol()+"://"+config.GetHost()+"/api/"+statuses.BasePath+"/"+targetStatusID+"/unpin", nil) 56 ctx.Request.Header.Set("accept", "application/json") 57 ctx.AddParam(statuses.IDKey, targetStatusID) 58 59 // trigger the handler 60 suite.statusModule.StatusUnpinPOSTHandler(ctx) 61 62 // read the response 63 result := recorder.Result() 64 defer result.Body.Close() 65 66 b, err := ioutil.ReadAll(result.Body) 67 if err != nil { 68 return nil, err 69 } 70 71 errs := gtserror.MultiError{} 72 73 // check code + body 74 if resultCode := recorder.Code; expectedHTTPStatus != resultCode { 75 errs = append(errs, fmt.Sprintf("expected %d got %d", expectedHTTPStatus, resultCode)) 76 } 77 78 // if we got an expected body, return early 79 if expectedBody != "" && string(b) != expectedBody { 80 errs = append(errs, fmt.Sprintf("expected %s got %s", expectedBody, string(b))) 81 } 82 83 if len(errs) > 0 { 84 return nil, errs.Combine() 85 } 86 87 resp := &apimodel.Status{} 88 if err := json.Unmarshal(b, resp); err != nil { 89 return nil, err 90 } 91 92 return resp, nil 93 } 94 95 func (suite *StatusUnpinTestSuite) TestUnpinStatusOK() { 96 // Unpin a pinned public status that this account owns. 97 targetStatus := suite.testStatuses["admin_account_status_1"] 98 99 resp, err := suite.createUnpin(http.StatusOK, "", targetStatus.ID) 100 if err != nil { 101 suite.FailNow(err.Error()) 102 } 103 104 suite.False(resp.Pinned) 105 } 106 107 func (suite *StatusUnpinTestSuite) TestUnpinStatusNotFound() { 108 // Unpin a pinned followers-only status owned by another account. 109 targetStatus := suite.testStatuses["local_account_2_status_7"] 110 111 if _, err := suite.createUnpin(http.StatusNotFound, `{"error":"Not Found"}`, targetStatus.ID); err != nil { 112 suite.FailNow(err.Error()) 113 } 114 } 115 116 func (suite *StatusUnpinTestSuite) TestUnpinStatusUnprocessable() { 117 // Unpin a not-pinned status owned by another account. 118 targetStatus := suite.testStatuses["local_account_1_status_1"] 119 120 if _, err := suite.createUnpin( 121 http.StatusUnprocessableEntity, 122 `{"error":"Unprocessable Entity: status 01F8MHAMCHF6Y650WCRSCP4WMY does not belong to account 01F8MH17FWEB39HZJ76B6VXSKF"}`, 123 targetStatus.ID, 124 ); err != nil { 125 suite.FailNow(err.Error()) 126 } 127 } 128 129 func TestStatusUnpinTestSuite(t *testing.T) { 130 suite.Run(t, new(StatusUnpinTestSuite)) 131 }