From d60edf7ec61537d70915c41de5526b81dd795a2c Mon Sep 17 00:00:00 2001 From: tobi <31960611+tsmethurst@users.noreply.github.com> Date: Sun, 10 Dec 2023 12:36:00 +0100 Subject: [PATCH] [bugfix] Ensure `pre` renders as expected, fix orderedCollectionPage (#2434) --- internal/ap/serialize.go | 19 ++++--- .../api/activitypub/users/outboxget_test.go | 56 +++++++++++++------ .../api/activitypub/users/repliesget_test.go | 2 +- .../api/client/accounts/accountverify_test.go | 2 +- .../api/client/instance/instancepatch_test.go | 12 ++-- internal/api/client/search/searchget_test.go | 6 +- .../api/client/statuses/statusmute_test.go | 8 +-- internal/db/bundb/account_test.go | 24 ++++---- internal/db/bundb/basic_test.go | 2 +- internal/db/bundb/instance_test.go | 2 +- internal/db/bundb/timeline_test.go | 10 ++-- internal/processing/account/rss_test.go | 4 +- internal/timeline/get_test.go | 6 +- internal/timeline/prune_test.go | 8 +-- internal/typeutils/internaltofrontend_test.go | 18 +++--- testrig/testmodels.go | 28 ++++++++++ web/source/css/status.css | 1 + 17 files changed, 130 insertions(+), 78 deletions(-) diff --git a/internal/ap/serialize.go b/internal/ap/serialize.go index 944e67407..774e95f2d 100644 --- a/internal/ap/serialize.go +++ b/internal/ap/serialize.go @@ -35,13 +35,15 @@ import ( // Currently, the following things will be custom serialized: // // - OrderedCollection: 'orderedItems' property will always be made into an array. +// - OrderedCollectionPage: 'orderedItems' property will always be made into an array. // - Any Accountable type: 'attachment' property will always be made into an array. // - Any Statusable type: 'attachment' property will always be made into an array; 'content' and 'contentMap' will be normalized. // - Any Activityable type: any 'object's set on an activity will be custom serialized as above. func Serialize(t vocab.Type) (m map[string]interface{}, e error) { switch tn := t.GetTypeName(); { - case tn == ObjectOrderedCollection: - return serializeOrderedCollection(t) + case tn == ObjectOrderedCollection || + tn == ObjectOrderedCollectionPage: + return serializeWithOrderedItems(t) case IsAccountable(tn): return serializeAccountable(t, true) case IsStatusable(tn): @@ -54,16 +56,17 @@ func Serialize(t vocab.Type) (m map[string]interface{}, e error) { } } -// serializeOrderedCollection is a custom serializer for an ActivityStreamsOrderedCollection. -// Unlike the standard streams.Serialize function, this serializer normalizes the orderedItems -// value to always be an array/slice, regardless of how many items are contained therein. -// -// TODO: Remove this function if we can fix the underlying issue in Go-Fed. +// serializeWithOrderedItems is a custom serializer +// for any type that has an `orderedItems` property. +// Unlike the standard streams.Serialize function, +// this serializer normalizes the orderedItems +// value to always be an array/slice, regardless +// of how many items are contained therein. // // See: // - https://github.com/go-fed/activity/issues/139 // - https://github.com/mastodon/mastodon/issues/24225 -func serializeOrderedCollection(t vocab.Type) (map[string]interface{}, error) { +func serializeWithOrderedItems(t vocab.Type) (map[string]interface{}, error) { data, err := streams.Serialize(t) if err != nil { return nil, err diff --git a/internal/api/activitypub/users/outboxget_test.go b/internal/api/activitypub/users/outboxget_test.go index 31b7e8e9b..55e9f2f78 100644 --- a/internal/api/activitypub/users/outboxget_test.go +++ b/internal/api/activitypub/users/outboxget_test.go @@ -140,16 +140,26 @@ func (suite *OutboxGetTestSuite) TestGetOutboxFirstPage() { "@context": "https://www.w3.org/ns/activitystreams", "id": "http://localhost:8080/users/the_mighty_zork/outbox?page=true", "next": "http://localhost:8080/users/the_mighty_zork/outbox?page=true\u0026max_id=01F8MHAMCHF6Y650WCRSCP4WMY", - "orderedItems": { - "actor": "http://localhost:8080/users/the_mighty_zork", - "cc": "http://localhost:8080/users/the_mighty_zork/followers", - "id": "http://localhost:8080/users/the_mighty_zork/statuses/01F8MHAMCHF6Y650WCRSCP4WMY/activity#Create", - "object": "http://localhost:8080/users/the_mighty_zork/statuses/01F8MHAMCHF6Y650WCRSCP4WMY", - "to": "https://www.w3.org/ns/activitystreams#Public", - "type": "Create" - }, + "orderedItems": [ + { + "actor": "http://localhost:8080/users/the_mighty_zork", + "cc": "http://localhost:8080/users/the_mighty_zork/followers", + "id": "http://localhost:8080/users/the_mighty_zork/statuses/01HH9KYNQPA416TNJ53NSATP40/activity#Create", + "object": "http://localhost:8080/users/the_mighty_zork/statuses/01HH9KYNQPA416TNJ53NSATP40", + "to": "https://www.w3.org/ns/activitystreams#Public", + "type": "Create" + }, + { + "actor": "http://localhost:8080/users/the_mighty_zork", + "cc": "http://localhost:8080/users/the_mighty_zork/followers", + "id": "http://localhost:8080/users/the_mighty_zork/statuses/01F8MHAMCHF6Y650WCRSCP4WMY/activity#Create", + "object": "http://localhost:8080/users/the_mighty_zork/statuses/01F8MHAMCHF6Y650WCRSCP4WMY", + "to": "https://www.w3.org/ns/activitystreams#Public", + "type": "Create" + } + ], "partOf": "http://localhost:8080/users/the_mighty_zork/outbox", - "prev": "http://localhost:8080/users/the_mighty_zork/outbox?page=true\u0026min_id=01F8MHAMCHF6Y650WCRSCP4WMY", + "prev": "http://localhost:8080/users/the_mighty_zork/outbox?page=true\u0026min_id=01HH9KYNQPA416TNJ53NSATP40", "type": "OrderedCollectionPage" }`, dst.String()) @@ -237,22 +247,32 @@ func checkDropPublished(t *testing.T, b []byte, at ...string) []byte { if err := json.Unmarshal(b, &m); err != nil { t.Fatalf("error unmarshaling json into map: %v", err) } - mm := m + + entries := make([]map[string]any, 0) for _, key := range at { - switch vt := mm[key].(type) { - case map[string]any: - mm = vt + switch vt := m[key].(type) { + case []interface{}: + for _, t := range vt { + if entry, ok := t.(map[string]any); ok { + entries = append(entries, entry) + } + } } } - if s, ok := mm["published"].(string); !ok { - t.Fatal("missing published data on json") - } else if _, err := time.Parse(time.RFC3339, s); err != nil { - t.Fatalf("error parsing published time: %v", err) + + for _, entry := range entries { + if s, ok := entry["published"].(string); !ok { + t.Fatal("missing published data on json") + } else if _, err := time.Parse(time.RFC3339, s); err != nil { + t.Fatalf("error parsing published time: %v", err) + } + delete(entry, "published") } - delete(mm, "published") + b, err := json.Marshal(m) if err != nil { t.Fatalf("error remarshaling json: %v", err) } + return b } diff --git a/internal/api/activitypub/users/repliesget_test.go b/internal/api/activitypub/users/repliesget_test.go index d20d8c6c0..757d0bc83 100644 --- a/internal/api/activitypub/users/repliesget_test.go +++ b/internal/api/activitypub/users/repliesget_test.go @@ -163,7 +163,7 @@ func (suite *RepliesGetTestSuite) TestGetRepliesNext() { "partOf": targetStatus.URI + "/replies?only_other_accounts=false", "next": "http://localhost:8080/users/the_mighty_zork/statuses/01F8MHAMCHF6Y650WCRSCP4WMY/replies?limit=20&min_id=01FF25D5Q0DH7CHD57CTRS6WK0&only_other_accounts=false", "prev": "http://localhost:8080/users/the_mighty_zork/statuses/01F8MHAMCHF6Y650WCRSCP4WMY/replies?limit=20&max_id=01FF25D5Q0DH7CHD57CTRS6WK0&only_other_accounts=false", - "orderedItems": "http://localhost:8080/users/admin/statuses/01FF25D5Q0DH7CHD57CTRS6WK0", + "orderedItems": []string{"http://localhost:8080/users/admin/statuses/01FF25D5Q0DH7CHD57CTRS6WK0"}, "totalItems": 1, }) assert.Equal(suite.T(), expect, string(b)) diff --git a/internal/api/client/accounts/accountverify_test.go b/internal/api/client/accounts/accountverify_test.go index 7827cc732..744488bf3 100644 --- a/internal/api/client/accounts/accountverify_test.go +++ b/internal/api/client/accounts/accountverify_test.go @@ -79,7 +79,7 @@ func (suite *AccountVerifyTestSuite) TestAccountVerifyGet() { suite.Equal("http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/header/small/01PFPMWK2FF0D9WMHEJHR07C3Q.jpg", apimodelAccount.HeaderStatic) suite.Equal(2, apimodelAccount.FollowersCount) suite.Equal(2, apimodelAccount.FollowingCount) - suite.Equal(6, apimodelAccount.StatusesCount) + suite.Equal(7, apimodelAccount.StatusesCount) suite.EqualValues(gtsmodel.VisibilityPublic, apimodelAccount.Source.Privacy) suite.Equal(testAccount.Language, apimodelAccount.Source.Language) suite.Equal(testAccount.NoteRaw, apimodelAccount.Source.Note) diff --git a/internal/api/client/instance/instancepatch_test.go b/internal/api/client/instance/instancepatch_test.go index 0c270de21..420bcd79e 100644 --- a/internal/api/client/instance/instancepatch_test.go +++ b/internal/api/client/instance/instancepatch_test.go @@ -133,7 +133,7 @@ func (suite *InstancePatchTestSuite) TestInstancePatch1() { }, "stats": { "domain_count": 2, - "status_count": 18, + "status_count": 19, "user_count": 4 }, "thumbnail": "http://localhost:8080/assets/logo.png", @@ -250,7 +250,7 @@ func (suite *InstancePatchTestSuite) TestInstancePatch2() { }, "stats": { "domain_count": 2, - "status_count": 18, + "status_count": 19, "user_count": 4 }, "thumbnail": "http://localhost:8080/assets/logo.png", @@ -367,7 +367,7 @@ func (suite *InstancePatchTestSuite) TestInstancePatch3() { }, "stats": { "domain_count": 2, - "status_count": 18, + "status_count": 19, "user_count": 4 }, "thumbnail": "http://localhost:8080/assets/logo.png", @@ -535,7 +535,7 @@ func (suite *InstancePatchTestSuite) TestInstancePatch6() { }, "stats": { "domain_count": 2, - "status_count": 18, + "status_count": 19, "user_count": 4 }, "thumbnail": "http://localhost:8080/assets/logo.png", @@ -674,7 +674,7 @@ func (suite *InstancePatchTestSuite) TestInstancePatch8() { }, "stats": { "domain_count": 2, - "status_count": 18, + "status_count": 19, "user_count": 4 }, "thumbnail": "http://localhost:8080/fileserver/01AY6P665V14JJR0AFVRT7311Y/attachment/original/`+instanceAccount.AvatarMediaAttachment.ID+`.gif",`+` @@ -828,7 +828,7 @@ func (suite *InstancePatchTestSuite) TestInstancePatch9() { }, "stats": { "domain_count": 2, - "status_count": 18, + "status_count": 19, "user_count": 4 }, "thumbnail": "http://localhost:8080/assets/logo.png", diff --git a/internal/api/client/search/searchget_test.go b/internal/api/client/search/searchget_test.go index 307b928bd..1b4b92c21 100644 --- a/internal/api/client/search/searchget_test.go +++ b/internal/api/client/search/searchget_test.go @@ -877,7 +877,7 @@ func (suite *SearchGetTestSuite) TestSearchAAny() { } suite.Len(searchResult.Accounts, 5) - suite.Len(searchResult.Statuses, 5) + suite.Len(searchResult.Statuses, 6) suite.Len(searchResult.Hashtags, 0) } @@ -918,7 +918,7 @@ func (suite *SearchGetTestSuite) TestSearchAAnyFollowingOnly() { } suite.Len(searchResult.Accounts, 2) - suite.Len(searchResult.Statuses, 5) + suite.Len(searchResult.Statuses, 6) suite.Len(searchResult.Hashtags, 0) } @@ -959,7 +959,7 @@ func (suite *SearchGetTestSuite) TestSearchAStatuses() { } suite.Len(searchResult.Accounts, 0) - suite.Len(searchResult.Statuses, 5) + suite.Len(searchResult.Statuses, 6) suite.Len(searchResult.Hashtags, 0) } diff --git a/internal/api/client/statuses/statusmute_test.go b/internal/api/client/statuses/statusmute_test.go index 91a361bd6..a83720a20 100644 --- a/internal/api/client/statuses/statusmute_test.go +++ b/internal/api/client/statuses/statusmute_test.go @@ -130,8 +130,8 @@ func (suite *StatusMuteTestSuite) TestMuteUnmuteStatus() { "header_static": "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/header/small/01PFPMWK2FF0D9WMHEJHR07C3Q.jpg", "followers_count": 2, "following_count": 2, - "statuses_count": 6, - "last_status_at": "2022-05-20T11:41:10.000Z", + "statuses_count": 7, + "last_status_at": "2023-12-10T09:24:00.000Z", "emojis": [], "fields": [], "enable_rss": true, @@ -193,8 +193,8 @@ func (suite *StatusMuteTestSuite) TestMuteUnmuteStatus() { "header_static": "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/header/small/01PFPMWK2FF0D9WMHEJHR07C3Q.jpg", "followers_count": 2, "following_count": 2, - "statuses_count": 6, - "last_status_at": "2022-05-20T11:41:10.000Z", + "statuses_count": 7, + "last_status_at": "2023-12-10T09:24:00.000Z", "emojis": [], "fields": [], "enable_rss": true, diff --git a/internal/db/bundb/account_test.go b/internal/db/bundb/account_test.go index 8c2de5519..e03300700 100644 --- a/internal/db/bundb/account_test.go +++ b/internal/db/bundb/account_test.go @@ -42,33 +42,33 @@ type AccountTestSuite struct { func (suite *AccountTestSuite) TestGetAccountStatuses() { statuses, err := suite.db.GetAccountStatuses(context.Background(), suite.testAccounts["local_account_1"].ID, 20, false, false, "", "", false, false) suite.NoError(err) - suite.Len(statuses, 6) + suite.Len(statuses, 7) } func (suite *AccountTestSuite) TestGetAccountStatusesPageDown() { // get the first page - statuses, err := suite.db.GetAccountStatuses(context.Background(), suite.testAccounts["local_account_1"].ID, 2, false, false, "", "", false, false) + statuses, err := suite.db.GetAccountStatuses(context.Background(), suite.testAccounts["local_account_1"].ID, 3, false, false, "", "", false, false) if err != nil { suite.FailNow(err.Error()) } - suite.Len(statuses, 2) + suite.Len(statuses, 3) // get the second page - statuses, err = suite.db.GetAccountStatuses(context.Background(), suite.testAccounts["local_account_1"].ID, 2, false, false, statuses[len(statuses)-1].ID, "", false, false) + statuses, err = suite.db.GetAccountStatuses(context.Background(), suite.testAccounts["local_account_1"].ID, 3, false, false, statuses[len(statuses)-1].ID, "", false, false) if err != nil { suite.FailNow(err.Error()) } - suite.Len(statuses, 2) + suite.Len(statuses, 3) // get the third page - statuses, err = suite.db.GetAccountStatuses(context.Background(), suite.testAccounts["local_account_1"].ID, 2, false, false, statuses[len(statuses)-1].ID, "", false, false) + statuses, err = suite.db.GetAccountStatuses(context.Background(), suite.testAccounts["local_account_1"].ID, 3, false, false, statuses[len(statuses)-1].ID, "", false, false) if err != nil { suite.FailNow(err.Error()) } - suite.Len(statuses, 2) + suite.Len(statuses, 1) // try to get the last page (should be empty) - statuses, err = suite.db.GetAccountStatuses(context.Background(), suite.testAccounts["local_account_1"].ID, 2, false, false, statuses[len(statuses)-1].ID, "", false, false) + statuses, err = suite.db.GetAccountStatuses(context.Background(), suite.testAccounts["local_account_1"].ID, 3, false, false, statuses[len(statuses)-1].ID, "", false, false) suite.ErrorIs(err, db.ErrNoEntries) suite.Empty(statuses) } @@ -76,13 +76,13 @@ func (suite *AccountTestSuite) TestGetAccountStatusesPageDown() { func (suite *AccountTestSuite) TestGetAccountStatusesExcludeRepliesAndReblogs() { statuses, err := suite.db.GetAccountStatuses(context.Background(), suite.testAccounts["local_account_1"].ID, 20, true, true, "", "", false, false) suite.NoError(err) - suite.Len(statuses, 6) + suite.Len(statuses, 7) } func (suite *AccountTestSuite) TestGetAccountStatusesExcludeRepliesAndReblogsPublicOnly() { statuses, err := suite.db.GetAccountStatuses(context.Background(), suite.testAccounts["local_account_1"].ID, 20, true, true, "", "", false, true) suite.NoError(err) - suite.Len(statuses, 1) + suite.Len(statuses, 2) } func (suite *AccountTestSuite) TestGetAccountStatusesMediaOnly() { @@ -306,13 +306,13 @@ func (suite *AccountTestSuite) TestUpdateAccount() { func (suite *AccountTestSuite) TestGetAccountLastPosted() { lastPosted, err := suite.db.GetAccountLastPosted(context.Background(), suite.testAccounts["local_account_1"].ID, false) suite.NoError(err) - suite.EqualValues(1653046870, lastPosted.Unix()) + suite.EqualValues(1702200240, lastPosted.Unix()) } func (suite *AccountTestSuite) TestGetAccountLastPostedWebOnly() { lastPosted, err := suite.db.GetAccountLastPosted(context.Background(), suite.testAccounts["local_account_1"].ID, true) suite.NoError(err) - suite.EqualValues(1634726437, lastPosted.Unix()) + suite.EqualValues(1702200240, lastPosted.Unix()) } func (suite *AccountTestSuite) TestInsertAccountWithDefaults() { diff --git a/internal/db/bundb/basic_test.go b/internal/db/bundb/basic_test.go index 67973a171..fc601f2a5 100644 --- a/internal/db/bundb/basic_test.go +++ b/internal/db/bundb/basic_test.go @@ -121,7 +121,7 @@ func (suite *BasicTestSuite) TestGetAllStatuses() { s := []*gtsmodel.Status{} err := suite.db.GetAll(context.Background(), &s) suite.NoError(err) - suite.Len(s, 22) + suite.Len(s, 23) } func (suite *BasicTestSuite) TestGetAllNotNull() { diff --git a/internal/db/bundb/instance_test.go b/internal/db/bundb/instance_test.go index f2ac202ef..4b8ec9962 100644 --- a/internal/db/bundb/instance_test.go +++ b/internal/db/bundb/instance_test.go @@ -47,7 +47,7 @@ func (suite *InstanceTestSuite) TestCountInstanceUsersRemote() { func (suite *InstanceTestSuite) TestCountInstanceStatuses() { count, err := suite.db.CountInstanceStatuses(context.Background(), config.GetHost()) suite.NoError(err) - suite.Equal(18, count) + suite.Equal(19, count) } func (suite *InstanceTestSuite) TestCountInstanceStatusesRemote() { diff --git a/internal/db/bundb/timeline_test.go b/internal/db/bundb/timeline_test.go index b3ce91755..98ae6b20f 100644 --- a/internal/db/bundb/timeline_test.go +++ b/internal/db/bundb/timeline_test.go @@ -157,7 +157,7 @@ func (suite *TimelineTestSuite) TestGetHomeTimeline() { suite.FailNow(err.Error()) } - suite.checkStatuses(s, id.Highest, id.Lowest, 18) + suite.checkStatuses(s, id.Highest, id.Lowest, 19) } func (suite *TimelineTestSuite) TestGetHomeTimelineNoFollowing() { @@ -189,7 +189,7 @@ func (suite *TimelineTestSuite) TestGetHomeTimelineNoFollowing() { suite.FailNow(err.Error()) } - suite.checkStatuses(s, id.Highest, id.Lowest, 6) + suite.checkStatuses(s, id.Highest, id.Lowest, 7) } func (suite *TimelineTestSuite) TestGetHomeTimelineWithFutureStatus() { @@ -211,7 +211,7 @@ func (suite *TimelineTestSuite) TestGetHomeTimelineWithFutureStatus() { } suite.NotContains(s, futureStatus) - suite.checkStatuses(s, id.Highest, id.Lowest, 18) + suite.checkStatuses(s, id.Highest, id.Lowest, 19) } func (suite *TimelineTestSuite) TestGetHomeTimelineBackToFront() { @@ -242,8 +242,8 @@ func (suite *TimelineTestSuite) TestGetHomeTimelineFromHighest() { } suite.checkStatuses(s, id.Highest, id.Lowest, 5) - suite.Equal("01HEN2RZ8BG29Y5Z9VJC73HZW7", s[0].ID) - suite.Equal("01FN3VJGFH10KR7S2PB0GFJZYG", s[len(s)-1].ID) + suite.Equal("01HH9KYNQPA416TNJ53NSATP40", s[0].ID) + suite.Equal("01G20ZM733MGN8J344T4ZDDFY1", s[len(s)-1].ID) } func (suite *TimelineTestSuite) TestGetListTimelineNoParams() { diff --git a/internal/processing/account/rss_test.go b/internal/processing/account/rss_test.go index 80f86211f..e528c27e0 100644 --- a/internal/processing/account/rss_test.go +++ b/internal/processing/account/rss_test.go @@ -45,14 +45,14 @@ func (suite *GetRSSTestSuite) TestGetAccountRSSAdmin() { func (suite *GetRSSTestSuite) TestGetAccountRSSZork() { getFeed, lastModified, err := suite.accountProcessor.GetRSSFeedForUsername(context.Background(), "the_mighty_zork") suite.NoError(err) - suite.EqualValues(1634726437, lastModified.Unix()) + suite.EqualValues(1702200240, lastModified.Unix()) feed, err := getFeed() suite.NoError(err) fmt.Println(feed) - suite.Equal("\n \n Posts from @the_mighty_zork@localhost:8080\n http://localhost:8080/@the_mighty_zork\n Posts from @the_mighty_zork@localhost:8080\n Wed, 20 Oct 2021 10:40:37 +0000\n Wed, 20 Oct 2021 10:40:37 +0000\n \n http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/avatar/small/01F8MH58A357CV5K7R7TJMSH6S.jpg\n Avatar for @the_mighty_zork@localhost:8080\n http://localhost:8080/@the_mighty_zork\n \n \n introduction post\n http://localhost:8080/@the_mighty_zork/statuses/01F8MHAMCHF6Y650WCRSCP4WMY\n @the_mighty_zork@localhost:8080 made a new post: "hello everyone!"\n \n @the_mighty_zork@localhost:8080\n http://localhost:8080/@the_mighty_zork/statuses/01F8MHAMCHF6Y650WCRSCP4WMY\n Wed, 20 Oct 2021 10:40:37 +0000\n http://localhost:8080/@the_mighty_zork/feed.rss\n \n \n", feed) + suite.Equal("\n \n Posts from @the_mighty_zork@localhost:8080\n http://localhost:8080/@the_mighty_zork\n Posts from @the_mighty_zork@localhost:8080\n Sun, 10 Dec 2023 09:24:00 +0000\n Sun, 10 Dec 2023 09:24:00 +0000\n \n http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/avatar/small/01F8MH58A357CV5K7R7TJMSH6S.jpg\n Avatar for @the_mighty_zork@localhost:8080\n http://localhost:8080/@the_mighty_zork\n \n \n HTML in post\n http://localhost:8080/@the_mighty_zork/statuses/01HH9KYNQPA416TNJ53NSATP40\n @the_mighty_zork@localhost:8080 made a new post: "Here's a bunch of HTML, read it and weep, weep then! ```html <section class="about-user"> <div class="col-header"> <h2>About</h2> </div> <div class="fields"> <h3 class="sr-only">Fields</h3> <dl> ...\n Here's a bunch of HTML, read it and weep, weep then!

<section class="about-user">\n    <div class="col-header">\n        <h2>About</h2>\n    </div>            \n    <div class="fields">\n        <h3 class="sr-only">Fields</h3>\n        <dl>\n            <div class="field">\n                <dt>should you follow me?</dt>\n                <dd>maybe!</dd>\n            </div>\n            <div class="field">\n                <dt>age</dt>\n                <dd>120</dd>\n            </div>\n        </dl>\n    </div>\n    <div class="bio">\n        <h3 class="sr-only">Bio</h3>\n        <p>i post about things that concern me</p>\n    </div>\n    <div class="sr-only" role="group">\n        <h3 class="sr-only">Stats</h3>\n        <span>Joined in Jun, 2022.</span>\n        <span>8 posts.</span>\n        <span>Followed by 1.</span>\n        <span>Following 1.</span>\n    </div>\n    <div class="accountstats" aria-hidden="true">\n        <b>Joined</b><time datetime="2022-06-04T13:12:00.000Z">Jun, 2022</time>\n        <b>Posts</b><span>8</span>\n        <b>Followed by</b><span>1</span>\n        <b>Following</b><span>1</span>\n    </div>\n</section>\n

There, hope you liked that!

]]>
\n @the_mighty_zork@localhost:8080\n http://localhost:8080/@the_mighty_zork/statuses/01HH9KYNQPA416TNJ53NSATP40\n Sun, 10 Dec 2023 09:24:00 +0000\n http://localhost:8080/@the_mighty_zork/feed.rss\n
\n \n introduction post\n http://localhost:8080/@the_mighty_zork/statuses/01F8MHAMCHF6Y650WCRSCP4WMY\n @the_mighty_zork@localhost:8080 made a new post: "hello everyone!"\n \n @the_mighty_zork@localhost:8080\n http://localhost:8080/@the_mighty_zork/statuses/01F8MHAMCHF6Y650WCRSCP4WMY\n Wed, 20 Oct 2021 10:40:37 +0000\n http://localhost:8080/@the_mighty_zork/feed.rss\n \n
\n
", feed) } func (suite *GetRSSTestSuite) TestGetAccountRSSZorkNoPosts() { diff --git a/internal/timeline/get_test.go b/internal/timeline/get_test.go index 360eac7b6..02256054e 100644 --- a/internal/timeline/get_test.go +++ b/internal/timeline/get_test.go @@ -228,7 +228,7 @@ func (suite *GetTestSuite) TestGetNewTimelineMoreThanPossible() { if err != nil { suite.FailNow(err.Error()) } - suite.checkStatuses(statuses, id.Highest, id.Lowest, 18) + suite.checkStatuses(statuses, id.Highest, id.Lowest, 19) } func (suite *GetTestSuite) TestGetNewTimelineMoreThanPossiblePageUp() { @@ -255,7 +255,7 @@ func (suite *GetTestSuite) TestGetNewTimelineMoreThanPossiblePageUp() { if err != nil { suite.FailNow(err.Error()) } - suite.checkStatuses(statuses, id.Highest, id.Lowest, 18) + suite.checkStatuses(statuses, id.Highest, id.Lowest, 19) } func (suite *GetTestSuite) TestGetNewTimelineNoFollowing() { @@ -284,7 +284,7 @@ func (suite *GetTestSuite) TestGetNewTimelineNoFollowing() { if err != nil { suite.FailNow(err.Error()) } - suite.checkStatuses(statuses, id.Highest, id.Lowest, 6) + suite.checkStatuses(statuses, id.Highest, id.Lowest, 7) for _, s := range statuses { if s.GetAccountID() != testAccount.ID { diff --git a/internal/timeline/prune_test.go b/internal/timeline/prune_test.go index 4cd677953..047166e9e 100644 --- a/internal/timeline/prune_test.go +++ b/internal/timeline/prune_test.go @@ -40,7 +40,7 @@ func (suite *PruneTestSuite) TestPrune() { pruned, err := suite.state.Timelines.Home.Prune(ctx, testAccountID, desiredPreparedItemsLength, desiredIndexedItemsLength) suite.NoError(err) - suite.Equal(17, pruned) + suite.Equal(18, pruned) suite.Equal(5, suite.state.Timelines.Home.GetIndexedLength(ctx, testAccountID)) } @@ -56,7 +56,7 @@ func (suite *PruneTestSuite) TestPruneTwice() { pruned, err := suite.state.Timelines.Home.Prune(ctx, testAccountID, desiredPreparedItemsLength, desiredIndexedItemsLength) suite.NoError(err) - suite.Equal(17, pruned) + suite.Equal(18, pruned) suite.Equal(5, suite.state.Timelines.Home.GetIndexedLength(ctx, testAccountID)) // Prune same again, nothing should be pruned this time. @@ -78,7 +78,7 @@ func (suite *PruneTestSuite) TestPruneTo0() { pruned, err := suite.state.Timelines.Home.Prune(ctx, testAccountID, desiredPreparedItemsLength, desiredIndexedItemsLength) suite.NoError(err) - suite.Equal(22, pruned) + suite.Equal(23, pruned) suite.Equal(0, suite.state.Timelines.Home.GetIndexedLength(ctx, testAccountID)) } @@ -95,7 +95,7 @@ func (suite *PruneTestSuite) TestPruneToInfinityAndBeyond() { pruned, err := suite.state.Timelines.Home.Prune(ctx, testAccountID, desiredPreparedItemsLength, desiredIndexedItemsLength) suite.NoError(err) suite.Equal(0, pruned) - suite.Equal(22, suite.state.Timelines.Home.GetIndexedLength(ctx, testAccountID)) + suite.Equal(23, suite.state.Timelines.Home.GetIndexedLength(ctx, testAccountID)) } func TestPruneTestSuite(t *testing.T) { diff --git a/internal/typeutils/internaltofrontend_test.go b/internal/typeutils/internaltofrontend_test.go index 6152bf77f..d65d47bf1 100644 --- a/internal/typeutils/internaltofrontend_test.go +++ b/internal/typeutils/internaltofrontend_test.go @@ -58,8 +58,8 @@ func (suite *InternalToFrontendTestSuite) TestAccountToFrontend() { "header_static": "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/header/small/01PFPMWK2FF0D9WMHEJHR07C3Q.jpg", "followers_count": 2, "following_count": 2, - "statuses_count": 6, - "last_status_at": "2022-05-20T11:41:10.000Z", + "statuses_count": 7, + "last_status_at": "2023-12-10T09:24:00.000Z", "emojis": [], "fields": [], "enable_rss": true, @@ -100,8 +100,8 @@ func (suite *InternalToFrontendTestSuite) TestAccountToFrontendWithEmojiStruct() "header_static": "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/header/small/01PFPMWK2FF0D9WMHEJHR07C3Q.jpg", "followers_count": 2, "following_count": 2, - "statuses_count": 6, - "last_status_at": "2022-05-20T11:41:10.000Z", + "statuses_count": 7, + "last_status_at": "2023-12-10T09:24:00.000Z", "emojis": [ { "shortcode": "rainbow", @@ -148,8 +148,8 @@ func (suite *InternalToFrontendTestSuite) TestAccountToFrontendWithEmojiIDs() { "header_static": "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/header/small/01PFPMWK2FF0D9WMHEJHR07C3Q.jpg", "followers_count": 2, "following_count": 2, - "statuses_count": 6, - "last_status_at": "2022-05-20T11:41:10.000Z", + "statuses_count": 7, + "last_status_at": "2023-12-10T09:24:00.000Z", "emojis": [ { "shortcode": "rainbow", @@ -192,8 +192,8 @@ func (suite *InternalToFrontendTestSuite) TestAccountToFrontendSensitive() { "header_static": "http://localhost:8080/fileserver/01F8MH1H7YV1Z7D2C8K2730QBF/header/small/01PFPMWK2FF0D9WMHEJHR07C3Q.jpg", "followers_count": 2, "following_count": 2, - "statuses_count": 6, - "last_status_at": "2022-05-20T11:41:10.000Z", + "statuses_count": 7, + "last_status_at": "2023-12-10T09:24:00.000Z", "emojis": [], "fields": [], "source": { @@ -896,7 +896,7 @@ func (suite *InternalToFrontendTestSuite) TestInstanceV1ToFrontend() { }, "stats": { "domain_count": 2, - "status_count": 18, + "status_count": 19, "user_count": 4 }, "thumbnail": "http://localhost:8080/assets/logo.png", diff --git a/testrig/testmodels.go b/testrig/testmodels.go index e039a7c16..e7c1f0c02 100644 --- a/testrig/testmodels.go +++ b/testrig/testmodels.go @@ -1676,6 +1676,31 @@ func NewTestStatuses() map[string]*gtsmodel.Status { ActivityStreamsType: ap.ActivityQuestion, PollID: "01HEN2RKT1YTEZ80SA8HGP105F", }, + "local_account_1_status_7": { + ID: "01HH9KYNQPA416TNJ53NSATP40", + URI: "http://localhost:8080/users/the_mighty_zork/statuses/01HH9KYNQPA416TNJ53NSATP40", + URL: "http://localhost:8080/@the_mighty_zork/statuses/01HH9KYNQPA416TNJ53NSATP40", + Content: "

Here's a bunch of HTML, read it and weep, weep then!

<section class="about-user">\n    <div class="col-header">\n        <h2>About</h2>\n    </div>            \n    <div class="fields">\n        <h3 class="sr-only">Fields</h3>\n        <dl>\n            <div class="field">\n                <dt>should you follow me?</dt>\n                <dd>maybe!</dd>\n            </div>\n            <div class="field">\n                <dt>age</dt>\n                <dd>120</dd>\n            </div>\n        </dl>\n    </div>\n    <div class="bio">\n        <h3 class="sr-only">Bio</h3>\n        <p>i post about things that concern me</p>\n    </div>\n    <div class="sr-only" role="group">\n        <h3 class="sr-only">Stats</h3>\n        <span>Joined in Jun, 2022.</span>\n        <span>8 posts.</span>\n        <span>Followed by 1.</span>\n        <span>Following 1.</span>\n    </div>\n    <div class="accountstats" aria-hidden="true">\n        <b>Joined</b><time datetime="2022-06-04T13:12:00.000Z">Jun, 2022</time>\n        <b>Posts</b><span>8</span>\n        <b>Followed by</b><span>1</span>\n        <b>Following</b><span>1</span>\n    </div>\n</section>\n

There, hope you liked that!

", + Text: "Here's a bunch of HTML, read it and weep, weep then!\n\n```html\n
\n
\n

About

\n
\n
\n

Fields

\n
\n
\n
should you follow me?
\n
maybe!
\n
\n
\n
age
\n
120
\n

Stats

\n Joined in Jun, 2022.\n 8 posts.\n Followed by 1.\n Following 1.\n
\n
\n Joined\n Posts8\n Followed by1\n Following1\n
\n
\n```\n\nThere, hope you liked that!", + CreatedAt: TimeMustParse("2023-12-10T11:24:00+02:00"), + UpdatedAt: TimeMustParse("2023-12-10T11:24:00+02:00"), + Local: util.Ptr(true), + AccountURI: "http://localhost:8080/users/the_mighty_zork", + AccountID: "01F8MH1H7YV1Z7D2C8K2730QBF", + InReplyToID: "", + BoostOfID: "", + ThreadID: "01HH9M3FVSF5J7120X9T6PG4GF", + ContentWarning: "HTML in post", + Visibility: gtsmodel.VisibilityPublic, + Sensitive: util.Ptr(true), + Language: "en", + CreatedWithApplicationID: "01F8MGY43H3N2C8EWPR2FPYEXG", + Federated: util.Ptr(true), + Boostable: util.Ptr(true), + Replyable: util.Ptr(true), + Likeable: util.Ptr(true), + ActivityStreamsType: ap.ObjectNote, + }, "local_account_2_status_1": { ID: "01F8MHBQCBTDKN6X5VHGMMN4MA", URI: "http://localhost:8080/users/1happyturtle/statuses/01F8MHBQCBTDKN6X5VHGMMN4MA", @@ -2169,6 +2194,9 @@ func NewTestThreads() map[string]*gtsmodel.Thread { "local_account_1_status_5": { ID: "01HCWE1ERQSMMVWDD0BE491E2P", }, + "local_account_1_status_7": { + ID: "01HH9M3FVSF5J7120X9T6PG4GF", + }, "local_account_2_status_1": { ID: "01HCWE2Q24FWCZE41AS77SDFRZ", }, diff --git a/web/source/css/status.css b/web/source/css/status.css index d2aa658f1..cbe8c04d2 100644 --- a/web/source/css/status.css +++ b/web/source/css/status.css @@ -155,6 +155,7 @@ main { .content { word-break: break-word; line-height: 1.6rem; + width: 100%; h1 { margin: 0;