using MongoDB.Entities; using PrivaPub.Infrastructure.Data.Migrations; using PrivaPub.Models.Federation; using PrivaPub.Models.Post; using PrivaPub.Tests.Support; namespace PrivaPub.Tests.Infrastructure { [Xunit.Collection(nameof(Exclusive))] [Trait("Category", "Integration")] public class MigrationTests { [Fact] public async Task Stored_remote_content_is_sanitized_and_local_content_rendered() { Assert.SkipUnless(MongoFixture.Enabled, MongoFixture.Skip); var token = TestContext.Current.CancellationToken; var remote = new Post { IsFederatedCopy = true, Text = "

hi

", ObjectURI = $"https://r.example/{Guid.NewGuid():N}" }; var local = new Post { Text = "**bold** raw", ObjectURI = $"https://privapub.test/{Guid.NewGuid():N}" }; await DB.Default.SaveAsync(new[] { remote, local }, token); await new _002_sanitize_stored_content().UpgradeAsync(); var migratedRemote = await DB.Default.Find().OneAsync(remote.ID, token); var migratedLocal = await DB.Default.Find().OneAsync(local.ID, token); Assert.Equal("

hi

", migratedRemote.Text); Assert.Equal("

hi

", migratedRemote.ContentHtml); Assert.Equal(ContentFormat.Html, migratedRemote.ContentFormat); Assert.Equal("**bold** raw", migratedLocal.Text); Assert.Equal("

bold <b>raw</b>

", migratedLocal.ContentHtml); Assert.Equal(ContentFormat.Markdown, migratedLocal.ContentFormat); } [Fact] public async Task Direct_posts_move_into_posts_with_their_conversation() { Assert.SkipUnless(MongoFixture.Enabled, MongoFixture.Skip); var token = TestContext.Current.CancellationToken; var dm = new DmPost { GroupId = "conversation1", Text = "psst", ObjectURI = $"https://privapub.test/{Guid.NewGuid():N}", GroupUserId = "a1" }; await DB.Default.SaveAsync(dm, token); await new _005_direct_posts_join_posts().UpgradeAsync(); var post = await DB.Default.Find().OneAsync(dm.ID, token); Assert.Equal(PostVisibility.Direct, post.Visibility); Assert.Equal("conversation1", post.ConversationId); Assert.Equal("a1", post.AuthorAccountId); } [Fact] public async Task Fetched_records_lose_the_signature_they_never_had_and_every_record_gets_its_extensions() { Assert.SkipUnless(MongoFixture.Enabled, MongoFixture.Skip); var token = TestContext.Current.CancellationToken; var fetched = new ObjectRecord { ObjectURI = $"https://r.example/{Guid.NewGuid():N}", Path = ObjectPath.Fetched, KeyId = "https://x.example/u#k", SignatureScheme = "draft-cavage", Algorithm = "rsa-sha256", SignedHeaders = new() { "host" }, ActivityContext = "\"https://www.w3.org/ns/activitystreams\"", Raw = "{\"type\":\"Note\",\"quoteUrl\":\"https://q.example/1\"}" }; var delivered = new ObjectRecord { ObjectURI = $"https://r.example/{Guid.NewGuid():N}", Path = ObjectPath.Delivered, KeyId = "https://x.example/u#k", SignatureScheme = "draft-cavage", Raw = "not json" }; await DB.Default.SaveAsync(new[] { fetched, delivered }, token); await new _008_fetched_records_lose_the_trigger_signature().UpgradeAsync(); await new _009_object_records_keep_their_extensions().UpgradeAsync(); var afterFetched = await DB.Default.Find().OneAsync(fetched.ID, token); var afterDelivered = await DB.Default.Find().OneAsync(delivered.ID, token); Assert.Null(afterFetched.KeyId); Assert.Null(afterFetched.SignatureScheme); Assert.Empty(afterFetched.SignedHeaders); Assert.Null(afterFetched.ActivityContext); Assert.Equal("https://x.example/u#k", afterDelivered.KeyId); Assert.Contains("legacy-quote", afterFetched.Extensions); Assert.Empty(afterDelivered.Extensions); } } }