diff options
author | 2023-01-02 13:10:50 +0100 | |
---|---|---|
committer | 2023-01-02 12:10:50 +0000 | |
commit | 941893a774c83802afdc4cc76e1d30c59b6c5585 (patch) | |
tree | 6e7296146dedfeac8e83655157270f41e190724b /internal/api/fileserver/servefile_test.go | |
parent | [chore]: Bump github.com/abema/go-mp4 from 0.8.0 to 0.9.0 (#1287) (diff) | |
download | gotosocial-941893a774c83802afdc4cc76e1d30c59b6c5585.tar.xz |
[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
Diffstat (limited to 'internal/api/fileserver/servefile_test.go')
-rw-r--r-- | internal/api/fileserver/servefile_test.go | 272 |
1 files changed, 272 insertions, 0 deletions
diff --git a/internal/api/fileserver/servefile_test.go b/internal/api/fileserver/servefile_test.go new file mode 100644 index 000000000..efaf3896d --- /dev/null +++ b/internal/api/fileserver/servefile_test.go @@ -0,0 +1,272 @@ +/* + 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 <http://www.gnu.org/licenses/>. +*/ + +package fileserver_test + +import ( + "context" + "io/ioutil" + "net/http" + "net/http/httptest" + "testing" + + "github.com/stretchr/testify/suite" + "github.com/superseriousbusiness/gotosocial/internal/api/fileserver" + "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" + "github.com/superseriousbusiness/gotosocial/internal/media" + "github.com/superseriousbusiness/gotosocial/testrig" +) + +type ServeFileTestSuite struct { + FileserverTestSuite +} + +// GetFile is just a convenience function to save repetition in this test suite. +// It takes the required params to serve a file, calls the handler, and returns +// the http status code, the response headers, and the parsed body bytes. +func (suite *ServeFileTestSuite) GetFile( + accountID string, + mediaType media.Type, + mediaSize media.Size, + filename string, +) (code int, headers http.Header, body []byte) { + recorder := httptest.NewRecorder() + + ctx, _ := testrig.CreateGinTestContext(recorder, nil) + ctx.Request = httptest.NewRequest(http.MethodGet, "http://localhost:8080/whatever", nil) + ctx.Request.Header.Set("accept", "*/*") + ctx.AddParam(fileserver.AccountIDKey, accountID) + ctx.AddParam(fileserver.MediaTypeKey, string(mediaType)) + ctx.AddParam(fileserver.MediaSizeKey, string(mediaSize)) + ctx.AddParam(fileserver.FileNameKey, filename) + + suite.fileServer.ServeFile(ctx) + code = recorder.Code + headers = recorder.Result().Header + + var err error + body, err = ioutil.ReadAll(recorder.Body) + if err != nil { + suite.FailNow(err.Error()) + } + + return +} + +// UncacheAttachment is a convenience function that uncaches the targetAttachment by +// removing its associated files from storage, and updating the database. +func (suite *ServeFileTestSuite) UncacheAttachment(targetAttachment *gtsmodel.MediaAttachment) { + ctx := context.Background() + + cached := false + targetAttachment.Cached = &cached + + if err := suite.db.UpdateByID(ctx, targetAttachment, targetAttachment.ID, "cached"); err != nil { + suite.FailNow(err.Error()) + } + if err := suite.storage.Delete(ctx, targetAttachment.File.Path); err != nil { + suite.FailNow(err.Error()) + } + if err := suite.storage.Delete(ctx, targetAttachment.Thumbnail.Path); err != nil { + suite.FailNow(err.Error()) + } +} + +func (suite *ServeFileTestSuite) TestServeOriginalLocalFileOK() { + targetAttachment := >smodel.MediaAttachment{} + *targetAttachment = *suite.testAttachments["admin_account_status_1_attachment_1"] + fileInStorage, err := suite.storage.Get(context.Background(), targetAttachment.File.Path) + if err != nil { + suite.FailNow(err.Error()) + } + + code, headers, body := suite.GetFile( + targetAttachment.AccountID, + media.TypeAttachment, + media.SizeOriginal, + targetAttachment.ID+".jpeg", + ) + + suite.Equal(http.StatusOK, code) + suite.Equal("image/jpeg", headers.Get("content-type")) + suite.Equal(fileInStorage, body) +} + +func (suite *ServeFileTestSuite) TestServeSmallLocalFileOK() { + targetAttachment := >smodel.MediaAttachment{} + *targetAttachment = *suite.testAttachments["admin_account_status_1_attachment_1"] + fileInStorage, err := suite.storage.Get(context.Background(), targetAttachment.Thumbnail.Path) + if err != nil { + suite.FailNow(err.Error()) + } + + code, headers, body := suite.GetFile( + targetAttachment.AccountID, + media.TypeAttachment, + media.SizeSmall, + targetAttachment.ID+".jpeg", + ) + + suite.Equal(http.StatusOK, code) + suite.Equal("image/jpeg", headers.Get("content-type")) + suite.Equal(fileInStorage, body) +} + +func (suite *ServeFileTestSuite) TestServeOriginalRemoteFileOK() { + targetAttachment := >smodel.MediaAttachment{} + *targetAttachment = *suite.testAttachments["remote_account_1_status_1_attachment_1"] + fileInStorage, err := suite.storage.Get(context.Background(), targetAttachment.File.Path) + if err != nil { + suite.FailNow(err.Error()) + } + + code, headers, body := suite.GetFile( + targetAttachment.AccountID, + media.TypeAttachment, + media.SizeOriginal, + targetAttachment.ID+".jpeg", + ) + + suite.Equal(http.StatusOK, code) + suite.Equal("image/jpeg", headers.Get("content-type")) + suite.Equal(fileInStorage, body) +} + +func (suite *ServeFileTestSuite) TestServeSmallRemoteFileOK() { + targetAttachment := >smodel.MediaAttachment{} + *targetAttachment = *suite.testAttachments["remote_account_1_status_1_attachment_1"] + fileInStorage, err := suite.storage.Get(context.Background(), targetAttachment.Thumbnail.Path) + if err != nil { + suite.FailNow(err.Error()) + } + + code, headers, body := suite.GetFile( + targetAttachment.AccountID, + media.TypeAttachment, + media.SizeSmall, + targetAttachment.ID+".jpeg", + ) + + suite.Equal(http.StatusOK, code) + suite.Equal("image/jpeg", headers.Get("content-type")) + suite.Equal(fileInStorage, body) +} + +func (suite *ServeFileTestSuite) TestServeOriginalRemoteFileRecache() { + targetAttachment := >smodel.MediaAttachment{} + *targetAttachment = *suite.testAttachments["remote_account_1_status_1_attachment_1"] + fileInStorage, err := suite.storage.Get(context.Background(), targetAttachment.File.Path) + if err != nil { + suite.FailNow(err.Error()) + } + + // uncache the attachment so we'll have to refetch it from the 'remote' instance + suite.UncacheAttachment(targetAttachment) + + code, headers, body := suite.GetFile( + targetAttachment.AccountID, + media.TypeAttachment, + media.SizeOriginal, + targetAttachment.ID+".jpeg", + ) + + suite.Equal(http.StatusOK, code) + suite.Equal("image/jpeg", headers.Get("content-type")) + suite.Equal(fileInStorage, body) +} + +func (suite *ServeFileTestSuite) TestServeSmallRemoteFileRecache() { + targetAttachment := >smodel.MediaAttachment{} + *targetAttachment = *suite.testAttachments["remote_account_1_status_1_attachment_1"] + fileInStorage, err := suite.storage.Get(context.Background(), targetAttachment.Thumbnail.Path) + if err != nil { + suite.FailNow(err.Error()) + } + + // uncache the attachment so we'll have to refetch it from the 'remote' instance + suite.UncacheAttachment(targetAttachment) + + code, headers, body := suite.GetFile( + targetAttachment.AccountID, + media.TypeAttachment, + media.SizeSmall, + targetAttachment.ID+".jpeg", + ) + + suite.Equal(http.StatusOK, code) + suite.Equal("image/jpeg", headers.Get("content-type")) + suite.Equal(fileInStorage, body) +} + +func (suite *ServeFileTestSuite) TestServeOriginalRemoteFileRecacheNotFound() { + targetAttachment := >smodel.MediaAttachment{} + *targetAttachment = *suite.testAttachments["remote_account_1_status_1_attachment_1"] + + // uncache the attachment *and* set the remote URL to something that will return a 404 + suite.UncacheAttachment(targetAttachment) + targetAttachment.RemoteURL = "http://nothing.at.this.url/weeeeeeeee" + if err := suite.db.UpdateByID(context.Background(), targetAttachment, targetAttachment.ID, "remote_url"); err != nil { + suite.FailNow(err.Error()) + } + + code, _, _ := suite.GetFile( + targetAttachment.AccountID, + media.TypeAttachment, + media.SizeOriginal, + targetAttachment.ID+".jpeg", + ) + + suite.Equal(http.StatusNotFound, code) +} + +func (suite *ServeFileTestSuite) TestServeSmallRemoteFileRecacheNotFound() { + targetAttachment := >smodel.MediaAttachment{} + *targetAttachment = *suite.testAttachments["remote_account_1_status_1_attachment_1"] + + // uncache the attachment *and* set the remote URL to something that will return a 404 + suite.UncacheAttachment(targetAttachment) + targetAttachment.RemoteURL = "http://nothing.at.this.url/weeeeeeeee" + if err := suite.db.UpdateByID(context.Background(), targetAttachment, targetAttachment.ID, "remote_url"); err != nil { + suite.FailNow(err.Error()) + } + + code, _, _ := suite.GetFile( + targetAttachment.AccountID, + media.TypeAttachment, + media.SizeSmall, + targetAttachment.ID+".jpeg", + ) + + suite.Equal(http.StatusNotFound, code) +} + +// Callers trying to get some random-ass file that doesn't exist should just get a 404 +func (suite *ServeFileTestSuite) TestServeFileNotFound() { + code, _, _ := suite.GetFile( + "01GMMY4G9B0QEG0PQK5Q5JGJWZ", + media.TypeAttachment, + media.SizeOriginal, + "01GMMY68Y7E5DJ3CA3Y9SS8524.jpeg", + ) + + suite.Equal(http.StatusNotFound, code) +} + +func TestServeFileTestSuite(t *testing.T) { + suite.Run(t, new(ServeFileTestSuite)) +} |