gtsocial-umbx

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

emojicreate_test.go (9487B)


      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 admin_test
     19 
     20 import (
     21 	"context"
     22 	"encoding/json"
     23 	"io/ioutil"
     24 	"net/http"
     25 	"net/http/httptest"
     26 	"testing"
     27 
     28 	"github.com/stretchr/testify/suite"
     29 	"github.com/superseriousbusiness/gotosocial/internal/api/client/admin"
     30 	apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model"
     31 	"github.com/superseriousbusiness/gotosocial/testrig"
     32 )
     33 
     34 type EmojiCreateTestSuite struct {
     35 	AdminStandardTestSuite
     36 }
     37 
     38 func (suite *EmojiCreateTestSuite) TestEmojiCreateNewCategory() {
     39 	// set up the request
     40 	requestBody, w, err := testrig.CreateMultipartFormData(
     41 		"image", "../../../../testrig/media/rainbow-original.png",
     42 		map[string]string{
     43 			"shortcode": "new_emoji",
     44 			"category":  "Test Emojis", // this category doesn't exist yet
     45 		})
     46 	if err != nil {
     47 		panic(err)
     48 	}
     49 	bodyBytes := requestBody.Bytes()
     50 	recorder := httptest.NewRecorder()
     51 	ctx := suite.newContext(recorder, http.MethodPost, bodyBytes, admin.EmojiPath, w.FormDataContentType())
     52 
     53 	// call the handler
     54 	suite.adminModule.EmojiCreatePOSTHandler(ctx)
     55 
     56 	// 1. we should have OK because our request was valid
     57 	suite.Equal(http.StatusOK, recorder.Code)
     58 
     59 	// 2. we should have no error message in the result body
     60 	result := recorder.Result()
     61 	defer result.Body.Close()
     62 
     63 	// check the response
     64 	b, err := ioutil.ReadAll(result.Body)
     65 	suite.NoError(err)
     66 	suite.NotEmpty(b)
     67 
     68 	// response should be an api model emoji
     69 	apiEmoji := &apimodel.Emoji{}
     70 	err = json.Unmarshal(b, apiEmoji)
     71 	suite.NoError(err)
     72 
     73 	// appropriate fields should be set
     74 	suite.Equal("new_emoji", apiEmoji.Shortcode)
     75 	suite.NotEmpty(apiEmoji.URL)
     76 	suite.NotEmpty(apiEmoji.StaticURL)
     77 	suite.True(apiEmoji.VisibleInPicker)
     78 
     79 	// emoji should be in the db
     80 	dbEmoji, err := suite.db.GetEmojiByShortcodeDomain(context.Background(), apiEmoji.Shortcode, "")
     81 	suite.NoError(err)
     82 
     83 	// check fields on the emoji
     84 	suite.NotEmpty(dbEmoji.ID)
     85 	suite.Equal("new_emoji", dbEmoji.Shortcode)
     86 	suite.Empty(dbEmoji.Domain)
     87 	suite.Empty(dbEmoji.ImageRemoteURL)
     88 	suite.Empty(dbEmoji.ImageStaticRemoteURL)
     89 	suite.Equal(apiEmoji.URL, dbEmoji.ImageURL)
     90 	suite.Equal(apiEmoji.StaticURL, dbEmoji.ImageStaticURL)
     91 	suite.NotEmpty(dbEmoji.ImagePath)
     92 	suite.NotEmpty(dbEmoji.ImageStaticPath)
     93 	suite.Equal("image/png", dbEmoji.ImageContentType)
     94 	suite.Equal("image/png", dbEmoji.ImageStaticContentType)
     95 	suite.Equal(36702, dbEmoji.ImageFileSize)
     96 	suite.Equal(10413, dbEmoji.ImageStaticFileSize)
     97 	suite.False(*dbEmoji.Disabled)
     98 	suite.NotEmpty(dbEmoji.URI)
     99 	suite.True(*dbEmoji.VisibleInPicker)
    100 	suite.NotEmpty(dbEmoji.CategoryID)
    101 
    102 	// emoji should be in storage
    103 	emojiBytes, err := suite.storage.Get(ctx, dbEmoji.ImagePath)
    104 	suite.NoError(err)
    105 	suite.Len(emojiBytes, dbEmoji.ImageFileSize)
    106 	emojiStaticBytes, err := suite.storage.Get(ctx, dbEmoji.ImageStaticPath)
    107 	suite.NoError(err)
    108 	suite.Len(emojiStaticBytes, dbEmoji.ImageStaticFileSize)
    109 }
    110 
    111 func (suite *EmojiCreateTestSuite) TestEmojiCreateExistingCategory() {
    112 	// set up the request
    113 	requestBody, w, err := testrig.CreateMultipartFormData(
    114 		"image", "../../../../testrig/media/rainbow-original.png",
    115 		map[string]string{
    116 			"shortcode": "new_emoji",
    117 			"category":  "cute stuff", // this category already exists
    118 		})
    119 	if err != nil {
    120 		panic(err)
    121 	}
    122 	bodyBytes := requestBody.Bytes()
    123 	recorder := httptest.NewRecorder()
    124 	ctx := suite.newContext(recorder, http.MethodPost, bodyBytes, admin.EmojiPath, w.FormDataContentType())
    125 
    126 	// call the handler
    127 	suite.adminModule.EmojiCreatePOSTHandler(ctx)
    128 
    129 	// 1. we should have OK because our request was valid
    130 	suite.Equal(http.StatusOK, recorder.Code)
    131 
    132 	// 2. we should have no error message in the result body
    133 	result := recorder.Result()
    134 	defer result.Body.Close()
    135 
    136 	// check the response
    137 	b, err := ioutil.ReadAll(result.Body)
    138 	suite.NoError(err)
    139 	suite.NotEmpty(b)
    140 
    141 	// response should be an api model emoji
    142 	apiEmoji := &apimodel.Emoji{}
    143 	err = json.Unmarshal(b, apiEmoji)
    144 	suite.NoError(err)
    145 
    146 	// appropriate fields should be set
    147 	suite.Equal("new_emoji", apiEmoji.Shortcode)
    148 	suite.NotEmpty(apiEmoji.URL)
    149 	suite.NotEmpty(apiEmoji.StaticURL)
    150 	suite.True(apiEmoji.VisibleInPicker)
    151 
    152 	// emoji should be in the db
    153 	dbEmoji, err := suite.db.GetEmojiByShortcodeDomain(context.Background(), apiEmoji.Shortcode, "")
    154 	suite.NoError(err)
    155 
    156 	// check fields on the emoji
    157 	suite.NotEmpty(dbEmoji.ID)
    158 	suite.Equal("new_emoji", dbEmoji.Shortcode)
    159 	suite.Empty(dbEmoji.Domain)
    160 	suite.Empty(dbEmoji.ImageRemoteURL)
    161 	suite.Empty(dbEmoji.ImageStaticRemoteURL)
    162 	suite.Equal(apiEmoji.URL, dbEmoji.ImageURL)
    163 	suite.Equal(apiEmoji.StaticURL, dbEmoji.ImageStaticURL)
    164 	suite.NotEmpty(dbEmoji.ImagePath)
    165 	suite.NotEmpty(dbEmoji.ImageStaticPath)
    166 	suite.Equal("image/png", dbEmoji.ImageContentType)
    167 	suite.Equal("image/png", dbEmoji.ImageStaticContentType)
    168 	suite.Equal(36702, dbEmoji.ImageFileSize)
    169 	suite.Equal(10413, dbEmoji.ImageStaticFileSize)
    170 	suite.False(*dbEmoji.Disabled)
    171 	suite.NotEmpty(dbEmoji.URI)
    172 	suite.True(*dbEmoji.VisibleInPicker)
    173 	suite.Equal(suite.testEmojiCategories["cute stuff"].ID, dbEmoji.CategoryID)
    174 
    175 	// emoji should be in storage
    176 	emojiBytes, err := suite.storage.Get(ctx, dbEmoji.ImagePath)
    177 	suite.NoError(err)
    178 	suite.Len(emojiBytes, dbEmoji.ImageFileSize)
    179 	emojiStaticBytes, err := suite.storage.Get(ctx, dbEmoji.ImageStaticPath)
    180 	suite.NoError(err)
    181 	suite.Len(emojiStaticBytes, dbEmoji.ImageStaticFileSize)
    182 }
    183 
    184 func (suite *EmojiCreateTestSuite) TestEmojiCreateNoCategory() {
    185 	// set up the request
    186 	requestBody, w, err := testrig.CreateMultipartFormData(
    187 		"image", "../../../../testrig/media/rainbow-original.png",
    188 		map[string]string{
    189 			"shortcode": "new_emoji",
    190 			"category":  "",
    191 		})
    192 	if err != nil {
    193 		panic(err)
    194 	}
    195 	bodyBytes := requestBody.Bytes()
    196 	recorder := httptest.NewRecorder()
    197 	ctx := suite.newContext(recorder, http.MethodPost, bodyBytes, admin.EmojiPath, w.FormDataContentType())
    198 
    199 	// call the handler
    200 	suite.adminModule.EmojiCreatePOSTHandler(ctx)
    201 
    202 	// 1. we should have OK because our request was valid
    203 	suite.Equal(http.StatusOK, recorder.Code)
    204 
    205 	// 2. we should have no error message in the result body
    206 	result := recorder.Result()
    207 	defer result.Body.Close()
    208 
    209 	// check the response
    210 	b, err := ioutil.ReadAll(result.Body)
    211 	suite.NoError(err)
    212 	suite.NotEmpty(b)
    213 
    214 	// response should be an api model emoji
    215 	apiEmoji := &apimodel.Emoji{}
    216 	err = json.Unmarshal(b, apiEmoji)
    217 	suite.NoError(err)
    218 
    219 	// appropriate fields should be set
    220 	suite.Equal("new_emoji", apiEmoji.Shortcode)
    221 	suite.NotEmpty(apiEmoji.URL)
    222 	suite.NotEmpty(apiEmoji.StaticURL)
    223 	suite.True(apiEmoji.VisibleInPicker)
    224 
    225 	// emoji should be in the db
    226 	dbEmoji, err := suite.db.GetEmojiByShortcodeDomain(context.Background(), apiEmoji.Shortcode, "")
    227 	suite.NoError(err)
    228 
    229 	// check fields on the emoji
    230 	suite.NotEmpty(dbEmoji.ID)
    231 	suite.Equal("new_emoji", dbEmoji.Shortcode)
    232 	suite.Empty(dbEmoji.Domain)
    233 	suite.Empty(dbEmoji.ImageRemoteURL)
    234 	suite.Empty(dbEmoji.ImageStaticRemoteURL)
    235 	suite.Equal(apiEmoji.URL, dbEmoji.ImageURL)
    236 	suite.Equal(apiEmoji.StaticURL, dbEmoji.ImageStaticURL)
    237 	suite.NotEmpty(dbEmoji.ImagePath)
    238 	suite.NotEmpty(dbEmoji.ImageStaticPath)
    239 	suite.Equal("image/png", dbEmoji.ImageContentType)
    240 	suite.Equal("image/png", dbEmoji.ImageStaticContentType)
    241 	suite.Equal(36702, dbEmoji.ImageFileSize)
    242 	suite.Equal(10413, dbEmoji.ImageStaticFileSize)
    243 	suite.False(*dbEmoji.Disabled)
    244 	suite.NotEmpty(dbEmoji.URI)
    245 	suite.True(*dbEmoji.VisibleInPicker)
    246 	suite.Empty(dbEmoji.CategoryID)
    247 
    248 	// emoji should be in storage
    249 	emojiBytes, err := suite.storage.Get(ctx, dbEmoji.ImagePath)
    250 	suite.NoError(err)
    251 	suite.Len(emojiBytes, dbEmoji.ImageFileSize)
    252 	emojiStaticBytes, err := suite.storage.Get(ctx, dbEmoji.ImageStaticPath)
    253 	suite.NoError(err)
    254 	suite.Len(emojiStaticBytes, dbEmoji.ImageStaticFileSize)
    255 }
    256 
    257 func (suite *EmojiCreateTestSuite) TestEmojiCreateAlreadyExists() {
    258 	// set up the request -- use a shortcode that already exists for an emoji in the database
    259 	requestBody, w, err := testrig.CreateMultipartFormData(
    260 		"image", "../../../../testrig/media/rainbow-original.png",
    261 		map[string]string{
    262 			"shortcode": "rainbow",
    263 		})
    264 	if err != nil {
    265 		panic(err)
    266 	}
    267 	bodyBytes := requestBody.Bytes()
    268 	recorder := httptest.NewRecorder()
    269 	ctx := suite.newContext(recorder, http.MethodPost, bodyBytes, admin.EmojiPath, w.FormDataContentType())
    270 
    271 	// call the handler
    272 	suite.adminModule.EmojiCreatePOSTHandler(ctx)
    273 
    274 	suite.Equal(http.StatusConflict, recorder.Code)
    275 
    276 	result := recorder.Result()
    277 	defer result.Body.Close()
    278 
    279 	// check the response
    280 	b, err := ioutil.ReadAll(result.Body)
    281 	suite.NoError(err)
    282 	suite.NotEmpty(b)
    283 
    284 	suite.Equal(`{"error":"Conflict: emoji with shortcode rainbow already exists"}`, string(b))
    285 }
    286 
    287 func TestEmojiCreateTestSuite(t *testing.T) {
    288 	suite.Run(t, &EmojiCreateTestSuite{})
    289 }