[feature] Add /api/v1/admin/custom_emojis endpoint (#902)

* add admin emojis get path + model + docs

* stub admin emojis get processor function

* add id + disabled fields to admin emoji

* add emoji -> api admin emoji converter

* tidy up a bit

* add GetEmojis function

* finish up get emojis function

* order by shortcodedomain

* ASC

* tidy up + explain

* update to allow paging

* make admin emojis pageable

* fix mixed case paging

* normalize emoji queries a bit better

* test emoji get paging

* make limit optional

* fix incorrect path in media cleanup tests

* i have bad coder syndrome

* don't trimspace

* rename -> GetUseableEmojis

* wrap emoji query in subquery
avoid selecting more than we need

* fix a bit of sillyness teehee

* fix subquery postgres woes
This commit is contained in:
tobi 2022-10-12 15:01:42 +02:00 committed by GitHub
commit eb85ef7325
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
18 changed files with 887 additions and 9 deletions

View file

@ -67,6 +67,8 @@ type TypeConverter interface {
MentionToAPIMention(ctx context.Context, m *gtsmodel.Mention) (model.Mention, error)
// EmojiToAPIEmoji converts a gts model emoji into its api (frontend) representation for serialization on the API.
EmojiToAPIEmoji(ctx context.Context, e *gtsmodel.Emoji) (model.Emoji, error)
// EmojiToAdminAPIEmoji converts a gts model emoji into an API representation with extra admin information.
EmojiToAdminAPIEmoji(ctx context.Context, e *gtsmodel.Emoji) (*model.AdminEmoji, error)
// TagToAPITag converts a gts model tag into its api (frontend) representation for serialization on the API.
TagToAPITag(ctx context.Context, t *gtsmodel.Tag) (model.Tag, error)
// StatusToAPIStatus converts a gts model status into its api (frontend) representation for serialization on the API.

View file

@ -363,6 +363,24 @@ func (c *converter) EmojiToAPIEmoji(ctx context.Context, e *gtsmodel.Emoji) (mod
}, nil
}
func (c *converter) EmojiToAdminAPIEmoji(ctx context.Context, e *gtsmodel.Emoji) (*model.AdminEmoji, error) {
emoji, err := c.EmojiToAPIEmoji(ctx, e)
if err != nil {
return nil, err
}
return &model.AdminEmoji{
Emoji: emoji,
ID: e.ID,
Disabled: *e.Disabled,
Domain: e.Domain,
UpdatedAt: util.FormatISO8601(e.UpdatedAt),
TotalFileSize: e.ImageFileSize + e.ImageStaticFileSize,
ContentType: e.ImageContentType,
URI: e.URI,
}, nil
}
func (c *converter) TagToAPITag(ctx context.Context, t *gtsmodel.Tag) (model.Tag, error) {
return model.Tag{
Name: t.Name,

View file

@ -141,6 +141,36 @@ func (suite *InternalToFrontendTestSuite) TestInstanceToFrontendWithAdminAccount
suite.Equal(`{"uri":"https://example.org","title":"example instance","description":"a much longer description","short_description":"a little description","email":"someone@example.org","version":"software-from-hell 0.666","registrations":false,"approval_required":false,"invites_enabled":false,"thumbnail":"","contact_account":{"id":"01FHMQX3GAABWSM0S2VZEC2SWC","username":"some_user","acct":"some_user@example.org","display_name":"some user","locked":true,"bot":false,"created_at":"2020-08-10T12:13:28.000Z","note":"i'm a real son of a gun","url":"http://example.org/@some_user","avatar":"","avatar_static":"","header":"http://localhost:8080/assets/default_header.png","header_static":"http://localhost:8080/assets/default_header.png","followers_count":0,"following_count":0,"statuses_count":0,"last_status_at":"","emojis":[],"fields":[]},"max_toot_chars":0}`, string(b))
}
func (suite *InternalToFrontendTestSuite) TestEmojiToFrontend() {
emoji, err := suite.typeconverter.EmojiToAPIEmoji(context.Background(), suite.testEmojis["rainbow"])
suite.NoError(err)
b, err := json.Marshal(emoji)
suite.NoError(err)
suite.Equal(`{"shortcode":"rainbow","url":"http://localhost:8080/fileserver/01F8MH17FWEB39HZJ76B6VXSKF/emoji/original/01F8MH9H8E4VG3KDYJR9EGPXCQ.png","static_url":"http://localhost:8080/fileserver/01F8MH17FWEB39HZJ76B6VXSKF/emoji/static/01F8MH9H8E4VG3KDYJR9EGPXCQ.png","visible_in_picker":true}`, string(b))
}
func (suite *InternalToFrontendTestSuite) TestEmojiToFrontendAdmin1() {
emoji, err := suite.typeconverter.EmojiToAdminAPIEmoji(context.Background(), suite.testEmojis["rainbow"])
suite.NoError(err)
b, err := json.Marshal(emoji)
suite.NoError(err)
suite.Equal(`{"shortcode":"rainbow","url":"http://localhost:8080/fileserver/01F8MH17FWEB39HZJ76B6VXSKF/emoji/original/01F8MH9H8E4VG3KDYJR9EGPXCQ.png","static_url":"http://localhost:8080/fileserver/01F8MH17FWEB39HZJ76B6VXSKF/emoji/static/01F8MH9H8E4VG3KDYJR9EGPXCQ.png","visible_in_picker":true,"id":"01F8MH9H8E4VG3KDYJR9EGPXCQ","disabled":false,"updated_at":"2021-09-20T10:40:37.000Z","total_file_size":47115,"content_type":"image/png","uri":"http://localhost:8080/emoji/01F8MH9H8E4VG3KDYJR9EGPXCQ"}`, string(b))
}
func (suite *InternalToFrontendTestSuite) TestEmojiToFrontendAdmin2() {
emoji, err := suite.typeconverter.EmojiToAdminAPIEmoji(context.Background(), suite.testEmojis["yell"])
suite.NoError(err)
b, err := json.Marshal(emoji)
suite.NoError(err)
suite.Equal(`{"shortcode":"yell","url":"http://localhost:8080/fileserver/01GD5KR15NHTY8FZ01CD4D08XP/emoji/original/01GD5KP5CQEE1R3X43Y1EHS2CW.png","static_url":"http://localhost:8080/fileserver/01GD5KR15NHTY8FZ01CD4D08XP/emoji/static/01GD5KP5CQEE1R3X43Y1EHS2CW.png","visible_in_picker":false,"id":"01GD5KP5CQEE1R3X43Y1EHS2CW","disabled":false,"domain":"fossbros-anonymous.io","updated_at":"2020-03-18T12:12:00.000Z","total_file_size":21697,"content_type":"image/png","uri":"http://fossbros-anonymous.io/emoji/01GD5KP5CQEE1R3X43Y1EHS2CW"}`, string(b))
}
func TestInternalToFrontendTestSuite(t *testing.T) {
suite.Run(t, new(InternalToFrontendTestSuite))
}