mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 04:32:25 -05:00 
			
		
		
		
	[feature] Allow newly uploaded emojis to be placed in categories (#939)
* [feature] Add emoji categories GET Serialize emojis in appropriate categories; make it possible to get categories via the admin API * [feature] Create (or use existing) category for new emoji uploads * fix lint issue * update misleading line in swagger docs
This commit is contained in:
		
					parent
					
						
							
								8c20ccd9a8
							
						
					
				
			
			
				commit
				
					
						4cd00d546c
					
				
			
		
					 31 changed files with 916 additions and 52 deletions
				
			
		|  | @ -36,12 +36,159 @@ type EmojiCreateTestSuite struct { | |||
| 	AdminStandardTestSuite | ||||
| } | ||||
| 
 | ||||
| func (suite *EmojiCreateTestSuite) TestEmojiCreate() { | ||||
| func (suite *EmojiCreateTestSuite) TestEmojiCreateNewCategory() { | ||||
| 	// set up the request | ||||
| 	requestBody, w, err := testrig.CreateMultipartFormData( | ||||
| 		"image", "../../../../testrig/media/rainbow-original.png", | ||||
| 		map[string]string{ | ||||
| 			"shortcode": "new_emoji", | ||||
| 			"category":  "Test Emojis", // this category doesn't exist yet | ||||
| 		}) | ||||
| 	if err != nil { | ||||
| 		panic(err) | ||||
| 	} | ||||
| 	bodyBytes := requestBody.Bytes() | ||||
| 	recorder := httptest.NewRecorder() | ||||
| 	ctx := suite.newContext(recorder, http.MethodPost, bodyBytes, admin.EmojiPath, w.FormDataContentType()) | ||||
| 
 | ||||
| 	// call the handler | ||||
| 	suite.adminModule.EmojiCreatePOSTHandler(ctx) | ||||
| 
 | ||||
| 	// 1. we should have OK because our request was valid | ||||
| 	suite.Equal(http.StatusOK, recorder.Code) | ||||
| 
 | ||||
| 	// 2. we should have no error message in the result body | ||||
| 	result := recorder.Result() | ||||
| 	defer result.Body.Close() | ||||
| 
 | ||||
| 	// check the response | ||||
| 	b, err := ioutil.ReadAll(result.Body) | ||||
| 	suite.NoError(err) | ||||
| 	suite.NotEmpty(b) | ||||
| 
 | ||||
| 	// response should be an api model emoji | ||||
| 	apiEmoji := &apimodel.Emoji{} | ||||
| 	err = json.Unmarshal(b, apiEmoji) | ||||
| 	suite.NoError(err) | ||||
| 
 | ||||
| 	// appropriate fields should be set | ||||
| 	suite.Equal("new_emoji", apiEmoji.Shortcode) | ||||
| 	suite.NotEmpty(apiEmoji.URL) | ||||
| 	suite.NotEmpty(apiEmoji.StaticURL) | ||||
| 	suite.True(apiEmoji.VisibleInPicker) | ||||
| 
 | ||||
| 	// emoji should be in the db | ||||
| 	dbEmoji, err := suite.db.GetEmojiByShortcodeDomain(context.Background(), apiEmoji.Shortcode, "") | ||||
| 	suite.NoError(err) | ||||
| 
 | ||||
| 	// check fields on the emoji | ||||
| 	suite.NotEmpty(dbEmoji.ID) | ||||
| 	suite.Equal("new_emoji", dbEmoji.Shortcode) | ||||
| 	suite.Empty(dbEmoji.Domain) | ||||
| 	suite.Empty(dbEmoji.ImageRemoteURL) | ||||
| 	suite.Empty(dbEmoji.ImageStaticRemoteURL) | ||||
| 	suite.Equal(apiEmoji.URL, dbEmoji.ImageURL) | ||||
| 	suite.Equal(apiEmoji.StaticURL, dbEmoji.ImageStaticURL) | ||||
| 	suite.NotEmpty(dbEmoji.ImagePath) | ||||
| 	suite.NotEmpty(dbEmoji.ImageStaticPath) | ||||
| 	suite.Equal("image/png", dbEmoji.ImageContentType) | ||||
| 	suite.Equal("image/png", dbEmoji.ImageStaticContentType) | ||||
| 	suite.Equal(36702, dbEmoji.ImageFileSize) | ||||
| 	suite.Equal(10413, dbEmoji.ImageStaticFileSize) | ||||
| 	suite.False(*dbEmoji.Disabled) | ||||
| 	suite.NotEmpty(dbEmoji.URI) | ||||
| 	suite.True(*dbEmoji.VisibleInPicker) | ||||
| 	suite.NotEmpty(dbEmoji.CategoryID) | ||||
| 
 | ||||
| 	// emoji should be in storage | ||||
| 	emojiBytes, err := suite.storage.Get(ctx, dbEmoji.ImagePath) | ||||
| 	suite.NoError(err) | ||||
| 	suite.Len(emojiBytes, dbEmoji.ImageFileSize) | ||||
| 	emojiStaticBytes, err := suite.storage.Get(ctx, dbEmoji.ImageStaticPath) | ||||
| 	suite.NoError(err) | ||||
| 	suite.Len(emojiStaticBytes, dbEmoji.ImageStaticFileSize) | ||||
| } | ||||
| 
 | ||||
| func (suite *EmojiCreateTestSuite) TestEmojiCreateExistingCategory() { | ||||
| 	// set up the request | ||||
| 	requestBody, w, err := testrig.CreateMultipartFormData( | ||||
| 		"image", "../../../../testrig/media/rainbow-original.png", | ||||
| 		map[string]string{ | ||||
| 			"shortcode": "new_emoji", | ||||
| 			"category":  "cute stuff", // this category already exists | ||||
| 		}) | ||||
| 	if err != nil { | ||||
| 		panic(err) | ||||
| 	} | ||||
| 	bodyBytes := requestBody.Bytes() | ||||
| 	recorder := httptest.NewRecorder() | ||||
| 	ctx := suite.newContext(recorder, http.MethodPost, bodyBytes, admin.EmojiPath, w.FormDataContentType()) | ||||
| 
 | ||||
| 	// call the handler | ||||
| 	suite.adminModule.EmojiCreatePOSTHandler(ctx) | ||||
| 
 | ||||
| 	// 1. we should have OK because our request was valid | ||||
| 	suite.Equal(http.StatusOK, recorder.Code) | ||||
| 
 | ||||
| 	// 2. we should have no error message in the result body | ||||
| 	result := recorder.Result() | ||||
| 	defer result.Body.Close() | ||||
| 
 | ||||
| 	// check the response | ||||
| 	b, err := ioutil.ReadAll(result.Body) | ||||
| 	suite.NoError(err) | ||||
| 	suite.NotEmpty(b) | ||||
| 
 | ||||
| 	// response should be an api model emoji | ||||
| 	apiEmoji := &apimodel.Emoji{} | ||||
| 	err = json.Unmarshal(b, apiEmoji) | ||||
| 	suite.NoError(err) | ||||
| 
 | ||||
| 	// appropriate fields should be set | ||||
| 	suite.Equal("new_emoji", apiEmoji.Shortcode) | ||||
| 	suite.NotEmpty(apiEmoji.URL) | ||||
| 	suite.NotEmpty(apiEmoji.StaticURL) | ||||
| 	suite.True(apiEmoji.VisibleInPicker) | ||||
| 
 | ||||
| 	// emoji should be in the db | ||||
| 	dbEmoji, err := suite.db.GetEmojiByShortcodeDomain(context.Background(), apiEmoji.Shortcode, "") | ||||
| 	suite.NoError(err) | ||||
| 
 | ||||
| 	// check fields on the emoji | ||||
| 	suite.NotEmpty(dbEmoji.ID) | ||||
| 	suite.Equal("new_emoji", dbEmoji.Shortcode) | ||||
| 	suite.Empty(dbEmoji.Domain) | ||||
| 	suite.Empty(dbEmoji.ImageRemoteURL) | ||||
| 	suite.Empty(dbEmoji.ImageStaticRemoteURL) | ||||
| 	suite.Equal(apiEmoji.URL, dbEmoji.ImageURL) | ||||
| 	suite.Equal(apiEmoji.StaticURL, dbEmoji.ImageStaticURL) | ||||
| 	suite.NotEmpty(dbEmoji.ImagePath) | ||||
| 	suite.NotEmpty(dbEmoji.ImageStaticPath) | ||||
| 	suite.Equal("image/png", dbEmoji.ImageContentType) | ||||
| 	suite.Equal("image/png", dbEmoji.ImageStaticContentType) | ||||
| 	suite.Equal(36702, dbEmoji.ImageFileSize) | ||||
| 	suite.Equal(10413, dbEmoji.ImageStaticFileSize) | ||||
| 	suite.False(*dbEmoji.Disabled) | ||||
| 	suite.NotEmpty(dbEmoji.URI) | ||||
| 	suite.True(*dbEmoji.VisibleInPicker) | ||||
| 	suite.Equal(suite.testEmojiCategories["cute stuff"].ID, dbEmoji.CategoryID) | ||||
| 
 | ||||
| 	// emoji should be in storage | ||||
| 	emojiBytes, err := suite.storage.Get(ctx, dbEmoji.ImagePath) | ||||
| 	suite.NoError(err) | ||||
| 	suite.Len(emojiBytes, dbEmoji.ImageFileSize) | ||||
| 	emojiStaticBytes, err := suite.storage.Get(ctx, dbEmoji.ImageStaticPath) | ||||
| 	suite.NoError(err) | ||||
| 	suite.Len(emojiStaticBytes, dbEmoji.ImageStaticFileSize) | ||||
| } | ||||
| 
 | ||||
| func (suite *EmojiCreateTestSuite) TestEmojiCreateNoCategory() { | ||||
| 	// set up the request | ||||
| 	requestBody, w, err := testrig.CreateMultipartFormData( | ||||
| 		"image", "../../../../testrig/media/rainbow-original.png", | ||||
| 		map[string]string{ | ||||
| 			"shortcode": "new_emoji", | ||||
| 			"category":  "", | ||||
| 		}) | ||||
| 	if err != nil { | ||||
| 		panic(err) | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue