mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 06:32:26 -05:00 
			
		
		
		
	[bugfix] Allow instance thumbnail description to be set separately from image (#1417)
This commit is contained in:
		
					parent
					
						
							
								04ac3f8acf
							
						
					
				
			
			
				commit
				
					
						80c26d61f7
					
				
			
		
					 3 changed files with 212 additions and 171 deletions
				
			
		|  | @ -178,19 +178,17 @@ func validateInstanceUpdate(form *apimodel.InstanceSettingsUpdateRequest) error | ||||||
| 		return errors.New("empty form submitted") | 		return errors.New("empty form submitted") | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	maxImageSize := config.GetMediaImageMaxSize() |  | ||||||
| 	maxDescriptionChars := config.GetMediaDescriptionMaxChars() |  | ||||||
| 
 |  | ||||||
| 	// validate avatar if present |  | ||||||
| 	if form.Avatar != nil { | 	if form.Avatar != nil { | ||||||
|  | 		maxImageSize := config.GetMediaImageMaxSize() | ||||||
| 		if size := form.Avatar.Size; size > int64(maxImageSize) { | 		if size := form.Avatar.Size; size > int64(maxImageSize) { | ||||||
| 			return fmt.Errorf("file size limit exceeded: limit is %d bytes but desired instance avatar was %d bytes", maxImageSize, size) | 			return fmt.Errorf("file size limit exceeded: limit is %d bytes but desired instance avatar was %d bytes", maxImageSize, size) | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 		if form.AvatarDescription != nil { | 	if form.AvatarDescription != nil { | ||||||
| 			if length := len([]rune(*form.AvatarDescription)); length > maxDescriptionChars { | 		maxDescriptionChars := config.GetMediaDescriptionMaxChars() | ||||||
| 				return fmt.Errorf("avatar description length must be less than %d characters (inclusive), but provided avatar description was %d chars", maxDescriptionChars, length) | 		if length := len([]rune(*form.AvatarDescription)); length > maxDescriptionChars { | ||||||
| 			} | 			return fmt.Errorf("avatar description length must be less than %d characters (inclusive), but provided avatar description was %d chars", maxDescriptionChars, length) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -37,37 +37,44 @@ type InstancePatchTestSuite struct { | ||||||
| 	InstanceStandardTestSuite | 	InstanceStandardTestSuite | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (suite *InstancePatchTestSuite) TestInstancePatch1() { | func (suite *InstancePatchTestSuite) instancePatch(fieldName string, fileName string, extraFields map[string]string) (code int, body []byte) { | ||||||
| 	requestBody, w, err := testrig.CreateMultipartFormData( | 	requestBody, w, err := testrig.CreateMultipartFormData(fieldName, fileName, extraFields) | ||||||
| 		"", "", |  | ||||||
| 		map[string]string{ |  | ||||||
| 			"title":            "Example Instance", |  | ||||||
| 			"contact_username": "admin", |  | ||||||
| 			"contact_email":    "someone@example.org", |  | ||||||
| 		}) |  | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		panic(err) | 		suite.FailNow(err.Error()) | ||||||
| 	} | 	} | ||||||
| 	bodyBytes := requestBody.Bytes() |  | ||||||
| 
 | 
 | ||||||
| 	// set up the request |  | ||||||
| 	recorder := httptest.NewRecorder() | 	recorder := httptest.NewRecorder() | ||||||
| 	ctx := suite.newContext(recorder, http.MethodPatch, instance.InstanceInformationPathV1, bodyBytes, w.FormDataContentType(), true) | 	ctx := suite.newContext(recorder, http.MethodPatch, instance.InstanceInformationPathV1, requestBody.Bytes(), w.FormDataContentType(), true) | ||||||
| 
 | 
 | ||||||
| 	// call the handler |  | ||||||
| 	suite.instanceModule.InstanceUpdatePATCHHandler(ctx) | 	suite.instanceModule.InstanceUpdatePATCHHandler(ctx) | ||||||
| 
 | 
 | ||||||
| 	// we should have OK because our request was valid |  | ||||||
| 	suite.Equal(http.StatusOK, recorder.Code) |  | ||||||
| 
 |  | ||||||
| 	result := recorder.Result() | 	result := recorder.Result() | ||||||
| 	defer result.Body.Close() | 	defer result.Body.Close() | ||||||
| 
 | 
 | ||||||
| 	b, err := io.ReadAll(result.Body) | 	b, err := io.ReadAll(result.Body) | ||||||
| 	suite.NoError(err) | 	if err != nil { | ||||||
|  | 		suite.FailNow(err.Error()) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return recorder.Code, b | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (suite *InstancePatchTestSuite) TestInstancePatch1() { | ||||||
|  | 	code, b := suite.instancePatch("", "", map[string]string{ | ||||||
|  | 		"title":            "Example Instance", | ||||||
|  | 		"contact_username": "admin", | ||||||
|  | 		"contact_email":    "someone@example.org", | ||||||
|  | 	}) | ||||||
|  | 
 | ||||||
|  | 	if expectedCode := http.StatusOK; code != expectedCode { | ||||||
|  | 		suite.FailNowf("wrong status code", "expected %d but got %d", expectedCode, code) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	dst := new(bytes.Buffer) | 	dst := new(bytes.Buffer) | ||||||
| 	err = json.Indent(dst, b, "", "  ") | 	if err := json.Indent(dst, b, "", "  "); err != nil { | ||||||
| 	suite.NoError(err) | 		suite.FailNow(err.Error()) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	suite.Equal(`{ | 	suite.Equal(`{ | ||||||
|   "uri": "http://localhost:8080", |   "uri": "http://localhost:8080", | ||||||
|   "account_domain": "localhost:8080", |   "account_domain": "localhost:8080", | ||||||
|  | @ -150,34 +157,19 @@ func (suite *InstancePatchTestSuite) TestInstancePatch1() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (suite *InstancePatchTestSuite) TestInstancePatch2() { | func (suite *InstancePatchTestSuite) TestInstancePatch2() { | ||||||
| 	requestBody, w, err := testrig.CreateMultipartFormData( | 	code, b := suite.instancePatch("", "", map[string]string{ | ||||||
| 		"", "", | 		"title": "<p>Geoff's Instance</p>", | ||||||
| 		map[string]string{ | 	}) | ||||||
| 			"title": "<p>Geoff's Instance</p>", | 
 | ||||||
| 		}) | 	if expectedCode := http.StatusOK; code != expectedCode { | ||||||
| 	if err != nil { | 		suite.FailNowf("wrong status code", "expected %d but got %d", expectedCode, code) | ||||||
| 		panic(err) |  | ||||||
| 	} | 	} | ||||||
| 	bodyBytes := requestBody.Bytes() |  | ||||||
| 
 | 
 | ||||||
| 	// set up the request |  | ||||||
| 	recorder := httptest.NewRecorder() |  | ||||||
| 	ctx := suite.newContext(recorder, http.MethodPatch, instance.InstanceInformationPathV1, bodyBytes, w.FormDataContentType(), true) |  | ||||||
| 
 |  | ||||||
| 	// call the handler |  | ||||||
| 	suite.instanceModule.InstanceUpdatePATCHHandler(ctx) |  | ||||||
| 
 |  | ||||||
| 	// we should have OK because our request was valid |  | ||||||
| 	suite.Equal(http.StatusOK, recorder.Code) |  | ||||||
| 
 |  | ||||||
| 	result := recorder.Result() |  | ||||||
| 	defer result.Body.Close() |  | ||||||
| 
 |  | ||||||
| 	b, err := io.ReadAll(result.Body) |  | ||||||
| 	suite.NoError(err) |  | ||||||
| 	dst := new(bytes.Buffer) | 	dst := new(bytes.Buffer) | ||||||
| 	err = json.Indent(dst, b, "", "  ") | 	if err := json.Indent(dst, b, "", "  "); err != nil { | ||||||
| 	suite.NoError(err) | 		suite.FailNow(err.Error()) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	suite.Equal(`{ | 	suite.Equal(`{ | ||||||
|   "uri": "http://localhost:8080", |   "uri": "http://localhost:8080", | ||||||
|   "account_domain": "localhost:8080", |   "account_domain": "localhost:8080", | ||||||
|  | @ -260,34 +252,19 @@ func (suite *InstancePatchTestSuite) TestInstancePatch2() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (suite *InstancePatchTestSuite) TestInstancePatch3() { | func (suite *InstancePatchTestSuite) TestInstancePatch3() { | ||||||
| 	requestBody, w, err := testrig.CreateMultipartFormData( | 	code, b := suite.instancePatch("", "", map[string]string{ | ||||||
| 		"", "", | 		"short_description": "<p>This is some html, which is <em>allowed</em> in short descriptions.</p>", | ||||||
| 		map[string]string{ | 	}) | ||||||
| 			"short_description": "<p>This is some html, which is <em>allowed</em> in short descriptions.</p>", | 
 | ||||||
| 		}) | 	if expectedCode := http.StatusOK; code != expectedCode { | ||||||
| 	if err != nil { | 		suite.FailNowf("wrong status code", "expected %d but got %d", expectedCode, code) | ||||||
| 		panic(err) |  | ||||||
| 	} | 	} | ||||||
| 	bodyBytes := requestBody.Bytes() |  | ||||||
| 
 | 
 | ||||||
| 	// set up the request |  | ||||||
| 	recorder := httptest.NewRecorder() |  | ||||||
| 	ctx := suite.newContext(recorder, http.MethodPatch, instance.InstanceInformationPathV1, bodyBytes, w.FormDataContentType(), true) |  | ||||||
| 
 |  | ||||||
| 	// call the handler |  | ||||||
| 	suite.instanceModule.InstanceUpdatePATCHHandler(ctx) |  | ||||||
| 
 |  | ||||||
| 	// we should have OK because our request was valid |  | ||||||
| 	suite.Equal(http.StatusOK, recorder.Code) |  | ||||||
| 
 |  | ||||||
| 	result := recorder.Result() |  | ||||||
| 	defer result.Body.Close() |  | ||||||
| 
 |  | ||||||
| 	b, err := io.ReadAll(result.Body) |  | ||||||
| 	suite.NoError(err) |  | ||||||
| 	dst := new(bytes.Buffer) | 	dst := new(bytes.Buffer) | ||||||
| 	err = json.Indent(dst, b, "", "  ") | 	if err := json.Indent(dst, b, "", "  "); err != nil { | ||||||
| 	suite.NoError(err) | 		suite.FailNow(err.Error()) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	suite.Equal(`{ | 	suite.Equal(`{ | ||||||
|   "uri": "http://localhost:8080", |   "uri": "http://localhost:8080", | ||||||
|   "account_domain": "localhost:8080", |   "account_domain": "localhost:8080", | ||||||
|  | @ -370,28 +347,18 @@ func (suite *InstancePatchTestSuite) TestInstancePatch3() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (suite *InstancePatchTestSuite) TestInstancePatch4() { | func (suite *InstancePatchTestSuite) TestInstancePatch4() { | ||||||
| 	requestBody, w, err := testrig.CreateMultipartFormData( | 	code, b := suite.instancePatch("", "", map[string]string{ | ||||||
| 		"", "", | 		"": "", | ||||||
| 		map[string]string{}) | 	}) | ||||||
| 	if err != nil { | 
 | ||||||
| 		panic(err) | 	if expectedCode := http.StatusBadRequest; code != expectedCode { | ||||||
|  | 		suite.FailNowf("wrong status code", "expected %d but got %d", expectedCode, code) | ||||||
| 	} | 	} | ||||||
| 	bodyBytes := requestBody.Bytes() |  | ||||||
| 
 | 
 | ||||||
| 	// set up the request | 	dst := new(bytes.Buffer) | ||||||
| 	recorder := httptest.NewRecorder() | 	if err := json.Indent(dst, b, "", "  "); err != nil { | ||||||
| 	ctx := suite.newContext(recorder, http.MethodPatch, instance.InstanceInformationPathV1, bodyBytes, w.FormDataContentType(), true) | 		suite.FailNow(err.Error()) | ||||||
| 
 | 	} | ||||||
| 	// call the handler |  | ||||||
| 	suite.instanceModule.InstanceUpdatePATCHHandler(ctx) |  | ||||||
| 
 |  | ||||||
| 	suite.Equal(http.StatusBadRequest, recorder.Code) |  | ||||||
| 
 |  | ||||||
| 	result := recorder.Result() |  | ||||||
| 	defer result.Body.Close() |  | ||||||
| 
 |  | ||||||
| 	b, err := io.ReadAll(result.Body) |  | ||||||
| 	suite.NoError(err) |  | ||||||
| 
 | 
 | ||||||
| 	suite.Equal(`{"error":"Bad Request: empty form submitted"}`, string(b)) | 	suite.Equal(`{"error":"Bad Request: empty form submitted"}`, string(b)) | ||||||
| } | } | ||||||
|  | @ -431,34 +398,19 @@ func (suite *InstancePatchTestSuite) TestInstancePatch5() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (suite *InstancePatchTestSuite) TestInstancePatch6() { | func (suite *InstancePatchTestSuite) TestInstancePatch6() { | ||||||
| 	requestBody, w, err := testrig.CreateMultipartFormData( | 	code, b := suite.instancePatch("", "", map[string]string{ | ||||||
| 		"", "", | 		"contact_email": "", | ||||||
| 		map[string]string{ | 	}) | ||||||
| 			"contact_email": "", | 
 | ||||||
| 		}) | 	if expectedCode := http.StatusOK; code != expectedCode { | ||||||
| 	if err != nil { | 		suite.FailNowf("wrong status code", "expected %d but got %d", expectedCode, code) | ||||||
| 		panic(err) |  | ||||||
| 	} | 	} | ||||||
| 	bodyBytes := requestBody.Bytes() |  | ||||||
| 
 | 
 | ||||||
| 	// set up the request |  | ||||||
| 	recorder := httptest.NewRecorder() |  | ||||||
| 	ctx := suite.newContext(recorder, http.MethodPatch, instance.InstanceInformationPathV1, bodyBytes, w.FormDataContentType(), true) |  | ||||||
| 
 |  | ||||||
| 	// call the handler |  | ||||||
| 	suite.instanceModule.InstanceUpdatePATCHHandler(ctx) |  | ||||||
| 
 |  | ||||||
| 	// we should have OK because our request was valid |  | ||||||
| 	suite.Equal(http.StatusOK, recorder.Code) |  | ||||||
| 
 |  | ||||||
| 	result := recorder.Result() |  | ||||||
| 	defer result.Body.Close() |  | ||||||
| 
 |  | ||||||
| 	b, err := io.ReadAll(result.Body) |  | ||||||
| 	suite.NoError(err) |  | ||||||
| 	dst := new(bytes.Buffer) | 	dst := new(bytes.Buffer) | ||||||
| 	err = json.Indent(dst, b, "", "  ") | 	if err := json.Indent(dst, b, "", "  "); err != nil { | ||||||
| 	suite.NoError(err) | 		suite.FailNow(err.Error()) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	suite.Equal(`{ | 	suite.Equal(`{ | ||||||
|   "uri": "http://localhost:8080", |   "uri": "http://localhost:8080", | ||||||
|   "account_domain": "localhost:8080", |   "account_domain": "localhost:8080", | ||||||
|  | @ -541,67 +493,40 @@ func (suite *InstancePatchTestSuite) TestInstancePatch6() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (suite *InstancePatchTestSuite) TestInstancePatch7() { | func (suite *InstancePatchTestSuite) TestInstancePatch7() { | ||||||
| 	requestBody, w, err := testrig.CreateMultipartFormData( | 	code, b := suite.instancePatch("", "", map[string]string{ | ||||||
| 		"", "", | 		"contact_email": "not.an.email.address", | ||||||
| 		map[string]string{ | 	}) | ||||||
| 			"contact_email": "not.an.email.address", | 
 | ||||||
| 		}) | 	if expectedCode := http.StatusBadRequest; code != expectedCode { | ||||||
| 	if err != nil { | 		suite.FailNowf("wrong status code", "expected %d but got %d", expectedCode, code) | ||||||
| 		panic(err) |  | ||||||
| 	} | 	} | ||||||
| 	bodyBytes := requestBody.Bytes() |  | ||||||
| 
 | 
 | ||||||
| 	// set up the request | 	dst := new(bytes.Buffer) | ||||||
| 	recorder := httptest.NewRecorder() | 	if err := json.Indent(dst, b, "", "  "); err != nil { | ||||||
| 	ctx := suite.newContext(recorder, http.MethodPatch, instance.InstanceInformationPathV1, bodyBytes, w.FormDataContentType(), true) | 		suite.FailNow(err.Error()) | ||||||
| 
 | 	} | ||||||
| 	// call the handler |  | ||||||
| 	suite.instanceModule.InstanceUpdatePATCHHandler(ctx) |  | ||||||
| 
 |  | ||||||
| 	suite.Equal(http.StatusBadRequest, recorder.Code) |  | ||||||
| 
 |  | ||||||
| 	result := recorder.Result() |  | ||||||
| 	defer result.Body.Close() |  | ||||||
| 
 |  | ||||||
| 	b, err := io.ReadAll(result.Body) |  | ||||||
| 	suite.NoError(err) |  | ||||||
| 
 | 
 | ||||||
| 	suite.Equal(`{"error":"Bad Request: mail: missing '@' or angle-addr"}`, string(b)) | 	suite.Equal(`{"error":"Bad Request: mail: missing '@' or angle-addr"}`, string(b)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (suite *InstancePatchTestSuite) TestInstancePatch8() { | func (suite *InstancePatchTestSuite) TestInstancePatch8() { | ||||||
| 	requestBody, w, err := testrig.CreateMultipartFormData( | 	code, b := suite.instancePatch("thumbnail", "../../../../testrig/media/peglin.gif", map[string]string{ | ||||||
| 		"thumbnail", "../../../../testrig/media/peglin.gif", | 		"thumbnail_description": "A bouncing little green peglin."}) | ||||||
| 		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) | ||||||
| 	if err != nil { |  | ||||||
| 		panic(err) |  | ||||||
| 	} | 	} | ||||||
| 	bodyBytes := requestBody.Bytes() |  | ||||||
| 
 | 
 | ||||||
| 	// set up the request | 	dst := new(bytes.Buffer) | ||||||
| 	recorder := httptest.NewRecorder() | 	if err := json.Indent(dst, b, "", "  "); err != nil { | ||||||
| 	ctx := suite.newContext(recorder, http.MethodPatch, instance.InstanceInformationPathV1, bodyBytes, w.FormDataContentType(), true) | 		suite.FailNow(err.Error()) | ||||||
| 
 | 	} | ||||||
| 	// call the handler |  | ||||||
| 	suite.instanceModule.InstanceUpdatePATCHHandler(ctx) |  | ||||||
| 	suite.Equal(http.StatusOK, recorder.Code) |  | ||||||
| 
 |  | ||||||
| 	result := recorder.Result() |  | ||||||
| 	defer result.Body.Close() |  | ||||||
| 
 | 
 | ||||||
| 	instanceAccount, err := suite.db.GetInstanceAccount(context.Background(), "") | 	instanceAccount, err := suite.db.GetInstanceAccount(context.Background(), "") | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		suite.FailNow(err.Error()) | 		suite.FailNow(err.Error()) | ||||||
| 	} | 	} | ||||||
| 	suite.NotEmpty(instanceAccount.AvatarMediaAttachmentID) |  | ||||||
| 
 | 
 | ||||||
| 	b, err := io.ReadAll(result.Body) |  | ||||||
| 	suite.NoError(err) |  | ||||||
| 	dst := new(bytes.Buffer) |  | ||||||
| 	err = json.Indent(dst, b, "", "  ") |  | ||||||
| 	suite.NoError(err) |  | ||||||
| 	suite.Equal(`{ | 	suite.Equal(`{ | ||||||
|   "uri": "http://localhost:8080", |   "uri": "http://localhost:8080", | ||||||
|   "account_domain": "localhost:8080", |   "account_domain": "localhost:8080", | ||||||
|  | @ -685,7 +610,7 @@ func (suite *InstancePatchTestSuite) TestInstancePatch8() { | ||||||
| }`, dst.String()) | }`, dst.String()) | ||||||
| 
 | 
 | ||||||
| 	// extra bonus: check the v2 model thumbnail after the patch | 	// extra bonus: check the v2 model thumbnail after the patch | ||||||
| 	instanceV2, err := suite.processor.InstanceGetV2(ctx) | 	instanceV2, err := suite.processor.InstanceGetV2(context.Background()) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		suite.FailNow(err.Error()) | 		suite.FailNow(err.Error()) | ||||||
| 	} | 	} | ||||||
|  | @ -701,6 +626,118 @@ func (suite *InstancePatchTestSuite) TestInstancePatch8() { | ||||||
|   "thumbnail_description": "A bouncing little green peglin.", |   "thumbnail_description": "A bouncing little green peglin.", | ||||||
|   "blurhash": "LG9t;qRS4YtO.4WDRlt5IXoxtPj[" |   "blurhash": "LG9t;qRS4YtO.4WDRlt5IXoxtPj[" | ||||||
| }`, string(instanceV2ThumbnailJson)) | }`, 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": "\u003cp\u003eThis is the GoToSocial testrig. It doesn't federate or anything.\u003c/p\u003e\u003cp\u003eWhen the testrig is shut down, all data on it will be deleted.\u003c/p\u003e\u003cp\u003eDon't use this in production!\u003c/p\u003e", | ||||||
|  |   "short_description": "\u003cp\u003eThis is the GoToSocial testrig. It doesn't federate or anything.\u003c/p\u003e\u003cp\u003eWhen the testrig is shut down, all data on it will be deleted.\u003c/p\u003e\u003cp\u003eDon't use this in production!\u003c/p\u003e", | ||||||
|  |   "email": "admin@example.org", | ||||||
|  |   "version": "0.0.0-testrig", | ||||||
|  |   "registrations": true, | ||||||
|  |   "approval_required": true, | ||||||
|  |   "invites_enabled": false, | ||||||
|  |   "configuration": { | ||||||
|  |     "statuses": { | ||||||
|  |       "max_characters": 5000, | ||||||
|  |       "max_media_attachments": 6, | ||||||
|  |       "characters_reserved_per_url": 25 | ||||||
|  |     }, | ||||||
|  |     "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 | ||||||
|  |     }, | ||||||
|  |     "emojis": { | ||||||
|  |       "emoji_size_limit": 51200 | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   "urls": { | ||||||
|  |     "streaming_api": "wss://localhost:8080" | ||||||
|  |   }, | ||||||
|  |   "stats": { | ||||||
|  |     "domain_count": 2, | ||||||
|  |     "status_count": 16, | ||||||
|  |     "user_count": 4 | ||||||
|  |   }, | ||||||
|  |   "thumbnail": "http://localhost:8080/assets/logo.png", | ||||||
|  |   "contact_account": { | ||||||
|  |     "id": "01F8MH17FWEB39HZJ76B6VXSKF", | ||||||
|  |     "username": "admin", | ||||||
|  |     "acct": "admin", | ||||||
|  |     "display_name": "", | ||||||
|  |     "locked": false, | ||||||
|  |     "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": "admin" | ||||||
|  |   }, | ||||||
|  |   "max_toot_chars": 5000 | ||||||
|  | }`, dst.String()) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func TestInstancePatchTestSuite(t *testing.T) { | func TestInstancePatchTestSuite(t *testing.T) { | ||||||
|  |  | ||||||
|  | @ -221,8 +221,8 @@ func (p *processor) InstancePatch(ctx context.Context, form *apimodel.InstanceSe | ||||||
| 
 | 
 | ||||||
| 	var updateInstanceAccount bool | 	var updateInstanceAccount bool | ||||||
| 
 | 
 | ||||||
| 	// process instance avatar if provided |  | ||||||
| 	if form.Avatar != nil && form.Avatar.Size != 0 { | 	if form.Avatar != nil && form.Avatar.Size != 0 { | ||||||
|  | 		// process instance avatar image + description | ||||||
| 		avatarInfo, err := p.accountProcessor.UpdateAvatar(ctx, form.Avatar, form.AvatarDescription, ia.ID) | 		avatarInfo, err := p.accountProcessor.UpdateAvatar(ctx, form.Avatar, form.AvatarDescription, ia.ID) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, gtserror.NewErrorBadRequest(err, "error processing avatar") | 			return nil, gtserror.NewErrorBadRequest(err, "error processing avatar") | ||||||
|  | @ -230,10 +230,16 @@ func (p *processor) InstancePatch(ctx context.Context, form *apimodel.InstanceSe | ||||||
| 		ia.AvatarMediaAttachmentID = avatarInfo.ID | 		ia.AvatarMediaAttachmentID = avatarInfo.ID | ||||||
| 		ia.AvatarMediaAttachment = avatarInfo | 		ia.AvatarMediaAttachment = avatarInfo | ||||||
| 		updateInstanceAccount = true | 		updateInstanceAccount = true | ||||||
|  | 	} else if form.AvatarDescription != nil && ia.AvatarMediaAttachment != nil { | ||||||
|  | 		// process just the description for the existing avatar | ||||||
|  | 		ia.AvatarMediaAttachment.Description = *form.AvatarDescription | ||||||
|  | 		if err := p.db.UpdateByID(ctx, ia.AvatarMediaAttachment, ia.AvatarMediaAttachmentID, "description"); err != nil { | ||||||
|  | 			return nil, gtserror.NewErrorInternalError(fmt.Errorf("db error updating instance avatar description: %s", err)) | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// process instance header if provided |  | ||||||
| 	if form.Header != nil && form.Header.Size != 0 { | 	if form.Header != nil && form.Header.Size != 0 { | ||||||
|  | 		// process instance header image | ||||||
| 		headerInfo, err := p.accountProcessor.UpdateHeader(ctx, form.Header, nil, ia.ID) | 		headerInfo, err := p.accountProcessor.UpdateHeader(ctx, form.Header, nil, ia.ID) | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return nil, gtserror.NewErrorBadRequest(err, "error processing header") | 			return nil, gtserror.NewErrorBadRequest(err, "error processing header") | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue