// GoToSocial
// Copyright (C) GoToSocial Authors admin@gotosocial.org
// SPDX-License-Identifier: AGPL-3.0-or-later
//
// 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
This is the GoToSocial testrig. It doesn't federate or anything.
When the testrig is shut down, all data on it will be deleted.
Don't use this in production!
", "short_description": "This is the GoToSocial testrig. It doesn't federate or anything.
When the testrig is shut down, all data on it will be deleted.
Don't use this in production!
", "email": "someone@example.org", "version": "0.0.0-testrig", "languages": [ "nl", "en-gb" ], "registrations": true, "approval_required": true, "invites_enabled": false, "configuration": { "statuses": { "max_characters": 5000, "max_media_attachments": 6, "characters_reserved_per_url": 25, "supported_mime_types": [ "text/plain", "text/markdown" ] }, "media_attachments": { "supported_mime_types": [ "image/jpeg", "image/gif", "image/png", "image/webp", "video/mp4" ], "image_size_limit": 10485760, "image_matrix_limit": 16777216, "video_size_limit": 41943040, "video_frame_rate_limit": 60, "video_matrix_limit": 16777216 }, "polls": { "max_options": 6, "max_characters_per_option": 50, "min_expiration": 300, "max_expiration": 2629746 }, "accounts": { "allow_custom_css": true, "max_featured_tags": 10, "max_profile_fields": 6 }, "emojis": { "emoji_size_limit": 51200 } }, "urls": { "streaming_api": "wss://localhost:8080" }, "stats": { "domain_count": 2, "status_count": 18, "user_count": 4 }, "thumbnail": "http://localhost:8080/assets/logo.png", "contact_account": { "id": "01F8MH17FWEB39HZJ76B6VXSKF", "username": "admin", "acct": "admin", "display_name": "", "locked": false, "discoverable": true, "bot": false, "created_at": "2022-05-17T13:10:59.000Z", "note": "", "url": "http://localhost:8080/@admin", "avatar": "", "avatar_static": "", "header": "http://localhost:8080/assets/default_header.png", "header_static": "http://localhost:8080/assets/default_header.png", "followers_count": 1, "following_count": 1, "statuses_count": 4, "last_status_at": "2021-10-20T10:41:37.000Z", "emojis": [], "fields": [], "enable_rss": true, "role": { "name": "admin" } }, "max_toot_chars": 5000, "rules": [ { "id": "01GP3AWY4CRDVRNZKW0TEAMB51", "text": "Be gay" }, { "id": "01GP3DFY9XQ1TJMZT5BGAZPXX3", "text": "Do crime" } ] }`, dst.String()) } func (suite *InstancePatchTestSuite) TestInstancePatch2() { code, b := suite.instancePatch("", "", map[string][]string{ "title": {"Geoff's Instance
"}, }) if expectedCode := http.StatusOK; code != expectedCode { suite.FailNowf("wrong status code", "expected %d but got %d", expectedCode, code) } dst := new(bytes.Buffer) if err := json.Indent(dst, b, "", " "); err != nil { suite.FailNow(err.Error()) } suite.Equal(`{ "uri": "http://localhost:8080", "account_domain": "localhost:8080", "title": "Geoff's Instance", "description": "This is the GoToSocial testrig. It doesn't federate or anything.
When the testrig is shut down, all data on it will be deleted.
Don't use this in production!
", "short_description": "This is the GoToSocial testrig. It doesn't federate or anything.
When the testrig is shut down, all data on it will be deleted.
Don't use this in production!
", "email": "admin@example.org", "version": "0.0.0-testrig", "languages": [ "nl", "en-gb" ], "registrations": true, "approval_required": true, "invites_enabled": false, "configuration": { "statuses": { "max_characters": 5000, "max_media_attachments": 6, "characters_reserved_per_url": 25, "supported_mime_types": [ "text/plain", "text/markdown" ] }, "media_attachments": { "supported_mime_types": [ "image/jpeg", "image/gif", "image/png", "image/webp", "video/mp4" ], "image_size_limit": 10485760, "image_matrix_limit": 16777216, "video_size_limit": 41943040, "video_frame_rate_limit": 60, "video_matrix_limit": 16777216 }, "polls": { "max_options": 6, "max_characters_per_option": 50, "min_expiration": 300, "max_expiration": 2629746 }, "accounts": { "allow_custom_css": true, "max_featured_tags": 10, "max_profile_fields": 6 }, "emojis": { "emoji_size_limit": 51200 } }, "urls": { "streaming_api": "wss://localhost:8080" }, "stats": { "domain_count": 2, "status_count": 18, "user_count": 4 }, "thumbnail": "http://localhost:8080/assets/logo.png", "contact_account": { "id": "01F8MH17FWEB39HZJ76B6VXSKF", "username": "admin", "acct": "admin", "display_name": "", "locked": false, "discoverable": true, "bot": false, "created_at": "2022-05-17T13:10:59.000Z", "note": "", "url": "http://localhost:8080/@admin", "avatar": "", "avatar_static": "", "header": "http://localhost:8080/assets/default_header.png", "header_static": "http://localhost:8080/assets/default_header.png", "followers_count": 1, "following_count": 1, "statuses_count": 4, "last_status_at": "2021-10-20T10:41:37.000Z", "emojis": [], "fields": [], "enable_rss": true, "role": { "name": "admin" } }, "max_toot_chars": 5000, "rules": [ { "id": "01GP3AWY4CRDVRNZKW0TEAMB51", "text": "Be gay" }, { "id": "01GP3DFY9XQ1TJMZT5BGAZPXX3", "text": "Do crime" } ] }`, dst.String()) } func (suite *InstancePatchTestSuite) TestInstancePatch3() { code, b := suite.instancePatch("", "", map[string][]string{ "short_description": {"This is some html, which is allowed in short descriptions.
"}, }) if expectedCode := http.StatusOK; code != expectedCode { suite.FailNowf("wrong status code", "expected %d but got %d", expectedCode, code) } dst := new(bytes.Buffer) if err := json.Indent(dst, b, "", " "); err != nil { suite.FailNow(err.Error()) } suite.Equal(`{ "uri": "http://localhost:8080", "account_domain": "localhost:8080", "title": "GoToSocial Testrig Instance", "description": "This is the GoToSocial testrig. It doesn't federate or anything.
When the testrig is shut down, all data on it will be deleted.
Don't use this in production!
", "short_description": "This is some html, which is allowed in short descriptions.
", "email": "admin@example.org", "version": "0.0.0-testrig", "languages": [ "nl", "en-gb" ], "registrations": true, "approval_required": true, "invites_enabled": false, "configuration": { "statuses": { "max_characters": 5000, "max_media_attachments": 6, "characters_reserved_per_url": 25, "supported_mime_types": [ "text/plain", "text/markdown" ] }, "media_attachments": { "supported_mime_types": [ "image/jpeg", "image/gif", "image/png", "image/webp", "video/mp4" ], "image_size_limit": 10485760, "image_matrix_limit": 16777216, "video_size_limit": 41943040, "video_frame_rate_limit": 60, "video_matrix_limit": 16777216 }, "polls": { "max_options": 6, "max_characters_per_option": 50, "min_expiration": 300, "max_expiration": 2629746 }, "accounts": { "allow_custom_css": true, "max_featured_tags": 10, "max_profile_fields": 6 }, "emojis": { "emoji_size_limit": 51200 } }, "urls": { "streaming_api": "wss://localhost:8080" }, "stats": { "domain_count": 2, "status_count": 18, "user_count": 4 }, "thumbnail": "http://localhost:8080/assets/logo.png", "contact_account": { "id": "01F8MH17FWEB39HZJ76B6VXSKF", "username": "admin", "acct": "admin", "display_name": "", "locked": false, "discoverable": true, "bot": false, "created_at": "2022-05-17T13:10:59.000Z", "note": "", "url": "http://localhost:8080/@admin", "avatar": "", "avatar_static": "", "header": "http://localhost:8080/assets/default_header.png", "header_static": "http://localhost:8080/assets/default_header.png", "followers_count": 1, "following_count": 1, "statuses_count": 4, "last_status_at": "2021-10-20T10:41:37.000Z", "emojis": [], "fields": [], "enable_rss": true, "role": { "name": "admin" } }, "max_toot_chars": 5000, "rules": [ { "id": "01GP3AWY4CRDVRNZKW0TEAMB51", "text": "Be gay" }, { "id": "01GP3DFY9XQ1TJMZT5BGAZPXX3", "text": "Do crime" } ] }`, dst.String()) } func (suite *InstancePatchTestSuite) TestInstancePatch4() { code, b := suite.instancePatch("", "", map[string][]string{ "": {""}, }) if expectedCode := http.StatusBadRequest; code != expectedCode { suite.FailNowf("wrong status code", "expected %d but got %d", expectedCode, code) } dst := new(bytes.Buffer) if err := json.Indent(dst, b, "", " "); err != nil { suite.FailNow(err.Error()) } suite.Equal(`{"error":"Bad Request: empty form submitted"}`, string(b)) } func (suite *InstancePatchTestSuite) TestInstancePatch5() { requestBody, w, err := testrig.CreateMultipartFormData( "", "", map[string][]string{ "short_description": {"This is some html, which is allowed in short descriptions.
"}, }) if err != nil { panic(err) } bodyBytes := requestBody.Bytes() // set up the request recorder := httptest.NewRecorder() ctx := suite.newContext(recorder, http.MethodPatch, instance.InstanceInformationPathV1, bodyBytes, w.FormDataContentType(), true) ctx.Set(oauth.SessionAuthorizedAccount, suite.testAccounts["local_account_1"]) ctx.Set(oauth.SessionAuthorizedToken, oauth.DBTokenToToken(suite.testTokens["local_account_1"])) ctx.Set(oauth.SessionAuthorizedApplication, suite.testApplications["application_1"]) ctx.Set(oauth.SessionAuthorizedUser, suite.testUsers["local_account_1"]) // call the handler suite.instanceModule.InstanceUpdatePATCHHandler(ctx) suite.Equal(http.StatusForbidden, recorder.Code) result := recorder.Result() defer result.Body.Close() b, err := io.ReadAll(result.Body) suite.NoError(err) suite.Equal(`{"error":"Forbidden: user is not an admin so cannot update instance settings"}`, string(b)) } func (suite *InstancePatchTestSuite) TestInstancePatch6() { code, b := suite.instancePatch("", "", map[string][]string{ "contact_email": {""}, }) if expectedCode := http.StatusOK; code != expectedCode { suite.FailNowf("wrong status code", "expected %d but got %d", expectedCode, code) } dst := new(bytes.Buffer) if err := json.Indent(dst, b, "", " "); err != nil { suite.FailNow(err.Error()) } suite.Equal(`{ "uri": "http://localhost:8080", "account_domain": "localhost:8080", "title": "GoToSocial Testrig Instance", "description": "This is the GoToSocial testrig. It doesn't federate or anything.
When the testrig is shut down, all data on it will be deleted.
Don't use this in production!
", "short_description": "This is the GoToSocial testrig. It doesn't federate or anything.
When the testrig is shut down, all data on it will be deleted.
Don't use this in production!
", "email": "", "version": "0.0.0-testrig", "languages": [ "nl", "en-gb" ], "registrations": true, "approval_required": true, "invites_enabled": false, "configuration": { "statuses": { "max_characters": 5000, "max_media_attachments": 6, "characters_reserved_per_url": 25, "supported_mime_types": [ "text/plain", "text/markdown" ] }, "media_attachments": { "supported_mime_types": [ "image/jpeg", "image/gif", "image/png", "image/webp", "video/mp4" ], "image_size_limit": 10485760, "image_matrix_limit": 16777216, "video_size_limit": 41943040, "video_frame_rate_limit": 60, "video_matrix_limit": 16777216 }, "polls": { "max_options": 6, "max_characters_per_option": 50, "min_expiration": 300, "max_expiration": 2629746 }, "accounts": { "allow_custom_css": true, "max_featured_tags": 10, "max_profile_fields": 6 }, "emojis": { "emoji_size_limit": 51200 } }, "urls": { "streaming_api": "wss://localhost:8080" }, "stats": { "domain_count": 2, "status_count": 18, "user_count": 4 }, "thumbnail": "http://localhost:8080/assets/logo.png", "contact_account": { "id": "01F8MH17FWEB39HZJ76B6VXSKF", "username": "admin", "acct": "admin", "display_name": "", "locked": false, "discoverable": true, "bot": false, "created_at": "2022-05-17T13:10:59.000Z", "note": "", "url": "http://localhost:8080/@admin", "avatar": "", "avatar_static": "", "header": "http://localhost:8080/assets/default_header.png", "header_static": "http://localhost:8080/assets/default_header.png", "followers_count": 1, "following_count": 1, "statuses_count": 4, "last_status_at": "2021-10-20T10:41:37.000Z", "emojis": [], "fields": [], "enable_rss": true, "role": { "name": "admin" } }, "max_toot_chars": 5000, "rules": [ { "id": "01GP3AWY4CRDVRNZKW0TEAMB51", "text": "Be gay" }, { "id": "01GP3DFY9XQ1TJMZT5BGAZPXX3", "text": "Do crime" } ] }`, dst.String()) } func (suite *InstancePatchTestSuite) TestInstancePatch7() { code, b := suite.instancePatch("", "", map[string][]string{ "contact_email": {"not.an.email.address"}, }) if expectedCode := http.StatusBadRequest; code != expectedCode { suite.FailNowf("wrong status code", "expected %d but got %d", expectedCode, code) } dst := new(bytes.Buffer) if err := json.Indent(dst, b, "", " "); err != nil { suite.FailNow(err.Error()) } suite.Equal(`{"error":"Bad Request: mail: missing '@' or angle-addr"}`, string(b)) } func (suite *InstancePatchTestSuite) TestInstancePatch8() { code, b := suite.instancePatch("thumbnail", "../../../../testrig/media/peglin.gif", map[string][]string{ "thumbnail_description": {"A bouncing little green peglin."}, }) if expectedCode := http.StatusOK; code != expectedCode { suite.FailNowf("wrong status code", "expected %d but got %d", expectedCode, code) } dst := new(bytes.Buffer) if err := json.Indent(dst, b, "", " "); err != nil { suite.FailNow(err.Error()) } instanceAccount, err := suite.db.GetInstanceAccount(context.Background(), "") if err != nil { suite.FailNow(err.Error()) } suite.Equal(`{ "uri": "http://localhost:8080", "account_domain": "localhost:8080", "title": "GoToSocial Testrig Instance", "description": "This is the GoToSocial testrig. It doesn't federate or anything.
When the testrig is shut down, all data on it will be deleted.
Don't use this in production!
", "short_description": "This is the GoToSocial testrig. It doesn't federate or anything.
When the testrig is shut down, all data on it will be deleted.
Don't use this in production!
", "email": "admin@example.org", "version": "0.0.0-testrig", "languages": [ "nl", "en-gb" ], "registrations": true, "approval_required": true, "invites_enabled": false, "configuration": { "statuses": { "max_characters": 5000, "max_media_attachments": 6, "characters_reserved_per_url": 25, "supported_mime_types": [ "text/plain", "text/markdown" ] }, "media_attachments": { "supported_mime_types": [ "image/jpeg", "image/gif", "image/png", "image/webp", "video/mp4" ], "image_size_limit": 10485760, "image_matrix_limit": 16777216, "video_size_limit": 41943040, "video_frame_rate_limit": 60, "video_matrix_limit": 16777216 }, "polls": { "max_options": 6, "max_characters_per_option": 50, "min_expiration": 300, "max_expiration": 2629746 }, "accounts": { "allow_custom_css": true, "max_featured_tags": 10, "max_profile_fields": 6 }, "emojis": { "emoji_size_limit": 51200 } }, "urls": { "streaming_api": "wss://localhost:8080" }, "stats": { "domain_count": 2, "status_count": 18, "user_count": 4 }, "thumbnail": "http://localhost:8080/fileserver/01AY6P665V14JJR0AFVRT7311Y/attachment/original/`+instanceAccount.AvatarMediaAttachment.ID+`.gif",`+` "thumbnail_type": "image/gif", "thumbnail_description": "A bouncing little green peglin.", "contact_account": { "id": "01F8MH17FWEB39HZJ76B6VXSKF", "username": "admin", "acct": "admin", "display_name": "", "locked": false, "discoverable": true, "bot": false, "created_at": "2022-05-17T13:10:59.000Z", "note": "", "url": "http://localhost:8080/@admin", "avatar": "", "avatar_static": "", "header": "http://localhost:8080/assets/default_header.png", "header_static": "http://localhost:8080/assets/default_header.png", "followers_count": 1, "following_count": 1, "statuses_count": 4, "last_status_at": "2021-10-20T10:41:37.000Z", "emojis": [], "fields": [], "enable_rss": true, "role": { "name": "admin" } }, "max_toot_chars": 5000, "rules": [ { "id": "01GP3AWY4CRDVRNZKW0TEAMB51", "text": "Be gay" }, { "id": "01GP3DFY9XQ1TJMZT5BGAZPXX3", "text": "Do crime" } ] }`, dst.String()) // extra bonus: check the v2 model thumbnail after the patch instanceV2, err := suite.processor.InstanceGetV2(context.Background()) if err != nil { suite.FailNow(err.Error()) } instanceV2ThumbnailJson, err := json.MarshalIndent(instanceV2.Thumbnail, "", " ") if err != nil { suite.FailNow(err.Error()) } suite.Equal(`{ "url": "http://localhost:8080/fileserver/01AY6P665V14JJR0AFVRT7311Y/attachment/original/`+instanceAccount.AvatarMediaAttachment.ID+`.gif",`+` "thumbnail_type": "image/gif", "thumbnail_description": "A bouncing little green peglin.", "blurhash": "LG9t;qRS4YtO.4WDRlt5IXoxtPj[" }`, string(instanceV2ThumbnailJson)) // double extra special bonus: now update the image description without changing the image code2, b2 := suite.instancePatch("", "", map[string][]string{ "thumbnail_description": {"updating the thumbnail description without changing anything else!"}, }) if expectedCode := http.StatusOK; code2 != expectedCode { suite.FailNowf("wrong status code", "expected %d but got %d", expectedCode, code2) } // just extract the value we wanna check, no need to print the whole thing again i := make(map[string]interface{}) if err := json.Unmarshal(b2, &i); err != nil { suite.FailNow(err.Error()) } suite.EqualValues("updating the thumbnail description without changing anything else!", i["thumbnail_description"]) } func (suite *InstancePatchTestSuite) TestInstancePatch9() { code, b := suite.instancePatch("", "", map[string][]string{ "thumbnail_description": {"setting a new description without having a custom image set; this should change nothing!"}, }) if expectedCode := http.StatusOK; code != expectedCode { suite.FailNowf("wrong status code", "expected %d but got %d", expectedCode, code) } dst := new(bytes.Buffer) if err := json.Indent(dst, b, "", " "); err != nil { suite.FailNow(err.Error()) } suite.Equal(`{ "uri": "http://localhost:8080", "account_domain": "localhost:8080", "title": "GoToSocial Testrig Instance", "description": "This is the GoToSocial testrig. It doesn't federate or anything.
When the testrig is shut down, all data on it will be deleted.
Don't use this in production!
", "short_description": "This is the GoToSocial testrig. It doesn't federate or anything.
When the testrig is shut down, all data on it will be deleted.
Don't use this in production!
", "email": "admin@example.org", "version": "0.0.0-testrig", "languages": [ "nl", "en-gb" ], "registrations": true, "approval_required": true, "invites_enabled": false, "configuration": { "statuses": { "max_characters": 5000, "max_media_attachments": 6, "characters_reserved_per_url": 25, "supported_mime_types": [ "text/plain", "text/markdown" ] }, "media_attachments": { "supported_mime_types": [ "image/jpeg", "image/gif", "image/png", "image/webp", "video/mp4" ], "image_size_limit": 10485760, "image_matrix_limit": 16777216, "video_size_limit": 41943040, "video_frame_rate_limit": 60, "video_matrix_limit": 16777216 }, "polls": { "max_options": 6, "max_characters_per_option": 50, "min_expiration": 300, "max_expiration": 2629746 }, "accounts": { "allow_custom_css": true, "max_featured_tags": 10, "max_profile_fields": 6 }, "emojis": { "emoji_size_limit": 51200 } }, "urls": { "streaming_api": "wss://localhost:8080" }, "stats": { "domain_count": 2, "status_count": 18, "user_count": 4 }, "thumbnail": "http://localhost:8080/assets/logo.png", "contact_account": { "id": "01F8MH17FWEB39HZJ76B6VXSKF", "username": "admin", "acct": "admin", "display_name": "", "locked": false, "discoverable": true, "bot": false, "created_at": "2022-05-17T13:10:59.000Z", "note": "", "url": "http://localhost:8080/@admin", "avatar": "", "avatar_static": "", "header": "http://localhost:8080/assets/default_header.png", "header_static": "http://localhost:8080/assets/default_header.png", "followers_count": 1, "following_count": 1, "statuses_count": 4, "last_status_at": "2021-10-20T10:41:37.000Z", "emojis": [], "fields": [], "enable_rss": true, "role": { "name": "admin" } }, "max_toot_chars": 5000, "rules": [ { "id": "01GP3AWY4CRDVRNZKW0TEAMB51", "text": "Be gay" }, { "id": "01GP3DFY9XQ1TJMZT5BGAZPXX3", "text": "Do crime" } ] }`, dst.String()) } func TestInstancePatchTestSuite(t *testing.T) { suite.Run(t, &InstancePatchTestSuite{}) }