diff options
author | 2023-05-09 12:16:10 +0200 | |
---|---|---|
committer | 2023-05-09 11:16:10 +0100 | |
commit | 0e29f1f5bb68a48d9b837d7f4e0a16370734955b (patch) | |
tree | f08d203ec8ca8aeea728e5251b1dc3956524b4f4 /internal/typeutils | |
parent | [chore/performance] Make sender multiplier configurable (#1750) (diff) | |
download | gotosocial-0e29f1f5bb68a48d9b837d7f4e0a16370734955b.tar.xz |
[feature] Enable federation in/out of profile PropertyValue fields (#1722)
Co-authored-by: kim <grufwub@gmail.com>
Co-authored-by: kim <89579420+NyaaaWhatsUpDoc@users.noreply.github.com>
Diffstat (limited to 'internal/typeutils')
-rw-r--r-- | internal/typeutils/astointernal.go | 3 | ||||
-rw-r--r-- | internal/typeutils/internaltoas.go | 20 | ||||
-rw-r--r-- | internal/typeutils/internaltoas_test.go | 139 | ||||
-rw-r--r-- | internal/typeutils/internaltofrontend.go | 37 | ||||
-rw-r--r-- | internal/typeutils/internaltofrontend_test.go | 39 | ||||
-rw-r--r-- | internal/typeutils/wrap_test.go | 6 |
6 files changed, 202 insertions, 42 deletions
diff --git a/internal/typeutils/astointernal.go b/internal/typeutils/astointernal.go index f94ac128a..7c0b60ad5 100644 --- a/internal/typeutils/astointernal.go +++ b/internal/typeutils/astointernal.go @@ -86,7 +86,8 @@ func (c *converter) ASRepresentationToAccount(ctx context.Context, accountable a acct.Emojis = emojis } - // TODO: fields aka attachment array + // fields aka attachment array + acct.Fields = ap.ExtractFields(accountable) // note aka summary acct.Note = ap.ExtractSummary(accountable) diff --git a/internal/typeutils/internaltoas.go b/internal/typeutils/internaltoas.go index ceff1cb4d..3c1615cfb 100644 --- a/internal/typeutils/internaltoas.go +++ b/internal/typeutils/internaltoas.go @@ -240,7 +240,25 @@ func (c *converter) AccountToAS(ctx context.Context, a *gtsmodel.Account) (vocab // attachment // Used for profile fields. - // TODO: The PropertyValue type has to be added: https://schema.org/PropertyValue + if len(a.Fields) != 0 { + attachmentProp := streams.NewActivityStreamsAttachmentProperty() + + for _, field := range a.Fields { + propertyValue := streams.NewSchemaPropertyValue() + + nameProp := streams.NewActivityStreamsNameProperty() + nameProp.AppendXMLSchemaString(field.Name) + propertyValue.SetActivityStreamsName(nameProp) + + valueProp := streams.NewSchemaValueProperty() + valueProp.Set(field.Value) + propertyValue.SetSchemaValue(valueProp) + + attachmentProp.AppendSchemaPropertyValue(propertyValue) + } + + person.SetActivityStreamsAttachment(attachmentProp) + } // endpoints // NOT IMPLEMENTED -- this is for shared inbox which we don't use diff --git a/internal/typeutils/internaltoas_test.go b/internal/typeutils/internaltoas_test.go index 486866160..60c59326c 100644 --- a/internal/typeutils/internaltoas_test.go +++ b/internal/typeutils/internaltoas_test.go @@ -21,11 +21,11 @@ import ( "context" "encoding/json" "errors" + "fmt" "strings" "testing" "github.com/stretchr/testify/suite" - "github.com/superseriousbusiness/activity/streams" "github.com/superseriousbusiness/gotosocial/internal/ap" "github.com/superseriousbusiness/gotosocial/internal/db" "github.com/superseriousbusiness/gotosocial/internal/gtsmodel" @@ -43,7 +43,7 @@ func (suite *InternalToASTestSuite) TestAccountToAS() { asPerson, err := suite.typeconverter.AccountToAS(context.Background(), testAccount) suite.NoError(err) - ser, err := streams.Serialize(asPerson) + ser, err := ap.Serialize(asPerson) suite.NoError(err) bytes, err := json.MarshalIndent(ser, "", " ") @@ -85,6 +85,107 @@ func (suite *InternalToASTestSuite) TestAccountToAS() { }`, trimmed) } +func (suite *InternalToASTestSuite) TestAccountToASWithFields() { + testAccount := >smodel.Account{} + *testAccount = *suite.testAccounts["local_account_2"] + + asPerson, err := suite.typeconverter.AccountToAS(context.Background(), testAccount) + suite.NoError(err) + + ser, err := ap.Serialize(asPerson) + suite.NoError(err) + + bytes, err := json.MarshalIndent(ser, "", " ") + suite.NoError(err) + + // trim off everything up to 'attachment'; + // this is necessary because the order of multiple 'context' entries is not determinate + trimmed := strings.Split(string(bytes), "\"attachment\"")[1] + + fmt.Printf("\n\n\n%s\n\n\n", string(bytes)) + + suite.Equal(`: [ + { + "name": "should you follow me?", + "type": "PropertyValue", + "value": "maybe!" + }, + { + "name": "age", + "type": "PropertyValue", + "value": "120" + } + ], + "discoverable": false, + "featured": "http://localhost:8080/users/1happyturtle/collections/featured", + "followers": "http://localhost:8080/users/1happyturtle/followers", + "following": "http://localhost:8080/users/1happyturtle/following", + "id": "http://localhost:8080/users/1happyturtle", + "inbox": "http://localhost:8080/users/1happyturtle/inbox", + "manuallyApprovesFollowers": true, + "name": "happy little turtle :3", + "outbox": "http://localhost:8080/users/1happyturtle/outbox", + "preferredUsername": "1happyturtle", + "publicKey": { + "id": "http://localhost:8080/users/1happyturtle#main-key", + "owner": "http://localhost:8080/users/1happyturtle", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtTc6Jpg6LrRPhVQG4KLz\n2+YqEUUtZPd4YR+TKXuCnwEG9ZNGhgP046xa9h3EWzrZXaOhXvkUQgJuRqPrAcfN\nvc8jBHV2xrUeD8pu/MWKEabAsA/tgCv3nUC47HQ3/c12aHfYoPz3ufWsGGnrkhci\nv8PaveJ3LohO5vjCn1yZ00v6osMJMViEZvZQaazyE9A8FwraIexXabDpoy7tkHRg\nA1fvSkg4FeSG1XMcIz2NN7xyUuFACD+XkuOk7UqzRd4cjPUPLxiDwIsTlcgGOd3E\nUFMWVlPxSGjY2hIKa3lEHytaYK9IMYdSuyCsJshd3/yYC9LqxZY2KdlKJ80VOVyh\nyQIDAQAB\n-----END PUBLIC KEY-----\n" + }, + "summary": "\u003cp\u003ei post about things that concern me\u003c/p\u003e", + "tag": [], + "type": "Person", + "url": "http://localhost:8080/@1happyturtle" +}`, trimmed) +} + +func (suite *InternalToASTestSuite) TestAccountToASWithOneField() { + testAccount := >smodel.Account{} + *testAccount = *suite.testAccounts["local_account_2"] + testAccount.Fields = testAccount.Fields[0:1] // Take only one field. + + asPerson, err := suite.typeconverter.AccountToAS(context.Background(), testAccount) + suite.NoError(err) + + ser, err := ap.Serialize(asPerson) + suite.NoError(err) + + bytes, err := json.MarshalIndent(ser, "", " ") + suite.NoError(err) + + // trim off everything up to 'attachment'; + // this is necessary because the order of multiple 'context' entries is not determinate + trimmed := strings.Split(string(bytes), "\"attachment\"")[1] + + // Despite only one field being set, attachments should still be a slice/array. + suite.Equal(`: [ + { + "name": "should you follow me?", + "type": "PropertyValue", + "value": "maybe!" + } + ], + "discoverable": false, + "featured": "http://localhost:8080/users/1happyturtle/collections/featured", + "followers": "http://localhost:8080/users/1happyturtle/followers", + "following": "http://localhost:8080/users/1happyturtle/following", + "id": "http://localhost:8080/users/1happyturtle", + "inbox": "http://localhost:8080/users/1happyturtle/inbox", + "manuallyApprovesFollowers": true, + "name": "happy little turtle :3", + "outbox": "http://localhost:8080/users/1happyturtle/outbox", + "preferredUsername": "1happyturtle", + "publicKey": { + "id": "http://localhost:8080/users/1happyturtle#main-key", + "owner": "http://localhost:8080/users/1happyturtle", + "publicKeyPem": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtTc6Jpg6LrRPhVQG4KLz\n2+YqEUUtZPd4YR+TKXuCnwEG9ZNGhgP046xa9h3EWzrZXaOhXvkUQgJuRqPrAcfN\nvc8jBHV2xrUeD8pu/MWKEabAsA/tgCv3nUC47HQ3/c12aHfYoPz3ufWsGGnrkhci\nv8PaveJ3LohO5vjCn1yZ00v6osMJMViEZvZQaazyE9A8FwraIexXabDpoy7tkHRg\nA1fvSkg4FeSG1XMcIz2NN7xyUuFACD+XkuOk7UqzRd4cjPUPLxiDwIsTlcgGOd3E\nUFMWVlPxSGjY2hIKa3lEHytaYK9IMYdSuyCsJshd3/yYC9LqxZY2KdlKJ80VOVyh\nyQIDAQAB\n-----END PUBLIC KEY-----\n" + }, + "summary": "\u003cp\u003ei post about things that concern me\u003c/p\u003e", + "tag": [], + "type": "Person", + "url": "http://localhost:8080/@1happyturtle" +}`, trimmed) +} + func (suite *InternalToASTestSuite) TestAccountToASWithEmoji() { testAccount := >smodel.Account{} *testAccount = *suite.testAccounts["local_account_1"] // take zork for this test @@ -93,7 +194,7 @@ func (suite *InternalToASTestSuite) TestAccountToASWithEmoji() { asPerson, err := suite.typeconverter.AccountToAS(context.Background(), testAccount) suite.NoError(err) - ser, err := streams.Serialize(asPerson) + ser, err := ap.Serialize(asPerson) suite.NoError(err) bytes, err := json.MarshalIndent(ser, "", " ") @@ -154,7 +255,7 @@ func (suite *InternalToASTestSuite) TestAccountToASWithSharedInbox() { asPerson, err := suite.typeconverter.AccountToAS(context.Background(), testAccount) suite.NoError(err) - ser, err := streams.Serialize(asPerson) + ser, err := ap.Serialize(asPerson) suite.NoError(err) bytes, err := json.MarshalIndent(ser, "", " ") @@ -206,7 +307,7 @@ func (suite *InternalToASTestSuite) TestOutboxToASCollection() { collection, err := suite.typeconverter.OutboxToASCollection(ctx, testAccount.OutboxURI) suite.NoError(err) - ser, err := streams.Serialize(collection) + ser, err := ap.Serialize(collection) suite.NoError(err) bytes, err := json.MarshalIndent(ser, "", " ") @@ -227,7 +328,7 @@ func (suite *InternalToASTestSuite) TestStatusToAS() { asStatus, err := suite.typeconverter.StatusToAS(ctx, testStatus) suite.NoError(err) - ser, err := streams.Serialize(asStatus) + ser, err := ap.Serialize(asStatus) suite.NoError(err) bytes, err := json.MarshalIndent(ser, "", " ") @@ -268,7 +369,7 @@ func (suite *InternalToASTestSuite) TestStatusWithTagsToASWithIDs() { asStatus, err := suite.typeconverter.StatusToAS(ctx, testStatus) suite.NoError(err) - ser, err := streams.Serialize(asStatus) + ser, err := ap.Serialize(asStatus) suite.NoError(err) bytes, err := json.MarshalIndent(ser, "", " ") @@ -328,7 +429,7 @@ func (suite *InternalToASTestSuite) TestStatusWithTagsToASFromDB() { asStatus, err := suite.typeconverter.StatusToAS(ctx, testStatus) suite.NoError(err) - ser, err := streams.Serialize(asStatus) + ser, err := ap.Serialize(asStatus) suite.NoError(err) bytes, err := json.MarshalIndent(ser, "", " ") @@ -389,7 +490,7 @@ func (suite *InternalToASTestSuite) TestStatusToASWithMentions() { asStatus, err := suite.typeconverter.StatusToAS(ctx, testStatus) suite.NoError(err) - ser, err := streams.Serialize(asStatus) + ser, err := ap.Serialize(asStatus) suite.NoError(err) bytes, err := json.MarshalIndent(ser, "", " ") @@ -437,7 +538,7 @@ func (suite *InternalToASTestSuite) TestStatusToASDeletePublicReply() { asDelete, err := suite.typeconverter.StatusToASDelete(ctx, testStatus) suite.NoError(err) - ser, err := streams.Serialize(asDelete) + ser, err := ap.Serialize(asDelete) suite.NoError(err) bytes, err := json.MarshalIndent(ser, "", " ") @@ -475,7 +576,7 @@ func (suite *InternalToASTestSuite) TestStatusToASDeletePublicReplyOriginalDelet asDelete, err := suite.typeconverter.StatusToASDelete(ctx, testStatus) suite.NoError(err) - ser, err := streams.Serialize(asDelete) + ser, err := ap.Serialize(asDelete) suite.NoError(err) bytes, err := json.MarshalIndent(ser, "", " ") @@ -501,7 +602,7 @@ func (suite *InternalToASTestSuite) TestStatusToASDeletePublic() { asDelete, err := suite.typeconverter.StatusToASDelete(ctx, testStatus) suite.NoError(err) - ser, err := streams.Serialize(asDelete) + ser, err := ap.Serialize(asDelete) suite.NoError(err) bytes, err := json.MarshalIndent(ser, "", " ") @@ -524,7 +625,7 @@ func (suite *InternalToASTestSuite) TestStatusToASDeleteDirectMessage() { asDelete, err := suite.typeconverter.StatusToASDelete(ctx, testStatus) suite.NoError(err) - ser, err := streams.Serialize(asDelete) + ser, err := ap.Serialize(asDelete) suite.NoError(err) bytes, err := json.MarshalIndent(ser, "", " ") @@ -551,7 +652,7 @@ func (suite *InternalToASTestSuite) TestStatusesToASOutboxPage() { page, err := suite.typeconverter.StatusesToASOutboxPage(ctx, testAccount.OutboxURI, "", "", statuses) suite.NoError(err) - ser, err := streams.Serialize(page) + ser, err := ap.Serialize(page) suite.NoError(err) bytes, err := json.MarshalIndent(ser, "", " ") @@ -604,7 +705,7 @@ func (suite *InternalToASTestSuite) TestSelfBoostFollowersOnlyToAS() { asBoost, err := suite.typeconverter.BoostToAS(ctx, boostWrapperStatus, testAccount, testAccount) suite.NoError(err) - ser, err := streams.Serialize(asBoost) + ser, err := ap.Serialize(asBoost) suite.NoError(err) bytes, err := json.MarshalIndent(ser, "", " ") @@ -637,7 +738,7 @@ func (suite *InternalToASTestSuite) TestReportToAS() { flag, err := suite.typeconverter.ReportToASFlag(ctx, testReport) suite.NoError(err) - ser, err := streams.Serialize(flag) + ser, err := ap.Serialize(flag) suite.NoError(err) bytes, err := json.MarshalIndent(ser, "", " ") @@ -670,7 +771,7 @@ func (suite *InternalToASTestSuite) TestPinnedStatusesToASSomeItems() { suite.FailNow(err.Error()) } - ser, err := ap.SerializeOrderedCollection(collection) + ser, err := ap.Serialize(collection) suite.NoError(err) bytes, err := json.MarshalIndent(ser, "", " ") @@ -702,7 +803,7 @@ func (suite *InternalToASTestSuite) TestPinnedStatusesToASNoItems() { suite.FailNow(err.Error()) } - ser, err := ap.SerializeOrderedCollection(collection) + ser, err := ap.Serialize(collection) suite.NoError(err) bytes, err := json.MarshalIndent(ser, "", " ") @@ -731,7 +832,7 @@ func (suite *InternalToASTestSuite) TestPinnedStatusesToASOneItem() { suite.FailNow(err.Error()) } - ser, err := ap.SerializeOrderedCollection(collection) + ser, err := ap.Serialize(collection) suite.NoError(err) bytes, err := json.MarshalIndent(ser, "", " ") diff --git a/internal/typeutils/internaltofrontend.go b/internal/typeutils/internaltofrontend.go index 88646c311..1e5fb024f 100644 --- a/internal/typeutils/internaltofrontend.go +++ b/internal/typeutils/internaltofrontend.go @@ -77,7 +77,7 @@ func (c *converter) AccountToAPIAccountSensitive(ctx context.Context, a *gtsmode Language: a.Language, StatusContentType: statusContentType, Note: a.NoteRaw, - Fields: apiAccount.Fields, + Fields: c.fieldsToAPIFields(a.FieldsRaw), FollowRequestsCount: frc, } @@ -131,7 +131,6 @@ func (c *converter) AccountToAPIAccountPublic(ctx context.Context, a *gtsmodel.A aviURLStatic string headerURL string headerURLStatic string - fields = make([]apimodel.Field, len(a.Fields)) ) if a.AvatarMediaAttachment != nil { @@ -144,19 +143,8 @@ func (c *converter) AccountToAPIAccountPublic(ctx context.Context, a *gtsmodel.A headerURLStatic = a.HeaderMediaAttachment.Thumbnail.URL } - // GTS model fields -> frontend. - for i, field := range a.Fields { - mField := apimodel.Field{ - Name: field.Name, - Value: field.Value, - } - - if !field.VerifiedAt.IsZero() { - mField.VerifiedAt = util.FormatISO8601(field.VerifiedAt) - } - - fields[i] = mField - } + // convert account gts model fields to front api model fields + fields := c.fieldsToAPIFields(a.Fields) // GTS model emojis -> frontend. apiEmojis, err := c.convertEmojisToAPIEmojis(ctx, a.Emojis, a.EmojiIDs) @@ -239,6 +227,25 @@ func (c *converter) AccountToAPIAccountPublic(ctx context.Context, a *gtsmodel.A return accountFrontend, nil } +func (c *converter) fieldsToAPIFields(f []*gtsmodel.Field) []apimodel.Field { + fields := make([]apimodel.Field, len(f)) + + for i, field := range f { + mField := apimodel.Field{ + Name: field.Name, + Value: field.Value, + } + + if !field.VerifiedAt.IsZero() { + mField.VerifiedAt = func() *string { s := util.FormatISO8601(field.VerifiedAt); return &s }() + } + + fields[i] = mField + } + + return fields +} + func (c *converter) AccountToAPIAccountBlocked(ctx context.Context, a *gtsmodel.Account) (*apimodel.Account, error) { var ( acct string diff --git a/internal/typeutils/internaltofrontend_test.go b/internal/typeutils/internaltofrontend_test.go index c8ab5a8e1..558d3acea 100644 --- a/internal/typeutils/internaltofrontend_test.go +++ b/internal/typeutils/internaltofrontend_test.go @@ -873,7 +873,18 @@ func (suite *InternalToFrontendTestSuite) TestReportToFrontend2() { "statuses_count": 7, "last_status_at": "2021-10-20T10:40:37.000Z", "emojis": [], - "fields": [], + "fields": [ + { + "name": "should you follow me?", + "value": "maybe!", + "verified_at": null + }, + { + "name": "age", + "value": "120", + "verified_at": null + } + ], "role": { "name": "user" } @@ -977,7 +988,18 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontend1() { "statuses_count": 7, "last_status_at": "2021-10-20T10:40:37.000Z", "emojis": [], - "fields": [], + "fields": [ + { + "name": "should you follow me?", + "value": "maybe!", + "verified_at": null + }, + { + "name": "age", + "value": "120", + "verified_at": null + } + ], "role": { "name": "user" } @@ -1137,7 +1159,18 @@ func (suite *InternalToFrontendTestSuite) TestAdminReportToFrontend2() { "statuses_count": 7, "last_status_at": "2021-10-20T10:40:37.000Z", "emojis": [], - "fields": [], + "fields": [ + { + "name": "should you follow me?", + "value": "maybe!", + "verified_at": null + }, + { + "name": "age", + "value": "120", + "verified_at": null + } + ], "role": { "name": "user" } diff --git a/internal/typeutils/wrap_test.go b/internal/typeutils/wrap_test.go index 2978a0251..46d28f5c4 100644 --- a/internal/typeutils/wrap_test.go +++ b/internal/typeutils/wrap_test.go @@ -23,7 +23,7 @@ import ( "testing" "github.com/stretchr/testify/suite" - "github.com/superseriousbusiness/activity/streams" + "github.com/superseriousbusiness/gotosocial/internal/ap" ) type WrapTestSuite struct { @@ -40,7 +40,7 @@ func (suite *WrapTestSuite) TestWrapNoteInCreateIRIOnly() { suite.NoError(err) suite.NotNil(create) - createI, err := streams.Serialize(create) + createI, err := ap.Serialize(create) suite.NoError(err) bytes, err := json.MarshalIndent(createI, "", " ") @@ -68,7 +68,7 @@ func (suite *WrapTestSuite) TestWrapNoteInCreate() { suite.NoError(err) suite.NotNil(create) - createI, err := streams.Serialize(create) + createI, err := ap.Serialize(create) suite.NoError(err) bytes, err := json.MarshalIndent(createI, "", " ") |