gtsocial-umbx

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

searchget_test.go (34167B)


      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 search_test
     19 
     20 import (
     21 	"context"
     22 	"encoding/json"
     23 	"fmt"
     24 	"io"
     25 	"net/http"
     26 	"net/http/httptest"
     27 	"net/url"
     28 	"strconv"
     29 	"strings"
     30 	"testing"
     31 
     32 	"github.com/stretchr/testify/suite"
     33 	"github.com/superseriousbusiness/gotosocial/internal/api/client/search"
     34 	apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
     35 	apiutil "github.com/superseriousbusiness/gotosocial/internal/api/util"
     36 	"github.com/superseriousbusiness/gotosocial/internal/config"
     37 	"github.com/superseriousbusiness/gotosocial/internal/gtserror"
     38 	"github.com/superseriousbusiness/gotosocial/internal/gtsmodel"
     39 	"github.com/superseriousbusiness/gotosocial/internal/oauth"
     40 	"github.com/superseriousbusiness/gotosocial/testrig"
     41 )
     42 
     43 type SearchGetTestSuite struct {
     44 	SearchStandardTestSuite
     45 }
     46 
     47 func (suite *SearchGetTestSuite) getSearch(
     48 	requestingAccount *gtsmodel.Account,
     49 	token *gtsmodel.Token,
     50 	user *gtsmodel.User,
     51 	maxID *string,
     52 	minID *string,
     53 	limit *int,
     54 	offset *int,
     55 	query string,
     56 	queryType *string,
     57 	resolve *bool,
     58 	following *bool,
     59 	expectedHTTPStatus int,
     60 	expectedBody string,
     61 ) (*apimodel.SearchResult, error) {
     62 	var (
     63 		recorder   = httptest.NewRecorder()
     64 		ctx, _     = testrig.CreateGinTestContext(recorder, nil)
     65 		requestURL = testrig.URLMustParse("/api" + search.BasePathV1)
     66 		queryParts []string
     67 	)
     68 
     69 	// Put the request together.
     70 	if maxID != nil {
     71 		queryParts = append(queryParts, apiutil.MaxIDKey+"="+url.QueryEscape(*maxID))
     72 	}
     73 
     74 	if minID != nil {
     75 		queryParts = append(queryParts, apiutil.MinIDKey+"="+url.QueryEscape(*minID))
     76 	}
     77 
     78 	if limit != nil {
     79 		queryParts = append(queryParts, apiutil.LimitKey+"="+strconv.Itoa(*limit))
     80 	}
     81 
     82 	if offset != nil {
     83 		queryParts = append(queryParts, apiutil.SearchOffsetKey+"="+strconv.Itoa(*offset))
     84 	}
     85 
     86 	queryParts = append(queryParts, apiutil.SearchQueryKey+"="+url.QueryEscape(query))
     87 
     88 	if queryType != nil {
     89 		queryParts = append(queryParts, apiutil.SearchTypeKey+"="+url.QueryEscape(*queryType))
     90 	}
     91 
     92 	if resolve != nil {
     93 		queryParts = append(queryParts, apiutil.SearchResolveKey+"="+strconv.FormatBool(*resolve))
     94 	}
     95 
     96 	if following != nil {
     97 		queryParts = append(queryParts, apiutil.SearchFollowingKey+"="+strconv.FormatBool(*following))
     98 	}
     99 
    100 	requestURL.RawQuery = strings.Join(queryParts, "&")
    101 	ctx.Request = httptest.NewRequest(http.MethodGet, requestURL.String(), nil)
    102 	ctx.Set(oauth.SessionAuthorizedAccount, requestingAccount)
    103 	ctx.Set(oauth.SessionAuthorizedToken, oauth.DBTokenToToken(token))
    104 	ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplications["application_1"])
    105 	ctx.Set(oauth.SessionAuthorizedUser, user)
    106 
    107 	// Trigger the function being tested.
    108 	suite.searchModule.SearchGETHandler(ctx)
    109 
    110 	// Read the result.
    111 	result := recorder.Result()
    112 	defer result.Body.Close()
    113 
    114 	b, err := io.ReadAll(result.Body)
    115 	if err != nil {
    116 		suite.FailNow(err.Error())
    117 	}
    118 
    119 	errs := gtserror.MultiError{}
    120 
    121 	// Check expected code + body.
    122 	if resultCode := recorder.Code; expectedHTTPStatus != resultCode {
    123 		errs = append(errs, fmt.Sprintf("expected %d got %d", expectedHTTPStatus, resultCode))
    124 	}
    125 
    126 	// If we got an expected body, return early.
    127 	if expectedBody != "" && string(b) != expectedBody {
    128 		errs = append(errs, fmt.Sprintf("expected %s got %s", expectedBody, string(b)))
    129 	}
    130 
    131 	if err := errs.Combine(); err != nil {
    132 		suite.FailNow("", "%v (body %s)", err, string(b))
    133 	}
    134 
    135 	searchResult := &apimodel.SearchResult{}
    136 	if err := json.Unmarshal(b, searchResult); err != nil {
    137 		suite.FailNow(err.Error())
    138 	}
    139 
    140 	return searchResult, nil
    141 }
    142 
    143 func (suite *SearchGetTestSuite) bodgeLocalInstance(domain string) {
    144 	// Set new host.
    145 	config.SetHost(domain)
    146 
    147 	// Copy instance account to not mess up other tests.
    148 	instanceAccount := &gtsmodel.Account{}
    149 	*instanceAccount = *suite.testAccounts["instance_account"]
    150 
    151 	// Set username of instance account to given domain.
    152 	instanceAccount.Username = domain
    153 	if err := suite.db.UpdateAccount(context.Background(), instanceAccount, "username"); err != nil {
    154 		suite.FailNow(err.Error())
    155 	}
    156 }
    157 
    158 func (suite *SearchGetTestSuite) TestSearchRemoteAccountByURI() {
    159 	var (
    160 		requestingAccount          = suite.testAccounts["local_account_1"]
    161 		token                      = suite.testTokens["local_account_1"]
    162 		user                       = suite.testUsers["local_account_1"]
    163 		maxID              *string = nil
    164 		minID              *string = nil
    165 		limit              *int    = nil
    166 		offset             *int    = nil
    167 		resolve            *bool   = func() *bool { i := true; return &i }()
    168 		query                      = "https://unknown-instance.com/users/brand_new_person"
    169 		queryType          *string = func() *string { i := "accounts"; return &i }()
    170 		following          *bool   = nil
    171 		expectedHTTPStatus         = http.StatusOK
    172 		expectedBody               = ""
    173 	)
    174 
    175 	searchResult, err := suite.getSearch(
    176 		requestingAccount,
    177 		token,
    178 		user,
    179 		maxID,
    180 		minID,
    181 		limit,
    182 		offset,
    183 		query,
    184 		queryType,
    185 		resolve,
    186 		following,
    187 		expectedHTTPStatus,
    188 		expectedBody)
    189 	if err != nil {
    190 		suite.FailNow(err.Error())
    191 	}
    192 
    193 	if !suite.Len(searchResult.Accounts, 1) {
    194 		suite.FailNow("expected 1 account in search results but got 0")
    195 	}
    196 
    197 	gotAccount := searchResult.Accounts[0]
    198 	suite.NotNil(gotAccount)
    199 }
    200 
    201 func (suite *SearchGetTestSuite) TestSearchRemoteAccountByNamestring() {
    202 	var (
    203 		requestingAccount          = suite.testAccounts["local_account_1"]
    204 		token                      = suite.testTokens["local_account_1"]
    205 		user                       = suite.testUsers["local_account_1"]
    206 		maxID              *string = nil
    207 		minID              *string = nil
    208 		limit              *int    = nil
    209 		offset             *int    = nil
    210 		resolve            *bool   = func() *bool { i := true; return &i }()
    211 		query                      = "@brand_new_person@unknown-instance.com"
    212 		queryType          *string = func() *string { i := "accounts"; return &i }()
    213 		following          *bool   = nil
    214 		expectedHTTPStatus         = http.StatusOK
    215 		expectedBody               = ""
    216 	)
    217 
    218 	searchResult, err := suite.getSearch(
    219 		requestingAccount,
    220 		token,
    221 		user,
    222 		maxID,
    223 		minID,
    224 		limit,
    225 		offset,
    226 		query,
    227 		queryType,
    228 		resolve,
    229 		following,
    230 		expectedHTTPStatus,
    231 		expectedBody)
    232 	if err != nil {
    233 		suite.FailNow(err.Error())
    234 	}
    235 
    236 	if !suite.Len(searchResult.Accounts, 1) {
    237 		suite.FailNow("expected 1 account in search results but got 0")
    238 	}
    239 
    240 	gotAccount := searchResult.Accounts[0]
    241 	suite.NotNil(gotAccount)
    242 }
    243 
    244 func (suite *SearchGetTestSuite) TestSearchRemoteAccountByNamestringUppercase() {
    245 	var (
    246 		requestingAccount          = suite.testAccounts["local_account_1"]
    247 		token                      = suite.testTokens["local_account_1"]
    248 		user                       = suite.testUsers["local_account_1"]
    249 		maxID              *string = nil
    250 		minID              *string = nil
    251 		limit              *int    = nil
    252 		offset             *int    = nil
    253 		resolve            *bool   = func() *bool { i := true; return &i }()
    254 		query                      = "@Some_User@example.org"
    255 		queryType          *string = func() *string { i := "accounts"; return &i }()
    256 		following          *bool   = nil
    257 		expectedHTTPStatus         = http.StatusOK
    258 		expectedBody               = ""
    259 	)
    260 
    261 	searchResult, err := suite.getSearch(
    262 		requestingAccount,
    263 		token,
    264 		user,
    265 		maxID,
    266 		minID,
    267 		limit,
    268 		offset,
    269 		query,
    270 		queryType,
    271 		resolve,
    272 		following,
    273 		expectedHTTPStatus,
    274 		expectedBody)
    275 	if err != nil {
    276 		suite.FailNow(err.Error())
    277 	}
    278 
    279 	if !suite.Len(searchResult.Accounts, 1) {
    280 		suite.FailNow("expected 1 account in search results but got 0")
    281 	}
    282 
    283 	gotAccount := searchResult.Accounts[0]
    284 	suite.NotNil(gotAccount)
    285 }
    286 
    287 func (suite *SearchGetTestSuite) TestSearchRemoteAccountByNamestringNoLeadingAt() {
    288 	var (
    289 		requestingAccount          = suite.testAccounts["local_account_1"]
    290 		token                      = suite.testTokens["local_account_1"]
    291 		user                       = suite.testUsers["local_account_1"]
    292 		maxID              *string = nil
    293 		minID              *string = nil
    294 		limit              *int    = nil
    295 		offset             *int    = nil
    296 		resolve            *bool   = func() *bool { i := true; return &i }()
    297 		query                      = "brand_new_person@unknown-instance.com"
    298 		queryType          *string = func() *string { i := "accounts"; return &i }()
    299 		following          *bool   = nil
    300 		expectedHTTPStatus         = http.StatusOK
    301 		expectedBody               = ""
    302 	)
    303 
    304 	searchResult, err := suite.getSearch(
    305 		requestingAccount,
    306 		token,
    307 		user,
    308 		maxID,
    309 		minID,
    310 		limit,
    311 		offset,
    312 		query,
    313 		queryType,
    314 		resolve,
    315 		following,
    316 		expectedHTTPStatus,
    317 		expectedBody)
    318 	if err != nil {
    319 		suite.FailNow(err.Error())
    320 	}
    321 
    322 	if !suite.Len(searchResult.Accounts, 1) {
    323 		suite.FailNow("expected 1 account in search results but got 0")
    324 	}
    325 
    326 	gotAccount := searchResult.Accounts[0]
    327 	suite.NotNil(gotAccount)
    328 }
    329 
    330 func (suite *SearchGetTestSuite) TestSearchRemoteAccountByNamestringNoResolve() {
    331 	var (
    332 		requestingAccount          = suite.testAccounts["local_account_1"]
    333 		token                      = suite.testTokens["local_account_1"]
    334 		user                       = suite.testUsers["local_account_1"]
    335 		maxID              *string = nil
    336 		minID              *string = nil
    337 		limit              *int    = nil
    338 		offset             *int    = nil
    339 		resolve            *bool   = nil
    340 		query                      = "@brand_new_person@unknown-instance.com"
    341 		queryType          *string = func() *string { i := "accounts"; return &i }()
    342 		following          *bool   = nil
    343 		expectedHTTPStatus         = http.StatusOK
    344 		expectedBody               = ""
    345 	)
    346 
    347 	searchResult, err := suite.getSearch(
    348 		requestingAccount,
    349 		token,
    350 		user,
    351 		maxID,
    352 		minID,
    353 		limit,
    354 		offset,
    355 		query,
    356 		queryType,
    357 		resolve,
    358 		following,
    359 		expectedHTTPStatus,
    360 		expectedBody)
    361 	if err != nil {
    362 		suite.FailNow(err.Error())
    363 	}
    364 
    365 	suite.Len(searchResult.Accounts, 0)
    366 }
    367 
    368 func (suite *SearchGetTestSuite) TestSearchRemoteAccountByNamestringSpecialChars() {
    369 	var (
    370 		requestingAccount          = suite.testAccounts["local_account_1"]
    371 		token                      = suite.testTokens["local_account_1"]
    372 		user                       = suite.testUsers["local_account_1"]
    373 		maxID              *string = nil
    374 		minID              *string = nil
    375 		limit              *int    = nil
    376 		offset             *int    = nil
    377 		resolve            *bool   = nil
    378 		query                      = "@üser@ëxample.org"
    379 		queryType          *string = func() *string { i := "accounts"; return &i }()
    380 		following          *bool   = nil
    381 		expectedHTTPStatus         = http.StatusOK
    382 		expectedBody               = ""
    383 	)
    384 
    385 	searchResult, err := suite.getSearch(
    386 		requestingAccount,
    387 		token,
    388 		user,
    389 		maxID,
    390 		minID,
    391 		limit,
    392 		offset,
    393 		query,
    394 		queryType,
    395 		resolve,
    396 		following,
    397 		expectedHTTPStatus,
    398 		expectedBody)
    399 	if err != nil {
    400 		suite.FailNow(err.Error())
    401 	}
    402 
    403 	if l := len(searchResult.Accounts); l != 1 {
    404 		suite.FailNow("", "expected %d accounts, got %d", 1, l)
    405 	}
    406 	suite.Equal("üser@ëxample.org", searchResult.Accounts[0].Acct)
    407 }
    408 
    409 func (suite *SearchGetTestSuite) TestSearchRemoteAccountByNamestringSpecialCharsPunycode() {
    410 	var (
    411 		requestingAccount          = suite.testAccounts["local_account_1"]
    412 		token                      = suite.testTokens["local_account_1"]
    413 		user                       = suite.testUsers["local_account_1"]
    414 		maxID              *string = nil
    415 		minID              *string = nil
    416 		limit              *int    = nil
    417 		offset             *int    = nil
    418 		resolve            *bool   = nil
    419 		query                      = "@üser@xn--xample-ova.org"
    420 		queryType          *string = func() *string { i := "accounts"; return &i }()
    421 		following          *bool   = nil
    422 		expectedHTTPStatus         = http.StatusOK
    423 		expectedBody               = ""
    424 	)
    425 
    426 	searchResult, err := suite.getSearch(
    427 		requestingAccount,
    428 		token,
    429 		user,
    430 		maxID,
    431 		minID,
    432 		limit,
    433 		offset,
    434 		query,
    435 		queryType,
    436 		resolve,
    437 		following,
    438 		expectedHTTPStatus,
    439 		expectedBody)
    440 	if err != nil {
    441 		suite.FailNow(err.Error())
    442 	}
    443 
    444 	if l := len(searchResult.Accounts); l != 1 {
    445 		suite.FailNow("", "expected %d accounts, got %d", 1, l)
    446 	}
    447 	suite.Equal("üser@ëxample.org", searchResult.Accounts[0].Acct)
    448 }
    449 
    450 func (suite *SearchGetTestSuite) TestSearchLocalAccountByNamestring() {
    451 	var (
    452 		requestingAccount          = suite.testAccounts["local_account_1"]
    453 		token                      = suite.testTokens["local_account_1"]
    454 		user                       = suite.testUsers["local_account_1"]
    455 		maxID              *string = nil
    456 		minID              *string = nil
    457 		limit              *int    = nil
    458 		offset             *int    = nil
    459 		resolve            *bool   = nil
    460 		query                      = "@the_mighty_zork"
    461 		queryType          *string = func() *string { i := "accounts"; return &i }()
    462 		following          *bool   = nil
    463 		expectedHTTPStatus         = http.StatusOK
    464 		expectedBody               = ""
    465 	)
    466 
    467 	searchResult, err := suite.getSearch(
    468 		requestingAccount,
    469 		token,
    470 		user,
    471 		maxID,
    472 		minID,
    473 		limit,
    474 		offset,
    475 		query,
    476 		queryType,
    477 		resolve,
    478 		following,
    479 		expectedHTTPStatus,
    480 		expectedBody)
    481 	if err != nil {
    482 		suite.FailNow(err.Error())
    483 	}
    484 
    485 	if !suite.Len(searchResult.Accounts, 1) {
    486 		suite.FailNow("expected 1 account in search results but got 0")
    487 	}
    488 
    489 	gotAccount := searchResult.Accounts[0]
    490 	suite.NotNil(gotAccount)
    491 }
    492 
    493 func (suite *SearchGetTestSuite) TestSearchLocalAccountByNamestringWithDomain() {
    494 	var (
    495 		requestingAccount          = suite.testAccounts["local_account_1"]
    496 		token                      = suite.testTokens["local_account_1"]
    497 		user                       = suite.testUsers["local_account_1"]
    498 		maxID              *string = nil
    499 		minID              *string = nil
    500 		limit              *int    = nil
    501 		offset             *int    = nil
    502 		resolve            *bool   = nil
    503 		query                      = "@the_mighty_zork@localhost:8080"
    504 		queryType          *string = func() *string { i := "accounts"; return &i }()
    505 		following          *bool   = nil
    506 		expectedHTTPStatus         = http.StatusOK
    507 		expectedBody               = ""
    508 	)
    509 
    510 	searchResult, err := suite.getSearch(
    511 		requestingAccount,
    512 		token,
    513 		user,
    514 		maxID,
    515 		minID,
    516 		limit,
    517 		offset,
    518 		query,
    519 		queryType,
    520 		resolve,
    521 		following,
    522 		expectedHTTPStatus,
    523 		expectedBody)
    524 	if err != nil {
    525 		suite.FailNow(err.Error())
    526 	}
    527 
    528 	if !suite.Len(searchResult.Accounts, 1) {
    529 		suite.FailNow("expected 1 account in search results but got 0")
    530 	}
    531 
    532 	gotAccount := searchResult.Accounts[0]
    533 	suite.NotNil(gotAccount)
    534 }
    535 
    536 func (suite *SearchGetTestSuite) TestSearchNonexistingLocalAccountByNamestringResolveTrue() {
    537 	var (
    538 		requestingAccount          = suite.testAccounts["local_account_1"]
    539 		token                      = suite.testTokens["local_account_1"]
    540 		user                       = suite.testUsers["local_account_1"]
    541 		maxID              *string = nil
    542 		minID              *string = nil
    543 		limit              *int    = nil
    544 		offset             *int    = nil
    545 		resolve            *bool   = func() *bool { i := true; return &i }()
    546 		query                      = "@somone_made_up@localhost:8080"
    547 		queryType          *string = func() *string { i := "accounts"; return &i }()
    548 		following          *bool   = nil
    549 		expectedHTTPStatus         = http.StatusOK
    550 		expectedBody               = ""
    551 	)
    552 
    553 	searchResult, err := suite.getSearch(
    554 		requestingAccount,
    555 		token,
    556 		user,
    557 		maxID,
    558 		minID,
    559 		limit,
    560 		offset,
    561 		query,
    562 		queryType,
    563 		resolve,
    564 		following,
    565 		expectedHTTPStatus,
    566 		expectedBody)
    567 	if err != nil {
    568 		suite.FailNow(err.Error())
    569 	}
    570 
    571 	suite.Len(searchResult.Accounts, 0)
    572 }
    573 
    574 func (suite *SearchGetTestSuite) TestSearchLocalAccountByURI() {
    575 	var (
    576 		requestingAccount          = suite.testAccounts["local_account_1"]
    577 		token                      = suite.testTokens["local_account_1"]
    578 		user                       = suite.testUsers["local_account_1"]
    579 		maxID              *string = nil
    580 		minID              *string = nil
    581 		limit              *int    = nil
    582 		offset             *int    = nil
    583 		resolve            *bool   = nil
    584 		query                      = "http://localhost:8080/users/the_mighty_zork"
    585 		queryType          *string = func() *string { i := "accounts"; return &i }()
    586 		following          *bool   = nil
    587 		expectedHTTPStatus         = http.StatusOK
    588 		expectedBody               = ""
    589 	)
    590 
    591 	searchResult, err := suite.getSearch(
    592 		requestingAccount,
    593 		token,
    594 		user,
    595 		maxID,
    596 		minID,
    597 		limit,
    598 		offset,
    599 		query,
    600 		queryType,
    601 		resolve,
    602 		following,
    603 		expectedHTTPStatus,
    604 		expectedBody)
    605 	if err != nil {
    606 		suite.FailNow(err.Error())
    607 	}
    608 
    609 	if !suite.Len(searchResult.Accounts, 1) {
    610 		suite.FailNow("expected 1 account in search results but got 0")
    611 	}
    612 
    613 	gotAccount := searchResult.Accounts[0]
    614 	suite.NotNil(gotAccount)
    615 }
    616 
    617 func (suite *SearchGetTestSuite) TestSearchLocalAccountByURL() {
    618 	var (
    619 		requestingAccount          = suite.testAccounts["local_account_1"]
    620 		token                      = suite.testTokens["local_account_1"]
    621 		user                       = suite.testUsers["local_account_1"]
    622 		maxID              *string = nil
    623 		minID              *string = nil
    624 		limit              *int    = nil
    625 		offset             *int    = nil
    626 		resolve            *bool   = nil
    627 		query                      = "http://localhost:8080/@the_mighty_zork"
    628 		queryType          *string = func() *string { i := "accounts"; return &i }()
    629 		following          *bool   = nil
    630 		expectedHTTPStatus         = http.StatusOK
    631 		expectedBody               = ""
    632 	)
    633 
    634 	searchResult, err := suite.getSearch(
    635 		requestingAccount,
    636 		token,
    637 		user,
    638 		maxID,
    639 		minID,
    640 		limit,
    641 		offset,
    642 		query,
    643 		queryType,
    644 		resolve,
    645 		following,
    646 		expectedHTTPStatus,
    647 		expectedBody)
    648 	if err != nil {
    649 		suite.FailNow(err.Error())
    650 	}
    651 
    652 	if !suite.Len(searchResult.Accounts, 1) {
    653 		suite.FailNow("expected 1 account in search results but got 0")
    654 	}
    655 
    656 	gotAccount := searchResult.Accounts[0]
    657 	suite.NotNil(gotAccount)
    658 }
    659 
    660 func (suite *SearchGetTestSuite) TestSearchNonexistingLocalAccountByURL() {
    661 	var (
    662 		requestingAccount          = suite.testAccounts["local_account_1"]
    663 		token                      = suite.testTokens["local_account_1"]
    664 		user                       = suite.testUsers["local_account_1"]
    665 		maxID              *string = nil
    666 		minID              *string = nil
    667 		limit              *int    = nil
    668 		offset             *int    = nil
    669 		resolve            *bool   = func() *bool { i := true; return &i }()
    670 		query                      = "http://localhost:8080/@the_shmighty_shmork"
    671 		queryType          *string = func() *string { i := "accounts"; return &i }()
    672 		following          *bool   = nil
    673 		expectedHTTPStatus         = http.StatusOK
    674 		expectedBody               = ""
    675 	)
    676 
    677 	searchResult, err := suite.getSearch(
    678 		requestingAccount,
    679 		token,
    680 		user,
    681 		maxID,
    682 		minID,
    683 		limit,
    684 		offset,
    685 		query,
    686 		queryType,
    687 		resolve,
    688 		following,
    689 		expectedHTTPStatus,
    690 		expectedBody)
    691 	if err != nil {
    692 		suite.FailNow(err.Error())
    693 	}
    694 
    695 	suite.Len(searchResult.Accounts, 0)
    696 }
    697 
    698 func (suite *SearchGetTestSuite) TestSearchStatusByURL() {
    699 	var (
    700 		requestingAccount          = suite.testAccounts["local_account_1"]
    701 		token                      = suite.testTokens["local_account_1"]
    702 		user                       = suite.testUsers["local_account_1"]
    703 		maxID              *string = nil
    704 		minID              *string = nil
    705 		limit              *int    = nil
    706 		offset             *int    = nil
    707 		resolve            *bool   = func() *bool { i := true; return &i }()
    708 		query                      = "https://turnip.farm/users/turniplover6969/statuses/70c53e54-3146-42d5-a630-83c8b6c7c042"
    709 		queryType          *string = func() *string { i := "statuses"; return &i }()
    710 		following          *bool   = nil
    711 		expectedHTTPStatus         = http.StatusOK
    712 		expectedBody               = ""
    713 	)
    714 
    715 	searchResult, err := suite.getSearch(
    716 		requestingAccount,
    717 		token,
    718 		user,
    719 		maxID,
    720 		minID,
    721 		limit,
    722 		offset,
    723 		query,
    724 		queryType,
    725 		resolve,
    726 		following,
    727 		expectedHTTPStatus,
    728 		expectedBody)
    729 	if err != nil {
    730 		suite.FailNow(err.Error())
    731 	}
    732 
    733 	if !suite.Len(searchResult.Statuses, 1) {
    734 		suite.FailNow("expected 1 status in search results but got 0")
    735 	}
    736 
    737 	gotStatus := searchResult.Statuses[0]
    738 	suite.NotNil(gotStatus)
    739 }
    740 
    741 func (suite *SearchGetTestSuite) TestSearchBlockedDomainURL() {
    742 	var (
    743 		requestingAccount          = suite.testAccounts["local_account_1"]
    744 		token                      = suite.testTokens["local_account_1"]
    745 		user                       = suite.testUsers["local_account_1"]
    746 		maxID              *string = nil
    747 		minID              *string = nil
    748 		limit              *int    = nil
    749 		offset             *int    = nil
    750 		resolve            *bool   = func() *bool { i := true; return &i }()
    751 		query                      = "https://replyguys.com/@someone"
    752 		queryType          *string = func() *string { i := "accounts"; return &i }()
    753 		following          *bool   = nil
    754 		expectedHTTPStatus         = http.StatusOK
    755 		expectedBody               = ""
    756 	)
    757 
    758 	searchResult, err := suite.getSearch(
    759 		requestingAccount,
    760 		token,
    761 		user,
    762 		maxID,
    763 		minID,
    764 		limit,
    765 		offset,
    766 		query,
    767 		queryType,
    768 		resolve,
    769 		following,
    770 		expectedHTTPStatus,
    771 		expectedBody)
    772 	if err != nil {
    773 		suite.FailNow(err.Error())
    774 	}
    775 
    776 	suite.Len(searchResult.Accounts, 0)
    777 	suite.Len(searchResult.Statuses, 0)
    778 	suite.Len(searchResult.Hashtags, 0)
    779 }
    780 
    781 func (suite *SearchGetTestSuite) TestSearchBlockedDomainNamestring() {
    782 	var (
    783 		requestingAccount          = suite.testAccounts["local_account_1"]
    784 		token                      = suite.testTokens["local_account_1"]
    785 		user                       = suite.testUsers["local_account_1"]
    786 		maxID              *string = nil
    787 		minID              *string = nil
    788 		limit              *int    = nil
    789 		offset             *int    = nil
    790 		resolve            *bool   = func() *bool { i := true; return &i }()
    791 		query                      = "@someone@replyguys.com"
    792 		queryType          *string = func() *string { i := "accounts"; return &i }()
    793 		following          *bool   = nil
    794 		expectedHTTPStatus         = http.StatusOK
    795 		expectedBody               = ""
    796 	)
    797 
    798 	searchResult, err := suite.getSearch(
    799 		requestingAccount,
    800 		token,
    801 		user,
    802 		maxID,
    803 		minID,
    804 		limit,
    805 		offset,
    806 		query,
    807 		queryType,
    808 		resolve,
    809 		following,
    810 		expectedHTTPStatus,
    811 		expectedBody)
    812 	if err != nil {
    813 		suite.FailNow(err.Error())
    814 	}
    815 
    816 	suite.Len(searchResult.Accounts, 0)
    817 	suite.Len(searchResult.Statuses, 0)
    818 	suite.Len(searchResult.Hashtags, 0)
    819 }
    820 
    821 func (suite *SearchGetTestSuite) TestSearchAAny() {
    822 	var (
    823 		requestingAccount          = suite.testAccounts["local_account_1"]
    824 		token                      = suite.testTokens["local_account_1"]
    825 		user                       = suite.testUsers["local_account_1"]
    826 		maxID              *string = nil
    827 		minID              *string = nil
    828 		limit              *int    = nil
    829 		offset             *int    = nil
    830 		resolve            *bool   = func() *bool { i := true; return &i }()
    831 		query                      = "a"
    832 		queryType          *string = nil // Return anything.
    833 		following          *bool   = nil
    834 		expectedHTTPStatus         = http.StatusOK
    835 		expectedBody               = ""
    836 	)
    837 
    838 	searchResult, err := suite.getSearch(
    839 		requestingAccount,
    840 		token,
    841 		user,
    842 		maxID,
    843 		minID,
    844 		limit,
    845 		offset,
    846 		query,
    847 		queryType,
    848 		resolve,
    849 		following,
    850 		expectedHTTPStatus,
    851 		expectedBody)
    852 	if err != nil {
    853 		suite.FailNow(err.Error())
    854 	}
    855 
    856 	suite.Len(searchResult.Accounts, 5)
    857 	suite.Len(searchResult.Statuses, 4)
    858 	suite.Len(searchResult.Hashtags, 0)
    859 }
    860 
    861 func (suite *SearchGetTestSuite) TestSearchAAnyFollowingOnly() {
    862 	var (
    863 		requestingAccount          = suite.testAccounts["local_account_1"]
    864 		token                      = suite.testTokens["local_account_1"]
    865 		user                       = suite.testUsers["local_account_1"]
    866 		maxID              *string = nil
    867 		minID              *string = nil
    868 		limit              *int    = nil
    869 		offset             *int    = nil
    870 		resolve            *bool   = func() *bool { i := true; return &i }()
    871 		query                      = "a"
    872 		queryType          *string = nil // Return anything.
    873 		following          *bool   = func() *bool { i := true; return &i }()
    874 		expectedHTTPStatus         = http.StatusOK
    875 		expectedBody               = ""
    876 	)
    877 
    878 	searchResult, err := suite.getSearch(
    879 		requestingAccount,
    880 		token,
    881 		user,
    882 		maxID,
    883 		minID,
    884 		limit,
    885 		offset,
    886 		query,
    887 		queryType,
    888 		resolve,
    889 		following,
    890 		expectedHTTPStatus,
    891 		expectedBody)
    892 	if err != nil {
    893 		suite.FailNow(err.Error())
    894 	}
    895 
    896 	suite.Len(searchResult.Accounts, 2)
    897 	suite.Len(searchResult.Statuses, 4)
    898 	suite.Len(searchResult.Hashtags, 0)
    899 }
    900 
    901 func (suite *SearchGetTestSuite) TestSearchAStatuses() {
    902 	var (
    903 		requestingAccount          = suite.testAccounts["local_account_1"]
    904 		token                      = suite.testTokens["local_account_1"]
    905 		user                       = suite.testUsers["local_account_1"]
    906 		maxID              *string = nil
    907 		minID              *string = nil
    908 		limit              *int    = nil
    909 		offset             *int    = nil
    910 		resolve            *bool   = func() *bool { i := true; return &i }()
    911 		query                      = "a"
    912 		queryType          *string = func() *string { i := "statuses"; return &i }() // Only statuses.
    913 		following          *bool   = nil
    914 		expectedHTTPStatus         = http.StatusOK
    915 		expectedBody               = ""
    916 	)
    917 
    918 	searchResult, err := suite.getSearch(
    919 		requestingAccount,
    920 		token,
    921 		user,
    922 		maxID,
    923 		minID,
    924 		limit,
    925 		offset,
    926 		query,
    927 		queryType,
    928 		resolve,
    929 		following,
    930 		expectedHTTPStatus,
    931 		expectedBody)
    932 	if err != nil {
    933 		suite.FailNow(err.Error())
    934 	}
    935 
    936 	suite.Len(searchResult.Accounts, 0)
    937 	suite.Len(searchResult.Statuses, 4)
    938 	suite.Len(searchResult.Hashtags, 0)
    939 }
    940 
    941 func (suite *SearchGetTestSuite) TestSearchAAccounts() {
    942 	var (
    943 		requestingAccount          = suite.testAccounts["local_account_1"]
    944 		token                      = suite.testTokens["local_account_1"]
    945 		user                       = suite.testUsers["local_account_1"]
    946 		maxID              *string = nil
    947 		minID              *string = nil
    948 		limit              *int    = nil
    949 		offset             *int    = nil
    950 		resolve            *bool   = func() *bool { i := true; return &i }()
    951 		query                      = "a"
    952 		queryType          *string = func() *string { i := "accounts"; return &i }() // Only accounts.
    953 		following          *bool   = nil
    954 		expectedHTTPStatus         = http.StatusOK
    955 		expectedBody               = ""
    956 	)
    957 
    958 	searchResult, err := suite.getSearch(
    959 		requestingAccount,
    960 		token,
    961 		user,
    962 		maxID,
    963 		minID,
    964 		limit,
    965 		offset,
    966 		query,
    967 		queryType,
    968 		resolve,
    969 		following,
    970 		expectedHTTPStatus,
    971 		expectedBody)
    972 	if err != nil {
    973 		suite.FailNow(err.Error())
    974 	}
    975 
    976 	suite.Len(searchResult.Accounts, 5)
    977 	suite.Len(searchResult.Statuses, 0)
    978 	suite.Len(searchResult.Hashtags, 0)
    979 }
    980 
    981 func (suite *SearchGetTestSuite) TestSearchAAccountsLimit1() {
    982 	var (
    983 		requestingAccount          = suite.testAccounts["local_account_1"]
    984 		token                      = suite.testTokens["local_account_1"]
    985 		user                       = suite.testUsers["local_account_1"]
    986 		maxID              *string = nil
    987 		minID              *string = nil
    988 		limit              *int    = func() *int { i := 1; return &i }()
    989 		offset             *int    = nil
    990 		resolve            *bool   = func() *bool { i := true; return &i }()
    991 		query                      = "a"
    992 		queryType          *string = func() *string { i := "accounts"; return &i }() // Only accounts.
    993 		following          *bool   = nil
    994 		expectedHTTPStatus         = http.StatusOK
    995 		expectedBody               = ""
    996 	)
    997 
    998 	searchResult, err := suite.getSearch(
    999 		requestingAccount,
   1000 		token,
   1001 		user,
   1002 		maxID,
   1003 		minID,
   1004 		limit,
   1005 		offset,
   1006 		query,
   1007 		queryType,
   1008 		resolve,
   1009 		following,
   1010 		expectedHTTPStatus,
   1011 		expectedBody)
   1012 	if err != nil {
   1013 		suite.FailNow(err.Error())
   1014 	}
   1015 
   1016 	suite.Len(searchResult.Accounts, 1)
   1017 	suite.Len(searchResult.Statuses, 0)
   1018 	suite.Len(searchResult.Hashtags, 0)
   1019 }
   1020 
   1021 func (suite *SearchGetTestSuite) TestSearchLocalInstanceAccountByURI() {
   1022 	var (
   1023 		requestingAccount          = suite.testAccounts["local_account_1"]
   1024 		token                      = suite.testTokens["local_account_1"]
   1025 		user                       = suite.testUsers["local_account_1"]
   1026 		maxID              *string = nil
   1027 		minID              *string = nil
   1028 		limit              *int    = nil
   1029 		offset             *int    = nil
   1030 		resolve            *bool   = nil
   1031 		query                      = "http://localhost:8080/users/localhost:8080"
   1032 		queryType          *string = func() *string { i := "accounts"; return &i }()
   1033 		following          *bool   = nil
   1034 		expectedHTTPStatus         = http.StatusOK
   1035 		expectedBody               = ""
   1036 	)
   1037 
   1038 	searchResult, err := suite.getSearch(
   1039 		requestingAccount,
   1040 		token,
   1041 		user,
   1042 		maxID,
   1043 		minID,
   1044 		limit,
   1045 		offset,
   1046 		query,
   1047 		queryType,
   1048 		resolve,
   1049 		following,
   1050 		expectedHTTPStatus,
   1051 		expectedBody)
   1052 	if err != nil {
   1053 		suite.FailNow(err.Error())
   1054 	}
   1055 
   1056 	suite.Len(searchResult.Accounts, 0)
   1057 	suite.Len(searchResult.Statuses, 0)
   1058 	suite.Len(searchResult.Hashtags, 0)
   1059 }
   1060 
   1061 func (suite *SearchGetTestSuite) TestSearchInstanceAccountFull() {
   1062 	// Namestring excludes ':' in usernames, so we
   1063 	// need to fiddle with the instance account a
   1064 	// bit to get it to look like a different domain.
   1065 	newDomain := "example.org"
   1066 	suite.bodgeLocalInstance(newDomain)
   1067 
   1068 	var (
   1069 		requestingAccount          = suite.testAccounts["local_account_1"]
   1070 		token                      = suite.testTokens["local_account_1"]
   1071 		user                       = suite.testUsers["local_account_1"]
   1072 		maxID              *string = nil
   1073 		minID              *string = nil
   1074 		limit              *int    = nil
   1075 		offset             *int    = nil
   1076 		resolve            *bool   = nil
   1077 		query                      = "@" + newDomain + "@" + newDomain
   1078 		queryType          *string = nil
   1079 		following          *bool   = nil
   1080 		expectedHTTPStatus         = http.StatusOK
   1081 		expectedBody               = ""
   1082 	)
   1083 
   1084 	searchResult, err := suite.getSearch(
   1085 		requestingAccount,
   1086 		token,
   1087 		user,
   1088 		maxID,
   1089 		minID,
   1090 		limit,
   1091 		offset,
   1092 		query,
   1093 		queryType,
   1094 		resolve,
   1095 		following,
   1096 		expectedHTTPStatus,
   1097 		expectedBody)
   1098 	if err != nil {
   1099 		suite.FailNow(err.Error())
   1100 	}
   1101 
   1102 	suite.Len(searchResult.Accounts, 0)
   1103 	suite.Len(searchResult.Statuses, 0)
   1104 	suite.Len(searchResult.Hashtags, 0)
   1105 }
   1106 
   1107 func (suite *SearchGetTestSuite) TestSearchInstanceAccountPartial() {
   1108 	// Namestring excludes ':' in usernames, so we
   1109 	// need to fiddle with the instance account a
   1110 	// bit to get it to look like a different domain.
   1111 	newDomain := "example.org"
   1112 	suite.bodgeLocalInstance(newDomain)
   1113 
   1114 	var (
   1115 		requestingAccount          = suite.testAccounts["local_account_1"]
   1116 		token                      = suite.testTokens["local_account_1"]
   1117 		user                       = suite.testUsers["local_account_1"]
   1118 		maxID              *string = nil
   1119 		minID              *string = nil
   1120 		limit              *int    = nil
   1121 		offset             *int    = nil
   1122 		resolve            *bool   = nil
   1123 		query                      = "@" + newDomain
   1124 		queryType          *string = nil
   1125 		following          *bool   = nil
   1126 		expectedHTTPStatus         = http.StatusOK
   1127 		expectedBody               = ""
   1128 	)
   1129 
   1130 	searchResult, err := suite.getSearch(
   1131 		requestingAccount,
   1132 		token,
   1133 		user,
   1134 		maxID,
   1135 		minID,
   1136 		limit,
   1137 		offset,
   1138 		query,
   1139 		queryType,
   1140 		resolve,
   1141 		following,
   1142 		expectedHTTPStatus,
   1143 		expectedBody)
   1144 	if err != nil {
   1145 		suite.FailNow(err.Error())
   1146 	}
   1147 
   1148 	suite.Len(searchResult.Accounts, 0)
   1149 	suite.Len(searchResult.Statuses, 0)
   1150 	suite.Len(searchResult.Hashtags, 0)
   1151 }
   1152 
   1153 func (suite *SearchGetTestSuite) TestSearchBadQueryType() {
   1154 	var (
   1155 		requestingAccount          = suite.testAccounts["local_account_1"]
   1156 		token                      = suite.testTokens["local_account_1"]
   1157 		user                       = suite.testUsers["local_account_1"]
   1158 		maxID              *string = nil
   1159 		minID              *string = nil
   1160 		limit              *int    = nil
   1161 		offset             *int    = nil
   1162 		resolve            *bool   = nil
   1163 		query                      = "whatever"
   1164 		queryType          *string = func() *string { i := "aaaaaaaaaaa"; return &i }()
   1165 		following          *bool   = nil
   1166 		expectedHTTPStatus         = http.StatusBadRequest
   1167 		expectedBody               = `{"error":"Bad Request: search query type aaaaaaaaaaa was not recognized, valid options are ['', 'accounts', 'statuses', 'hashtags']"}`
   1168 	)
   1169 
   1170 	_, err := suite.getSearch(
   1171 		requestingAccount,
   1172 		token,
   1173 		user,
   1174 		maxID,
   1175 		minID,
   1176 		limit,
   1177 		offset,
   1178 		query,
   1179 		queryType,
   1180 		resolve,
   1181 		following,
   1182 		expectedHTTPStatus,
   1183 		expectedBody)
   1184 	if err != nil {
   1185 		suite.FailNow(err.Error())
   1186 	}
   1187 }
   1188 
   1189 func (suite *SearchGetTestSuite) TestSearchEmptyQuery() {
   1190 	var (
   1191 		requestingAccount          = suite.testAccounts["local_account_1"]
   1192 		token                      = suite.testTokens["local_account_1"]
   1193 		user                       = suite.testUsers["local_account_1"]
   1194 		maxID              *string = nil
   1195 		minID              *string = nil
   1196 		limit              *int    = nil
   1197 		offset             *int    = nil
   1198 		resolve            *bool   = nil
   1199 		query                      = ""
   1200 		queryType          *string = func() *string { i := "aaaaaaaaaaa"; return &i }()
   1201 		following          *bool   = nil
   1202 		expectedHTTPStatus         = http.StatusBadRequest
   1203 		expectedBody               = `{"error":"Bad Request: required key q was not set or had empty value"}`
   1204 	)
   1205 
   1206 	_, err := suite.getSearch(
   1207 		requestingAccount,
   1208 		token,
   1209 		user,
   1210 		maxID,
   1211 		minID,
   1212 		limit,
   1213 		offset,
   1214 		query,
   1215 		queryType,
   1216 		resolve,
   1217 		following,
   1218 		expectedHTTPStatus,
   1219 		expectedBody)
   1220 	if err != nil {
   1221 		suite.FailNow(err.Error())
   1222 	}
   1223 }
   1224 
   1225 func TestSearchGetTestSuite(t *testing.T) {
   1226 	suite.Run(t, &SearchGetTestSuite{})
   1227 }