[feature] Implement /api/v1/reports endpoints on client API (#1330)

* start adding report client api

* route + test reports get

* start report create endpoint

* you can create reports now babyy

* stub account report processor

* add single reportGet endpoint

* fix test

* add more filtering params to /api/v1/reports GET

* update swagger

* use marshalIndent in tests

* add + test missing Link info
This commit is contained in:
tobi 2023-01-23 13:14:21 +01:00 committed by GitHub
commit e9747247d5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 2184 additions and 20 deletions

View file

@ -87,6 +87,8 @@ type TypeConverter interface {
NotificationToAPINotification(ctx context.Context, n *gtsmodel.Notification) (*apimodel.Notification, error)
// DomainBlockToAPIDomainBlock converts a gts model domin block into a api domain block, for serving at /api/v1/admin/domain_blocks
DomainBlockToAPIDomainBlock(ctx context.Context, b *gtsmodel.DomainBlock, export bool) (*apimodel.DomainBlock, error)
// ReportToAPIReport converts a gts model report into an api model report, for serving at /api/v1/reports
ReportToAPIReport(ctx context.Context, r *gtsmodel.Report) (*apimodel.Report, error)
/*
INTERNAL (gts) MODEL TO FRONTEND (rss) MODEL

View file

@ -475,6 +475,7 @@ type TypeUtilsTestSuite struct {
testAttachments map[string]*gtsmodel.MediaAttachment
testPeople map[string]vocab.ActivityStreamsPerson
testEmojis map[string]*gtsmodel.Emoji
testReports map[string]*gtsmodel.Report
typeconverter typeutils.TypeConverter
}
@ -489,6 +490,7 @@ func (suite *TypeUtilsTestSuite) SetupSuite() {
suite.testAttachments = testrig.NewTestAttachments()
suite.testPeople = testrig.NewTestFediPeople()
suite.testEmojis = testrig.NewTestEmojis()
suite.testReports = testrig.NewTestReports()
suite.typeconverter = typeutils.NewConverter(suite.db)
}

View file

@ -807,6 +807,44 @@ func (c *converter) DomainBlockToAPIDomainBlock(ctx context.Context, b *gtsmodel
return domainBlock, nil
}
func (c *converter) ReportToAPIReport(ctx context.Context, r *gtsmodel.Report) (*apimodel.Report, error) {
report := &apimodel.Report{
ID: r.ID,
CreatedAt: util.FormatISO8601(r.CreatedAt),
ActionTaken: !r.ActionTakenAt.IsZero(),
Category: "other", // todo: only support default 'other' category right now
Comment: r.Comment,
Forwarded: *r.Forwarded,
StatusIDs: r.StatusIDs,
RuleIDs: []int{}, // todo: not supported yet
}
if !r.ActionTakenAt.IsZero() {
actionTakenAt := util.FormatISO8601(r.ActionTakenAt)
report.ActionTakenAt = &actionTakenAt
}
if actionComment := r.ActionTaken; actionComment != "" {
report.ActionComment = &actionComment
}
if r.TargetAccount == nil {
tAccount, err := c.db.GetAccountByID(ctx, r.TargetAccountID)
if err != nil {
return nil, fmt.Errorf("ReportToAPIReport: error getting target account with id %s from the db: %s", r.TargetAccountID, err)
}
r.TargetAccount = tAccount
}
apiAccount, err := c.AccountToAPIAccountPublic(ctx, r.TargetAccount)
if err != nil {
return nil, fmt.Errorf("ReportToAPIReport: error converting target account to api: %s", err)
}
report.TargetAccount = apiAccount
return report, nil
}
// convertAttachmentsToAPIAttachments will convert a slice of GTS model attachments to frontend API model attachments, falling back to IDs if no GTS models supplied.
func (c *converter) convertAttachmentsToAPIAttachments(ctx context.Context, attachments []*gtsmodel.MediaAttachment, attachmentIDs []string) ([]apimodel.Attachment, error) {
var errs gtserror.MultiError

View file

@ -604,6 +604,93 @@ func (suite *InternalToFrontendTestSuite) TestEmojiToFrontendAdmin2() {
}`, string(b))
}
func (suite *InternalToFrontendTestSuite) TestReportToFrontend1() {
report, err := suite.typeconverter.ReportToAPIReport(context.Background(), suite.testReports["local_account_2_report_remote_account_1"])
suite.NoError(err)
b, err := json.MarshalIndent(report, "", " ")
suite.NoError(err)
suite.Equal(`{
"id": "01GP3AWY4CRDVRNZKW0TEAMB5R",
"created_at": "2022-05-14T10:20:03.000Z",
"action_taken": false,
"action_taken_at": null,
"action_taken_comment": null,
"category": "other",
"comment": "dark souls sucks, please yeet this nerd",
"forwarded": true,
"status_ids": [
"01FVW7JHQFSFK166WWKR8CBA6M"
],
"rule_ids": [],
"target_account": {
"id": "01F8MH5ZK5VRH73AKHQM6Y9VNX",
"username": "foss_satan",
"acct": "foss_satan@fossbros-anonymous.io",
"display_name": "big gerald",
"locked": false,
"bot": false,
"created_at": "2021-09-26T10:52:36.000Z",
"note": "i post about like, i dunno, stuff, or whatever!!!!",
"url": "http://fossbros-anonymous.io/@foss_satan",
"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": 1,
"last_status_at": "2021-09-20T10:40:37.000Z",
"emojis": [],
"fields": []
}
}`, string(b))
}
func (suite *InternalToFrontendTestSuite) TestReportToFrontend2() {
report, err := suite.typeconverter.ReportToAPIReport(context.Background(), suite.testReports["remote_account_1_report_local_account_2"])
suite.NoError(err)
b, err := json.MarshalIndent(report, "", " ")
suite.NoError(err)
suite.Equal(`{
"id": "01GP3DFY9XQ1TJMZT5BGAZPXX7",
"created_at": "2022-05-15T14:20:12.000Z",
"action_taken": true,
"action_taken_at": "2022-05-15T15:01:56.000Z",
"action_taken_comment": "user was warned not to be a turtle anymore",
"category": "other",
"comment": "this is a turtle, not a person, therefore should not be a poster",
"forwarded": true,
"status_ids": [],
"rule_ids": [],
"target_account": {
"id": "01F8MH5NBDF2MV7CTC4Q5128HF",
"username": "1happyturtle",
"acct": "1happyturtle",
"display_name": "happy little turtle :3",
"locked": true,
"bot": false,
"created_at": "2022-06-04T13:12:00.000Z",
"note": "\u003cp\u003ei post about things that concern me\u003c/p\u003e",
"url": "http://localhost:8080/@1happyturtle",
"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": 7,
"last_status_at": "2021-10-20T10:40:37.000Z",
"emojis": [],
"fields": [],
"role": "user"
}
}`, string(b))
}
func TestInternalToFrontendTestSuite(t *testing.T) {
suite.Run(t, new(InternalToFrontendTestSuite))
}