using PrivaPub.Federation.Objects; using PrivaPub.Models.Post; using System.Text.Json.Nodes; namespace PrivaPub.Tests.Federation { public class NoteParserTests { const string MastodonNote = """ { "id": "https://m.example/users/alice/statuses/1", "type": "Note", "summary": "spoilers", "inReplyTo": "https://privapub.test/peasants/bob/posts/abc", "published": "2026-09-30T10:00:00Z", "url": "https://m.example/@alice/1", "attributedTo": "https://m.example/users/alice", "to": ["https://www.w3.org/ns/activitystreams#Public"], "cc": ["https://m.example/users/alice/followers", "https://privapub.test/peasants/bob"], "sensitive": true, "conversation": "tag:m.example,2026-09-30:objectId=1:objectType=Conversation", "context": "https://m.example/contexts/1", "content": "

@bob hi #Fedi

", "contentMap": { "en": "

hi

" }, "attachment": [{ "type": "Document", "mediaType": "image/png", "url": "https://files.m.example/a.png", "name": "a cat", "blurhash": "UBL_:rOpGG-oBUNG,qRj2so|=eE1w^n4S5NH", "focalPoint": [0.5, -2.0], "width": 640, "height": 480 }], "tag": [ { "type": "Mention", "href": "https://privapub.test/peasants/bob", "name": "@bob@privapub.test" }, { "type": "Hashtag", "href": "https://m.example/tags/fedi", "name": "#Fedi" }, { "type": "Emoji", "name": ":blob:", "icon": { "type": "Image", "url": "https://files.m.example/blob.png" } } ] } """; // Castopod's episode: its words in description, its sound in audio, the sound's name for a title [Fact] public void A_podcast_episode_is_read_with_its_words_sound_and_cover() { var episode = NoteParser.Parse(JsonNode.Parse(""" {"id":"https://castopod.test/@pod/episodes/one","type":"PodcastEpisode","published":"2026-10-06T09:08:17+00:00", "to":["https://www.w3.org/ns/activitystreams#Public"],"attributedTo":"https://castopod.test/@pod", "description":{"type":"Note","mediaType":"text/markdown","content":"Listen to the **meadow**","contentMap":{"en":"

Listen to the meadow

"}}, "image":{"type":"Image","mediaType":"image/png","url":"https://castopod.test/media/cover.png"}, "audio":{"id":"https://castopod.test/audio/one.mp3","type":"Audio","name":"Episode one","size":16791,"duration":4.02, "url":{"href":"https://castopod.test/audio/one.mp3","type":"Link","mediaType":"audio/mpeg"}}} """)); Assert.Equal(("PodcastEpisode", "Episode one", "https://castopod.test/media/cover.png"), (episode.Type, episode.Title, episode.CoverURL)); Assert.Contains("meadow", episode.ContentHtml); var sound = Assert.Single(episode.Attachments); Assert.Equal(("https://castopod.test/audio/one.mp3", "audio/mpeg"), (sound.RemoteURL, sound.ContentType)); Assert.Equal(4.02, episode.Audio.DurationSeconds); } [Fact] public void Reads_a_mastodon_note() { var note = NoteParser.Parse(JsonNode.Parse(MastodonNote)); Assert.Equal("https://m.example/users/alice", note.AttributedTo); Assert.Equal("spoilers", note.SpoilerText); Assert.True(note.Sensitive); Assert.Equal("en", note.Language); Assert.Equal("https://m.example/@alice/1", note.Url); Assert.Equal("https://m.example/contexts/1", note.Context); Assert.DoesNotContain("